[MySQL] 一致性读分析
MySQL MVCC
MySQL InnoDB存储引起实现的是基于多版本的并发控制协议---MVCC(Multi-Version Concurrency Control),基于锁的并发控制,Lock-Based Concurrency Control。
一致性读,又称快照读,读取的是undo中已提交的数据,可能是数据的历史版本,no-locking,所以是非阻塞的读取操作。
A consistent read means that InnoDB uses multi-versioning to present to a query a snapshot of the database at a point in time. The query sees the changes made by transactions that committed before that point of time, and no changes made by later or uncommitted transactions. The exception to this rule is that the query sees the changes made by earlier statements within the same transaction.
那么一致性读(快照读)和当前读有什么区别呢?
snapshot read:
读取记录的可见版本(有可能是历史版本), no-locking
no-locking reads: 简单的select语句
- select..
current read:
读取的是记录的最新版本, 加锁保证事务隔离性
locking-reads: 特殊操作, 插入/更新/删除操作
- select .. for update
- select ... in share mode
- insert
- update
- delete
RC隔离和RR隔离的中的一致性读
Case1:RR隔离
对于RR的事务隔离级别,同一个事务所有的一致性读建立在第一次read操作开始时。
If the transaction isolation level is REPEATABLE READ (the default level), all consistent reads within the same transaction read the snapshot established by the first such read in that transaction.
深入理解下"the first such read in that transaction"这句话,事务开始后,对表的第一次select语句建立了该事务中一致性读的snapshot,而并非指事务的begin或者start transaction。
上面的实验说明:RR隔离级别下的一致性读,不是以begin为开始建立的snapshot,而是第一条select语句为timepoint建立的snapshot。
上面的实验说明:RR隔离级别下的一致性读,是以第一条select语句为timepoint建立的snapshot,即使是针对不同的表做检查。
上面的实验说明:RR隔离级别下,其他事务插入的数据,即使没有提交,在本事务中也可以update成功,因为update语句执行的是“当前读”,并且修改后的数据在本事务中可见。
最后,在RR隔离级别下,locking reads的加锁信息依赖于具体的SQL条件,如果基于UK的唯一搜索条件,那么会锁定二级uk index记录以及聚簇索引表的记录(no-gap锁);如果基于范围区域的扫描条件,那么会锁定记录本身外,还会使用gap locks/next-key lock来避免幻读。具体可参考"MySQL 加锁处理分析"
Case2:RC隔离
对于RC事务隔离级别,每一个一致性读都是最新的快照数据。
With READ COMMITTED isolation level, each consistent read within a transaction sets and reads its own fresh snapshot.
MySQL中事务开始时间
一般的begin/start transaction是事务开始的时间点,这里有误区,正如上面的实验看到的。事务开始的真正时间点(LSN)是start transaction之后执行的第一条语句。
START TRANSACTION WITH consistent snapshot指执行start transaction同事建立事务的一致性读snapshot。
The WITH CONSISTENT SNAPSHOT modifier starts a consistent read for storage engines that are capable of it. This applies only to InnoDB. The effect is the same as issuing a START TRANSACTION followed by a SELECT from any InnoDB table. See Section 14.2.2.2, “Consistent Nonlocking Reads”. The WITH CONSISTENT SNAPSHOT modifier does not change the current transaction isolation level, so it provides a consistent snapshot only if the current isolation level is one that permits a consistent read. The only isolation level that permits a consistent read is REPEATABLE READ. For all other isolation levels, the WITH CONSISTENT SNAPSHOT clause is ignored. As of MySQL 5.7.2, a warning is generated when the WITH CONSISTENT SNAPSHOT clause is ignored.
一致性读问题
一致性读在遇到特定的DDL语句的问题
Consistent read does not work over certain DDL statements
- drop table语句,因为MySQL是无法使用一个已经被drop的表。
- alter table语句,因为alter table会通过表copy的方式实现,在一致性读开始后,alter table过程中的临时表数据是无法看到的,这种情况下,事务会返回:ER_TABLE_DEF_CHANGED(Table definition has changed, please retry transaction)。
这个问题经常发生在mysqldump一致性备份期间。
一致性mysqldump问题
mysqldump是MySQL逻辑数据导出的有力工具,其中参数:--single-transaction参数支持数据的一致性导出。原理是:设置事务为RR模式,然后获取LSN快照,来获得一致性的数据。
--single-transaction
Creates a consistent snapshot by dumping all tables in a
single transaction. Works ONLY for tables stored in
storage engines which support multiversioning (currently
only InnoDB does); the dump is NOT guaranteed to be
consistent for other storage engines. While a
--single-transaction dump is in process, to ensure a
valid dump file (correct table contents and binary log
position), no other connection should use the following
statements: ALTER TABLE, DROP TABLE, RENAME TABLE,
TRUNCATE TABLE, as consistent snapshot is not isolated
from them. Option automatically turns off --lock-tables.
ALTER TABLE, DROP TABLE, RENAME TABLE, TRUNCATE TABLE 这些DDL语句的执行,会导致无法使用undo构造出正确的一致性读,一致性读和它们是无法隔离的。
另外在mysqldump中还可能遇到大查询带来的"waiting for table flush"问题, 假设有3个会话,会话A执行大查询,访问t表;然后一个备份会话B正处于关闭表阶段,需要关闭表t;随后会话C也请求访问t表。三个会话按照这个顺序执行,我们会发现备份会话B和会话C访问t表的线程都处于“waiting for table flush”状态。这就是关闭表引起的,这个问题很严重,因为此时普通的select查询也被堵住了。下面简单解释下原因:
- 会话A打开表t,执行中……
- 备份会话B需要清理表t的cache,更新版本号(refresh_version++)
- 会话B发现表t存在旧版本(version != refresh_version),表示还有会话正在访问表t,
等待,加入share对象的等待队列 后续会话C同样发现存在旧版本(version != refresh_version),
等待,加入share对象的等待队列
......大查询执行完毕,调用free_table_share,唤醒所有等待线程。
free_table_share //逐一唤醒所有等待的线程。
{
while ((ticket= it++))
ticket->get_ctx()->m_wait.set_status(MDL_wait::GRANTED);
}
第4步与第5步之间,所有的访问该表的会话都处于“waiting for table flush”状态,唯有大查询结束后,等待状态才能解除。
参考:
MySQL 5.7官方文档:http://dev.mysql.com/doc/refman/5.7/en/innodb-consistent-read.html
MySQL 加锁处理分析:http://hedengcheng.com/?p=771
FTWRL详解:http://www.cnblogs.com/cchust/p/4603599.html
[MySQL] 一致性读分析的更多相关文章
- MySQL 一致性读 深入研究
一致性读,又称为快照读.使用的是MVCC机制读取undo中的已经提交的数据.所以它的读取是非阻塞的. 相关文档:http://dev.mysql.com/doc/refman/5.6/en/innod ...
- MySQL 一致性读 深入研究 digdeep博客学习
http://www.cnblogs.com/digdeep/p/4947694.html 一致性读,又称为快照读.使用的是MVCC机制读取undo中的已经提交的数据.所以它的读取是非阻塞的. 相关文 ...
- 差点掉坑,MySQL一致性读原来是有条件的
众所周知,在设定了隔离等级为Repeatable Read及以上时,InnoDB 可以实现数据的一致性读.换句话来说,就是事务执行的任意时刻,读取到的数据是同一个快照,不会受到其他事务的更新影响. 以 ...
- MySQL一致性读原来是有条件的
众所周知,在设定了隔离等级为Repeatable Read及以上时,InnoDB 可以实现数据的一致性读.换句话来说,就是事务执行的任意时刻,读取到的数据是同一个快照,不会受到其他事务的更新影响. 以 ...
- mysql一致性读
Consistent Nonlocking Reads 一致读意味着InnoDB用多版本来提供一个查询数据库某个时间点的快照.这种查询可以看到在当前世界点之前事务提交的改变,看不到此后提交的改变,更看 ...
- MySQL一致性非锁定读
一致性非锁定读(consistent nonlocking read)是指InnoDB存储引擎通过多版本控制(multi versionning)的方式来读取当前执行时间数据库中行的数据,如果读取的行 ...
- 6. SOFAJRaft源码分析— 透过RheaKV看线性一致性读
开篇 其实这篇文章我本来想在讲完选举的时候就开始讲线性一致性读的,但是感觉直接讲没头没尾的看起来比比较困难,所以就有了RheaKV的系列,这是RheaKV,终于可以讲一下SOFAJRaft的线性一致性 ...
- MySQL的默认隔离级别的实现依赖于MVCC和锁,准确点说就是一致性读和锁。
MySQL的默认隔离级别的实现依赖于MVCC和锁,准确点说就是一致性读和锁.
- MySQL——一致性非锁定读(快照读)&MVCC
MySQL--一致性非锁定读(快照读) MySQL数据库中读分为一致性非锁定读.一致性锁定读 一致性非锁定读(快照读),普通的SELECT,通过多版本并发控制(MVCC)实现. 一致性锁定读(当前读) ...
随机推荐
- 转 Using $.ajaxPrefilter() To Configure AJAX Requests In jQuery 1.5
Using $.ajaxPrefilter() To Configure AJAX Requests In jQuery 1.5 Posted February 18, 2011 at 6:29 PM ...
- 通过NTP(Network Time Protocal)协议进行时间同步
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAwUAAAKOCAYAAAD3ZbXWAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjw
- qemu的drive参数解释
drive参数很简单,可以理解成是定义了一个实际的硬盘(或者是cd)与drive对应的是device-drive option[,option[,option[,...]]] Define a new ...
- Struts1之logic标签
logic是Struts1中的逻辑标签 <%@ taglib prefix="logic" uri="http://struts.apache.org/tags-l ...
- P2066 机器分配
题目背景 无 题目描述 总公司拥有高效设备M台,准备分给下属的N个分公司.各分公司若获得这些设备,可以为国家提供一定的盈利.问:如何分配这M台设备才能使国家得到的盈利最大?求出最大盈利值.其中M≤15 ...
- LeetCode -- Best Time to Buy and Sell Stock系列
Question: Best Time to Buy and Sell Stock Say you have an array for which the ith element is the pri ...
- [UVA1625]Color Length
题面在这里 description 输入两个长度分别为\(n\)和\(m\)的颜色序列,要求按顺序合并成同一个序列,即每次可以把一个序列开头的颜色放到新序列的尾部. 对于每个颜色\(c\)来说,其跨度 ...
- ZOJ 3229 Shoot the Bullet | 有源汇可行流
题目: 射命丸文要给幻想乡的居民照相,共照n天m个人,每天射命丸文照相数不多于d个,且一个人n天一共被拍的照片不能少于g个,且每天可照的人有限制,且这些人今天照的相片必须在[l,r]以内,求是否有可行 ...
- The 13th Zhejiang Provincial Collegiate Programming Contest - I
People Counting Time Limit: 2 Seconds Memory Limit: 65536 KB In a BG (dinner gathering) for ZJU ...
- Educational Codeforces Round 55:A. Vasya and Book
A. Vasya and Book 题目链接:https://codeforc.es/contest/1082/problem/A 题意: 给出n,x,y,d,x是起点,y是终点,d是可以跳的格数,注 ...