InnoDB数据库取证:从重做日志中 增强数据操作查询的重构外文翻译资料

 2022-03-12 15:49:37

英语原文共 12 页,剩余内容已隐藏,支付完成后下载完整资料


InnoDB数据库取证:从重做日志中

增强数据操作查询的重构

摘要

InnoDB存储引擎是MySQL使用最广泛的存储引擎之一,本篇文章讨论了利用InnoDB数据库的重做日志进行取证分析的可能性以及从MySQL定义的文件中提取所需的信息,以便进行这种分析。由于重做日志是存储引擎的内部日志文件,因此不容易在不被察觉地情况下被改变,这种取证方法针对那些拥有管理员权限的入侵者非常有用,否则他们能通过操纵用于审计和控制地传统日志文件来覆盖他们的踪迹。基于原型实现,我们展示了恢复针对一个数据库已发布的插入,删除和更新的语句的方法。

关键字:MySQL、InnoDB、数字取证、数据库、日志文件

1.引言和背景

在执行SQL语句时,InnoDB存储引擎将部分语句保存在多个存储位置(Pavlou和Snodgrass,2008年11月)。因此,取证分析与这些位置建立联系可以揭示最近的活动,可以帮助我们创建过去事件的(部分)时间线并进行恢复被删除或修改的数据(Stahlberg等,2010)。虽然这个事实在计算机取证研究领域是众所周知的,并且存在一些取证工具(弗朗西亚和克林顿,2005年6月)以及方法(Francia等人,2006; Jin和Lotspiech,11月2003; McDonald等人,2008年4月; Yen et al,2009)来分析数据,对数据库系统进行系统分析直到最近才开始(Kieseberg等人,2011a; Kieseberg等人,2011B; Olivier,2009年3月; Wright和Burleson,2008)。直到今天,这些方法仍然都没有包含存储在InnoDB重做日志中的数据,这些数据不但构成了丰富的有关事务的信息库,而且它们甚至能允许我们重建数据库的以前的状态。

自InnoDB 5.5版本以来,InnoDB是MySQL数据库默认的存储引擎。它是事务安全的并且支持提交,回滚和崩溃恢复(存储引擎,2010;Widenius和Axmark,2002)。事务安全意味着数据的每一次改变都是作为原子操作minitransaction(mtr)来实现的,这是为重做的目的而作的记录。因此,每次数据操作都会导致至少一次的函数mtr_commit()的调用,它将日志记录写入InnoDB重做日志。自MySQL版本5.1以来,InnoDB 用特殊算法压缩已写入的数据(在版本5.1.x变化,2008)在我们的研究中,我们分解了重做日志文件,这些文件在内部用于故障恢复,以便为数字取证目的识别和恢复事务。

本文的内容是我们基于对最新的ARES会议所做的析出文献(Fruehwirt等,2012),其中概述了所用的基本方法。第2节部分中我们描述了在分析过程中使用的日志文件的一般结构,在第3部分中我们详细介绍了识别近期操作的方法,以及使用重做信息恢复已覆盖的数据。此外,除了概述的方法(Fruehwirt等人,2012),我们在第4部分提出了用于收集表格结构和键上所需基本信息的方法。第5部分通过分析示例日志条目,给出了关于我们取证方法的能力的详细演示。在第6部分中,我们总结了工作并写下关于发展更多用于恢复更复杂语句类型的方法的未来计划。

2.日志文件结构

2.1一般结构

如果使用激活的innodb_file_per_table选项来启动MySQL(using per-table tablespac,11.08.2010),InnoDB使用两个默认大小为5兆字节的日志文件ib_logfile0和ib_logfile1作为默认操作。这两个文件具有相同的结构,而InnoDB在两者之间回转并最终覆写旧数据。与数据文件((Fruuml;hwirt et al., 2010)类似,日志文件被分成几个片段(见图1):

1)一个包含日志文件一般信息的头部块;

2)保护日志文件免受损坏的两个检查点;

3)包含实际日志数据的多个日志块;

标头块与两个检查点相结合加上填充块通常被称为头文件,长度正好是2048字节。每个日志块都包含一个头部,一个尾部和几个日志块条目。由于每个日志块的长度正好是512字节,所以日志块条目可以被拆分并存储在两个日志块中(请参阅有关日志块标题的进一步说明信息)。

2.2头部块

日志文件的第一部分由头部块组成,其中包含有关该文件的一般信息。这个块的固定长度为48个字节,并从偏移量0x00开始,即头文件的开头。表1给出了头部块的概述内容。

2.3检查点

