Bug #50917 | slave stops with HA_ERR_KEY_NOT_FOUND | ||
---|---|---|---|
Submitted: | 4 Feb 2010 15:23 | Modified: | 3 Dec 2010 12:19 |
Reporter: | Matthias Leich | Email Updates: | |
Status: | Verified | Impact on me: | |
Category: | MySQL Server: Replication | Severity: | S3 (Non-critical) |
Version: | 5.1.43,5.5.2-m2 | OS: | Any |
Assigned to: | Assigned Account | CPU Architecture: | Any |
Tags: | auto_increment |
[4 Feb 2010 15:23]
Matthias Leich
[6 Dec 2010 17:17]
Luis Soares
Here is an improved test case: --source include/master-slave.inc CREATE TABLE t1 ( pk int auto_increment, col1 tinyint, primary key (pk)); CREATE TABLE t2 ( pk int auto_increment, col1 tinyint, primary key (pk)); SET session sql_auto_is_null=1; -- let $val= 1 -- eval INSERT INTO t1 VALUES ( $val + 1, 0) -- eval INSERT INTO t2 VALUES ( $val, 0) INSERT INTO t2 VALUES ( NULL, 1); SET SESSION BINLOG_FORMAT = STATEMENT ; UPDATE t1 SET pk = col1 WHERE pk IS NULL; -- sync_slave_with_master -- let $diff_table_1=master:test.t1 -- let $diff_table_2=slave:test.t1 -- source include/diff_tables.inc -- connection master SET SESSION BINLOG_FORMAT = ROW; UPDATE t1 SET col1 = 1; --sync_slave_with_master -- let $diff_table_1=master:test.t1 -- let $diff_table_2=slave:test.t1 -- source include/diff_tables.inc -- connection master # Cleanup DROP TABLE t1; DROP TABLE t2; --sync_slave_with_master -- exit ANALYSIS ======== Considering the test case posted above... Description ----------- When sql_auto_is_null=1 the statement: - UPDATE t1 SET pk = col1 WHERE pk IS NULL; makes the master to update the row on t1. The slave however, does not update any row, because it has no context in auto_inc values. In detail, the three INSERTs before this update are replicated using ROW format, while the UPDATE is replicated using STMT format. Consequently, the slave actually inserts the value the master has generated for the second row for t2 INSERT, and not the NULL value as the master does. From the slave standpoint, there is no NULL values involved so far for the events it has processed (which is not true for the master). As a consequence, when the slave processes the UPDATE with "pk IS NULL" clause, it will not update any row, because there is no context referring to auto_inc columns and IS NULL. If obscure, see [1]. NOTE: At this point table t1 diverge on master and slave. Later when the second UPDATE is replicated (this one in ROW format) the before image contained in the UPDATE_ROWS_EVENT will not match any of the rows on the slave's table, because they have diverged... This makes the second update to not find any row and fail with HA_ERR_KEY_NOT_FOUND. The case for 5.5+ ----------------- In 5.5.3, the default value for sql_auto_is_null was changed from 1 to 0. This makes the test case pass. However, when set to 1, the test fails for the reason outlined in the previous section. Conclusion ---------- This is a very obscure combinations of factors here: - the special and non-intuitive case for sql_auto_is_null=1 [1], which is not the default anymore as of 5.5.3; - the fact that replication events are limited, ie, do not carry all information and re-create all master server context. - the exceptional case for interchanging STMT and ROW format and its interaction with sql_auto_is_null=1. All of this playing together makes replication break. REFERENCES ========== [1] http://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_sql_auto_is_nul...