MySQL MVCC机制

本文同时发表在https://github.com/zhangyachen/zhangyachen.github.io/issues/68

行结构

每一行额外包含三个隐藏字段:

  • DB_TRX_ID:事务ID。行的创建时间和删除时间记录的就是此值。
  • DB_ROLL_PTR:指向当前记录项的undo信息。
  • DB_ROW_ID::随着新行插入单调递增的一个字段。当由innodb自动产生聚集索引时,聚集索引包括这个DB_ROW_ID的值,不然的话聚集索引中不包括这个值。
  • 在insert操作时,创建时间 = DB_ROW_ID,这时,“删除时间 ”是未定义的。
  • 在update操作时,复制新增行的“创建时间”=DB_ROW_ID,删除时间未定义,旧数据行“创建时间”不变,删除时间=该事务的DB_ROW_ID。
  • 在delete操作时,相应数据行的“创建时间”不变,删除时间 = 该事务的DB_ROW_ID。
  • select操作对两者都不修改,只读相应的数据。

    Read View

    dulint    low_limit_id;    /* 事务号 >= low_limit_id的记录,对于当前Read View都是不可见的 */

    dulint    up_limit_id;    /* 事务号 < up_limit_id ,对于当前Read View都是可见的 */

    ulint    n_trx_ids;    /* Number of cells in the trx_ids array */

    dulint*    trx_ids;    /* Additional trx ids which the read should

                not see: typically, these are the active

                transactions at the time when the read is

                serialized, except the reading transaction

                itself; the trx ids in this array are in a

                descending order */

dulint    creator_trx_id;    /* trx id of creating transaction, or

                (0, 0) used in purge */

关于low_limit_id,up_limit_id的理解:

up_limit_id:当前已经提交的事务号 + 1,事务号 < up_limit_id ,对于当前Read View都是可见的。理解起来就是创建Read View视图的时候,之前已经提交的事务对于该事务肯定是可见的。

low_limit_id:当前最大的事务号 + 1,事务号 >= low_limit_id,对于当前Read View都是不可见的。理解起来就是在创建Read View视图之后创建的事务对于该事务肯定是不可见的。

另外,trx_ids为活跃事务id列表,即Read View初始化时当前未提交的事务列表。所以当进行RR读的时候,trx_ids中的事务对于本事务是不可见的(除了自身事务,自身事务对于表的修改对于自己当然是可见的)。理解起来就是创建RV时,将当前活跃事务ID记录下来,后续即使他们提交对于本事务也是不可见的。

example

步骤 1 2 3
begin
begin
insert into test(score) values(1607); 假设此时事务号21
insert into test(score) values(1607); 此时事务号22
此时创建读视图,up_limit_id = 21, low_limit_id = 23 活跃事务列表为(21,22)
insert into test(score) values(1620); 事务号为23
insert into test(score) values(1621); 事务号为24
insert into test(score) values(1622); 事务号为25
select * from test; 此时的up_limit_id 为21,low_limit_id 为26,活跃事务列表为(21,22),故21,22在活跃事务列表不可见
select * from test; 此时low_limit_id为26,up_limit_id 为21,活跃事务列表是(21,22) 22本事务自身可见。21的在活跃事务列表不可见。23,24不在活跃事务列表,可见
十一 select * from test; 事务内readview不变,low_limit_id = 23,up_limit_id = 21,活跃事务列表 (21,22)。故21自身可见,22在活跃事务列表不可见。>=23的都不可见

注意的几点:

  • Read View视图是在进行RR读之前创建的,而不是在事务刚begin时创建的。如果Read View视图是在事务刚begin时创建的,那么在步骤四中事务22的Read View就定下来了(up_limit_id = 21,low_limit_id = 23),那么在步骤十中就看不到3中提交的数据了,因为事务号23,24,25大于等于事务22.low_limit_id
  • 事务内Read View一旦创建就不变化了。
  • 在第十步中按我之前的理解,3中insert的数据是在2中begin之后插入的,按理说2是看不到3中insert插入的数据的。但是事务保证的是两次select的数据是一致的,所以Read View是在第一次select时创建的,所以3中insert的数据是在2中可以看到。

参考资料:http://hedengcheng.com/?p=148

时间: 2024-10-18 23:10:30

MySQL MVCC机制的相关文章

MySQL缓存机制

目录 1. MySQL缓存简介 1. MySQL缓存机制说明 2. MySQL缓存失效 3. 使用场景 2. 命中条件 3. 工作流程 4. 缓存失败 5. 缓存的内存管理 6. 缓存的使用时机 1. 通过缓存命中率判断 2. 通过缓存写入率判断 3. 通过命中-写入率判断 7. 缓存参数配置 1. 查看缓存相关配置 2. query_cache_type 3. query_cache_size 4. query_cache_min_res_unit 5. query_cache_limit 6

