Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member

众所周知,SAP HANA是内存数据库,很多人会有疑问,内存是断电就会丢失数据的设备,SAP HANA是怎样保证数据在内存中并且断电不会丢失的呢?

此问题涉及到概念叫数据库保护:排除和防止各种对数据库的干扰破坏,确保数据安全可靠,以及在数据库遭到破坏后尽快地恢复。而数据库的恢复技术是数据库保护的重要手段。还要介绍一个概念:事务:一个不可分割的操作序列,其中的操作要么都做,要么都不做。举个例子:银行转帐:A帐户转帐到B帐户100元。该处理包括了两个更新步骤

  • A=A-100
  • B=B+100

这两个操作是不可分的:要么都做,要么都不做。事务的状态在日志中包含三种:

  • <Start T>表示事务T已经开始;
  • <Commit T>表示事务T已经成功完成并且所有的修改都已经写入数据库;
  • <Abort T>表示事务T已经被终止,并且所有的修改已被取消。

数据库的故障分为三类:

  • 事务故障:单个事务的内部故障,不会影响其他事务;
  • 介质故障:硬故障:如磁盘损坏,磁盘已满等;
  • 系统故障:软故障,如停电、死机等,这些故障会导致内存数据丢失,影响当前的全部事务。

数据库对系统故障的恢复主要目的是恢复到故障发生之前的状态,即尚未完成的事务进行回滚,已完成的事务要确保其完成。

系统故障恢复验证

SAP HANA中,这些概念同样适用,下面对SAP HANA的系统故障的恢复进行验证。本文的测试案例所使用的SAP HANA版本为SAP HANA SPS7 Revision 70.00

首先修改savepoint时间,在savepoint过程中,SAP HANA会把内存页持久化在硬盘上,而SAP HANA的默认savepoint间隔为300s,将其改为3000s


开启两个SQL窗口,将SQL 窗口的auto commit属性设置为off

sql窗口1中执行


insert into "LOGTEST"."TEST" values(1,'谢谢大家关注HANAGeek,欢迎大家一起来学习SAP HANA知识,分享SAP HANA知识。');

sql窗口2中执行


insert into "LOGTEST"."TEST" values(2,'谢谢大家关注HANAGeek,欢迎大家一起来学习SAP HANA知识,分享SAP HANA知识。');


commit;

SAP HANA进行断电处理。开机重启SAP HANA,查看此表内容。

我们可以认为窗口1和窗口2是两个事务T1T2,事务T1执行一条修改后,没有commit,因此故障之后回滚到事务T1执行前。事务T2已经commit,虽然SAP HANA尚未把数据持久化到硬盘上(未做savepoint),但是由于事务日志的存在,数据库被成功恢复到了故障点。

系统故障的恢复策略

如上图所示,当发生故障时,若是介质故障,则首先重装副本(系统故障省略此步骤),然后利用日志进行事务故障恢复和系统故障恢复,一直恢复到故障发生点。

事务日志

事务日志是用来管理数据库系统中记录的变化,记录了所有更新操作的具体细节。为了让一个事务持久化不丢失,我们不必在事务提交时就把完整的数据内容持久化在硬盘中,只需要持久化事务日志就足够了。当系统崩溃后,数据库中的最近的一致性状态可以通过回放事务日志来恢复。因此日志文件的记录严格按照事务的执行时间次序。

事务日志主要包含三种:Undo日志、Redo日志、Undo/Redo日志。而在SAP HANA中,只有两种日志:Undo日志、Redo日志。

