From 68bad3c7c0a0f0babcb18590d1cb2c6a2873eb15 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 11 Apr 2014 08:39:48 +0200 Subject: [PATCH 1/2] MDEV-6067: Partitioned table DML sometimes binlogged without XID event Revert the old patch revid:monty@askmonty.org-20100325133339-7mkel6valai0b4lb This patch caused the InnoDB part of the transaction to not be marked read-write in some cases, which messes up XA commit (and likely other stuff as well). --- sql/handler.cc | 7 ++----- sql/handler.h | 18 +++--------------- sql/sql_base.cc | 1 - 3 files changed, 5 insertions(+), 21 deletions(-) diff --git a/sql/handler.cc b/sql/handler.cc index eb53cfb76a7..9e4ac52656d 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -3245,14 +3245,11 @@ int handler::ha_check(THD *thd, HA_CHECK_OPT *check_opt) if it is started. */ +inline void -handler::mark_trx_read_write_part2() +handler::mark_trx_read_write() { Ha_trx_info *ha_info= &ha_thd()->ha_data[ht->slot].ha_info[0]; - - /* Don't call this function again for this statement */ - mark_trx_done= TRUE; - /* When a storage engine method is called, the transaction must have been started, unless it's a DDL call, for which the diff --git a/sql/handler.h b/sql/handler.h index 16bf3daa08c..1faf9761391 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1255,7 +1255,6 @@ public: enum {NONE=0, INDEX, RND} inited; bool locked; bool implicit_emptied; /* Can be !=0 only if HEAP */ - bool mark_trx_done; bool cloned; /* 1 if this was created with clone */ const COND *pushed_cond; /** @@ -1300,7 +1299,7 @@ public: ref(0), key_used_on_scan(MAX_KEY), active_index(MAX_KEY), ref_length(sizeof(my_off_t)), ft_handler(0), inited(NONE), - locked(FALSE), implicit_emptied(FALSE), mark_trx_done(FALSE), cloned(0), + locked(FALSE), implicit_emptied(FALSE), cloned(0), pushed_cond(0), next_insert_id(0), insert_id_for_cur_row(0), auto_inc_intervals_count(0) { @@ -1360,13 +1359,6 @@ public: } int ha_rnd_init_with_error(bool scan) __attribute__ ((warn_unused_result)); int ha_reset(); - /* Tell handler (not storage engine) this is start of a new statement */ - void ha_start_of_new_statement() - { - ft_handler= 0; - mark_trx_done= FALSE; - } - /* this is necessary in many places, e.g. in HANDLER command */ int ha_index_or_rnd_end() { @@ -1996,12 +1988,8 @@ protected: private: /* Private helpers */ - void mark_trx_read_write_part2(); - inline void mark_trx_read_write() - { - if (!mark_trx_done) - mark_trx_read_write_part2(); - } + inline void mark_trx_read_write(); +private: inline void increment_statistics(ulong SSV::*offset) const; inline void decrement_statistics(ulong SSV::*offset) const; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index c1c12166543..91e7949cc2a 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -3029,7 +3029,6 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, table->status=STATUS_NO_RECORD; table->insert_values= 0; table->fulltext_searched= 0; - table->file->ha_start_of_new_statement(); table->file->ft_handler= 0; /* Check that there is no reference to a condition from an earlier query From a1ae8f9ba86bf3967b0b55439c306ff611913345 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 11 Apr 2014 09:03:53 +0200 Subject: [PATCH 2/2] MDEV-6067: Partitioned table DML sometimes binlogged without XID event Add test case. --- .../suite/parts/r/partition_mdev6067.result | 38 +++++++++++++++++++ .../suite/parts/t/partition_mdev6067.test | 32 ++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 mysql-test/suite/parts/r/partition_mdev6067.result create mode 100644 mysql-test/suite/parts/t/partition_mdev6067.test diff --git a/mysql-test/suite/parts/r/partition_mdev6067.result b/mysql-test/suite/parts/r/partition_mdev6067.result new file mode 100644 index 00000000000..7b123d7c17c --- /dev/null +++ b/mysql-test/suite/parts/r/partition_mdev6067.result @@ -0,0 +1,38 @@ +CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB +PARTITION BY KEY (a) PARTITIONS 2; +INSERT INTO t1 VALUES (1,1); +INSERT INTO t1 VALUES (2,2), (3,8); +INSERT INTO t1 VALUES (4,16); +show binlog events in 'master-bin.000001' from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (1,1) +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (2,2), (3,8) +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (4,16) +master-bin.000001 # Xid # # COMMIT /* XID */ +DROP TABLE t1; +SET binlog_format='row'; +CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB +PARTITION BY KEY (a) PARTITIONS 2; +INSERT INTO t1 VALUES (1,1); +INSERT INTO t1 VALUES (2,2), (3,8); +INSERT INTO t1 VALUES (4,16); +show binlog events in 'master-bin.000001' from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Xid # # COMMIT /* XID */ +DROP TABLE t1; diff --git a/mysql-test/suite/parts/t/partition_mdev6067.test b/mysql-test/suite/parts/t/partition_mdev6067.test new file mode 100644 index 00000000000..7d64de2e8a7 --- /dev/null +++ b/mysql-test/suite/parts/t/partition_mdev6067.test @@ -0,0 +1,32 @@ +--source include/have_innodb.inc +--source include/have_partition.inc +--source include/have_binlog_format_statement.inc + +# Test binlogging of some transactions on a partitioned InnoDB table. +# The bug was seen as one of the inserts being logged with a COMMIT query +# event instead of the correct XID event. + +CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB + PARTITION BY KEY (a) PARTITIONS 2; +--let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1) +--let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1) +INSERT INTO t1 VALUES (1,1); +INSERT INTO t1 VALUES (2,2), (3,8); +INSERT INTO t1 VALUES (4,16); + +--source include/show_binlog_events.inc + +# Same thing in row mode. +DROP TABLE t1; +SET binlog_format='row'; +CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB + PARTITION BY KEY (a) PARTITIONS 2; +--let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1) +--let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1) +INSERT INTO t1 VALUES (1,1); +INSERT INTO t1 VALUES (2,2), (3,8); +INSERT INTO t1 VALUES (4,16); + +--source include/show_binlog_events.inc + +DROP TABLE t1;