summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2022-03-08 10:03:45 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2022-03-08 10:03:45 +0200
commite8a2a70cf869cf32a50144704646a5f34e8d7be9 (patch)
treea50505a6d936f15536368b3405e43260e0e8696c
parentc8a18589dec9137730122ecc07e16c4164939988 (diff)
parentaf87186c1d3f9eeab73bc38b1faa51ba17fa8017 (diff)
downloadmariadb-git-e8a2a70cf869cf32a50144704646a5f34e8d7be9.tar.gz
Merge 10.7 into 10.8
-rw-r--r--mysql-test/main/innodb_mysql_sync.result12
-rw-r--r--mysql-test/main/innodb_mysql_sync.test13
-rw-r--r--mysql-test/suite/federated/rpl.test1
-rw-r--r--mysql-test/suite/galera/disabled.def1
-rw-r--r--mysql-test/suite/galera_3nodes/disabled.def1
-rw-r--r--mysql-test/suite/innodb/r/innodb_buffer_pool_resize_bigtest.result14
-rw-r--r--mysql-test/suite/innodb/r/instant_alter_debug.result17
-rw-r--r--mysql-test/suite/innodb/r/lock_delete_updated.result20
-rw-r--r--mysql-test/suite/innodb/r/lock_wait_conflict.result27
-rw-r--r--mysql-test/suite/innodb/r/page_reorganize.result7
-rw-r--r--mysql-test/suite/innodb/t/innodb_buffer_pool_resize_bigtest.opt2
-rw-r--r--mysql-test/suite/innodb/t/innodb_buffer_pool_resize_bigtest.test28
-rw-r--r--mysql-test/suite/innodb/t/instant_alter_debug.test19
-rw-r--r--mysql-test/suite/innodb/t/lock_delete_updated.test34
-rw-r--r--mysql-test/suite/innodb/t/lock_wait_conflict.test60
-rw-r--r--mysql-test/suite/innodb/t/page_reorganize.test8
-rw-r--r--mysql-test/suite/innodb_fts/r/innodb-fts-ddl.result29
-rw-r--r--mysql-test/suite/innodb_fts/t/innodb-fts-ddl.opt1
-rw-r--r--mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test25
-rw-r--r--mysql-test/suite/versioning/r/update.result1
-rw-r--r--mysql-test/suite/versioning/t/update.test4
-rw-r--r--plugin/type_mysql_json/type.cc2
-rw-r--r--scripts/mysql_install_db.sh9
-rw-r--r--scripts/mysqld_safe.sh1
-rw-r--r--sql/item_func.cc12
-rw-r--r--sql/sql_table.cc10
-rw-r--r--storage/innobase/btr/btr0cur.cc3
-rw-r--r--storage/innobase/buf/buf0buddy.cc6
-rw-r--r--storage/innobase/buf/buf0buf.cc16
-rw-r--r--storage/innobase/buf/buf0flu.cc2
-rw-r--r--storage/innobase/buf/buf0lru.cc6
-rw-r--r--storage/innobase/dict/drop.cc4
-rw-r--r--storage/innobase/fts/fts0fts.cc49
-rw-r--r--storage/innobase/handler/ha_innodb.cc48
-rw-r--r--storage/innobase/handler/ha_innodb.h5
-rw-r--r--storage/innobase/include/buf0buf.h25
-rw-r--r--storage/innobase/include/fts0fts.h23
-rw-r--r--storage/innobase/include/hash0hash.h23
-rw-r--r--storage/innobase/include/lock0lock.h7
-rw-r--r--storage/innobase/include/lock0lock.inl2
-rw-r--r--storage/innobase/include/lock0priv.h2
-rw-r--r--storage/innobase/include/lock0priv.inl2
-rw-r--r--storage/innobase/include/trx0trx.h2
-rw-r--r--storage/innobase/lock/lock0lock.cc98
-rw-r--r--storage/innobase/lock/lock0prdt.cc2
-rw-r--r--storage/innobase/row/row0merge.cc16
46 files changed, 325 insertions, 374 deletions
diff --git a/mysql-test/main/innodb_mysql_sync.result b/mysql-test/main/innodb_mysql_sync.result
index 46ed7d43830..7fe3bdbba18 100644
--- a/mysql-test/main/innodb_mysql_sync.result
+++ b/mysql-test/main/innodb_mysql_sync.result
@@ -131,6 +131,7 @@ connection default;
DROP DATABASE db1;
# Test 2: Primary index (implicit), should block writes.
CREATE TABLE t1(a INT NOT NULL, b INT NOT NULL) engine=innodb;
+INSERT INTO t1 VALUES(1, 2);
SET DEBUG_SYNC= "alter_table_inplace_after_lock_downgrade SIGNAL manage WAIT_FOR query";
# Sending:
ALTER TABLE t1 ADD UNIQUE INDEX(a), LOCK=SHARED;
@@ -139,15 +140,16 @@ SET DEBUG_SYNC= "now WAIT_FOR manage";
USE test;
SELECT * FROM t1;
a b
+1 2
# Sending:
-UPDATE t1 SET a=NULL;
+UPDATE t1 SET a=3;
connection con2;
# Waiting for SELECT to be blocked by the metadata lock on t1
SET DEBUG_SYNC= "now SIGNAL query";
connection default;
# Reaping: ALTER TABLE t1 ADD UNIQUE INDEX(a)
connection con1;
-# Reaping: UPDATE t1 SET a=NULL
+# Reaping: UPDATE t1 SET a=3
# Test 3: Primary index (explicit), should block writes.
connection default;
ALTER TABLE t1 DROP INDEX a;
@@ -158,15 +160,16 @@ connection con1;
SET DEBUG_SYNC= "now WAIT_FOR manage";
SELECT * FROM t1;
a b
+3 2
# Sending:
-UPDATE t1 SET a=NULL;
+UPDATE t1 SET a=4;
connection con2;
# Waiting for SELECT to be blocked by the metadata lock on t1
SET DEBUG_SYNC= "now SIGNAL query";
connection default;
# Reaping: ALTER TABLE t1 ADD PRIMARY KEY (a)
connection con1;
-# Reaping: UPDATE t1 SET a=NULL
+# Reaping: UPDATE t1 SET a=4
# Test 4: Secondary unique index, should not block reads.
connection default;
SET DEBUG_SYNC= "alter_table_inplace_after_lock_downgrade SIGNAL manage WAIT_FOR query";
@@ -176,6 +179,7 @@ connection con1;
SET DEBUG_SYNC= "now WAIT_FOR manage";
SELECT * FROM t1;
a b
+4 2
SET DEBUG_SYNC= "now SIGNAL query";
connection default;
# Reaping: ALTER TABLE t1 ADD UNIQUE (b)
diff --git a/mysql-test/main/innodb_mysql_sync.test b/mysql-test/main/innodb_mysql_sync.test
index 4026080c4b4..466bcb360c5 100644
--- a/mysql-test/main/innodb_mysql_sync.test
+++ b/mysql-test/main/innodb_mysql_sync.test
@@ -176,6 +176,7 @@ DROP DATABASE db1;
--echo # Test 2: Primary index (implicit), should block writes.
CREATE TABLE t1(a INT NOT NULL, b INT NOT NULL) engine=innodb;
+INSERT INTO t1 VALUES(1, 2);
SET DEBUG_SYNC= "alter_table_inplace_after_lock_downgrade SIGNAL manage WAIT_FOR query";
--echo # Sending:
--send ALTER TABLE t1 ADD UNIQUE INDEX(a), LOCK=SHARED
@@ -185,13 +186,13 @@ SET DEBUG_SYNC= "now WAIT_FOR manage";
USE test;
SELECT * FROM t1;
--echo # Sending:
---send UPDATE t1 SET a=NULL
+--send UPDATE t1 SET a=3
connection con2;
--echo # Waiting for SELECT to be blocked by the metadata lock on t1
let $wait_condition= SELECT COUNT(*)= 1 FROM information_schema.processlist
WHERE state= 'Waiting for table metadata lock'
- AND info='UPDATE t1 SET a=NULL';
+ AND info='UPDATE t1 SET a=3';
--source include/wait_condition.inc
SET DEBUG_SYNC= "now SIGNAL query";
@@ -200,7 +201,7 @@ connection default;
--reap
connection con1;
---echo # Reaping: UPDATE t1 SET a=NULL
+--echo # Reaping: UPDATE t1 SET a=3
--reap
--echo # Test 3: Primary index (explicit), should block writes.
@@ -215,13 +216,13 @@ connection con1;
SET DEBUG_SYNC= "now WAIT_FOR manage";
SELECT * FROM t1;
--echo # Sending:
---send UPDATE t1 SET a=NULL
+--send UPDATE t1 SET a=4
connection con2;
--echo # Waiting for SELECT to be blocked by the metadata lock on t1
let $wait_condition= SELECT COUNT(*)= 1 FROM information_schema.processlist
WHERE state= 'Waiting for table metadata lock'
- AND info='UPDATE t1 SET a=NULL';
+ AND info='UPDATE t1 SET a=4';
--source include/wait_condition.inc
SET DEBUG_SYNC= "now SIGNAL query";
@@ -230,7 +231,7 @@ connection default;
--reap
connection con1;
---echo # Reaping: UPDATE t1 SET a=NULL
+--echo # Reaping: UPDATE t1 SET a=4
--reap
--echo # Test 4: Secondary unique index, should not block reads.
diff --git a/mysql-test/suite/federated/rpl.test b/mysql-test/suite/federated/rpl.test
index 6ec4bec5a1a..cc94ea8b716 100644
--- a/mysql-test/suite/federated/rpl.test
+++ b/mysql-test/suite/federated/rpl.test
@@ -1,3 +1,4 @@
+source have_federatedx.inc;
source include/have_binlog_format_row.inc;
source include/master-slave.inc;
diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def
index 1e38075de0d..eb1aba72162 100644
--- a/mysql-test/suite/galera/disabled.def
+++ b/mysql-test/suite/galera/disabled.def
@@ -14,7 +14,6 @@ GCF-1081 : MDEV-18283 Galera test failure on galera.GCF-1081
GCF-939 : MDEV-21520 galera.GCF-939
MW-328A : MDEV-22666 galera.MW-328A MTR failed: "Semaphore wait has lasted > 600 seconds" and do not release port 16002
MW-328B : MDEV-22666 galera.MW-328A MTR failed: "Semaphore wait has lasted > 600 seconds" and do not release port 16002
-MW-328D : MDEV-27550 ER_LOCK_DEADLOCK is gone after MDEV-27025
MW-329 : MDEV-19962 Galera test failure on MW-329
galera_applier_ftwrl_table_alter : MDEV-26502 : galera.galera_applier_ftwrl_table_alter MTR failed : Result content mismatch
galera_as_slave_replication_bundle : MDEV-15785 OPTION_GTID_BEGIN is set in Gtid_log_event::do_apply_event()
diff --git a/mysql-test/suite/galera_3nodes/disabled.def b/mysql-test/suite/galera_3nodes/disabled.def
index 0638dd1e3bc..123b9ea5885 100644
--- a/mysql-test/suite/galera_3nodes/disabled.def
+++ b/mysql-test/suite/galera_3nodes/disabled.def
@@ -12,6 +12,7 @@
GAL-501 : MDEV-24645 galera_3nodes.GAL-501 MTR failed: failed to open gcomm backend connection: 110
GCF-354 : MDEV-25614 Galera test failure on GCF-354
+galera_2_cluster : MDEV-22195 temporarily disabled due to issues to be fixed with MDEV-22195
galera_gtid_2_cluster : MDEV-23775 Galera test failure on galera_3nodes.galera_gtid_2_cluster
galera_ist_gcache_rollover : MDEV-23578 WSREP: exception caused by message: {v=0,t=1,ut=255,o=4,s=0,sr=0,as=1,f=6,src=50524cfe,srcvid=view_id(REG,50524cfe,4),insvid=view_id(UNKNOWN,00000000,0),ru=00000000,r=[-1,-1],fs=75,nl=(}
galera_load_data_ist : MDEV-24639 galera_3nodes.galera_load_data_ist MTR failed with SIGABRT: query 'reap' failed: 2013: Lost connection to server during query
diff --git a/mysql-test/suite/innodb/r/innodb_buffer_pool_resize_bigtest.result b/mysql-test/suite/innodb/r/innodb_buffer_pool_resize_bigtest.result
new file mode 100644
index 00000000000..d6b29060dc7
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb_buffer_pool_resize_bigtest.result
@@ -0,0 +1,14 @@
+SET @save_size=@@innodb_buffer_pool_size;
+#
+# MDEV-27891: Delayed SIGSEGV in InnoDB buffer pool resize
+# after or during DROP TABLE
+#
+select @@innodb_buffer_pool_chunk_size;
+@@innodb_buffer_pool_chunk_size
+1048576
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
+SET GLOBAL innodb_buffer_pool_size=256*1024*1024;
+DROP TABLE t1;
+SET GLOBAL innodb_buffer_pool_size=@@innodb_buffer_pool_size + @@innodb_buffer_pool_chunk_size;
+# End of 10.6 tests
+SET GLOBAL innodb_buffer_pool_size=@save_size;
diff --git a/mysql-test/suite/innodb/r/instant_alter_debug.result b/mysql-test/suite/innodb/r/instant_alter_debug.result
index d6229415d34..82230573c44 100644
--- a/mysql-test/suite/innodb/r/instant_alter_debug.result
+++ b/mysql-test/suite/innodb/r/instant_alter_debug.result
@@ -462,12 +462,27 @@ INSERT INTO t1 SET a=0, i=REPEAT('1', 10000);
ROLLBACK;
set DEBUG_SYNC='now SIGNAL go';
connection default;
-disconnect con1;
SELECT * FROM t1;
a b c d e f g h i
1 2 3 4 5 6 7 8 test
DROP TABLE t1;
SET DEBUG_SYNC=RESET;
+#
+# MDEV-27962 Instant DDL downgrades the MDL when table is empty
+#
+CREATE TABLE t1(f1 INT NOT NULL, f2 INT NOT NULL)ENGINE=InnoDB;
+SET DEBUG_SYNC="alter_table_inplace_after_lock_downgrade SIGNAL try_insert WAIT_FOR alter_progress";
+ALTER TABLE t1 ADD INDEX(f1), ADD INDEX(f2);
+connection con1;
+SET SESSION lock_wait_timeout=1;
+SET DEBUG_SYNC="now WAIT_FOR try_insert";
+INSERT INTO t1 VALUES(1, 2);
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+SET DEBUG_SYNC="now SIGNAL alter_progress";
+disconnect con1;
+connection default;
+DROP TABLE t1;
+SET DEBUG_SYNC=reset;
# End of 10.4 tests
#
# MDEV-22867 Assertion instant.n_core_fields == n_core_fields
diff --git a/mysql-test/suite/innodb/r/lock_delete_updated.result b/mysql-test/suite/innodb/r/lock_delete_updated.result
new file mode 100644
index 00000000000..c2cd47b5dd9
--- /dev/null
+++ b/mysql-test/suite/innodb/r/lock_delete_updated.result
@@ -0,0 +1,20 @@
+CREATE TABLE t(a INT PRIMARY KEY) ENGINE=InnoDB;
+INSERT INTO t VALUES (3);
+BEGIN;
+connection default;
+UPDATE t SET a = 2;
+connect con1,localhost,root;
+DELETE FROM t;
+connection default;
+UPDATE t SET a = 1;
+COMMIT;
+connection con1;
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+disconnect con1;
+connection default;
+# The above DELETE must delete all the rows in the table, so the
+# following SELECT must show 0 rows.
+SELECT count(*) FROM t;
+count(*)
+1
+DROP TABLE t;
diff --git a/mysql-test/suite/innodb/r/lock_wait_conflict.result b/mysql-test/suite/innodb/r/lock_wait_conflict.result
deleted file mode 100644
index 25d18c03ea1..00000000000
--- a/mysql-test/suite/innodb/r/lock_wait_conflict.result
+++ /dev/null
@@ -1,27 +0,0 @@
-#
-# MDEV-27025 insert-intention lock conflicts with waiting ORDINARY lock
-#
-CREATE TABLE t (a INT PRIMARY KEY, b INT NOT NULL UNIQUE) ENGINE=InnoDB;
-connect prevent_purge,localhost,root,,;
-start transaction with consistent snapshot;
-connection default;
-INSERT INTO t VALUES (20,20);
-DELETE FROM t WHERE b = 20;
-connect con_ins,localhost,root,,;
-SET DEBUG_SYNC = 'row_ins_sec_index_entry_dup_locks_created SIGNAL ins_set_locks WAIT_FOR ins_cont';
-INSERT INTO t VALUES(10, 20);
-connect con_del,localhost,root,,;
-SET DEBUG_SYNC = 'now WAIT_FOR ins_set_locks';
-SET DEBUG_SYNC = 'lock_wait_suspend_thread_enter SIGNAL del_locked';
-DELETE FROM t WHERE b = 20;
-connection default;
-SET DEBUG_SYNC = 'now WAIT_FOR del_locked';
-SET DEBUG_SYNC = 'now SIGNAL ins_cont';
-connection con_ins;
-disconnect con_ins;
-connection con_del;
-disconnect con_del;
-disconnect prevent_purge;
-connection default;
-SET DEBUG_SYNC = 'RESET';
-DROP TABLE t;
diff --git a/mysql-test/suite/innodb/r/page_reorganize.result b/mysql-test/suite/innodb/r/page_reorganize.result
index 1059fc78531..20e1600bd0d 100644
--- a/mysql-test/suite/innodb/r/page_reorganize.result
+++ b/mysql-test/suite/innodb/r/page_reorganize.result
@@ -25,3 +25,10 @@ f1
disconnect con1;
connection default;
drop table t1;
+#
+# MDEV-27993 Assertion failed in btr_page_reorganize_low()
+#
+CREATE TABLE t1(a INT PRIMARY KEY, b INT UNIQUE) ENGINE=InnoDB;
+SET DEBUG_DBUG = '+d,do_page_reorganize';
+INSERT INTO t1 VALUES(0,0);
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/t/innodb_buffer_pool_resize_bigtest.opt b/mysql-test/suite/innodb/t/innodb_buffer_pool_resize_bigtest.opt
new file mode 100644
index 00000000000..72f055d3b58
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_buffer_pool_resize_bigtest.opt
@@ -0,0 +1,2 @@
+--innodb-buffer-pool-chunk-size=1M
+--loose-skip-innodb-disable-resize_buffer_pool_debug
diff --git a/mysql-test/suite/innodb/t/innodb_buffer_pool_resize_bigtest.test b/mysql-test/suite/innodb/t/innodb_buffer_pool_resize_bigtest.test
new file mode 100644
index 00000000000..db5da2924fa
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_buffer_pool_resize_bigtest.test
@@ -0,0 +1,28 @@
+--source include/have_innodb.inc
+--source include/big_test.inc
+
+SET @save_size=@@innodb_buffer_pool_size;
+
+let $wait_timeout = 60;
+let $wait_condition =
+ SELECT SUBSTR(variable_value, 1, 30) = 'Completed resizing buffer pool'
+ FROM information_schema.global_status
+ WHERE variable_name = 'INNODB_BUFFER_POOL_RESIZE_STATUS';
+
+--echo #
+--echo # MDEV-27891: Delayed SIGSEGV in InnoDB buffer pool resize
+--echo # after or during DROP TABLE
+--echo #
+
+select @@innodb_buffer_pool_chunk_size;
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
+SET GLOBAL innodb_buffer_pool_size=256*1024*1024;
+DROP TABLE t1;
+--source include/wait_condition.inc
+SET GLOBAL innodb_buffer_pool_size=@@innodb_buffer_pool_size + @@innodb_buffer_pool_chunk_size;
+--source include/wait_condition.inc
+
+--echo # End of 10.6 tests
+
+SET GLOBAL innodb_buffer_pool_size=@save_size;
+--source include/wait_condition.inc
diff --git a/mysql-test/suite/innodb/t/instant_alter_debug.test b/mysql-test/suite/innodb/t/instant_alter_debug.test
index 02464d4f100..f102185c27f 100644
--- a/mysql-test/suite/innodb/t/instant_alter_debug.test
+++ b/mysql-test/suite/innodb/t/instant_alter_debug.test
@@ -533,11 +533,28 @@ set DEBUG_SYNC='now SIGNAL go';
connection default;
reap;
-disconnect con1;
SELECT * FROM t1;
DROP TABLE t1;
SET DEBUG_SYNC=RESET;
+--echo #
+--echo # MDEV-27962 Instant DDL downgrades the MDL when table is empty
+--echo #
+CREATE TABLE t1(f1 INT NOT NULL, f2 INT NOT NULL)ENGINE=InnoDB;
+SET DEBUG_SYNC="alter_table_inplace_after_lock_downgrade SIGNAL try_insert WAIT_FOR alter_progress";
+send ALTER TABLE t1 ADD INDEX(f1), ADD INDEX(f2);
+connection con1;
+SET SESSION lock_wait_timeout=1;
+SET DEBUG_SYNC="now WAIT_FOR try_insert";
+--error ER_LOCK_WAIT_TIMEOUT
+INSERT INTO t1 VALUES(1, 2);
+SET DEBUG_SYNC="now SIGNAL alter_progress";
+disconnect con1;
+connection default;
+reap;
+DROP TABLE t1;
+SET DEBUG_SYNC=reset;
+
--echo # End of 10.4 tests
--echo #
diff --git a/mysql-test/suite/innodb/t/lock_delete_updated.test b/mysql-test/suite/innodb/t/lock_delete_updated.test
new file mode 100644
index 00000000000..4621d5fcd2b
--- /dev/null
+++ b/mysql-test/suite/innodb/t/lock_delete_updated.test
@@ -0,0 +1,34 @@
+--source include/have_innodb.inc
+--source include/count_sessions.inc
+
+CREATE TABLE t(a INT PRIMARY KEY) ENGINE=InnoDB;
+INSERT INTO t VALUES (3);
+
+BEGIN;
+
+connection default;
+UPDATE t SET a = 2;
+
+connect con1,localhost,root;
+send DELETE FROM t;
+
+connection default;
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Updating" and info = "DELETE FROM t";
+--source include/wait_condition.inc
+
+UPDATE t SET a = 1;
+COMMIT;
+
+connection con1;
+error ER_LOCK_DEADLOCK;
+reap;
+disconnect con1;
+
+connection default;
+--echo # The above DELETE must delete all the rows in the table, so the
+--echo # following SELECT must show 0 rows.
+SELECT count(*) FROM t;
+DROP TABLE t;
+--source include/wait_until_count_sessions.inc
diff --git a/mysql-test/suite/innodb/t/lock_wait_conflict.test b/mysql-test/suite/innodb/t/lock_wait_conflict.test
deleted file mode 100644
index 46a29e14b43..00000000000
--- a/mysql-test/suite/innodb/t/lock_wait_conflict.test
+++ /dev/null
@@ -1,60 +0,0 @@
---source include/have_innodb.inc
---source include/count_sessions.inc
---source include/have_debug.inc
---source include/have_debug_sync.inc
-
---echo #
---echo # MDEV-27025 insert-intention lock conflicts with waiting ORDINARY lock
---echo #
-
-# The test checks the ability to acquire exclusive record lock if the acquiring
-# transaction already holds a shared lock on the record and another transaction
-# is waiting for a lock.
-
-CREATE TABLE t (a INT PRIMARY KEY, b INT NOT NULL UNIQUE) ENGINE=InnoDB;
-
---connect(prevent_purge,localhost,root,,)
-start transaction with consistent snapshot;
-
---connection default
-INSERT INTO t VALUES (20,20);
-DELETE FROM t WHERE b = 20;
-
---connect(con_ins,localhost,root,,)
-SET DEBUG_SYNC = 'row_ins_sec_index_entry_dup_locks_created SIGNAL ins_set_locks WAIT_FOR ins_cont';
-send
-INSERT INTO t VALUES(10, 20);
-
---connect(con_del,localhost,root,,)
-SET DEBUG_SYNC = 'now WAIT_FOR ins_set_locks';
-SET DEBUG_SYNC = 'lock_wait_suspend_thread_enter SIGNAL del_locked';
-###############################################################################
-# This DELETE creates waiting ORDINARY X-lock for heap_no 2 as the record is
-# delete-marked, this lock conflicts with ORDINARY S-lock set by the the last
-# INSERT. After the last INSERT creates insert-intention lock on
-# heap_no 2, this lock will conflict with waiting ORDINARY X-lock of this
-# DELETE, what causes DEADLOCK error for this DELETE.
-###############################################################################
-send
-DELETE FROM t WHERE b = 20;
-
---connection default
-SET DEBUG_SYNC = 'now WAIT_FOR del_locked';
-SET DEBUG_SYNC = 'now SIGNAL ins_cont';
-
---connection con_ins
---reap
---disconnect con_ins
-
---connection con_del
-# Without the fix, ER_LOCK_DEADLOCK would be reported here.
---reap
---disconnect con_del
-
---disconnect prevent_purge
-
---connection default
-
-SET DEBUG_SYNC = 'RESET';
-DROP TABLE t;
---source include/wait_until_count_sessions.inc
diff --git a/mysql-test/suite/innodb/t/page_reorganize.test b/mysql-test/suite/innodb/t/page_reorganize.test
index 7408353976d..c4e0160cb6d 100644
--- a/mysql-test/suite/innodb/t/page_reorganize.test
+++ b/mysql-test/suite/innodb/t/page_reorganize.test
@@ -53,4 +53,12 @@ connection default;
drop table t1;
+--echo #
+--echo # MDEV-27993 Assertion failed in btr_page_reorganize_low()
+--echo #
+CREATE TABLE t1(a INT PRIMARY KEY, b INT UNIQUE) ENGINE=InnoDB;
+SET DEBUG_DBUG = '+d,do_page_reorganize';
+INSERT INTO t1 VALUES(0,0);
+DROP TABLE t1;
+
--source include/wait_until_count_sessions.inc
diff --git a/mysql-test/suite/innodb_fts/r/innodb-fts-ddl.result b/mysql-test/suite/innodb_fts/r/innodb-fts-ddl.result
index a64086c9802..daf552cde8b 100644
--- a/mysql-test/suite/innodb_fts/r/innodb-fts-ddl.result
+++ b/mysql-test/suite/innodb_fts/r/innodb-fts-ddl.result
@@ -289,3 +289,32 @@ ENGINE=InnoDB;
ALTER TABLE t1 ADD c SERIAL;
DROP TABLE t1;
# End of 10.3 tests
+#
+# MDEV-27582 Fulltext DDL decrements the FTS_DOC_ID value
+#
+CREATE TABLE t1 (
+f1 INT NOT NULL PRIMARY KEY,
+f2 VARCHAR(64), FULLTEXT ft(f2)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1,'foo'),(2,'bar');
+connect con1,localhost,root,,,;
+START TRANSACTION WITH CONSISTENT SNAPSHOT;
+connection default;
+DELETE FROM t1 WHERE f1 = 2;
+ALTER TABLE t1 DROP INDEX ft;
+ALTER TABLE t1 ADD FULLTEXT INDEX ft (f2);
+INSERT INTO t1 VALUES (3, 'innodb fts search');
+SET GLOBAL innodb_optimize_fulltext_only=ON;
+OPTIMIZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 optimize status OK
+SET GLOBAL innodb_ft_aux_table = 'test/t1';
+SELECT max(DOC_ID) FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE;
+max(DOC_ID)
+3
+SELECT * FROM t1 WHERE MATCH(f2) AGAINST("+innodb +search" IN BOOLEAN MODE);
+f1 f2
+3 innodb fts search
+DROP TABLE t1;
+disconnect con1;
+SET GLOBAL innodb_optimize_fulltext_only=OFF;
+SET GLOBAL innodb_ft_aux_table = default;
diff --git a/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.opt b/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.opt
index e6ae8d0fe0a..5d5cca1c6f2 100644
--- a/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.opt
+++ b/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.opt
@@ -1 +1,2 @@
--enable-plugin-innodb-sys-tables
+--innodb_ft_index_table
diff --git a/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test b/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test
index e8a7d603750..1ed164492d5 100644
--- a/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test
+++ b/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test
@@ -357,3 +357,28 @@ ALTER TABLE t1 ADD c SERIAL;
DROP TABLE t1;
--echo # End of 10.3 tests
+
+--echo #
+--echo # MDEV-27582 Fulltext DDL decrements the FTS_DOC_ID value
+--echo #
+CREATE TABLE t1 (
+ f1 INT NOT NULL PRIMARY KEY,
+ f2 VARCHAR(64), FULLTEXT ft(f2)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1,'foo'),(2,'bar');
+connect(con1,localhost,root,,,);
+START TRANSACTION WITH CONSISTENT SNAPSHOT;
+
+connection default;
+DELETE FROM t1 WHERE f1 = 2;
+ALTER TABLE t1 DROP INDEX ft;
+ALTER TABLE t1 ADD FULLTEXT INDEX ft (f2);
+INSERT INTO t1 VALUES (3, 'innodb fts search');
+SET GLOBAL innodb_optimize_fulltext_only=ON;
+OPTIMIZE TABLE t1;
+SET GLOBAL innodb_ft_aux_table = 'test/t1';
+SELECT max(DOC_ID) FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE;
+SELECT * FROM t1 WHERE MATCH(f2) AGAINST("+innodb +search" IN BOOLEAN MODE);
+DROP TABLE t1;
+disconnect con1;
+SET GLOBAL innodb_optimize_fulltext_only=OFF;
+SET GLOBAL innodb_ft_aux_table = default;
diff --git a/mysql-test/suite/versioning/r/update.result b/mysql-test/suite/versioning/r/update.result
index b899969d1d1..c62a992ceb1 100644
--- a/mysql-test/suite/versioning/r/update.result
+++ b/mysql-test/suite/versioning/r/update.result
@@ -283,6 +283,7 @@ connection default;
update t1 set b = 'foo';
connection con1;
update t1 set a = 'bar';
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
disconnect con1;
connection default;
drop table t1;
diff --git a/mysql-test/suite/versioning/t/update.test b/mysql-test/suite/versioning/t/update.test
index a80a8a7b714..8ef304f2de3 100644
--- a/mysql-test/suite/versioning/t/update.test
+++ b/mysql-test/suite/versioning/t/update.test
@@ -186,9 +186,7 @@ send update t1 set b = 'foo';
connection con1;
let $wait_condition= select count(*) from information_schema.innodb_lock_waits;
source include/wait_condition.inc;
-# There must no be DEADLOCK here as con1 transaction already holds locks, and
-# default's transaction lock is waiting, so the locks of the following "UPDATE"
-# must not conflict with waiting lock.
+error ER_LOCK_DEADLOCK;
update t1 set a = 'bar';
disconnect con1;
connection default;
diff --git a/plugin/type_mysql_json/type.cc b/plugin/type_mysql_json/type.cc
index d2d49b20229..7e6576e5df4 100644
--- a/plugin/type_mysql_json/type.cc
+++ b/plugin/type_mysql_json/type.cc
@@ -211,6 +211,6 @@ maria_declare_plugin(type_mysql_json)
NULL,
NULL,
"0.1",
- MariaDB_PLUGIN_MATURITY_BETA
+ MariaDB_PLUGIN_MATURITY_GAMMA
}
maria_declare_plugin_end;
diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh
index 667b57b0f63..4f499d8e577 100644
--- a/scripts/mysql_install_db.sh
+++ b/scripts/mysql_install_db.sh
@@ -525,10 +525,11 @@ then
args="$args --user=$user"
fi
-if test -n "$group"
-then
- args="$args --group=$group"
-fi
+#To be enabled if/when we enable --group as an option to mysqld
+#if test -n "$group"
+#then
+# args="$args --group=$group"
+#fi
if test -f "$ldata/mysql/user.frm"
then
diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh
index 9ef1b0a6971..34a2de1c119 100644
--- a/scripts/mysqld_safe.sh
+++ b/scripts/mysqld_safe.sh
@@ -704,6 +704,7 @@ then
if test "$user" != "root" -o $SET_USER = 1
then
USER_OPTION="--user=$user"
+ # To be used if/when we enable --system-group as an option to mysqld
GROUP_OPTION="--group=$group"
fi
if test -n "$open_files"
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 511e7f34f3b..cbf25ddf791 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -3480,6 +3480,7 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func,
thd->alloc(f_args.arg_count*sizeof(Item_result))))
{
+ err_exit:
free_udf(u_d);
DBUG_RETURN(TRUE);
}
@@ -3511,7 +3512,8 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func,
func->used_tables_and_const_cache_join(item);
f_args.arg_type[i]=item->result_type();
}
- if (!(buffers=new (thd->mem_root) String[arg_count]) ||
+ buffers=new (thd->mem_root) String[arg_count];
+ if (!buffers ||
!multi_alloc_root(thd->mem_root,
&f_args.args, arg_count * sizeof(char *),
&f_args.lengths, arg_count * sizeof(long),
@@ -3520,10 +3522,7 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func,
&f_args.attributes, arg_count * sizeof(char *),
&f_args.attribute_lengths, arg_count * sizeof(long),
NullS))
- {
- free_udf(u_d);
- DBUG_RETURN(TRUE);
- }
+ goto err_exit;
}
if (func->fix_length_and_dec())
DBUG_RETURN(TRUE);
@@ -3591,8 +3590,7 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func,
{
my_error(ER_CANT_INITIALIZE_UDF, MYF(0),
u_d->name.str, init_msg_buff);
- free_udf(u_d);
- DBUG_RETURN(TRUE);
+ goto err_exit;
}
func->max_length=MY_MIN(initid.max_length,MAX_BLOB_WIDTH);
func->set_maybe_null(initid.maybe_null);
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 314221eccd9..8b3d1a6aefc 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -7494,16 +7494,15 @@ static bool mysql_inplace_alter_table(THD *thd,
lock for prepare phase under LOCK TABLES in the same way as when
exclusive lock is required for duration of the whole statement.
*/
- if (!ha_alter_info->mdl_exclusive_after_prepare &&
- (inplace_supported == HA_ALTER_INPLACE_EXCLUSIVE_LOCK ||
- ((inplace_supported == HA_ALTER_INPLACE_COPY_NO_LOCK ||
+ if (inplace_supported == HA_ALTER_INPLACE_EXCLUSIVE_LOCK ||
+ ((inplace_supported == HA_ALTER_INPLACE_COPY_NO_LOCK ||
inplace_supported == HA_ALTER_INPLACE_COPY_LOCK ||
inplace_supported == HA_ALTER_INPLACE_NOCOPY_NO_LOCK ||
inplace_supported == HA_ALTER_INPLACE_NOCOPY_LOCK ||
inplace_supported == HA_ALTER_INPLACE_INSTANT) &&
(thd->locked_tables_mode == LTM_LOCK_TABLES ||
thd->locked_tables_mode == LTM_PRELOCKED_UNDER_LOCK_TABLES)) ||
- alter_info->requested_lock == Alter_info::ALTER_TABLE_LOCK_EXCLUSIVE))
+ alter_info->requested_lock == Alter_info::ALTER_TABLE_LOCK_EXCLUSIVE)
{
if (wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN))
goto cleanup;
@@ -7636,7 +7635,8 @@ static bool mysql_inplace_alter_table(THD *thd,
necessary only for prepare phase (unless we are not under LOCK TABLES) and
user has not explicitly requested exclusive lock.
*/
- if ((inplace_supported == HA_ALTER_INPLACE_COPY_NO_LOCK ||
+ if (!ha_alter_info->mdl_exclusive_after_prepare &&
+ (inplace_supported == HA_ALTER_INPLACE_COPY_NO_LOCK ||
inplace_supported == HA_ALTER_INPLACE_COPY_LOCK ||
inplace_supported == HA_ALTER_INPLACE_NOCOPY_LOCK ||
inplace_supported == HA_ALTER_INPLACE_NOCOPY_NO_LOCK) &&
diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc
index 5185b90b137..f71f4e350fd 100644
--- a/storage/innobase/btr/btr0cur.cc
+++ b/storage/innobase/btr/btr0cur.cc
@@ -3,7 +3,7 @@
Copyright (c) 1994, 2019, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2015, 2021, MariaDB Corporation.
+Copyright (c) 2015, 2022, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -3501,6 +3501,7 @@ fail_err:
<< ib::hex(thr ? thr->graph->trx->id : 0)
<< ' ' << rec_printer(entry).str());
DBUG_EXECUTE_IF("do_page_reorganize",
+ if (n_recs)
btr_page_reorganize(page_cursor, index, mtr););
/* Now, try the insert */
diff --git a/storage/innobase/buf/buf0buddy.cc b/storage/innobase/buf/buf0buddy.cc
index 3d476fbac77..85a698bc875 100644
--- a/storage/innobase/buf/buf0buddy.cc
+++ b/storage/innobase/buf/buf0buddy.cc
@@ -298,7 +298,7 @@ static buf_buddy_free_t* buf_buddy_alloc_zip(ulint i)
buf = UT_LIST_GET_FIRST(buf_pool.zip_free[i]);
- if (buf_pool.curr_size < buf_pool.old_size
+ if (buf_pool.is_shrinking()
&& UT_LIST_GET_LEN(buf_pool.withdraw)
< buf_pool.withdraw_target) {
@@ -609,7 +609,7 @@ recombine:
We may waste up to 15360*max_len bytes to free blocks
(1024 + 2048 + 4096 + 8192 = 15360) */
if (UT_LIST_GET_LEN(buf_pool.zip_free[i]) < 16
- && buf_pool.curr_size >= buf_pool.old_size) {
+ && !buf_pool.is_shrinking()) {
goto func_exit;
}
@@ -715,7 +715,7 @@ buf_buddy_realloc(void* buf, ulint size)
void buf_buddy_condense_free()
{
mysql_mutex_assert_owner(&buf_pool.mutex);
- ut_ad(buf_pool.curr_size < buf_pool.old_size);
+ ut_ad(buf_pool.is_shrinking());
for (ulint i = 0; i < UT_ARR_SIZE(buf_pool.zip_free); ++i) {
buf_buddy_free_t* buf =
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc
index dbe7f9cbd2d..d6281073942 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -1191,7 +1191,6 @@ bool buf_pool_t::create()
for (size_t i= 0; i < UT_ARR_SIZE(zip_free); ++i)
UT_LIST_INIT(zip_free[i], &buf_buddy_free_t::list);
ulint s= curr_size;
- old_size= s;
s/= BUF_READ_AHEAD_PORTION;
read_ahead_area= s >= READ_AHEAD_PAGES
? READ_AHEAD_PAGES
@@ -1664,7 +1663,6 @@ inline void buf_pool_t::resize()
#endif /* BTR_CUR_HASH_ADAPT */
mysql_mutex_lock(&mutex);
- ut_ad(curr_size == old_size);
ut_ad(n_chunks_new == n_chunks);
ut_ad(UT_LIST_GET_LEN(withdraw) == 0);
@@ -1673,7 +1671,7 @@ inline void buf_pool_t::resize()
curr_size = n_chunks_new * chunks->size;
mysql_mutex_unlock(&mutex);
- if (curr_size < old_size) {
+ if (is_shrinking()) {
/* set withdraw target */
size_t w = 0;
@@ -1694,7 +1692,7 @@ inline void buf_pool_t::resize()
withdraw_retry:
/* wait for the number of blocks fit to the new size (if needed)*/
- bool should_retry_withdraw = curr_size < old_size
+ bool should_retry_withdraw = is_shrinking()
&& withdraw_blocks();
if (srv_shutdown_state != SRV_SHUTDOWN_NONE) {
@@ -1777,7 +1775,7 @@ withdraw_retry:
ULINTPF " chunks to " ULINTPF " chunks.",
n_chunks, n_chunks_new);
- if (n_chunks_new < n_chunks) {
+ if (is_shrinking()) {
/* delete chunks */
chunk_t* chunk = chunks + n_chunks_new;
const chunk_t* const echunk = chunks + n_chunks;
@@ -1841,8 +1839,7 @@ withdraw_retry:
goto calc_buf_pool_size;
}
- ulint n_chunks_copy = ut_min(n_chunks_new,
- n_chunks);
+ ulint n_chunks_copy = ut_min(n_chunks_new, n_chunks);
memcpy(new_chunks, chunks,
n_chunks_copy * sizeof *new_chunks);
@@ -1909,7 +1906,6 @@ calc_buf_pool_size:
/* set size */
ut_ad(UT_LIST_GET_LEN(withdraw) == 0);
ulint s= curr_size;
- old_size= s;
s/= BUF_READ_AHEAD_PORTION;
read_ahead_area= s >= READ_AHEAD_PAGES
? READ_AHEAD_PAGES
@@ -3866,7 +3862,7 @@ void buf_pool_t::validate()
mysql_mutex_unlock(&flush_list_mutex);
- if (curr_size == old_size
+ if (n_chunks_new == n_chunks
&& n_lru + n_free > curr_size + n_zip) {
ib::fatal() << "n_LRU " << n_lru << ", n_free " << n_free
@@ -3876,7 +3872,7 @@ void buf_pool_t::validate()
ut_ad(UT_LIST_GET_LEN(LRU) >= n_lru);
- if (curr_size == old_size
+ if (n_chunks_new == n_chunks
&& UT_LIST_GET_LEN(free) != n_free) {
ib::fatal() << "Free list len "
diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc
index 0fe9ce7a14b..1945cd04832 100644
--- a/storage/innobase/buf/buf0flu.cc
+++ b/storage/innobase/buf/buf0flu.cc
@@ -1248,7 +1248,7 @@ static void buf_flush_LRU_list_batch(ulint max, flush_counters_t *n)
ulint free_limit= srv_LRU_scan_depth;
mysql_mutex_assert_owner(&buf_pool.mutex);
- if (buf_pool.withdraw_target && buf_pool.curr_size < buf_pool.old_size)
+ if (buf_pool.withdraw_target && buf_pool.is_shrinking())
free_limit+= buf_pool.withdraw_target - UT_LIST_GET_LEN(buf_pool.withdraw);
const auto neighbors= UT_LIST_GET_LEN(buf_pool.LRU) < BUF_LRU_OLD_MIN_LEN
diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc
index 5469ac49b3a..e3f5de0697f 100644
--- a/storage/innobase/buf/buf0lru.cc
+++ b/storage/innobase/buf/buf0lru.cc
@@ -288,7 +288,7 @@ buf_block_t* buf_LRU_get_free_only()
ut_a(!block->page.in_file());
UT_LIST_REMOVE(buf_pool.free, &block->page);
- if (buf_pool.curr_size >= buf_pool.old_size
+ if (!buf_pool.is_shrinking()
|| UT_LIST_GET_LEN(buf_pool.withdraw)
>= buf_pool.withdraw_target
|| !buf_pool.will_be_withdrawn(block->page)) {
@@ -321,7 +321,7 @@ static void buf_LRU_check_size_of_non_data_objects()
{
mysql_mutex_assert_owner(&buf_pool.mutex);
- if (recv_recovery_is_on() || buf_pool.curr_size != buf_pool.old_size)
+ if (recv_recovery_is_on() || buf_pool.n_chunks_new != buf_pool.n_chunks)
return;
const auto s= UT_LIST_GET_LEN(buf_pool.free) + UT_LIST_GET_LEN(buf_pool.LRU);
@@ -1010,7 +1010,7 @@ buf_LRU_block_free_non_file_page(
page_zip_set_size(&block->page.zip, 0);
}
- if (buf_pool.curr_size < buf_pool.old_size
+ if (buf_pool.is_shrinking()
&& UT_LIST_GET_LEN(buf_pool.withdraw) < buf_pool.withdraw_target
&& buf_pool.will_be_withdrawn(block->page)) {
/* This should be withdrawn */
diff --git a/storage/innobase/dict/drop.cc b/storage/innobase/dict/drop.cc
index 0093601f32f..0263c08118e 100644
--- a/storage/innobase/dict/drop.cc
+++ b/storage/innobase/dict/drop.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2021, MariaDB Corporation.
+Copyright (c) 2021, 2022, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -152,7 +152,7 @@ dberr_t trx_t::drop_table(const dict_table_t &table)
ut_ad(table.n_lock_x_or_s == 1);
ut_ad(UT_LIST_GET_LEN(table.locks) >= 1);
#ifdef UNIV_DEBUG
- bool found_x;
+ bool found_x= false;
for (lock_t *lock= UT_LIST_GET_FIRST(table.locks); lock;
lock= UT_LIST_GET_NEXT(un_member.tab_lock.locks, lock))
{
diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc
index 2039b45498a..c7004e0c8e8 100644
--- a/storage/innobase/fts/fts0fts.cc
+++ b/storage/innobase/fts/fts0fts.cc
@@ -224,18 +224,6 @@ fts_add_doc_by_id(
/*==============*/
fts_trx_table_t*ftt, /*!< in: FTS trx table */
doc_id_t doc_id); /*!< in: doc id */
-/******************************************************************//**
-Update the last document id. This function could create a new
-transaction to update the last document id.
-@return DB_SUCCESS if OK */
-static
-dberr_t
-fts_update_sync_doc_id(
-/*===================*/
- const dict_table_t* table, /*!< in: table */
- doc_id_t doc_id, /*!< in: last document id */
- trx_t* trx) /*!< in: update trx, or NULL */
- MY_ATTRIBUTE((nonnull(1)));
/** Tokenize a document.
@param[in,out] doc document to tokenize
@@ -2484,27 +2472,6 @@ fts_get_max_cache_size(
#endif
/*********************************************************************//**
-Update the next and last Doc ID in the CONFIG table to be the input
-"doc_id" value (+ 1). We would do so after each FTS index build or
-table truncate */
-void
-fts_update_next_doc_id(
-/*===================*/
- trx_t* trx, /*!< in/out: transaction */
- const dict_table_t* table, /*!< in: table */
- doc_id_t doc_id) /*!< in: DOC ID to set */
-{
- table->fts->cache->synced_doc_id = doc_id;
- table->fts->cache->next_doc_id = doc_id + 1;
-
- table->fts->cache->first_doc_id = table->fts->cache->next_doc_id;
-
- fts_update_sync_doc_id(
- table, table->fts->cache->synced_doc_id, trx);
-
-}
-
-/*********************************************************************//**
Get the next available document id.
@return DB_SUCCESS if OK */
dberr_t
@@ -2662,17 +2629,17 @@ func_exit:
return(error);
}
-/*********************************************************************//**
-Update the last document id. This function could create a new
+/** Update the last document id. This function could create a new
transaction to update the last document id.
-@return DB_SUCCESS if OK */
-static
+@param table table to be updated
+@param doc_id last document id
+@param trx update trx or null
+@retval DB_SUCCESS if OK */
dberr_t
fts_update_sync_doc_id(
-/*===================*/
- const dict_table_t* table, /*!< in: table */
- doc_id_t doc_id, /*!< in: last document id */
- trx_t* trx) /*!< in: update trx, or NULL */
+ const dict_table_t* table,
+ doc_id_t doc_id,
+ trx_t* trx)
{
byte id[FTS_MAX_ID_LEN];
pars_info_t* info;
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index a2ea8d50154..a36fe4a1897 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -2752,44 +2752,6 @@ overflow:
return(~(ulonglong) 0);
}
-/*******************************************************************//**
-Reset the auto-increment counter to the given value, i.e. the next row
-inserted will get the given value. This is called e.g. after TRUNCATE
-is emulated by doing a 'DELETE FROM t'. HA_ERR_WRONG_COMMAND is
-returned by storage engines that don't support this operation.
-@return 0 or error code */
-int ha_innobase::reset_auto_increment(ulonglong value)
-{
- DBUG_ENTER("ha_innobase::reset_auto_increment");
-
- dberr_t error;
-
- update_thd(ha_thd());
-
- error = row_lock_table_autoinc_for_mysql(m_prebuilt);
-
- if (error != DB_SUCCESS) {
-err_exit:
- DBUG_RETURN(convert_error_code_to_mysql(
- error, m_prebuilt->table->flags, m_user_thd));
- }
-
- /* The next value can never be 0. */
- if (value == 0) {
- value = 1;
- }
-
- error = innobase_lock_autoinc();
- if (error != DB_SUCCESS) {
- goto err_exit;
- }
-
- dict_table_autoinc_initialize(m_prebuilt->table, value);
- m_prebuilt->table->autoinc_mutex.wr_unlock();
-
- DBUG_RETURN(0);
-}
-
/*********************************************************************//**
Initializes some fields in an InnoDB transaction object. */
static
@@ -8726,16 +8688,6 @@ ha_innobase::delete_row(
error, m_prebuilt->table->flags, m_user_thd));
}
-/** Delete all rows from the table.
-@return error number or 0 */
-
-int
-ha_innobase::delete_all_rows()
-{
- DBUG_ENTER("ha_innobase::delete_all_rows");
- DBUG_RETURN(HA_ERR_WRONG_COMMAND);
-}
-
/**********************************************************************//**
Removes a new lock set on a row, if it was not read optimistically. This can
be called after a row has been read in the processing of an UPDATE or a DELETE
diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h
index 4185f7a68cd..08501859ec9 100644
--- a/storage/innobase/handler/ha_innodb.h
+++ b/storage/innobase/handler/ha_innodb.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2000, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2021, MariaDB Corporation.
+Copyright (c) 2013, 2022, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -109,8 +109,6 @@ public:
double read_time(uint index, uint ranges, ha_rows rows) override;
- int delete_all_rows() override;
-
int write_row(const uchar * buf) override;
int update_row(const uchar * old_data, const uchar * new_data) override;
@@ -244,7 +242,6 @@ public:
ulonglong nb_desired_values,
ulonglong* first_value,
ulonglong* nb_reserved_values) override;
- int reset_auto_increment(ulonglong value) override;
bool get_error_message(int error, String *buf) override;
diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
index d584bab9263..e2b226b9e5c 100644
--- a/storage/innobase/include/buf0buf.h
+++ b/storage/innobase/include/buf0buf.h
@@ -1344,7 +1344,7 @@ public:
{
ut_ad(is_initialised());
size_t size= 0;
- for (auto j= n_chunks; j--; )
+ for (auto j= ut_min(n_chunks_new, n_chunks); j--; )
size+= chunks[j].size;
return size;
}
@@ -1354,7 +1354,7 @@ public:
@return whether the frame will be withdrawn */
bool will_be_withdrawn(const byte *ptr) const
{
- ut_ad(curr_size < old_size);
+ ut_ad(n_chunks_new < n_chunks);
#ifdef SAFE_MUTEX
if (resize_in_progress())
mysql_mutex_assert_owner(&mutex);
@@ -1374,7 +1374,7 @@ public:
@return whether the frame will be withdrawn */
bool will_be_withdrawn(const buf_page_t &bpage) const
{
- ut_ad(curr_size < old_size);
+ ut_ad(n_chunks_new < n_chunks);
#ifdef SAFE_MUTEX
if (resize_in_progress())
mysql_mutex_assert_owner(&mutex);
@@ -1531,11 +1531,18 @@ public:
inline void watch_remove(buf_page_t *watch, hash_chain &chain);
/** @return whether less than 1/4 of the buffer pool is available */
+ TPOOL_SUPPRESS_TSAN
bool running_out() const
{
return !recv_recovery_is_on() &&
- UNIV_UNLIKELY(UT_LIST_GET_LEN(free) + UT_LIST_GET_LEN(LRU) <
- std::min(curr_size, old_size) / 4);
+ UT_LIST_GET_LEN(free) + UT_LIST_GET_LEN(LRU) <
+ n_chunks_new / 4 * chunks->size;
+ }
+
+ /** @return whether the buffer pool is shrinking */
+ inline bool is_shrinking() const
+ {
+ return n_chunks_new < n_chunks;
}
#ifdef UNIV_DEBUG
@@ -1594,15 +1601,15 @@ public:
ut_allocator<unsigned char> allocator; /*!< Allocator used for
allocating memory for the the "chunks"
member. */
- volatile ulint n_chunks; /*!< number of buffer pool chunks */
- volatile ulint n_chunks_new; /*!< new number of buffer pool chunks */
+ ulint n_chunks; /*!< number of buffer pool chunks */
+ ulint n_chunks_new; /*!< new number of buffer pool chunks.
+ both n_chunks{,new} are protected under
+ mutex */
chunk_t* chunks; /*!< buffer pool chunks */
chunk_t* chunks_old; /*!< old buffer pool chunks to be freed
after resizing buffer pool */
/** current pool size in pages */
Atomic_counter<ulint> curr_size;
- /** previous pool size in pages */
- Atomic_counter<ulint> old_size;
/** read-ahead request size in pages */
Atomic_counter<uint32_t> read_ahead_area;
diff --git a/storage/innobase/include/fts0fts.h b/storage/innobase/include/fts0fts.h
index b83a385938b..774221dd208 100644
--- a/storage/innobase/include/fts0fts.h
+++ b/storage/innobase/include/fts0fts.h
@@ -398,17 +398,6 @@ fts_get_next_doc_id(
/*================*/
const dict_table_t* table, /*!< in: table */
doc_id_t* doc_id);/*!< out: new document id */
-/*********************************************************************//**
-Update the next and last Doc ID in the CONFIG table to be the input
-"doc_id" value (+ 1). We would do so after each FTS index build or
-table truncate */
-void
-fts_update_next_doc_id(
-/*===================*/
- trx_t* trx, /*!< in/out: transaction */
- const dict_table_t* table, /*!< in: table */
- doc_id_t doc_id) /*!< in: DOC ID to set */
- MY_ATTRIBUTE((nonnull(2)));
/******************************************************************//**
Create a new fts_doc_ids_t.
@@ -950,6 +939,18 @@ bool fts_check_aux_table(const char *name,
table_id_t *table_id,
index_id_t *index_id);
+/** Update the last document id. This function could create a new
+transaction to update the last document id.
+@param table table to be updated
+@param doc_id last document id
+@param trx update trx or null
+@retval DB_SUCCESS if OK */
+dberr_t
+fts_update_sync_doc_id(const dict_table_t *table,
+ doc_id_t doc_id,
+ trx_t *trx)
+ MY_ATTRIBUTE((nonnull(1)));
+
/** Sync the table during commit phase
@param[in] table table to be synced */
void fts_sync_during_ddl(dict_table_t* table);
diff --git a/storage/innobase/include/hash0hash.h b/storage/innobase/include/hash0hash.h
index a732c17f767..6eb5bb3f183 100644
--- a/storage/innobase/include/hash0hash.h
+++ b/storage/innobase/include/hash0hash.h
@@ -94,29 +94,6 @@ do {\
}\
} while (0)
-/*******************************************************************//**
-Inserts a struct to the head of hash table. */
-
-#define HASH_PREPEND(TYPE, NAME, TABLE, FOLD, DATA) \
-do { \
- hash_cell_t* cell3333; \
- TYPE* struct3333; \
- \
- (DATA)->NAME = NULL; \
- \
- cell3333 = &(TABLE)->array[(TABLE)->calc_hash(FOLD)]; \
- \
- if (cell3333->node == NULL) { \
- cell3333->node = DATA; \
- DATA->NAME = NULL; \
- } else { \
- struct3333 = (TYPE*) cell3333->node; \
- \
- DATA->NAME = struct3333; \
- \
- cell3333->node = DATA; \
- } \
-} while (0)
#ifdef UNIV_HASH_DEBUG
# define HASH_ASSERT_VALID(DATA) ut_a((void*) (DATA) != (void*) -1)
# define HASH_INVALIDATE(DATA, NAME) *(void**) (&DATA->NAME) = (void*) -1
diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h
index b7ff8b61752..28d75517d45 100644
--- a/storage/innobase/include/lock0lock.h
+++ b/storage/innobase/include/lock0lock.h
@@ -1175,10 +1175,6 @@ without checking for deadlocks or conflicts.
@param[in] index the index tree
@param[in,out] trx transaction
@param[in] holds_trx_mutex whether the caller holds trx->mutex
-@param[in] insert_before_waiting if true, inserts new B-tree record lock
-just after the last non-waiting lock of the current transaction which is
-located before the first waiting for the current transaction lock, otherwise
-the lock is inserted at the end of the queue
@return created lock */
lock_t*
lock_rec_create_low(
@@ -1189,8 +1185,7 @@ lock_rec_create_low(
ulint heap_no,
dict_index_t* index,
trx_t* trx,
- bool holds_trx_mutex,
- bool insert_before_waiting = false);
+ bool holds_trx_mutex);
/** Enqueue a waiting request for a lock which cannot be granted immediately.
Check for deadlocks.
diff --git a/storage/innobase/include/lock0lock.inl b/storage/innobase/include/lock0lock.inl
index 7d08cbb930c..ca64587628a 100644
--- a/storage/innobase/include/lock0lock.inl
+++ b/storage/innobase/include/lock0lock.inl
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2021, MariaDB Corporation.
+Copyright (c) 2017, 2022, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
diff --git a/storage/innobase/include/lock0priv.h b/storage/innobase/include/lock0priv.h
index 4e469c6598c..b0a5f7aaf3b 100644
--- a/storage/innobase/include/lock0priv.h
+++ b/storage/innobase/include/lock0priv.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2021, MariaDB Corporation.
+Copyright (c) 2015, 2022, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
diff --git a/storage/innobase/include/lock0priv.inl b/storage/innobase/include/lock0priv.inl
index 21e7c7c95dc..3b4ebcc835b 100644
--- a/storage/innobase/include/lock0priv.inl
+++ b/storage/innobase/include/lock0priv.inl
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2014, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2018, 2021, MariaDB Corporation.
+Copyright (c) 2018, 2022, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h
index 24bafa61337..64b0923229b 100644
--- a/storage/innobase/include/trx0trx.h
+++ b/storage/innobase/include/trx0trx.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2021, MariaDB Corporation.
+Copyright (c) 2015, 2022, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc
index 5551c85db0b..fa1ea357fe6 100644
--- a/storage/innobase/lock/lock0lock.cc
+++ b/storage/innobase/lock/lock0lock.cc
@@ -1010,37 +1010,17 @@ LOCK_INSERT_INTENTION
@param[in] id page identifier
@param[in] heap_no heap number of the record
@param[in] trx our transaction
-@param[out] was_ignored true if conflicting locks waiting for the current
-transaction were ignored
@return conflicting lock and the flag which indicated if conflicting locks
which wait for the current transaction were ignored */
static lock_t *lock_rec_other_has_conflicting(unsigned mode,
const hash_cell_t &cell,
const page_id_t id,
- ulint heap_no, const trx_t *trx,
- bool *was_ignored= nullptr)
+ ulint heap_no, const trx_t *trx)
{
bool is_supremum = (heap_no == PAGE_HEAP_NO_SUPREMUM);
for (lock_t* lock = lock_sys_t::get_first(cell, id, heap_no);
lock; lock = lock_rec_get_next(heap_no, lock)) {
- /* There is no need to lock lock_sys.wait_mutex to check
- trx->lock.wait_trx here because the current function is
- executed under the cell latch, and trx->lock.wait_trx
- transaction can change wait_trx field only under the cell
- latch, wait_trx trx_t object can not be deinitialized before
- releasing all its locks, and during releasing the locks the
- cell latch will also be requested. So while the cell latch is
- held, lock->trx->lock.wait_trx can't be changed. There also
- can't be lock loops for one record, because all waiting locks
- of the record will always wait for the same lock of the record
- in a cell array, and check for conflicting lock will always
- start with the first lock for the heap_no, and go ahead with
- the same order(the order of the locks in the cell array) */
- if (lock->is_waiting() && lock->trx->lock.wait_trx == trx) {
- if (was_ignored) *was_ignored= true;
- continue;
- }
if (lock_rec_has_to_wait(true, trx, mode, lock, is_supremum)) {
return(lock);
}
@@ -1166,10 +1146,6 @@ without checking for deadlocks or conflicts.
@param[in] index the index tree
@param[in,out] trx transaction
@param[in] holds_trx_mutex whether the caller holds trx->mutex
-@param[in] insert_before_waiting if true, inserts new B-tree record lock
-just after the last non-waiting lock of the current transaction which is
-located before the first waiting for the current transaction lock, otherwise
-the lock is inserted at the end of the queue
@return created lock */
lock_t*
lock_rec_create_low(
@@ -1180,8 +1156,7 @@ lock_rec_create_low(
ulint heap_no,
dict_index_t* index,
trx_t* trx,
- bool holds_trx_mutex,
- bool insert_before_waiting)
+ bool holds_trx_mutex)
{
lock_t* lock;
ulint n_bytes;
@@ -1256,36 +1231,7 @@ lock_rec_create_low(
ut_ad(index->table->get_ref_count() || !index->table->can_be_evicted);
const auto lock_hash = &lock_sys.hash_get(type_mode);
- hash_cell_t& cell = *lock_hash->cell_get(page_id.fold());
-
- if (insert_before_waiting
- && !(type_mode & (LOCK_PREDICATE | LOCK_PRDT_PAGE))) {
- /* Try to insert the lock just after the last non-waiting
- lock of the current transaction which immediately
- precedes the first waiting lock request. */
-
- lock_t* last_non_waiting = nullptr;
-
- for (lock_t* l = lock_sys_t::get_first(cell, page_id, heap_no);
- l; l = lock_rec_get_next(heap_no, l)) {
- if (l->is_waiting() && l->trx->lock.wait_trx == trx) {
- break;
- }
- if (l->trx == trx) {
- last_non_waiting = l;
- }
- }
-
- if (!last_non_waiting) {
- goto append_last;
- }
-
- cell.insert_after(*last_non_waiting, *lock, &lock_t::hash);
- }
- else {
-append_last:
- cell.append(*lock, &lock_t::hash);
- }
+ lock_hash->cell_get(page_id.fold())->append(*lock, &lock_t::hash);
if (type_mode & LOCK_WAIT) {
if (trx->lock.wait_trx) {
@@ -1311,7 +1257,6 @@ append_last:
/** Enqueue a waiting request for a lock which cannot be granted immediately.
Check for deadlocks.
-@param[in] c_lock conflicting lock
@param[in] type_mode the requested lock mode (LOCK_S or LOCK_X)
possibly ORed with LOCK_GAP or
LOCK_REC_NOT_GAP, ORed with
@@ -1417,15 +1362,12 @@ which does NOT check for deadlocks or lock compatibility!
@param[in] heap_no heap number of the record
@param[in] index index of record
@param[in,out] trx transaction
-@param[in] caller_owns_trx_mutex TRUE if caller owns the transaction mutex
-@param[in] insert_before_waiting true=insert B-tree record lock right
-before a waiting lock request; false=insert the lock at the end of the queue */
+@param[in] caller_owns_trx_mutex TRUE if caller owns the transaction mutex */
TRANSACTIONAL_TARGET
static void lock_rec_add_to_queue(unsigned type_mode, hash_cell_t &cell,
const page_id_t id, const page_t *page,
ulint heap_no, dict_index_t *index,
- trx_t *trx, bool caller_owns_trx_mutex,
- bool insert_before_waiting= false)
+ trx_t *trx, bool caller_owns_trx_mutex)
{
ut_d(lock_sys.hash_get(type_mode).assert_locked(id));
ut_ad(xtest() || caller_owns_trx_mutex == trx->mutex_is_owner());
@@ -1520,7 +1462,7 @@ create:
lock_rec_create_low(nullptr,
type_mode, id, page, heap_no, index, trx,
- caller_owns_trx_mutex, insert_before_waiting);
+ caller_owns_trx_mutex);
}
/*********************************************************************//**
@@ -1587,10 +1529,8 @@ lock_rec_lock(
/* Do nothing if the trx already has a strong enough lock on rec */
if (!lock_rec_has_expl(mode, g.cell(), id, heap_no, trx))
{
- bool was_ignored = false;
if (lock_t *c_lock= lock_rec_other_has_conflicting(mode, g.cell(), id,
- heap_no, trx,
- &was_ignored))
+ heap_no, trx))
/*
If another transaction has a non-gap conflicting
request in the queue, as this transaction does not
@@ -1603,7 +1543,7 @@ lock_rec_lock(
{
/* Set the requested lock on the record. */
lock_rec_add_to_queue(mode, g.cell(), id, block->page.frame, heap_no,
- index, trx, true, was_ignored);
+ index, trx, true);
err= DB_SUCCESS_LOCKED_REC;
}
}
@@ -4707,7 +4647,7 @@ func_exit:
wsrep_report_bf_lock_wait(impl_trx->mysql_thd, impl_trx->id);
wsrep_report_bf_lock_wait(other_lock->trx->mysql_thd, other_lock->trx->id);
- if (!lock_rec_has_expl(LOCK_S | LOCK_REC_NOT_GAP,
+ if (!lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP,
cell, id, heap_no,
impl_trx)) {
ib::info() << "WSREP impl BF lock conflict";
@@ -4716,22 +4656,8 @@ func_exit:
#endif /* WITH_WSREP */
{
ut_ad(other_lock->is_waiting());
- /* After MDEV-27025 fix the following case is
- possible:
- 1. trx 1 acquires S-lock;
- 2. trx 2 creates X-lock waiting for trx 1;
- 3. trx 1 creates implicit lock, as
- lock_rec_other_has_conflicting() returns no
- conflicting trx 2 X-lock, the explicit lock
- will not be created;
- 4. trx 3 creates waiting X-lock,
- it will wait for S-lock of trx 1.
- That is why we relaxing the condition here and
- check only for S-lock.
- */
- ut_ad(lock_rec_has_expl(LOCK_S
- | LOCK_REC_NOT_GAP,
- cell, id, heap_no,
+ ut_ad(lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP,
+ cell, id, heap_no,
impl_trx));
}
}
@@ -5127,7 +5053,7 @@ lock_rec_convert_impl_to_expl_for_trx(
!lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP, g.cell(), id, heap_no,
trx))
lock_rec_add_to_queue(LOCK_X | LOCK_REC_NOT_GAP, g.cell(), id,
- page_align(rec), heap_no, index, trx, true, true);
+ page_align(rec), heap_no, index, trx, true);
}
trx->mutex_unlock();
diff --git a/storage/innobase/lock/lock0prdt.cc b/storage/innobase/lock/lock0prdt.cc
index e924d46bd3f..5a12d97411f 100644
--- a/storage/innobase/lock/lock0prdt.cc
+++ b/storage/innobase/lock/lock0prdt.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2014, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2018, 2021, MariaDB Corporation.
+Copyright (c) 2018, 2022, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc
index da8f62177cb..785b7b6070d 100644
--- a/storage/innobase/row/row0merge.cc
+++ b/storage/innobase/row/row0merge.cc
@@ -3013,7 +3013,21 @@ wait_again:
err = fts_sync_table(const_cast<dict_table_t*>(new_table));
if (err == DB_SUCCESS) {
- fts_update_next_doc_id(NULL, new_table, max_doc_id);
+ new_table->fts->cache->synced_doc_id = max_doc_id;
+
+ /* Update the max value as next FTS_DOC_ID */
+ if (max_doc_id >= new_table->fts->cache->next_doc_id) {
+ new_table->fts->cache->next_doc_id =
+ max_doc_id + 1;
+ }
+
+ new_table->fts->cache->first_doc_id =
+ new_table->fts->cache->next_doc_id;
+
+ err= fts_update_sync_doc_id(
+ new_table,
+ new_table->fts->cache->synced_doc_id,
+ NULL);
}
}