innodb_table_locks设置到底能做什么?

时间:2018-10-13 11:34:56

标签: mysql innodb locks

有人可以解释此设置如何影响innodb中的锁定行为(示例)。我用不同的线程(自动提交,innodb_table_locks,LOCK TABLE ...(写,读)等)进行了许多实验。但是似乎切换此选项不会以任何方式影响锁定行为。根据文档innodb_table_locks

  

在MySQL 5.6中,innodb_table_locks = 0对用LOCK TABLES ... WRITE显式锁定的表无效。对于通过LOCK TABLES ... WRITE隐式(例如,通过触发器)或LOCK TABLES ... READ锁定的表进行读取或写入,确实有作用。

但是,即使执行LOCK TABLES READ,即使将其设置为“ OFF”,我也看不到任何效果。

我尝试使用5.6、5.7,AWS Aurora。所有人的行为都一样。

更新: 这是我在storage / innobase / handler / ha_innodb.cc源代码中找到的:

 if (thd_sql_command(thd) == SQLCOM_LOCK_TABLES
            && THDVAR(thd, table_locks)
            && thd_test_options(thd, OPTION_NOT_AUTOCOMMIT)
            && thd_in_lock_tables(thd)) {

            dberr_t error = row_lock_table_for_mysql(
                prebuilt, NULL, 0);

            if (error != DB_SUCCESS) {
                DBUG_RETURN(
                    convert_error_code_to_mysql(
                        error, 0, thd));
            }
        }

那么,为什么他们在文档中说设置innodb_table_locks = 0对显式锁定的表无效呢?从我看来,没有这种检查。但是可能我仍然缺少一些东西。

1 个答案:

答案 0 :(得分:0)

好的,我想我已经解决了。也许这对某人会有所帮助,因为我在其他任何地方都找不到解释。 innodb_table_locks = 0不适用于 LOCK TABLE WRITE (锁定表写)的原因,是因为表锁也由 MDL (元数据锁管理器)处理。 但是, LOCK TABLE READ 的行为在版本> = 5.7中有所不同,我认为文档已过时。

这里是一个示例:

#connection 1
drop table if exists t1; 
create table t1 (id integer primary key, x integer) engine=INNODB;
insert into t1 values(0, 0),(1,1),(2,2);
begin;
SELECT * FROM t1 WHERE x = 0 FOR UPDATE;

该文件将挂起,因为它试图在第一个连接持有innodb IX 锁的同时将innodb S 锁定在表上。

#connection 2 
set @@autocommit=0;
lock table t1 READ;

由于禁用了innodb锁定,并且MDL MDL_SHARED_READ MDL_SHARED_WRITE 兼容,因此该版本将在5.6中成功。但是,在5.7及更高版本中,它也会挂起,因为他们引入了新的锁类型 MDL_SHARED_READ_ONLY ,该锁类型与 MDL_SHARED_WRITE 不兼容。

#connection 3 
set @@autocommit=0;
set @@innodb_table_locks = 0;
lock table t1 READ; 

对当前MYSQL测试用例的评论:

  

旧的锁定方法(InnoDB忽略了LOCK TABLE)   当使用LOCK TABLE ... WRITE修复错误时可以工作#46272   “ MySQL 5.4.4,新的MDL:不必要和错误#37346” innodb不会   检测更新和变更表之间的死锁。” WL#6671之后   “通过不对InnoDB表使用thr_lock.c锁来提高可伸缩性”   已实现,它也不再适用于LOCK TABLES READ。锁   TABLES锁现在完全由MDL子系统处理。

因此,我想他们需要在5.7及更高版本中更新文档,以提及即使 LOCK TABLE READ ;