MyISAM表锁的解决方案

Table_locks_immediate和Table_locks_waited两个状态:

Table_locks_immediate表示立即释放表锁数,Table_locks_waited表示需要等待的表锁数,
如果Table_locks_immediate / Table_locks_waited > 5000,说明不严重,
因为InnoDB是行锁而MyISAM是表锁,对于高并发写入的应用InnoDB效果会好些。
示例中的服务器Table_locks_immediate / Table_locks_waited = 235,MyISAM不太好。

?Table_locks_immediate 
The number of times that a request for a table lock could be granted immediately.

?Table_locks_waited 
The number of times that a request for a table lock could not be granted immediately and a wait was needed. If this is high and you have performance problems, you should first optimize your queries, and then either split your table or tables or use replication.

实际上应该关心的是Table_locks_waited的值
这是我们服务器上的一个值
mysql> show global status like 'table%';
+-----------------------+---------+
| Variable_name         | Value   |
+-----------------------+---------+
| Table_locks_immediate | 1147514 |
| Table_locks_waited    | 135     |
+-----------------------+---------+

解决方案大概有如下几种: 
MyISAM存储引擎有一个系统变量concurrent_insert,专门用以控制其并发插入的行为,其值分别可以为0、1或2。 
0 不允许并发操作 
1 如果MyISAM表中没有空洞(即表的中间没有被删除的行),MyISAM允许在一个进程读表的同时,另一个进程从表尾插入记录。这也是MySQL的默认设置。 
2 无论MyISAM表中有没有空洞,都允许在表尾并发插入记录

使用--low-priority-updates启用mysqld。这将给所有更新(修改)一个表的语句以比SELECT语句低的优先级。在这种情况下,在先前情形的最后的SELECT语句将在INSERT语句前执行。 
为max_write_lock_count设置一个低值,使得在一定数量的WRITE锁定后,给出READ锁定 
使用LOW_PRIORITY属性给于一个特定的INSERT,UPDATE或DELETE较低的优先级 
使用HIGH_PRIORITY属性给于一个特定的SELECT 
使用INSERT DELAYED语句

综合自己的业务需求,使用了方案2。看来需要不断监测服务器状态,再进行更合适的调整。

原文地址:https://www.cnblogs.com/ouruola863/p/8482233.html