1
0
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:
Sergey Vojtovich
2016-05-06 13:44:07 +04:00
parent e2d6912609
commit d665e79c5b
31 changed files with 151 additions and 1034 deletions

View File

@ -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;