diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2017-09-25 09:29:27 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2017-09-25 09:29:27 +0300 |
commit | 21614f4a85deaaa771e3333ef003882c17677674 (patch) | |
tree | 802953c129683f2bcbe91613ab457d53daa48c4a | |
parent | cd2a85e763671dfe9f91fbc5a00aa6f747d8860d (diff) | |
download | mariadb-git-21614f4a85deaaa771e3333ef003882c17677674.tar.gz |
MDEV-13898 Corruption during online table-rebuilding ALTER of ROW_FORMAT=REDUNDANT tablesmariadb-10.2.9
This bug is a regression caused by the code refactoring in
commit f5a833c3e085524585d1ae5b8303c168f075dab3. It was not present
in any release of the MariaDB server. The bug affects table-rebuilding
ALTER TABLE when the source table is in ROW_FORMAT=REDUNDANT and
contains no virtual columns.
row_log_table_low_redundant(): Log virtual column data only if
virtual columns are present.
-rw-r--r-- | mysql-test/suite/innodb/r/innodb-table-online.result | 8 | ||||
-rw-r--r-- | mysql-test/suite/innodb/t/innodb-table-online.test | 8 | ||||
-rw-r--r-- | storage/innobase/row/row0log.cc | 8 |
3 files changed, 17 insertions, 7 deletions
diff --git a/mysql-test/suite/innodb/r/innodb-table-online.result b/mysql-test/suite/innodb/r/innodb-table-online.result index ec5199e4f52..d6a0d4785f5 100644 --- a/mysql-test/suite/innodb/r/innodb-table-online.result +++ b/mysql-test/suite/innodb/r/innodb-table-online.result @@ -167,7 +167,8 @@ ROLLBACK; connection con1; KILL QUERY @id; ERROR 70100: Query execution was interrupted -SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL rebuilt WAIT_FOR kill_done'; +SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL rebuilt WAIT_FOR dml_done'; +SET DEBUG_SYNC = 'row_log_table_apply2_before SIGNAL applied WAIT_FOR kill_done'; ALTER TABLE t1 ROW_FORMAT=REDUNDANT; # session default connection default; @@ -180,6 +181,10 @@ ddl_online_create_index 1 ddl_pending_alter_table 1 ddl_sort_file_alter_table 0 ddl_log_file_alter_table 0 +BEGIN; +INSERT INTO t1 VALUES(7,4,2); +ROLLBACK; +SET DEBUG_SYNC = 'now SIGNAL dml_done WAIT_FOR applied'; KILL QUERY @id; SET DEBUG_SYNC = 'now SIGNAL kill_done'; # session con1 @@ -227,6 +232,7 @@ t1 CREATE TABLE `t1` ( `c3` char(255) NOT NULL, PRIMARY KEY (`c1`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT +ALTER TABLE t1 ROW_FORMAT=REDUNDANT; SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL rebuilt2 WAIT_FOR dml2_done'; SET lock_wait_timeout = 10; ALTER TABLE t1 ROW_FORMAT=COMPACT, ALGORITHM = INPLACE; diff --git a/mysql-test/suite/innodb/t/innodb-table-online.test b/mysql-test/suite/innodb/t/innodb-table-online.test index 51f5445693e..d3fbeffd19f 100644 --- a/mysql-test/suite/innodb/t/innodb-table-online.test +++ b/mysql-test/suite/innodb/t/innodb-table-online.test @@ -158,7 +158,8 @@ let $ID= `SELECT @id := CONNECTION_ID()`; --error ER_QUERY_INTERRUPTED KILL QUERY @id; -SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL rebuilt WAIT_FOR kill_done'; +SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL rebuilt WAIT_FOR dml_done'; +SET DEBUG_SYNC = 'row_log_table_apply2_before SIGNAL applied WAIT_FOR kill_done'; --send ALTER TABLE t1 ROW_FORMAT=REDUNDANT; @@ -166,6 +167,10 @@ ALTER TABLE t1 ROW_FORMAT=REDUNDANT; connection default; SET DEBUG_SYNC = 'now WAIT_FOR rebuilt'; eval $innodb_metrics_select; +BEGIN; +INSERT INTO t1 VALUES(7,4,2); +ROLLBACK; +SET DEBUG_SYNC = 'now SIGNAL dml_done WAIT_FOR applied'; let $ignore= `SELECT @id := $ID`; KILL QUERY @id; SET DEBUG_SYNC = 'now SIGNAL kill_done'; @@ -201,6 +206,7 @@ WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_encrypted'); --echo # session con1 connection con1; SHOW CREATE TABLE t1; +ALTER TABLE t1 ROW_FORMAT=REDUNDANT; # Exceed the configured innodb_online_alter_log_max_size. # The actual limit is a multiple of innodb_sort_buf_size, diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc index 1385238f560..747959fcde5 100644 --- a/storage/innobase/row/row0log.cc +++ b/storage/innobase/row/row0log.cc @@ -853,7 +853,7 @@ row_log_table_low_redundant( size = rec_get_converted_size_temp( index, tuple->fields, tuple->n_fields, &extra_size); - ulint v_size = ventry + ulint v_size = num_v ? rec_get_converted_size_temp_v(index, ventry) : 0; mrec_size = ROW_LOG_HEADER_SIZE + size + v_size + (extra_size >= 0x80); @@ -909,12 +909,10 @@ row_log_table_low_redundant( rec_convert_dtuple_to_temp( b + extra_size, index, tuple->fields, tuple->n_fields); b += size; - if (ventry) { + ut_ad(!num_v == !v_size); + if (num_v) { rec_convert_dtuple_to_temp_v(b, new_index, ventry); b += v_size; - } - - if (num_v) { if (o_ventry) { rec_convert_dtuple_to_temp_v( b, new_index, o_ventry); |