List:Commits« Previous MessageNext Message »
From:magnus.blaudd Date:April 27 2012 8:26am
Subject:bzr push into mysql-trunk branch (magnus.blaudd:3749 to 3750)
View as plain text  
 3750 magnus.blaudd@stripped	2012-04-27 [merge]
      Merge trunk-wl5917 with latest trunk

    added:
      mysql-test/suite/binlog/std_data/ver_trunk_row_v2.001
      mysql-test/suite/rpl/r/rpl_extra_row_data.result
      mysql-test/suite/rpl/t/rpl_extra_row_data-master.opt
      mysql-test/suite/rpl/t/rpl_extra_row_data-slave.opt
      mysql-test/suite/rpl/t/rpl_extra_row_data.test
      mysql-test/suite/sys_vars/r/log_bin_use_v1_row_events_basic.result
      mysql-test/suite/sys_vars/t/log_bin_use_v1_row_events_basic.test
    modified:
      client/mysqlbinlog.cc
      mysql-test/extra/binlog_tests/binlog.test
      mysql-test/r/flush2.result
      mysql-test/r/mysqld--help-notwin.result
      mysql-test/r/mysqld--help-win.result
      mysql-test/suite/binlog/r/binlog_old_versions.result
      mysql-test/suite/binlog/r/binlog_row_binlog.result
      mysql-test/suite/binlog/r/binlog_stm_binlog.result
      mysql-test/suite/binlog/r/binlog_variables_log_bin.result
      mysql-test/suite/binlog/r/binlog_variables_log_bin_index.result
      mysql-test/suite/binlog/t/binlog_old_versions.test
      mysql-test/suite/rpl/t/rpl_row_4_bytes-master.opt
      sql/binlog.cc
      sql/log_event.cc
      sql/log_event.h
      sql/log_event_old.h
      sql/mysqld.cc
      sql/mysqld.h
      sql/rpl_constants.h
      sql/rpl_injector.cc
      sql/rpl_injector.h
      sql/sql_binlog.cc
      sql/sql_class.cc
      sql/sql_class.h
      sql/sys_vars.cc
 3749 Norvald H. Ryeng	2012-04-27
      Bug#13735712 SELECT W/ SUBQUERY PRODUCES MORE ROWS WHEN USING
      VARIABLES
      
      Outer join queries with ALL may return incorrect results because the
      optimizer incorrectly rewrites them to use inner join. E.g.:
      
      SELECT *
      FROM t2 RIGHT JOIN t3 ON(t3.c = t2.b)
      WHERE t2.b < ALL(SELECT t1.a FROM t1 WHERE t1.a <= 7);
      
      is first rewritten by Item_in_subselect::single_value_transformer()
      into:
      
      SELECT *
      FROM t2 RIGHT JOIN t3 ON(t3.c = t2.b)
      WHERE <not>(t2.b >= (SELECT MIN(t1.a) FROM t1 WHERE t1.a <= 7));
      
      When simplify_joins() checks not_null_tables() on the <not> condition
      to find out if the outer join can be transformed into an inner join,
      Item_func::not_null_tables() returns its arguments'
      not_null_tables(). This means that simplify_joins() is told that the
      condition will be false if t2.b is NULL. But the condition is actually
      true if t1 has no rows where t1.a <= 7. This leads to the optimizer
      incorrectly rewriting the query to use inner join.
      
      Fix: Let Item_func_not_all::not_null_tables() return a zero table map.
     @ mysql-test/include/subquery.inc
        Add test cases for bugs #13735712.
     @ mysql-test/r/subquery_all.result
        Add test cases for bugs #13735712.
     @ mysql-test/r/subquery_all_bka.result
        Add test cases for bugs #13735712.
     @ mysql-test/r/subquery_all_bka_nixbnl.result
        Add test cases for bugs #13735712.
     @ mysql-test/r/subquery_nomat_nosj.result
        Add test cases for bugs #13735712.
     @ mysql-test/r/subquery_nomat_nosj_bka.result
        Add test cases for bugs #13735712.
     @ mysql-test/r/subquery_nomat_nosj_bka_nixbnl.result
        Add test cases for bugs #13735712.
     @ mysql-test/r/subquery_none.result
        Add test cases for bugs #13735712.
     @ mysql-test/r/subquery_none_bka.result
        Add test cases for bugs #13735712.
     @ mysql-test/r/subquery_none_bka_nixbnl.result
        Add test cases for bugs #13735712.
     @ sql/item_cmpfunc.h
        Return 0 from Item_func_not_all::not_null_tables().

    modified:
      mysql-test/include/subquery.inc
      mysql-test/r/subquery_all.result
      mysql-test/r/subquery_all_bka.result
      mysql-test/r/subquery_all_bka_nixbnl.result
      mysql-test/r/subquery_nomat_nosj.result
      mysql-test/r/subquery_nomat_nosj_bka.result
      mysql-test/r/subquery_nomat_nosj_bka_nixbnl.result
      mysql-test/r/subquery_none.result
      mysql-test/r/subquery_none_bka.result
      mysql-test/r/subquery_none_bka_nixbnl.result
      sql/item_cmpfunc.h
