Commit 21614f4a authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-13898 Corruption during online table-rebuilding ALTER of ROW_FORMAT=REDUNDANT tables

This bug is a regression caused by the code refactoring in
commit f5a833c3. 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.
parent cd2a85e7
...@@ -167,7 +167,8 @@ ROLLBACK; ...@@ -167,7 +167,8 @@ ROLLBACK;
connection con1; connection con1;
KILL QUERY @id; KILL QUERY @id;
ERROR 70100: Query execution was interrupted 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; ALTER TABLE t1 ROW_FORMAT=REDUNDANT;
# session default # session default
connection default; connection default;
...@@ -180,6 +181,10 @@ ddl_online_create_index 1 ...@@ -180,6 +181,10 @@ ddl_online_create_index 1
ddl_pending_alter_table 1 ddl_pending_alter_table 1
ddl_sort_file_alter_table 0 ddl_sort_file_alter_table 0
ddl_log_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; KILL QUERY @id;
SET DEBUG_SYNC = 'now SIGNAL kill_done'; SET DEBUG_SYNC = 'now SIGNAL kill_done';
# session con1 # session con1
...@@ -227,6 +232,7 @@ t1 CREATE TABLE `t1` ( ...@@ -227,6 +232,7 @@ t1 CREATE TABLE `t1` (
`c3` char(255) NOT NULL, `c3` char(255) NOT NULL,
PRIMARY KEY (`c1`) PRIMARY KEY (`c1`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT ) 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 DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL rebuilt2 WAIT_FOR dml2_done';
SET lock_wait_timeout = 10; SET lock_wait_timeout = 10;
ALTER TABLE t1 ROW_FORMAT=COMPACT, ALGORITHM = INPLACE; ALTER TABLE t1 ROW_FORMAT=COMPACT, ALGORITHM = INPLACE;
......
...@@ -158,7 +158,8 @@ let $ID= `SELECT @id := CONNECTION_ID()`; ...@@ -158,7 +158,8 @@ let $ID= `SELECT @id := CONNECTION_ID()`;
--error ER_QUERY_INTERRUPTED --error ER_QUERY_INTERRUPTED
KILL QUERY @id; 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 --send
ALTER TABLE t1 ROW_FORMAT=REDUNDANT; ALTER TABLE t1 ROW_FORMAT=REDUNDANT;
...@@ -166,6 +167,10 @@ ALTER TABLE t1 ROW_FORMAT=REDUNDANT; ...@@ -166,6 +167,10 @@ ALTER TABLE t1 ROW_FORMAT=REDUNDANT;
connection default; connection default;
SET DEBUG_SYNC = 'now WAIT_FOR rebuilt'; SET DEBUG_SYNC = 'now WAIT_FOR rebuilt';
eval $innodb_metrics_select; 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`; let $ignore= `SELECT @id := $ID`;
KILL QUERY @id; KILL QUERY @id;
SET DEBUG_SYNC = 'now SIGNAL kill_done'; SET DEBUG_SYNC = 'now SIGNAL kill_done';
...@@ -201,6 +206,7 @@ WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_encrypted'); ...@@ -201,6 +206,7 @@ WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_encrypted');
--echo # session con1 --echo # session con1
connection con1; connection con1;
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
ALTER TABLE t1 ROW_FORMAT=REDUNDANT;
# Exceed the configured innodb_online_alter_log_max_size. # Exceed the configured innodb_online_alter_log_max_size.
# The actual limit is a multiple of innodb_sort_buf_size, # The actual limit is a multiple of innodb_sort_buf_size,
......
...@@ -853,7 +853,7 @@ row_log_table_low_redundant( ...@@ -853,7 +853,7 @@ row_log_table_low_redundant(
size = rec_get_converted_size_temp( size = rec_get_converted_size_temp(
index, tuple->fields, tuple->n_fields, &extra_size); 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; ? rec_get_converted_size_temp_v(index, ventry) : 0;
mrec_size = ROW_LOG_HEADER_SIZE + size + v_size + (extra_size >= 0x80); mrec_size = ROW_LOG_HEADER_SIZE + size + v_size + (extra_size >= 0x80);
...@@ -909,12 +909,10 @@ row_log_table_low_redundant( ...@@ -909,12 +909,10 @@ row_log_table_low_redundant(
rec_convert_dtuple_to_temp( rec_convert_dtuple_to_temp(
b + extra_size, index, tuple->fields, tuple->n_fields); b + extra_size, index, tuple->fields, tuple->n_fields);
b += size; b += size;
if (ventry) { ut_ad(!num_v == !v_size);
if (num_v) {
rec_convert_dtuple_to_temp_v(b, new_index, ventry); rec_convert_dtuple_to_temp_v(b, new_index, ventry);
b += v_size; b += v_size;
}
if (num_v) {
if (o_ventry) { if (o_ventry) {
rec_convert_dtuple_to_temp_v( rec_convert_dtuple_to_temp_v(
b, new_index, o_ventry); b, new_index, o_ventry);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment