myisam锁操作

5次阅读
没有评论

共计 1592 个字符,预计需要花费 4 分钟才能阅读完成。

misaim 表支持表锁,innodb 支持表锁也支持行锁。
表锁:加锁快,不会出现死锁,锁定粒度大,发生锁冲突机率高,并发度低。
可以使用 mysql> show status like 'tables%'; 查看表锁争用情况,'Table_locks_waited' 的 value 如果较高,则说明存在表锁争夺情况。

myisam 表锁

表锁测试

使用 tmux 或者打开两个终端,进入 mysql 会话,在会话 1 加写锁:‘lock table table_name write’;

其中 table_name 是数据表名。锁定之后,只有在会话 1 里可以进行查看、插入操作,

在会话 2 执行一样的操作则会进入等待。使用“unlock tables”释放锁后,会话 2 获得锁,操作才得以继续。

如何加表锁

myisam 在执行查询语句前,会自动给涉及的所有表加读锁(获得锁才可以正常操作,没有获得锁则等待),在执行更新、删除、插入动作时,会自动加写锁(隐式加锁),这个过程不需要用户干预。

给表显示加锁,一般是为了在一定程度模拟事物操作,实现对某一时间点多个表的一致性读取,比如有 order 表和 order_goods 表,一个是订单表,有总价格(total),一个是订单详细表,有多个商品,有商品小记(sub_total),这时候需要验证两张表价格是否一致,如果在不加锁的情况下直接验证,则可能在验证的过程中会有新的数据插入,造成数据的不一致,这时候就需要将两表加锁。mysql> lock tables order read local , order_detail read local; 验算完后,再释放锁 mysql>unlock tables;

注意:在执行 lock tables ... 后,只能访问显示加锁的这些表(未加锁的表则不能访问,如果是加读锁,则不可写),所以需要在加锁时,同时取得所有需要设计表带锁。

注意:如果一张表在 sql 中重复出现并且使用别名,则需要在加锁时同步锁定。

例:select * from table_a as a,tables_b as b.....,在加锁时就需要 mysql>lock table table_a as a read , table_a as b read;

并发插入

查询和插入操作并发进行。

myisam 存储引擎有一个系统变量“concurrent_insert”来控制并发操作的行为,其值 [0,1,2]

1、当值为 0 时,不允许并发插入。

2、当值为 1 时,如果表中没有空洞(自增 id,1 到 100 之间没有删除过记录),允许在一个进程读表的同时,另一个进程从尾部插入纪录,也是默认值。

3、当值为 2 时,无论有没有空洞,都允许在表尾并发插入纪录。

测试:

1)在终端进入 mysql 会话 1,mysql>lock table table_a read local;   #加读锁,这里测试读写并发,

此时,不能对锁定表进行插入、更新操作。

2)mysql 会话 2,可以插入(重点,这时会从尾部插入本条纪录,但在会话 1 中,是不显示此纪录),但更新会被等待。

3)查询刚才插入的纪录,为空。

4)会话 1 释放锁后,可以查询刚才插入的纪录,并且,会话 2 中的更新操作会被执行。

myisam 的锁调度

我们知道,读锁和写锁是互斥的,读写是串行的,这时,如果一个进程请求读锁,同时另一个进程请求写锁,mysql 会如何处理呢?答案是”写锁“先得,写锁具有优先级,mysql 认为写比读重要。这也是 myisam 表不太适合大量更新和大量查询操作的原因,大量的更新操作会造成查询操作很难获得锁,因而造成阻塞,幸好,我们可以通过设置来调节 Myisam 的调度行为。

1、通过指定启动参数 low-priority-updates,使“读”优先。

2、通过执行命令 SET LOW_PRIORITY_UPDATES=1, 使得“写”请求降低。

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

正文完
 0
admin
版权声明:本站原创文章,由 admin 于2015-11-24发表,共计1592字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)
验证码