日志文件的内容主要包含以下三方面:

  • 事务的开始标记(<Start T>
  • 事务的结束标记(<Commit, T><Abort T>
  • 事务的更新操作记录,一般包括以下内容

其中,一条更新操作记录包括:执行操作的事务标识,操作对象,更新前值(Undo)或者更新后值(Redo)或者更新前值和更新后值(Undo/Redo)。


Redo日志

Redo日志的特点是,在修改数据写入数据库之前,对应该修改的Redo日志记录必须已被写到磁盘上。日志中数据修改记录的格式为<T,x,v>其中,T为事务标示,x为被修改数据标识,v为修改后的值。

如下图所示,事务T1的操作是A=A-100B=B+100,图左方为数据库中的T1具体步骤,图中间为T1对应的Redo日志内容,图右方标识AB的初始值分别为1000,2000

Redo日志的恢复过程如下:

  1. 从头扫描日志,找出所有有<Commit,T>的事务,放入一个事务列表L
  2. 从首部开始扫描日志记录<T,x,v>,如果T属于 L,则
  • write (X, v)(将新值赋给X
  • output (X)(将X写入数据库)
  1. For each T不属于 L do
  • write <Abort,T > to log

这种恢复方式的理论基础是没有<Commit,T>记录的操作必定没有改写磁盘中数据,因此在恢复时可以不理会。而有<Commit,T>记录的结果可能还未写回磁盘,因此在恢复时要Redo

SAP HANARedo日志是与事务处理的过程同步的写到磁盘中的。当数据库遇到崩溃后重启,需要对持久化的日志进行处理,为了提高日志处理的速度,系统会定期的进行savepoints(保存点,类似于传统数据库中的checkpoint)。在一个savepoint的过程中,系统确保在上一个savepoint后所有在内存中的数据改变都被持久化在硬盘中。因此,当启动系统后,只有最后一次savepoint之后的redo日志才需要被处理。当日志备份后,savepoint之前的过时的redo日志可以被删除。


Undo日志

SAP HANA不仅仅持久化committed的改变记录,它还可能持久化未committed的改变记录(注:此改变记录并非log,而是data),例如:在savepoint过程中,最近版本的的改变过的页都会被写到磁盘中,无论这个改变是否已commit。因此Undo日志需要被持久化在硬盘中。Undo日志的记录格式为<T, x, v>,其中v是修改之前x的值。

如下图所示事务T1的操作是A=A-100B=B+100,图左方为数据库中的T1具体步骤,图中间为T1对应的Undo日志内容,图右方标识AB的初始值分别为1000,2000

Undo日志的恢复过程如下:

  1. 从头扫描日志,找出所有没有<Commit,T><Abort,T>的所有事务,放入一个事务列表L
  2. 从尾部开始扫描日志记录<T,x,v>,如果T属于 L,则
  • write (X, v) (将旧值赋给X
  • output (X) (将X写入数据库)
  1. For each T属于L do
  • write <Abort,T > to log

SAP HANA中,与Redo日志不同,Undo日志持久化时不放在日志区,而是放在数据区,在savepoint时才会被持久化。这样做的原因是系统重启后可以自动恢复到最近一次savepoint的状态,在这此savepoint后的事务如果已经commit,则可以通过redo日志进行回放,如果未commit,也不需要undo log进行回滚,因此,此savepoint的之后的undo log是没有用的。这样做带来的好处:

  • 更少的log记录在事务提交时被持久化。
  • 减缓Log区硬盘使用量的增长。
  • 数据库可以只从数据区就可以恢复到一致性状态。(不需要日志区)

Savepoint

当系统发生故障时,必须扫描整个日志来确定undo列表和redo列表,这样会带来问题是:这个搜索过程太耗时,因为日志文件增长很快;会导致最后产生的Redo列表很大,使恢复过程变得很长。因此SAP HANA会定期的做savepoint,在savepoint过程中主要做以下工作:

  1. 不再接受新的事务
  2. undo信息写到磁盘(data区)
  3. 把内存中修改过的数据页写到磁盘
  4. log文件中写入 savepoint标记(log区)

如下图所示,savepoint技术保证了savepoint之前所有的commit操作已被写到磁盘,在恢复时不需要进行redo操作。

想获取更多SAP HANA学习资料或有任何疑问,请关注新浪微博@HANAGeek!我们欢迎你的加入!

5 Comments