=== modified file 'client/mysqlbinlog.cc'
--- a/client/mysqlbinlog.cc	2012-04-16 09:14:37 +0000
+++ b/client/mysqlbinlog.cc	2012-04-24 16:52:56 +0000
@@ -1034,6 +1034,9 @@ Exit_status process_event(PRINT_EVENT_IN
     case WRITE_ROWS_EVENT:
     case DELETE_ROWS_EVENT:
     case UPDATE_ROWS_EVENT:
+    case WRITE_ROWS_EVENT_V1:
+    case UPDATE_ROWS_EVENT_V1:
+    case DELETE_ROWS_EVENT_V1:
     case PRE_GA_WRITE_ROWS_EVENT:
     case PRE_GA_DELETE_ROWS_EVENT:
     case PRE_GA_UPDATE_ROWS_EVENT:
@@ -1042,7 +1045,10 @@ Exit_status process_event(PRINT_EVENT_IN
       Table_map_log_event *ignored_map= NULL;
       if (ev_type == WRITE_ROWS_EVENT ||
           ev_type == DELETE_ROWS_EVENT ||
-          ev_type == UPDATE_ROWS_EVENT)
+          ev_type == UPDATE_ROWS_EVENT ||
+          ev_type == WRITE_ROWS_EVENT_V1 ||
+          ev_type == DELETE_ROWS_EVENT_V1 ||
+          ev_type == UPDATE_ROWS_EVENT_V1)
       {
         Rows_log_event *new_ev= (Rows_log_event*) ev;
         if (new_ev->get_flags(Rows_log_event::STMT_END_F))

=== modified file 'mysql-test/extra/binlog_tests/binlog.test'
--- a/mysql-test/extra/binlog_tests/binlog.test	2012-03-06 14:29:42 +0000
+++ b/mysql-test/extra/binlog_tests/binlog.test	2012-04-24 16:52:56 +0000
@@ -357,7 +357,7 @@ SHOW SESSION VARIABLES LIKE "%_checks";
 --echo # INSERT INTO t1 VALUES(2)
 --echo # foreign_key_checks=1 and unique_checks=1
 --echo # It should not change current session's variables, even error happens
-call mtr.add_suppression("Slave SQL.*Could not execute Write_rows event on table test.t1; Duplicate entry .2. for key .PRIMARY., Error_code: 1062");
+call mtr.add_suppression("Slave SQL.*Could not execute Write_rows_v1 event on table test.t1; Duplicate entry .2. for key .PRIMARY., Error_code: 1062");
 --error 1062
 BINLOG '
 dfLtTBMBAAAAKQAAAKsBAAAAABcAAAAAAAEABHRlc3QAAnQxAAEDAAE=

=== modified file 'mysql-test/r/flush2.result'
--- a/mysql-test/r/flush2.result	2010-11-16 09:38:43 +0000
+++ b/mysql-test/r/flush2.result	2012-04-24 16:52:56 +0000
@@ -6,6 +6,7 @@ log_bin	OFF
 log_bin_basename	
 log_bin_index	
 log_bin_trust_function_creators	ON
+log_bin_use_v1_row_events	OFF
 show variables like 'relay_log%';
 Variable_name	Value
 relay_log	
@@ -23,6 +24,7 @@ log_bin	OFF
 log_bin_basename	
 log_bin_index	
 log_bin_trust_function_creators	ON
+log_bin_use_v1_row_events	OFF
 show variables like 'relay_log%';
 Variable_name	Value
 relay_log	

=== modified file 'mysql-test/r/mysqld--help-notwin.result'
--- a/mysql-test/r/mysqld--help-notwin.result	2012-03-21 21:19:11 +0000
+++ b/mysql-test/r/mysqld--help-notwin.result	2012-04-24 16:52:56 +0000
@@ -270,6 +270,11 @@ The following options may be given as th
  ALWAYS use row-based binary logging, the security issues
  do not exist and the binary logging cannot break, so you
  can safely set this to TRUE
+ --log-bin-use-v1-row-events 
+ If equal to 1 then version 1 row events are written to a
+ row based binary log.  If equal to 0, then the latest
+ version of events are written.  This option is useful
+ during some upgrades.
  --log-error[=name]  Error log file
  --log-isam[=name]   Log all MyISAM changes to file.
  --log-output=name   Syntax: log-output=value[,value...], where "value" could
@@ -976,6 +981,7 @@ lock-wait-timeout 31536000
 log-bin (No default value)
 log-bin-index (No default value)
 log-bin-trust-function-creators FALSE
+log-bin-use-v1-row-events FALSE
 log-error 
 log-isam myisam.log
 log-output FILE

=== modified file 'mysql-test/r/mysqld--help-win.result'
--- a/mysql-test/r/mysqld--help-win.result	2012-03-21 21:19:11 +0000
+++ b/mysql-test/r/mysqld--help-win.result	2012-04-24 16:52:56 +0000
@@ -269,6 +269,11 @@ The following options may be given as th
  ALWAYS use row-based binary logging, the security issues
  do not exist and the binary logging cannot break, so you
  can safely set this to TRUE
+ --log-bin-use-v1-row-events 
+ If equal to 1 then version 1 row events are written to a
+ row based binary log.  If equal to 0, then the latest
+ version of events are written.  This option is useful
+ during some upgrades.
  --log-error[=name]  Error log file
  --log-isam[=name]   Log all MyISAM changes to file.
  --log-output=name   Syntax: log-output=value[,value...], where "value" could
@@ -983,6 +988,7 @@ lock-wait-timeout 31536000
 log-bin (No default value)
 log-bin-index (No default value)
 log-bin-trust-function-creators FALSE
+log-bin-use-v1-row-events FALSE
 log-error 
 log-isam myisam.log
 log-output FILE

=== modified file 'mysql-test/suite/binlog/r/binlog_old_versions.result'
--- a/mysql-test/suite/binlog/r/binlog_old_versions.result	2010-12-19 17:22:30 +0000
+++ b/mysql-test/suite/binlog/r/binlog_old_versions.result	2012-04-24 16:52:56 +0000
@@ -1,3 +1,18 @@
+==== Read binlog with v2 row events ====
+SELECT * FROM t1 ORDER BY a;
+a	b
+0	last_insert_id
+1	one
+3	last stm in trx: next event should be xid
+4	four
+62046	random
+SELECT * FROM t2 ORDER BY a;
+a	b
+3	first stm in trx
+SELECT COUNT(*) FROM t3;
+COUNT(*)
+17920
+DROP TABLE t1, t2, t3;
 ==== Read modern binlog (version 5.1.23) ====
 SELECT * FROM t1 ORDER BY a;
 a	b

=== modified file 'mysql-test/suite/binlog/r/binlog_row_binlog.result'
--- a/mysql-test/suite/binlog/r/binlog_row_binlog.result	2012-03-06 14:29:42 +0000
+++ b/mysql-test/suite/binlog/r/binlog_row_binlog.result	2012-04-24 16:52:56 +0000
@@ -803,7 +803,7 @@ unique_checks	OFF
 # INSERT INTO t1 VALUES(2)
 # foreign_key_checks=1 and unique_checks=1
 # It should not change current session's variables, even error happens
-call mtr.add_suppression("Slave SQL.*Could not execute Write_rows event on table test.t1; Duplicate entry .2. for key .PRIMARY., Error_code: 1062");
+call mtr.add_suppression("Slave SQL.*Could not execute Write_rows_v1 event on table test.t1; Duplicate entry .2. for key .PRIMARY., Error_code: 1062");
 BINLOG '
 dfLtTBMBAAAAKQAAAKsBAAAAABcAAAAAAAEABHRlc3QAAnQxAAEDAAE=
 dfLtTBcBAAAAIgAAAM0BAAAAABcAAAAAAAEAAf/+AgAAAA==

=== modified file 'mysql-test/suite/binlog/r/binlog_stm_binlog.result'
--- a/mysql-test/suite/binlog/r/binlog_stm_binlog.result	2012-03-06 14:29:42 +0000
+++ b/mysql-test/suite/binlog/r/binlog_stm_binlog.result	2012-04-24 16:52:56 +0000
@@ -572,7 +572,7 @@ unique_checks	OFF
 # INSERT INTO t1 VALUES(2)
 # foreign_key_checks=1 and unique_checks=1
 # It should not change current session's variables, even error happens
-call mtr.add_suppression("Slave SQL.*Could not execute Write_rows event on table test.t1; Duplicate entry .2. for key .PRIMARY., Error_code: 1062");
+call mtr.add_suppression("Slave SQL.*Could not execute Write_rows_v1 event on table test.t1; Duplicate entry .2. for key .PRIMARY., Error_code: 1062");
 BINLOG '
 dfLtTBMBAAAAKQAAAKsBAAAAABcAAAAAAAEABHRlc3QAAnQxAAEDAAE=
 dfLtTBcBAAAAIgAAAM0BAAAAABcAAAAAAAEAAf/+AgAAAA==

=== modified file 'mysql-test/suite/binlog/r/binlog_variables_log_bin.result'
--- a/mysql-test/suite/binlog/r/binlog_variables_log_bin.result	2010-11-04 14:43:52 +0000
+++ b/mysql-test/suite/binlog/r/binlog_variables_log_bin.result	2012-04-24 16:52:56 +0000
@@ -7,3 +7,5 @@ Variable_name	log_bin_index
 Value	MYSQLTEST_VARDIR/mysqld.1/data/other.index
 Variable_name	log_bin_trust_function_creators
 Value	ON
+Variable_name	log_bin_use_v1_row_events
+Value	OFF

=== modified file 'mysql-test/suite/binlog/r/binlog_variables_log_bin_index.result'
--- a/mysql-test/suite/binlog/r/binlog_variables_log_bin_index.result	2010-11-04 14:43:52 +0000
+++ b/mysql-test/suite/binlog/r/binlog_variables_log_bin_index.result	2012-04-24 16:52:56 +0000
@@ -7,3 +7,5 @@ Variable_name	log_bin_index
 Value	MYSQLTEST_VARDIR/tmp/something.index
 Variable_name	log_bin_trust_function_creators
 Value	ON
+Variable_name	log_bin_use_v1_row_events
+Value	OFF

=== added file 'mysql-test/suite/binlog/std_data/ver_trunk_row_v2.001'
Binary files a/mysql-test/suite/binlog/std_data/ver_trunk_row_v2.001	1970-01-01 00:00:00 +0000 and b/mysql-test/suite/binlog/std_data/ver_trunk_row_v2.001	2012-04-24 16:52:56 +0000 differ

=== modified file 'mysql-test/suite/binlog/t/binlog_old_versions.test'
--- a/mysql-test/suite/binlog/t/binlog_old_versions.test	2010-12-19 17:22:30 +0000
+++ b/mysql-test/suite/binlog/t/binlog_old_versions.test	2012-04-24 16:52:56 +0000
@@ -24,6 +24,17 @@
 
 source include/not_embedded.inc;
 
+--echo ==== Read binlog with v2 row events ====
+
+# Read binlog.
+--exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/ver_trunk_row_v2.001 | $MYSQL --local-infile=1
+# Show result.
+SELECT * FROM t1 ORDER BY a;
+SELECT * FROM t2 ORDER BY a;
+SELECT COUNT(*) FROM t3;
+# Reset.
+DROP TABLE t1, t2, t3;
+
 
 --echo ==== Read modern binlog (version 5.1.23) ====
 

=== added file 'mysql-test/suite/rpl/r/rpl_extra_row_data.result'
--- a/mysql-test/suite/rpl/r/rpl_extra_row_data.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_extra_row_data.result	2012-04-24 16:52:56 +0000
@@ -0,0 +1,49 @@
+include/master-slave.inc
+Warnings:
+Note	####	Sending passwords in plain text without SSL/TLS is extremely insecure.
+Note	####	Storing MySQL user name or password information in the master.info repository is not secure and is therefore not recommended. Please see the MySQL Manual for more about this issue and possible alternatives.
+[connection master]
+Basic insert, update, delete from Master->Slave
+DBUG code will set + check transfer of extra
+row data in RBR
+**** On Master ****
+CREATE TABLE t1 (a INT);
+Ten inserts in one transaction -> 1 epoch transaction
+BEGIN;
+INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
+COMMIT;
+Wait for Binlog-on-disk
+flush logs;
+Check that we have the expected extra row data in the Binlog
+create table raw_data(txt varchar(1000));
+select replace(txt, '\r', '') from raw_data where txt like '%### Extra row data format%' order by txt;
+replace(txt, '\r', '')
+### Extra row data format: 0, len: 0 :
+### Extra row data format: 1, len: 1 :0x01
+### Extra row data format: 2, len: 2 :0x0202
+### Extra row data format: 3, len: 3 :0x030303
+### Extra row data format: 4, len: 4 :0x04040404
+### Extra row data format: 5, len: 5 :0x0505050505
+### Extra row data format: 6, len: 6 :0x060606060606
+### Extra row data format: 7, len: 7 :0x07070707070707
+### Extra row data format: 8, len: 8 :0x0808080808080808
+### Extra row data format: 9, len: 9 :0x090909090909090909
+drop table raw_data;
+Generate some more insert, update, delete traffic
+INSERT INTO t1 SELECT a+10 FROM t1;
+INSERT INTO t1 SELECT a+20 FROM t1;
+INSERT INTO t1 SELECT a+40 FROM t1;
+UPDATE t1 SET a = a+1;
+UPDATE t1 SET a = a+1;
+UPDATE t1 SET a = a+1;
+UPDATE t1 SET a = a+1;
+UPDATE t1 SET a = a+1;
+DELETE FROM t1 WHERE a > 390;
+**** On Slave ****
+Check row count and that slave is running ok
+SELECT count(*) from t1;
+count(*)
+80
+include/check_slave_is_running.inc
+DROP TABLE t1;
+include/rpl_end.inc

=== added file 'mysql-test/suite/rpl/t/rpl_extra_row_data-master.opt'
--- a/mysql-test/suite/rpl/t/rpl_extra_row_data-master.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_extra_row_data-master.opt	2012-04-24 16:52:56 +0000
@@ -0,0 +1 @@
+--loose-debug=+d,extra_row_data_set

=== added file 'mysql-test/suite/rpl/t/rpl_extra_row_data-slave.opt'
--- a/mysql-test/suite/rpl/t/rpl_extra_row_data-slave.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_extra_row_data-slave.opt	2012-04-24 16:52:56 +0000
@@ -0,0 +1 @@
+--loose-debug=+d,extra_row_data_check

=== added file 'mysql-test/suite/rpl/t/rpl_extra_row_data.test'
--- a/mysql-test/suite/rpl/t/rpl_extra_row_data.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_extra_row_data.test	2012-04-24 16:52:56 +0000
@@ -0,0 +1,62 @@
+--source include/master-slave.inc
+--source include/have_debug.inc
+--source include/have_binlog_format_row.inc
+
+--echo Basic insert, update, delete from Master->Slave
+--echo DBUG code will set + check transfer of extra
+--echo row data in RBR
+--echo **** On Master ****
+CREATE TABLE t1 (a INT);
+
+--echo Ten inserts in one transaction -> 1 epoch transaction
+BEGIN;
+INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
+COMMIT;
+
+--echo Wait for Binlog-on-disk
+flush logs;
+
+--echo Check that we have the expected extra row data in the Binlog
+create table raw_data(txt varchar(1000));
+--disable_query_log
+let $MYSQLD_DATADIR= `select @@datadir;`;
+--exec $MYSQL_BINLOG --verbose $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/rpl_extra_row_data.out
+
+--eval load data local infile '$MYSQLTEST_VARDIR/tmp/rpl_extra_row_data.out' into table raw_data columns terminated by '\n';
+--enable_query_log
+
+select replace(txt, '\r', '') from raw_data where txt like '%### Extra row data format%' order by txt;
+drop table raw_data;
+
+--echo Generate some more insert, update, delete traffic
+INSERT INTO t1 SELECT a+10 FROM t1;
+INSERT INTO t1 SELECT a+20 FROM t1;
+INSERT INTO t1 SELECT a+40 FROM t1;
+# 80 rows, 80 inserts
+UPDATE t1 SET a = a+1;
+UPDATE t1 SET a = a+1;
+UPDATE t1 SET a = a+1;
+UPDATE t1 SET a = a+1;
+UPDATE t1 SET a = a+1;
+# 5 Updates of 80 rows = 400 updates, enough to show all potential lengths
+# of Binlog extra row data including 0 + 255.
+
+# 10 deletes
+DELETE FROM t1 WHERE a > 390;
+
+#show binlog events;
+#let $MYSQLD_DATADIR= `select @@datadir;`;
+#--exec $MYSQL_BINLOG --verbose $MYSQLD_DATADIR/master-bin.000001
+
+--echo **** On Slave ****
+--sync_slave_with_master
+connection slave;
+
+--echo Check row count and that slave is running ok
+SELECT count(*) from t1;
+source include/check_slave_is_running.inc;
+
+connection master;
+DROP TABLE t1;
+--sync_slave_with_master
+--source include/rpl_end.inc

=== modified file 'mysql-test/suite/rpl/t/rpl_row_4_bytes-master.opt'
--- a/mysql-test/suite/rpl/t/rpl_row_4_bytes-master.opt	2007-06-27 12:28:02 +0000
+++ b/mysql-test/suite/rpl/t/rpl_row_4_bytes-master.opt	2012-04-24 16:52:56 +0000
@@ -1 +1,2 @@
 --loose-debug=d,"old_row_based_repl_4_byte_map_id_master"
+--log-bin-use-v1-row-events=1
\ No newline at end of file

=== added file 'mysql-test/suite/sys_vars/r/log_bin_use_v1_row_events_basic.result'
--- a/mysql-test/suite/sys_vars/r/log_bin_use_v1_row_events_basic.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/r/log_bin_use_v1_row_events_basic.result	2012-04-24 16:52:56 +0000
@@ -0,0 +1,71 @@
+'#---------------------BS_STVARS_002_01----------------------#'
+SET @start_value= @@global.log_bin_use_v1_row_events;
+SELECT @start_value;
+@start_value
+0
+SELECT COUNT(@@GLOBAL.log_bin_use_v1_row_events);
+COUNT(@@GLOBAL.log_bin_use_v1_row_events)
+1
+1 Expected
+'#---------------------BS_STVARS_002_02----------------------#'
+SET @@global.log_bin_use_v1_row_events = TRUE;
+SET @@global.log_bin_use_v1_row_events = DEFAULT;
+SELECT @@global.log_bin_use_v1_row_events;
+@@global.log_bin_use_v1_row_events
+0
+SET @@global.log_bin_use_v1_row_events = ON;
+SELECT @@global.log_bin_use_v1_row_events;
+@@global.log_bin_use_v1_row_events
+1
+SET @@global.log_bin_use_v1_row_events = OFF;
+SELECT @@global.log_bin_use_v1_row_events;
+@@global.log_bin_use_v1_row_events
+0
+SET @@global.log_bin_use_v1_row_events = 1;
+SELECT @@global.log_bin_use_v1_row_events;
+@@global.log_bin_use_v1_row_events
+1
+SET @@global.log_bin_use_v1_row_events = 0;
+SELECT @@global.log_bin_use_v1_row_events;
+@@global.log_bin_use_v1_row_events
+0
+SET @@global.log_bin_use_v1_row_events = TRUE;
+SELECT @@global.log_bin_use_v1_row_events;
+@@global.log_bin_use_v1_row_events
+1
+SET @@global.log_bin_use_v1_row_events = FALSE;
+SELECT @@global.log_bin_use_v1_row_events;
+@@global.log_bin_use_v1_row_events
+0
+'#-------------------FN_DYNVARS_063_04----------------------------#'
+SET @@session.log_bin_use_v1_row_events = 0;
+ERROR HY000: Variable 'log_bin_use_v1_row_events' is a GLOBAL variable and should be set with SET GLOBAL
+SELECT @@session.log_bin_use_v1_row_events;
+ERROR HY000: Variable 'log_bin_use_v1_row_events' is a GLOBAL variable
+'#---------------------BS_STVARS_002_03----------------------#'
+SELECT IF(@@GLOBAL.log_bin_use_v1_row_events, "ON", "OFF") = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
+WHERE VARIABLE_NAME='log_bin_use_v1_row_events';
+IF(@@GLOBAL.log_bin_use_v1_row_events, "ON", "OFF") = VARIABLE_VALUE
+1
+1 Expected
+SELECT COUNT(@@GLOBAL.log_bin_use_v1_row_events);
+COUNT(@@GLOBAL.log_bin_use_v1_row_events)
+1
+1 Expected
+SELECT COUNT(VARIABLE_VALUE)
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
+WHERE VARIABLE_NAME='log_bin_use_v1_row_events';
+COUNT(VARIABLE_VALUE)
+1
+1 Expected
+'#---------------------BS_STVARS_002_05----------------------#'
+SELECT COUNT(@@log_bin_use_v1_row_events);
+COUNT(@@log_bin_use_v1_row_events)
+1
+1 Expected
+SELECT COUNT(@@GLOBAL.log_bin_use_v1_row_events);
+COUNT(@@GLOBAL.log_bin_use_v1_row_events)
+1
+1 Expected
+SET @@global.log_bin_use_v1_row_events= @start_value;

=== added file 'mysql-test/suite/sys_vars/t/log_bin_use_v1_row_events_basic.test'
--- a/mysql-test/suite/sys_vars/t/log_bin_use_v1_row_events_basic.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/t/log_bin_use_v1_row_events_basic.test	2012-04-24 16:52:56 +0000
@@ -0,0 +1,95 @@
+############# mysql-test\t\log_bin_use_v1_row_events_basic.test ###############
+#                                                                             #
+# Variable Name: log_bin_use_v1_row_events                                    #
+# Scope: Global                                                               #
+# Access Type: Static                                                         #
+# Data Type: bool                                                             #
+#                                                                             #
+#                                                                             #
+# Creation Date: 2011-11-23                                                   #
+# Author : Frazer Clement                                                     #
+#                                                                             #
+#                                                                             #
+# Description:Test Cases of Static System Variable log_bin_use_v1_row_events  #
+#             that checks the behavior of this variable in the following ways #
+#              * Value Check                                                  #
+#              * Scope Check                                                  #
+#                                                                             #
+# Reference:                                                                  #
+#    http://dev.mysql.com/doc/refman/5.X/en/server-system-variables.html      #
+#                                                                             #
+###############################################################################
+
+
+--echo '#---------------------BS_STVARS_002_01----------------------#'
+####################################################################
+#   Displaying default value                                       #
+####################################################################
+SET @start_value= @@global.log_bin_use_v1_row_events;
+SELECT @start_value;
+
+SELECT COUNT(@@GLOBAL.log_bin_use_v1_row_events);
+--echo 1 Expected
+
+--echo '#---------------------BS_STVARS_002_02----------------------#'
+####################################################################
+#   Check if Value can set                                         #
+####################################################################
+SET @@global.log_bin_use_v1_row_events = TRUE;
+SET @@global.log_bin_use_v1_row_events = DEFAULT;
+SELECT @@global.log_bin_use_v1_row_events;
+
+SET @@global.log_bin_use_v1_row_events = ON;
+SELECT @@global.log_bin_use_v1_row_events;
+SET @@global.log_bin_use_v1_row_events = OFF;
+SELECT @@global.log_bin_use_v1_row_events;
+SET @@global.log_bin_use_v1_row_events = 1;
+SELECT @@global.log_bin_use_v1_row_events;
+SET @@global.log_bin_use_v1_row_events = 0;
+SELECT @@global.log_bin_use_v1_row_events;
+SET @@global.log_bin_use_v1_row_events = TRUE;
+SELECT @@global.log_bin_use_v1_row_events;
+SET @@global.log_bin_use_v1_row_events = FALSE;
+SELECT @@global.log_bin_use_v1_row_events;
+
+--echo '#-------------------FN_DYNVARS_063_04----------------------------#'
+###############################################################################
+#     Test if accessing session log_bin_use_v1_row_events gives error         #
+###############################################################################
+
+--Error ER_GLOBAL_VARIABLE
+SET @@session.log_bin_use_v1_row_events = 0;
+--Error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SELECT @@session.log_bin_use_v1_row_events;
+
+--echo '#---------------------BS_STVARS_002_03----------------------#'
+#################################################################
+# Check if the value in GLOBAL Table matches value in variable  #
+#################################################################
+
+SELECT IF(@@GLOBAL.log_bin_use_v1_row_events, "ON", "OFF") = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
+WHERE VARIABLE_NAME='log_bin_use_v1_row_events';
+--echo 1 Expected
+
+SELECT COUNT(@@GLOBAL.log_bin_use_v1_row_events);
+--echo 1 Expected
+
+SELECT COUNT(VARIABLE_VALUE)
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
+WHERE VARIABLE_NAME='log_bin_use_v1_row_events';
+--echo 1 Expected
+
+
+--echo '#---------------------BS_STVARS_002_05----------------------#'
+################################################################################
+# Check if log_bin_use_v1_row_events can be accessed with and without @@ sign  #
+################################################################################
+
+SELECT COUNT(@@log_bin_use_v1_row_events);
+--echo 1 Expected
+SELECT COUNT(@@GLOBAL.log_bin_use_v1_row_events);
+--echo 1 Expected
+
+SET @@global.log_bin_use_v1_row_events= @start_value;
+

=== modified file 'sql/binlog.cc'
--- a/sql/binlog.cc	2012-04-20 22:39:38 +0000
+++ b/sql/binlog.cc	2012-04-24 16:52:56 +0000
@@ -6347,14 +6347,15 @@ template <class RowsEventT> Rows_log_eve
 THD::binlog_prepare_pending_rows_event(TABLE* table, uint32 serv_id,
                                        size_t needed,
                                        bool is_transactional,
-				       RowsEventT *hint __attribute__((unused)))
+				       RowsEventT *hint __attribute__((unused)),
+                                       const uchar* extra_row_info)
 {
   DBUG_ENTER("binlog_prepare_pending_rows_event");
   /* Pre-conditions */
   DBUG_ASSERT(table->s->table_map_id != ~0UL);
 
   /* Fetch the type code for the RowsEventT template parameter */
-  int const type_code= RowsEventT::TYPE_CODE;
+  int const general_type_code= RowsEventT::TYPE_CODE;
 
   Rows_log_event* pending= binlog_get_pending_rows_event(is_transactional);
 
@@ -6374,14 +6375,16 @@ THD::binlog_prepare_pending_rows_event(T
   if (!pending ||
       pending->server_id != serv_id || 
       pending->get_table_id() != table->s->table_map_id ||
-      pending->get_type_code() != type_code || 
+      pending->get_general_type_code() != general_type_code ||
       pending->get_data_size() + needed > opt_binlog_rows_event_max_size ||
-      pending->read_write_bitmaps_cmp(table) == FALSE)
+      pending->read_write_bitmaps_cmp(table) == FALSE ||
+      !binlog_row_event_extra_data_eq(pending->get_extra_row_data(),
+                                      extra_row_info))
   {
     /* Create a new RowsEventT... */
     Rows_log_event* const
 	ev= new RowsEventT(this, table, table->s->table_map_id,
-                           is_transactional);
+                           is_transactional, extra_row_info);
     if (unlikely(!ev))
       DBUG_RETURN(NULL);
     ev->server_id= serv_id; // I don't like this, it's too easy to forget.
@@ -6527,7 +6530,8 @@ CPP_UNNAMED_NS_START
 CPP_UNNAMED_NS_END
 
 int THD::binlog_write_row(TABLE* table, bool is_trans, 
-                          uchar const *record) 
+                          uchar const *record,
+                          const uchar* extra_row_info)
 { 
   DBUG_ASSERT(is_current_stmt_binlog_format_row() && mysql_bin_log.is_open());
 
@@ -6545,7 +6549,8 @@ int THD::binlog_write_row(TABLE* table, 
 
   Rows_log_event* const ev=
     binlog_prepare_pending_rows_event(table, server_id, len, is_trans,
-                                      static_cast<Write_rows_log_event*>(0));
+                                      static_cast<Write_rows_log_event*>(0),
+                                      extra_row_info);
 
   if (unlikely(ev == 0))
     return HA_ERR_OUT_OF_MEM;
@@ -6555,7 +6560,8 @@ int THD::binlog_write_row(TABLE* table, 
 
 int THD::binlog_update_row(TABLE* table, bool is_trans,
                            const uchar *before_record,
-                           const uchar *after_record)
+                           const uchar *after_record,
+                           const uchar* extra_row_info)
 { 
   DBUG_ASSERT(is_current_stmt_binlog_format_row() && mysql_bin_log.is_open());
   int error= 0;
@@ -6603,7 +6609,8 @@ int THD::binlog_update_row(TABLE* table,
   Rows_log_event* const ev=
     binlog_prepare_pending_rows_event(table, server_id,
 				      before_size + after_size, is_trans,
-				      static_cast<Update_rows_log_event*>(0));
+				      static_cast<Update_rows_log_event*>(0),
+                                      extra_row_info);
 
   if (unlikely(ev == 0))
     return HA_ERR_OUT_OF_MEM;
@@ -6619,7 +6626,8 @@ int THD::binlog_update_row(TABLE* table,
 }
 
 int THD::binlog_delete_row(TABLE* table, bool is_trans, 
-                           uchar const *record)
+                           uchar const *record,
+                           const uchar* extra_row_info)
 { 
   DBUG_ASSERT(is_current_stmt_binlog_format_row() && mysql_bin_log.is_open());
   int error= 0;
@@ -6653,7 +6661,8 @@ int THD::binlog_delete_row(TABLE* table,
 
   Rows_log_event* const ev=
     binlog_prepare_pending_rows_event(table, server_id, len, is_trans,
-				      static_cast<Delete_rows_log_event*>(0));
+				      static_cast<Delete_rows_log_event*>(0),
+                                      extra_row_info);
 
   if (unlikely(ev == 0))
     return HA_ERR_OUT_OF_MEM;
@@ -6776,6 +6785,38 @@ int THD::binlog_flush_pending_rows_event
 }
 
 
+/**
+   binlog_row_event_extra_data_eq
+
+   Comparator for two binlog row event extra data
+   pointers.
+
+   It compares their significant bytes.
+
+   Null pointers are acceptable
+
+   @param a
+     first pointer
+
+   @param b
+     first pointer
+
+   @return
+     true if the referenced structures are equal
+*/
+bool
+THD::binlog_row_event_extra_data_eq(const uchar* a,
+                                    const uchar* b)
+{
+  return ((a == b) ||
+          ((a != NULL) &&
+           (b != NULL) &&
+           (a[EXTRA_ROW_INFO_LEN_OFFSET] ==
+            b[EXTRA_ROW_INFO_LEN_OFFSET]) &&
+           (memcmp(a, b,
+                   a[EXTRA_ROW_INFO_LEN_OFFSET]) == 0)));
+}
+
 #if !defined(DBUG_OFF) && !defined(_lint)
 static const char *
 show_query_type(THD::enum_binlog_query_type qtype)

=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc	2012-04-21 12:11:15 +0000
+++ b/sql/log_event.cc	2012-04-24 16:52:56 +0000
@@ -80,7 +80,6 @@ TYPELIB binlog_checksum_typelib=
 
 #define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
 
-
 /*
   Size of buffer for printing a double in format %.<PREC>g
 
@@ -661,14 +660,17 @@ const char* Log_event::get_type_str(Log_
   case PRE_GA_WRITE_ROWS_EVENT: return "Write_rows_event_old";
   case PRE_GA_UPDATE_ROWS_EVENT: return "Update_rows_event_old";
   case PRE_GA_DELETE_ROWS_EVENT: return "Delete_rows_event_old";
-  case WRITE_ROWS_EVENT: return "Write_rows";
-  case UPDATE_ROWS_EVENT: return "Update_rows";
-  case DELETE_ROWS_EVENT: return "Delete_rows";
+  case WRITE_ROWS_EVENT_V1: return "Write_rows_v1";
+  case UPDATE_ROWS_EVENT_V1: return "Update_rows_v1";
+  case DELETE_ROWS_EVENT_V1: return "Delete_rows_v1";
   case BEGIN_LOAD_QUERY_EVENT: return "Begin_load_query";
   case EXECUTE_LOAD_QUERY_EVENT: return "Execute_load_query";
   case INCIDENT_EVENT: return "Incident";
   case IGNORABLE_LOG_EVENT: return "Ignorable";
   case ROWS_QUERY_LOG_EVENT: return "Rows_query";
+  case WRITE_ROWS_EVENT: return "Write_rows";
+  case UPDATE_ROWS_EVENT: return "Update_rows";
+  case DELETE_ROWS_EVENT: return "Delete_rows";
   case GTID_LOG_EVENT: return "Gtid";
   case ANONYMOUS_GTID_LOG_EVENT: return "Anonymous_Gtid";
   case PREVIOUS_GTIDS_LOG_EVENT: return "Previous_gtids";
@@ -1552,13 +1554,13 @@ Log_event* Log_event::read_log_event(con
     case PRE_GA_DELETE_ROWS_EVENT:
       ev = new Delete_rows_log_event_old(buf, event_len, description_event);
       break;
-    case WRITE_ROWS_EVENT:
+    case WRITE_ROWS_EVENT_V1:
       ev = new Write_rows_log_event(buf, event_len, description_event);
       break;
-    case UPDATE_ROWS_EVENT:
+    case UPDATE_ROWS_EVENT_V1:
       ev = new Update_rows_log_event(buf, event_len, description_event);
       break;
-    case DELETE_ROWS_EVENT:
+    case DELETE_ROWS_EVENT_V1:
       ev = new Delete_rows_log_event(buf, event_len, description_event);
       break;
     case TABLE_MAP_EVENT:
@@ -1584,6 +1586,17 @@ Log_event* Log_event::read_log_event(con
     case PREVIOUS_GTIDS_LOG_EVENT:
       ev= new Previous_gtids_log_event(buf, event_len, description_event);
       break;
+#if defined(HAVE_REPLICATION)
+    case WRITE_ROWS_EVENT:
+      ev = new Write_rows_log_event(buf, event_len, description_event);
+      break;
+    case UPDATE_ROWS_EVENT:
+      ev = new Update_rows_log_event(buf, event_len, description_event);
+      break;
+    case DELETE_ROWS_EVENT:
+      ev = new Delete_rows_log_event(buf, event_len, description_event);
+      break;
+#endif
     default:
       /*
         Create an object of Ignorable_log_event for unrecognized sub-class.
@@ -2282,9 +2295,33 @@ void Rows_log_event::print_verbose(IO_CA
   Table_map_log_event *map;
   table_def *td;
   const char *sql_command, *sql_clause1, *sql_clause2;
-  Log_event_type type_code= get_type_code();
+  Log_event_type general_type_code= get_general_type_code();
   
-  switch (type_code) {
+  if (m_extra_row_data)
+  {
+    uint8 extra_data_len= m_extra_row_data[EXTRA_ROW_INFO_LEN_OFFSET];
+    uint8 extra_payload_len= extra_data_len - EXTRA_ROW_INFO_HDR_BYTES;
+    assert(extra_data_len >= EXTRA_ROW_INFO_HDR_BYTES);
+
+    my_b_printf(file, "### Extra row data format: %u, len: %u :",
+                m_extra_row_data[EXTRA_ROW_INFO_FORMAT_OFFSET],
+                extra_payload_len);
+    if (extra_payload_len)
+    {
+      /*
+         Buffer for hex view of string, including '0x' prefix,
+         2 hex chars / byte and trailing 0
+      */
+      const int buff_len= 2 + (256 * 2) + 1;
+      char buff[buff_len];
+      str_to_hex(buff, (const char*) &m_extra_row_data[EXTRA_ROW_INFO_HDR_BYTES],
+                 extra_payload_len);
+      my_b_printf(file, "%s", buff);
+    }
+    my_b_printf(file, "\n");
+  }
+
+  switch (general_type_code) {
   case WRITE_ROWS_EVENT:
     sql_command= "INSERT INTO";
     sql_clause1= "### SET\n";
@@ -2313,7 +2350,7 @@ void Rows_log_event::print_verbose(IO_CA
   }
 
   /* If the write rows event contained no values for the AI */
-  if (((type_code == WRITE_ROWS_EVENT) && (m_rows_buf==m_rows_end)))
+  if (((general_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());
@@ -2390,31 +2427,45 @@ void Log_event::print_base64(IO_CACHE* f
   if (print_event_info->verbose)
   {
     Rows_log_event *ev= NULL;
+    Log_event_type et= (Log_event_type) ptr[EVENT_TYPE_OFFSET];
+
     if (checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF &&
         checksum_alg != BINLOG_CHECKSUM_ALG_OFF)
       size-= BINLOG_CHECKSUM_LEN; // checksum is displayed through the header
     
-    if (ptr[4] == TABLE_MAP_EVENT)
+    switch(et)
+    {
+    case TABLE_MAP_EVENT:
     {
       Table_map_log_event *map; 
       map= new Table_map_log_event((const char*) ptr, size, 
                                    glob_description_event);
       print_event_info->m_table_map.set_table(map->get_table_id(), map);
+      break;
     }
-    else if (ptr[4] == WRITE_ROWS_EVENT)
+    case WRITE_ROWS_EVENT:
+    case WRITE_ROWS_EVENT_V1:
     {
       ev= new Write_rows_log_event((const char*) ptr, size,
                                    glob_description_event);
+      break;
     }
-    else if (ptr[4] == DELETE_ROWS_EVENT)
+    case DELETE_ROWS_EVENT:
+    case DELETE_ROWS_EVENT_V1:
     {
       ev= new Delete_rows_log_event((const char*) ptr, size,
                                     glob_description_event);
+      break;
     }
-    else if (ptr[4] == UPDATE_ROWS_EVENT)
+    case UPDATE_ROWS_EVENT:
+    case UPDATE_ROWS_EVENT_V1:
     {
       ev= new Update_rows_log_event((const char*) ptr, size,
                                     glob_description_event);
+      break;
+    }
+    default:
+      break;
     }
     
     if (ev)
@@ -5044,10 +5095,10 @@ Format_description_log_event(uint8 binlo
       post_header_len[PRE_GA_UPDATE_ROWS_EVENT-1] = 0;
       post_header_len[PRE_GA_DELETE_ROWS_EVENT-1] = 0;
 
-      post_header_len[TABLE_MAP_EVENT-1]=    TABLE_MAP_HEADER_LEN;
-      post_header_len[WRITE_ROWS_EVENT-1]=   ROWS_HEADER_LEN;
-      post_header_len[UPDATE_ROWS_EVENT-1]=  ROWS_HEADER_LEN;
-      post_header_len[DELETE_ROWS_EVENT-1]=  ROWS_HEADER_LEN;
+      post_header_len[TABLE_MAP_EVENT-1]=       TABLE_MAP_HEADER_LEN;
+      post_header_len[WRITE_ROWS_EVENT_V1-1]=   ROWS_HEADER_LEN_V1;
+      post_header_len[UPDATE_ROWS_EVENT_V1-1]=  ROWS_HEADER_LEN_V1;
+      post_header_len[DELETE_ROWS_EVENT_V1-1]=  ROWS_HEADER_LEN_V1;
       /*
         We here have the possibility to simulate a master of before we changed
         the table map id to be stored in 6 bytes: when it was stored in 4
@@ -5060,16 +5111,16 @@ Format_description_log_event(uint8 binlo
       */
       DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
                       post_header_len[TABLE_MAP_EVENT-1]=
-                      post_header_len[WRITE_ROWS_EVENT-1]=
-                      post_header_len[UPDATE_ROWS_EVENT-1]=
-                      post_header_len[DELETE_ROWS_EVENT-1]= 6;);
+                      post_header_len[WRITE_ROWS_EVENT_V1-1]=
+                      post_header_len[UPDATE_ROWS_EVENT_V1-1]=
+                      post_header_len[DELETE_ROWS_EVENT_V1-1]= 6;);
       post_header_len[INCIDENT_EVENT-1]= INCIDENT_HEADER_LEN;
       post_header_len[HEARTBEAT_LOG_EVENT-1]= 0;
       post_header_len[IGNORABLE_LOG_EVENT-1]= IGNORABLE_HEADER_LEN;
       post_header_len[ROWS_QUERY_LOG_EVENT-1]= IGNORABLE_HEADER_LEN;
-      post_header_len[RESERVED_EVENT_NUM_1-1]= RESERVED_HEADER_LEN;
-      post_header_len[RESERVED_EVENT_NUM_2-1]= RESERVED_HEADER_LEN;
-      post_header_len[RESERVED_EVENT_NUM_3-1]= RESERVED_HEADER_LEN;
+      post_header_len[WRITE_ROWS_EVENT-1]=  ROWS_HEADER_LEN_V2;
+      post_header_len[UPDATE_ROWS_EVENT-1]= ROWS_HEADER_LEN_V2;
+      post_header_len[DELETE_ROWS_EVENT-1]= ROWS_HEADER_LEN_V2;
       post_header_len[GTID_LOG_EVENT-1]=
         post_header_len[ANONYMOUS_GTID_LOG_EVENT-1]=
         Gtid_log_event::POST_HEADER_LENGTH;
@@ -8641,6 +8692,59 @@ const char *sql_ex_info::init(const char
   return buf;
 }
 
+#ifndef DBUG_OFF
+#ifndef MYSQL_CLIENT
+static uchar dbug_extra_row_data_val= 0;
+
+/**
+   set_extra_data
+
+   Called during self-test to generate various
+   self-consistent binlog row event extra
+   thread data structures which can be checked
+   when reading the binlog.
+
+   @param arr  Buffer to use
+*/
+const uchar* set_extra_data(uchar* arr)
+{
+  uchar val= (dbug_extra_row_data_val++) %
+    (EXTRA_ROW_INFO_MAX_PAYLOAD + 1); /* 0 .. MAX_PAYLOAD + 1 */
+  arr[EXTRA_ROW_INFO_LEN_OFFSET]= val + EXTRA_ROW_INFO_HDR_BYTES;
+  arr[EXTRA_ROW_INFO_FORMAT_OFFSET]= val;
+  for (uchar i=0; i<val; i++)
+    arr[EXTRA_ROW_INFO_HDR_BYTES+i]= val;
+
+  return arr;
+}
+
+#endif // #ifndef MYSQL_CLIENT
+
+/**
+   check_extra_data
+
+   Called during self-test to check that
+   binlog row event extra data is self-
+   consistent as defined by the set_extra_data
+   function above.
+
+   Will assert(false) if not.
+
+   @param extra_row_data
+*/
+void check_extra_data(uchar* extra_row_data)
+{
+  assert(extra_row_data);
+  uint16 len= extra_row_data[EXTRA_ROW_INFO_LEN_OFFSET];
+  uint8 val= len - EXTRA_ROW_INFO_HDR_BYTES;
+  assert(extra_row_data[EXTRA_ROW_INFO_FORMAT_OFFSET] == val);
+  for (uint16 i= 0; i < val; i++)
+  {
+    assert(extra_row_data[EXTRA_ROW_INFO_HDR_BYTES + i] == val);
+  }
+}
+
+#endif  // #ifndef DBUG_OFF
 
 /**************************************************************************
 	Rows_log_event member functions
@@ -8648,7 +8752,9 @@ const char *sql_ex_info::init(const char
 
 #ifndef MYSQL_CLIENT
 Rows_log_event::Rows_log_event(THD *thd_arg, TABLE *tbl_arg, ulong tid,
-                               MY_BITMAP const *cols, bool using_trans)
+                               MY_BITMAP const *cols, bool using_trans,
+                               Log_event_type event_type,
+                               const uchar* extra_row_info)
   : Log_event(thd_arg, 0,
              using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
                            Log_event::EVENT_STMT_CACHE,
@@ -8657,7 +8763,8 @@ Rows_log_event::Rows_log_event(THD *thd_
     m_table(tbl_arg),
     m_table_id(tid),
     m_width(tbl_arg ? tbl_arg->s->fields : 1),
-    m_rows_buf(0), m_rows_cur(0), m_rows_end(0), m_flags(0) 
+    m_rows_buf(0), m_rows_cur(0), m_rows_end(0), m_flags(0),
+    m_type(event_type), m_extra_row_data(0)
 #ifdef HAVE_REPLICATION
     , m_curr_row(NULL), m_curr_row_end(NULL), m_key(NULL)
 #endif
@@ -8675,6 +8782,27 @@ Rows_log_event::Rows_log_event(THD *thd_
       set_flags(NO_FOREIGN_KEY_CHECKS_F);
   if (thd_arg->variables.option_bits & OPTION_RELAXED_UNIQUE_CHECKS)
       set_flags(RELAXED_UNIQUE_CHECKS_F);
+#ifndef DBUG_OFF
+  uchar extra_data[255];
+  DBUG_EXECUTE_IF("extra_row_data_set",
+                  /* Set extra row data to a known value */
+                  extra_row_info = set_extra_data(extra_data););
+#endif
+  if (extra_row_info)
+  {
+    /* Copy Extra data from thd into new event */
+    uint8 extra_data_len= extra_row_info[EXTRA_ROW_INFO_LEN_OFFSET];
+    assert(extra_data_len >= EXTRA_ROW_INFO_HDR_BYTES);
+
+    m_extra_row_data= (uchar*) my_malloc(extra_data_len, MYF(MY_WME));
+
+    if (likely(m_extra_row_data != NULL))
+    {
+      memcpy(m_extra_row_data, extra_row_info,
+             extra_data_len);
+    }
+  }
+
   /* if bitmap_init fails, caught in is_valid() */
   if (likely(!bitmap_init(&m_cols,
                           m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL,
@@ -8697,7 +8825,6 @@ Rows_log_event::Rows_log_event(THD *thd_
 #endif
 
 Rows_log_event::Rows_log_event(const char *buf, uint event_len,
-                               Log_event_type event_type,
                                const Format_description_log_event
                                *description_event)
   : Log_event(buf, description_event),
@@ -8705,13 +8832,17 @@ Rows_log_event::Rows_log_event(const cha
 #ifndef MYSQL_CLIENT
     m_table(NULL),
 #endif
-    m_table_id(0), m_rows_buf(0), m_rows_cur(0), m_rows_end(0)
+    m_table_id(0), m_rows_buf(0), m_rows_cur(0), m_rows_end(0),
+    m_extra_row_data(0)
 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
     , m_curr_row(NULL), m_curr_row_end(NULL), m_key(NULL)
 #endif
 {
   DBUG_ENTER("Rows_log_event::Rows_log_event(const char*,...)");
   uint8 const common_header_len= description_event->common_header_len;
+  Log_event_type event_type= (Log_event_type) buf[EVENT_TYPE_OFFSET];
+  m_type= event_type;
+
   uint8 const post_header_len= description_event->post_header_len[event_type-1];
 
   DBUG_PRINT("enter",("event_len: %u  common_header_len: %d  "
@@ -8734,9 +8865,57 @@ Rows_log_event::Rows_log_event(const cha
   }
 
   m_flags= uint2korr(post_start);
+  post_start+= 2;
+
+  uint16 var_header_len= 0;
+  if (post_header_len == ROWS_HEADER_LEN_V2)
+  {
+    /*
+      Have variable length header, check length,
+      which includes length bytes
+    */
+    var_header_len= uint2korr(post_start);
+    assert(var_header_len >= 2);
+    var_header_len-= 2;
+
+    /* Iterate over var-len header, extracting 'chunks' */
+    const char* start= post_start + 2;
+    const char* end= start + var_header_len;
+    for (const char* pos= start; pos < end;)
+    {
+      switch(*pos++)
+      {
+      case RW_V_EXTRAINFO_TAG:
+      {
+        /* Have an 'extra info' section, read it in */
+        assert((end - pos) >= EXTRA_ROW_INFO_HDR_BYTES);
+        uint8 infoLen= pos[EXTRA_ROW_INFO_LEN_OFFSET];
+        assert((end - pos) >= infoLen);
+        /* Just store/use the first tag of this type, skip others */
+        if (likely(!m_extra_row_data))
+        {
+          m_extra_row_data= (uchar*) my_malloc(infoLen,
+                                               MYF(MY_WME));
+          if (likely(m_extra_row_data != NULL))
+          {
+            memcpy(m_extra_row_data, pos, infoLen);
+          }
+          DBUG_EXECUTE_IF("extra_row_data_check",
+                          /* Check extra data has expected value */
+                          check_extra_data(m_extra_row_data););
+        }
+        pos+= infoLen;
+        break;
+      }
+      default:
+        /* Unknown code, we will not understand anything further here */
+        pos= end; /* Break loop */
+      }
+    }
+  }
 
   uchar const *const var_start=
-    (const uchar *)buf + common_header_len + post_header_len;
+    (const uchar *)buf + common_header_len + post_header_len + var_header_len;
   uchar const *const ptr_width= var_start;
   uchar *ptr_after_width= (uchar*) ptr_width;
   DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
@@ -8763,7 +8942,8 @@ Rows_log_event::Rows_log_event(const cha
 
   m_cols_ai.bitmap= m_cols.bitmap; /* See explanation in is_valid() */
 
-  if (event_type == UPDATE_ROWS_EVENT)
+  if ((event_type == UPDATE_ROWS_EVENT) ||
+      (event_type == UPDATE_ROWS_EVENT_V1))
   {
     DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
 
@@ -8816,24 +8996,38 @@ Rows_log_event::~Rows_log_event()
     m_cols.bitmap= 0; // so no my_free in bitmap_free
   bitmap_free(&m_cols); // To pair with bitmap_init().
   my_free(m_rows_buf);
+  my_free(m_extra_row_data);
 }
 
 int Rows_log_event::get_data_size()
 {
-  int const type_code= get_type_code();
+  int const general_type_code= get_general_type_code();
 
   uchar buf[sizeof(m_width) + 1];
   uchar *end= net_store_length(buf, m_width);
 
   DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
                   return 6 + no_bytes_in_map(&m_cols) + (end - buf) +
-                  (type_code == UPDATE_ROWS_EVENT ? no_bytes_in_map(&m_cols_ai) : 0) +
+                  (general_type_code == UPDATE_ROWS_EVENT ? no_bytes_in_map(&m_cols_ai) : 0) +
                   (m_rows_cur - m_rows_buf););
-  int data_size= ROWS_HEADER_LEN;
+
+  int data_size= 0;
+  bool is_v2_event= get_type_code() > DELETE_ROWS_EVENT_V1;
+  if (is_v2_event)
+  {
+    data_size= ROWS_HEADER_LEN_V2 +
+      (m_extra_row_data ?
+       RW_V_TAG_LEN + m_extra_row_data[EXTRA_ROW_INFO_LEN_OFFSET]:
+       0);
+  }
+  else
+  {
+    data_size= ROWS_HEADER_LEN_V1;
+  }
   data_size+= no_bytes_in_map(&m_cols);
   data_size+= (uint) (end - buf);
 
-  if (type_code == UPDATE_ROWS_EVENT)
+  if (general_type_code == UPDATE_ROWS_EVENT)
     data_size+= no_bytes_in_map(&m_cols_ai);
 
   data_size+= (uint) (m_rows_cur - m_rows_buf);
@@ -9010,6 +9204,8 @@ int Rows_log_event::do_apply_event(Relay
     else
       thd->variables.option_bits&= ~OPTION_ALLOW_BATCH;
 
+    thd->binlog_row_event_extra_data = m_extra_row_data;
+
     /* A small test to verify that objects have consistent types */
     DBUG_ASSERT(sizeof(thd->variables.option_bits) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
 
@@ -9118,6 +9314,8 @@ int Rows_log_event::do_apply_event(Relay
     */
     thd->set_time(&when);
 
+    thd->binlog_row_event_extra_data = m_extra_row_data;
+
     /*
       Now we are in a statement and will stay in a statement until we
       see a STMT_END_F.
@@ -9145,13 +9343,13 @@ int Rows_log_event::do_apply_event(Relay
     DBUG_PRINT_BITSET("debug", "Setting table's write_set from: %s", &m_cols);
     
     bitmap_set_all(table->read_set);
-    if (get_type_code() == DELETE_ROWS_EVENT)
+    if (get_general_type_code() == DELETE_ROWS_EVENT)
         bitmap_intersect(table->read_set,&m_cols);
 
     bitmap_set_all(table->write_set);
     if (!get_flags(COMPLETE_ROWS_F))
     {
-      if (get_type_code() == UPDATE_ROWS_EVENT)
+      if (get_general_type_code() == UPDATE_ROWS_EVENT)
         bitmap_intersect(table->write_set,&m_cols_ai);
       else /* WRITE ROWS EVENTS store the bitmap in m_cols instead of m_cols_ai */
         bitmap_intersect(table->write_set,&m_cols);
@@ -9452,7 +9650,7 @@ Rows_log_event::do_update_pos(Relay_log_
 #ifndef MYSQL_CLIENT
 bool Rows_log_event::write_data_header(IO_CACHE *file)
 {
-  uchar buf[ROWS_HEADER_LEN];	// No need to init the buffer
+  uchar buf[ROWS_HEADER_LEN_V2];	// No need to init the buffer
   DBUG_ASSERT(m_table_id != ~0UL);
   DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
                   {
@@ -9462,7 +9660,43 @@ bool Rows_log_event::write_data_header(I
                   });
   int6store(buf + RW_MAPID_OFFSET, (ulonglong)m_table_id);
   int2store(buf + RW_FLAGS_OFFSET, m_flags);
-  return (wrapper_my_b_safe_write(file, buf, ROWS_HEADER_LEN));
+  int rc = 0;
+  if (likely(!log_bin_use_v1_row_events))
+  {
+    /*
+       v2 event, with variable header portion.
+       Determine length of variable header payload
+    */
+    uint16 vhlen= 2;
+    uint16 vhpayloadlen= 0;
+    uint16 extra_data_len= 0;
+    if (m_extra_row_data)
+    {
+      extra_data_len= m_extra_row_data[EXTRA_ROW_INFO_LEN_OFFSET];
+      vhpayloadlen= RW_V_TAG_LEN + extra_data_len;
+    }
+
+    /* Var-size header len includes len itself */
+    int2store(buf + RW_VHLEN_OFFSET, vhlen + vhpayloadlen);
+    rc= wrapper_my_b_safe_write(file, buf, ROWS_HEADER_LEN_V2);
+
+    /* Write var-sized payload, if any */
+    if ((vhpayloadlen > 0) &&
+        (rc == 0))
+    {
+      /* Add tag and extra row info */
+      uchar type_code= RW_V_EXTRAINFO_TAG;
+      rc= wrapper_my_b_safe_write(file, &type_code, RW_V_TAG_LEN);
+      if (rc==0)
+        rc= wrapper_my_b_safe_write(file, m_extra_row_data, extra_data_len);
+    }
+  }
+  else
+  {
+    rc= wrapper_my_b_safe_write(file, buf, ROWS_HEADER_LEN_V1);
+  }
+
+  return (rc != 0);
 }
 
 bool Rows_log_event::write_data_body(IO_CACHE*file)
@@ -9486,7 +9720,7 @@ bool Rows_log_event::write_data_body(IO_
   /*
     TODO[refactor write]: Remove the "down cast" here (and elsewhere).
    */
-  if (get_type_code() == UPDATE_ROWS_EVENT)
+  if (get_general_type_code() == UPDATE_ROWS_EVENT)
   {
     DBUG_DUMP("m_cols_ai", (uchar*) m_cols_ai.bitmap,
               no_bytes_in_map(&m_cols_ai));
@@ -10152,8 +10386,13 @@ void Table_map_log_event::print(FILE *, 
 #if !defined(MYSQL_CLIENT)
 Write_rows_log_event::Write_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
                                            ulong tid_arg,
-                                           bool is_transactional)
-  : Rows_log_event(thd_arg, tbl_arg, tid_arg, tbl_arg->write_set, is_transactional)
+                                           bool is_transactional,
+                                           const uchar* extra_row_info)
+  : Rows_log_event(thd_arg, tbl_arg, tid_arg, tbl_arg->write_set, is_transactional,
+                   log_bin_use_v1_row_events?
+                   WRITE_ROWS_EVENT_V1:
+                   WRITE_ROWS_EVENT,
+                   extra_row_info)
 {
 }
 #endif
@@ -10165,7 +10404,7 @@ Write_rows_log_event::Write_rows_log_eve
 Write_rows_log_event::Write_rows_log_event(const char *buf, uint event_len,
                                            const Format_description_log_event
                                            *description_event)
-: Rows_log_event(buf, event_len, WRITE_ROWS_EVENT, description_event)
+: Rows_log_event(buf, event_len, description_event)
 {
 }
 #endif
@@ -11343,8 +11582,13 @@ err:
 #ifndef MYSQL_CLIENT
 Delete_rows_log_event::Delete_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
                                              ulong tid,
-                                             bool is_transactional)
-  : Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional)
+                                             bool is_transactional,
+                                             const uchar* extra_row_info)
+  : Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional,
+                   log_bin_use_v1_row_events?
+                   DELETE_ROWS_EVENT_V1:
+                   DELETE_ROWS_EVENT,
+                   extra_row_info)
 {
 }
 #endif /* #if !defined(MYSQL_CLIENT) */
@@ -11356,7 +11600,7 @@ Delete_rows_log_event::Delete_rows_log_e
 Delete_rows_log_event::Delete_rows_log_event(const char *buf, uint event_len,
                                              const Format_description_log_event
                                              *description_event)
-  : Rows_log_event(buf, event_len, DELETE_ROWS_EVENT, description_event)
+  : Rows_log_event(buf, event_len, description_event)
 {
 }
 #endif
@@ -11434,8 +11678,13 @@ void Delete_rows_log_event::print(FILE *
 #if !defined(MYSQL_CLIENT)
 Update_rows_log_event::Update_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
                                              ulong tid,
-                                             bool is_transactional)
-: Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional)
+                                             bool is_transactional,
+                                             const uchar* extra_row_info)
+: Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional,
+                 log_bin_use_v1_row_events?
+                 UPDATE_ROWS_EVENT_V1:
+                 UPDATE_ROWS_EVENT,
+                 extra_row_info)
 {
   init(tbl_arg->write_set);
 }
@@ -11475,7 +11724,7 @@ Update_rows_log_event::Update_rows_log_e
                                              const
                                              Format_description_log_event
                                              *description_event)
-  : Rows_log_event(buf, event_len, UPDATE_ROWS_EVENT, description_event)
+  : Rows_log_event(buf, event_len, description_event)
 {
 }
 #endif

=== modified file 'sql/log_event.h'
--- a/sql/log_event.h	2012-04-21 12:11:15 +0000
+++ b/sql/log_event.h	2012-04-24 16:52:56 +0000
@@ -262,14 +262,14 @@ struct sql_ex_info
 #define FORMAT_DESCRIPTION_HEADER_LEN (START_V3_HEADER_LEN+1+LOG_EVENT_TYPES)
 #define XID_HEADER_LEN         0
 #define BEGIN_LOAD_QUERY_HEADER_LEN APPEND_BLOCK_HEADER_LEN
-#define ROWS_HEADER_LEN        8
+#define ROWS_HEADER_LEN_V1     8
 #define TABLE_MAP_HEADER_LEN   8
 #define EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN (4 + 4 + 4 + 1)
 #define EXECUTE_LOAD_QUERY_HEADER_LEN  (QUERY_HEADER_LEN + EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN)
 #define INCIDENT_HEADER_LEN    2
 #define HEARTBEAT_HEADER_LEN   0
 #define IGNORABLE_HEADER_LEN   0
-#define RESERVED_HEADER_LEN    0
+#define ROWS_HEADER_LEN_V2     10
 
 /*
    The maximum number of updated databases that a status of
@@ -437,6 +437,9 @@ struct sql_ex_info
 /* RW = "RoWs" */
 #define RW_MAPID_OFFSET    0
 #define RW_FLAGS_OFFSET    6
+#define RW_VHLEN_OFFSET    8
+#define RW_V_TAG_LEN       1
+#define RW_V_EXTRAINFO_TAG 0
 
 /* ELQ = "Execute Load Query" */
 #define ELQ_FILE_ID_OFFSET QUERY_HEADER_LEN
@@ -666,11 +669,11 @@ enum Log_event_type
   PRE_GA_DELETE_ROWS_EVENT = 22,
 
   /*
-    These event numbers are used from 5.1.16 and forward
+    These event numbers are used from 5.1.16 until mysql-trunk-xx
    */
-  WRITE_ROWS_EVENT = 23,
-  UPDATE_ROWS_EVENT = 24,
-  DELETE_ROWS_EVENT = 25,
+  WRITE_ROWS_EVENT_V1 = 23,
+  UPDATE_ROWS_EVENT_V1 = 24,
+  DELETE_ROWS_EVENT_V1 = 25,
 
   /*
     Something out of the ordinary happened on the master
@@ -692,10 +695,10 @@ enum Log_event_type
   IGNORABLE_LOG_EVENT= 28,
   ROWS_QUERY_LOG_EVENT= 29,
 
-  /* Following event numbers reserved for WL#5917 */
-  RESERVED_EVENT_NUM_1 = 30,
-  RESERVED_EVENT_NUM_2 = 31,
-  RESERVED_EVENT_NUM_3 = 32,
+  /* Version 2 of the Row events */
+  WRITE_ROWS_EVENT = 30,
+  UPDATE_ROWS_EVENT = 31,
+  DELETE_ROWS_EVENT = 32,
 
   GTID_LOG_EVENT= 33,
   ANONYMOUS_GTID_LOG_EVENT= 34,
@@ -3885,6 +3888,9 @@ public:
   void clear_flags(flag_set flags_arg) { m_flags &= ~flags_arg; }
   flag_set get_flags(flag_set flags_arg) const { return m_flags & flags_arg; }
 
+  Log_event_type get_type_code() { return m_type; } /* Specific type (_V1 etc) */
+  virtual Log_event_type get_general_type_code() = 0; /* General rows op type, no version */
+
 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
   virtual int pack_info(Protocol *protocol);
 #endif
@@ -3940,7 +3946,7 @@ public:
   {
     bool res= FALSE;
 
-    switch (get_type_code())
+    switch (get_general_type_code())
     {
       case DELETE_ROWS_EVENT:
         res= bitmap_cmp(get_cols(), table->read_set);
@@ -3981,6 +3987,8 @@ public:
 
   uint     m_row_count;         /* The number of rows added to the event */
 
+  const uchar* get_extra_row_data() const   { return m_extra_row_data; }
+
 protected:
   /* 
      The constructors are protected since you're supposed to inherit
@@ -3988,10 +3996,11 @@ protected:
   */
 #ifdef MYSQL_SERVER
   Rows_log_event(THD*, TABLE*, ulong table_id, 
-		 MY_BITMAP const *cols, bool is_transactional);
+		 MY_BITMAP const *cols, bool is_transactional,
+                 Log_event_type event_type,
+                 const uchar* extra_row_info);
 #endif
   Rows_log_event(const char *row_data, uint event_len, 
-		 Log_event_type event_type,
 		 const Format_description_log_event *description_event);
 
 #ifdef MYSQL_CLIENT
@@ -4029,6 +4038,11 @@ protected:
 
   flag_set m_flags;		/* Flags for row-level events */
 
+  Log_event_type m_type;        /* Actual event type */
+
+  uchar    *m_extra_row_data;   /* Pointer to extra row data if any */
+                                /* If non null, first byte is length */
+
   /* helper functions */
 
 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
@@ -4137,7 +4151,8 @@ public:
 
 #if defined(MYSQL_SERVER)
   Write_rows_log_event(THD*, TABLE*, ulong table_id, 
-		       bool is_transactional);
+		       bool is_transactional,
+                       const uchar* extra_row_info);
 #endif
 #ifdef HAVE_REPLICATION
   Write_rows_log_event(const char *buf, uint event_len, 
@@ -4151,12 +4166,12 @@ public:
                                           const uchar *after_record)
   {
     return thd->binlog_write_row(table, is_transactional,
-                                 after_record);
+                                 after_record, NULL);
   }
 #endif
 
 private:
-  virtual Log_event_type get_type_code() { return (Log_event_type)TYPE_CODE; }
+  virtual Log_event_type get_general_type_code() { return (Log_event_type)TYPE_CODE; }
 
 #ifdef MYSQL_CLIENT
   void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
@@ -4195,10 +4210,12 @@ public:
   Update_rows_log_event(THD*, TABLE*, ulong table_id,
 			MY_BITMAP const *cols_bi,
 			MY_BITMAP const *cols_ai,
-                        bool is_transactional);
+                        bool is_transactional,
+                        const uchar* extra_row_info);
 
   Update_rows_log_event(THD*, TABLE*, ulong table_id,
-                        bool is_transactional);
+                        bool is_transactional,
+                        const uchar* extra_row_info);
 
   void init(MY_BITMAP const *cols);
 #endif
@@ -4217,7 +4234,7 @@ public:
                                           const uchar *after_record)
   {
     return thd->binlog_update_row(table, is_transactional,
-                                  before_record, after_record);
+                                  before_record, after_record, NULL);
   }
 #endif
 
@@ -4227,7 +4244,7 @@ public:
   }
 
 protected:
-  virtual Log_event_type get_type_code() { return (Log_event_type)TYPE_CODE; }
+  virtual Log_event_type get_general_type_code() { return (Log_event_type)TYPE_CODE; }
 
 #ifdef MYSQL_CLIENT
   void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
@@ -4271,7 +4288,7 @@ public:
 
 #ifdef MYSQL_SERVER
   Delete_rows_log_event(THD*, TABLE*, ulong, 
-			bool is_transactional);
+			bool is_transactional, const uchar* extra_row_info);
 #endif
 #ifdef HAVE_REPLICATION
   Delete_rows_log_event(const char *buf, uint event_len, 
@@ -4285,12 +4302,12 @@ public:
                                           __attribute__((unused)))
   {
     return thd->binlog_delete_row(table, is_transactional,
-                                  before_record);
+                                  before_record, NULL);
   }
 #endif
   
 protected:
-  virtual Log_event_type get_type_code() { return (Log_event_type)TYPE_CODE; }
+  virtual Log_event_type get_general_type_code() { return (Log_event_type)TYPE_CODE; }
 
 #ifdef MYSQL_CLIENT
   void print(FILE *file, PRINT_EVENT_INFO *print_event_info);

=== modified file 'sql/log_event_old.h'
--- a/sql/log_event_old.h	2012-03-06 14:29:42 +0000
+++ b/sql/log_event_old.h	2012-04-24 16:52:56 +0000
@@ -42,6 +42,8 @@
   but we keep them this way for now.  /Sven
 */
 
+/* These classes are based on the v1 RowsHeaderLen */
+#define ROWS_HEADER_LEN ROWS_HEADER_LEN_V1
 
 /**
   @class Old_rows_log_event
@@ -374,7 +376,7 @@ public:
                                           const uchar *after_record)
   {
     return thd->binlog_write_row(table, is_transactional,
-                                 after_record);
+                                 after_record, NULL);
   }
 #endif
 
@@ -448,7 +450,7 @@ public:
                                           const uchar *after_record)
   {
     return thd->binlog_update_row(table, is_transactional,
-                                  before_record, after_record);
+                                  before_record, after_record, NULL);
   }
 #endif
 
@@ -522,7 +524,7 @@ public:
                                           __attribute__((unused)))
   {
     return thd->binlog_delete_row(table, is_transactional,
-                                  before_record);
+                                  before_record, NULL);
   }
 #endif
   

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2012-04-20 08:55:22 +0000
+++ b/sql/mysqld.cc	2012-04-24 16:52:56 +0000
@@ -521,6 +521,7 @@ ulong specialflag=0;
 ulong binlog_cache_use= 0, binlog_cache_disk_use= 0;
 ulong binlog_stmt_cache_use= 0, binlog_stmt_cache_disk_use= 0;
 ulong max_connections, max_connect_errors;
+my_bool log_bin_use_v1_row_events= 0;
 /**
   Limit of the total number of prepared statements in the server.
   Is necessary to protect the server against out-of-memory attacks.

=== modified file 'sql/mysqld.h'
--- a/sql/mysqld.h	2012-04-20 08:55:22 +0000
+++ b/sql/mysqld.h	2012-04-24 16:52:56 +0000
@@ -190,6 +190,7 @@ extern uint  slave_net_timeout;
 extern ulong opt_mts_slave_parallel_workers;
 extern ulonglong opt_mts_pending_jobs_size_max;
 extern uint max_user_connections;
+extern my_bool log_bin_use_v1_row_events;
 extern ulong what_to_log,flush_time;
 extern ulong max_prepared_stmt_count, prepared_stmt_count;
 extern ulong open_files_limit;

=== modified file 'sql/rpl_constants.h'
--- a/sql/rpl_constants.h	2012-03-06 14:29:42 +0000
+++ b/sql/rpl_constants.h	2012-04-24 16:52:56 +0000
@@ -58,4 +58,44 @@ enum Master_Slave_Proto
 
 void add_master_slave_proto(ushort *flag, enum Master_Slave_Proto pt);
 bool is_master_slave_proto(ushort flag, enum Master_Slave_Proto pt);
+
+/**
+   Enumeration of the reserved formats of Binlog extra row information
+*/
+enum ExtraRowInfoFormat {
+  /** Ndb format */
+  ERIF_NDB          =   0,
+
+  /** Reserved formats  0 -> 63 inclusive */
+  ERIF_LASTRESERVED =  63,
+
+  /**
+      Available / uncontrolled formats
+      64 -> 254 inclusive
+  */
+  ERIF_OPEN1        =  64,
+  ERIF_OPEN2        =  65,
+
+  ERIF_LASTOPEN     =  254,
+
+  /**
+     Multi-payload format 255
+
+      Length is total length, payload is sequence of
+      sub-payloads with their own headers containing
+      length + format.
+  */
+  ERIF_MULTI        =  255
+};
+
+/*
+   1 byte length, 1 byte format
+   Length is total length in bytes, including 2 byte header
+   Length values 0 and 1 are currently invalid and reserved.
+*/
+#define EXTRA_ROW_INFO_LEN_OFFSET 0
+#define EXTRA_ROW_INFO_FORMAT_OFFSET 1
+#define EXTRA_ROW_INFO_HDR_BYTES 2
+#define EXTRA_ROW_INFO_MAX_PAYLOAD (255 - EXTRA_ROW_INFO_HDR_BYTES)
+
 #endif /* RPL_CONSTANTS_H */

=== modified file 'sql/rpl_injector.cc'
--- a/sql/rpl_injector.cc	2012-03-09 16:56:10 +0000
+++ b/sql/rpl_injector.cc	2012-04-24 16:52:56 +0000
@@ -173,7 +173,8 @@ int injector::transaction::use_table(ser
 
 int injector::transaction::write_row (server_id_type sid, table tbl, 
 				      MY_BITMAP const* cols, size_t colcnt,
-				      record_type record)
+				      record_type record,
+                                      const uchar* extra_row_info)
 {
    DBUG_ENTER("injector::transaction::write_row(...)");
 
@@ -186,15 +187,23 @@ int injector::transaction::write_row (se
    table::save_sets saveset(tbl, cols, cols);
 
    error= m_thd->binlog_write_row(tbl.get_table(), tbl.is_transactional(), 
-                                  record);
+                                  record, extra_row_info);
    m_thd->set_server_id(save_id);
    DBUG_RETURN(error);
 }
 
+int injector::transaction::write_row (server_id_type sid, table tbl,
+				      MY_BITMAP const* cols, size_t colcnt,
+				      record_type record)
+{
+  return write_row(sid, tbl, cols, colcnt, record, NULL);
+}
+
 
 int injector::transaction::delete_row(server_id_type sid, table tbl,
 				      MY_BITMAP const* cols, size_t colcnt,
-				      record_type record)
+				      record_type record,
+                                      const uchar* extra_row_info)
 {
    DBUG_ENTER("injector::transaction::delete_row(...)");
 
@@ -206,15 +215,23 @@ int injector::transaction::delete_row(se
    m_thd->set_server_id(sid);
    table::save_sets saveset(tbl, cols, cols);
    error= m_thd->binlog_delete_row(tbl.get_table(), tbl.is_transactional(), 
-                                   record);
+                                   record, extra_row_info);
    m_thd->set_server_id(save_id);
    DBUG_RETURN(error);
 }
 
