MySQL数据库InnoDB存储引擎Log漫游Word格式.docx

上传人:b****5 文档编号:19953317 上传时间:2023-01-12 格式:DOCX 页数:13 大小:63.52KB
下载 相关 举报
MySQL数据库InnoDB存储引擎Log漫游Word格式.docx_第1页
第1页 / 共13页
MySQL数据库InnoDB存储引擎Log漫游Word格式.docx_第2页
第2页 / 共13页
MySQL数据库InnoDB存储引擎Log漫游Word格式.docx_第3页
第3页 / 共13页
MySQL数据库InnoDB存储引擎Log漫游Word格式.docx_第4页
第4页 / 共13页
MySQL数据库InnoDB存储引擎Log漫游Word格式.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

MySQL数据库InnoDB存储引擎Log漫游Word格式.docx

《MySQL数据库InnoDB存储引擎Log漫游Word格式.docx》由会员分享,可在线阅读,更多相关《MySQL数据库InnoDB存储引擎Log漫游Word格式.docx(13页珍藏版)》请在冰豆网上搜索。

MySQL数据库InnoDB存储引擎Log漫游Word格式.docx

C.Undolog必须先于数据持久化到磁盘。

如果在G,H之间系统崩溃,undolog是完整的,

 

可以用来回滚事务。

D.如果在A-F之间系统崩溃,因为数据没有持久化到磁盘。

所以磁盘上的数据还是保持在事务开始前的状态。

缺陷:

每个事务提交前将数据和UndoLog写入磁盘,这样会导致大量的磁盘IO,因此性能很低。

如果能够将数据缓存一段时间,就能减少IO提高性能。

但是这样就会丧失事务的持久性。

因此引入了另外一

种机制来实现持久化,即RedoLog.

01–RedoLog

和UndoLog相反,RedoLog记录的是新数据的备份。

在事务提交前,只要将RedoLog持久化即可,

不需要将数据持久化。

当系统崩溃时,虽然数据没有持久化,但是RedoLog已经持久化。

系统可以根据

RedoLog的内容,将所有数据恢复到最新的状态。

-Undo+Redo事务的简化过程

假设有A、B两个数据,值分别为1,2.

D.记录A=3到redolog.

E.记录B=2到undolog.

F.修改B=4.

G.记录B=4到redolog.

H.将redolog写入磁盘。

I.事务提交

-Undo+Redo事务的特点

A.为了保证持久性,必须在事务提交前将RedoLog持久化。

B.数据不需要在事务提交前写入磁盘,而是缓存在内存中。

C.RedoLog保证事务的持久性。

D.UndoLog保证事务的原子性。

E.有一个隐含的特点,数据必须要晚于redolog写入持久存储。

-IO性能

Undo+Redo的设计主要考虑的是提升IO性能。

虽说通过缓存数据,减少了写数据的IO.

但是却引入了新的IO,即写RedoLog的IO。

如果RedoLog的IO性能不好,就不能起到提高性能的目的。

为了保证RedoLog能够有比较好的IO性能,InnoDB的RedoLog的设计有以下几个特点:

A.尽量保持RedoLog存储在一段连续的空间上。

因此在系统第一次启动时就会将日志文件的空间完全分配。

以顺序追加的方式记录RedoLog,通过顺序IO来改善性能。

B.批量写入日志。

日志并不是直接写入文件,而是先写入redologbuffer.当需要将日志刷新到磁盘时

(如事务提交),将许多日志一起写入磁盘.

C.并发的事务共享RedoLog的存储空间,它们的RedoLog按语句的执行顺序,依次交替的记录在一起,

以减少日志占用的空间。

例如,RedoLog中的记录内容可能是这样的:

记录1:

<

trx1,insert…>

记录2:

trx2,update…>

记录3:

trx1,delete…>

记录4:

trx3,update…>

记录5:

trx2,insert…>

D.因为C的原因,当一个事务将RedoLog写入磁盘时,也会将其他未提交的事务的日志写入磁盘。

E.RedoLog上只进行顺序追加的操作,当一个事务需要回滚时,它的RedoLog记录也不会从

RedoLog中删除掉。

02–恢复(Recovery)

-恢复策略

前面说到未提交的事务和回滚了的事务也会记录RedoLog,因此在进行恢复时,这些事务要进行特殊的

的处理.有2中不同的恢复策略:

A.进行恢复时,只重做已经提交了的事务。

B.进行恢复时,重做所有事务包括未提交的事务和回滚了的事务。

然后通过UndoLog回滚那些

未提交的事务。

-InnoDB存储引擎的恢复机制

MySQL数据库InnoDB存储引擎使用了B策略,InnoDB存储引擎中的恢复机制有几个特点:

A.在重做RedoLog时,并不关心事务性。

