图文带你彻底弄懂MySQL事务原子性之UndoLog

Undo Log

事务的第一个特性就是原子性,原子性就是要保证一个事务中的增删改操作要么都成功,要么都不做。这时就需要 undo log,在对数据库进行修改前,会先记录对应的 undo log,然后在事务失败或回滚的时候,就可以用这些 undo log 来将数据回滚到修改之前的样子。

下面先简单介绍下事务ID和行记录中的隐藏列,因为后面的内容都与这两个东西有关系。

事务ID

事务执行过程中在对某个表执行增、删、改操作时,InnoDB就会给这个事务分配一个唯一的事务ID。如果一个事务中没有执行增删改操作,就不会分配事务ID。

InnoDB 在内存维护了一个全局变量来表示事务ID,每当要分配一个事务ID时,就获取这个变量值,然后把这个变量自增1。每当这个变量的值为256的倍数时,就会将该变量的值刷新到系统表空间的页号为5的页面中一个称之为Max Trx ID的属性处。当系统下一次重新启动时,会将Max Trx ID属性加载到内存中,并将该值加上256之后赋值给这个全局变量(这个过程跟主键row_id的分配是类似的)。

我们可以通过
information_schema.INNODB_TRX 来查询当前系统中运行的事务信息,这张表的第一个字段trx_id就是事务ID。

mysql> SELECT trx_id,trx_state,trx_started,trx_rows_locked,trx_isolation_level,trx_is_read_only FROM information_schema.INNODB_TRX;
+-----------+-----------+---------------------+-----------------+---------------------+------------------+
| trx_id    | trx_state | trx_started         | trx_rows_locked | trx_isolation_level | trx_is_read_only |
+-----------+-----------+---------------------+-----------------+---------------------+------------------+
| 164531720 | RUNNING   | 2021-05-14 16:38:59 |               1 | REPEATABLE READ     |                0 |
+-----------+-----------+---------------------+-----------------+---------------------+------------------+

行记录隐藏列

在介绍InnoDB行记录格式这篇文章中,我们了解到行记录中会有三个隐藏列:

  • DB_ROW_ID:如果没有为表显式的定义主键,并且表中也没有定义唯一索引,那么InnoDB会自动为表添加一个row_id的隐藏列作为主键。
  • DB_TRX_ID:事务中对某条记录做增删改时,就会将这个事务的事务ID写入trx_id中。
  • DB_ROLL_PTR:回滚指针,本质上就是指向 undo log 的指针。

Undo Log 类型

每对一条记录做一次改动,就会产生1条或者2条 undo log。一个事务中可能会有多个增删改SQL语句,一个SQL语句可能会产生多条 undo log,一个事务中的这些 undo log 会被从 0 开始递增编号,这个编号称为 undo no。

undo log 主要是记录对数据库增删改的撤销日志,下面就分别来看下增删改操作的 undo log 格式是怎样的。

还是以之前的 account 表为例来做一些演示。

CREATE TABLE `account` (
  `id` bigint(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `card` varchar(60) NOT NULL COMMENT '卡号',
  `balance` int(11) NOT NULL DEFAULT '0' COMMENT '余额',
  PRIMARY KEY (`id`),
  UNIQUE KEY `account_u1` (`card`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='账户表';

我们可以通过
information_schema.INNODB_SYS_TABLES 查询得到这张表的表空间ID为 13881。

mysql> SELECT * FROM information_schema.
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值