没有合适的资源?快使用搜索试试~ 我知道了~
首页MYSQL锁机制全揭秘.pdf
资源详情
资源评论
资源推荐

资源由 www.eimhe.com 美河学习在线收集分享

资源由 www.eimhe.com 美河学习在线收集分享
MYSQL 锁
锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,除传统的 计算资
源(如 CPU、RAM、I/O 等)的争用以外,数据也是一种供许多用户共享的资源。如何保
证数据并发访问的一致性、有效性是所有数据库必须解决的一 个问题,锁冲突也是影响数
据库并发访问性能的一个重要因素。从这个角度来说,锁对数据库而言显得尤其重要,也更
加复杂。本章我们着重讨论 MySQL 锁机制 的特点,常见的锁问题,以及解决 MySQL 锁
问题的一些方法或建议。
MySQL 锁概述
相对其他数据库而言,MySQL 的锁机制比较简单,其最 显著的特点是不同的存储引擎支持
不同的锁机制。比如,MyISAM 和 MEMORY 存储引擎采用的是表级锁(table-level locking);
BDB 存储引擎采用的是页面锁(page-level locking),但也支持表级锁;InnoDB 存储引擎既
支持行级锁(row-level locking),也支持表级锁,但默认情况下是采用行级锁。
MySQL 这 3 种锁的特性可大致归纳如下。
l 表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发
度最低。
l 行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发
度也最高。
l 页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行
锁之间,并发度一般。
从上述特点可见,很难笼统地说哪种锁更好,只能就具体应用的特点来说哪种锁更合适!仅
从锁的角度 来说:表级锁更适合于以查询为主,只有少量按索引条件更新数据的应用,如
Web 应用;而行级锁则更适合于有大量按索引条件并发更新少量不同数据,同时又有 并发
查询的应用,如一些在线事务处理(OLTP)系统。这一点在本书的“开发篇”介绍表类型
的选择时,也曾提到过。下面几节我们重点介绍 MySQL 表锁和 InnoDB 行锁的问题,由于
BDB 已经被 InnoDB 取代,即将成为历史,在此就不做进一步的讨论了。
MyISAM 表锁
MyISAM 存储引擎只支持表锁,这也是 MySQL 开始几个版本中唯一支持的锁类型。随着应
用对事务完整性和 并发性要求的不断提高,MySQL 才开始开发基于事务的存储引擎,后来
慢慢出现了支持页锁的 BDB 存储引擎和支持行锁的 InnoDB 存储引擎(实际 InnoDB 是单
独的一个公司,现在已经被 Oracle 公司收购)。但是 MyISAM 的表锁依然是使用最为广泛
的锁类型。本节将详细介绍 MyISAM 表锁 的使用。
查询表级锁争用情况

资源由 www.eimhe.com 美河学习在线收集分享
可以通过检查table_locks_waited和 table_locks_immediate状态变量来分析系统上的表锁定争
夺:
mysql> show status like 'table%';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| Table_locks_immediate | 2979 |
| Table_locks_waited | 0 |
+-----------------------+-------+
2 rows in set (0.00 sec))
如果 Table_locks_waited 的值比较高,则说明存在着较严重的表级锁争用情况。
MySQL 表级锁的锁模式
MySQL 的表级锁有两种模式:表共享读锁(Table Read Lock)和表独占写锁(Table Write
Lock)。锁模式的兼容性如表 20-1 所示。
可见,对 MyISAM 表的读操作,不会阻塞其他用户对同一表的读请求,但会阻塞对同一表
的写请求;对 MyISAM 表的写操作,则会阻塞其他用户对同一表的读和写操作;MyISAM
表的读操作与写操作之间,以及写操作之间是串行的!根据如表 20-2 所示的 例子可以知道,
当一个线程获得对一个表的写锁后,只有持有锁的线程可以对表进行更新操作。其他线程的
读、写操作都会等待,直到锁被释放为止。
表 20-2 MyISAM 存储引擎的写阻塞读例子
session_1
session_2
获得表 film_text 的 WRITE 锁定
mysql> lock table film_text write;
Query OK, 0 rows affected (0.00 sec)
当前 session 对锁定表的查询、更新、插入操作都可以执行:
mysql> select film_id,title from film_text where film_id = 1001;
+---------+-------------+
| film_id | title |
+---------+-------------+
| 1001 | Update Test |
+---------+-------------+
1 row in set (0.00 sec)
mysql> insert into film_text (film_id,title) values(1003,'Test');
Query OK, 1 row affected (0.00 sec)
mysql> update film_text set title = 'Test' where film_id = 1001;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
其他 session 对锁定表的查询被阻塞,需要等待锁被释放:
mysql> select film_id,title from film_text where film_id = 1001;
等待
释放锁:

