summaryrefslogtreecommitdiff
path: root/sql/sql_class.cc
diff options
context:
space:
mode:
authorNuno Carvalho <nuno.carvalho@oracle.com>2012-11-14 17:17:14 +0000
committerNuno Carvalho <nuno.carvalho@oracle.com>2012-11-14 17:17:14 +0000
commitc09787bef81059dc45cf88aa261d0b53d4f6f142 (patch)
treee5390647eea1ee5db19d5a3c9ab6902885ceddb5 /sql/sql_class.cc
parentd075f0fab72d40ca324285d3bedcdc43bbe06339 (diff)
downloadmariadb-git-c09787bef81059dc45cf88aa261d0b53d4f6f142.tar.gz
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.
Diffstat (limited to 'sql/sql_class.cc')
-rw-r--r--sql/sql_class.cc13
1 files changed, 13 insertions, 0 deletions
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)
{