MySQL的MyISAM引擎老是发生锁表(卡死)怎么办?

作者:admin 发布时间:2020-09-24 15:02:52 浏览:1156次
最近服务器上经常出现mysql进程占CPU100%的情况,使用show processlist命令后,看到出现了很多状态为LOCKED的sql。使用show status like 'table%'检查Table_locks_immediate和Table_locks_waited,发现Table_locks_waited偏 大。出问题的表是MyISAM,分析大概是MyISAM的锁表导致。 MyISAM适合于读频率远大于写频率这一情况。而我目前的应用可能会出现在某一时段读写频率相当。大致如下: 一个客户端发出需要长时间运行的SELECT 其他客户端在同一个表上发出INSERT或者UPDATE,这个客户将等待SELECT完成 另一个客户在同一个表上发出另一个SELECT;因UPDATE或INSERT比SELECT有更高有优先级,该SELECT将等待UPDATE或INSERT完成,也将等待第一个SELECT完成 也就是说对MyISAM表的读操作,不会阻塞其他用户对同一表的读请求,但会阻塞对同一表的写请求;对 MyISAM表的写操作,则会阻塞其他用户对同一表的读和写操作;MyISAM表的读操作与写操作之间,以及写操作之间是串行的!

解决方案大概有如下几种:

当一个线程对一个表执行一个DELAYED语句时,如果不存在这样的处理程序,一个处理器线程被创建以处理对于该表的所有DELAYED语句。 通常来说,在MyISAM里读写操作是串行的,但当对同一个表进行查询和插入操作时,为了降低锁竞争的频率,根据concurrent_insert的设置,MyISAM是可以并行处理查询和插入的. 1、MyISAM存储引擎有一个系统变量concurrent_insert,专门用以控制其并发插入的行为,其值分别可以为0、1或2。 当concurrent_insert=0时 不允许并发操作 当concurrent_insert=1时 如果MyISAM表中没有空洞(即表的中间没有被删除的行),MyISAM允许在一个进程读表的同时,另一个进程从表尾插入记录。这也是MySQL的默认设置。 当concurrent_insert=2时 无论MyISAM表中有没有空洞,都允许在表尾并发插入记录 这样看来,把concurrent_insert设置为2是很划算的,至于由此产生的文件碎片,可以定期使用OPTIMIZE TABLE语法优化。 2、使用--low-priority-updates启用mysqld。这将给所有更新(修改)一个表的语句以比SELECT语句低的优先级。在这种情况下,在先前情形的最后的SELECT语句将在INSERT语句前执行。 3、为max_write_lock_count设置一个低值,使得在一定数量的WRITE锁定后,给出READ锁定 4、使用LOW_PRIORITY属性给于一个特定的INSERT,UPDATE或DELETE较低的优先级 5、使用HIGH_PRIORITY属性给于一个特定的SELECT 6、使用INSERT DELAYED语句

MyISAM锁调度

myISAM的读锁和写锁是互斥的,读写串行的。那么,在一个进程请求某个MyISAM表的锁的时候,同时另一个进程也请求同一表的写锁。 MySQL如何处理?结果是先写进程后读进程。这是应为mysql认为写请求一般比读请求重要。我们可以通过一些设置来改变锁处理先后顺序: 通过启动参数low-priority-updates,使MyISAM引擎默认给予读侵权以优先权利。 通过set low_priority_updates=1,使该连接发出的更新请求优先级降低。 通过指定insert,update,delete语句的low_priority属性,降低该语句的优先级。 还可以设置max_write_lock_count。当表的读锁到这个值的时候,mysql就暂时将写请求的优先级降低,给读进程一个获得锁的机会。

如需转载请保留本文出处: https://zhe94.com/802.html

上一篇:快速建站之前言:如何建立一个自己的网站
下一篇:你知道服务器PV、TPS、QPS是怎么计算出来的吗?