mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-7660 - MySQL WL#6671 "Improve scalability by not using thr_lock.c locks
for InnoDB tables" Don't use thr_lock.c locks for InnoDB tables. Below is list of changes that were needed to implement this: - HANDLER OPEN acquireis MDL_SHARED_READ instead of MDL_SHARED - HANDLER READ calls external_lock() even if SE is not going to be locked by THR_LOCK - InnoDB lock wait timeouts are now honored which are much shorter by default than server lock wait timeouts (1 year vs 50 seconds) - with @@autocommit= 1 LOCK TABLES disables autocommit implicitely, though user still sees @@autocommt= 1 - the above starts implicit transaction - transactions started by LOCK TABLES are now rolled back on disconnect (previously everything was committed due to autocommit) - transactions started by LOCK TABLES are now rolled back by ROLLBACK (previously everything was committed due to autocommit) - it is now impossible to change BINLOG_FORMAT under LOCK TABLES (at least to statement) due to running transaction - LOCK TABLES WRITE is additionally handled by MDL - ...in contrast LOCK TABLES READ protection against DML is pure InnoDB - combining transactional and non-transactional tables under LOCK TABLES may cause rolled back changes in transactional table and "committed" changes in non-transactional table - user may disable innodb_table_locks, which will cause LOCK TABLES to be noop basically Removed tests for BUG#45143 and BUG#55930 which cover InnoDB + THR_LOCK. To operate properly these tests require code flow to go through THR_LOCK debug sync points, which is not the case after this patch. These tests are removed by WL#6671 as well. An alternative is to port them to different storage engine.
This commit is contained in:
@ -338,6 +338,7 @@ Success: 'load data infile '../../std_data/rpl_loaddata.dat' into table t2 (@a,
|
||||
# 2.8 REPLACE with a subquery.
|
||||
#
|
||||
# Same is true for this statement as well.
|
||||
# Suppress warnings for REPLACE ... SELECT
|
||||
connection default;
|
||||
Success: 'replace into t2 select i+5 from t1' doesn't allow concurrent inserts into 't1'.
|
||||
connection default;
|
||||
@ -704,87 +705,6 @@ disconnect con1;
|
||||
disconnect con2;
|
||||
set @@global.concurrent_insert= @old_concurrent_insert;
|
||||
#
|
||||
# Test for bug #45143 "All connections hang on concurrent ALTER TABLE".
|
||||
#
|
||||
# Concurrent execution of statements which required weak write lock
|
||||
# (TL_WRITE_ALLOW_WRITE) on several instances of the same table and
|
||||
# statements which tried to acquire stronger write lock (TL_WRITE,
|
||||
# TL_WRITE_ALLOW_READ) on this table might have led to deadlock.
|
||||
drop table if exists t1;
|
||||
drop view if exists v1;
|
||||
# Create auxiliary connections used through the test.
|
||||
connect con_bug45143_1,localhost,root,,test,,;
|
||||
connect con_bug45143_3,localhost,root,,test,,;
|
||||
connect con_bug45143_2,localhost,root,,test,,;
|
||||
connection default;
|
||||
# Reset DEBUG_SYNC facility before using it.
|
||||
set debug_sync= 'RESET';
|
||||
# Turn off logging so calls to locking subsystem performed
|
||||
# for general_log table won't interfere with our test.
|
||||
set @old_general_log = @@global.general_log;
|
||||
set @@global.general_log= OFF;
|
||||
create table t1 (i int) engine=InnoDB;
|
||||
# We have to use view in order to make LOCK TABLES avoid
|
||||
# acquiring SNRW metadata lock on table.
|
||||
create view v1 as select * from t1;
|
||||
insert into t1 values (1);
|
||||
# Prepare user lock which will be used for resuming execution of
|
||||
# the first statement after it acquires TL_WRITE_ALLOW_WRITE lock.
|
||||
select get_lock("lock_bug45143_wait", 0);
|
||||
get_lock("lock_bug45143_wait", 0)
|
||||
1
|
||||
connection con_bug45143_1;
|
||||
# Sending:
|
||||
insert into t1 values (get_lock("lock_bug45143_wait", 100));;
|
||||
connection con_bug45143_2;
|
||||
# Wait until the above INSERT takes TL_WRITE_ALLOW_WRITE lock on 't1'
|
||||
# and then gets blocked on user lock 'lock_bug45143_wait'.
|
||||
# Ensure that upcoming SELECT waits after acquiring TL_WRITE_ALLOW_WRITE
|
||||
# lock for the first instance of 't1'.
|
||||
set debug_sync='thr_multi_lock_after_thr_lock SIGNAL parked WAIT_FOR go';
|
||||
# Sending:
|
||||
select count(*) > 0 from t1 as a, t1 as b for update;;
|
||||
connection con_bug45143_3;
|
||||
# Wait until the above SELECT ... FOR UPDATE is blocked after
|
||||
# acquiring lock for the the first instance of 't1'.
|
||||
set debug_sync= 'now WAIT_FOR parked';
|
||||
# Send LOCK TABLE statement which will try to get TL_WRITE lock on 't1':
|
||||
lock table v1 write;;
|
||||
connection default;
|
||||
# Wait until this LOCK TABLES statement starts waiting for table lock.
|
||||
# Allow SELECT ... FOR UPDATE to resume.
|
||||
# Since it already has TL_WRITE_ALLOW_WRITE lock on the first instance
|
||||
# of 't1' it should be able to get lock on the second instance without
|
||||
# waiting, even although there is another thread which has such lock
|
||||
# on this table and also there is a thread waiting for a TL_WRITE on it.
|
||||
set debug_sync= 'now SIGNAL go';
|
||||
connection con_bug45143_2;
|
||||
# Reap SELECT ... FOR UPDATE
|
||||
count(*) > 0
|
||||
1
|
||||
connection default;
|
||||
# Resume execution of the INSERT statement.
|
||||
select release_lock("lock_bug45143_wait");
|
||||
release_lock("lock_bug45143_wait")
|
||||
1
|
||||
connection con_bug45143_1;
|
||||
# Reap INSERT statement.
|
||||
# In Statement and Mixed replication mode we get here "Unsafe
|
||||
# for binlog" warnings. In row mode there are no warnings.
|
||||
# Hide the discrepancy.
|
||||
connection con_bug45143_3;
|
||||
# Reap LOCK TABLES statement.
|
||||
unlock tables;
|
||||
connection default;
|
||||
# Do clean-up.
|
||||
disconnect con_bug45143_1;
|
||||
disconnect con_bug45143_2;
|
||||
disconnect con_bug45143_3;
|
||||
set debug_sync= 'RESET';
|
||||
set @@global.general_log= @old_general_log;
|
||||
drop view v1;
|
||||
drop table t1;
|
||||
#
|
||||
# Bug#50821 Deadlock between LOCK TABLES and ALTER TABLE
|
||||
#
|
||||
DROP TABLE IF EXISTS t1, t2;
|
||||
@ -827,44 +747,6 @@ connection default;
|
||||
DROP EVENT e2;
|
||||
SET DEBUG_SYNC="RESET";
|
||||
#
|
||||
# Bug#55930 Assertion `thd->transaction.stmt.is_empty() ||
|
||||
# thd->in_sub_stmt || (thd->state..
|
||||
#
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1(a INT) engine=InnoDB;
|
||||
INSERT INTO t1 VALUES (1), (2);
|
||||
connect con1, localhost, root;
|
||||
connect con2, localhost, root;
|
||||
connection con1;
|
||||
SET SESSION lock_wait_timeout= 1;
|
||||
SET DEBUG_SYNC= 'ha_admin_open_ltable SIGNAL opti_recreate WAIT_FOR opti_analyze';
|
||||
# Sending:
|
||||
OPTIMIZE TABLE t1;
|
||||
connection con2;
|
||||
SET DEBUG_SYNC= 'now WAIT_FOR opti_recreate';
|
||||
SET DEBUG_SYNC= 'after_lock_tables_takes_lock SIGNAL thrlock WAIT_FOR release_thrlock';
|
||||
# Sending:
|
||||
INSERT INTO t1 VALUES (3);
|
||||
connection default;
|
||||
SET DEBUG_SYNC= 'now WAIT_FOR thrlock';
|
||||
SET DEBUG_SYNC= 'now SIGNAL opti_analyze';
|
||||
connection con1;
|
||||
# Reaping: OPTIMIZE TABLE t1
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
|
||||
test.t1 optimize error Lock wait timeout exceeded; try restarting transaction
|
||||
test.t1 optimize status Operation failed
|
||||
Warnings:
|
||||
Error 1205 Lock wait timeout exceeded; try restarting transaction
|
||||
SET DEBUG_SYNC= 'now SIGNAL release_thrlock';
|
||||
disconnect con1;
|
||||
connection con2;
|
||||
# Reaping: INSERT INTO t1 VALUES (3)
|
||||
disconnect con2;
|
||||
connection default;
|
||||
DROP TABLE t1;
|
||||
SET DEBUG_SYNC= 'RESET';
|
||||
#
|
||||
# Bug#57130 crash in Item_field::print during SHOW CREATE TABLE or VIEW
|
||||
#
|
||||
DROP TABLE IF EXISTS t1;
|
||||
|
Reference in New Issue
Block a user