+int injector::transaction::delete_row(server_id_type sid, table tbl,
+				      MY_BITMAP const* cols, size_t colcnt,
+				      record_type record)
+{
+  return delete_row(sid, tbl, cols, colcnt, record, NULL);
+}
+
 
 int injector::transaction::update_row(server_id_type sid, table tbl, 
 				      MY_BITMAP const* cols, size_t colcnt,
-				      record_type before, record_type after)
+				      record_type before, record_type after,
+                                      const uchar* extra_row_info)
 {
    DBUG_ENTER("injector::transaction::update_row(...)");
 
@@ -228,11 +245,17 @@ int injector::transaction::update_row(se
    table::save_sets saveset(tbl, cols, cols);
 
    error= m_thd->binlog_update_row(tbl.get_table(), tbl.is_transactional(), 
-                                   before, after);
+                                   before, after, extra_row_info);
    m_thd->set_server_id(save_id);
    DBUG_RETURN(error);
 }
 
+int injector::transaction::update_row(server_id_type sid, table tbl,
+				      MY_BITMAP const* cols, size_t colcnt,
+				      record_type before, record_type after)
+{
+  return update_row(sid, tbl, cols, colcnt, before, after, NULL);
+}
 
 injector::transaction::binlog_pos injector::transaction::start_pos() const
 {

=== modified file 'sql/rpl_injector.h'
--- a/sql/rpl_injector.h	2012-03-09 16:56:10 +0000
+++ b/sql/rpl_injector.h	2012-04-24 16:52:56 +0000
@@ -206,20 +206,31 @@ public:
       */
       int write_row (server_id_type sid, table tbl, 
                      MY_BITMAP const *cols, size_t colcnt,
-                     record_type record);
+                     record_type record,
+                     const uchar* extra_row_info);
+      int write_row (server_id_type sid, table tbl,
+                      MY_BITMAP const *cols, size_t colcnt,
+                      record_type record);
 
       /*
         Add a 'delete row' entry to the transaction.
       */
       int delete_row(server_id_type sid, table tbl, 
                      MY_BITMAP const *cols, size_t colcnt,
+                     record_type record,
+                     const uchar* extra_row_info);
+      int delete_row(server_id_type sid, table tbl,
+                     MY_BITMAP const *cols, size_t colcnt,
                      record_type record);