恢复时,没有BEGIN,也没有COMMIT,ROLLBACK的行为。

也不关心每个日志是哪个事务的。

尽管事务ID等事务相关的内容会记入RedoLog,这些内容只是被当作

要操作的数据的一部分。

B.使用B策略就必须要将UndoLog持久化,而且必须要在写RedoLog之前将对应的UndoLog写入磁盘。

Undo和RedoLog的这种关联,使得持久化变得复杂起来。

为了降低复杂度,InnoDB将UndoLog看作

数据,因此记录UndoLog的操作也会记录到redolog中。

这样undolog就可以象数据一样缓存起来,

而不用在redolog之前写入磁盘了。

包含UndoLog操作的RedoLog,看起来是这样的:

trx1,Undologinsert<

undo_insert…>

>

trx2, 

Undologinsert<

undo_update…>

trx3,Undologinsert<

undo_delete…>

记录6:

trx3,delete…>

C.到这里,还有一个问题没有弄清楚。

既然Redo没有事务性,那岂不是会重新执行被回滚了的事务?

确实是这样。

同时Innodb也会将事务回滚时的操作也记录到redolog中。

回滚操作本质上也是

对数据进行修改,因此回滚时对数据的操作也会记录到RedoLog中。

一个回滚了的事务的RedoLog,看起来是这样的:

trx1,insertA…>

trx1,updateB…>

trx1,deleteC…>

记录7:

trx1,insertC>

记录8:

trx1,updateBtooldvalue>

记录9:

trx1,deleteA>

一个被回滚了的事务在恢复时的操作就是先redo再undo,因此不会破坏数据的一致性.

-InnoDB存储引擎中相关的函数

Redo:

recv_recovery_from_checkpoint_start()

Undo:

recv_recovery_rollback_active()

UndoLog的RedoLog:

trx_undof_page_add_undo_rec_log()

03–日志的内容

-数据是什么

从不同的角度和层次来看,我们可以将数据库中的数据看作:

A.关系数据

B.元组或对象

C.存在Page中的二进制序列

因此Log中也可以记录不同的内容:

-物理的日志(PhysicalLog)

A.记录完整的Page

B.记录Page中被修改的部分(page中的偏移,内容和长度).

优点:

因为恢复时,完全不依赖原页面上的内容,所以不要求持久化了的数据保持在一个一致的状态。

比如在写一个页面到磁盘上时,系统发生故障,页面上的一部数据写入了磁盘,另一部分丢失了。

这时仍然可以恢复出正确的数据。

缺点:

Log记录的内容很多,占用很大的空间。

如B-Tree的分裂操作,要记录约一个完整Page的内容。

-逻辑的日志(LogicalLog)

记录在关系(表)上的一个元组操作。

A.插入一行记录。

B.修改一行记录。

C.删除一行记录。

逻辑日志比起物理的日志,显得简洁的多。

而且占用的空间也要小的多。

但是逻辑日志有2个缺点:

A.部分执行

例如:

表T有2个索引,在向T插入1条记录时,需要分别向2个B-Tree中插入记录。

有可能第一个B-Tree插入成功了,但是第二个B-Tree没有插入成功。

在恢复或

回滚时,需要处理这些特殊情况。

B.操作的一致性问题

一个插入操作有一个B-Tree的分裂,页A的一半数据移到了B页,A页写入了磁盘,B页没有写入磁盘。

如果这时候发生了故障,需要进行恢复,逻辑日志是很难搞定的。

逻辑的日志上的‘部分执行’的问题是比较好维护的,但是‘一致性’的问题维护起来是很复杂的。

-物理和逻辑结合的日志(PhysiologicalLog)

这种日志将物理和逻辑日志相结合,取其利,去其害。

从而达到一个相对更好的一个状态。

这种日志有2个特点:

A.物理到page.将操作细分到页级别。

为每个页上的操作单独记日志。

比如,一个Insert分别在2个B-Tree的节点上做了插入操作,那么就分别为每一个页的操作记录一条日志。

B.Page内采用逻辑的日志。

比如对一个B-Tree的页内插入一条记录时,物理上来说要修改PageHeader的

内容(如,页内的记录数要加1),要插入一行数据到某个位置,要修改相邻记录里的链表指针,要修改Slot的

属性等。

从逻辑上来说,就是在这个页内插入了一行记录。

因此Page内的逻辑日志只记录:

’这是一个

插入操作’和’这行数据的内容‘。

MySQL数据库InnoDB存储引擎的RedoLog记录的就是这种物理和逻辑相结合的日志。

使用页内的逻辑日志,可以减少日志占用的空间。

但是它毕竟还是逻辑日志,上面提到的2个问题能够避免吗?

A.页面内的部分执行的情况可以认为不存在了。

