TokuDB · 特性分析 · 行锁(row-lock)与区间锁(range-lock)

简介

TokuDB使用LockTree(ft-index/locktree)来维护事务的锁状态(row-lock和range-lock),LockTree的数据结构是一个Binary Tree。 
本篇将通过几个“栗子”来谈谈TokuDB的row-lock和range-lock。 
表t:

mysql> show create table t\G
*************************** 1. row ***************************
       Table: t
Create Table: CREATE TABLE `t` (
  `id` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=TokuDB DEFAULT CHARSET=latin1

row-lock

mysql> set autocommit=off;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into t values (1),(10),(100);
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> select * from information_schema.tokudb_locks\G
*************************** 1. row ***************************
               locks_trx_id: 238
      locks_mysql_thread_id: 3
                locks_dname: ./test/t-main
             locks_key_left: 0001000000
            locks_key_right: 0001000000
         locks_table_schema: test
           locks_table_name: t
locks_table_dictionary_name: main
*************************** 2. row ***************************
               locks_trx_id: 238
      locks_mysql_thread_id: 3
                locks_dname: ./test/t-main
             locks_key_left: 000a000000
            locks_key_right: 000a000000
         locks_table_schema: test
           locks_table_name: t
locks_table_dictionary_name: main
*************************** 3. row ***************************
               locks_trx_id: 238
      locks_mysql_thread_id: 3
                locks_dname: ./test/t-main
             locks_key_left: 0064000000
            locks_key_right: 0064000000
         locks_table_schema: test
           locks_table_name: t
locks_table_dictionary_name: main
3 rows in set (0.00 sec)

从tokudb_locks表可以查询到,生成了3条row-lock(locks_key_left和locks_key_right相等)。 
为了存储和显示方便,locks_key_left/locks_key_right取key的hash值。

range-lock

mysql> set autocommit=off;
Query OK, 0 rows affected (0.00 sec)

mysql> delete from t where id<100;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from information_schema.tokudb_locks\G
*************************** 1. row ***************************
               locks_trx_id: 280
      locks_mysql_thread_id: 12
                locks_dname: ./test/t-main
             locks_key_left: -infinity
            locks_key_right: ff64000000
         locks_table_schema: test
           locks_table_name: t
locks_table_dictionary_name: main
1 row in set (0.00 sec)

从tokudb_locks表可以查询到,where条件的rang-lock区间为[-infinity, ff64000000],只要其他事务的锁区间跟这个有任何重叠,则需要等待。

锁冲突

client1执行如下操作:

mysql1> set autocommit=off;
Query OK, 0 rows affected (0.00 sec)

mysql1> insert into t values (1),(10),(100);
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql1> select * from information_schema.tokudb_locks\G
*************************** 1. row ***************************
               locks_trx_id: 283
      locks_mysql_thread_id: 14
                locks_dname: ./test/t-main
             locks_key_left: 0001000000
            locks_key_right: 0001000000
         locks_table_schema: test
           locks_table_name: t
locks_table_dictionary_name: main
*************************** 2. row ***************************
               locks_trx_id: 283
      locks_mysql_thread_id: 14
                locks_dname: ./test/t-main
             locks_key_left: 000a000000
            locks_key_right: 000a000000
         locks_table_schema: test
           locks_table_name: t
locks_table_dictionary_name: main
*************************** 3. row ***************************
               locks_trx_id: 283
      locks_mysql_thread_id: 14
                locks_dname: ./test/t-main
             locks_key_left: 0064000000
            locks_key_right: 0064000000
         locks_table_schema: test
           locks_table_name: t
locks_table_dictionary_name: main
3 rows in set (0.00 sec)

client2执行如下操作:

mysql2> set autocommit=off;
Query OK, 0 rows affected (0.00 sec)

mysql2> insert into t values (2),(100);
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql2> select * from information_schema.tokudb_locks\G
*************************** 1. row ***************************
               locks_trx_id: 283
      locks_mysql_thread_id: 14
                locks_dname: ./test/t-main
             locks_key_left: 0001000000
            locks_key_right: 0001000000
         locks_table_schema: test
           locks_table_name: t
locks_table_dictionary_name: main
*************************** 2. row ***************************
               locks_trx_id: 283
      locks_mysql_thread_id: 14
                locks_dname: ./test/t-main
             locks_key_left: 000a000000
            locks_key_right: 000a000000
         locks_table_schema: test
           locks_table_name: t
locks_table_dictionary_name: main
*************************** 3. row ***************************
               locks_trx_id: 283
      locks_mysql_thread_id: 14
                locks_dname: ./test/t-main
             locks_key_left: 0064000000
            locks_key_right: 0064000000
         locks_table_schema: test
           locks_table_name: t
locks_table_dictionary_name: main
*************************** 4. row ***************************
               locks_trx_id: 289
      locks_mysql_thread_id: 16
                locks_dname: ./test/t-main
             locks_key_left: 0002000000
            locks_key_right: 0002000000
         locks_table_schema: test
           locks_table_name: t
locks_table_dictionary_name: main
4 rows in set (0.00 sec)

mysql2> select @@tokudb_last_lock_timeout;
+--------------------------------------------------------------------------------------------------------------------+
| @@tokudb_last_lock_timeout                                                                                         |
+--------------------------------------------------------------------------------------------------------------------+
| {"mysql_thread_id":16, "dbname":"./test/t-main", "requesting_txnid":289, "blocking_txnid":283, "key":"0064000000"} |
+--------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

锁等待超时了,通过参数tokudb_last_lock_timeout得知,hash为0064000000的row-lock已经被txnid为283(client1)抢占。

总结

在使用TokuDB过程中,如果show processlist里有锁等待语句,可以通过tokudb_locks表获取到当前所有事务的锁信息,以快速定位到问题。 
TokuDB提供tokudb_lock_timeout_debug参数,可以设置不同值(默认值为1)来记录锁冲突信息,说明如下:

tokudb_lock_timeout_debug = 0: No lock timeouts or lock deadlocks are reported.
tokudb_lock_timeout_debug = 1: A JSON document that describes the lock conflict is stored in the tokudb_last_lock_timeout session variable
tokudb_lock_timeout_debug = 2: A JSON document that describes the lock conflict is printed to the MySQL error log.
tokudb_lock_timeout_debug = 3: A JSON document that describes the lock conflict is stored in the 
时间: 2024-10-26 05:44:06

TokuDB · 特性分析 · 行锁(row-lock)与区间锁(range-lock)的相关文章

MySQL · TokuDB · TokuDB 中的行锁

前言 4月份月报有篇文章<行锁(row-lock)与区间锁(range-lock)>,介绍了 TokuDB 的行锁/区间锁是如何使用的.这篇文章是其姐妹篇,介绍TokuDB行锁的实现,大家可以对照着看. 行锁申请 与 InnoDB 类似,TokuDB 也支持行级锁用来协调多个 txn 对数据库表某一段数据的并发访问.一个表中所有已经 grant 的行锁是用一个 binary search tree 来表示的,TokuDB 的术语称它为 lock tree.lock tree 与数据库表之间是一

MySQL · 特性分析 · innodb 锁分裂继承与迁移

innodb行锁简介 行锁类型 LOCK_S:共享锁 LOCK_X: 排他锁 GAP类型 LOCK_GAP:只锁间隙 LOCK_REC_NO_GAP:只锁记录 LOCK_ORDINARY: 锁记录和记录之前的间隙 LOCK_INSERT_INTENTION: 插入意向锁,用于insert时检查锁冲突 每个行锁由锁类型和GAP类型组成 例如: LOCK_X|LOCK_ORDINARY 表示对记录和记录之前的间隙加排他锁 LOCK_S|LOCK_GAP 表示只对记录前的间隙加共享锁 锁的兼容性: 值

MySQL · 特性分析 · MDL 实现分析

前言 在MySQL中,DDL是不属于事务范畴的,如果事务和DDL并行执行,操作相关联的表的话,会出现各种意想不到问题,如事务特性被破坏.binlog顺序错乱等,为了解决类似这些问题,MySQL在5.5.3引入了MDL锁(Metadata Locking),关于其设计思路可以参考这两个worklog:WL#3726 和 WL#4284.本篇从代码实现角度对MDL进行分析. 重要数据结构 MDL 是在 MySQL server 层实现的一个模块,通过对外接口和server层其它模块进行交互,在sql

[MySQL学习] Innodb锁系统(4) Insert/Delete 锁处理及死锁示例分析

A.INSERT 插入操作在函数btr_cur_optimistic_insert->btr_cur_ins_lock_and_undo->lock_rec_insert_check_and_lock这里进行锁的判断,我们简单的看看这个函数的流程: 1.首先先看看欲插入记录之后的数据上有没有锁,    next_rec = page_rec_get_next_const(rec);    next_rec_heap_no = page_rec_get_heap_no(next_rec);  

MySQL · 特性分析 · LOGICAL_CLOCK 并行复制原理及实现分析

在MySQL5.7 引入基于Logical clock的并行复制方案前,MySQL使用基于Schema的并行复制,使不同db下的DML操作可以在备库并发回放.在优化后,可以做到不同表table下并发.但是如果业务在Master端高并发写入一个库(或者优化后的表),那么slave端就会出现较大的延迟.基于schema的并行复制,Slave作为只读实例提供读取功能时候可以保证同schema下事务的因果序(Causal Consistency,本文讨论Consistency的时候均假设Slave端为只

银行取款[多线程]{使用重入锁Lock接口ReentrantLock锁确保线程同步}

经典例子:老婆(朱丽叶)老公(罗密欧),使用银行卡和存折,或者网银等,同时对同一账户操作的安全问题.  此处用多线程实现,同时取款的模拟实现,使用使用Lock接口ReentrantLock锁确保线程同步,查看取款安全隐患问题,代码如下: -----------------------------------------------------------------------------------------------------------------------------------

SQLServer · 特性分析 · SQL Server 2012的分析函数未必都理解透了(1)

title: SQLServer · 特性分析 · SQL Server 2012的分析函数未必都理解透了 author: 石沫 1. 背景 最近有用户在做一些项目,使用到SQL SERVER 2012的一些新特性,比如SQL SERVER 提供的8个非常有用的分析函数,一开始我看了相关的文档,感觉内容很多,理解不清楚,不透彻.而我现在想来,其实不需要那么清楚,我觉得值要理解他的基本用法就足以应对工作,下面根据我的理解,以最简单的方式解析这些分析函数. 1. 分析函数CUME_DIST 微软的定

SQLServer · 特性分析 · SQL Server中XML与JSON应用比较

title: SQLServer · 特性分析 · SQL Server中XML与JSON应用比较 author: 石沫 背景 SQL Server是一种强大的数据库引擎,不仅性能卓越,稳定,功能还很强大,SQL Server 2016中已经支持JSON.这让我想到以前工作中经常使用的SQL XML,也对比一下他们几个关键领域的应用方法.这两种SQL特性,在实际的工作中也是常用的功能,特别是JSON在最近发展非常火爆,SQL Server也不落后,很快就在SQL Server2016支持. 广义

SQLServer · 特性分析 · SQL Server 2012的分析函数未必都理解透了(2)

title: SQLServer · 特性分析 · SQL Server 2012的分析函数未必都理解透了 author: 石沫 1. 背景 最近有用户在做一些项目,使用到SQL SERVER 2012的一些新特性,比如SQL SERVER 提供的8个非常有用的分析函数,一开始我看了相关的文档,感觉内容很多,理解不清楚,不透彻.而我现在想来,其实不需要那么清楚,我觉得值要理解他的基本用法就足以应对工作,下面根据我的理解,以最简单的方式解析这些分析函数. 5. 分析函数 LAG 微软定义:访问相同