文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

MySQL实战 | 06/07 简单说说MySQL中的锁

2024-04-02 19:55

关注

MySQL实战 | 06/07 简单说说MySQL中的锁

锁是计算机协调多个进程或纯线程并发访问某一资源的机制。

在数据库中,除传统的计算资源(CPU、RAM、I/O)的争用以外,数据也是一种供许多用户共享的资源。

如何保证数据并发访问的一致性、有效性是所在有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂。

为什么要有锁?

使用数据库,避免不了并发问题,当并发事务同时访问一个资源时,有可能导致数据不一致,因此需要一种机制来将数据访问顺序化,以保证数据库数据的一致性

锁就是其中的一种机制。

我们可以用公厕做个比喻。

公厕是可供多个消费者使用的,因此可能出现多个人同时需要使用厕所的情况。

但是,厕所只有一个,总不能大家一起吧?

为了避免冲突,于是厕所里装了锁,某一个人在上测试时,可以在里面用锁锁住,其他人就不能再从外面打开了,只能等待。

等里面的人出来了,从里面把锁打开,外面的人才能进去。

下面,带你一起梳理下 MySQL 的锁管理机制和锁的执行流程,先有一个大致的脉络。

MySQL 的锁管理机制

MySQL实战 | 06/07 简单说说MySQL中的锁

1、全局读锁 — FLUSH TABLES WITH READ LOCK(SQL层)

2、表级 table-level 数据锁(SQL层)

3、Meta-data 元数据锁:在 table cache 缓存里实现的,为 DDL(Data Definition Language)提供隔离操作。

4、存储引擎特有机制 — row locks行锁,page locks页锁,table locks表级,版本控制(在引擎中实现)

相对其他数据库而言,MySQL 的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制。

MySQL 的锁执行流程

MySQL实战 | 06/07 简单说说MySQL中的锁

1、计算语句使用到的所有表;

2、在每个表:打开表,从 table cache 缓存里得到 TABLE 对象,并在此表加上 meta-data 元数据锁;

3、等待全局读锁后改变数据;

4、在每个表:锁表,在表加上 table-level 数据锁;

5、执行语句:调用:handler::write_row()/read_rnd()/read_index() 等;隐式地调用引擎级 engine-level 锁机制;

6、在每个表:释放表的数据锁;

7、在每个表:释放表的 DDL 锁并把表放回 table cache 缓存里;

下面,我们开始简单针对每一种锁,看下都有什么特点。

全局锁

加了全局锁后,整个库变为只读状态,所有的写操作都会被阻塞,包括:

加全局锁的命令:Flush tables with read lock,即 FTWRL。

全局锁的主要使用场景是全库的逻辑备份,加了全局锁进行备份时有一定的使用风险:

1、若在主库备份,备份期间只读,会影响业务;
2、若在从库备份,从库只读,无法及时同步主可以的更新,造成主从不一致;

mysqldump --single-transaction

也许你还记得,我们在之前讲事务的时候,有一个隔离级别叫做可重复读,也就是设置了隔离级别进入事务后,别的事务更改数据不会影响当前的读取。

使用 mysqldump 命令,结合 --single-transaction 参数,可以将隔离级别设置为:REPEATABLE READ。

并且随后再执行一条 START TRANSACTION 语句,让整个数据在 dump 过程中保证数据的一致性,这个选项对 InnoDB 的数据表很有用,且不会锁表。

为了确保使用 --single-transaction 命令时,最终 dump 文件的有效性。需没有下列语句 ALTER TABLE, CREATE TABLE, DROP TABLE, RENAME TABLE, TRUNCATE TABLE,因为一致性读不能隔离上述语句。所以如果在 dump 过程中,使用上述语句,可能会导致 dump 出来的文件数据不一致或者不可用。

为啥不直接使用 mysqldump --single-transaction 来备份?

因为,有些引擎不支持事务啊,比如 MyISAM 引擎,所以,现在大家都在力推用 InnoDB 替代 MyISAM。

