mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Merge kindahl-laptop.dnsalias.net:/home/bkroot/mysql-5.1-rpl
into kindahl-laptop.dnsalias.net:/home/bk/b19958-mysql-5.1-rpl sql/log_event.cc: Auto merged
This commit is contained in:
71
mysql-test/suite/rpl/r/rpl_idempotency.result
Normal file
71
mysql-test/suite/rpl/r/rpl_idempotency.result
Normal file
@ -0,0 +1,71 @@
|
||||
stop slave;
|
||||
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||
reset master;
|
||||
reset slave;
|
||||
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||
start slave;
|
||||
CREATE TABLE t1 (a INT PRIMARY KEY);
|
||||
CREATE TABLE t2 (a INT);
|
||||
INSERT INTO t1 VALUES (-1),(-2),(-3);
|
||||
INSERT INTO t2 VALUES (-1),(-2),(-3);
|
||||
DELETE FROM t1 WHERE a = -2;
|
||||
DELETE FROM t2 WHERE a = -2;
|
||||
DELETE FROM t1 WHERE a = -2;
|
||||
DELETE FROM t2 WHERE a = -2;
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
a
|
||||
-3
|
||||
-1
|
||||
SELECT * FROM t2 ORDER BY a;
|
||||
a
|
||||
-3
|
||||
-1
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
a
|
||||
-3
|
||||
-1
|
||||
SELECT * FROM t2 ORDER BY a;
|
||||
a
|
||||
-3
|
||||
-1
|
||||
Last_SQL_Error
|
||||
0
|
||||
INSERT IGNORE INTO t1 VALUES (-2);
|
||||
INSERT IGNORE INTO t1 VALUES (-2);
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
a
|
||||
-3
|
||||
-2
|
||||
-1
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
a
|
||||
-3
|
||||
-2
|
||||
-1
|
||||
Last_SQL_Error
|
||||
0
|
||||
UPDATE t1 SET a = 1 WHERE a = -1;
|
||||
UPDATE t2 SET a = 1 WHERE a = -1;
|
||||
UPDATE t1 SET a = 1 WHERE a = -1;
|
||||
UPDATE t2 SET a = 1 WHERE a = -1;
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
a
|
||||
-3
|
||||
-2
|
||||
1
|
||||
SELECT * FROM t2 ORDER BY a;
|
||||
a
|
||||
-3
|
||||
1
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
a
|
||||
-3
|
||||
-2
|
||||
1
|
||||
SELECT * FROM t2 ORDER BY a;
|
||||
a
|
||||
-3
|
||||
1
|
||||
Last_SQL_Error
|
||||
0
|
||||
DROP TABLE t1, t2;
|
79
mysql-test/suite/rpl/t/rpl_idempotency.test
Normal file
79
mysql-test/suite/rpl/t/rpl_idempotency.test
Normal file
@ -0,0 +1,79 @@
|
||||
# Testing various forms of idempotency for replication that should
|
||||
# work the same way under statement based as under row based.
|
||||
|
||||
source include/master-slave.inc;
|
||||
|
||||
connection master;
|
||||
CREATE TABLE t1 (a INT PRIMARY KEY);
|
||||
CREATE TABLE t2 (a INT);
|
||||
INSERT INTO t1 VALUES (-1),(-2),(-3);
|
||||
INSERT INTO t2 VALUES (-1),(-2),(-3);
|
||||
sync_slave_with_master;
|
||||
|
||||
# A delete for a row that does not exist, the statement is
|
||||
# deliberately written to be idempotent for statement-based
|
||||
# replication as well. We test this towards both a table with a
|
||||
# primary key and without a primary key.
|
||||
|
||||
connection slave;
|
||||
DELETE FROM t1 WHERE a = -2;
|
||||
DELETE FROM t2 WHERE a = -2;
|
||||
connection master;
|
||||
DELETE FROM t1 WHERE a = -2;
|
||||
DELETE FROM t2 WHERE a = -2;
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
SELECT * FROM t2 ORDER BY a;
|
||||
sync_slave_with_master;
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
SELECT * FROM t2 ORDER BY a;
|
||||
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1);
|
||||
disable_query_log;
|
||||
eval SELECT "$last_error" AS Last_SQL_Error;
|
||||
enable_query_log;
|
||||
|
||||
# An insert of a row that already exists. Since we are replacing the
|
||||
# row if it already exists, the most apropriate representation is
|
||||
# INSERT IGNORE. We only test this towards a table with a primary key,
|
||||
# since the other case does not make sense.
|
||||
|
||||
INSERT IGNORE INTO t1 VALUES (-2);
|
||||
connection master;
|
||||
INSERT IGNORE INTO t1 VALUES (-2);
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
sync_slave_with_master;
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1);
|
||||
disable_query_log;
|
||||
eval SELECT "$last_error" AS Last_SQL_Error;
|
||||
enable_query_log;
|
||||
|
||||
# BUG#19958: RBR idempotency issue for UPDATE and DELETE
|
||||
|
||||
# Statement-based and row-based replication have different behaviour
|
||||
# when updating a row with an explicit WHERE-clause that matches
|
||||
# exactly one row (or no row at all). For statement-based replication,
|
||||
# the statement is idempotent since the first time it is executed, it
|
||||
# will update exactly one row, and the second time it will not update
|
||||
# any row at all. This was not the case for row-based replication, so
|
||||
# we test under both row-based and statement-based replication both
|
||||
# for tables with and without primary keys.
|
||||
|
||||
connection slave;
|
||||
UPDATE t1 SET a = 1 WHERE a = -1;
|
||||
UPDATE t2 SET a = 1 WHERE a = -1;
|
||||
connection master;
|
||||
UPDATE t1 SET a = 1 WHERE a = -1;
|
||||
UPDATE t2 SET a = 1 WHERE a = -1;
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
SELECT * FROM t2 ORDER BY a;
|
||||
sync_slave_with_master;
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
SELECT * FROM t2 ORDER BY a;
|
||||
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1);
|
||||
disable_query_log;
|
||||
eval SELECT "$last_error" AS Last_SQL_Error;
|
||||
enable_query_log;
|
||||
|
||||
connection master;
|
||||
DROP TABLE t1, t2;
|
||||
sync_slave_with_master;
|
@ -36,6 +36,63 @@
|
||||
|
||||
#define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
static const char *HA_ERR(int i)
|
||||
{
|
||||
switch (i) {
|
||||
case HA_ERR_KEY_NOT_FOUND: return "HA_ERR_KEY_NOT_FOUND";
|
||||
case HA_ERR_FOUND_DUPP_KEY: return "HA_ERR_FOUND_DUPP_KEY";
|
||||
case HA_ERR_RECORD_CHANGED: return "HA_ERR_RECORD_CHANGED";
|
||||
case HA_ERR_WRONG_INDEX: return "HA_ERR_WRONG_INDEX";
|
||||
case HA_ERR_CRASHED: return "HA_ERR_CRASHED";
|
||||
case HA_ERR_WRONG_IN_RECORD: return "HA_ERR_WRONG_IN_RECORD";
|
||||
case HA_ERR_OUT_OF_MEM: return "HA_ERR_OUT_OF_MEM";
|
||||
case HA_ERR_NOT_A_TABLE: return "HA_ERR_NOT_A_TABLE";
|
||||
case HA_ERR_WRONG_COMMAND: return "HA_ERR_WRONG_COMMAND";
|
||||
case HA_ERR_OLD_FILE: return "HA_ERR_OLD_FILE";
|
||||
case HA_ERR_NO_ACTIVE_RECORD: return "HA_ERR_NO_ACTIVE_RECORD";
|
||||
case HA_ERR_RECORD_DELETED: return "HA_ERR_RECORD_DELETED";
|
||||
case HA_ERR_RECORD_FILE_FULL: return "HA_ERR_RECORD_FILE_FULL";
|
||||
case HA_ERR_INDEX_FILE_FULL: return "HA_ERR_INDEX_FILE_FULL";
|
||||
case HA_ERR_END_OF_FILE: return "HA_ERR_END_OF_FILE";
|
||||
case HA_ERR_UNSUPPORTED: return "HA_ERR_UNSUPPORTED";
|
||||
case HA_ERR_TO_BIG_ROW: return "HA_ERR_TO_BIG_ROW";
|
||||
case HA_WRONG_CREATE_OPTION: return "HA_WRONG_CREATE_OPTION";
|
||||
case HA_ERR_FOUND_DUPP_UNIQUE: return "HA_ERR_FOUND_DUPP_UNIQUE";
|
||||
case HA_ERR_UNKNOWN_CHARSET: return "HA_ERR_UNKNOWN_CHARSET";
|
||||
case HA_ERR_WRONG_MRG_TABLE_DEF: return "HA_ERR_WRONG_MRG_TABLE_DEF";
|
||||
case HA_ERR_CRASHED_ON_REPAIR: return "HA_ERR_CRASHED_ON_REPAIR";
|
||||
case HA_ERR_CRASHED_ON_USAGE: return "HA_ERR_CRASHED_ON_USAGE";
|
||||
case HA_ERR_LOCK_WAIT_TIMEOUT: return "HA_ERR_LOCK_WAIT_TIMEOUT";
|
||||
case HA_ERR_LOCK_TABLE_FULL: return "HA_ERR_LOCK_TABLE_FULL";
|
||||
case HA_ERR_READ_ONLY_TRANSACTION: return "HA_ERR_READ_ONLY_TRANSACTION";
|
||||
case HA_ERR_LOCK_DEADLOCK: return "HA_ERR_LOCK_DEADLOCK";
|
||||
case HA_ERR_CANNOT_ADD_FOREIGN: return "HA_ERR_CANNOT_ADD_FOREIGN";
|
||||
case HA_ERR_NO_REFERENCED_ROW: return "HA_ERR_NO_REFERENCED_ROW";
|
||||
case HA_ERR_ROW_IS_REFERENCED: return "HA_ERR_ROW_IS_REFERENCED";
|
||||
case HA_ERR_NO_SAVEPOINT: return "HA_ERR_NO_SAVEPOINT";
|
||||
case HA_ERR_NON_UNIQUE_BLOCK_SIZE: return "HA_ERR_NON_UNIQUE_BLOCK_SIZE";
|
||||
case HA_ERR_NO_SUCH_TABLE: return "HA_ERR_NO_SUCH_TABLE";
|
||||
case HA_ERR_TABLE_EXIST: return "HA_ERR_TABLE_EXIST";
|
||||
case HA_ERR_NO_CONNECTION: return "HA_ERR_NO_CONNECTION";
|
||||
case HA_ERR_NULL_IN_SPATIAL: return "HA_ERR_NULL_IN_SPATIAL";
|
||||
case HA_ERR_TABLE_DEF_CHANGED: return "HA_ERR_TABLE_DEF_CHANGED";
|
||||
case HA_ERR_NO_PARTITION_FOUND: return "HA_ERR_NO_PARTITION_FOUND";
|
||||
case HA_ERR_RBR_LOGGING_FAILED: return "HA_ERR_RBR_LOGGING_FAILED";
|
||||
case HA_ERR_DROP_INDEX_FK: return "HA_ERR_DROP_INDEX_FK";
|
||||
case HA_ERR_FOREIGN_DUPLICATE_KEY: return "HA_ERR_FOREIGN_DUPLICATE_KEY";
|
||||
case HA_ERR_TABLE_NEEDS_UPGRADE: return "HA_ERR_TABLE_NEEDS_UPGRADE";
|
||||
case HA_ERR_TABLE_READONLY: return "HA_ERR_TABLE_READONLY";
|
||||
case HA_ERR_AUTOINC_READ_FAILED: return "HA_ERR_AUTOINC_READ_FAILED";
|
||||
case HA_ERR_AUTOINC_ERANGE: return "HA_ERR_AUTOINC_ERANGE";
|
||||
case HA_ERR_GENERIC: return "HA_ERR_GENERIC";
|
||||
case HA_ERR_RECORD_IS_THE_SAME: return "HA_ERR_RECORD_IS_THE_SAME";
|
||||
case HA_ERR_LOGGING_IMPOSSIBLE: return "HA_ERR_LOGGING_IMPOSSIBLE";
|
||||
case HA_ERR_CORRUPT_EVENT: return "HA_ERR_CORRUPT_EVENT";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
Cache that will automatically be written to a dedicated file on
|
||||
destruction.
|
||||
@ -6254,8 +6311,11 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
|
||||
|
||||
/* Some recoverable errors */
|
||||
case HA_ERR_RECORD_CHANGED:
|
||||
case HA_ERR_KEY_NOT_FOUND: /* Idempotency support: OK if
|
||||
tuple does not exist */
|
||||
case HA_ERR_RECORD_DELETED:
|
||||
case HA_ERR_KEY_NOT_FOUND:
|
||||
case HA_ERR_END_OF_FILE:
|
||||
/* Idempotency support: OK if tuple does not exist */
|
||||
DBUG_PRINT("info", ("error: %s", HA_ERR(error)));
|
||||
error= 0;
|
||||
break;
|
||||
|
||||
@ -7493,6 +7553,9 @@ static bool record_compare(TABLE *table)
|
||||
records. Check that the other engines also return correct records.
|
||||
*/
|
||||
|
||||
DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
|
||||
DBUG_DUMP("record[1]", table->record[1], table->s->reclength);
|
||||
|
||||
bool result= FALSE;
|
||||
uchar saved_x[2], saved_filler[2];
|
||||
|
||||
@ -7581,7 +7644,7 @@ record_compare_exit:
|
||||
|
||||
int Rows_log_event::find_row(const Relay_log_info *rli)
|
||||
{
|
||||
DBUG_ENTER("find_row");
|
||||
DBUG_ENTER("Rows_log_event::find_row");
|
||||
|
||||
DBUG_ASSERT(m_table && m_table->in_use != NULL);
|
||||
|
||||
@ -7810,7 +7873,7 @@ int Rows_log_event::find_row(const Relay_log_info *rli)
|
||||
DBUG_DUMP("record found", table->record[0], table->s->reclength);
|
||||
table->file->ha_rnd_end();
|
||||
|
||||
DBUG_ASSERT(error == HA_ERR_END_OF_FILE || error == 0);
|
||||
DBUG_ASSERT(error == HA_ERR_END_OF_FILE || error == HA_ERR_RECORD_DELETED || error == 0);
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user