List:Commits« Previous MessageNext Message »
From:Alfranio Correia Date:April 20 2010 4:33pm
Subject:Re: bzr commit into mysql-5.1-rpl-wl5092 branch (luis.soares:3186)
Bug#49100
View as plain text  
Hi Luis,

Not approved.

The code seems ok but we need to improve the comments and clarify
some points. See comments in-line

Cheers.

Luis Soares wrote:
> #At file:///home/lsoares/Workspace/bzr/work/features/wl5092/mysql-5.1-rpl-wl5092/
> based on revid:luis.soares@stripped
> 
>  3186 Luis Soares	2010-03-31
>       BUG#49100: RBR: Unexpected behavior when AI contains no usable
>                  data for slave columns
>       
>       RBR was not fully compliant with empty before and after
>       images (BI and AI) in row events. Several faulty scenarios
>       surfaced during WL#5092 implementation, especially when MINIMAL
>       images were used:
>       
>         S1. Inserting an empty row on the master would cause slave to
>             skip the event (empty AI);
>       
>             Expected: slave(s) shall apply the insert and fill its
>             table with default values as master did.
>       
>         S2. Master inserts values just for columns that slave doesn't
>             have (unusable AI at the slave). 

Please, describe what was the bug. Most likely, it is equivalent to S1
but it is better to make this clear.


>       
>             Expected: slave(s) shall apply the insert and fill its
>             table with default values as master did for columns that
>             user did not provide data.
>        
>         S3. Master updates columns that only it knows about (unusable
>             AI at the slave) but references columns that it shares with
>             the slave (usable BI at the slave). This would trigger an
>             assertion on a third slave in chained replication: m -> s1
>             -> s2, s2 would abort.
>       
>             Expected: slave s1 shall not update any row and slave s2
>             shall not assert.
>       
>         S4. Master updates and references columns that only it knows
>             about (unusable AI and BI at the slave).


The same here. See above.

>       
>             Expected: slave(s) shall skip the event and not update its
>             tables with any value.
>       
>         S5. Master references columns that only it knows
>             about (unusable BI at the slave) and updates columns shared
>             with the slave (usable AI at the slave). Slave must stop.
>       

What was the error before the patch?

>             Expected: slave(s) shall fail with HA_ERR_END_OF_FILE.
>       
>       We fix S1 to S5 by relaxing some asserts that were triggered on
>       when processing empty images. Additionally, on the
>       Update_rows_log_event::do_exec_row we deployed a check the
>       verifies if there is any value for AI. If there is not, then the
>       event is skipped (neither BI nor AI is are processed).

Are S3 and S4 only about asserts? I don't think so. Please, update the summary of
the solutions.

>       
>       For mysqlbinlog --verbose --base64=decode-rows we print out an
>       INSERT INTO t VALUES () when a write rows event contains an
>       empty AI.

ok.

