mirror of
https://github.com/MariaDB/server.git
synced 2025-07-07 06:01:31 +03:00
When MySQL 5.7 introduced indexed virtual columns, it introduced several bugs into the online table-rebuilding ALTER, that is, the row_log_table_apply() family of functions. The online_log format that was introduced for online table-rebuilding ALTER in MySQL 5.6 should be sufficient. Ideally, any indexed virtual column values would be evaluated based on the log records in the temporary file. There is no need to log virtual column values. (For ADD INDEX, that is row_log_apply(), we always must log the values of the keys, no matter if the columns are virtual.) Because omitting the virtual column values removes any chance of row_log_table_apply() working with indexed virtual columns, we will for now refuse LOCK=NONE in table-rebuilding ALTER operations when indexes on virtual columns exist. This restriction would be lifted in MDEV-14341. innobase_indexed_virtual_exist(): New predicate, to determine if indexed virtual columns exist in a table definition. ha_innobase::check_if_supported_inplace_alter(): Refuse online rebuild if indexed virtual columns exist. rec_get_converted_size_temp_v(), rec_convert_dtuple_to_temp_v(): Remove. row_log_table_delete(), row_log_table_update(, row_log_table_insert(): Remove parameters for virtual columns. trx_undo_read_v_rows(): Remove the col_map parameter. row_log_table_apply(): Do not deal with virtual columns.
275 lines
7.3 KiB
Plaintext
275 lines
7.3 KiB
Plaintext
--source include/have_innodb.inc
|
|
--source include/have_debug_sync.inc
|
|
--source include/have_debug.inc
|
|
--source include/count_sessions.inc
|
|
|
|
set default_storage_engine=innodb;
|
|
CREATE TABLE `t` (
|
|
`a` VARCHAR(100),
|
|
`b` VARCHAR(100),
|
|
`c` VARCHAR(200) GENERATED ALWAYS AS (CONCAT(a,b)) VIRTUAL,
|
|
`h` VARCHAR(10) DEFAULT NULL,
|
|
`i` int
|
|
) ENGINE=InnoDB;
|
|
|
|
INSERT INTO t VALUES (REPEAT('g', 100), REPEAT('x', 10), DEFAULT, "kk", 1);
|
|
INSERT INTO t VALUES (REPEAT('a', 100), REPEAT('b', 100), DEFAULT, "mm", 2);
|
|
|
|
CREATE INDEX idx ON t(c(100));
|
|
|
|
SET session debug_dbug="+d,ib_alter_add_virtual_fail";
|
|
--error ER_WRONG_KEY_COLUMN
|
|
ALTER TABLE t ADD COLUMN x VARCHAR(200) GENERATED ALWAYS AS (a) VIRTUAL,
|
|
ALGORITHM = INPLACE;
|
|
--error ER_WRONG_KEY_COLUMN
|
|
ALTER TABLE t DROP COLUMN c, ALGORITHM = INPLACE;
|
|
SET session debug_dbug="";
|
|
DROP TABLE t;
|
|
|
|
#online test
|
|
CREATE TABLE t (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), h VARCHAR(10));
|
|
|
|
INSERT INTO t VALUES (11, 3, DEFAULT, 'mm');
|
|
INSERT INTO t VALUES (18, 1, DEFAULT, 'mm');
|
|
INSERT INTO t VALUES (28, 1, DEFAULT, 'mm');
|
|
INSERT INTO t VALUES (null, null, DEFAULT, "mx");
|
|
|
|
SET DEBUG_SYNC = 'innodb_inplace_alter_table_enter SIGNAL start_create WAIT_FOR go_ahead';
|
|
--send CREATE INDEX idx ON t(c)
|
|
|
|
connect (con1,localhost,root,,);
|
|
|
|
SET DEBUG_SYNC = 'now WAIT_FOR start_create';
|
|
update t set a=0 where a = 11;
|
|
start transaction;
|
|
update t set a=1 where a = 0;
|
|
ROLLBACK;
|
|
SET DEBUG_SYNC = 'now SIGNAL go_ahead';
|
|
|
|
connection default;
|
|
reap;
|
|
|
|
SELECT c FROM t;
|
|
SHOW CREATE TABLE t;
|
|
SELECT * FROM t;
|
|
|
|
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
|
|
ALTER TABLE t FORCE, LOCK=NONE;
|
|
if (0) {# MDEV-14341 TODO: re-enable this
|
|
SET DEBUG_SYNC = 'innodb_inplace_alter_table_enter SIGNAL start_create WAIT_FOR go_ahead';
|
|
--send ALTER TABLE t FORCE
|
|
|
|
connection con1;
|
|
|
|
SET DEBUG_SYNC = 'now WAIT_FOR start_create';
|
|
start transaction;
|
|
update t set a=1 where a = 0;
|
|
rollback;
|
|
start transaction;
|
|
delete from t;
|
|
insert into t values(1,null,default,null);
|
|
rollback;
|
|
start transaction;
|
|
update t set b=b+1;
|
|
rollback;
|
|
SET DEBUG_SYNC = 'now SIGNAL go_ahead';
|
|
|
|
connection default;
|
|
reap;
|
|
|
|
check table t;
|
|
SELECT c FROM t;
|
|
|
|
SET DEBUG_SYNC = 'innodb_inplace_alter_table_enter SIGNAL start_create WAIT_FOR go_ahead';
|
|
--send ALTER TABLE t FORCE
|
|
|
|
connection con1;
|
|
|
|
SET DEBUG_SYNC = 'now WAIT_FOR start_create';
|
|
start transaction;
|
|
DELETE FROM t WHERE a = 0;
|
|
ROLLBACK;
|
|
DELETE FROM t WHERE a = 0;
|
|
SET DEBUG_SYNC = 'now SIGNAL go_ahead';
|
|
|
|
connection default;
|
|
reap;
|
|
|
|
SELECT c FROM t;
|
|
}
|
|
|
|
disconnect con1;
|
|
DROP TABLE t;
|
|
|
|
SET DEBUG_SYNC = 'RESET';
|
|
|
|
|
|
# Test add virtual column and add index at the same time
|
|
# introduce some error
|
|
|
|
CREATE TABLE t (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), h VARCHAR(10));
|
|
|
|
INSERT INTO t VALUES (11, 3, DEFAULT, 'mm');
|
|
|
|
INSERT INTO t VALUES (18, 1, DEFAULT, 'mm');
|
|
|
|
INSERT INTO t VALUES (28, 1, DEFAULT, 'mm');
|
|
|
|
INSERT INTO t VALUES (null, null, DEFAULT, 'mm');
|
|
|
|
CREATE INDEX idx_1 on t(c);
|
|
|
|
SET SESSION debug_dbug="+d,create_index_fail";
|
|
|
|
--enable_info
|
|
--error ER_DUP_ENTRY
|
|
ALTER TABLE t ADD COLUMN x INT GENERATED ALWAYS AS(a+b), ADD INDEX idx (x);
|
|
SET SESSION debug_dbug="";
|
|
--disable_info
|
|
|
|
SHOW CREATE TABLE t;
|
|
|
|
SELECT c FROM t;
|
|
|
|
DROP TABLE t;
|
|
|
|
if (0) {# MDEV-14341 TODO: re-enable LOCK=NONE and these tests
|
|
--echo #
|
|
--echo # Bug#22018532 ASSERTION WHEN ONLINE REAPPLY REBUILD LOG ON
|
|
--echo # MULTIPLE INDEXED VIRTUAL COLUMNS
|
|
--echo #
|
|
|
|
create table t (
|
|
a int as (1) virtual,
|
|
b int,
|
|
c int as (1) virtual,
|
|
unique(b),
|
|
unique(c),
|
|
key(a)
|
|
) engine=innodb;
|
|
|
|
insert ignore into t values();
|
|
|
|
SET DEBUG_SYNC = 'innodb_inplace_alter_table_enter SIGNAL start_create WAIT_FOR go_ahead';
|
|
--send optimize table t
|
|
|
|
connect (con1,localhost,root,,);
|
|
|
|
SET DEBUG_SYNC = 'now WAIT_FOR start_create';
|
|
insert ignore into t values();
|
|
SET DEBUG_SYNC = 'now SIGNAL go_ahead';
|
|
|
|
connection default;
|
|
--echo /* connection default */ optimize table t;
|
|
reap;
|
|
SELECT c FROM t;
|
|
SHOW CREATE TABLE t;
|
|
SELECT * FROM t;
|
|
DROP TABLE t;
|
|
|
|
# Do another test without duplicate error
|
|
|
|
CREATE TABLE t (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), h VARCHAR(10));
|
|
|
|
INSERT INTO t VALUES (11, 3, DEFAULT, 'mm');
|
|
INSERT INTO t VALUES (18, 1, DEFAULT, 'mm');
|
|
INSERT INTO t VALUES (28, 1, DEFAULT, 'mm');
|
|
INSERT INTO t VALUES (null, null, DEFAULT, 'mm');
|
|
|
|
CREATE INDEX idx ON t(c);
|
|
|
|
SET DEBUG_SYNC = 'innodb_inplace_alter_table_enter SIGNAL start_rebuild WAIT_FOR go_ahead';
|
|
--send optimize table t
|
|
|
|
connection con1;
|
|
SET DEBUG_SYNC = 'now WAIT_FOR start_rebuild';
|
|
INSERT INTO t VALUES (48, 2, DEFAULT, 'xx');
|
|
INSERT INTO t VALUES (68, 3, DEFAULT, 'sx');
|
|
SET DEBUG_SYNC = 'now SIGNAL go_ahead';
|
|
|
|
connection default;
|
|
--echo /* connection default */ optimize table t;
|
|
reap;
|
|
|
|
SELECT c FROM t;
|
|
|
|
disconnect con1;
|
|
|
|
DROP TABLE t;
|
|
|
|
--echo #
|
|
--echo # Bug#22951879 - ASSERTS RELATED TO ONLINE DDL AND GCOL
|
|
--echo #
|
|
|
|
# Create a table with 2 virtual column, one (vbidxcol) is indexed and
|
|
# the other one (vbcol) is not
|
|
create table ibstd_14 (a int not null, d int not null, b varchar(198) not null, c char(181), vadcol int as (a+length(d)) stored, vbcol char(2) as (substr(b,2,2)) virtual, vbidxcol char(3) as (substr(b,1,3)) virtual , index(d), index(a), index(vbidxcol), index(a,vbidxcol), index(vbidxcol,d), unique key (b(10), a, d), index(c(99), b(31)), index(b(5), c(10), a) , index(a,d)) engine=InnoDB stats_persistent=1 row_format=dynamic;
|
|
|
|
# Do an alter table rebuild table and also create a new index on this
|
|
# non-indexed virtual column
|
|
SET DEBUG_SYNC = 'innodb_inplace_alter_table_enter SIGNAL start_create WAIT_FOR go_ahead';
|
|
--send alter table ibstd_14 row_format=compressed key_block_size=4,add key kn3 (d,c,vbcol,b)
|
|
|
|
# Do a concurrent insert, and make sure this newly indexed virtual column
|
|
# is also logged
|
|
connect (con1,localhost,root);
|
|
SET DEBUG_SYNC = 'now WAIT_FOR start_create';
|
|
insert into ibstd_14 (a,d,b,c, vbidxcol, vbcol) values ('118','6',repeat('oacolaarlruoacuroauurloraarucoooarcooauoolacalllaulrruarrrucruuooclacuoouccarrcoocloccorrrrarourcooalloocooccouruolaorlcaocualolc','1'),repeat('lolrrlalcocroraaulauclaaucolcorcuooaolruaooooluooooouaoorlarucorullalcrrloccououaooaorluorraclrcooouuolocoaolcocaaculruoocucoocoooauuolarcoraraocaoolulolarru','1'),default,default);
|
|
|
|
insert into ibstd_14 (a,d,b,c, vbidxcol, vbcol) values ('118','6', 'aaaa', 'lll', default, default);
|
|
|
|
# Also do an concurrent update, make sure this is performed
|
|
update ibstd_14 set b='11111' where b='aaaa';
|
|
|
|
SET DEBUG_SYNC = 'now SIGNAL go_ahead';
|
|
|
|
connection default;
|
|
reap;
|
|
|
|
select * from ibstd_14;
|
|
|
|
# This will use the newly added "kn3" index, to check materialized vbcol
|
|
# after log reapply
|
|
select d,c,vbcol,b from ibstd_14;
|
|
|
|
# check the value is inserted into the index
|
|
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';
|
|
|
|
--source include/wait_until_count_sessions.inc
|