锁机制之MySQL表锁

标签: 程序相关 mysql 锁机制 | 发表时间:2012-11-05 08:23 | 作者:胖胖
出处:http://www.phppan.com

如何保证在被并发访问时数据的一致性、完整性和有效性,是数据库关注的核心问题。数据库的锁机制就是为了解决这个问题而出现的。锁机制在一定程度上将对共享资源的并发访问有序化,从而保证数据的一致完整性。锁机制的好坏直接影响到数据的并发处理能力和性能。一个好的锁机制的实现是一个数据的核心竞争力之一。

我们知道在MySQL中存在表级锁、页级锁和行级锁,其中MySQL默认实现了表级锁定。其它锁机制在不同的存储引擎中实现,这也是MySQL特点之一:针对特定的应用场景可以使用当前合适的存储引擎。先不论各种存储引擎和锁机制的优劣,这里只是说说他们各自的特点和实现。

MyISAM存储引擎作为曾经的默认存储引擎,其使用的锁机制是MySQL提供的默认表级锁定。虽然它没有实现自己的锁机制,但是在默认表级锁的基础上,增加了并发插入的特性。并发插入与系统参数concurrent_insert相关,concurrent_insert有三个值:

  • concurrent_insert=0 关闭并发写入
  • concurrent_insert=1 (默认)在没有空数据块的MyISAM表中启用并行插入
  • concurrent_insert=2 为所有MyISAM表启用并行插入。如果表有空记录或正被另一线程使用,新行将插入到表的最后。如果表未使用,MySQL将进行普通读锁定并将新行插入空记录。

此参数与MyISAM存储引擎的数据存储方式相关:常规情况下,MyISAM的新数据都会被附加到数据文件的结尾,当做了一些DELETE操作之后,数据文件就不再是连续的,形象一点来说,就是数据文件里出现了很多hole,此时再插入新数据时,按缺省设置会先看这些hole的大小是否可以容纳下新数据,如果可以,则直接把新数据保存到hole里,反之,则把新数据保存到数据文件的结尾。之所以这样做是为了减少数据文件的大小,降低文件碎片的产生。

如果我们使用concurrent_insert=2(通常也推荐这样做),这样会产生较多的文件碎片,为此,我们需要在设置这个参数值的同时,定期对数据表进行OPTIMIZE TABLE操作。此操作可以去除删除操作后留下的数据文件碎片,减小文件尺寸,加快未来的读写操作。但是,在OPTIMIZE TABLE运行过程中,MySQL会锁表。

MySQL的表锁有两种模式:表共享读锁(Table Read Lock)和表独占写锁(Table Write Lock)。共享锁和独占锁在锁机制中是一种非常普通的实现方式。 MyISAM在执行查询语句前,会自动给涉及的所有表加读锁,在执行更新操作(DDL)前,会自动给相关的表加写锁。 MySQL的读写锁(mysys/thr_lock.c)是通过4个队列来维护的,他们分别是:

  • 当前读锁队列(lock->read): 存储当前持有读锁所有线程相关信息,按获取锁的时间排序
  • 读锁等待队列(lock->read_wait):存储正在等待读锁锁定资源的线程相关信息
  • 当前写锁队列(lock->write):存储当前持有写锁所有线程相关信息,按获取锁的时间排序
  • 写锁等待队列(lock->write_wait):存储正在等待写锁锁定资源的线程相关信息

对于读锁,当请求的资源没有加写锁或在写锁等待队列中没有更高优先级的写锁定在等待。读锁是共享锁,不会阻塞其他进程对同一资源的读请求,但会阻塞对同一资源的写请求。只有当读锁释放后,才会执行其它进程的写操作。

对于写锁,当请求的资源在当前写锁队列、写锁等待队列或当前读锁队列,进入等待写锁队列;写锁会阻塞其他进程对同一资源的读和写操作,只有当写锁释放后,才会执行其它进程的读写操作。

表锁是MySQL数据库中加锁粒度最大的一种锁,除此之外,MySQL还有页级锁和行锁。表锁的执行开销小,加锁速度快,不会出现死锁,但是其加锁的粒度大,发生锁冲突的概率非常高,从而导致并发度低。可以考虑使用主从结构解决并发度低的问题。

参考资料

http://www.zhaokunyao.com/archives/206

