1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

BUG#11765650 - 58637: MARK UPDATES THAT DEPEND ON ORDER OF TWO KEYS UNSAFE

Description: When the table has more than one unique or primary key, 
 INSERT... ON DUP KEY UPDATE statement is sensitive to the order in which
 the storage engines checks the keys. Depending on this order, the storage
 engine may determine different rows to mysql, and hence mysql can update
 different rows on master and slave.
      
 Solution: We mark INSERT...ON DUP KEY UPDATE on a table with more than on unique
 key as unsafe therefore the event will be logged in row format if it is available
 (ROW/MIXED). If only STATEMENT format is available, a warning will be thrown.
This commit is contained in:
Rohit Kalhans
2012-03-30 18:35:53 +05:30
parent 3865ce52e9
commit fe9352454f
7 changed files with 55 additions and 1 deletions

View File

@ -5691,6 +5691,30 @@ bool lock_tables(THD *thd, TABLE_LIST *tables, uint count,
has_write_table_with_auto_increment_and_select(tables))
thd->lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_WRITE_AUTOINC_SELECT);
/*
INSERT...ON DUPLICATE KEY UPDATE on a table with more than one unique keys
can be unsafe.
*/
uint unique_keys= 0;
for (TABLE_LIST *query_table= tables; query_table && unique_keys <= 1;
query_table= query_table->next_global)
if(query_table->table)
{
uint keys= query_table->table->s->keys, i= 0;
unique_keys= 0;
for (KEY* keyinfo= query_table->table->s->key_info;
i < keys && unique_keys <= 1; i++, keyinfo++)
{
if (keyinfo->flags & HA_NOSAME)
unique_keys++;
}
if (!query_table->placeholder() &&
query_table->lock_type >= TL_WRITE_ALLOW_WRITE &&
unique_keys > 1 && thd->lex->sql_command == SQLCOM_INSERT &&
thd->lex->duplicates == DUP_UPDATE)
thd->lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_INSERT_TWO_KEYS);
}
/* We have to emulate LOCK TABLES if we are statement needs prelocking. */
if (thd->lex->requires_prelocking())
{