From c09787bef81059dc45cf88aa261d0b53d4f6f142 Mon Sep 17 00:00:00 2001 From: Nuno Carvalho Date: Wed, 14 Nov 2012 17:17:14 +0000 Subject: [PATCH] BUG#12669186: AUTOINC VALUE PERSISTENCY BREAKS CERTAIN REPLICATION SCENARIOS When master and slave have different schemas, in particular different AUTO_INCREMENT columns, INSERT_ID events logged for a given table on master may be applied to a different table on slave on SBR, e.g.: master has one table (t1) with one auto-inc column and another table (t2) without auto-inc column, on slave t1 does not have auto-inc column (despite having the same columns) and t2 has a auto-inc column. The INSERT_ID that is intended for t1, since t1 on slave doesn't have auto-inc column is used on t2, causing consistency problems. To fix this incorrect behaviour, auto-inc interval allocation via INSERT_ID is made effectively terminated at the end of top-level statements on slave and binlog replay. --- sql/sql_class.cc | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 9b0a76bf749..ff7f2340ac0 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1693,6 +1693,19 @@ void THD::cleanup_after_query() stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0; auto_inc_intervals_in_cur_stmt_for_binlog.empty(); rand_used= 0; +#ifndef EMBEDDED_LIBRARY + /* + Clean possible unused INSERT_ID events by current statement. + is_update_query() is needed to ignore SET statements: + Statements that don't update anything directly and don't + used stored functions. This is mostly necessary to ignore + statements in binlog between SET INSERT_ID and DML statement + which is intended to consume its event (there can be other + SET statements between them). + */ + if ((rli_slave || rli_fake) && is_update_query(lex->sql_command)) + auto_inc_intervals_forced.empty(); +#endif } if (first_successful_insert_id_in_cur_stmt > 0) {