• 进入"运维那点事"后,希望您第一件事就是阅读“关于”栏目,仔细阅读“关于Ctrl+c问题”,不希望误会!

MyISAM存储引擎锁机制

MySQL 彭东稳 8年前 (2016-04-03) 23454次浏览 已收录 0个评论

一、MYISAM表级锁

MyISAM存储引擎只支持表级锁的锁模式:有表级共享锁和表级排它锁

MyISAM在执行查询语句(SELECT)前,会自动给涉及的所有表加读锁,在执行更新操作(UPDATEDELETEINSERT等)前,会自动给涉及的表加写锁。

所以对MyISAM表进行操作会有以下情况:

1.MyISAM表的读操作(加读锁),不会阻塞其他进程对同一表的读请求,但会阻塞对同一表的写请求。只有当读锁释放后,才会执行其它进程的写操作。

2.MyISAM表的写操作(加写锁),会阻塞其他进程对同一表的读和写操作,只有当写锁释放后,才会执行其它进程的读写操作。

并发插入

原则上数据表有一个读锁时,其它进程无法对此表进行更新操作,但在一定条件下,MyISAM表也支持查询和插入操作的并发进行。MyISAM存储引擎有一个系统变量concurrent_insert,专门用以控制其并发插入的行为,其值分别可以为012

1. concurrent_insert设置为0时,不允许并发插入

2. concurrent_insert设置为1时,如果MyISAM表中没有空洞(即表的中间没有被删除的行),MyISAM允许在一个进程读表的同时,另一个进程从表尾插入记录。这也是MySQL的默认设置。

3. concurrent_insert设置为2时,无论MyISAM表中有没有空洞,都允许在表尾并发插入记录。

MYISAM的锁调度

由于MySQL认为写请求一般比读请求要重要,所以如果有读写请求同时进行的话,MYSQL将会优先执行写操作。这样MyISAM表在进行大量的更新操作时(特别是更新的字段中存在索引的情况下),会造成查询操作很难获得读锁,从而导致查询阻塞。

我们可以通过一些设置来调节MyISAM的调度行为:

1、通过指定启动参数low-priority-updates,使MyISAM引擎默认给予读请求以优先的权利。

2、通过执行命令SET LOW_PRIORITY_UPDATES=1,使该连接发出的更新请求优先级降低。

3、通过指定INSERTUPDATEDELETE语句的LOW_PRIORITY属性,降低该语句的优先级。

PS:上面3种方法都是要么更新优先,要么查询优先的方法。这里要说明的就是,不要盲目的给mysql设置为读优先,因为一些需要长时间运行的查询操作,也会使写进程“饿死”。只有根据你的实际情况,来决定设置哪种操作优先。这些方法还是没有从根本上同时解决查询和更新的问题

二、MYISAM表级锁实例

数据表gz_phone里有二百多万数据,字段id,phone,area,age。现在同时用多个客户端同时对该表进行操作分析。

当我用client 1进行一个比较长时间的读操作时,分别用client 23进行读和写操作并查看锁结果:

Client 1:读

Client 2:读

Client 3:写

总结:说明当数据表有一个读锁时,其它进程的查询操作可以马上执行,但更新操作需等待读锁释放后才会执行。

当用Client 1进行一个较长时间的更新操作时,用Client 2,3分别进行读写操作

Clinet 1:写

Client 2:读

Client 3:写

总结:说明当数据表有一个写锁时,其它进程的读写操作都需等待读锁释放后才会执行。


如果您觉得本站对你有帮助,那么可以支付宝扫码捐助以帮助本站更好地发展,在此谢过。
喜欢 (2)
[资助本站您就扫码 谢谢]
分享 (0)

您必须 登录 才能发表评论!