1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-17 06:42:17 +03:00
Files
mariadb/mysql-test/suite/innodb/t/instant_alter_limit.test
Marko Mäkelä d9d79e4d01 MDEV-17494 Refuse ALGORITHM=INSTANT when the row size is too large
With the MDEV-15562 instant DROP COLUMN, clustered index records
will contain traces of dropped columns, as follows:

In ROW_FORMAT=REDUNDANT, dropped columns will be stored as 0 bytes,
but they will consume 1 or 2 bytes per column in the record header.

In ROW_FORMAT=COMPACT or ROW_FORMAT=DYNAMIC, dropped columns will
be stored as NULL if allowed. This will consume 1 bit per nullable
column.

In ROW_FORMAT=COMPACT or ROW_FORMAT=DYNAMIC, dropped NOT NULL columns
will be stored as 0 bytes if allowed. This will consume 1 byte per
NOT NULL variable-length column. Fixed-length columns will be stored
using the fixed number of bytes.

The metadata record will be 20 bytes larger than user records, because
it will contain a metadata BLOB pointer.

We must refuse ALGORITHM=INSTANT (and require a table rebuild) if
the metadata record would grow too big to fit in the index page.

If SQL_MODE includes STRICT_TRANS_TABLES or STRICT_ALL_TABLES, we should
refuse ALGORITHM=INSTANT if the maximum length of user records would
exceed the maximum size of an index page, similar to what
row_create_index_for_mysql() does during CREATE TABLE. This limit
would kick in when the default values for any instantly added columns
in the metadata record are NULL or short, but the allowed maximum values
are long.

instant_alter_column_possible(): Add the parameter "bool strict" to
enable checks for the user record size, and always check the metadata
record size.
2019-04-16 17:21:17 +03:00

61 lines
1.7 KiB
Plaintext

--source include/innodb_page_size.inc
SET @old_instant=
(SELECT variable_value FROM information_schema.global_status
WHERE variable_name = 'innodb_instant_alter_column');
CREATE TABLE t(a INT PRIMARY KEY, b INT, c INT, d INT, e INT)
ENGINE=InnoDB;
INSERT INTO t VALUES(1,2,3,4,5);
--disable_query_log
let $n=253;
while ($n) {
dec $n;
ALTER TABLE t DROP b, DROP c, DROP d, DROP e,
ADD COLUMN b INT FIRST, ADD COLUMN c INT, ADD COLUMN d INT AFTER b,
ADD COLUMN e INT AFTER c, ALGORITHM=INSTANT;
}
--enable_query_log
SELECT * FROM t;
--error ER_ALTER_OPERATION_NOT_SUPPORTED
ALTER TABLE t DROP b, DROP c, DROP d, DROP e,
ADD COLUMN b INT, ALGORITHM=INSTANT;
ALTER TABLE t CHANGE COLUMN b beta INT AFTER a, ALGORITHM=INSTANT;
ALTER TABLE t DROP e, DROP c, DROP d, ALGORITHM=INSTANT;
SELECT * FROM t;
ALTER TABLE t DROP COLUMN beta, ALGORITHM=INSTANT;
--error ER_ALTER_OPERATION_NOT_SUPPORTED
ALTER TABLE t ADD COLUMN b INT NOT NULL, ALGORITHM=INSTANT;
SELECT variable_value-@old_instant instants
FROM information_schema.global_status
WHERE variable_name = 'innodb_instant_alter_column';
ALTER TABLE t ADD COLUMN b INT NOT NULL;
SELECT variable_value-@old_instant instants
FROM information_schema.global_status
WHERE variable_name = 'innodb_instant_alter_column';
SELECT * FROM t;
ALTER TABLE t ADD COLUMN (c CHAR(255) NOT NULL, d BIGINT NOT NULL),
ALGORITHM=INSTANT;
--disable_query_log
let $n=253;
while ($n) {
dec $n;
ALTER TABLE t DROP b, DROP c, DROP d,
ADD COLUMN (b INT NOT NULL, c CHAR(255) NOT NULL, d BIGINT NOT NULL);
}
--enable_query_log
UPDATE t SET b=b+1,d=d+1,c='foo';
SELECT * FROM t;
SELECT variable_value-@old_instant instants
FROM information_schema.global_status
WHERE variable_name = 'innodb_instant_alter_column';
DROP TABLE t;