InnoDB在日志文件中使用了一个检查点系统,它从doublewrite-buffer(Mysql performance blog,11.08.2010;Bannon et al., 2002; Kruckenberg and Pipes,2005)中冲刷数据库页面的变化和修改到小的批次,因为在一个单批次中处理所有内容会妨碍用户在检查点过程中发布的SQL语句的处理。

故障恢复:检查点系统对于故障恢复极其重要:每个日志文件中的两个检查点是在回转的基础上被写入的。因为这种方法,所以总是至少存在一个有效的检查点用于恢复。在故障恢复期间(Innodb检查点,2010;Tuuri,2009年4月),InnoDB加载两个检查点并且比较他们的内容。每个检查点包含一个八字节长的日志序列号(lsn)。序列号保证数据页面包含数据库的所有以前的更改(即具有较小lsn的所有条目)。所以,每一个未写入磁盘的更改必须存储在日志中用于故障恢复或回滚操作。InnoDB必须创建检查点以便将数据冲刷到磁盘(Tuuri,April

2009)。

在日志文件中的位置:两个检查点分别位于日志文件ib_logfile0的地址0x200和ib_logfile1的地址0x400。每个检查点都有相同的结构,具有304字节的固定长度。检查点结构的详细解释可以在表2中找到。当冲刷日志数据到磁盘的时候,当前检查点信息被写入到当前未完成的日志块头部。

2.4日志块的结构

日志文件条目存储在日志块中(日志文件不是按页而是按块组织),每个块分配512字节的数据,从而在启用InnoDB的时候(Zaitsev,2009年4月)与标准磁盘扇区大小相匹配。每个块分为三部分:日志块头部,数据和日志块尾部,InnoDB使用这种结构来提供更好的性能并允许更快的速度在日志中导航。

在下面的子章节中,我们讨论头部和尾部记录的结构,在第3节中我们将演示如何从日志块的实际内容中重现以前的查询。

1)日志块头部:每个块的前14个字节被称为日志块头部,该头部包含InnoDB存储引擎用于管理并读取日志数据(见表3)所需的所有信息。每过512字节InnoDB会自动创建一个新的头部,从而生成一个新的日志块。由于包含头部块,检查点和附加填充的日志文件头部长度恰好为2048字节,因此一个日志文件的第一个日志块头部的绝对地址是0x800。

如第2.3节所述,当前活动的日志块始终保持对当前活动检查点的引用,每次刷新日志内容到磁盘时都会更新此信息。

2)日志块尾部:日志块尾部只包含一个校验和用于验证日志块的有效性(见表4)。

3)将日志条目拆分为日志块:万一日志条目太大而不能适应当前活动的512字节日志块中的剩余空间,它会被分成两个日志块。为此,当前活动的块被填满直到剩下最后日志块尾部所需的四个字节。然后是一个新的日志块生成,包含一个日志块头部和被分割的日志条目的剩余内容。日志块头部中位于0x04和0x05的偏移量用于指定下一个日志条目的开始,即分割条目尾部的字节(参见图2)。这对于在不必引用日志块之前确定下一个条目的开始是必需的,从而大大增强在日志文件中的导航功能。

3.重构查询

在本节中,我们将演示如何根据来自在上一节中描述的日志文件的信息重构已执行的查询。由于数据的几个部分是以压缩格式存储(见附录A),给每个字段一个确切的长度定义几乎不可能,因为这些字段的长度由解压程序决定。这些值在字段“长度”中用圆圈符号(。)标记,包含星号的长度定义由日志条目中的其他字段定义,而星号前的数字指的是长度被定义的字段。在本文中,我们重点分析InnoDB的新型紧凑型文件格式,即通过在日志类型中加上前缀mlog_comp_来识别。旧版本的InnoDB日志文件需要更多的空间,不在本文讨论的范围内。

在我们的分析中,我们关注三种不同的基本语句,插入、删除和更新,因为它们构成了所有日志条目中的大部分。此外,它们是大多数取证分析情况下的主要关注点。

日志条目的描述:由于长度,数量和日志条目中相关字段的位置是极其易变的,我们避免给出有问题字段的数据的任何偏移量。为了提供表述清晰,按升序编号的字段和相同类型的字段(例如包含长度定义的可变数目的字段)被赋予相同的值。

3.1标识声明

所有日志条目可以通过它们的日志条目类型来标识,类型由每个条目的第一个字节提供。所有现有日志条目类型的完整列表可以在源代码中找到。然而,对于我们的取证分析,所有需要的信息可以从少数几个独特的日志条目中收集到(见表5)。

对于每一个数据操作语句,InnoDB都会至少产生一个类型为mlog_undo_insert的新日志条目。这个日志类型存储受影响表的标识号,语句类型(插入,更新,删除)的标识符,以及很大程度上取决于特定的语句类型的附加信息(见表6)。

