-
Notifications
You must be signed in to change notification settings - Fork 9.4k
Prevent db_schema.xml declarations with comment="" from breaking zero downtime deployments
#40242
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 2.4-develop
Are you sure you want to change the base?
Conversation
… downtime deployments The issue is if you define a db_schema.xml with comment="" then the system will always be flagged as needing to make changes. When a table is created there is no concept of a null versus empty string comment, the comment is either there or it is not and this disparity breaks the comparison. Given that the error here is never in the databases side of things, I believe it makes most sense to correct this during the reading and handling of db_schema.xml. We already have an area of code which is doing casting and manipulation of elements, so stripping out empty comment declarations (which will never make it to the database anyway) seems safe to me.
|
Hi @convenient. Thank you for your contribution!
Allowed build names are:
You can find more information about the builds here For more details, review the Code Contributions documentation. |
|
@magento run all tests |
|
Excellent addition, I love it. You get test failures for B2B which are nothing to do with you. (I hate that BTW) A linebreak at the |
|
@magento run all tests |
Removed unnecessary empty line in docblock.
|
@magento run all tests |
|
@magento run Unit Tests, Functional Tests EE, Functional Tests B2B |
|
@magento run Functional Tests B2B |
|
@magento run Functional Tests B2B, Sample Data Tests CE, Sample Data Tests EE, Sample Data Tests B2B |
|
@magento run Functional Tests B2B |
|
@magento create issue |
|
@magento run all tests |
engcom-Hotel
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/ElementFactory.php
Outdated
Show resolved
Hide resolved
| */ | ||
| private function removeEmptyComments(array $elementStructuralData) | ||
| { | ||
| if (isset($elementStructuralData['comment']) && $elementStructuralData['comment'] === "") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding the edge cases like if the whitespace-only strings (" ") or "0" (which is technically a valid comment but falsy)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello @engcom-Hotel
I'm not sure what you're seeing in the testing here, if someone wants to create a table with a comment 0 that's their prerogative. It adds cleanly to the database and has no issues in the comparison so not sure what you're seeing here.
It's not a common use case in the industry for people to define a comment with multiple space string chars, that's not a case I've seen in any extensions in the wild but i'll add trim to cater for that scenario
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the clarification! You're absolutely right about "0". A comment with the value "0" is perfectly valid and should be handled properly. My concern wasn't about "0" being falsy, but rather about ensuring the code explicitly handles this case as intended.
Regarding whitespace-only strings: I appreciate you adding trim() to handle that scenario. While it may not be common in the wild, defensive coding against such edge cases can prevent unexpected behavior in schema comparisons and improve code robustness.
Thanks for addressing the feedback!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @engcom-Hotel
The code seems to handle the case of 0 correctly, as it gets added to the database and also read back. Is there anything else you need at this stage to get this untagged from needs update? I think i have answered all queries?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes @convenient, thank you!
I am approving this PR for further processing. 👍
…ementFactory.php Co-authored-by: Abhinav Pathak <[email protected]>
|
@magento run all tests |
|
@magento run all tests |
|
@magento run Functional Tests B2B, Functional Tests EE |
Many magento deployment pipelines achieve zero downtime deployments by checking if database migrations need to be executed with
setup:db:statusand only putting up maintenance mode if there are changes needing to be made.This process can be seen in
deployerphp/deployerhere.The issue
The way
setup:db:statusworks is bydb_schema.xmlinto an arrayThe problem we frequently see is that third party modules inadvertently make a small mistake which breaks zero downtime deployments, they say
comment=""instead of omitting entirely.Given that the mistake is small and basically a NOOP it has a disproportionately negative impact. You can see this is not an infrequent error, many extensions make this mistake https://github.com/search?q=path%3A**%2Fdb_schema.xml+%22comment%3D%5C%22%5C%22%22&type=code
The issue is if you define a
db_schema.xmlwithcomment=""then the system will always be flagged as needing to make changes. When a table is created there is no concept of a null versus empty string comment, the comment is either there or it is not and this disparity breaks the comparison.Why this happens
db_schema.xmlCOMMENTsection<column comment="commented"/>COMMENT 'commented'<column /><column comment=""/>The data is read from the here database, defaulting the comment to NULL if it is not existing
magento2/lib/internal/Magento/Framework/Setup/Declaration/Schema/Db/MySQL/DbSchemaReader.php
Lines 97 to 119 in 98f028a
Potential fix
Given that the error here is never in the databases side of things, I believe it makes most sense to correct this during the reading and handling of
db_schema.xml. We already have an area of code which is doing casting and manipulation of elements, so stripping out empty comment declarations (which will never make it to the database anyway) seems safe to me.The fix and manual testing
In the past I have used this script I wrote for debugging what is breaking
setup:db:status. You can copy that and place it in your magento root assetup-db-status.phpWe can force in some example
db_schema.xmlchanges by editingvendor/magento/module-catalog/etc/db_schema.xmland placing these at the bottom of the file. These changes cover all cases to do with commentsAfter running
setup:upgradewe can see that we still have changes being flagged.And the deeper analysis using the debug script above
$ php setup-db-status.php modify_table some_dummy_table123 modify_column some_dummy_table123 some_dummy_field_with_empty_string_comment old: {"type":"text","nullable":true,"comment":null} new: {"type":"text","nullable":true,"comment":""} modify_column some_dummy_table456 some_dummy_field_with_empty_string_comment old: {"type":"text","nullable":true,"comment":null} new: {"type":"text","nullable":true,"comment":""} modify_column some_dummy_table789 some_dummy_field_with_empty_string_comment old: {"type":"text","nullable":true,"comment":null} new: {"type":"text","nullable":true,"comment":""}You can see that it believes the "old" value in the database is a null comment, while the "new" value from the schema is an empty string.
When you apply the fix from this PR we get the following output, which will allow for more robust zero downtime deployments
Contribution checklist (*)
Resolved issues:
db_schema.xmldeclarations withcomment=""from breaking zero downtime deployments #40254: Preventdb_schema.xmldeclarations withcomment=""from breaking zero downtime deployments