因为整个页面的操作是原子操作,在完成之前是不会写

到磁盘上的。

B.操作一致性的问题仍然存在。

如果在写一个Page到磁盘时发生了故障,可能导致PageHeader的记

录数被加1了,但是数据没有刷新到磁盘上,总之页面上的数据不一致了。

好在这个问题被缩小到了一个页面的范围内,因此比较容易解决。

InnoDB存储引擎中用DoubleWrite的方法

来解决这个问题。

-DoubleWrite

DoubleWrite的思路很简单:

A.在覆盖磁盘上的数据前,先将Page的内容写入到磁盘上的其他地方(InnoDB存储引擎中的doublewrite

buffer,这里的buffer不是内存空间,是持久存储上的空间).

B.然后再将Page的内容覆盖到磁盘上原来的数据。

如果在A步骤时系统故障,原来的数据没有被覆盖,还是完整的。

如果在B步骤时系统故障,原来的数据不完整了,但是新数据已经被完整的写入了doublewritebuffer.

因此系统恢复时就可以用doublewritebuffer中的新Page来覆盖这个不完整的page.

Doublewrite显然会曾加磁盘的IO。

直觉上IO次数增加了1倍,但是性能损失并不是很大。

Peter在

innodb-double-write中说性能损失不超过5-10%。

应该是因为多数情况下使用了批量写入的缘故。

A.Doublewritebuffer是一段连续的存储空间,可以顺序写入。

B.Doublewrite有自己的写buffer.

C.先将多个要做doublewrite的page写入内存的buffer,然后再一起写到磁盘上。

代码在:

buf0dblwr.cc

buf_flush_write_block_low()调用

buf_dblwr_write_single_page()或buf_dblwr_add_to_batch()来实现doublewrite.

-Checksum

检测页面是否一致的功能是靠Checksum来完成的,每个页面修改完成后都会记算一个页面的checksum。

这个checksum存放在页面的尾部.每次从磁盘读一个页到内存时,都需要检测页的一致性。

函数buf_page_is_corrupted()是用来检测page的一致性的.

-InnoDBRedoLog的日志类型

InnoDBredolog的格式可以概括为:

SpaceID>

+<

PageNO.>

操作类型>

数据>

.

RedoLog记录的页面操作大致可以分为以下几种类型:

A.在页面上写入N个字节的内容,这些可以看作是物理的Log.

MLOG_1BYTE,MLOG_2BYTES,MLOG_4BYTES,MLOG_8BYTES,MLOG_WRITE_STRING

各种Page链表的指针修改,以及文件头,段页等的内容的修改都是以这种方式记录的日志。

B.页面上的记录操作。

MLOG_REC_*,MLOG_LIST_*,MLOG_COMP_REC_*,MLOG_COMP_LIST_*

这些日志记录了对B-Tree页的INSER,DELETE,UPDATE操作和分裂合并操作。

C.文件和Page操作

MLOG_FILE_CREATE,MLOG_FILE_RENAME,MLOG_FILE_DELETE,

MLOG_PAGE_CREATE,MLOG_INIT_FILE_PAGE,MLOG_PAGE_REORGANIZE

D.UndoLog操作

MLOG_UNDO_*

InnoDB中将undolog的操作也记入了redolog.为什么要这样做,在前面‘恢复’已经说了.

这里只提到了部分RedoLog的类型,完整的定义在mtr0mtr.h文件中.通过这个类型的定义,可以

很容易的找到都在哪些地方使用了。

虽说RedoLog将数据的操作细分到了页面级别。

但是有些在多个页面上的操作是逻辑上不可分裂的。

比如B-Tree的分裂操作,对父节点和2个子节点的修改。

当进行恢复时,要么全部恢复,要么全部不

恢复,不能只恢复其中的部分页面。

InnoDB中通过mini-transaction(MTR)来保证这些不可再分

的操作的原子性。

-InnoDBUndoLog的日志类型

MySQL数据库InnoDB存储引擎的undolog采用了逻辑的日志。

InnoDBundolog的格式可以概括为:

<

TableID>

A.从表中删除一行记录

TRX_UNDO_DEL_MARK_REC(将主键记入日志)

在删除一条记录时,并不是真正的将数据从数据库中删除,只是标记为已删除.这样做的好处是

UndoLog中不用记录整行的信息.在undo时操作也变得很简单.

B.向表中插入一行记录

TRX_UNDO_INSERT_REC(将主键记入日志)

TRX_UNDO_UPD_DEL_REC(仅将主键记入日志)当表中有一条被标记为删除的记录和要插入的

数据主键相同时,实际的操作是更新这个被标记为删除的记录。

C.更新表中的一条记录

TRX_UNDO_UPD_EXIST_REC(将主键和被更新了的字段内容记入日志)

