-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
MDEV-36923 : Add warning messages for applier FK failures #4342
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: 10.11
Are you sure you want to change the base?
Conversation
e80adde to
04491fc
Compare
3595516 to
ada1189
Compare
22e5686 to
a40d8be
Compare
| SET GLOBAL wsrep_mode=128; | ||
| ERROR 42000: Variable 'wsrep_mode' can't be set to the value of '128' | ||
| SET GLOBAL wsrep_mode=65536; | ||
| ERROR 42000: Variable 'wsrep_mode' can't be set to the value of '65536' |
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.
Is this a tight limit? As far as I understand, the Sys_var_set Sys_wsrep_mode was extended with only one member. Hence I’d expect 256 to be a disallowed value.
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.
Fixed
| --let $assert_count = 1 | ||
| --let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.2.err | ||
| --let $assert_text = Foreign key warning in table | ||
| --let $assert_select = Foreign key warning in table | ||
| --source include/assert_grep.inc | ||
| --let $assert_text = adding an index entry to a child table failed | ||
| --let $assert_select = adding an index entry to a child table failed | ||
| --source include/assert_grep.inc |
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.
The table name and the constraint name are being omitted here, although a comment right before the statement INSERT INTO grandchild claims to know them.
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.
Added full text.
storage/innobase/row/row0ins.cc
Outdated
| #ifndef UNIV_DEBUG | ||
| /* In release builds do not output lock wait warnings to avoid | ||
| flooding error log. */ | ||
| if (err == DB_LOCK_WAIT) | ||
| return; | ||
| #endif |
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.
Do we really need this even in debug instrumented builds? Would a Galera specific DBUG_EXECUTE_IF in row_mysql_handle_errors() serve a similar purpose?
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.
We really do not want to log lock waits in release builds, they are not errors this change is intended. Case where (err != DB_SUCCESS && err != DB_LOCK_WAIT) is the only interesting case I just do not know test case to produce it.
storage/innobase/row/row0ins.cc
Outdated
| const char* end; | ||
| end= innobase_convert_name(db_table, sizeof db_table, | ||
| foreign->foreign_table_name, | ||
| strlen(foreign->foreign_table_name), | ||
| trx->mysql_thd); |
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.
TAB should not be for formatting new functions. Why are the declaration and initialization split?
storage/innobase/row/row0ins.cc
Outdated
| db_table[end - db_table] = '\0'; | ||
|
|
||
| const char *fk_id= strchr(foreign->id, '/'); |
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.
end may post one char past the end of db_table. If that is the case, this assignment would constitute a buffer overflow and fail to ensure that the db_table is NUL terminated. In my previous review I suggested the use of "%.*s" and specifying the length explicitly. The buffer overflow would have been avoided by that.
The formatting around the assignment operator = is inconsistent.
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.
I do not think so, see ut0ut.cc funtion ut_get_name, db_table size is bigger than actual table name can be even in multibyte names.
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.
I will make buffer slightly longer to avoid overflow.
storage/innobase/row/row0ins.cc
Outdated
| if (fk_id) | ||
| fk_id++; | ||
| else | ||
| fk_id= foreign->id; /* a constraint name from before MySQL 4.0.18 */ |
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.
Not implementing dict_foreign_t::sql_id() will cause a run-time merge conflict with #3960. If the tests are not revised to actually cover the constraint names that the messages are expected to output, then such conflicts will remain undetected.
| if (err != DB_SUCCESS) { | ||
|
|
||
| goto nonstandard_exit_func; | ||
| } |
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.
Heikki Tuuri insisted that there be an extra blank line before any goto statement. I disagree with that, but then again I think that we should avoid any changes to formatting unless some code nearby is being changed. This is not the only occurence of a blank line before a goto statement in this function.
| if (trx->is_wsrep()) { | ||
| wsrep_applier_log_fk(trx, foreign, | ||
| "Setting shared record lock " | ||
| "to matching record in the " | ||
| "child table failed err: ", | ||
| err); |
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.
In my previous review, I pointed out that we have some duplicated err: err: strings in the output. This still seems to be the case at least for this message.
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.
Fixed.
Add warning messages if applier write set execution fails because of foreign key constraint error. Warnings are printed by default and can be disabled using SET GLOBAL wsrep_mode=APPLIER_DISABLE_FK_WARNINGS.
a40d8be to
f915b1c
Compare
| include/assert_grep.inc [Foreign key warning in table: \`test\`\.\`grandchild\` constraint \`fk_2\` failed err: adding an index entry to a child table failed.] | ||
| connection node_1; | ||
| drop table grandchild; | ||
| drop table child; | ||
| drop table parent; | ||
| SET GLOBAL wsrep_provider_options = 'pc.ignore_sb=false'; | ||
| SET GLOBAL wsrep_provider_options = 'pc.weight=1'; | ||
| connection node_2; | ||
| call mtr.add_suppression("WSREP: Foreign key warning in table"); |
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.
There is some a duplicated word failed in the message as well as some confusion between warning and err. Why is the mtr.add_suppression() less specific? Do we really want to ignore any errors that could be issued for other table or constraint names?
| --- /home/jan/work/mariadb/10.11/mysql-test/suite/galera/r/galera_FK_duplicate_client_insert.result | ||
| +++ /home/jan/work/mariadb/10.11/mysql-test/suite/galera/r/galera_FK_duplicate_client_insert.reject |
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.
Absolute path names do not add any useful information. Some other redundant information had been removed in 88d9348.
| --let $assert_text = Foreign key warning in table: \`test\`\.\`cg\` constraint \`fk_1\` failed err: Setting shared record lock to matching record in the child table failed \(Lock wait\). | ||
| --let $assert_select = Foreign key warning in table: \`test\`\.\`cg\` constraint \`fk_1\` failed err: Setting shared record lock to matching record in the child table failed \(Lock wait\). |
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.
There is no table named cg or constraint fk_1 in this test. The error message is misleading or incorrect.
Also, the "child table" appears to be incorrect as well. The SQL terminology would be "referencing table". But, the referencing table is cg-, and there is no need to set any shared lock on it. INSERT would typically acquire an implicit exclusive lock. I believe that a shared lock would be set on a record in the referenced table, or "parent table".
Furthermore, I think that it is a dangerous path to issue "fake" errors in a debug instrumented executable. Why do we need to be so specific? Why can’t we just report "deadlock", "lock wait timeout" or "interrupted" without specifying which lock wait was aborted by that condition? If we need to be specific, then the exact message would have to be output somewhere in row_mysql_handle_errors() and in my opinion it should not be specific to Galera replication.
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.
Table cg was created on line 322 as well as fk_1, I will move this little bit earlier.
I'm sorry but I do not understand your second paragraph.
| Starting with MariaDB 12, constraint names are prepended with the | ||
| dict_table_t::name and the invalid UTF-8 sequence 0xff. */ | ||
| const char *s; | ||
| return ((s= strchr(id, '\377')) || (s= strchr(id, '/'))) ? ++s : id; |
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.
This is not what I requested earlier. We must not create an impression that a downgrade would work if it has not been tested. The check for '\377' must not be added.
Description
Added warning messages for applier FK failures. Warnings are printed by default and can be disabled using
set global wsrep_mode=APPLIER_DISABLE_FK_WARNINGS;
Ported to MariaDB [email protected]
Release Notes
TODO: What should the release notes say about this change?
Include any changed system variables, status variables or behaviour. Optionally list any https://mariadb.com/kb/ pages that need changing.
How can this PR be tested?
TODO: modify the automated test suite to verify that the PR causes MariaDB to behave as intended.
Consult the documentation on "Writing good test cases".
If the changes are not amenable to automated testing, please explain why not and carefully describe how to test manually.
Basing the PR against the correct MariaDB version
mainbranch.PR quality check