-
       /*
         Add an 'update row' entry to the transaction.
       */
       int update_row(server_id_type sid, table tbl, 
                      MY_BITMAP const *cols, size_t colcnt,
+                     record_type before, record_type after,
+                     const uchar* extra_row_info);
+      int update_row(server_id_type sid, table tbl,
+                     MY_BITMAP const *cols, size_t colcnt,
                      record_type before, record_type after);
 
       /*

=== modified file 'sql/sql_binlog.cc'
--- a/sql/sql_binlog.cc	2012-03-06 14:29:42 +0000
+++ b/sql/sql_binlog.cc	2012-04-24 16:52:56 +0000
@@ -81,6 +81,9 @@ static int check_event_type(int type, Re
   case WRITE_ROWS_EVENT:
   case UPDATE_ROWS_EVENT:
   case DELETE_ROWS_EVENT:
+  case WRITE_ROWS_EVENT_V1:
+  case UPDATE_ROWS_EVENT_V1:
+  case DELETE_ROWS_EVENT_V1:
   case PRE_GA_WRITE_ROWS_EVENT:
   case PRE_GA_UPDATE_ROWS_EVENT:
   case PRE_GA_DELETE_ROWS_EVENT:

=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc	2012-04-21 12:11:15 +0000
+++ b/sql/sql_class.cc	2012-04-24 16:52:56 +0000
@@ -792,6 +792,7 @@ THD::THD(bool enable_plugins)
               /* statement id */ 0),
    rli_fake(0), rli_slave(NULL),
    in_sub_stmt(0),
