作者 · 2010-12-30 10:32
·

恢复已删除的表

字数 7427 阅读 2308 评论 1 赞 0
恢复已删除的表 (Dropped Table Recovery)

我们在维护 DB2 数据库的过程中,偶尔会发生误删除表( DROP TABLE )的操作,这种误操作和删除表中的数据不一样。误删除数据,对于归档日志管理模式的数据库来说,可以通过前滚恢复来恢复数据,而误删除表则需要在前滚恢复 的时候加上“ recover dropped table tableid to target_dir ”选项,具体的步骤如下:

   1. 确保数据库可以进行前滚恢复( DB2 V9 之前的版本要保证数据库配置参数 logretain 或 userexit 打开, DB2 V9 则除了打开 logretain 或 userexit 参数可以把数据库改成归档管理模式,还可以通过修改 logarchmeth1 数据库配置参数来更改日志管理模式)。注意,需要在误删除表操作发生之前,数据库已经处于归档日志管理模式状态。
   2. 确保要被恢复的表所在的表空间“允许已废弃的表可恢复”, 在 DB2 V9 之前版本的数据库中,仅限常规表空间( regular tablespace ),在 DB2 V9 的版本中,由于对大型表空间做了修改,已经用来替代 V9 之前版本的常规表空间,所以,大型表空间也可以“允许已废弃的表可恢复”。如果误删除的表所在的表空间没有启用“允许已废弃的表可恢复”功能,可以通过命 令启用这个功能:
      ALTER TABLESPACE表空间名DROPPED TABLE RECOVERY ON
   3. 通过发出 “ list history dropped table all for 数据库名”命令,得到被删除表的 tableid 和表结构的 DDL 语句。记录下 tableid 和 DDL 语句,以便我们在第四步操作以及以后的恢复操作中使用。
   4. 利用误删除操作发生之前的数据库全备恢复数据库。
   5. 前滚数据库,在前滚时加上“ recover dropped table tableid to target_dir ”选项,其中 tableid 是第三步中得到的 tableid , target_dir 表示目的目录(在此目录中,将会创建 ../NODE000X/data 文件)用来存放误删除表中的数据。
   6. 利用第三步得到的 DDL 语句创建误删除的表,并将第五步中 target_dir 目录中的文件导入数据到表中。

下面我们通过具体的例子来看一下如何恢复已经删除的表。

首先我们需要把示例数据库 SAMPLE 的日志模式改成归档模式。下面在 DB2CLP 窗口中,先发出“ CONNECT TO SAMPLE ”命令,连上示例数据库 SAMPLE ,再发出“ UPDATE DATABASE CONFIGURATION USING LOGARCHMETH1 DISK:C:DB2IMMEDIATE ”命令,修改数据库配置参数 LOGARCHMETH1 ,使其自动归档日志到 C 盘 DB2 目录下,具体如清单 14 所示:

清单 14 . 修改示例数据库 SAMPLE 的配置参数

C:> db2 connect to sample

数据库连接信息

数据库服务器 = DB2 / NT 9.1.0
SQL 授权标识 = RHETTE
本地数据库别名 = SAMPLE

C:> DB2 UPDATE DATABASE CONFIGURATION USING LOGARCHMETH1 DISK:C:DB2IMMEDIATE
DB20000IUPDATE DATABASE CONFIGURATION 命令成功完成。
SQL1363W 未动态更改为立即修改而提交的一个或多个参数。对于这些配置参数,必须在所有应用程序都与此数据库断开连接之后,更改才会生效。


命令执行成功,这样我们就把示例数据库 SAMPLE 的日志模式改成了归档。在清单 14 中的命令执行成功后,由于 LOGARCHMETH1 配置参数更改成功后,需要等数据库上所有的连接都断开后才会生效,所以我们在 DB2CLP 窗口中,发出“ FORCE   APPLICATIONS ALL ”命令断开所有的连接,具体如清单 15 所示:

清单 15. 断开所有应用程序连接

C:> DB2 FORCE APPLICATIONS ALL
DB20000IFORCE APPLICATION 命令成功完成。
DB21024I 该命令为异步的,可能不会立即生效。


命令成功后,用 LIST   APPLICATIONS 看所有应用程序是否都断开了,如果没有断开,再重复执行 FORCE APPLICATIONS ALL ,保证所有连接都断开后,把数据库做一次全备。在我们首次把数据库的日志模式由循环模式改成归档模式后,数据库会处于 BACKUP   PENDING 状态,强制我们进行一次全量备份,在全量备份完成之前,不能访问数据库或表空间。

