【什么是undo日志】
事务是需要保证原子性的,也就是说,事务中的操作要么全部完成,要么什么也不做。但有如下情况,会造成事务执行不完:
- 情况一:事务执行过程中可能遇到各种错误,比如:代码bug出现异常。
- 情况二:程序员在事务执行过程中手动输入rollback语句结束当前事务的执行。
遇到上面的情况,为了保证事务的原子性,我们需要把数据还原回原来的样子,这个过程就叫做回滚(rollback)。有时候仅需要对部分语句进行回滚,有时间需要对整个事务进行回滚。
数据库为了回滚而记录的日志,我们就称之为撤销日志(undo log)
- 注意一点,由于SELECT操作并不会修改任何记录,所以并不需要记录相应的的undo日志。
【怎么是事务id】
- 何时分配事务id?
- 如果是只读事务:只有在它第一次对某个用户创建的临时表执行增删改操作时,才会为这个事务分配一个事务id,否则是不分配的。
- 如果是读写事务:只有在它第一次对某个表(包括用户创建的临时表)执行增删改操作时,才会为这个事务分配一个事务id,否则是不分配的。
综上所述,只有在事务对表中的记录进行改动时才会为这个事务分配一个唯一的事务id,否则事务id值默认为0。
- 如何开启只读事务?
通过START TRANSACTION READ ONLY语句开启一个只读事务。
在只读事务中,不可以对普通表进行增删改操作;但可以对临时表进行增删改操作。
- 如何开启读写事务?
通过START TRANSACTION READ WRITE语句开启一个读写事务。
使用BEGIN、START TRANSACTION语句开启的事务默认也算是读写事务。
在读写事务中可以对表执行增删改查操作。
【事务id是怎么生成的】
事务id本质上就是一个数字,事务id生成策略如下:
- 内存中维护一个全局变量,每当需要为某个事务分配事务id时,就会把该变量值当作事务id分配给该事务,并且自增1。
- 每当这个变量的值为256的倍数时,就会将值刷新到系统表空间中页号为5的页面中一个名为Max Trx ID的属性中(占用8个字节)。
- 当系统下一次启动时,会将Max Trx ID的值加载到到内存中,并加上256之后赋值给前面提到的全局变量。
- 为什么要加256?
答:因为上次关机时,该全局变量的值可能大于磁盘页面中的Max Trx ID属性值。
【trx_id隐藏列】
聚簇索引的记录会自动添加trx_id和roll_pointer的隐藏列。如果用户没有在表中定义主键,并且没有定义不允许为NULL值的UNIQUE键,还会自动添加一个名为row_id的隐藏列。
表示对这个聚簇索引记录进行改动的语句所对应的事务id。