+   binlog_row_event_extra_data(NULL),
    binlog_unsafe_warning_flags(0),
    binlog_table_maps(0),
    binlog_accessed_db_names(NULL),
@@ -1270,6 +1271,7 @@ void THD::init(void)
   update_charset();
   reset_current_stmt_binlog_format_row();
   memset(&status_var, 0, sizeof(status_var));
+  binlog_row_event_extra_data= 0;
 
   if (variables.sql_log_bin)
     variables.option_bits|= OPTION_BIN_LOG;

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2012-04-25 15:46:11 +0000
+++ b/sql/sql_class.h	2012-04-27 08:25:45 +0000
@@ -2357,6 +2357,15 @@ public:
   void set_next_event_pos(const char* _filename, ulonglong _pos);
   void clear_next_event_pos();
 
+  /*
+     Ptr to row event extra data to be written to Binlog /
+     received from Binlog.
+
+   */
+  uchar* binlog_row_event_extra_data;
+  static bool binlog_row_event_extra_data_eq(const uchar* a,
+                                             const uchar* b);
+
 #ifndef MYSQL_CLIENT
   int binlog_setup_trx_data();
 
@@ -2366,11 +2375,14 @@ public:
   int binlog_write_table_map(TABLE *table, bool is_transactional,
                              bool binlog_rows_query);
   int binlog_write_row(TABLE* table, bool is_transactional,
-                       const uchar *new_data);
+                       const uchar *new_data,
+                       const uchar* extra_row_info);
   int binlog_delete_row(TABLE* table, bool is_transactional,
-                        const uchar *old_data);
+                        const uchar *old_data,
+                        const uchar* extra_row_info);
   int binlog_update_row(TABLE* table, bool is_transactional,
-                        const uchar *old_data, const uchar *new_data);
+                        const uchar *old_data, const uchar *new_data,
+                        const uchar* extra_row_info);
   void binlog_prepare_row_images(TABLE* table);
 
   void set_server_id(uint32 sid) { server_id = sid; }
