mysql mvcc相关知识点

本文介绍如何使用 Redis 的 Set 数据结构实现高效的文章多标签查询功能。通过对比 SQL 查询语句,展示如何利用 Redis 的集合操作(如交集)来简化复杂的标签匹配过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

mysql undo.log / redo.log

在MySQL数据库中,事务的持久性和恢复能力依赖于两个关键的日志系统:undo log 和 redo log。这两个日志系统协同工作,确保了数据库在发生故障时的数据完整性和一致性。

1. Undo Log (操作前的记录)

Undo Log 主要用于支持事务的原子性和持久性。当一个事务对数据库中的数据进行修改(例如,插入、更新或删除)时,MySQL会将这些修改前的数据版本记录在undo log中。这样,当事务需要回滚时,可以通过undo log中的记录来撤销这些修改,恢复到事务开始之前的状态。

Undo Log 的作用:
  • 事务回滚:当事务执行失败或用户决定回滚时,可以使用undo log来撤销之前的操作。

  • 多版本并发控制(MVCC):在InnoDB存储引擎中,undo log是实现MVCC的关键部分。它允许读取操作不会阻塞写操作,反之亦然。

2. Redo Log(操作后的)

Redo Log 主要用于支持事务的持久性。当事务对数据库进行修改时,这些修改首先会被写入到redo log中。然后,这些修改才会被应用到数据库的数据页中。这样做的目的是确保即使在系统崩溃的情况下,也能通过redo log中的记录来恢复数据页的修改,保证数据的持久性。

Redo Log 的作用:
  • 数据恢复:在系统崩溃或宕机后,可以通过redo log中的记录来重做(redo)那些尚未应用到数据文件中的事务操作,从而恢复数据库的一致性状态。

  • 提高性能:通过减少对数据文件的直接写入操作(先写redo log),可以减少I/O操作的次数,提高数据库的写入性能。

两者之间的关系和重要性

  • 事务提交:一个事务在提交前,其所有的修改首先被写入redo log,然后才被写入数据库的数据页。这样即使系统崩溃,也可以通过redo log来恢复数据页的修改。

  • 事务回滚:如果事务需要回滚,则通过undo log来撤销之前对数据的修改。

数据记录的隐藏字段

        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 产生一个聚簇索引

聚簇索引和普通索引

聚簇索引整体是一个B+树,非叶子节点存放的是键值,叶子节点存放的是行数据,称之为数据页,这就决定了表中的数据也是聚簇索引中的一部分,数据页之间是通过一个双向链表来链接

普通索引:也叫二级索引,辅助索引, 除聚簇索引外的索引,即非聚簇索引。

所以普通索引查询记录的时候,如下

select id,name from user where age = 10;

1. 首先通过普通索引(age) 定位 age = 10 的ID

2. 然后通过聚集索引 查询select 字段返回结果集

即此过程 需要扫描两次索引B+树,它的性能较扫一遍索引树更低

数据版本链

两个事务的操作

事务1: 对student表中记录进行修改(update):将name(张三)改成name(李四)

事务2: 对student表中记录进行修改(update):将age(28)改成age(38)

隔离级别与ReadView

隔离级别可以复习: MySQL 四种隔离级别及测试_mysql隔离级别测试-优快云博客

ReadView仅仅适用于读已提交可重复读隔离级别, 对于这两种隔离级别, 都必须保证读到的是已经提交的事务修改过的记录. 假如另一个事务已经修改但是还没有提交, 是不能直接读取到的. 核心问题是判断版本链中哪些版本记录是当前事务可见的

如何解决,显然需要将事务进行分类,已完成的、进行中的要保存;且要保存一个一个视图

  • creator_trx_id: 创建这个ReadView的事务ID.
  • trx_ids: 在生成ReadView时, 当前系统中活跃的读写事务的ID列表.
  • up_limit_id: 活跃的事务中最小的事务ID.
  • low_limit_id: 表示在生成ReadView时系统应该分配给下一个事务的ID, 也就是系统中最大的事务ID值.

如下:事务2读取时,事务4已经提交了事务

//事务2的

Read View m_ids; // 1,3

up_limit_id; // 1

low_limit_id; // 4 + 1 = 5,ReadView生成时刻,系统尚未分配的下一个事务ID

creator_trx_id // 2

事务2能读到的最新数据记录是事务4所提交的版本,而事务4提交的版本也是全局角度上最新的版本

回到mvcc概念

MVCC也称: 多版本并发控制. 顾名思义, MVCC是通过数据行的多个版本管理来实现数据库的并发控制. MVCC使得在InnoDB的事务隔离级别下, 执行一致性读操作有了保证. 简单来说就是: 在需要读取一些正在被另一个事务更新的行数据时, 读取之前的历史版本数据(旧数据); 而不需要等待另一个事务释放锁.

‌MySQL的MVCC(多版本并发控制)机制主要解决了读写并发冲突问题,实现了读操作不阻塞写操作、写操作不阻塞读操作,从而提高了数据库的并发性能‌。

隔离级别mvcc的行为差异
读已提交(Read committed)每次读都生成ReadView,可以读取到其它事务已提交的修改
可重复读(Repeatable read(MySQL默认))事务首次生成ReadView,后续复用,保证读取的一致性

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值