summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2022-07-01 13:50:02 +0200
committerNikita Malyavin <nikitamalyavin@gmail.com>2022-10-17 15:24:45 +0300
commit181201afc97ebf3bd3c908de7bc07aac2d9608f0 (patch)
tree2dcab367b78eae34b6b0e8a701d32e8c4444e3ca
parent0919fcbd85c3baeb066e56995a34142c7c7fe906 (diff)
downloadmariadb-git-181201afc97ebf3bd3c908de7bc07aac2d9608f0.tar.gz
MDEV-28943 Online alter fails under LOCK TABLE with ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
if ALTER TABLE ... LOCK=xxx is executed under LOCK TABLES, ignore the LOCK clause, because ALTER should not downgrade already taken EXCLUSIVE table lock to SHARED or NONE. This commit preserves the existing behavior (LOCK was de facto ignored), but makes it explicit.
-rw-r--r--mysql-test/main/alter_table_lock.result45
-rw-r--r--mysql-test/main/alter_table_lock.test51
-rw-r--r--sql/sql_table.cc4
3 files changed, 99 insertions, 1 deletions
diff --git a/mysql-test/main/alter_table_lock.result b/mysql-test/main/alter_table_lock.result
index 620fca23315..5a787055478 100644
--- a/mysql-test/main/alter_table_lock.result
+++ b/mysql-test/main/alter_table_lock.result
@@ -14,4 +14,49 @@ ALTER TABLE t1 CHANGE COLUMN IF EXISTS b c INT;
SET SESSION max_session_mem_used = @max_session_mem_used_save;
UNLOCK TABLES;
DROP TABLE t1;
+#
# End of 10.5 tests
+#
+#
+# MDEV-28943 Online alter fails under LOCK TABLE with ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
+#
+create table t1 (f int) engine=innodb;
+insert t1 values (1);
+alter table t1 force, algorithm=copy, lock=none;
+alter table t1 force, algorithm=inplace, lock=none;
+alter table t1 force, algorithm=copy, lock=shared;
+alter table t1 force, algorithm=inplace, lock=shared;
+alter table t1 force, algorithm=copy, lock=exclusive;
+alter table t1 force, algorithm=inplace, lock=exclusive;
+lock table t1 write;
+connect con1, localhost, root;
+select count(*) as 'must be 0' from t1;
+connection default;
+alter table t1 force, algorithm=copy, lock=none;
+alter table t1 force, algorithm=inplace, lock=none;
+alter table t1 force, algorithm=copy, lock=shared;
+alter table t1 force, algorithm=inplace, lock=shared;
+alter table t1 force, algorithm=copy, lock=exclusive;
+alter table t1 force, algorithm=inplace, lock=exclusive;
+delete from t1;
+unlock tables;
+connection con1;
+must be 0
+0
+connection default;
+drop table t1;
+#
+# MDEV-29056 Replica SQL thread stops with 1846 error on ALTER ONLINE after LOCK WRITE
+#
+create table t1 (c varchar(1), key (c)) engine=innodb;
+insert into t1 (c) values ('g') ;
+alter table t1 add fulltext key(c), algorithm=inplace;
+alter online table t1 add column s blob not null, algorithm=inplace;
+ERROR 0A000: LOCK=NONE is not supported. Reason: Fulltext index creation requires a lock. Try LOCK=SHARED
+lock table t1 write;
+alter online table t1 add column s blob not null, algorithm=inplace;
+ERROR 0A000: LOCK=NONE is not supported. Reason: Fulltext index creation requires a lock. Try LOCK=SHARED
+drop table t1;
+#
+# End of 10.11 tests
+#
diff --git a/mysql-test/main/alter_table_lock.test b/mysql-test/main/alter_table_lock.test
index bd26c1ac7d0..6fe717f977e 100644
--- a/mysql-test/main/alter_table_lock.test
+++ b/mysql-test/main/alter_table_lock.test
@@ -1,4 +1,5 @@
--source include/not_msan.inc
+--source include/have_innodb.inc
--echo #
--echo # MDEV-23836: Assertion `! is_set() || m_can_overwrite_status' in
@@ -26,4 +27,54 @@ SET SESSION max_session_mem_used = @max_session_mem_used_save;
UNLOCK TABLES;
DROP TABLE t1;
+--echo #
--echo # End of 10.5 tests
+--echo #
+
+--echo #
+--echo # MDEV-28943 Online alter fails under LOCK TABLE with ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
+--echo #
+
+# test that any lock=xxx works under LOCK TABLES
+# and that it is ignored, does not actually downgrade the lock
+create table t1 (f int) engine=innodb;
+insert t1 values (1);
+alter table t1 force, algorithm=copy, lock=none;
+alter table t1 force, algorithm=inplace, lock=none;
+alter table t1 force, algorithm=copy, lock=shared;
+alter table t1 force, algorithm=inplace, lock=shared;
+alter table t1 force, algorithm=copy, lock=exclusive;
+alter table t1 force, algorithm=inplace, lock=exclusive;
+lock table t1 write;
+connect con1, localhost, root;
+--send select count(*) as 'must be 0' from t1
+--connection default
+alter table t1 force, algorithm=copy, lock=none;
+alter table t1 force, algorithm=inplace, lock=none;
+alter table t1 force, algorithm=copy, lock=shared;
+alter table t1 force, algorithm=inplace, lock=shared;
+alter table t1 force, algorithm=copy, lock=exclusive;
+alter table t1 force, algorithm=inplace, lock=exclusive;
+delete from t1;
+unlock tables;
+--connection con1
+--reap
+--connection default
+drop table t1;
+
+--echo #
+--echo # MDEV-29056 Replica SQL thread stops with 1846 error on ALTER ONLINE after LOCK WRITE
+--echo #
+create table t1 (c varchar(1), key (c)) engine=innodb;
+insert into t1 (c) values ('g') ;
+alter table t1 add fulltext key(c), algorithm=inplace;
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
+alter online table t1 add column s blob not null, algorithm=inplace;
+lock table t1 write;
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
+alter online table t1 add column s blob not null, algorithm=inplace;
+drop table t1;
+
+--echo #
+--echo # End of 10.11 tests
+--echo #
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 4e98ab36221..07d31b0f9f3 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -10435,7 +10435,6 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db,
if (alter_info->requested_lock == Alter_info::ALTER_TABLE_LOCK_SHARED
|| alter_info->requested_lock > Alter_info::ALTER_TABLE_LOCK_NONE
|| alter_info->flags & ALTER_DROP_SYSTEM_VERSIONING
- || thd->locked_tables_mode == LTM_LOCK_TABLES
|| thd->lex->sql_command == SQLCOM_OPTIMIZE
|| alter_info->algorithm(thd) > Alter_info::ALTER_TABLE_ALGORITHM_COPY)
online= false;
@@ -11299,6 +11298,9 @@ do_continue:;
goto err_new_table_cleanup;
}
+ if (thd->locked_tables_mode == LTM_LOCK_TABLES)
+ online= false;
+
// If EXCLUSIVE lock is requested, upgrade already.
if (alter_info->requested_lock == Alter_info::ALTER_TABLE_LOCK_EXCLUSIVE &&
wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN))