MySQL · myrocks · 事务锁分析
概述
MyRocks中RocksDB作为基于快照的事务引擎,其在事务支持上有别于InnoDB,有其自身的特点。在早期的月报[myrocks之事务处理] 中,我们对锁的实现有过简单的分析,本文会以一些例子来介绍MyRocks是如果来加锁解锁的。
锁类型
MyRocks早期只支持排他锁,支持SELEC… IN SHARE MODE后,MyRocks才开始引入共享锁。
/* Type of locking to apply to rows */enum { RDB_LOCK_NONE, RDB_LOCK_READ, RDB_LOCK_WRITE } m_lock_rows;
#587是关于共享锁的一个有趣BUG,有兴趣的同学可以看看。
MyRocks的锁都是内存锁,因此MyRocks事务不宜持有过多的锁,以避免占用过多的内存。
MyRocks通过参数rocksdb_max_row_locks来控制单个事务所持有锁的总数。另外,rocksdb锁系统还支持以下参数
max_num_locks:系统锁个数总限制
expiration_time:锁过期时间
如果锁个数超出限制,客户端会返回下面的错误
failed: 12054: Status error 10 received from RocksDB: Operation aborted: Failed to acquire lock due to max_num_locks limit
隔离级别
MyRocks的事务隔离级只支持的READ-COMMITED和REPEATABLE-READ。隔离级别的支持和snapshot密切相关,隔离级别为READ-COMMITED时,事务中每的个stmt都会建立一个snapshot, 隔离级别为REPEATABLE-REA时,只在事务开启后第一个stmt建立一次snapshot。MyRocks中隔离级别不同不会影响加锁和解锁的行为,因此,后面在分析MyRocks的加锁解锁时不区分隔离级别。
隐式主键
MyRocks支持创建无主键的表,但RocksDB作为KV存储,是需要KEY的。因此,RocksDB内部会给表增加一个名为”HIDDEN_PK_ID”的隐式主键列,此值自增,类似与自增列。此列对于MySQL server层是透明的,读取表数据时会自动跳过”HIDDEN_PK_ID”列。
对于无主键的表,MyRocks的锁都是加在隐式主键上的。
对于binlog复制来说,MyRocks隐式主键并不会提升复制速度,因为隐式主键对server层是透明的,主键列不会记入binlog。 因此,建议MyRocks表都指定主键。
加锁分析
以此表结构来分析各类语句的加锁情况。
create table t1(id int primary key, c1 int unique, c2 int, c3 int, key idx_c2(c2)) engine=rocksdb;
insert into t1 values(1,1,1,1);
insert into t1 values(2,2,2,2);
insert into t1 values(3,3,3,3);
insert into t1 values(4,4,4,4);
- 示例 select
select * from t1;
MVCC, 普通读不加锁
- 示例 select .. in share mode
select * from t1 where id=1 in share mode;
对主键id=1记录加S锁
- 示例 select .. for update
select * from t1 where id=1 for update;
对主键id=1记录加X锁
- 示例 insert
begin;
insert into t1 values(1,1,1,1);
rollback;
主键id=1加X锁 唯一索引c1=1加X锁
- 示例 delete by主键
begin;
delete from t1 where id=1;
rollback;
主键id=1加X锁
- 示例 delete by唯一索引
begin;
delete from t1 where c1=2;
rollback;
主键id=2加X锁,其他索引不加锁
- 示例 delete by普通索引
begin;
delete from t1 where c2=3;
rollback;
主键id=3加X锁,其他索引不加锁
- 示例 delete by无索引
begin;
delete from t1 where c3=4;
rollback;
对主键每条加X锁,其他索引不加锁
实际上server层过滤不符合条件的行会释放锁,最终只对主键id=4加X锁
- 示例 delete by 主键不存在的行
begin;
delete from t1 where id=100;
rollback;
主键id=100加X锁
- 示例 delete by 其他索引不存在的行
begin;
delete from t1 where c1=100;
rollback;
没有锁可以加
以上例子基本可以覆盖所有加锁的情况,再举例几个例子练习下
- 示例 select for update
begin;
select * from t1 where c2=3 for update;
rollback;
主键id=3加X锁, 其他索引不加锁
- 示例 update更新无索引列
begin;
update t1 set c3=5 where c3=4;
rollback;
对主键每条加X锁,其他索引不加锁
实际上server层过滤不符合条件的行会释放锁,最终只对主键id=4加X锁
- 示例 update更新索引列
begin;
update t1 set c2=5 where c3=4;
rollback;
对主键每条加X锁,其他索引不加锁
实际上server层过滤不符合条件的行会释放锁,最终只对主键id=4加X锁
同时会对唯一索引c2=5加X锁
对于无主键表的表说,RocksDB内部会有隐式主键,所加锁都在隐式主键上
解锁
事务提交或回滚时都会将事务所持有的锁都释放掉。
另外一种情况是,对于不满足查询条件的记录,MySQL会提前释放锁。
总结
- MyRocks只会对主键和唯一索引加锁,普通索引不会加锁。
- 只有插入或更新了唯一索引时,才会对唯一索引加锁,对唯一索引加锁的目的是为了保证唯一性。
- 按主键锁定查找不存在的行时,会对不存在的行主键加X锁。
- 按二级索引查找时,只会对主键加锁,不会对二级锁引加锁。
- S锁只应用于SELECT … IN SHARE MODE语句。
堆栈
最后提供一些堆栈信息,方便学习
- 走唯一索引对主键加锁
#0 rocksdb::TransactionLockMgr::TryLock #1 rocksdb::PessimisticTransactionDB::TryLock #2 rocksdb::PessimisticTransaction::TryLock #3 rocksdb::TransactionBaseImpl::GetForUpdate #4 myrocks::Rdb_transaction_impl::get_for_update #5 myrocks::ha_rocksdb::get_for_update #6 myrocks::ha_rocksdb::get_row_by_rowid #7 get_row_by_rowid #8 myrocks::ha_rocksdb::read_row_from_secondary_key #9 myrocks::ha_rocksdb::index_read_map_impl #10 myrocks::ha_rocksdb::read_range_first #11 handler::multi_range_read_next #12 QUICK_RANGE_SELECT::get_next #13 rr_quick #14 mysql_delete #15 mysql_execute_command #16 mysql_parse #17 dispatch_command
- 提交时解锁
#0 rocksdb::TransactionLockMgr::UnLockKey #1 rocksdb::TransactionLockMgr::UnLock #2 rocksdb::PessimisticTransactionDB::UnLock #3 rocksdb::PessimisticTransaction::Clear #4 rocksdb::PessimisticTransaction::Commit #5 myrocks::Rdb_transaction_impl::commit_no_binlog #6 commit #7 myrocks::rocksdb_commit #8 ha_commit_low #9 TC_LOG_DUMMY::commit #10 ha_commit_trans #11 trans_commit #12 mysql_execute_command #13 mysql_parse #14 dispatch_command
MySQL · myrocks · 事务锁分析相关推荐
- mysql InnoDB 行锁分析
我们知道 mysql innodb 在插入更新数据时是锁行的,但这里所指的行并不是直面上说的单行,而是相对的范围的行! 引起我关注这个问题的是在做天气预报查询15天(http://tqybw.net) ...
- 数据库之mysql事务原理分析与锁机制 详解
1.事务 1.2.目的 事务将数据库从一种一致性状态转换为另一种一致性状态: 1.3.组成 事务可由一条非常简单的SQL语句组成,也可以由一组复杂的SQL语句组成: 其中单条语句会默认自动添加事务控制 ...
- MySQL事务原理分析(ACID特性、隔离级别、锁、MVCC、并发读异常、并发死锁以及如何避免死锁)
MySQL事务原理分析(ACID特性.隔离级别.锁.MVCC.并发读异常.并发死锁以及如何避免死锁) 一.事务 目的 组成 特征 事务空间语句 二.ACID特性 原子性(A) 隔离性(I) 持久性(d ...
- mysql transaction用法,mysql的事务,隔离级别和锁用法实例分析
本文实例讲述了mysql的事务,隔离级别和锁用法.分享给大家供大家参考,具体如下: 事务就是一组一起成功或一起失败的sql语句.事务还应该具备,原子性,一致性,隔离性和持久性. 一.事务的基本要素 ( ...
- MySQL · 引擎分析 · InnoDB行锁分析
前言 理解InnoDB行锁,分析一条SQL语句会加什么样的行锁,会锁住哪些数据范围对业务SQL设计和分析线上死锁问题都会有很大帮助.对于InnoDB的行锁,已经有多篇月报进行了介绍,这里笔者借鉴前面月 ...
- mysql分析表锁,MySQL锁分析和监控
通常在MySQL的管理和监控中,Active Session(活动会话)是监控指标中的一个很重要的指标,通过活动会话监控,可以很清楚的了解到数据库当前是否有SQL堆积,是否处于非常繁忙的状态.那么除了 ...
- MySQL之事务、锁
锁 一.概念 锁是计算机协调多个进程或线程访问某一个资源的机制.在数据库中,除传统的计算资源(CPU.RAM.IO)的争用意外,数据也是一种许多用户共享的资源.如何保证数据并发访问的一致性.有效性是所 ...
- linux mysql 释放x锁_MySQL 加锁处理分析-转载
背景 MySQL/InnoDB的加锁分析,一直是一个比较困难的话题.我在工作过程中,经常会有同事咨询这方面的问题.同时,微博上也经常会收到MySQL锁相关的私信,让我帮助解决一些死锁的问题.本文,准备 ...
- InnoDB 事务/锁/多版本分析?你了解多少?
目录 • InnoDB事务 – 事务结构/功能 – XA事务/Group Commit – mini-transaction• InnoDB锁 – 锁结构/类型/功能 – 锁等待/死锁检测 – 自增序 ...
- 【转】【MySQL】事务与锁(四):行锁到底锁住的是什么?记录?字段?索引?
首先我们有三张表t1,t2,t3,它们都是只有两个字段, int类型的id和varchar类型的name:区别是t1没有索引,t2有主键索引,t3有唯一索引. 再强调一次,在实验前必须提前关闭自动提交 ...
最新文章
- 【Java】练习题:蒙眼过马路
- cac会议投稿难度大吗_发表 SCI 论文有多难?
- 北航计算机和上财金融,这所985财经学府,不招本科生,隐藏实力却已超过上财、央财?...
- HashMap与垃圾回收
- ubuntu添加软件源
- java合并并排序_典型合并排序的Java实现
- MatConvnet工具箱文档翻译理解二
- matlab拟合函数求系数,matlab 求拟合函数的系数
- miui11稳定版获取完整root_怎么获取root权限-MIUI11系统开启系统ROOT权限图文教程-支持小米红米全部机型...
- 按照斗地主的规则,完成洗牌发牌的动作
- codeforces1467E Distinctive Roots in a Tree
- 如何卸载vivo手机自带的应用程序(尤其是开启开发者选项后出现在状态栏的黄色警告)
- 基本面分析中必须了解的88条避雷常识
- 【 Kotlin 脚本编程Kotlin Scripting 】Linux Shell 脚本与Kotlin Scripting
- 一个疑难故障,坑了我半年青春-----知识就是生产力
- 常见电路结构分析三:自锁控制
- 水样检测有哪些项目?水样检测的可测范围盘点
- oracle报表查询sql,63.Oracle数据库SQL开发之 高级查询——使用报表函数
- 案例干货!如何构建物流行业的数据分析模型?
- iOS后台模式以及后台持续运行
热门文章
- html语义化标签_9.28晨会分享 常见的HTML5语义化标签、实体字符
- 华数java 知乎_纠结编程语言的选择?他们为什么都选择了Java?
- 怎么虚拟机做成服务器,虚拟机怎么做成服务器
- 实验一 线性表的顺序存储与实现_线性表的存储结构(java)
- mysql基于时间盲注_MySQL基于时间盲注(Time-Based Blind SQL Injection)五种延时方法...
- seq()函数--R语言
- 转 oracle 监控执行计划突然变化
- java版chsi.com.cn模拟登陆
- 本地Exchange和exchange online混合部署后OWA统一登录的实现
- Jfinal的七牛云存储插件:qiniuPlugin for jfinal.