情形:
实例test下的testdb数据库其中TS2表空间有2张表tb1和tb2,在一次全备份后,
误删除了tb2表,如何恢复tb2表,且能不影响和丢失tb1和其他表空间的数据呢?
第一:循环日志模式,直接恢复到全备份时间点,那么则丢失备份点后的全部数据;
第二:归档日志模式,数据库恢复+rollforward,恢复数据库到备份时间点,并且
前滚到tb2删除时间前,那么则丢失tb2表删除时间点后的数据;
第三:归档日志模式下的,表空间恢复+rollforward,但表空间的恢复最小的时间点是系统目录
对表空间或其中表最后一次更新操作时间,也就是表空间或其中表最后的一次DDL语句
(create/alter/delete等)时间,所以上面情况表空间最多只能rollforward到tb2表删除后
的时间点,所以表空间恢复+rollforward不能帮助恢复tb2表。
查看表空间的最小需要前滚时间点:
[test@demo NODE0000]$ db2 "select substr(tablespace_name,1,15) as ts_name,min_recovery_time from table (snapshot_tbs_cfg('TESTDB',-1)) as a"
TS_NAME MIN_RECOVERY_TIME
--------------- --------------------------
SYSCATSPACE -
TEMPSPACE1 -
USERSPACE1 2019-01-06-15.58.23.000000
SYSTOOLSPACE - TS2 2019-01-06-16.05.36.000000
5 record(s) selected.
有没有什么办法可以:恢复了tb2表,并且不影响TS2表空间中的其他表tb1和其他表空间的数据呢?
DB2提供了dropped table recovery来获取误删表的定义和删除之前的数据,如此便可重建该表。
1.新建一个表空间ts2
[test@demo SQL00001]$ db2 "create tablespace ts2 managed by database using (file '/home/test/file' 10M)"
2.在表空间ts2上创建两张表tb1和tb2
db2 "create table tb1(id int,name varchar(10)) in ts2 "
db2 "insert into tb1 values(1,'yo1'),(2,'yo2'),(3,'yo3')"
db2 "create table tb2(id int,name varchar(10)) in ts2"
db2 "insert into tb2 values(1,'yo1'),(2,'yo2')"
可以从syscat.tables系统表视图查看:表属于哪个表空间
[test@demo db2cfg]$ db2 "select tabname, tbspace from syscat.tables"|grep -E '^TB'
tabname tbspace
TB1 TS2
TB2 TS2
3.打开表空间的dropped table recovery,默认是打开的,如果没打开,需要打开如下
db2 "alter tablespace ts2 dropped table recovery on "
4.发起online备份
[test@demo db2cfg]$ db2 backup db testdb online
Backup successful. The timestamp for this backup image is : 20190106151138
5.往tb2表里继续添加一些数据后,删除tb2表
[test@demo db2cfg]$ db2 "insert into tb2 values(6,'yo6') "
DB20000I The SQL command completed successfully.
[test@demo db2cfg]$ db2 "select * from tb2"
ID NAME
----------- ----------
1 yo1
2 yo2
6 yo6
3 record(s) selected.
[test@demo db2cfg]$ db2 drop table tb2
DB20000I The SQL command completed successfully.
[test@demo db2cfg]$ db2 list tables
Table/View Schema Type Creation time
------------------------------- --------------- ----- --------------------------
TB1 TEST T 2019-01-06-14.43.25.599076
1 record(s) selected.
6.删除tb2表后,往tb1表继续插入一些数据:
[test@demo db2cfg]$ db2 "insert into tb1 values(6,'yo6') "
DB20000I The SQL command completed successfully.
[test@demo db2cfg]$ db2 "select * from tb1"
ID NAME
----------- ----------
1 yo1
2 yo2
3 yo3
6 yo6
4 record(s) selected.
7.查看历史文件中关于dropped table的信息,
获取误删表的定义和 Backup ID:
[test@demo db2cfg]$ db2 list history dropped table all for testdb
List History File for testdb
Number of matching file entries = 1
Op Obj Timestamp+Sequence Type Dev Earliest Log Current Log Backup ID
-- --- ------------------ ---- --- ------------ ------------ --------------
D T 20190106151240 000000000000320200040004
----------------------------------------------------------------------------
"TEST "."TB2" resides in 1 tablespace(s):
00001 TS2
----------------------------------------------------------------------------
Comment: DROP TABLE
Start Time: 20190106151240
End Time: 20190106151240
Status: A
----------------------------------------------------------------------------
EID: 8
DDL: CREATE TABLE "TEST "."TB2" ( "ID" INTEGER , "NAME" VARCHAR(10) ) IN "TS2" ; --->获取表的定义
----------------------------------------------------------------------------
8.从备份里面恢复单个表空间ts2
[test@demo db2cfg]$ db2 "restore db testdb tablespace(ts2) taken at 20190106151138"
DB20000I The RESTORE DATABASE command completed successfully.
9.前滚表空间时指定从上面获取到的backup id,并把表数据导出到/db2cfg目录下
[test@demo db2cfg]$ db2 "rollforward db testdb to end of logs tablespace(ts2) recover dropped table 000000000000320200040004 to /db2cfg"
Rollforward Status
Input database alias = testdb
Number of nodes have returned status = 1
Node number = 0
Rollforward status = not pending
Next log file to be read =
Log files processed = -
Last committed transaction = 1970-01-01-00.00.00.000000 UTC
DB20000I The ROLLFORWARD command completed successfully.
查看导出的数据正是误删表的数据,包括备份之后再添加的数据:
[test@demo db2cfg]$ ls
NODE0000 test TESTDB.0.test.NODE0000.CATN0000.20190106151138.001
[test@demo db2cfg]$ cd NODE0000/
[test@demo NODE0000]$ ls
data
[test@demo NODE0000]$ cat data
1,"yo1"
2,"yo2"
6,"yo6"
10.表空间前滚结束后,表tb1数据不受影响并且是最新状态
[test@demo db2cfg]$ db2 "select * from tb1"
ID NAME
----------- ----------
1 yo1
2 yo2
3 yo3
6 yo6
4 record(s) selected.
11.由上面获取到的tb2的定义和数据来重建tb2表
[test@demo db2cfg]$ cat tb2.ddl
CREATE TABLE "TEST "."TB2" ( "ID" INTEGER , "NAME" VARCHAR(10) ) IN "TS2";
[test@demo db2cfg]$ db2 -tvf tb2.ddl
CREATE TABLE "TEST "."TB2" ( "ID" INTEGER , "NAME" VARCHAR(10) ) IN "TS2"
DB20000I The SQL command completed successfully.
[test@demo NODE0000]$ db2 import from /db2cfg/NODE0000/data of del insert into tb2
SQL3109N The utility is beginning to load data from file
"/db2cfg/NODE0000/data".
SQL3110N The utility has completed processing. "3" rows were read from the
input file.
SQL3221W ...Begin COMMIT WORK. Input Record Count = "3".
SQL3222W ...COMMIT of any database changes was successful.
SQL3149N "3" rows were processed from the input file. "3" rows were
successfully inserted into the table. "0" rows were rejected.
Number of rows read = 3
Number of rows skipped = 0
Number of rows inserted = 3
Number of rows updated = 0
Number of rows rejected = 0
Number of rows committed = 3
[test@demo db2cfg]$ db2 "select * from tb2"
ID NAME
----------- ----------
1 yo1
2 yo2
6 yo6
3 record(s) selected.