@@ -2382,7 +2394,8 @@ public:
     binlog_prepare_pending_rows_event(TABLE* table, uint32 serv_id,
                                       size_t needed,
                                       bool is_transactional,
-				      RowsEventT* hint);
+				      RowsEventT* hint,
+                                      const uchar* extra_row_info);
   Rows_log_event* binlog_get_pending_rows_event(bool is_transactional) const;
   void binlog_set_pending_rows_event(Rows_log_event* ev, bool is_transactional);
   inline int binlog_flush_pending_rows_event(bool stmt_end)

=== modified file 'sql/sys_vars.cc'
--- a/sql/sys_vars.cc	2012-04-13 12:00:39 +0000
+++ b/sql/sys_vars.cc	2012-04-24 16:52:56 +0000
@@ -1413,6 +1413,15 @@ static Sys_var_mybool Sys_trust_function
        GLOBAL_VAR(trust_function_creators),
        CMD_LINE(OPT_ARG), DEFAULT(FALSE));
 
+static Sys_var_mybool Sys_use_v1_row_events(
+       "log_bin_use_v1_row_events",
+       "If equal to 1 then version 1 row events are written to a row based "
+       "binary log.  If equal to 0, then the latest version of events are "
+       "written.  "
+       "This option is useful during some upgrades.",
+       GLOBAL_VAR(log_bin_use_v1_row_events),
+       CMD_LINE(OPT_ARG), DEFAULT(FALSE));
+
 static Sys_var_charptr Sys_log_error(
        "log_error", "Error log file",
        READ_ONLY GLOBAL_VAR(log_error_file_ptr),

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-trunk branch (magnus.blaudd:3749 to 3750) magnus.blaudd27 Apr