diff options
author | Nuno Carvalho <nuno.carvalho@oracle.com> | 2012-11-14 17:17:14 +0000 |
---|---|---|
committer | Nuno Carvalho <nuno.carvalho@oracle.com> | 2012-11-14 17:17:14 +0000 |
commit | c09787bef81059dc45cf88aa261d0b53d4f6f142 (patch) | |
tree | e5390647eea1ee5db19d5a3c9ab6902885ceddb5 /sql/sql_class.cc | |
parent | d075f0fab72d40ca324285d3bedcdc43bbe06339 (diff) | |
download | mariadb-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.cc | 13 |
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) { |