>      @ mysql-test/suite/rpl/r/rpl_row_img.result
>         Updates to result files.
>      @ mysql-test/suite/rpl/t/rpl_row_img.test
>         Added test cases.
>      @ sql/log_event.cc
>         1. Added printout for INSERT INTO ... VALUES () when AI is empty for
>            Write_rows_log_events.
>         2. Changed assertion from 'm_curr_row < ...' to 'm_curr_row <= ...'
>         3. Calculation of estimated rows for bulk insert is now conditional,
>            and dependent of whether m_curr_row < m_rows_end or not.
>         4. In the Update_rows_log_event, changed it to take into consideration
>            if there are any values in AI. If there are not, then skip event.
>      @ sql/log_event.h
>         Changed assertion to from 'm_curr_row < ...' to ' m_curr_row <= ...'
>      @ sql/rpl_record.cc
>         Do not unpack if master did not send any bit set in the write_set.
> 
>     modified:
>       mysql-test/suite/rpl/r/rpl_row_img.result
>       mysql-test/suite/rpl/t/rpl_row_img.test
>       sql/log_event.cc
>       sql/log_event.h
>       sql/rpl_record.cc
> === modified file 'mysql-test/suite/rpl/r/rpl_row_img.result'
> --- a/mysql-test/suite/rpl/r/rpl_row_img.result	2010-03-30 16:06:36 +0000
> +++ b/mysql-test/suite/rpl/r/rpl_row_img.result	2010-03-30 23:19:25 +0000
> @@ -24179,3 +24179,259 @@ FLUSH TABLES;
>  SHOW VARIABLES LIKE 'binlog_row_image';
>  Variable_name	Value
>  binlog_row_image	FULL
> +include/stop_slave.inc
> +RESET MASTER;
> +RESET SLAVE;
> +include/stop_slave.inc
> +RESET MASTER;
> +RESET SLAVE;
> +RESET MASTER;
> +RESET SLAVE;
> +include/start_slave.inc
> +include/start_slave.inc
> +DROP TABLE IF EXISTS t1;
> +CON: 'mysqld_a', IMG: 'MINIMAL', RESTART SLAVE: 'N'
> +SET SESSION binlog_row_image= 'MINIMAL';
> +SET GLOBAL binlog_row_image= 'MINIMAL';
> +FLUSH TABLES;
> +SHOW VARIABLES LIKE 'binlog_row_image';
> +Variable_name	Value
> +binlog_row_image	MINIMAL
> +CON: 'mysqld_b', IMG: 'MINIMAL', RESTART SLAVE: 'Y'
> +SET SESSION binlog_row_image= 'MINIMAL';
> +SET GLOBAL binlog_row_image= 'MINIMAL';
> +include/stop_slave.inc
> +include/start_slave.inc
> +FLUSH TABLES;
> +SHOW VARIABLES LIKE 'binlog_row_image';
> +Variable_name	Value
> +binlog_row_image	MINIMAL
> +CON: 'mysqld_c', IMG: 'MINIMAL', RESTART SLAVE: 'Y'
> +SET SESSION binlog_row_image= 'MINIMAL';
> +SET GLOBAL binlog_row_image= 'MINIMAL';
> +include/stop_slave.inc
> +include/start_slave.inc
> +FLUSH TABLES;
> +SHOW VARIABLES LIKE 'binlog_row_image';
> +Variable_name	Value
> +binlog_row_image	MINIMAL
> +#### case #1: AI: no values logged
> +CREATE TABLE t1 (c1 int DEFAULT 100);
> +INSERT INTO t1 VALUES ();
> +SHOW VARIABLES LIKE 'server_id';
> +Variable_name	Value
> +server_id	1
> +SELECT * FROM t1;
> +c1
> +100
> +SHOW VARIABLES LIKE 'server_id';
> +Variable_name	Value
> +server_id	2
> +SELECT * FROM t1;
> +c1
> +100
> +SHOW VARIABLES LIKE 'server_id';
> +Variable_name	Value
> +server_id	3
> +SELECT * FROM t1;
> +c1
> +100
> +DROP TABLE t1;
> +#### case #2: AI: not empty but slave does not have usable data for its columns
> (INSERT)
> +CREATE TABLE t1 (c1 int DEFAULT 100);
> +SET SQL_LOG_BIN=0;
> +CREATE TABLE t1 (c1 int DEFAULT 100);
> +SET SQL_LOG_BIN=1;
> +SET SQL_LOG_BIN=0;
> +CREATE TABLE t1 (c1 int DEFAULT 100, c2 int, primary key(c2));
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t1(c2) VALUES (1);
> +SHOW VARIABLES LIKE 'server_id';
> +Variable_name	Value
> +server_id	1
> +SELECT * FROM t1;
> +c1	c2
> +100	1
> +SHOW VARIABLES LIKE 'server_id';
> +Variable_name	Value
> +server_id	2
> +SELECT * FROM t1;
> +c1
> +100
> +SHOW VARIABLES LIKE 'server_id';
> +Variable_name	Value
> +server_id	3
> +SELECT * FROM t1;
> +c1
> +100
> +DROP TABLE t1;
> +#### case #3: BI: usable columns on the slave, AI: no usable columns on the slave
> +CREATE TABLE t1 (c1 int DEFAULT 100);
> +SET SQL_LOG_BIN=0;
> +CREATE TABLE t1 (c1 int DEFAULT 100);
> +SET SQL_LOG_BIN=1;
> +SET SQL_LOG_BIN=0;
> +CREATE TABLE t1 (c1 int DEFAULT 100, c2 int);
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t1 VALUES (1,1);
> +SHOW VARIABLES LIKE 'server_id';
> +Variable_name	Value
> +server_id	1
> +SELECT * FROM t1;
> +c1	c2
> +1	1
> +SHOW VARIABLES LIKE 'server_id';
> +Variable_name	Value
> +server_id	2
> +SELECT * FROM t1;
> +c1
> +1
> +SHOW VARIABLES LIKE 'server_id';
> +Variable_name	Value
> +server_id	3
> +SELECT * FROM t1;
> +c1
> +1
> +UPDATE t1 SET c2=2 WHERE c1=1 AND c2=1;
> +SHOW VARIABLES LIKE 'server_id';
> +Variable_name	Value
> +server_id	1
> +SELECT * FROM t1;
> +c1	c2
> +1	2
> +SHOW VARIABLES LIKE 'server_id';
> +Variable_name	Value
> +server_id	2
> +SELECT * FROM t1;
> +c1
> +1
> +SHOW VARIABLES LIKE 'server_id';
> +Variable_name	Value
> +server_id	3
> +SELECT * FROM t1;
> +c1
> +1
> +DROP TABLE t1;
> +#### case #4: AI, BI: no usable columns on the slave (NOOP UPDATE).
> +####          
> +CREATE TABLE t1 (c1 int DEFAULT 100);
> +SET SQL_LOG_BIN=0;
> +CREATE TABLE t1 (c1 int DEFAULT 100);
> +SET SQL_LOG_BIN=1;
> +SET SQL_LOG_BIN=0;
> +CREATE TABLE t1 (c1 int DEFAULT 100, c2 int, c3 int, primary key(c2));
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t1 VALUES (1,1,1);
> +SHOW VARIABLES LIKE 'server_id';
> +Variable_name	Value
> +server_id	1
> +SELECT * FROM t1;
> +c1	c2	c3
> +1	1	1
> +SHOW VARIABLES LIKE 'server_id';
> +Variable_name	Value
> +server_id	2
> +SELECT * FROM t1;
> +c1
> +1
> +SHOW VARIABLES LIKE 'server_id';
> +Variable_name	Value
> +server_id	3
> +SELECT * FROM t1;
> +c1
> +1
> +UPDATE t1 SET c3=300 WHERE c2=1;
> +SHOW VARIABLES LIKE 'server_id';
> +Variable_name	Value
> +server_id	1
> +SELECT * FROM t1;
> +c1	c2	c3
> +1	1	300
> +SHOW VARIABLES LIKE 'server_id';
> +Variable_name	Value
> +server_id	2
> +SELECT * FROM t1;
> +c1
> +1
> +SHOW VARIABLES LIKE 'server_id';
> +Variable_name	Value
> +server_id	3
> +SELECT * FROM t1;
> +c1
> +1
> +DROP TABLE t1;
> +#### case #5: BI: no usable columns on the slave, AI: usable columns on the slave
> (slave must stop).
> +####          
> +CREATE TABLE t1 (c1 INT DEFAULT 100);
> +SET SQL_LOG_BIN=0;
> +CREATE TABLE t1 (c1 INT DEFAULT 100);
> +SET SQL_LOG_BIN=1;
> +SET SQL_LOG_BIN=0;
> +CREATE TABLE t1 (c1 INT DEFAULT 100, c2 INT PRIMARY KEY);
> +SET SQL_LOG_BIN=1;
> +INSERT INTO t1 VALUES (1,1);
> +SHOW VARIABLES LIKE 'server_id';
> +Variable_name	Value
> +server_id	1
> +SELECT * FROM t1;
> +c1	c2
> +1	1
> +SHOW VARIABLES LIKE 'server_id';
> +Variable_name	Value
> +server_id	2
> +SELECT * FROM t1;
> +c1
> +1
> +SHOW VARIABLES LIKE 'server_id';
> +Variable_name	Value
> +server_id	3
> +SELECT * FROM t1;
> +c1
> +1
> +UPDATE t1 SET c1=300 WHERE c2=1;
> +SHOW VARIABLES LIKE 'server_id';
> +Variable_name	Value
> +server_id	1
> +SELECT * FROM t1;
> +c1	c2
> +300	1
> +SET SQL_LOG_BIN=0;
> +call mtr.add_suppression("Slave: Can\'t find record in \'t1\' Error_code: 1032");
> +SET SQL_LOG_BIN=1;
> +### SLAVE STOPPED HAS EXPECTED!
> +include/stop_slave.inc
> +RESET MASTER;
> +RESET SLAVE;
> +include/stop_slave.inc
> +RESET MASTER;
> +RESET SLAVE;
> +RESET MASTER;
> +RESET SLAVE;
> +include/start_slave.inc
> +include/start_slave.inc
> +DROP TABLE IF EXISTS t1;
> +CON: 'mysqld_a', IMG: 'FULL', RESTART SLAVE: 'N'
> +SET SESSION binlog_row_image= 'FULL';
> +SET GLOBAL binlog_row_image= 'FULL';
> +FLUSH TABLES;
> +SHOW VARIABLES LIKE 'binlog_row_image';
> +Variable_name	Value
> +binlog_row_image	FULL
> +CON: 'mysqld_b', IMG: 'FULL', RESTART SLAVE: 'Y'
> +SET SESSION binlog_row_image= 'FULL';
> +SET GLOBAL binlog_row_image= 'FULL';
> +include/stop_slave.inc
> +include/start_slave.inc
> +FLUSH TABLES;
> +SHOW VARIABLES LIKE 'binlog_row_image';
> +Variable_name	Value
> +binlog_row_image	FULL
> +CON: 'mysqld_c', IMG: 'FULL', RESTART SLAVE: 'Y'
> +SET SESSION binlog_row_image= 'FULL';
> +SET GLOBAL binlog_row_image= 'FULL';
> +include/stop_slave.inc
> +include/start_slave.inc
> +FLUSH TABLES;
> +SHOW VARIABLES LIKE 'binlog_row_image';
> +Variable_name	Value
> +binlog_row_image	FULL
> 
> === modified file 'mysql-test/suite/rpl/t/rpl_row_img.test'
> --- a/mysql-test/suite/rpl/t/rpl_row_img.test	2010-03-30 16:06:36 +0000
> +++ b/mysql-test/suite/rpl/t/rpl_row_img.test	2010-03-30 23:19:25 +0000
> @@ -1,12 +1,7 @@
>  #
> -# Test Description
> -# ================
> -#  
> -#   In this file we will run tests that mix engines, indexes
> -#   and blobs.
> -#  
> -#   See WL#5096 for details.
> +# This file contains tests for WL#5096 and bug fixes. 
>  #
> +
>  -- source include/rpl_chained_3_hosts.inc
>  -- source include/have_binlog_format_row.inc
>  
> @@ -18,6 +13,18 @@
>  -- source include/have_innodb.inc
>  -- connection mysqld_a
>  
> +#
> +# WL#5096
> +#
> +#   Test Description
> +#   ================
> +# 
> +#   WL#5096 Tests.
> +# 
> +#   In this file we will run tests that mix engines, indexes
> +#   and blobs.
> +#
> +
>  -- echo ###################################################################
>  -- echo ###################################################################
>  -- echo # engines and binlog-row-image mixes                              #
> @@ -41,3 +48,247 @@
>  -- echo ###################################################################
>  -- let $row_img_test_script= extra/rpl_tests/rpl_row_img_blobs.test
>  -- source include/rpl_row_img_general_loop.inc
> +
> +#
> +# BUG#49100: RBR: Unexpected behavior when AI contains no usable data 
> +#            for slave columns
> +#
> +
> +-- connection mysqld_c
> +-- source include/stop_slave.inc
> +RESET MASTER;
> +RESET SLAVE;
> +
> +-- connection mysqld_b
> +-- source include/stop_slave.inc
> +RESET MASTER;
> +RESET SLAVE;
> +
> +-- connection mysqld_a
> +RESET MASTER;
> +RESET SLAVE;
> +
> +-- connection mysqld_c
> +-- source include/start_slave.inc
> +
> +-- connection mysqld_b
> +-- source include/start_slave.inc
> +
> +-- disable_warnings
> +DROP TABLE IF EXISTS t1;
> +-- enable_warnings
> +-- source include/rpl_chained_3_hosts_sync.inc
> +-- connection mysqld_a
> +
> +-- let $row_img_set=mysqld_a:MINIMAL:N,mysqld_b:MINIMAL:Y,mysqld_c:MINIMAL:Y
> +-- source include/rpl_row_img_set.inc
> +
> +-- echo #### case #1: AI: no values logged
> +
> +CREATE TABLE t1 (c1 int DEFAULT 100);
> +INSERT INTO t1 VALUES ();
> +SHOW VARIABLES LIKE 'server_id';
> +SELECT * FROM t1;
> +-- source include/rpl_chained_3_hosts_sync.inc
> +-- connection mysqld_b
> +SHOW VARIABLES LIKE 'server_id';
> +SELECT * FROM t1;
> +-- connection mysqld_c
> +SHOW VARIABLES LIKE 'server_id';
> +SELECT * FROM t1;
> +
> +-- connection mysqld_a
> +DROP TABLE t1;
> +-- source include/rpl_chained_3_hosts_sync.inc
> +
> +-- echo #### case #2: AI: not empty but slave does not have usable data for its
> columns (INSERT)
> +
> +-- connection mysqld_c
> +CREATE TABLE t1 (c1 int DEFAULT 100);
> +
> +-- connection mysqld_b
> +SET SQL_LOG_BIN=0;
> +CREATE TABLE t1 (c1 int DEFAULT 100);
> +SET SQL_LOG_BIN=1;
> +
> +-- connection mysqld_a
> +SET SQL_LOG_BIN=0;
> +CREATE TABLE t1 (c1 int DEFAULT 100, c2 int, primary key(c2));
> +SET SQL_LOG_BIN=1;
> +
> +INSERT INTO t1(c2) VALUES (1);
> +SHOW VARIABLES LIKE 'server_id';
> +SELECT * FROM t1;
> +-- source include/rpl_chained_3_hosts_sync.inc
> +-- connection mysqld_b
> +SHOW VARIABLES LIKE 'server_id';
> +SELECT * FROM t1;
> +-- connection mysqld_c
> +SHOW VARIABLES LIKE 'server_id';
> +SELECT * FROM t1;
> +
> +-- connection mysqld_a
> +DROP TABLE t1;
> +-- source include/rpl_chained_3_hosts_sync.inc
> +
> +-- echo #### case #3: BI: usable columns on the slave, AI: no usable columns on the
> slave
> +
> +-- connection mysqld_c
> +CREATE TABLE t1 (c1 int DEFAULT 100);
> +
> +-- connection mysqld_b
> +SET SQL_LOG_BIN=0;
> +CREATE TABLE t1 (c1 int DEFAULT 100);
> +SET SQL_LOG_BIN=1;
> +
> +-- connection mysqld_a
> +SET SQL_LOG_BIN=0;
> +CREATE TABLE t1 (c1 int DEFAULT 100, c2 int);
> +SET SQL_LOG_BIN=1;
> +
> +INSERT INTO t1 VALUES (1,1);
> +SHOW VARIABLES LIKE 'server_id';
> +SELECT * FROM t1;
> +-- source include/rpl_chained_3_hosts_sync.inc
> +-- connection mysqld_b
> +SHOW VARIABLES LIKE 'server_id';
> +SELECT * FROM t1;
> +-- connection mysqld_c
> +SHOW VARIABLES LIKE 'server_id';
> +SELECT * FROM t1;
> +
> +-- connection mysqld_a
> +UPDATE t1 SET c2=2 WHERE c1=1 AND c2=1;
> +SHOW VARIABLES LIKE 'server_id';
> +SELECT * FROM t1;
> +-- source include/rpl_chained_3_hosts_sync.inc
> +-- connection mysqld_b
> +SHOW VARIABLES LIKE 'server_id';
> +SELECT * FROM t1;
> +-- connection mysqld_c
> +SHOW VARIABLES LIKE 'server_id';
> +SELECT * FROM t1;
> +
> +-- connection mysqld_a
> +DROP TABLE t1;
> +-- source include/rpl_chained_3_hosts_sync.inc
> +
> +-- echo #### case #4: AI, BI: no usable columns on the slave (NOOP UPDATE).
> +-- echo ####          
> +
> +-- connection mysqld_c
> +CREATE TABLE t1 (c1 int DEFAULT 100);
> +
> +-- connection mysqld_b
> +SET SQL_LOG_BIN=0;
> +CREATE TABLE t1 (c1 int DEFAULT 100);
> +SET SQL_LOG_BIN=1;
> +
> +-- connection mysqld_a
> +SET SQL_LOG_BIN=0;
> +CREATE TABLE t1 (c1 int DEFAULT 100, c2 int, c3 int, primary key(c2));
> +SET SQL_LOG_BIN=1;
> +
> +INSERT INTO t1 VALUES (1,1,1);
> +SHOW VARIABLES LIKE 'server_id';
> +SELECT * FROM t1;
> +-- source include/rpl_chained_3_hosts_sync.inc
> +-- connection mysqld_b
> +SHOW VARIABLES LIKE 'server_id';
> +SELECT * FROM t1;
> +-- connection mysqld_c
> +SHOW VARIABLES LIKE 'server_id';
> +SELECT * FROM t1;
> +
> +-- connection mysqld_a
> +UPDATE t1 SET c3=300 WHERE c2=1;
> +SHOW VARIABLES LIKE 'server_id';
> +SELECT * FROM t1;
> +-- source include/rpl_chained_3_hosts_sync.inc
> +-- connection mysqld_b
> +SHOW VARIABLES LIKE 'server_id';
> +SELECT * FROM t1;
> +-- connection mysqld_c
> +SHOW VARIABLES LIKE 'server_id';
> +SELECT * FROM t1;
> +
> +-- connection mysqld_a
> +DROP TABLE t1;
> +-- source include/rpl_chained_3_hosts_sync.inc
> +
> +-- echo #### case #5: BI: no usable columns on the slave, AI: usable columns on the
> slave (slave must stop).
> +-- echo ####          
> +
> +-- connection mysqld_c
> +CREATE TABLE t1 (c1 INT DEFAULT 100);
> +
> +-- connection mysqld_b
> +SET SQL_LOG_BIN=0;
> +CREATE TABLE t1 (c1 INT DEFAULT 100);
> +SET SQL_LOG_BIN=1;
> +
> +-- connection mysqld_a
> +SET SQL_LOG_BIN=0;
> +CREATE TABLE t1 (c1 INT DEFAULT 100, c2 INT PRIMARY KEY);
> +SET SQL_LOG_BIN=1;
> +
> +INSERT INTO t1 VALUES (1,1);
> +SHOW VARIABLES LIKE 'server_id';
> +SELECT * FROM t1;
> +-- source include/rpl_chained_3_hosts_sync.inc
> +-- connection mysqld_b
> +SHOW VARIABLES LIKE 'server_id';
> +SELECT * FROM t1;
> +-- connection mysqld_c
> +SHOW VARIABLES LIKE 'server_id';
> +SELECT * FROM t1;
> +
> +-- connection mysqld_a
> +UPDATE t1 SET c1=300 WHERE c2=1;
> +SHOW VARIABLES LIKE 'server_id';
> +SELECT * FROM t1;
> +-- connection mysqld_b
> +SET SQL_LOG_BIN=0;
> +call mtr.add_suppression("Slave: Can\'t find record in \'t1\' Error_code: 1032");
> +SET SQL_LOG_BIN=1;
> +-- source include/wait_for_slave_sql_to_stop.inc
> +-- let $errno=query_get_value("show slave status", Last_SQL_Errno, 1)
> +if (`SELECT $errno <> 1032`)
> +{
> +  -- echo ### UNEXPECTED ERROR AT THE SLAVE: $errno
> +  SHOW SLAVE STATUS;
> +  -- die
> +}
> +-- echo ### SLAVE STOPPED HAS EXPECTED!
> +
> +## CLEAN UP
> +
> +-- connection mysqld_c
> +-- source include/stop_slave.inc
> +RESET MASTER;
> +RESET SLAVE;
> +
> +-- connection mysqld_b
> +-- source include/stop_slave.inc
> +RESET MASTER;
> +RESET SLAVE;
> +
> +-- connection mysqld_a
> +RESET MASTER;
> +RESET SLAVE;
> +
> +-- connection mysqld_c
> +-- source include/start_slave.inc
> +
> +-- connection mysqld_b
> +-- source include/start_slave.inc
> +
> +-- connection mysqld_a
> +-- disable_warnings
> +DROP TABLE IF EXISTS t1;
> +-- enable_warnings
> +-- source include/rpl_chained_3_hosts_sync.inc
> +
> +-- let $row_img_set=mysqld_a:FULL:N,mysqld_b:FULL:Y,mysqld_c:FULL:Y
> +-- source include/rpl_row_img_set.inc
> +
> 
> === modified file 'sql/log_event.cc'
> --- a/sql/log_event.cc	2010-03-04 17:00:32 +0000
> +++ b/sql/log_event.cc	2010-03-30 23:19:25 +0000
> @@ -1953,6 +1953,14 @@ void Rows_log_event::print_verbose(IO_CA
>      return;
>    }
>  
> +  /* If the write rows event contained no values for the AI */
> +  if ((type_code == WRITE_ROWS_EVENT) && (m_rows_buf==m_rows_end))
> +  {
> +    my_b_printf(file, "### INSERT INTO `%s`.`%s` VALUES ()\n", 
> +                      map->get_db_name(), map->get_table_name());
> +    goto end;
> +  }
> +