set global readonly=true?

set global readonly=true 也可以将全局表设为只读状态,有啥区别呢?

首先,修改 global 变量的方式影响面更大,不建议使用。

另外,异常处理机制上和 FTWRL 有差异:

注意点

表级锁

表锁

语法

LOCK TABLES tbl_name ; # 不影响其他表的写操作

解锁也是:

UNLOCK TABLES;

注意点:

P.S. MYSQL 的 read lock 和 wirte lock

read-lock:允许其他并发的读请求,但阻塞写请求,即可以同时读,但不允许任何写,也叫共享锁
write-lock:不允许其他并发的读和写请求,是排他的(exclusive),也叫独占锁

元数据锁(MDL:metadata lock)

元数据锁不需要显式使用,在访问一个表的时候会自动加上

它的作用主要是保证读写的正确性。

如果有两个线程要同时给一个表加字段,其中一个要等另一个执行完才能开始执行。

事务中的 MDL 锁,在语句执行开始时申请,但是语句结束后并不会马上释放,而会等到整个事务提交后再释放

因此,需要避免长事务,因为长事务会造成锁一直不能释放,后续的操作会堆积,这个库的线程很快就会爆满。

行锁

行锁是引擎层实现的,像 MyISAM 引擎就直接不支持行锁,这些引擎在并发控制只能用表锁!

InnoDB 的行锁

两阶段协议:

当需要锁多个行时,尽量把影响并发的锁往后放,这样可以最大程度的减少事务之间的锁等待,提升并发度。

另外,InnoDB 的 行锁建立在索引的基础上,锁的是索引。因此,如果更新的列没建索引会锁住整个表。

死锁

MySQL实战 | 06/07 简单说说MySQL中的锁

不同线程出现循环资源依赖,涉及的线程都在等待别的线程释放资源。

死锁对策

1、主动等待超时,由参数 innodb_lock_wait_timeout 设置,但是业务无法等待;

2、主动死锁检测(innodb_deadlock_detect=on

发生死锁后,InnoDB 一般都可以检测到,并使一个事务释放锁回退,另一个则可以获取锁完成事务。

另外,我们可以采取以下方式避免死锁:

另外,死锁检测也非常耗费资源,判断会不会由于自己的加入导致了死锁,这是一个时间复杂度是 O(n) 的操作。

比如有 1000 个并发线程要同时更新同一行,那么死锁检测操作就是 100 万这个量级的,这将消耗大量的 CPU 资源。

如何解决死锁检测耗费资源的情况?

1、关掉死锁检测,需要保证不会发生死锁;
2、控制并发,对应相同行的更新,在进入引擎之前排队;

更新一条记录时具体什么时候用行锁什么时候是表锁

引擎支持行锁就行锁,比如 innodb;

引擎不支持行锁就表锁,比如 myisam;

Online DDL 的过程

在 MySQL5.6 中,开始支持更多的 alter table 类型操作来避免 copy data,同时支持了在线上 DDL 的过程中不阻塞 DML 操作,真正意义上的实现了 Online DDL。

MySQL实战 | 06/07 简单说说MySQL中的锁

1、拿 MDL 写锁
2、降级成 MDL 读锁
3、真正做 DDL
4、升级成 MDL 写锁
5、释放 MDL 锁

1、2、4、5 如果没有锁冲突,执行时间非常短。
第 3 步占用了 DDL 绝大部分时间,这期间这个表可以正常读写数据,是因此称为「online」

总结

上述特点来看,很难说哪种锁更好,只能相对于所处的业务场景来选择更加适合的锁机制。

如果仅从锁的角度来看,表级锁更适合以查询为主的应用场景,而行级锁则更适合于大量按索引条件并发更新少量数据的应用场景

对于平时常用的存储引擎,MyISAM 采用的是表级锁,InnoDB 采用的是行级锁加表级锁。

参考:
https://dwz.cn/oudQ7cM9

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-数据库
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