mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
BUG#11758262 - 50439: MARK INSERT...SEL...ON DUP KEY UPD,REPLACE...SEL,CREATE...[IGN|REPL] SEL
Problem: The following statements can cause the slave to go out of sync if logged in statement format: INSERT IGNORE...SELECT INSERT ... SELECT ... ON DUPLICATE KEY UPDATE REPLACE ... SELECT UPDATE IGNORE : CREATE ... IGNORE SELECT CREATE ... REPLACE SELECT Background: Since the order of the rows returned by the SELECT statement or otherwise may differ on master and slave, therefore the above statements may cuase the salve to go out of sync with the master. Fix: Issue a warning when statements like the above are exectued and the bin-logging format is statement. If the logging format is mixed, use row based logging. Marking a statement as unsafe has been done in the sql/sql_parse.cc instead of sql/sql_yacc.cc, because while parsing for a token has been done we cannot be sure if the parsing of the other tokens has been done as well. Six new warning messages has been added for each unsafe statement. binlog.binlog_unsafe.test has been updated to incoporate these additional unsafe statments. ****** BUG#11758262 - 50439: MARK INSERT...SEL...ON DUP KEY UPD,REPLACE...SEL,CREATE...[IGN|REPL] SEL Problem: The following statements can cause the slave to go out of sync if logged in statement format: INSERT IGNORE...SELECT INSERT ... SELECT ... ON DUPLICATE KEY UPDATE REPLACE ... SELECT UPDATE IGNORE : CREATE ... IGNORE SELECT CREATE ... REPLACE SELECT Background: Since the order of the rows returned by the SELECT statement or otherwise may differ on master and slave, therefore the above statements may cuase the salve to go out of sync with the master. Fix: Issue a warning when statements like the above are exectued and the bin-logging format is statement. If the logging format is mixed, use row based logging. Marking a statement as unsafe has been done in the sql/sql_parse.cc instead of sql/sql_yacc.cc, because while parsing for a token has been done we cannot be sure if the parsing of the other tokens has been done as well. Six new warning messages has been added for each unsafe statement. binlog.binlog_unsafe.test has been updated to incoporate these additional unsafe statments.
This commit is contained in:
@ -2386,6 +2386,19 @@ case SQLCOM_PREPARE:
|
||||
{
|
||||
select_result *result;
|
||||
|
||||
/*
|
||||
CREATE TABLE...IGNORE/REPLACE SELECT... can be unsafe, unless
|
||||
ORDER BY PRIMARY KEY clause is used in SELECT statement. We therefore
|
||||
use row based logging if mixed or row based logging is available.
|
||||
TODO: Check if the order of the output of the select statement is
|
||||
deterministic. Waiting for BUG#42415
|
||||
*/
|
||||
if(lex->ignore)
|
||||
lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_CREATE_IGNORE_SELECT);
|
||||
|
||||
if(lex->duplicates == DUP_REPLACE)
|
||||
lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_CREATE_REPLACE_SELECT);
|
||||
|
||||
/*
|
||||
If:
|
||||
a) we inside an SP and there was NAME_CONST substitution,
|
||||
@ -2720,6 +2733,16 @@ end_with_restore_list:
|
||||
DBUG_ASSERT(first_table == all_tables && first_table != 0);
|
||||
if (update_precheck(thd, all_tables))
|
||||
break;
|
||||
|
||||
/*
|
||||
UPDATE IGNORE can be unsafe. We therefore use row based
|
||||
logging if mixed or row based logging is available.
|
||||
TODO: Check if the order of the output of the select statement is
|
||||
deterministic. Waiting for BUG#42415
|
||||
*/
|
||||
if (lex->ignore)
|
||||
lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_UPDATE_IGNORE);
|
||||
|
||||
DBUG_ASSERT(select_lex->offset_limit == 0);
|
||||
unit->set_limit(select_lex);
|
||||
MYSQL_UPDATE_START(thd->query());
|
||||
@ -2886,6 +2909,23 @@ end_with_restore_list:
|
||||
DBUG_ASSERT(first_table == all_tables && first_table != 0);
|
||||
if ((res= insert_precheck(thd, all_tables)))
|
||||
break;
|
||||
/*
|
||||
INSERT...SELECT...ON DUPLICATE KEY UPDATE/REPLACE SELECT/
|
||||
INSERT...IGNORE...SELECT can be unsafe, unless ORDER BY PRIMARY KEY
|
||||
clause is used in SELECT statement. We therefore use row based
|
||||
logging if mixed or row based logging is available.
|
||||
TODO: Check if the order of the output of the select statement is
|
||||
deterministic. Waiting for BUG#42415
|
||||
*/
|
||||
if (lex->sql_command == SQLCOM_INSERT_SELECT &&
|
||||
lex->duplicates == DUP_UPDATE)
|
||||
lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_INSERT_SELECT_UPDATE);
|
||||
|
||||
if (lex->sql_command == SQLCOM_INSERT_SELECT && lex->ignore)
|
||||
lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_INSERT_IGNORE_SELECT);
|
||||
|
||||
if (lex->sql_command == SQLCOM_REPLACE_SELECT)
|
||||
lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_REPLACE_SELECT);
|
||||
|
||||
/* Fix lock for first table */
|
||||
if (first_table->lock_type == TL_WRITE_DELAYED)
|
||||
|
Reference in New Issue
Block a user