MySQL的redo log结构和SQL Server的log结构对比
innodb 存储引擎 mysql技术内幕
f
1
f
2
f
3
f
4
f
5
f
6
f
7
f
sqlserver
http://www.cnblogs.com/CareySon/p/3308926.html
事务对数据库中每次修改都会分解成多个多个原子层级的条目被记录到持久存储中,这些条目就是所谓的日志记录(Log Record),我们可以通过fn_dblog来查看这些条目。如图2所示。
图2.Fn_dblog
每个日志记录都会被背赋予一个唯一的顺序编号,这个编号大小为10字节,由三部分组成,分别为:
- VLF顺序号(4字节)
- Log Block顺序号(4字节)
- Log Block内的顺序编号(2字节)
因此,由于VLF是不断递增的(同一个VLF被复用会导致编号改变),因此LSN序号也是不断递增的。因此,通过上面的LSN结构不难发现,如果比VLF更小的粒度并不是直接对应LOG RECORD,而是LOG Block。Log Block是日志写入持久化存储的最小单位,Log Block的大小从512字节到60K不等,这取决于事务的大小,那些在内存还未被写入持久化存储的Log Block也就是所谓的In-Flight日志。以下两个因素决定Log Block的大小:
- 事务提交或回滚
- Log Block满60K会强制Flush到持久化存储,以保证WAL
因此当一个事务很大时(比如说大面积update),每60K就会成为一个Log Block写入持久化存储。而对于很多小事务,提交或回滚就会称为一个Block写入持久化存储,因此根据事务的大小,LOG Block的大小也会不同。值得疑惑的是,因为磁盘上分配单元的大小是2的N次方,因此最接近LOG BLOCK的大小应该是64K,而SQL Server为什么不把Log Block设定为64K呢。这样可以更优化IO。
VLF和Log Block和Log Record的关系如图3所示。
图3.三者之间的关系
从比较高的层级了解了日志之后,我们再仔细了解日志中应该存储的关键信息,每条Log Record中都包含下面一部分关键信息:
- LSN
- Log Record的Context
- Log Record所属的事务ID(所有的用户事务都会存在事务ID)
- Log Record所占的字节
- 同一个事务中上一条Log Record的LSN(用于Undo)
- 为Undo所保留的日志空间
当然,这些仅仅是日志的一小部分内容。通过Log Record所记录的内容,就能够精确的记录对数据库所做的修改。
日志用于Undo
在了解为了Undo,日志所起的作用之前,我们首先可以了解一下为什么需要事务存在回滚:
- 因为事务可能失败,或者死锁等原因,如果希望事务不违反原子性而造成数据库不一致的话,则需要通过回滚将已经部分执行的事务回滚掉。
- 根据业务需求,如果在某些关联业务失败等情况下,回滚数据。