mysql myisam的锁机制[ mysql数据库 ]
mysql数据库
时间:2024-12-03 12:11:45
作者:文/会员上传
简介:
首先我们知道MySQL支持多种引擎,并且不同存储引擎有很多不同,最重要的即便是自动提交模式下 当start transaction;之后,必须要显现的commit;才能释放锁资源,myisam的锁机制: 不支
以下为本文的正文内容,内容仅供参考!本站为公益性网站,复制本文以及下载DOC文档全部免费。
首先我们知道MySQL支持多种引擎,并且不同存储引擎有很多不同,最重要的即便是自动提交模式下 当start transaction;之后,必须要显现的commit;才能释放锁资源,myisam的锁机制: 不支持行级锁,支持的是表级锁,分为共享读锁和独占写锁。1)什么是表锁 表锁:操作对象是数据表。Mysql大多数锁策略都支持(常见mysql innodb),是系统开销最低但并发性最低的一个锁策略。事务t对整个表加读锁,则其他事务可读不可写,若加写锁,则其他事务增删改都不行2)什么是读锁 读锁:也叫共享锁、S锁,若事务T对表A加上S锁,则事务T可以读表A但不能修改表A,其他事务只能再对表A加S锁,而不能加X锁,直到T释放A上的S 锁。这保证了其他事务可以读表A,但在事务T释放表A上的S锁之前不能对表A做任何修改,总结起来就是:我读的时候你不能写;3)什么是写锁 写锁:又称排他锁、X锁。若事务T对表A加上X锁,事务T可以读表A也可以修改表A,其他事务不能再对表A加任何锁,直到事务T释放表A上的锁。这保证了其他事务在事务T释放表A上的锁之前不能再读取和修改表A,总结起来就是:我写的时候,你不能读,也不能写。实验一:我读的时候你不能写,但是你可以读; 首先表company_info是myisam引擎的表;事务1,执行长时间的查询操作mysql> select company_idfromcompany_infowhere company_name like '%liluwedafasdf%';Empty set (43.27 sec)事务2,尝试更新表company_info ,发现等待。。。执行了21秒。mysql>updatecompany_info setcompany_name='liuhehhe' where company_id='4028809f60bf40fd0160bf4678be0000';+----------------------------------+--------------+| company_id | company_name |+----------------------------------+--------------+| 4028809f60bf40fd0160bf4678be0000 | liuhehhe |+----------------------------------+--------------+Query OK, 0 rows affected(21.98 sec)Rows matched: 1Changed: 0Warnings: 0再打开一个窗口,可以看到,事务2确实在等待一个表级别的锁:mysql> showprocesslist;+----+------+-----------+----------+---------+------+------------------------------+------------------------------------------------------------------------------------------------------+| Id | User | Host| db | Command | Time | State| Info |+----+------+-----------+----------+---------+------+------------------------------+------------------------------------------------------------------------------------------------------+| 14 | root | localhost | liuwenhe | Sleep | 4506 || NULL || 15 | root | localhost | liuwenhe | Query |1 | Sending data | select company_idfromcompany_infowhere company_name like '%liluwedafasdf%' || 16 | root | localhost | liuwenhe | Query |1 |Waiting for table level lock| updatecompany_info setcompany_name='liuhehhe' where company_id='4028809f60bf40fd0160bf4678be0000 || 17 | root | localhost | NULL | Query |0 | init | showprocesslist|+----+------+-----------+----------+---------+------+------------------------------+------------------------------------------------------------------------------------------------------+4 rows in set (0.00 sec)然后再开启一个窗口,执行查询操作(事务3):发现事务1还没有执行完,事务3就执行完了,说明事务1不会阻塞事务3;mysql> select company_namefromcompany_info wherecompany_id='4028809f60bf40fd0160bf4678be0000';+--------------+| company_name |+--------------+| liuhehhe |+--------------+1 row in set (2.10 sec)实验一证明:事务1对表A加上S锁,则事务1可以读表A但不能修改表A,其他事务只能再对表A加S锁,而不能加X锁,直到T释放A上的S 锁。也就是说我读的时候你不能写,但是你可以读;实验二:我写的时候,你不能读,也不能写; 事务1:执行更新一个表的一个字段。mysql> updatecompany_info setcompany_name='liuhehhe' where company_name like'%liuwehe%';Query OK, 0 rows affected (1.95 sec)Rows matched: 0Changed: 0Warnings: 0事务2尝试查询这个表,发现等待。。mysql> select count(*) fromcompany_info;+----------+| count(*) |+----------+|1818708 |+----------+1 row in set (1.11 sec)再开启一个窗口,查看进程,发现事务2确实在等待一个表级别的锁;mysql> show processlist;+----+------+-----------+----------+---------+------+------------------------------+----------------------------------------------------------------------------------------+| Id | User | Host| db | Command | Time | State| Info |+----+------+-----------+----------+---------+------+------------------------------+----------------------------------------------------------------------------------------+| 19 | root | localhost | liuwenhe | Query |1 | updating | updatecompany_info setcompany_name='liuhehhe' where company_name like'%liuwehe%' || 20 | root | localhost | liuwenhe | Query |1 |Waiting for table level lock| select count(*) fromcompany_info || 21 | root | localhost | NULL | Query |0 | init | show processlist |+----+------+-----------+----------+---------+------+------------------------------+----------------------------------------------------------------------------------------+3 rows in set (0.00 sec)实验二证明:mysql的myisam引擎下,更新表的一行数据,也会上一个表级别的锁排他锁,不允许其他事务读取该表的数据,当然也不允许其他事务去写这个表,也就是说:我写的时候,你不能读,也不能写;mysql myisam的锁小结:MyISAM的读操作和写操作,以及写操作之间是串行的!MyISAM在执行读写操作的时候会自动给表加相应的锁(也就是说不用显示的使用lock table命令,然后注意是表级别的锁),MyISAM总是一次获得SQL语句所需要的全部锁,这也是MyISAM不会出现死锁的原因.区别于mysql innodb的锁机制,innodb的一般的select 是不会加任何锁的,接下来会介绍innodb的锁机制,请看下一篇文章
展开阅读全文 ∨