mysql 缓存机制

目录 1. MySQL缓存简介 1. MySQL缓存机制说明 2. MySQL缓存失效 3. 使用场景 2. 命中条件 3. 工作流程 4. 缓存失败 5. 缓存的内存管理 6. 缓存的使用时机 1. 通过缓存命中率判断 2. 通过缓存写入率判断 3. 通过命中-写入率判断 7. 缓存参数配置 1. 查看缓存相关配置 2. query_cache_type 3. query_cache_size 4. query_cache_min_res_unit 5. query_cache_limit 6

mysql锁机制(转载)

锁是计算机协调多个进程或线程并发访问某一资源的机制 .在数据库中,除传统的 计算资源(如CPU.RAM.I/O等)的争用以外,数据也是一种供许多用户共享的资源.如何保证数据并发访问的一致性.有效性是所有数据库必须解决的一 个问题,锁冲突也是影响数据库并发访问性能的一个重要因素. 从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂.本章我们着重讨论MySQL锁机制 的特点,常见的锁问题,以及解决MySQL锁问题的一些方法或建议. MySQL锁概述相对其他数据库而言,MySQL的锁机制比较简单,

对mysql锁机制的学习

1.对于mysql学习,经常翻看一些博客,论坛,好像或多或少有mysq锁机制的学习与总结,所以今天有必要 对mysql锁机制的一些个人的总结,以便以后深入的学习. 2.学习这件事,从来都是“深入浅出”的,今天留个痕迹,说不定以后“受益匪浅”. a.数据库锁是什么 数据库锁就是为了保证数据库数据的一致性在一个共享资源被并发访问时使得数据访问顺序化的机制. MySQL数据库的锁机制比较独特,支持不同的存储引擎使用不同的锁机制. b.mysql锁机制的3中类型 表级锁,行级锁,页级锁 c.各级锁的特点

Mysql锁机制和事务控制

如何加锁 锁定表的语法:    LOCK TABLES    tbl_name [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE}    [, tbl_name [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE}] ...解锁语法:    UNLOCK TABLES innodb的存储引擎提供行级锁,支持共享锁和排他锁两种锁定模式,以及四种不同的隔离级别. 死锁 InnoDB自动检测事务的死锁,并回滚一个

MySQL锁定机制简介

MySQL锁定机制简介 数据库锁定机制简单来说就是数据库为了保证数据的一致性而使各种共享资源在被并发访问访问变得有序所设计的一种规则.对于任何一种数据库来说都需要有相应的锁定机制,所以MySQL自然也不能例外.MySQL数据库由于其自身架构的特点,存在多种数据存储引擎,每种存储引擎所针对的应用场景特点都不太一样,为了满足各自特定应用场景的需求,每种存储引擎的锁定机制都是为各自所面对的特定场景而优化设计,所以各存储引擎的锁定机制也有较大区别. 总的来说,MySQL各存储引擎使用了三种类型(级别)的

mysql锁机制整理

Auth: jinDate: 20140506 主要参考整理资料MYSQL性能调优与架构设计-第七章 MYSQL锁定机制http://www.cnblogs.com/ggjucheng/archive/2012/11/14/2770445.html理解MySQL--架构与概念http://www.cnblogs.com/yequan/archive/2009/12/24/1631703.html 一.mysql锁类型及应用介绍1.锁类型和应用类型相對其他數據庫而言,MySQL的鎖機制比較簡單,其

详解mysql复制机制--异步复制,半同步复制和并行复制

详解MySQL复制机制--异步复制,半同步复制和并行复制 **# 异步复制 异步复制是MySQL自带的最原始的复制方式,主库和备库成功建立复制关系后,在备库上会有一个IO线程去主库拉取binlog,并将binlogx到本地,就是下图中Relaylog,然后备库会开启另外一个SQL线程取回放Relay log,通过这种方式达到Master-Slave数据同步的目的. 通常情况下,slave是只读的,可以承担一部分读流量,而且可以根据实际需要,添加一个或者多个slave,这样在一定程度上可以缓解主库

mysql锁机制详解

前言 大概几个月之前项目中用到事务,需要保证数据的强一致性,期间也用到了mysql的锁,但当时对mysql的锁机制只是管中窥豹,所以本文打算总结一下mysql的锁机制. 本文主要论述关于mysql锁机制,mysql版本为5.7,引擎为innodb,由于实际中关于innodb锁相关的知识及加锁方式很多,所以没有那么多精力罗列所有场景下的加锁过程并加以分析,仅根据现在了解的知识,结合官方文档,说说自己的理解,如果发现有不对的地方,欢迎指正. 概述 总的来说,InnoDB共有七种类型的锁: 共享/排它