mysql存储引擎如何处理回滚_mysql操作机制说明

来源:这里教程网 时间:2026-02-28 20:52:12 作者:

回滚靠的是 InnoDB 的 Undo Log,不是“读旧数据”

MySQL 本身不存历史快照,

ROLLBACK
能撤销修改,全靠 InnoDB 在事务执行时同步写入的
Undo Log
。它不是备份,而是“反向操作指令”: -
INSERT
回滚 → 记录主键,回滚时执行
DELETE
-
UPDATE
回滚 → 保存旧值,回滚时用旧值覆盖当前行 -
DELETE
回滚 → 记录整行内容,回滚时重新
INSERT

这些日志按时间逆序执行,所以大事务回滚可能卡顿,且会持续占用

undo tablespace
。MyISAM 完全没这套机制——它压根不写
Undo Log
,所以
ROLLBACK
对它无效。

为什么 ROLLBACK 有时像没生效?三个检查点必须做

回滚失败,90% 是因为事务根本没真正“活”着。执行前务必确认: -

SELECT @@in_transaction;
返回
1
才表示当前有未提交事务 -
SELECT @@autocommit;
返回
0
(或已用
START TRANSACTION
显式开启) - 表引擎是
InnoDB
:运行
SHOW CREATE TABLE table_name;
ENGINE=InnoDB

常见假象: - 直接写

UPDATE
后跟
ROLLBACK
→ 失败,因为
autocommit=1
下每句都已提交 - 执行过
ALTER TABLE
CREATE INDEX
→ 隐式触发
COMMIT
,之后的
ROLLBACK
只能回滚它之后的操作 - 客户端异常断连 → 若
autocommit=1
,所有语句早已落盘,无法挽回

SAVEPOINT 不是“子事务”,只是回滚锚点

SAVEPOINT
解决不了嵌套逻辑,它只是在当前事务里打个标记,供
ROLLBACK TO SAVEPOINT
使用: -
SAVEPOINT before_update;
-
UPDATE ...;
-
ROLLBACK TO SAVEPOINT before_update;
→ 仅撤销
UPDATE
,保留之前所有操作

注意: -

SAVEPOINT
不隔离锁、不创建新事务上下文 - 同名
SAVEPOINT
会覆盖前一个,不存在“栈式管理” -
RELEASE SAVEPOINT sp_name;
只是释放标记,不影响数据

自动回滚只发生在底层错误,业务错要自己兜底

MySQL 不会因为你代码里写了

if (balance  就自动回滚。它只在极少数系统级异常时介入:  
- 死锁 → InnoDB 主动选一个事务 <code>ROLLBACK
- 锁等待超时(
innodb_lock_wait_timeout
)→ 默认只回滚最后一条语句;设
innodb_rollback_on_timeout=ON
才回滚整个事务(但慎开,可能破坏业务语义)

真要保业务一致性,得靠存储过程里的错误处理器:

DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
  ROLLBACK;
  RESIGNAL;
END;

否则,靠人眼判断再敲

ROLLBACK
,永远有窗口期。

回滚不是后悔药,它是依赖引擎、连接状态和操作顺序的精密协作。最常被忽略的,其实是

autocommit
@@in_transaction
这两个变量——它们不报错,但能让所有
ROLLBACK
归零。

相关推荐