大家好,我是砸锅。一个摸鱼八年的后端开发。熟悉 Go、Lua。今天和大家一起学习 MySQL😊
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 28 天,点击查看活动详情
锁
MySQL 里的锁可以分成全局锁、表级锁和行锁三类
全局锁
MySQL 全局锁是一种锁定整个数据库实例的锁。当在数据库实例上执行备份操作或进行一些维护工作时,需要使用全局锁来防止对数据库实例的并发写入操作。在加锁时,其他用户无法对任何表进行更新操作,因为所有线程都必须等待全局锁被释放。
命令是 Flush tables with read lock(FTWRL),FTWRL 多在不支持事务的引擎上使用,例如 MyISAM。让全库只读的方式尽量使用 FTWRL,因为遇到客户端异常断开时,MySQL 会自动释放这个全局锁,而使用 set global readonly=true 的话,发生异常会一直保持 readonly 状态,导致整个库长时间处于不可写状态
官方自带逻辑备份工具是 mysqldump,当 mysqldump 使用参数 -single-transaction 的时候,导数据之前就会开启一个事务,来确保拿到一致性视图,这个过程可以正常更新
表级锁
表级锁分为两种,一种是表锁,一种是元数据锁(meta data lock,MDL)
表锁语法是 lock tables … read / write ,可以使用 unlock tables 主动释放,也可以在客户端断开的时候自动释放
MDL 不需要显式使用,在访问一个表的时候会自动加上,保证读写的正确性。读锁之间不互斥,读写锁之间、写锁之间是互斥的。事务中的 MDL 锁在语句开始时申请,语句结束之后不会马上释放,而是等到整个事务提交才释放
如何安全给表加字段
在 alter table 语句里设定等待时间,如果在指定的等待时间里可以拿到 MDL 写锁最好,拿不到也不要阻塞后面的业务语句,所以在 MariaDB 里可以采取以下写法:
ALTER TABLE tbl_name NOWAIT add column ...
ALTER TABLE tbl_name WAIT N add column ...
MySQL 暂时不支持
此文章为3月Day2学习笔记,内容来源于极客时间《MySQL 实战 45 讲》