http://dev.mysql.com/doc/refman/5.1/zh/database-administration.html

《MySQL性能调优与架构设计》 – 简朝阳

相关 [mysql] 推荐:

Linux Ksplice,MySQL and Oracle

- Syn - DBA Notes
Oracle 在 7 月份收购了 Ksplice. 使用了 Ksplice 的 Linux 系统,为 Kernel 打补丁无需重启动,做系统维护的朋友应该明白这是一个杀手级特性. 现在该产品已经合并到 Oracle Linux 中. 目前已经有超过 700 家客户,超过 10 万套系统使用了 Ksplice (不知道国内是否已经有用户了.

MySQL Replication 线程

- - CSDN博客推荐文章
Replication 线程. Mysql 的Replication 是一个异步的复制过程,从一个Mysql instace(我们称之为Master)复制到另一个Mysql instance(我们称之Slave). 在Master 与Slave 之间的实现整个复制过程主. 要由三个线程来完成,其中两个线程(Sql 线程和IO 线程)在Slave 端,另外一个线程(IO 线程)在Master 端.

mysql backup 脚本

- - ITeye博客
网上备份脚本很多,但考虑都不周全. 保证创建备份文件只能是创建者跟root可以访问,其他用户没有权限,保证了数据库备份的安全. 上面脚本是负责备份的份数管理,. 已有 0 人发表留言,猛击->> 这里<<-参与讨论. —软件人才免语言低担保 赴美带薪读研.

Oracle MySQL Or NoSQL续

- - Sky.Jian 朝阳的天空
接前面一篇,这里再将之前在“中国系统架构师大会”5周年的时候发布的纪念册“IT架构实录”上的一篇文章发出来,也算是前面博文中PPT的一个文字版解读吧. Oracle,MySQL 还是 NoSQL. 随着阿里系的“去IOE”运动在社区的宣传声越来越大,国内正在掀起一股“去xxx”的技术潮. 不仅仅是互联网企业,包括运营商以及金融机构都已经开始加入到这个潮流之中.

mysql优化

- - 数据库 - ITeye博客
公司网站访问量越来越大,MySQL自然成为瓶颈,因此最近我一直在研究 MySQL  的优化,第一步自然想到的是 MySQL 系统参数的优化,作为一个访问量很大的网站(日20万人次以上)的数据库系统,不可能指望 MySQL  默认的系统参数能够让 MySQL运行得非常顺畅. 在Apache, PHP,  MySQL的体系架构中,MySQL对于性能的影响最大,也是关键的核心部分.

MySql动态SQL

- - SQL - 编程语言 - ITeye博客
13.7. 用于预处理语句的SQL语法. MySQL 5.1对服务器一方的预制语句提供支持. 如果您使用合适的客户端编程界面,则这种支持可以发挥在MySQL 4.1中实施的高效客户端/服务器二进制协议的优势. 候选界面包括MySQL C API客户端库(用于C程序)、MySQL Connector/J(用于Java程序)和MySQL Connector/NET.

MySQL 性能

- - 谁主沉浮
这里罗列了一些基本的 MySQL 性能提示,但不是放之四海而皆准,需要根据实际的应用情况而决定. 使用标准化设计(数据库三范式),记住表的联合查询(join)性能不会差. 选择合适的字符集,虽然UTF16无所不能,但需要两倍的存储;UTF8适合各种字符,但比latin1慢,尽可能选用latin1(此条不适合中文).

mysql explain 解析

- - SQL - 编程语言 - ITeye博客
Mysql Explain 详解. 例如: explain select * from t3 where id=3952602;. 二.explain输出解释. | id | select_type | table | type  | possible_keys     | key     | key_len | ref   | rows | Extra |.

mysql profile使用

- - 数据库 - ITeye博客
mysql的sql语句优化都使用explain,但是这个没有办法知道详细的Memory/CPU等使用量. MySQL Query Profiler, 可以查询到此 SQL 语句会执行多少, 并看出 CPU/Memory 使用. 量, 执行过程 System lock, Table lock 花多少时间等等.

mysql tips两则

- - jackyrong
mysql tips两则,都可以用来查看当前执行的语句. 已有 0 人发表留言,猛击->> 这里<<-参与讨论. —软件人才免语言低担保 赴美带薪读研.