Commit 84167947 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-11369 Rewrite innodb.instant_alter test

Create each table with a SPATIAL INDEX, because when MySQL 5.7
(and MariaDB 10.2.2) introduced SPATIAL INDEX for InnoDB tables,
a table-rebuilding LOCK=NONE would be refused if the table
contains any SPATIAL INDEX. With instant ADD COLUMN, the operations
must be allowed, and must report '0 rows affected' for everything
else except ROW_FORMAT=COMPRESSED tables.

FIXME: When instant ADD COLUMN is enabled, the ALGORITHM=INPLACE
will have to be changed to LOCK=NONE.
parent 0729217e
--source include/innodb_page_size.inc
#
# MMDEV-11369: Instant add columns for innodb
#
create database instant_alter;
use instant_alter;
set timestamp = 1;
set time_zone='+03:00';
eval CREATE TABLE `t1` ( `id` int(11) NOT NULL, `c2` int(11) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB ROW_FORMAT=$row_format;
insert into t1 (id, c2) values(1,1);
select * from t1;
# instant alter
alter table t1 add column (
`d1` int(11) DEFAULT NULL,
`d2` int(11) DEFAULT 10,
`d3` varchar(20) NOT NULL DEFAULT 'abcde',
`d4` timestamp NOT NULL DEFAULT current_timestamp());
select * from t1;
insert into t1 (id) values(2),(3),(4),(5),(6);
# add virtural columns
alter table t1 add column `e1` int(11) AS (`id` * 3);
alter table t1 add column `e2` varchar(30) AS (d3);
alter table t1 add column `e3` int(11) AS (`id` * 2);
# instant alter
alter table t1 add column (d5 varchar(20) default 'hijkl', d6 int default 12345, d7 int );
#select * from information_schema.innodb_sys_tables;
#select * from information_schema.innodb_sys_columns_added;
#select * from information_schema.innodb_sys_columns_added a, information_schema.innodb_sys_tables b where a.table_id = b.table_id and b.table_name like '%t1%';
# non-inplace update
update t1 set d3 = 'yyyyy' where id = 1;
# inplace update
update t1 set d3 = 'xxxxx' where id = 2;
# transaction rollback
begin;
update t1 set d3 = 'xxxxx' where id = 3;
select * from t1 where id = 3;
rollback;
select * from t1 where id = 3;
# null to null, no change
begin;
update t1 set d7 = null where id = 5;
rollback;
begin;
update t1 set d7 = null, d6 = 10 where id = 5;
select * from t1 where id = 5;
rollback;
select * from t1 where id = 5;
# add virtual stored columns, copy data
alter table t1 add column (f1 varchar(20) as (concat('x', e2)) stored);
# instant add
alter table t1 add column (d8 varchar(20) default 'omnopq');
select * from t1;
eval create table t2 (id int primary key, c1 varchar(4000), c2 varchar(4000), c3 varchar(1000)) ENGINE=InnoDB ROW_FORMAT=$row_format;
insert into t2 values(1, repeat('a', 4000), repeat('b', 4000), repeat('c', 1));
insert into t2 values(2, repeat('a', 4000), repeat('b', 4000), repeat('c', 1));
alter table t2 add column d1 varchar(2000) default 'fdsafadfdasfafgadsgdasfdassfdasfdassfdasfdassfdassfdasfdasfdassfdasfdassfdasfdasfdassfdsafdsfdasfdasfdasfdassfdasfdassfs';
select * from t2;
# inplace update, rollback
begin;
update t2 set c1 = repeat('c', 4000) where id = 1;
rollback;
# non-inplace update. Create new external columns when rollback.
begin;
update t2 set c1 = repeat('x', 200) where id = 1;
rollback;
select * from t2;
# alter change default values
eval CREATE TABLE t3(a INT PRIMARY KEY, b INT) ENGINE=InnoDB ROW_FORMAT=$row_format;
INSERT INTO t3 SET a=1;
# instantly add columns
ALTER TABLE t3 ADD COLUMN (c INT, d CHAR(10) NULL DEFAULT 'foo', e INT NOT NULL DEFAULT 42);
INSERT INTO t3 SET a=2;
# change some DEFAULT values of old columns, and add one column
ALTER TABLE t3 CHANGE COLUMN b b INT DEFAULT 5,
CHANGE COLUMN c c INT DEFAULT 10,
CHANGE COLUMN d d char(10) DEFAULT NULL;
alter table t3 ADD COLUMN f INT UNSIGNED DEFAULT 0;
INSERT INTO t3 SET a=3;
# change DEFAULTs in .frm file only (nothing inside InnoDB)
ALTER TABLE t3
CHANGE COLUMN a a INT NOT NULL DEFAULT 101,
CHANGE COLUMN b b INT DEFAULT 102,
CHANGE COLUMN c c INT DEFAULT 103,
CHANGE COLUMN d d char(10) DEFAULT 'eleventy',
CHANGE COLUMN e e INT NOT NULL DEFAULT 105,
CHANGE COLUMN f f INT UNSIGNED DEFAULT 106;
SELECT * FROM t3;
# datetime
create table t4 (id int primary key, c2 int);
insert into t4 values(1,1),(2,2),(3,3);
alter table t4 add column (c3 datetime default current_timestamp(), c4 timestamp not null default current_timestamp());
select * from t4;
alter table t4 add column c5 time not null default current_timestamp();
alter table t4 add column c6 date not null default current_timestamp();
select * from t4;
# add bolb column
eval create table bug53592(a int) engine=innodb row_format=compact ROW_FORMAT=$row_format;
insert into bug53592 values(1);
alter table bug53592 add column b text charset utf8;
alter table bug53592 add column c blob not null;
select * from bug53592;
# big table
create table big_table (id int primary key, c1 varchar(4000), c2 varchar(4000), c3 varchar(1000));
insert into big_table values(1, repeat('a', 200), repeat('b', 200), repeat('c', 159));
set @i:=1;
insert into big_table select @i:=@i+1, c1, c2, c3 from big_table;
insert into big_table select @i:=@i+1, c1, c2, c3 from big_table;
insert into big_table select @i:=@i+1, c1, c2, c3 from big_table;
insert into big_table select @i:=@i+1, c1, c2, c3 from big_table;
insert into big_table select @i:=@i+1, c1, c2, c3 from big_table;
insert into big_table select @i:=@i+1, c1, c2, c3 from big_table;
insert into big_table select @i:=@i+1, c1, c2, c3 from big_table;
insert into big_table select @i:=@i+1, c1, c2, c3 from big_table;
insert into big_table select @i:=@i+1, c1, c2, c3 from big_table;
insert into big_table select @i:=@i+1, c1, c2, c3 from big_table;
insert into big_table select @i:=@i+1, c1, c2, c3 from big_table;
alter table big_table add column (d1 int default 0, d2 varchar(20) default 'abcde', d3 timestamp not null default current_timestamp on update current_timestamp);
insert into big_table(id, c1, c2, c3) select @i:=@i+1, c1, c2, c3 from big_table;
insert into big_table(id, c1, c2, c3) select @i:=@i+1, c1, c2, c3 from big_table;
checksum table big_table;
drop database instant_alter;
846c846
< SPATIAL INDEX(c3)) ENGINE=InnoDB ROW_FORMAT=COMPRESSED;
---
> SPATIAL INDEX(c3)) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
950c950
< ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED
---
> ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
972c972
< ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED
---
> ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
988c988
< ENGINE=InnoDB ROW_FORMAT=COMPRESSED;
---
> ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
1015c1015
< ENGINE=InnoDB ROW_FORMAT=COMPRESSED;
---
> ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
1086c1086
< ENGINE=InnoDB ROW_FORMAT=COMPRESSED;
---
> ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
846c846
< SPATIAL INDEX(c3)) ENGINE=InnoDB ROW_FORMAT=COMPRESSED;
---
> SPATIAL INDEX(c3)) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
950c950
< ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED
---
> ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
972c972
< ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED
---
> ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
988c988
< ENGINE=InnoDB ROW_FORMAT=COMPRESSED;
---
> ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
1015c1015
< ENGINE=InnoDB ROW_FORMAT=COMPRESSED;
---
> ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
1086c1086
< ENGINE=InnoDB ROW_FORMAT=COMPRESSED;
---
> ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
--source include/innodb_page_size.inc
--let $row_format=redundant
--source ../include/instant_alter.inc
--let $row_format=compact
--source ../include/instant_alter.inc
--let $row_format=dynamic
--source ../include/instant_alter.inc
#--let $row_format=compressed
#--source ../include/instant_alter.inc
--echo #
--echo # MDEV-11369: Instant ADD COLUMN for InnoDB
--echo #
SET timestamp = 42;
SET time_zone='+03:00';
let $format= 4;
while ($format) {
let $engine= `SELECT CONCAT('ENGINE=InnoDB ROW_FORMAT=',CASE $format
WHEN 1 THEN CASE WHEN @@GLOBAL.innodb_page_size>16384
THEN 'DYNAMIC' ELSE 'COMPRESSED' END
WHEN 2 THEN 'DYNAMIC'
WHEN 3 THEN 'COMPACT'
ELSE 'REDUNDANT' END)`;
eval CREATE TABLE t1
(id INT PRIMARY KEY, c2 INT UNIQUE,
c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'),
SPATIAL INDEX(c3)) $engine;
INSERT INTO t1 (id, c2) values(1,1);
SELECT * FROM t1;
SET GLOBAL innodb_monitor_enable = module_ddl;
--enable_info
ALTER TABLE t1 ADD COLUMN (
d1 INT, d2 INT UNSIGNED DEFAULT 10, d3 VARCHAR(20) NOT NULL DEFAULT 'abcde',
d4 TIMESTAMP NOT NULL DEFAULT current_timestamp());
--disable_info
SELECT * FROM t1;
INSERT INTO t1 (id) VALUES(2),(3),(4),(5),(6);
--enable_info
ALTER TABLE t1 CHANGE d1 d1 INT DEFAULT 5, CHANGE d2 d2 INT DEFAULT 15,
CHANGE d3 d3 VARCHAR(20) NOT NULL DEFAULT 'fghij',
CHANGE d4 dfour TIMESTAMP NOT NULL DEFAULT now();
--disable_info
INSERT INTO t1 SET id = 7;
SELECT * FROM t1;
# add virtual columns
--enable_info
ALTER TABLE t1 ADD COLUMN e1 INT AS (id * 3);
ALTER TABLE t1 ADD COLUMN e2 VARCHAR(30) AS (d3);
ALTER TABLE t1 ADD COLUMN e3 INT AS (id * 2);
# instant alter
ALTER TABLE t1 CHANGE d3 d3 VARCHAR(20) NOT NULL DEFAULT 'foobar',
ADD COLUMN (d5 CHAR(20) DEFAULT 'hijkl', d6 INT DEFAULT -12345, d7 INT);
--disable_info
INSERT INTO t1 SET id = 8;
# Updating a column by extending an existing record
UPDATE t1 SET d3 = 'yyyyy' WHERE id = 1;
# Updating an already materialized column
UPDATE t1 SET d3 = 'xxxxx' WHERE id = 2;
# transaction rollback
BEGIN;
UPDATE t1 SET d3 = 'xxxxx' WHERE id = 3;
SELECT * FROM t1 WHERE id = 3;
ROLLBACK;
SELECT * FROM t1 WHERE id = 3;
# NULL to NULL, no change
BEGIN;
UPDATE t1 SET d7 = NULL WHERE ID = 5;
ROLLBACK;
BEGIN;
UPDATE t1 SET d7 = NULL, d6 = 10 WHERE id = 5;
SELECT * FROM t1 WHERE id = 5;
ROLLBACK;
SELECT * FROM t1 WHERE id = 5;
# add virtual stored columns; not instant
--enable_info
ALTER TABLE t1 ADD COLUMN (f1 VARCHAR(20) AS (concat('x', e2)) STORED);
# instant add
ALTER TABLE t1 ADD COLUMN (d8 VARCHAR(20) DEFAULT 'omnopq');
--disable_info
SELECT * FROM t1;
SHOW CREATE TABLE t1;
--enable_info
ALTER TABLE t1
CHANGE c2 c2 INT DEFAULT 42,
CHANGE d1 d1 INT DEFAULT 1,
CHANGE d2 d2 INT DEFAULT 20,
CHANGE d3 d3 VARCHAR(20) NOT NULL DEFAULT 'boofar';
--disable_info
INSERT INTO t1 SET id=9;
--enable_info
ALTER TABLE t1 DROP c3;
--disable_info
SHOW CREATE TABLE t1;
SELECT * FROM t1;
DROP TABLE t1;
eval CREATE TABLE t2
(id INT primary key, c1 VARCHAR(4000),
p GEOMETRY NOT NULL DEFAULT ST_GeomFromText('LINESTRING(0 0,0 1,1 1)'),
SPATIAL INDEX(p))
$engine;
BEGIN;
INSERT INTO t2 SET id=1, c1=REPEAT('a', 4000);
INSERT INTO t2 SET id=2, c1=REPEAT('a', 4000), p=ST_GeomFromText('POINT(1 1)');
COMMIT;
--enable_info
ALTER TABLE t2 ADD COLUMN d1 VARCHAR(2000) DEFAULT REPEAT('asdf',500);
--disable_info
SELECT * FROM t2;
# inplace update, rollback
BEGIN;
UPDATE t2 SET c1 = repeat(id, 4000);
ROLLBACK;
# non-inplace update. Rollback will materialize off-page columns.
BEGIN;
UPDATE t2 SET d1 = repeat(id, 200);
ROLLBACK;
--enable_info
ALTER TABLE t2 DROP p;
--disable_info
SELECT * FROM t2;
DROP TABLE t2;
# datetime
eval CREATE TABLE t3
(id INT PRIMARY KEY, c2 INT UNSIGNED NOT NULL UNIQUE,
c3 POLYGON NOT NULL DEFAULT ST_PolyFromText('POLYGON((1 1,2 2,3 3,1 1))'),
SPATIAL INDEX(c3))
$engine;
INSERT INTO t3(id,c2) VALUES(1,1),(2,2),(3,3);
SELECT * FROM t3;
--enable_info
ALTER TABLE t3 ADD COLUMN
(c4 DATETIME DEFAULT current_timestamp(),
c5 TIMESTAMP NOT NULL DEFAULT current_timestamp(),
c6 POINT);
SELECT * FROM t3;
ALTER TABLE t3 ADD COLUMN c7 TIME NOT NULL DEFAULT current_timestamp();
ALTER TABLE t3 ADD COLUMN c8 DATE NOT NULL DEFAULT current_timestamp();
--disable_info
SELECT * FROM t3;
--enable_info
ALTER TABLE t3 ADD COLUMN t TEXT CHARSET utf8
DEFAULT 'The quick brown fox jumps over the lazy dog';
ALTER TABLE t3 ADD COLUMN b BLOB NOT NULL;
--error ER_NO_DEFAULT_FOR_FIELD
INSERT INTO t3 SET id=4;
INSERT INTO t3 SET id=4, c2=0, b=0xf09f98b1;
ALTER TABLE t3 CHANGE t phrase TEXT DEFAULT 0xc3a4c3a448,
CHANGE b b BLOB NOT NULL DEFAULT 'binary line of business';
--disable_info
INSERT INTO t3 SET id=5, c2=9;
SELECT * FROM t3;
--enable_info
ALTER TABLE t3 DROP c3, DROP c7;
--disable_info
SELECT * FROM t3;
DROP TABLE t3;
eval CREATE TABLE big
(id INT PRIMARY KEY, c1 VARCHAR(4000), c2 VARCHAR(4000), c3 VARCHAR(1000),
p POINT NOT NULL DEFAULT ST_GeomFromText('POINT(0 0)'), SPATIAL INDEX(p))
$engine;
BEGIN;
INSERT INTO big
SET id=1, c1=REPEAT('a', 200), c2=REPEAT('b', 200), c3=REPEAT('c', 159);
SET @i:=1;
INSERT INTO big SELECT @i:=@i+1, c1, c2, c3, p FROM big;
INSERT INTO big SELECT @i:=@i+1, c1, c2, c3, p FROM big;
INSERT INTO big SELECT @i:=@i+1, c1, c2, c3, p FROM big;
INSERT INTO big SELECT @i:=@i+1, c1, c2, c3, p FROM big;
INSERT INTO big SELECT @i:=@i+1, c1, c2, c3, p FROM big;
INSERT INTO big SELECT @i:=@i+1, c1, c2, c3, p FROM big;
INSERT INTO big SELECT @i:=@i+1, c1, c2, c3, p FROM big;
INSERT INTO big SELECT @i:=@i+1, c1, c2, c3, p FROM big;
INSERT INTO big SELECT @i:=@i+1, c1, c2, c3, p FROM big;
INSERT INTO big SELECT @i:=@i+1, c1, c2, c3, p FROM big;
INSERT INTO big SELECT @i:=@i+1, c1, c2, c3, p FROM big;
COMMIT;
--enable_info
ALTER TABLE big ADD COLUMN
(d1 INT DEFAULT 0, d2 VARCHAR(20) DEFAULT 'abcde',
d3 TIMESTAMP NOT NULL DEFAULT current_timestamp ON UPDATE current_timestamp);
--disable_info
CHECKSUM TABLE big;
BEGIN;
INSERT INTO big(id, c1, c2, c3) SELECT @i:=@i+1, c1, c2, c3 FROM big;
INSERT INTO big(id, c1, c2, c3) SELECT @i:=@i+1, c1, c2, c3 FROM big;
CHECKSUM TABLE big;
ROLLBACK;
CHECKSUM TABLE big;
DROP TABLE big;
dec $format;
}
SET GLOBAL innodb_monitor_disable = module_ddl;
--disable_warnings
SET GLOBAL innodb_monitor_enable = default;
SET GLOBAL innodb_monitor_disable = default;
--enable_warnings
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