2.5.3 优化手段

1.成组提交

存储系统要求先将REDO日志刷入磁盘才可以更新内存中的数据,如果每个事务都要求将日志立即刷入磁盘,系统的吞吐量将会很差。因此,存储系统往往有一个是否立即刷入磁盘的选项,对于一致性要求很高的应用,可以设置为立即刷入;相应地,对于一致性要求不太高的应用,可以设置为不要求立即刷入,首先将REDO日志缓存到操作系统或者存储系统的内存缓冲区中,定期刷入磁盘。这种做法有一个问题,如果存储系统意外故障,可能丢失最后一部分更新操作。

成组提交(Group Commit)技术是一种有效的优化手段。REDO日志首先写入到存储系统的日志缓冲区中:

a)日志缓冲区中的数据量超过一定大小,比如512KB;

b)距离上次刷入磁盘超过一定时间,比如10ms。

当满足以上两个条件中的某一个时,将日志缓冲区中的多个事务操作一次性刷入磁盘,接着一次性将多个事务的修改操作应用到内存中并逐个返回客户端操作结果。与定期刷入磁盘不同的是,成组提交技术保证REDO日志成功刷入磁盘后才返回写操作成功。这种做法可能会牺牲写事务的延时,但大大提高了系统的吞吐量。

2.检查点

如果所有的数据都保存在内存中,那么可能出现两个问题:

●故障恢复时需要回放所有的REDO日志,效率较低。如果REDO日志较多,比如超过100GB,那么,故障恢复时间是无法接受的。

●内存不足。即使内存足够大,存储系统往往也只能够缓存最近较长一段时间的更新操作,很难缓存所有的数据。

因此,需要将内存中的数据定期转储(Dump)到磁盘,这种技术称为checkpoint(检查点)技术。系统定期将内存中的操作以某种易于加载的形式(checkpoint文件)转储到磁盘中,并记录checkpoint时刻的日志回放点,以后故障恢复只需要回放checkpoint时刻的日志回放点之后的REDO日志。

由于将内存数据转储到磁盘需要很长的时间,而这段时间还可能有新的更新操作,checkpoint必须找到一个一致的状态。checkpoint流程如下:

1)日志文件中记录"START CKPT"。

2)将内存中的数据以某种易于加载的组织方式转储到磁盘中,形成checkpoint文件。checkpoint文件中往往记录"START CKPT"的日志回放点,用于故障恢复。

3)日志文件中记录"END CKPT"。

故障恢复流程如下:

1)将checkpoint文件加载到内存中,这一步操作往往只需要加载索引数据,加载效率很高。

2)读取checkpoint文件中记录的"START CKPT"日志回放点,回放之后的REDO日志。

上述checkpoint故障恢复方式依赖REDO日志中记录的都是修改后的结果这一特性,也就是说,即使checkpoint文件中已经包含了某些操作的结果,重新回放一次或者多次这些操作的REDO日志也不会造成数据错误。如果同一个操作执行一次与重复执行多次的效果相同,这种操作具有“幂等性”。有些操作不具备这种特性,例如,加法操作、追加操作。如果REDO日志记录的是这种操作,那么checkpoint文件中的数据一定不能包含"START CKPT"与"END CKPT"之间的操作。为此,主要有两种处理方法:

●checkpoint过程中停止写服务,所有的修改操作直接失败。这种方法实现简单,但不适合在线业务。

●内存数据结构支持快照。执行checkpoint操作时首先对内存数据结构做一次快照,接着将快照中的数据转储到磁盘生成checkpoint文件,并记录此时对应的REDO日志回放点。生成checkpoint文件的过程中允许写操作,但checkpoint文件中的快照数据不会包含这些操作的结果。