Commit 6f5f7208 authored by Marko Mäkelä's avatar Marko Mäkelä Committed by Marko Mäkelä

Bug#22018745 CORRUPTION IN ONLINE TABLE REBUILD (ROW_FORMAT=REDUNDANT, INDEXED VIRTUAL COLUMN)

Apparently, WL#8149 QA did not cover the code changes made to
online table rebuild (which was introduced in MySQL 5.6.8 by WL#6255)
for ROW_FORMAT=REDUNDANT tables.

row_log_table_low_redundant(): Log the new values of indexed virtual
columns (ventry) only once.

row_log_table_low(): Assert that if o_ventry is specified, the
logged operation must not be ROW_T_INSERT, and ventry must be specified
as well.

row_log_table_low(): When computing the size of old_pk, pass v_entry=NULL to
rec_get_converted_size_temp(), to be consistent with the subsequent call
to rec_convert_dtuple_to_temp() for logging old_pk. Assert that
old_pk never contains information on virtual columns, thus proving that this
change is a no-op.

RB: 13822
Reviewed-by: default avatarJimmy Yang <jimmy.yang@oracle.com>
parent 223eb5fb
......@@ -223,5 +223,35 @@ vbcol
11
ac
drop table ibstd_14;
#
# Bug#22018745 CORRUPTION IN ONLINE TABLE REBUILD
# (ROW_FORMAT=REDUNDANT, INDEXED VIRTUAL COLUMN)
#
CREATE TABLE t (
b char(5) PRIMARY KEY,
v char(3) GENERATED ALWAYS AS (substr(b,1,3)) VIRTUAL, KEY(v)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=REDUNDANT;
connection con1;
SET DEBUG_SYNC='row_log_table_apply1_before SIGNAL prepared WAIT_FOR apply';
OPTIMIZE TABLE t;
connection default;
SET DEBUG_SYNC='now WAIT_FOR prepared';
INSERT INTO t SET b='fubar';
BEGIN;
DELETE FROM t;
ROLLBACK;
SET DEBUG_SYNC='now SIGNAL apply';
connection con1;
Table Op Msg_type Msg_text
test.t optimize note Table does not support optimize, doing recreate + analyze instead
test.t optimize status OK
connection default;
CHECK TABLE t;
Table Op Msg_type Msg_text
test.t check status OK
SELECT * FROM t;
b v
fubar fub
DROP TABLE t;
disconnect con1;
SET DEBUG_SYNC = 'RESET';
......@@ -233,6 +233,36 @@ select vbcol from ibstd_14;
drop table ibstd_14;
--echo #
--echo # Bug#22018745 CORRUPTION IN ONLINE TABLE REBUILD
--echo # (ROW_FORMAT=REDUNDANT, INDEXED VIRTUAL COLUMN)
--echo #
CREATE TABLE t (
b char(5) PRIMARY KEY,
v char(3) GENERATED ALWAYS AS (substr(b,1,3)) VIRTUAL, KEY(v)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=REDUNDANT;
connection con1;
SET DEBUG_SYNC='row_log_table_apply1_before SIGNAL prepared WAIT_FOR apply';
--send OPTIMIZE TABLE t
connection default;
SET DEBUG_SYNC='now WAIT_FOR prepared';
INSERT INTO t SET b='fubar';
BEGIN;
DELETE FROM t;
ROLLBACK;
SET DEBUG_SYNC='now SIGNAL apply';
connection con1;
reap;
connection default;
CHECK TABLE t;
SELECT * FROM t;
DROP TABLE t;
disconnect con1;
SET DEBUG_SYNC = 'RESET';
......
......@@ -820,12 +820,9 @@ row_log_table_low_redundant(
mrec_size = ROW_LOG_HEADER_SIZE + size + (extra_size >= 0x80);
if (ventry && ventry->n_v_fields > 0) {
ulint v_extra = 0;
mrec_size += rec_get_converted_size_temp(
index, NULL, 0, ventry, &v_extra);
if (num_v) {
if (o_ventry) {
ulint v_extra = 0;
mrec_size += rec_get_converted_size_temp(
index, NULL, 0, o_ventry, &v_extra);
}
......@@ -878,11 +875,7 @@ row_log_table_low_redundant(
ventry);
b += size;
if (ventry && ventry->n_v_fields > 0) {
rec_convert_dtuple_to_temp(
b, new_index, NULL, 0, ventry);
b += mach_read_from_2(b);
if (num_v) {
if (o_ventry) {
rec_convert_dtuple_to_temp(
b, new_index, NULL, 0, o_ventry);
......@@ -943,6 +936,13 @@ row_log_table_low(
ut_ad(fil_page_get_type(page_align(rec)) == FIL_PAGE_INDEX);
ut_ad(page_is_leaf(page_align(rec)));
ut_ad(!page_is_comp(page_align(rec)) == !rec_offs_comp(offsets));
/* old_pk=row_log_table_get_pk() [not needed in INSERT] is a prefix
of the clustered index record (PRIMARY KEY,DB_TRX_ID,DB_ROLL_PTR),
with no information on virtual columns */
ut_ad(!old_pk || !insert);
ut_ad(!old_pk || old_pk->n_v_fields == 0);
ut_ad(!o_ventry || !insert);
ut_ad(!o_ventry || ventry);
if (dict_index_is_corrupted(index)
|| !dict_index_is_online_ddl(index)
......@@ -996,7 +996,7 @@ row_log_table_low(
old_pk_size = rec_get_converted_size_temp(
new_index, old_pk->fields, old_pk->n_fields,
old_pk, &old_pk_extra_size);
NULL, &old_pk_extra_size);
ut_ad(old_pk_extra_size < 0x100);
mrec_size += 1/*old_pk_extra_size*/ + old_pk_size;
}
......
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