mysql的 myisam引擎锁问题
作者:网络转载 发布时间:[ 2016/10/14 10:26:26 ] 推荐标签:MySQL 数据库
当多次使用lock tables时,不仅需要一次锁定用到的所有表,而且,同一个表在sql语句中出现多少次,要通过与sql语句中相同的别名来锁定多少次,否则也会出错。
例子:
mysql> lock table t18 read;
Query OK, 0 rows affected (0.00 sec)
mysql> select a.name,b.name from t18 a,t18 b where a.id=b.id;
ERROR 1100 (HY000): Table 'a' was not locked with LOCK TABLES
我们做了一个表本身的连接,查询出错,正确的做法如下:
##先释放上面的锁
mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)
##对别名分别锁定
mysql> lock table t18 a read,t18 b read;
Query OK, 0 rows affected (0.00 sec)
mysql> select a.name,b.name from t18 a,t18 b where a.id=b.id;
+------+------+
| name | name |
+------+------+
| fzy1 | fzy1 |
| fzy2 | fzy2 |
| fzy3 | fzy3 |
| fzy4 | fzy4 |
| fzy6 | fzy6 |
| fzy6 | fzy6 |
+------+------+
6 rows in set (0.01 sec)
3,如何加表锁
myisam在执行查询语句(select)前,会自动给涉及的所有表加读锁,在执行更新操作(update,delete,insert)前,会自动给涉及的表加写锁,这个过程并不需要用户干预,因此,用户一般不需要直接用lock table命令个myisam表显式加锁。这边我们加锁是为了模拟事务操作,实现对某一时间点多个表的一致性读取。
当我们需要同时对两张表锁定的时候:
mysql> lock tables t17 read local,t18 read local;
Query OK, 0 rows affected (0.00 sec)
#执行操作
...
mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)
(1)上面的例子lock tables时加了local 其作用是在满足myisam表并发插入的条件情况下,允许其他用户在表尾并发插入记录
(2)在用lock tables给表显式加表锁的时候,必须同时取得所有涉及表的锁,并且mysql不支持锁升级,也是说,在执行lock tables后只能访问显式加锁的这些表,不能访问未加锁的表。在自动加锁的情况下,myisam总是一次读取sql语句所需要的全部锁,这也是myisam不会出现死锁的原因。
4,并发插入
myisam表的读和写是串行的,但这是总体而言的,在一定条件下,myisam表也支持查询和插入操作的并发。
myisam存储引擎有一个系统变量concurrent_insert,专门用以控制其并发插入的行为,其值可以分别为0,1,2:
当值为0时,不允许并发插入,
当值为1时,如果myisam表中没有空洞(即表的中间没有被删除的行),myisam允许在一个进程读表的同时,另一个进程从表尾插入记录,这也是mysql的默认设置,
当值为2时,无论myisam表中有没有空洞,都允许在表尾并发插入记录。
5,myisam的锁的调度
myisam存储引擎的读锁和写锁是互斥的,读写操作是串行的。那么,一个进程请求某个myisam表的读锁,同时另一个进程也请求同一表的写锁,mysql怎么处理呢?
答案是写进程先获得锁,不仅如此,即使是读请求先到锁等待队列,写请求后到,写锁也会插入到读锁之前。这是因为mysql认为写请求一般比读请求更重要。不过我们可以通过一些设置来调节myisam的调度行为。
(1)通过指定启动参数low-priority-updates,使myisam引擎默认给予读请求以优先的权利
(2)通过执行命令set low_priority_updates=1,使该连接发出的更新请求优先级降低
(3)通过指定insert ,update ,delete 语句的low_priority属性,降低该语句的优先级。
三,小结
好,下面对锁问题总结一下:主要介绍了mysql中myisam表级锁实现特点:
对于myisam的表锁,主要有一下几点:
(1)共享锁(s)之间是兼容的,但共享锁(s)与排它锁(x)之间,以及排它锁写锁(x)之间是互斥的,也是说读和写是串行的。
(2)在一定条件下,myisqm允许查询和插入并发执行,可以利用这一点来解决应用中对同一表查询和插入的锁争用问题。
(3)myisam默认的锁调度机制是写优先,这并不一定适合所有应用,用户可以设置low_priority_updates参数,或在insert ,update ,delete 语句中指定 low_prority选项来调节读写锁的争用。
(4)由于表锁的锁定粒度打,读写之间又是串行的,因此,如果更新操作较多,myisqm表可能会出现严重的锁等待,可以考虑采用innodb表来减少冲突。
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系SPASVO小编(021-61079698-8054),我们将立即处理,马上删除。
相关推荐
在测试数据库性能时,需要注意哪些方面的内容?测试管理工具TC数据库报错的原因有哪些?怎么解决?数据库的三大范式以及五大约束编程常用的几种时间戳转换(java .net 数据库)优化mysql数据库的几个步骤数据库并行读取和写入之Python实现深入理解数据库(DB2)缓冲池(BufferPool)国内三大云数据库测试对比预警即预防:6大常见数据库安全漏洞数据库规划、设计与管理数据库-事务的概念SQL Server修改数据库物理文件存在位置使用PHP与SQL搭建可搜索的加密数据库用Python写一个NoSQL数据库详述 SQL 中的数据库操作详述 SQL 中的数据库操作Java面试准备:数据库MySQL性能优化

sales@spasvo.com