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

本文涉及的产品
云原生数据库 PolarDB 分布式版,标准版 2核8GB
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
简介: 简介 TokuDB使用LockTree(ft-index/locktree)来维护事务的锁状态(row-lock和range-lock),LockTree的数据结构是一个Binary Tree。  本篇将通过几个“栗子”来谈谈TokuDB的row-lock和range-lock。  表t:

简介

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 
相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
存储 SQL 关系型数据库
深入浅出表锁(Table Lock)
深入浅出表锁(Table Lock)
深入浅出表锁(Table Lock)
|
10月前
|
SQL 监控 关系型数据库
MySQL 并发delete不存在记录申请gap锁导致死锁
一 前言死锁,其实是一个很有意思也很有挑战的技术问题,大概每个DBA都会在工作过程中遇见。关于死锁我会持续写一个系列的案例分析,希望能够对想了解死锁的朋友有所帮助。本文源于我们的生产案例:并发申请gap锁导致的死锁案例,与之前的 死锁案例一不同,本案例是因为RR模式下两个事务中的sql可以获取同一个...
247 0
|
SQL 缓存 关系型数据库
《深入理解共享锁lock in share mode排他锁for update区别》
《深入理解共享锁lock in share mode排他锁for update区别》
《深入理解共享锁lock in share mode排他锁for update区别》
|
存储 SQL 算法
拿捏!隔离级别、幻读、Gap Lock、Next-Key Lock
前面我写了很多Mysql相关的知识点,到这一篇稍微可以串一下了,从SQL执行流程、MVCC到锁,很多时候可能觉得对于间隙锁和Next-Key Lock好像已经理解了,但是好像又觉得理解差那么一点意思,这篇文章从头来梳理一下概念,明确一下这些知识。
拿捏!隔离级别、幻读、Gap Lock、Next-Key Lock
|
SQL 关系型数据库 索引
|
索引 关系型数据库 存储
InnoDB,select为啥会阻塞insert?
MySQL的InnoDB的细粒度行锁,是它最吸引人的特性之一。
733 0
|
关系型数据库 索引
InnoDB并发插入,居然使用意向锁?
《插入InnoDB自增列,居然是表级别锁?》介绍了InnoDB所使用的七种锁中的一种,自增锁。 今天,将要介绍InnoDB另外三种:共享/排他锁,意向锁,插入意向锁。
1101 0