show status like 'table%';查看锁表情况
+-----------------------+---------+
| Variable_name | Value |
+-----------------------+---------+
| Table_locks_immediate | 3440025 |
| Table_locks_waited | 31936 |
+-----------------------+---------+
Table_locks_immediate表示立即释放表锁数,Table_locks_waited表示需要等待的表锁数,如果Table_locks_immediate / Table_locks_waited > 5000,最好采用InnoDB引擎,因为InnoDB是行锁而MyISAM是表锁,对于高并发写入的应用InnoDB效果会好些。否则MyISAM就足够了。
一、相关默认数值
show variables like 'concurrent_insert';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| concurrent_insert | 1 |
+-------------------+-------+
MyISAM存储引擎有一个系统变量concurrent_insert,专门用以控制其并发插入的行为,其值分别可以为0、1或2。(在my.cf的mysqld下面配置)
设置为0时,不允许并发插入。
设置为1时,如果MyISAM表中没有空洞(即表的中间没有被删除的行),MyISAM允许在一个进程读表的同时,另一个进程从表尾插入记录。这也是MySQL的默认设置。
设置为2时,无论MyISAM表中有没有空洞,都允许在表尾并发插入记录。
把concurrent_insert设置为2是很划算的,至于由此产生的文件碎片,可以定期使用OPTIMIZE TABLE语法优化。
缺省情况下,写操作的优先级要高于读操作的优先级,即便是先发送的读请求,后发送的写请求,此时也会优先处理写请求,然后再处理读请求。这就造成一 个问题:一旦我发出若干个写请求,就会堵塞所有的读请求,直到写请求全都处理完,才有机会处理读请求。此时可以考虑使用 max_write_lock_count
max_write_lock_count=3
有了这样的设置,当系统处理3个写操作后,MySQL就暂时将写请求的优先级降低,给读进程一定获得锁的机会。
二、锁表方式
1、读锁后其他本sisson不能写能读锁定的表,也不能读写其他未锁定的表,而其他sisson可以读取被锁定的表。(别名操作也需要在读锁的时候声明)
2、写锁后本sisson可以在锁定表上执行读写操作,无法读写其他未锁定的表,而其他sisson不能对锁定的表进行读写操作
MyISAM在执行查询语句(SELECT)前,会自动给涉及的所有表加读锁,在执行更新操作
(UPDATE、DELETE、INSERT等)前,会自动给涉及的表加写锁,这个过程并不需要用户干预,因此,用户一般不需要直接用LOCK
TABLE命令给MyISAM表显式加锁。
给MyISAM表显示加锁,一般是为了在一定程度模拟事务操作,实现对某一时间点多个表的一致性读取。例如, 有一个订单表orders,其中记录有各订单的总金额total,同时还有一个订单明细表order_detail,其中记录有各订单每一产品的金额小计 subtotal,假设我们需要检查这两个表的金额合计是否相符,可能就需要同时执行如下两条SQL:
Select sum(total) from orders;
Select sum(subtotal) from order_detail;
这时,如果不先给两个表加锁,就可能产生错误的结果,因为第一条语句执行过程中,order_detail表可能已经发生了改变。因此,正确的方法应该是:
先Lock tables orders read local, order_detail read local再select,最后Unlock tables;
上面的例子在LOCK TABLES时加了“local”选项,其作用就是在满足MyISAM表并发插入条件的情况下,允许其他用户在表尾并发插入记录,所谓并发插入条件,就是上面的concurrent_insert参数
阅读(1750) | 评论(0) | 转发(0) |