资源由 www.eimhe.com 美河学习在线收集分享
mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)
等待
Session2 获得锁,查询返回:
mysql> select film_id,title from film_text where film_id = 1001;
+---------+-------+
| film_id | title |
+---------+-------+
| 1001 | Test |
+---------+-------+
1 row in set (57.59 sec)
如何加表锁
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 sum(total) from orders;
Select sum(subtotal) from order_detail;
Unlock tables;
要特别说明以下两点内容。
¡ 上面的例子在 LOCK TABLES 时加了“local”选项,其作用就是在满足 MyISAM 表并发
插入条件的情况下,允许其他用户在表尾并发插入记录,有关 MyISAM 表的并发插入问题,
在后面的章节中还会进一步介绍。
¡ 在用 LOCK TABLES 给表显式加表锁时,必须同时取得所有涉及到表的锁,并且 MySQL
不支持锁升级。也就是说,在执行 LOCK TABLES 后,只能访问显式加锁的这些表,不能
访问未加锁的表;同时,如果加的是读锁,那么只能执行查询操作,而不能执行更新操作。
其实,在自动加锁的 情况下也基本如此,MyISAM 总是一次获得 SQL 语句所需要的全部锁。
这也正是 MyISAM 表不会出现死锁(Deadlock Free)的原因。
在如表 20-3 所示的例子中,一个 session 使用 LOCK TABLE 命令给表 film_text 加了读锁,
这个 session 可以查询锁定表中的记录,但更新或访问其他表都会提示错误;同时,另外一
个 session 可以查询表中的记录,但更新就会出现锁等待。
表 20-3 MyISAM 存储引擎的读阻塞写例子
session_1
session_2

资源由 www.eimhe.com 美河学习在线收集分享
获得表 film_text 的 READ 锁定
mysql> lock table film_text read;
Query OK, 0 rows affected (0.00 sec)
当前 session 可以查询该表记录
mysql> select film_id,title from film_text where film_id = 1001;
+---------+------------------+
| film_id | title |
+---------+------------------+
| 1001 | ACADEMY DINOSAUR |
+---------+------------------+
1 row in set (0.00 sec)
其他 session 也可以查询该表的记录
mysql> select film_id,title from film_text where film_id = 1001;
+---------+------------------+
| film_id | title |
+---------+------------------+
| 1001 | ACADEMY DINOSAUR |
+---------+------------------+
1 row in set (0.00 sec)
当前 session 不能查询没有锁定的表
mysql> select film_id,title from film where film_id = 1001;
ERROR 1100 (HY000): Table 'film' was not locked with LOCK TABLES
其他 session 可以查询或者更新未锁定的表
mysql> select film_id,title from film where film_id = 1001;
+---------+---------------+
| film_id | title |
+---------+---------------+
| 1001 | update record |
+---------+---------------+
1 row in set (0.00 sec)
mysql> update film set title = 'Test' where film_id = 1001;
Query OK, 1 row affected (0.04 sec)
Rows matched: 1 Changed: 1 Warnings: 0
当前 session 中插入或者更新锁定的表都会提示错误:
mysql> insert into film_text (film_id,title) values(1002,'Test');
ERROR 1099 (HY000): Table 'film_text' was locked with a READ lock and can't be updated
mysql> update film_text set title = 'Test' where film_id = 1001;
ERROR 1099 (HY000): Table 'film_text' was locked with a READ lock and can't be updated
其他 session 更新锁定表会等待获得锁:
mysql> update film_text set title = 'Test' where film_id = 1001;
等待
释放锁
mysql> unlock tables;
剩余36页未读,继续阅读














皓空揽月
- 粉丝: 218
- 资源: 1
上传资源 快速赚钱
我的内容管理 收起
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助

会员权益专享
最新资源
- Xilinx SRIO详解.pptx
- Informatica PowerCenter 10.2 for Centos7.6安装配置说明.pdf
- 现代无线系统射频电路实用设计卷II 英文版.pdf
- 电子产品可靠性设计 自己讲课用的PPT,包括设计方案的可靠性选择,元器件的选择与使用,降额设计,热设计,余度设计,参数优化设计 和 失效分析等
- MPC5744P-DEV-KIT-REVE-QSG.pdf
- 通信原理课程设计报告(ASK FSK PSK Matlab仿真--数字调制技术的仿真实现及性能研究)
- ORIGIN7.0使用说明
- 在VMware Player 3.1.3下安装Redhat Linux详尽步骤
- python学生信息管理系统实现代码
- 西门子MES手册 13 OpcenterEXCR_PortalStudio1_81RB1.pdf
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈



安全验证
文档复制为VIP权益,开通VIP直接复制

评论0