TRX_UNDO_DEL_MARK_REC和TRX_UNDO_INSERT_REC,当更新主键字段时,实际执行的过程

是删除旧的记录然后,再插入一条新的记录。

因为undolog还要被MVCC和Purge使用,所以还有TRX_ID和DATA_ROLL_PTR等特殊的内容记录

在日志中。

TRX_UNDO_INSERT_REC不需要记录这些内容.因为MVCC中不可内引用一个不存在的数据。

这也是事务将insert和update、delete的undolog分开存放的原因。

事务提交后,insert的undo

占用的空间就可以立即释放了.

这些类型定义在:

trx0rec.h.

记录日志的过程在:

trx_undo_page_report_insert()和trx_undo_page_report_modify()中。

Undo操作在row0undo.c,row0uins.c和row0umod.c中,入口函数是row_undo().

-逻辑日志的一致性问题

前面说了逻辑日志的一致性问题是很复杂的,为什么undolog要用逻辑日志呢?

因为redolog使用了physiological日志和MTR,就可以保证在恢复时重做完redolog后,

数据是一致。

在执行undo时,就不必考虑这个问题了。

04–Checkpoint

理论上来说,如果MySQL数据库InnoDB存储引擎的buffer足够大,就不需要将数据本身持久化。

将全部的redolog重新执行一遍

就可以恢复所有的数据。

但是随着时间的积累,RedoLog会变的很大很大。

如果每次都从第一条记

录开始恢复,恢复的过程就会很慢,从而无法被容忍。

为了减少恢复的时间,就引入了Checkpoint机制。

-脏页(dirtypage)

如果一个数据页在内存中修改了,但是还没有刷新到磁盘。

这个数据页就称作脏页。

-日志顺序号(LogSequenceNumber)

LSN是日志空间中每条日志的结束点,用字节偏移量来表示。

在Checkpoint和恢复时使用。

假设在某个时间点,所有的脏页都被刷新到了磁盘上.这个时间点之前的所有RedoLog就不需要重

做了。

系统记录下这个时间点时redolog的结尾位置作为checkpoint.在进行恢复时,从这个

checkpoint的位置开始即可。

Checkpoint点之前的日志也就不再需要了,可以被删除掉。

为了

更好的利用日志空间,InnoDB以环形缓存(circularbuffer)的方式来使用日志空间。

SharpCheckpoint

-SharpCheckpoint

对于繁忙的系统来说,很少会出现这样的的一个时间点。

为了能创造出这样一个时间点,最简单的办

法就是,在某个时间开始停止一切更新操作,直到所有的脏页被刷新到磁盘,Checkpoint被记录。

显然对于繁忙的系统,这种方法是不合适的。

能不能在checkpoint时不停止用户的操作呢?

-FuzzyCheckpoint

如下图所示,如果刷脏页的同时用户还在更新数据,LSN1前的某个脏页在刷到持久存储之前就有可能被

LSN1之后的某个操作给修改了。

当checkpoint完成时,LSN1后的部分操作(R1,R2对应的操作)也被

持久化了。

当Sharpcheckpoint完成时,持久存储中存储的数据是某个确切时间点的内存数据的快照。

Fuzzycheckpoint完成时,持久存储中存储的数据不是某个确切时间点的内存数据的快照。

从某种

程度上,可以说持久存储中的数据丧失了一致性。

在恢复时,必须要解决这个问题。

FuzzyCheckpoint

-幂等(Idempotence)规则

如上图所示,checkpoint在LSN1位置,当checkpoint完成时R1,R2对应的修改也被刷到了持久存储。

恢复时要从LSN1位置开始,包括R1,R2在内。

重新执行后,数据还能正确吗?

幂等规则要求无论redolog被执行了多少次,数据始终正确。

InnoDB的redolog,物理到Page,Page内是逻辑日志。

物理日志,天然支持幂等规则.但是逻辑日志需要特殊处理,才能支持满足幂等规则。

-数据页的最新(最大)LSN

为了满足幂等规则,InnoDB中每个数据页上都记录有一个LSN。

每次更新数据页时,将LSN修改为

当前操作的redolog的LSN。

在恢复时,如果数据页的LSN大于等于当前redolog的LSN,则跳过此

日志。

-异步Checkpoint

实现了幂等规则后,脏页就可以在任何时间,以任何顺序写入持久存储了。

InnoDB的bufferpool有

一套单独的机制来刷脏页。

因此很多情况下checkpoint时,并不写脏页到存储。

只是将所有脏页的

最小的LSN记做checkpoint.

checkpoint的实现在log0log.c.

log_checkpoint()实现异步checkpoint.

-同步Checkpoint

InnoDB的bufferpool通过LRU的算法来决定哪些脏页应该被写入持久存储

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工作范文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1