List:Commits« Previous MessageNext Message »
From:Andrei Elkin Date:October 30 2007 8:00pm
Subject:Re: bk commit into 5.1 tree (mats:1.2582) BUG#19958
View as plain text  
Mats, hej.

The patch is okay.

I only would like you to rephrase  comments and update the cset's
synopsis

Bug #19958  	RBR idempotency issue for UPDATE and DELETE

> Below is the list of changes that have just been committed into a local
> 5.1 repository of mats. When mats does a push these changes will
> be propagated to the main repository and, within 24 hours after the
> push, to the public repository.
> For information on how to access the public repository
> see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
>
> ChangeSet@stripped, 2007-10-26 09:32:25+02:00, mats@stripped +3 -0
>   BUG#19958 (rpl_trigger.test causes Error in Update_rows event when used with RBR):
>   
>   The rpl_trigger test case indicated a problem with idempotency support when run
>   under row-based replication, which this patch fixes.
>   
>   However, despite this, the test is not designed for execution under row-based
>   replication and hence rpl_trigger.test is not executed under row-based
>   replication.
>   
>   The problem is that the test expects triggers to be executed when the slave
>   updates rows on the slave, and this is (deliberately) not done with row-based
>   replication.
>
>   mysql-test/suite/rpl/r/rpl_idempotency.result@stripped, 2007-10-26 09:32:21+02:00,
> mats@stripped +71 -0
>     New BitKeeper file ``mysql-test/suite/rpl/r/rpl_idempotency.result''
>
>   mysql-test/suite/rpl/r/rpl_idempotency.result@stripped, 2007-10-26 09:32:21+02:00,
> mats@stripped +0 -0
>
>   mysql-test/suite/rpl/t/rpl_idempotency.test@stripped, 2007-10-26 09:32:21+02:00,
> mats@stripped +76 -0
>     New BitKeeper file ``mysql-test/suite/rpl/t/rpl_idempotency.test''
>
>   mysql-test/suite/rpl/t/rpl_idempotency.test@stripped, 2007-10-26 09:32:21+02:00,
> mats@stripped +0 -0
>
>   sql/log_event.cc@stripped, 2007-10-26 09:32:21+02:00, mats@stripped
> +67 -4
>     Adding function to print symbolic name of handler errors for debug purposes.
>     Ignoring some more error messages to provide full idempotency support for
>     update and delete operations.
>
> diff -Nrup a/mysql-test/suite/rpl/r/rpl_idempotency.result
> b/mysql-test/suite/rpl/r/rpl_idempotency.result
> --- /dev/null	Wed Dec 31 16:00:00 196900
> +++ b/mysql-test/suite/rpl/r/rpl_idempotency.result	2007-10-26 09:32:21 +02:00
> @@ -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;
> diff -Nrup a/mysql-test/suite/rpl/t/rpl_idempotency.test
> b/mysql-test/suite/rpl/t/rpl_idempotency.test
> --- /dev/null	Wed Dec 31 16:00:00 196900
> +++ b/mysql-test/suite/rpl/t/rpl_idempotency.test	2007-10-26 09:32:21 +02:00
> @@ -0,0 +1,76 @@
> +# 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: rpl_trigger.test causes Error in Update_rows event when
> +# used with RBR.
> +
> +# This test case caused different behaviour in the following
> +# situation, but statement-based and row-based should do the same
> +# thing in this case. We test this both for tables with and without
> +# primary keys.

Could you please change this. It's hard to read. "caused different
behaviour in the following situation" - where is the situation?


> +
> +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;
> diff -Nrup a/sql/log_event.cc b/sql/log_event.cc
> --- a/sql/log_event.cc	2007-10-24 16:54:11 +02:00
> +++ b/sql/log_event.cc	2007-10-26 09:32:21 +02:00
> @@ -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.
> @@ -6228,8 +6285,11 @@ int Rows_log_event::do_apply_event(Relay
>  
>        /* 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;
>  
> @@ -7467,6 +7527,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];
>  
> @@ -7555,7 +7618,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);
>  
> @@ -7784,7 +7847,7 @@ int Rows_log_event::find_row(const Relay
>        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);
>    }
>  
>
> -- 
> MySQL Code Commits Mailing List
> For list archives: http://lists.mysql.com/commits
> To unsubscribe:    http://lists.mysql.com/commits?unsub=1
>

regards,

Andrei
Thread
bk commit into 5.1 tree (mats:1.2582) BUG#19958Mats Kindahl26 Oct
  • Re: bk commit into 5.1 tree (mats:1.2582) BUG#19958Andrei Elkin30 Oct