花都高端网站建设,怀柔网站建设推广,上海推广服务,西部数码网站管理助手serv-u默认密码目录 一、3个记录隐藏字段
二、undo 日志
三、read view 一、3个记录隐藏字段 本片文章是帮助理解上篇文章Mysql隔离性的辅助知识。 mysql在建表时#xff0c;不仅仅创建了表的结构#xff0c;还创建了3个隐藏字段。 DB_TRX_ID #xff1a;6 byte#xff0c;最近修改( 修…目录 一、3个记录隐藏字段
二、undo 日志
三、read view 一、3个记录隐藏字段 本片文章是帮助理解上篇文章Mysql隔离性的辅助知识。 mysql在建表时不仅仅创建了表的结构还创建了3个隐藏字段。 DB_TRX_ID 6 byte最近修改( 修改/插入 )事务ID记录创建这条记录/最后一次修改该记录的事务ID DB_ROLL_PTR : 7 byte回滚指针指向这条记录的上一个版本简单理解成指向历史版本就 行这些数据一般在 undo log 中 DB_ROW_ID : 6 byte隐含的自增ID隐藏主键如果数据表没有主键 InnoDB 会自动以 DB_ROW_ID 产生一个聚簇索引 DB_TRX_ID该字段占6个字节其中存储最近修改或插入的事务ID也就是你当前对表进行插入或者修改此时的事务ID就会被存储到该字段中。 DB_ROLL_PTR占7个字节为指针指向该记录的上一个版本。 DB_ROW_ID占6字节如果我们建表时没有主键InnoDB会生成一个隐藏的主键根据该主键来建立聚簇索引。 假设当前的建立表为 实际的三个隐藏字段会这样存储 我们目前并不知道创建该记录的事务ID隐式主键我们就默认设置成null1。第一条记录也没有其他版本我们设置回滚指针为null。 二、undo 日志 MySQL的日志是具有功能性和保存数据的功能的。这里的数据包括sql语句。 我们这里理解undo log简单理解成就是 MySQL 中的一段内存缓冲区用来保存日志数据的就行。 undo log主要解决两个问题 1.回滚 2.MVCC ---》多版本控制 ---》来解决隔离性和 隔离级别 我们上文表格中的数据为 1 a。 此时来了一个事务10准备修改 a 为 abc。undo log就要发挥作用。 事务10,因为要修改所以要先给该记录加行锁。 修改前现将改行记录拷贝到undo log中所以undo log中就有了一行副本数据。 事务10提交释放锁。 现在又有一个事务11准备修改 abc为dcb。 事务11,因为也要修改所以要先给该记录加行锁。 修改前现将改行记录拷贝到undo log中所以undo log中就又有了一行副本数据。此时新的 副本我们采用头插方式插入undo log。 事务11提交释放锁。 这样我们就有了一个基于链表记录的历史版本链。所谓的回滚无非就是用历史数据覆盖当前数 据。 上面的一个一个版本我们可以称之为一个一个的快照。 有了这个版本链那回滚就可以依靠它来执行想要回滚时直接将先前的数据覆盖现在的数据即可。 那我在insert等其他修改时其他事务要select此时select读取是读取最新的版本呢还是读取历史版本 当前读读取最新的记录就是当前读。增删改都叫做当前读select也有可能当前读. 快照读读取历史版本(一般而言)就叫做快照读。 我们可以看到在多个事务同时删改查的时候都是当前读是要加锁的。那同时有select过来如果也要读取最新版(当前读)那么也就需要加锁这就是串行化。 但如果是快照读读取历史版本的话是不受加锁限制的。 那么是什么决定了select是当前读还是快照读呢隔离级别. 那么如何保证不同的事务看到不同的内容呢也就是如何如何实现隔离级别
三、read view Read View就是事务进行 快照读 操作的时候生产的 读视图 (Read View)在该事务执行的快照读的那一 刻会生成数据库系统当前的一个快照记录并维护系统当前活跃事务的ID(当每个事务开启时都会被分配一个ID, 这个ID是递增的所以最新的事务ID值越大) Read View 在 MySQL 源码中,就是一个类本质是用来进行可见性判断的。 即当我们某个事务执行快照 读的时候对该记录创建一个 Read View 读视图把它比作条件,用来判断当前事务能够看到哪个版本的 数据既可能是当前最新的数据也有可能是该行记录的 undo log 里面的某个版本的数据。 简化后的结构体如图所示 该事务执行的快照读的那一 刻会生成数据库系统当前的一个快照记录并维护系统当前活跃事务的ID其中最小的id放在up_limit_id中最大的id放在low_limit_id中。 我们现在拥有的数据版本链undo log中的链式结构以及当前快照读的 ReadView。 我们将read view中的事务id与数据版本链中id做对比就能知道当前快照读所能读到的内容。 在画图之前要记住 /** 高水位大于等于这个ID的事务均不可见*/ trx_id_t m_low_limit_id /** 低水位小于这个ID的事务均可见 */ trx_id_t m_up_limit_id; 我们举个例子。 事务4修改name(张三) 变成name(李四) 当 事务2 对某行数据执行了 快照读 数据库为该行数据生成一个 Read View 读视图 //事务2的 Read View m_ids; // 1,3 up_limit_id; // 1 low_limit_id; // 4 1 5原因ReadView生成时刻系统尚未分配的下一个事务ID creator_trx_id // 2 此时版本链是 现在要是对比看事务二是否能读到版本链中的哪一个。 //事务2的 Read View m_ids; // 1,3 up_limit_id; // 1 low_limit_id; // 4 1 5原因ReadView生成时刻系统尚未分配的下一个事务ID creator_trx_id // 2 对比 up_limit_idDB_TRX_IDlow_limit_id; 并且DB_TRX_ID不在m_Ids中。 证明事务2可以读取事务4修改之后的版本。 整篇文章的流程为 我们知道了建表时会创建三个隐藏的记录字段用来记录事务的ID、地址与隐藏的主键。这三个会帮助实现回滚回滚需要用到undo logundo log中存放的一个个副本数据成链状表示。在不同的隔离级别下不同事务读到的数据不一样需要read view来协助在read view中的low_limit_idup_limit_id与undo log中的DB_TRX_ID做对比来判断能读到什么版本。