下面我们继续在 DB2CLP 窗口中,发出“ BACKUP DB SAMPLE ”命令,全量备份示例数据库 SAMPLE ,具体如清单 16 所示:

清单 16 . 对示例数据库做一次全备

C:> DB2 LIST   APPLICATIONS
DB21034E 该命令被当作 SQL 语句来处理,因为它是无效的“命令行处理器”命令。在
SQL 处理期间,它返回:
SQL1224N 由于错误或强制中断,导致数据库管理器不能接受新请求,已终止正在处理的所有请求,或者已终止特定请求。 SQLSTATE = 55032

C:> db2 backup db sample

备份成功。此备份映像的时间戳记是:20080405000129


备份成功完成,备份映像文件的时间戳记为 20080405000129 。

下面我们继续在当前 DB2CLP 窗口中,发出“ CONNECT TO SAMPLE ”命令,连上示例数据库 SAMPLE ,再发出“ db2 create table newtest2 ( id int , name varchar(10) ) ” 创建示例表 NEWTEST2 ,并插入 2 条记录,然后删除掉表 NEWTEST2 ,具体如清单 17 所示:

清单 17. 创建示例表 NEWTEST2,并删除掉

C:> db2 connect to sample

数据库连接信息

数据库服务器 = DB2 / NT 9.1.0
SQL 授权标识 = RHETTE
本地数据库别名 = SAMPLE

C:> db2 create table newtest2 ( id int , name varchar(10) )
DB20000ISQL 命令成功完成。

C:> db2 insert into newtest2values ( 1 ,'aa' )
DB20000ISQL 命令成功完成。

C:> db2 insert into newtest2values ( 2 ,'bb' )
DB20000ISQL 命令成功完成。

C:>db2 drop table newtest2
DB20000ISQL 命令成功完成。


命令成功完成。下面我们来把已经删除的表 NEWTEST2 恢复。参照本小节开头的步骤,第一步确保数据库已经处于归档管理模式已经完成,第二步,确保误删除表所在的表空间启用了“允许已废弃的表可恢复”也已经完 成( IBMDB2SAMPLEREL 默认已经启用“允许已废弃的表可恢复”功能),

下面我们来进行第三步的操作。继续在当前 DB2CLP 窗口中,通过发出 “ list history dropped table all for 数据库名”命令,得到被删除表 NEWTEST2 的 tableid 为“ 000000000000cdd200030020 ”和表结构的 DDL 语句。记录下 tableid 和 DDL 语句,以便我们在第四步操作以及以后的恢复操作中使用。具体如清单 18 所示:

清单 18 . 第三步,得到被删除表 NEWTEST2 的 tableid 和表结构的 DDL 语句

C:> db2 list history dropped table all for sample

列示 sample 的历史记录文件

匹配的文件条目数 = 1


Op 对象 时间戳记 + 序列类型 设备 最早日志当前日志备份标识
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
D T 20080405002004000000000000cdd200030020
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
"RHETTE"."NEWTEST2" 驻留在 1 表空间中:

00001 IBMDB2SAMPLEREL
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
注释:DROP TABLE
开始时间:20080405002004
结束时间:20080405002004
状态:A
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

EID:95

DDL: CREATE TABLE "RHETTE"."NEWTEST2" ( "ID" INTEGER , "NAME" VARCHAR(10) )
IN "IBMDB2SAMPLEREL" ;
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


下面我来做第四步。

利用之前清单 16 所在数据库全备生成的备份映像文件(时间戳记为 20080405000129 ) 恢复示例数据库 SAMPLE 。我们继续在当前 DB2CLP 窗口,发出“ FORCE APPLICATIONS ALL ”命令,停掉示例数据库 SAMPLE 上所有的连接,再发出“ db2 restore db sample taken at 20080405000129 ”命令恢复数据库,还原的过程中,会提示“ SQL2539W 警告!正在复原至与备份映像数据库相同的现有数据库。数据库文件将被删除。想要继续吗?( y / n )”,这时候输入 “ y ”,也就是“是”的意思,回车。具体如清单 19 所示:

清单 19. 第四步,恢复示例数据库 SAMPLE

