UNDO 行为

-- 回滚表空间各区使用状况

select status, sum (blocks) as blocks, sum (bytes/ 1024 ) as Size_Kb
 
from dba_undo_extents
 
where tablespace_name = 'UNDOTBS01'
 
group by status

 

 

每个undo extent 可以有三种状态:

active: 有活动事务在此extent

expired: 已结束的事务,undo 信息超过undo_retention 时间限制

unexpired: 已经结束的事务,undo 信息未达到undo_retention 时间限制

当一个事务开始它将会去寻找可用的undo block 来存放undo 信息,它将按照以下顺序请求undo space.

1. 先去搜索拥有非active extentundo segment ,如果没有发现,那么会去创建新的undo segment, 如果空间不够不能创建,将返回错误

2. 如果有一个undo segment 被选中,但是其中freeundo block 并不足以存储该事务的undo 信息,那么它将尝试创建extent ,如果没有空间,那么将会进入下一步。

3. 如果创建新extent 失败,它将会搜索其他undo segmentexpired extent 并重用。

4. 如果其他undo segment 中没有expired extent 可使用,那么它会继续搜索其他undo segmentunexpired extent 并重用。

5. 如果经过以上尝试还没有可用空间,将会返回错误。

V$undostat

EXPSTEALCNT: 尝试请求 expired extent 的次数
EXPBLKREUCNT:
实际使用 expired block
UNXPSTEALCNT:
尝试请求 unexpired extent 的次数
UNXPBLKREUCNT:
实际使用 unexpired block

 

 

V$ROLLSTAT 中的常用列
?        USN
:回滚段标识
?        RSSIZE
:回滚段默认大小
?        XACTS
:活动事务数

在一段时间内增量用到的列
?        WRITES
:回滚段写入数 ( 单位 :bytes)
?        SHRINKS
:回滚段收缩次数
?        EXTENDS
:回滚段扩展次数
?        WRAPS
:回滚段翻转 (wrap) 次数
?        GETS
:获取回滚段头次数
?        WAITS
:回滚段头等待次数

 

09-02
在 MySQL 的 InnoDB 存储引擎中,**Undo Log(撤销日志)** 是一种非常重要的日志机制,主要用于支持事务的 **回滚(rollback)** 和 **多版本并发控制(MVCC)**。 --- ## 一、Undo Log 的作用 ### ✅ 1. 支持事务回滚 当事务执行过程中发生错误或主动调用 `ROLLBACK` 时,InnoDB 会使用 Undo Log 撤销已执行的修改,将数据恢复到事务开始前的状态。 ### ✅ 2. 支持 MVCC(多版本并发控制) Undo Log 保存了数据的旧版本,使得多个事务可以同时读取不同版本的数据,从而实现 **非锁定读(如 SELECT)**,提高并发性能。 例如: ```sql START TRANSACTION; UPDATE users SET name = 'Tom' WHERE id = 1; -- 此时其他事务仍能看到旧的 name 值 ``` ### ✅ 3. 崩溃恢复 在崩溃恢复时,Undo Log 可帮助清理未提交的事务对数据库的影响。 --- ## 二、Undo Log 的存储结构 - **InnoDB 的 Undo Log 并不是单独的文件**,而是存储在 **Undo Tablespace** 或 **System Tablespace** 中。 - 默认情况下,MySQL 8.0 引入了 **独立的 Undo 表空间**(`innodb_undo_tablespaces`),可以提升性能和可维护性。 - 每个事务在执行写操作时,都会生成自己的 Undo Log 条目。 --- ## 三、Undo Log 与 Redo Log 的区别 | 特性 | Redo Log | Undo Log | |------|----------|----------| | 所属组件 | InnoDB | InnoDB | | 日志类型 | 物理日志(记录页的物理修改) | 逻辑日志(记录事务前的数据状态) | | 作用 | 崩溃恢复、事务持久性 | 事务回滚、MVCC | | 写入时机 | 事务提交前写入 | 修改数据前写入 | | 是否循环使用 | 是(固定大小) | 否(可被 purge 线程清理) | --- ## 四、Undo Log 的生命周期 1. 事务开始前,InnoDB 会记录数据的旧值到 Undo Log。 2. 如果事务提交,这些 Undo Log 条目不会立即删除(因为可能被其他事务用于 MVCC)。 3. 当所有依赖这些 Undo Log 的事务都完成后,**Purge 线程**会异步清理这些旧版本数据。 --- ## 五、查看 Undo Log 相关信息(通过系统表) 你可以通过 InnoDB 的系统表来查看 Undo Log 的相关信息: ```sql SELECT * FROM information_schema.INNODB_SYS_TABLES WHERE NAME LIKE '%SYS%UNDO%'; SELECT * FROM information_schema.INNODB_SYS_COLUMNS WHERE TABLE_ID = <table_id>; ``` --- ## 六、配置参数(MySQL 配置文件 my.cnf / my.ini) ```ini [mysqld] innodb_undo_tablespaces = 2 # 创建 2 个独立的 Undo 表空间 innodb_undo_logs = 128 # 设置回滚段数量(旧版本为 innodb_rollback_segments) innodb_max_undo_log_size = 1G # 单个 Undo 表空间最大大小 innodb_purge_rseg_update_interval = 10 innodb_purge_batch_size = 300 # 控制 Purge 操作的批量大小 ``` --- ## 七、Python 示例:模拟 Undo Log 的作用(伪代码) 虽然 Undo Log 是 InnoDB 内部机制,不能直接访问,但可以通过事务模拟其行为: ```python import pymysql conn = pymysql.connect(host='127.0.0.1', user='root', password='your_password', db='test') cursor = conn.cursor() try: cursor.execute("START TRANSACTION") cursor.execute("UPDATE users SET name = 'OldName' WHERE id = 1") # 原本是 'NewName' print("Update executed, but not committed yet.") # 模拟崩溃或回滚 conn.rollback() print("Transaction rolled back, Undo Log applied.") cursor.execute("SELECT name FROM users WHERE id = 1") print("Current name:", cursor.fetchone()[0]) except Exception as e: print("Error:", e) conn.rollback() finally: cursor.close() conn.close() ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值