ok.


>    for (const uchar *value= m_rows_buf; value < m_rows_end; )
>    {
>      size_t length;
> @@ -7636,7 +7644,7 @@ int Rows_log_event::do_apply_event(Relay
>  
>      // row processing loop
>  
> -    while (error == 0 && m_curr_row < m_rows_end)
> +    while (error == 0)
>      {
>        /* in_use can have been set to NULL in close_tables_for_reopen */
>        THD* old_thd= table->in_use;
> @@ -7687,7 +7695,7 @@ int Rows_log_event::do_apply_event(Relay
>    
>        // at this moment m_curr_row_end should be set
>        DBUG_ASSERT(error || m_curr_row_end != NULL); 
> -      DBUG_ASSERT(error || m_curr_row < m_curr_row_end);
> +      DBUG_ASSERT(error || m_curr_row <= m_curr_row_end);
>        DBUG_ASSERT(error || m_curr_row_end <= m_rows_end);
>    
>        m_curr_row= m_curr_row_end;
> @@ -7695,6 +7703,9 @@ int Rows_log_event::do_apply_event(Relay
>        if (error == 0 && !transactional_table)
>          thd->transaction.all.modified_non_trans_table=
>            thd->transaction.stmt.modified_non_trans_table= TRUE;
> +
> +      if (m_curr_row == m_rows_end)
> +        break;
>      } // row processing loop

ok.

>  
>      {/**
> @@ -8695,7 +8706,11 @@ Rows_log_event::write_row(const Relay_lo
>      /* this is the first row to be inserted, we estimate the rows with
>         the size of the first row and use that value to initialize
>         storage engine for bulk insertion */
> -    ulong estimated_rows= (m_rows_end - m_curr_row) / (m_curr_row_end -
> m_curr_row);
> +    DBUG_ASSERT(!(m_curr_row > m_curr_row_end));
> +    ulong estimated_rows= 1;
> +    if (m_curr_row < m_curr_row_end)
> +      estimated_rows= (m_rows_end - m_curr_row) / (m_curr_row_end - m_curr_row);
> +


Please, rewrite it as follows:


+    if (m_curr_row < m_curr_row_end)
+      estimated_rows= (m_rows_end - m_curr_row) / (m_curr_row_end - m_curr_row);
+    else if (m_curr_row = m_curr_row_end)
+      ulong estimated_rows= 1;


It think it would be easier to read.

>      m_table->file->ha_start_bulk_insert(estimated_rows);
>    }
>    
> @@ -9665,8 +9680,34 @@ int 
>  Update_rows_log_event::do_exec_row(const Relay_log_info *const rli)
>  {
>    DBUG_ASSERT(m_table != NULL);
> +  int error= 0;
> +
> +  /* check if update contains only values (for both BI and AI)
> +     for columns that do not exist on the slave. If they do, we
> +     can just unpack the rows and return (do nothing on the local 
> +     table).
> +
> +     We can optimize and check only if there are usable values on 
> +     the AI. However, if no good values on AI but we have values 
> +     on BI, we will not be letting the slave thread to search the
> +     SE for the row. This means that we may be loosing a bit on 
> +     the safety side!
> +     
> +     After all, find_row is a consistency check as well.
> +  */

These comments are difficult to read. Please, improve them.
Does this handle S3 and S4?


> +  if (/*!is_any_column_signaled_for_table(m_table, &m_cols) &&*/ /* BI
> */
> +      !is_any_column_signaled_for_table(m_table, &m_cols_ai) /* AI */)
> +  {
> +    /* read and discard images, because they don't contain any 
> +       useful information for this server table */
> +    error = unpack_current_row(rli, &m_cols);
> +    m_curr_row= m_curr_row_end;
> +    error = error | unpack_current_row(rli, &m_cols_ai);
> +
> +    return error;
> +  }

See above.
>  
> -  int error= find_row(rli); 
> +  error= find_row(rli); 
>    if (error)
>    {
>      /*

ok.

> 
> === modified file 'sql/log_event.h'
> --- a/sql/log_event.h	2010-03-04 17:00:32 +0000
> +++ b/sql/log_event.h	2010-03-30 23:19:25 +0000
> @@ -3628,7 +3628,7 @@ protected:
>      DBUG_ASSERT(m_table);
>  
>      bool first_row= (m_curr_row == m_rows_buf);
> -    ASSERT_OR_RETURN_ERROR(m_curr_row < m_rows_end, HA_ERR_CORRUPT_EVENT);
> +    ASSERT_OR_RETURN_ERROR(m_curr_row <= m_rows_end, HA_ERR_CORRUPT_EVENT);
>      int const result= ::unpack_row(rli, m_table, m_width, m_curr_row, cols,
>                                     &m_curr_row_end, &m_master_reclength,
>                                     abort_on_warning, first_row);

ok.

> 
> === modified file 'sql/rpl_record.cc'
> --- a/sql/rpl_record.cc	2010-03-04 17:00:32 +0000
> +++ b/sql/rpl_record.cc	2010-03-30 23:19:25 +0000
> @@ -208,6 +208,20 @@ unpack_row(Relay_log_info const *rli,
>    uchar const *null_ptr= row_data;
>    uchar const *pack_ptr= row_data + master_null_byte_count;
>  
> +  if (bitmap_is_clear_all(cols))
> +  {
> +    /**
> +       There was no data sent from the master, so there is 
> +       nothing to unpack. In case we are unpacking an AI (for
> +       update or insert purposes), we just use the default 

Is this comment right? Default value for an update?

> +       values from the slave to do the insert.

Updates ---> Inserts?

Please, improve these comments.

> +    */
> +    *row_end= pack_ptr;
> +    *master_reclength= 0;
> +    DBUG_RETURN(error);
> +  }
> +
> +
>    Field **const begin_ptr = table->field;
>    Field **field_ptr;
>    Field **const end_ptr= begin_ptr + colcnt;
> 
> 
> ------------------------------------------------------------------------
> 
> This body part will be downloaded on demand.
Thread
bzr commit into mysql-5.1-rpl-wl5092 branch (luis.soares:3186)Bug#49100Luis Soares31 Mar
  • Re: bzr commit into mysql-5.1-rpl-wl5092 branch (luis.soares:3186)Bug#49100Alfranio Correia20 Apr
    • Re: bzr commit into mysql-5.1-rpl-wl5092 branch (luis.soares:3186)Bug#49100Luís Soares21 Apr
      • Re: bzr commit into mysql-5.1-rpl-wl5092 branch (luis.soares:3186)Bug#49100Luís Soares21 Apr
      • Re: bzr commit into mysql-5.1-rpl-wl5092 branch (luis.soares:3186)Bug#49100Alfranio Correia23 Apr
        • Re: bzr commit into mysql-5.1-rpl-wl5092 branch (luis.soares:3186)Bug#49100Luís Soares23 Apr