C:> db2 force applications all
DB20000IFORCE APPLICATION 命令成功完成。
DB21024I 此命令为异步的,可能未能立即生效。


C:> db2 restore db sample taken at 20080405000129
SQL2539W 警告!正在复原至与备份映像数据库相同的现有数据库。数据库文件将被删除。

想要继续吗?( y / n ) y
DB20000IRESTORE DATABASE 命令成功完成。


命令成功完成。

下面我们继续来做第五步,前滚数据库。

继续在当前 DB2CLP 窗口中,利用第三步得到的 tableid ( 000000000000cdd200030020 )发出前滚恢复命令“ db2 rollforward db sample to end of logs and stop recover dropped table 000000000000cdd200030020 to c:db2 ”,具体如清单 20 所示:

清单 20. 第五步,前滚恢复示例数据库 SAMPLE

C:> db2 rollforward db sample to end of logs and stop recover dropped
            table 000000000000cdd200030020 to c:db2

前滚状态

输入数据库别名 = sample
节点数已返回状态 = 1

节点号 = 0
前滚状态 = 未暂挂
下一个要读取的日志文件 =
已处理的日志文件 = S0000000.LOG - S0000000.LOG
上次落实的事务 = 2008-04-04-16.37.26.000000 UTC

DB20000IROLLFORWARD 命令成功完成。


命令成功完成。误删除表 NEWTEST2 的数据被导入到了 C:DB2NODE0000data 文件中。

下面我们来进行第六步,也是最后一步。

继续在当前 DB2CLP 窗口中,发出“ CONNECT TO SAMPLE ”命令,连上示例数据库 SAMPLE ,再利用第三步得到的表 NEWTEST2 的 DDL 语句重新创建表 NEWTEST2 ,再从 C:DB2NODE0000data 文件导入数据,具体如清单 21 所示:

清单 21. 第六步,重新创建表 NEWTEST2,再从 ..NODE0000data 文件导入数据

C:> db2 connect to sample

数据库连接信息

数据库服务器 = DB2/NT 9.1.0
SQL 授权标识 = RHETTE
本地数据库别名 = SAMPLE


C:> db2CREATE TABLE "RHETTE"."NEWTEST2" ( "ID" INTEGER , "NAME" VARCHAR(10) )
             IN "IBMDB2SAMPLEREL"
DB20000ISQL 命令成功完成。

C:> db2 import from C:DB2NODE0000data of del insert into newtest2
SQL3109N 实用程序正在开始从文件 "C:DB2NODE0000data" 装入数据。

SQL3110N 实用程序已完成处理。从输入文件读了 " 2 " 行。

SQL3221W. . . 开始 COMMIT WORK 。输入记录计数 = " 2 " 。

SQL3222W. . . 对任何数据库更改的 COMMIT 都成功。

SQL3019N 处理了输入文件中的 " 2 " 行。已将 " 2 " 行成功插入表中。拒绝了 " 0 " 行。


读取行数 = 2
跳过行数 = 0
插入行数 = 2
更新行数 = 0
拒绝行数 = 0
落实行数 = 2


C:> db2 select * from newtest2

IDNAME
- - - - - - - - - - - - - - - - - - - - -
1        aa
2        bb

2 条记录已选择。


命令成功完成。至此,我们已经完成了六步全部操作,被误删除的表 NEWTEST2 已经成功的恢复,数据也成功的导入其中。

需要注意的是,对可从已废弃的表中复原的数据类型有一些限制,下列类型不可能复原:

   1. 大对象( LOB )或长型字段数据。对于大型表空间,不支持 DROPPED TABLE RECOVERY 选项。如果尝试复原包含 LOB 或 LONG VARCHAR 列的已废弃的表,这些列将在生成的导出文件中设置为 NULL 。仅可对常规表空间使用 DROPPED TABLE RECOVERY 选项,而不能对临时或大型表空间使用。
   2. 与行类型相关的元数据。(数据已复原,但不是元数据。)将复原有类型表的层次结构表中的数据。此数据包含的信息可能比已废弃的类型表中的信息多。
   3. XML 数据。如果尝试恢复包含 XML 数据的已废弃的表,那么相应的列数据将为空。

如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!

0

添加新评论1 条评论

start2000 start2000 系统架构师ABB
2010-12-31 16:08
好!
Ctrl+Enter 发表

作者其他文章

相关文章

相关问题

相关资料

X社区推广