mysql锁机制的再研究
作者:点晴
出品:大淘宝技术
在分布式系统中,分布式锁已经的使用越发常见,我们系统由于较为老旧,使用数据库实现分布式锁,方案为:使用lock_key, lock_biz组成唯一索引,利用数据库对一条记录insert和delete操作的事务性来实现不可重入的db分布式锁。
前一段时间,发现系统分布式锁出现死锁告警,在处理完问题后,重新去看现场日志,发现数据库出现了死锁,在阿里云性能诊断系统中的锁分析里找出死锁日志,但奇怪的是不同的唯一索引值出现了死锁,如下图所示。抱着不懂就研究的心态,重新去研究了mysql Inndb的锁机制(ps:公司mysql 默认是RC隔离级别)。
关于锁的基础知识
本文下方所有实例均依旧该表进行,建表语句如下:
CREATE TABLE `test_lock` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', `gmt_create` datetime NOT NULL COMMENT '创建时间', `gmt_modified` datetime NOT NULL COMMENT '修改时间', `lock_key` varchar(128) NOT NULL COMMENT '锁名称', `lock_context` varchar(512) DEFAULT NULL COMMENT '锁上下文', `lock_biz` varchar(64) NOT NULL COMMENT '锁类型', PRIMARY KEY (`id`), UNIQUE KEY `idx_uk_lock_name` (`lock_key`,`lock_biz`) ) ENGINE=InnoDB AUTO_INCREMENT=26229 DEFAULT CHARSET=utf8 COMMENT='分布式锁表' 11
锁的作用范围分类
全局锁
在DB级别对整个数据库实例加锁
加锁表现:
数据库处于只读状态
阻塞对数据的增删改以及DDL
加锁方式:lock Flush tables with read lock 释放锁:unlock tables(发生异常时会自动释放)
作用场景:全局锁主要用于做全库的逻辑备份,和设置数据库只读(set global readonly=true)相比,全局锁在发生异常时会自动释放
表锁
表级别对操作的整张表加锁, 锁定颗粒度大,资源消耗少,不会出现死锁,但并发度低
分为表共享锁和表排他锁,注意:意向锁为表锁,但是由存储引擎自己维护,无需用户手工命令干预。
显示加锁方式:lock tables {tb_name} read/write 释放锁:unlock table {tb_name} (连接中断也会自动释放)
带你读《2022技术人的百宝黑皮书》——mysql锁机制的再研究(2)https://developer.aliyun.com/article/1340033?groupCode=taobaotech