关于灾难性恢复的基础知识
The Cornerstone Of Crash Recovery
Roger Sanders
著
Viviral
译
笑熬浆糊
整理
天堂鸟自由空间原创作品
天堂鸟自由空间©2002-2006
版权所有
转载请保持文档的完整性
访问更多可以浏览
http://hbird.vicp.net/myself.html
Blog: http://blog.csdn.net/mr_bean
BBS
讨论
: http://hbird.vicp.net
关于灾难性恢复的基础知识
Roger Sanders
著
Viviral
译
笑熬浆糊
整理
原文出处:《DB2 Magazine
》 Quarter 1, 2005 Vol. 10, Issue 1
英文原文(由于文章翻译未经授权,请在转载时保留原文链接)
在系统崩溃的时候使用DB2 事务日志来恢复你的数据库。
你曾经多少次遇到过的如下提示信息:SQL0946C 数据库的事务日志已满?
当你尝试去解决这个问题的时候,你有没有停下来想想为什么事务日至会存在并且出于什么样的目的会进行事务的日志处理呢?
如果没有事务处理,多用户和应用程序就不会在与数据库进行交互的同时没有脏读的数据。如果没有事务日志的存在,一些DB2 UDB中可以使用数据库恢复的方法将不复存在。
如果你不能完全理解这些,不要着急。我将告诉你什么是事务处理以及事务日志
纪录后的结构。然后我会告诉你怎么使用数据库的事务日志里的数据在系统崩溃或者程序错误之后来把数据库恢复到正常能使用的状态去。
但这些也不是处理这些重要的日志全部内容。在后面的专栏里,我将告诉你怎样使用事务日志重新操作将数据库恢复至指定时间点上的原有状态。
事务处理
一个事务(也被认为是一个工作单元)是一个拥有一个或者多个SQL操作的序列它通常在一个应用程序处理过程内把上述的序列汇集在一起成为了一个单独的单元。这个单元常被称为“原子”,因为它是不可分割的,要么它们全被执行,要么一个也不执行。一个指定的事务处理可以执行任意数量的SQL操作(从1至数万,这取决于你的事务逻辑里被确定的“单步”)。
单一事务处理的开始和结束定义了数据库里数据一致性的点。要么是一个事务中的所有操作执行的结果被应用于该数据库并且永久有效(就是通常所说的落实更新committed),要么就是他们全部被回退(也就是通常所说的回滚 rolled back),同时数据库将会恢复到事务被执行之前的最初状态。
事务开始于数据库连接建立以后SQL语句被执行的第一时间或者在一个已存在的事务被结束后马上执行。事务一旦开始执行,它可能会通过自动落实更新(automatic commit)的属性隐性的结束。这样,每个可执行的SQL语句会被认为是一个单独的事务。这些语句一旦成功执行的话,它所引起的数据库的一切修改将会落实,反之将会被丢弃。
事务处理可以明确地通过COMMIT或ROLLBACK SQL语句执行来结束。
这些语句的基本语法如下:
COMMIT
<WORK>
ROLLBACK
<WORK>
当用COMMIT终止一个事务时,所有事务开始以后对数据库的变动将会是永久的。而用ROLLBACK,所有的变动都会被回退回原来状态。
对于事务中所引起的未落实更新的那些改变是不能够被其他用户和应用程序来讲是不能够被访问到的,除非他们正在使用未落实更新读的隔离级别(UR隔离级别)。但是,这些变动一旦被落实更新,它们就能被所有其他用户和应用程序访问并且只能通过在新的事务中执行新的SQL语句才能被移除。
事务处理日志
当你插入一个基表,首先会在指明表数据存储的表空间上关联的缓冲池里面创建一条记录。每当记录被更新或者删除的时候,将会从存储空间中取出包含记录的页并且把它拷贝到相应的缓冲池中去,然后它就在这里通过更新或删除得到修改。一旦修正完成,执行的操作的动作将被写进日志缓存---另一个在内存中被设计用于存储的存储空间(为日志缓冲保留的实际内存的数量取决于数据库配置参数logbufsiz的值)。如果执行插入操作,将会写入一条包含新数据行的记录。执行删除,则写入一条包含原始数据行的记录。执行更新,则写入一个既包含原始数据值又包含新的数据行的记录(在多数情况下,更新事务的日志纪录是通过用所在行要更新的值在其的初始值上执行EXCLUSIVE OR来产生)。最后,当执行插入、更新或删除的事务处理结束的时候,相应的落实更新或者落实更新的记录就被写进日志缓冲。
每当缓冲设备I/O 页清除器被激活,日志缓冲暴满或者一个事务处理被落实更新或回滚的时候,储存在日志缓冲器的全部记录会立即被写入存储在磁盘里的一个或多个事务处理日志文件中。如果系统发生错误这些定时刷新的日志缓冲器将会使丢失的日志记录的数量减到最小值。同时记录事务处理的详细的日志纪录(包括相应的落实更新和回滚纪录)将会被顺利地具体到一个或多个日志文件中,这种事务处理带来的影响是它自身被复制到适当表空间容器中用于永久的存储。(修改后的数据页本身仍保留在内存里,这样就可以在需要它们的时候被很快的存取,直到它们被覆盖)。这个过程被称为write-ahead logging,它用于保证为数据做的更改始终在被存储在数据库之前先记录日志文件。(见图1)
由于多重事务处理可能在任意一点上与数据库一起工作,一个单独的日志文件也可能包含属于不同的几个事务处理日志纪录。为了便于追踪日志纪录究竟属于哪个事务处理,每个日志纪录指派了一个专门的与事务处理相关联的事务处理标识符。通过使用事务处理标识符,与这个事务处理相关联的日志纪录可在任何时刻被写入一个或多个日志文件而不影响数据的一致性---最终,终止事务处理操作的落实更新或者回滚操作的纪录将同时被写入日志。
灾难恢复
那么在日志所引起的改变被落实更新之前出现问题会怎样呢?例如,突然断电或者应用程序异常结束的时候。事务处理下的那些尚未落实更新或者回滚的一些工作丢失了。而且,如果落实更新的事务处理在将数据提交到数据库的过程中被中断,数据库将会处于一种不一致、不可用的状态。(一个处于不一致状态下的数据库在每次试图建立连接时候将生成返回代码和错误报告)你不能恢复存储在内从当中的事务处理的纪录,但你可以通过执行一个被称之为灾难性恢复的操作来将数据库恢复为一致性的状态。
最常用的启动灾难性恢复的方法就是在DB2命令行处理器(CLP)中执行RESTART命令。这个命令的基本语法如下:
RESTART [DATABASE | DB]
[DatabaseName]
USER [UserName] < USING
[Password] > >
< DROP PENDING TABLESPACES
( [TS_Name] , ... ) >
< WRITE RESUME >
在这里:
- DatabaseName指名的试图恢复的数据库的名称。
- UserName 指名能使用灾难性恢复的用户的名称。
- Password指名指定用户能使用灾难性恢复的口令。
- TS_Name指名在试图恢复表空间到一致性状态时遇到错误情况下需要设置成为不能工作并处在Drop Pending模式的一个或几个表空间的名称。
注意:(< >)里的参数是可选择的。([ ])的参数或选项是必需的。而(, ...)说明前面的参数可以重复若干次。至于完整的RESTART命令行语法,请参阅IBM DB2 Universal Database, Version 8 Command Reference。
要是你想在SAMPLE数据库上执行灾难性恢复的操作,执行RESTART DATABASE SAMPLE命令。
你也可以把数据库设置成当它处于不一致状态时在用户或程序试图连接它时自动启动灾难性恢复。简单的方法就是将数据库的AUTORESTART配置开关参数设置为ON(DB2数据库管理器每次在它被激活的时候或者试图建立连接的时候去检查数据库的状态。如果数据库处于不一致的状态,那么数据库库管理器在AUTORESTART配置开关参数打开的情况下将会自动执行RESTART命令)。
在灾难恢复过程中,存储在数据库的事务处理日志文件中的纪录经过分析,每一个拥有相应的落实更新纪录的纪录被重新应用于数据库中。
而那些没有相应的落实更新的纪录的纪录被重新运行之后被回收(这就是为什么所有的更新操作的之前和之后的信息都需要记录的原因)。由于日志纪录经常被具体化并且被一个特定的事务所做出的修改仅仅只能在这个事务本身成功结束的时候才会被具体化,因此在发生错误之后把数据库恢复到一致性状态的能力始终是有保障的。
灾难恢复是事务处理日志所提供的众多功能中的一个。在我讲述前滚恢复时,我将介绍怎样运用存储在事务处理日志文件中的纪录及时地把一个数据库恢复到任何一个指定的点上的状态。不过首先,你必需先了解备份镜像和版本恢复的概念,我将在下一专栏中开设这两个专题。
完整版本(包含图片的PDF文件)请到http://hbird.vicp.net/viewthread.php?tid=2387&extra=page%3D1处下载