Mysql优化(出自官方文档) - 第十二篇(优化锁操作篇)
Mysql优化(出自官方文档) - 第十二篇(优化锁操作篇)
1 Internal Locking Methods
这里介绍Mysql的几种锁,该锁由Mysql自行进行管理,用户不需要处理该锁。
-
Row-Level Locking
对于InnoDB,行锁可以通过
SELECT ... FOR UPDATE
语句进行获取,如果行锁中出现了死锁,Mysql会自行检测死锁,并对相关的事务进行一定的回滚,这会极大的影响性能。行锁的优点如下:- 当不同session访问不同的行时,可以产生更少的冲突。
- 当出现rollback的时候,需要rollback的内容也更少。
- 可以长时间的锁定某一行。
-
Table-Level Locking
对于
MyISAM, MEMORY或者MERGE
表,使用的是表锁,这种类型的表使用场景多为read-only, read-mostly或者single-user
应用中。在获取表锁的时候,如果多个请求需要获取同一张表的锁,那么通常就需要进行排序,当前请求必须等到前一个请求处理完成后才能获取到表锁进行后续的处理。表锁的优点为:
- 更少的锁内存占用(行锁往往需要较多的内存)
- 当需要处理一个表中大部分行的时候速度很快,因为只需要处理一个锁就可以了。
- 进行
GROUP BY
的时候,效率更高,因为这种操作需要扫描整张表。
-
Choosing the Type of Locking
通常来讲,对于下面的场景,表锁优于行锁:
-
大多数都是读的场景
-
混合读写,但是写只包含更新和删除(没有插入),且都是更新和删除具体的一行(即通过
unique_key
获取的行),比如下面的语句:UPDATE tbl_name SET column=value WHERE unique_key_col=key_value; DELETE FROM tbl_name WHERE unique_key_col=key_value;
-
带有多个并发
INSERT
的SELECT
语句,也可以有极少数的UPDATE
和DELETE
语句 -
多个scan或者
GROUP BY
操作,但是需要保证没有写入语句。
通过使用更高级的锁,你可以更加轻松的调试并加快应用程序的效率,这些高级别的锁开销要比行级锁小很多,这些锁包括:
- 版本控制(
Versioning
)可以允许同时存在多个写和读,这意味这数据库或者表对于不同的请求支持多个不同的views,实现这种功能的手段经常有:"time travel", "copy on write", "copy on demand"
等。 Copy on demand
在大多数情况下是比行锁要好的,但是在极端情况下,要比普通的锁占用更多的内存。- 也可以使用应用级别的锁,使用
GET_LOCK()
andRELEASE_LOCK()
-
2 Metadata Locking
Mysql使用metadata Locking
来管理对数据库对象的并发访问和保证数据的一致性,该锁不仅适用于表,也适用于schemas,stored programs(包括存储过程,函数,触发器,scheduled events), tablespaces, 使用主动使用GET_LOCK()
获取到的锁。可以通过 metadata_locks
表查看当前metadata Locking
的详情。
-
Metadata Lock Acquisition
对于
DML
来讲,锁的获取按照statement里面涉及到的顺序进行;对于DDL
,为了减小可能存在的死锁问题,锁的获取按照表名顺序进行,当然,也有特例,对于那些带有外键的表,其子表的锁也同时会被隐性的获取。 -
Metadata Lock Release
-
Mysql在事务开始,会获取
metadata locking
,在事务结束,会自动释放lock
,如果当前事务对某表进行操作,其他事务尝试对该表进行DDL
操作,那么其他事务会阻塞。 -
除了
DDL
语句,LOCK TABLES ... READ
语句也会有获取metadata Locking
的效果。 -
如果一个事务中,某条语句获取了
metadata Locking
,但是后续语句执行失败了,对于该事务,Mysql不会提前释放metadata Locking
,因为这些失败的语句会写入到binlog
中,锁可以保证log的一致性。 -
在
autocommit
模式下,每一条语句都是一个完整的事务,所以metadata locking
的获取和释放只发生在语句的开始和结束。 -
对于prepare语句,锁的获取开始于prepare语句,结束于prepare语句完成后。
-
对于Mysql8.0.13,一个处于PREPARED状态的
XA
事务,即使客户端失去了链接或者服务器重启了,metadata lock也会一直被保存着(持久化),除非XA COMMIT
orXA ROLLBACK
被执行。
-
3 External Locking
外部锁通常指多个Mysql进程共享一个数据文件夹,导致该文件夹被其他进程锁住的时候,当前进程就不能继续进行操作了,一般不要这么做。同时,对于MyISAM,myisamchk命令也可能会导致这种情况,需要特别注意下。