Skip to content

Commit

Permalink
MDEV-14016 Allow instant ADD COLUMN, ADD INDEX, LOCK=NONE
Browse files Browse the repository at this point in the history
Ideally, we would move some code from
ha_innobase::prepare_inplace_alter_table() to
ha_innobase::check_if_supported_inplace_alter(),
but the API does not really allow us to return errors; it can
only inform which forms of ALGORITHM and LOCK are allowed.

So, we have to duplicate some logic between the "check" and "prepare"
phases. We do the duplication by calling common functions.

instant_alter_column_possible(): Check if instant column operation
is possible. Invoked from both
ha_innobase::check_if_supported_inplace_alter() and
prepare_inplace_alter_table_dict().

ha_innobase::check_if_supported_inplace_alter(): Before refusing
certain operations if FULLTEXT INDEX exist, check if instant ALTER TABLE
is possible and return early if it is the case.

prepare_inplace_alter_table_dict(): Before checking the limitations
on FULLTEXT INDEX, check if instant ALTER TABLE is possible, and suppress
the checks if it is the case. If instant ADD COLUMN is used when the
table already contains FULLTEXT INDEX, do account for a
hidden FTS_DOC_ID_INDEX in a debug assertion.
  • Loading branch information
dr-m committed Nov 2, 2017
1 parent 5603a58 commit 6402ca7
Show file tree
Hide file tree
Showing 5 changed files with 273 additions and 150 deletions.
21 changes: 21 additions & 0 deletions mysql-test/suite/innodb/r/innodb-alter.result
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,27 @@ tt CREATE TABLE `tt` (
PRIMARY KEY (`pk`),
FULLTEXT KEY `ct` (`ct`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
ALTER TABLE tt ADD COLUMN c CHAR(1) NOT NULL FIRST, LOCK=NONE;
ERROR 0A000: LOCK=NONE is not supported. Reason: InnoDB presently supports one FULLTEXT index creation at a time. Try LOCK=SHARED
ALTER TABLE tt ADD COLUMN c CHAR(1) NOT NULL, LOCK=NONE;
ERROR 0A000: LOCK=NONE is not supported. Reason: InnoDB presently supports one FULLTEXT index creation at a time. Try LOCK=SHARED
CREATE TABLE tu (
pk INT PRIMARY KEY, FTS_DOC_ID BIGINT UNSIGNED NOT NULL, t TEXT,
FULLTEXT INDEX(t)
) ENGINE=InnoDB;
ALTER TABLE tu ADD COLUMN c CHAR(1) NOT NULL FIRST, LOCK=NONE;
ERROR 0A000: LOCK=NONE is not supported. Reason: InnoDB presently supports one FULLTEXT index creation at a time. Try LOCK=SHARED
ALTER TABLE tu ADD COLUMN c CHAR(1) NOT NULL, LOCK=NONE;
DROP TABLE tu;
CREATE TABLE tv (
pk INT PRIMARY KEY, FTS_DOC_ID BIGINT UNSIGNED NOT NULL, t TEXT,
UNIQUE INDEX FTS_DOC_ID_INDEX(FTS_DOC_ID),
FULLTEXT INDEX(t)
) ENGINE=InnoDB;
ALTER TABLE tv ADD COLUMN c CHAR(1) NOT NULL FIRST, LOCK=NONE;
ERROR 0A000: LOCK=NONE is not supported. Reason: InnoDB presently supports one FULLTEXT index creation at a time. Try LOCK=SHARED
ALTER TABLE tv ADD COLUMN c CHAR(1) NOT NULL, LOCK=NONE;
DROP TABLE tv;
ALTER TABLE t1o CHANGE c1 dB_row_Id INT, ALGORITHM=COPY;
ERROR 42000: Incorrect column name 'dB_row_Id'
ALTER TABLE t1o CHANGE c1 dB_row_Id INT, ALGORITHM=INPLACE;
Expand Down
27 changes: 27 additions & 0 deletions mysql-test/suite/innodb/t/innodb-alter.test
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,33 @@ ALGORITHM=INPLACE, LOCK=SHARED;
-- source suite/innodb/include/innodb_dict.inc

SHOW CREATE TABLE tt;
# Non-instant ADD COLUMN would require the table to be rebuilt.
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
ALTER TABLE tt ADD COLUMN c CHAR(1) NOT NULL FIRST, LOCK=NONE;
# This is still non-instant ADD COLUMN, because FTS_DOC_ID is hidden.
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
ALTER TABLE tt ADD COLUMN c CHAR(1) NOT NULL, LOCK=NONE;

CREATE TABLE tu (
pk INT PRIMARY KEY, FTS_DOC_ID BIGINT UNSIGNED NOT NULL, t TEXT,
FULLTEXT INDEX(t)
) ENGINE=InnoDB;
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
ALTER TABLE tu ADD COLUMN c CHAR(1) NOT NULL FIRST, LOCK=NONE;
# Instant ADD COLUMN (adding after the visible FTS_DOC_ID)
ALTER TABLE tu ADD COLUMN c CHAR(1) NOT NULL, LOCK=NONE;
DROP TABLE tu;

CREATE TABLE tv (
pk INT PRIMARY KEY, FTS_DOC_ID BIGINT UNSIGNED NOT NULL, t TEXT,
UNIQUE INDEX FTS_DOC_ID_INDEX(FTS_DOC_ID),
FULLTEXT INDEX(t)
) ENGINE=InnoDB;
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
ALTER TABLE tv ADD COLUMN c CHAR(1) NOT NULL FIRST, LOCK=NONE;
# Instant ADD COLUMN (adding after the visible FTS_DOC_ID)
ALTER TABLE tv ADD COLUMN c CHAR(1) NOT NULL, LOCK=NONE;
DROP TABLE tv;

# DB_ROW_ID, DB_TRX_ID, DB_ROLL_PTR are reserved InnoDB system column names.
--error ER_WRONG_COLUMN_NAME
Expand Down
53 changes: 48 additions & 5 deletions mysql-test/suite/innodb_gis/r/alter_spatial_index.result
Original file line number Diff line number Diff line change
Expand Up @@ -483,16 +483,55 @@ info: Records: 0 Duplicates: 0 Warnings: 0
ALTER TABLE tab MODIFY COLUMN c2 GEOMETRY NOT NULL;
affected rows: 0
info: Records: 0 Duplicates: 0 Warnings: 0
ALTER TABLE tab add COLUMN c8 POINT NOT NULL AFTER c5, ALGORITHM = INPLACE, LOCK=NONE;
ALTER TABLE tab MODIFY COLUMN c3 POLYGON NOT NULL;
affected rows: 10
info: Records: 10 Duplicates: 0 Warnings: 0
ALTER TABLE tab add COLUMN c7 POINT NOT NULL;
affected rows: 0
info: Records: 0 Duplicates: 0 Warnings: 0
ALTER TABLE tab add COLUMN c8 POINT NOT NULL, ALGORITHM = INPLACE, LOCK=NONE;
SELECT HEX(c8) FROM tab;
HEX(c8)










BEGIN;
INSERT INTO tab SELECT 0,c2,c3,c4,c5,
ST_GeomFromText('POINT(67 89)'),ST_GeomFromText('POINT(67 89)')
FROM tab LIMIT 1;
SELECT HEX(c8) FROM tab;
HEX(c8)
0000000001010000000000000000C050400000000000405640










ROLLBACK;
ALTER TABLE tab add COLUMN c9 POINT NOT NULL AFTER c5, ALGORITHM = INPLACE, LOCK=NONE;
ERROR 0A000: LOCK=NONE is not supported. Reason: Do not support online operation on table with GIS index. Try LOCK=SHARED
SHOW CREATE TABLE tab;
Table Create Table
tab CREATE TABLE `tab` (
`c1` int(11) NOT NULL,
`c2` geometry NOT NULL,
`c3` linestring NOT NULL,
`c3` polygon NOT NULL,
`c4` polygon NOT NULL,
`c5` geometry NOT NULL,
`c7` point NOT NULL,
`c8` point NOT NULL,
PRIMARY KEY (`c1`),
SPATIAL KEY `idx2` (`c2`),
SPATIAL KEY `idx3` (`c3`),
Expand Down Expand Up @@ -525,9 +564,11 @@ Table Create Table
tab CREATE TABLE `tab` (
`c1` int(11) NOT NULL,
`c2` geometry NOT NULL,
`c3` linestring NOT NULL,
`c3` polygon NOT NULL,
`c4` geometry NOT NULL,
`c5` geometry NOT NULL,
`c7` point NOT NULL,
`c8` point NOT NULL,
PRIMARY KEY (`c1`),
SPATIAL KEY `idx2` (`c2`),
SPATIAL KEY `idx3` (`c3`),
Expand Down Expand Up @@ -571,8 +612,8 @@ ALTER TABLE tab MODIFY COLUMN c2 POINT NOT NULL;
affected rows: 8
info: Records: 8 Duplicates: 0 Warnings: 0
ALTER TABLE tab MODIFY COLUMN c3 LINESTRING NOT NULL;
affected rows: 0
info: Records: 0 Duplicates: 0 Warnings: 0
affected rows: 8
info: Records: 8 Duplicates: 0 Warnings: 0
ALTER TABLE tab MODIFY COLUMN c4 POLYGON NOT NULL;
affected rows: 8
info: Records: 8 Duplicates: 0 Warnings: 0
Expand All @@ -584,6 +625,8 @@ tab CREATE TABLE `tab` (
`c3` linestring NOT NULL,
`c4` polygon NOT NULL,
`c5` geometry NOT NULL,
`c7` point NOT NULL,
`c8` point NOT NULL,
PRIMARY KEY (`c1`),
SPATIAL KEY `idx2` (`c2`),
SPATIAL KEY `idx3` (`c3`),
Expand Down
25 changes: 12 additions & 13 deletions mysql-test/suite/innodb_gis/t/alter_spatial_index.test
Original file line number Diff line number Diff line change
Expand Up @@ -476,25 +476,24 @@ ALTER TABLE tab ADD INDEX idx6(c4(10)) USING BTREE;

ALTER TABLE tab MODIFY COLUMN c2 GEOMETRY NOT NULL;

# --error ER_CANT_CREATE_GEOMETRY_OBJECT
# ALTER TABLE tab MODIFY COLUMN c3 POLYGON NOT NULL;
ALTER TABLE tab MODIFY COLUMN c3 POLYGON NOT NULL;

# --error ER_INVALID_USE_OF_NULL
# ALTER TABLE tab add COLUMN c7 POINT NOT NULL;
ALTER TABLE tab add COLUMN c7 POINT NOT NULL;
--disable_info

# instant add, supported
#ALTER TABLE tab add COLUMN c8 POINT NOT NULL, ALGORITHM = INPLACE, LOCK=NONE;
#SELECT HEX(c8) FROM tab;
#BEGIN;
#INSERT INTO tab SELECT 0,c2,c3,c4,c5,ST_GeomFromText('POINT(67 89)')
#FROM tab LIMIT 1;
#SELECT HEX(c8) FROM tab;
#ROLLBACK;
ALTER TABLE tab add COLUMN c8 POINT NOT NULL, ALGORITHM = INPLACE, LOCK=NONE;
SELECT HEX(c8) FROM tab;
BEGIN;
INSERT INTO tab SELECT 0,c2,c3,c4,c5,
ST_GeomFromText('POINT(67 89)'),ST_GeomFromText('POINT(67 89)')
FROM tab LIMIT 1;
SELECT HEX(c8) FROM tab;
ROLLBACK;

# not instant, not supported
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
ALTER TABLE tab add COLUMN c8 POINT NOT NULL AFTER c5, ALGORITHM = INPLACE, LOCK=NONE;
--disable_info
ALTER TABLE tab add COLUMN c9 POINT NOT NULL AFTER c5, ALGORITHM = INPLACE, LOCK=NONE;

SHOW CREATE TABLE tab;

Expand Down
Loading

0 comments on commit 6402ca7

Please sign in to comment.