语句识别的最重要字段是保存数据操作类型的字段,在我们的分析中,这个关键参数的值是我们关注的,如表7所示。

每个mlog_undo_insert日志条目的形式很大程度上取决于实际语句所陈述的内容。因此,日志条目没有一般的结构,但每种类型的条目表示各不相同,以此允许用一种没有任何填充的简洁的形式来存储它们。在是更新和删除语句的情况下,剩下的log_undo_insert日志条目完整地详细说明这条语句,而在插入的情况下,跟在log_undo_insert之后的mlog_comp_rec_insert日志条目提供了有关该语句参数的信息。

3.2重建插入语句

在是更新或删除语句的情况下,大部分信息需要存储在mlog_undo_insert日志条目中,这在是插入语句的情况下无效。在InnoDB将一个新记录插入表的过程中,InnoDB在日志文件中创建了9个日志条目(有关列表,请参阅表8)。

大多数日志条目与本文中概述的取证分析无关,而mlog_comp_rec_insert-log条目(日志条目代码0x26)包含各种可以用来重建已记录的插入语句的详细信息(Insert语句的标识是通过之前在mlog_undo_insert条目中检查数据操作类型来完成的)。表9给出了在mlog_comp_rec_insert日志条目里找到关于插入语句的字段的详细说明。

类型为comp_rec_insert的日志条目的结构相当复杂。在第一个通常为日志条目数据字段(日志条目类型,表空间ID和页面ID)之后,即也定义了使用的数据库表,提供了两个保存有关基础表的列信息的数据条目:n和n。n定义了可以在这个日志记录中被预计的数据字段的数量,而nunique指定了包含主键的数据字段的数量。数据字段下的数字n不等于表中的列数,因为系统内部字段的定义比如事务ID和数据回滚指针也存储在数据字段中。

遵循nunique的定义,接下来的2*nunique字节被保留用于定义这些unique列的长度,一列对应两个字节。此外,包含事务ID和数据回滚指针的数据字段的长度已被定义。接下来的2*(n-nunique)字节包含了无主键列的长度定义,必须考虑到在本节中给出的长度定义是指由表格定义的长度,而不是插入数据的实际长度。像int这样的静态数据类型的情况下,实际长度始终是定义的长度。但是像varchar(包含可变长度的数据)这样动态数据类型的情况下,以上所述长度定义只保持固定值0x8000。要插入数据的实际长度稍后会在日志条目中定义,图3显示了长度定义和数据字段之间的前后关系。

以下字节包含有关记录本身的元信息,但是,对于重建插入语句它不是需要的。接下来,所有包含动态数据类型的列(如前所述这些列的长度定义被填充了固定值0x8000)的长度信息,每个字节长和其压缩形式(见图3)被存储。接下来5个字节是附加字节和标志位,我们的取证方法不需要它们。

最后,插入记录的内容被按列定义为column:第一个nunique字段保存主键列的数据(字段的长度之前被定义在记录中),紧跟着是一个字段保存事务ID,一个字段保存数据回滚指针。接下来是这些包含非主键列的n-nunique-2字段,长度也是关于之前所说在记录开始时的定义。当然,为了正确的数据字段的解释,(特别是数据类型),关于对底层表定义的理解是需要的,这可以从对.frm文件的分析中导出(Fruuml;hwirt et al., 2010)。

3.3更新

在Update语句的情况下,需要两个日志条目用于重构:mlog_undo_insert日志条目(其中Insert语句仅用于确定语句类型)是恢复已被覆写的数据所需的,而mlog_comp_rec_insert日志条目对于重建在更新过程中被插入的数据是需要的。在这个演示中,我们关注于不改变主键值的更新语句,因为这些会导致更多的日志条目和整体索引结构的更改。

1)重建覆写的数据:作为InnoDB内部存储的用以恢复和回滚的覆写数据,为了取证目的,我们关注在mlog_undo_insert日志条目上(表10)。

关于前五个字段的解释,请参阅第3.1节。

接下来的两个字节包含表的标识符,这个标识符也可以在表的定义中找到(它存储在地址0x26处的.frm文件中),结合这些信

全文共16040字,剩余内容已隐藏,支付完成后下载完整资料


资料编号:[16431],资料为PDF文档或Word文档,PDF文档可免费转换为Word

原文和译文剩余内容已隐藏,您需要先支付 30元 才能查看原文和译文全部内容!立即支付

以上是毕业论文外文翻译,课题毕业论文、任务书、文献综述、开题报告、程序设计、图纸设计等资料可联系客服协助查找。