测试平台:rhel 4.6 and ids10.00uc3r1
相关命令:lsof用于显示打开的文件(list open file),此软件在其他系统中可能需要另行安装.
dd用于覆盖及复制文件(convert and copy a file).
测试例子
在正在运行的数据库服务器中(如下)
[informix@netsky datafile]$ onstat -d
IBM Informix Dynamic Server Version 10.00.UC3R1 -- On-Line -- Up 00:56:19 -- 28228 Kbytes
Dbspaces
address number flags fchunk nchunks pgsize flags owner name
4442e7e0 1 0x1 1 1 2048 N informix rootdbs
4442ec90 2 0x2001 2 1 2048 N T informix tempdbs
4442ede8 3 0x1 3 1 2048 N informix logdbs
44523630 4 0x1 4 1 2048 N informix phydbs
44523788 5 0x1 5 1 2048 N informix workdbs
445238e0 6 0x1 6 1 2048 N informix testdbs0
44523a38 7 0x1 7 1 2048 N informix testdbs1
44523b90 8 0x1 8 1 2048 N informix testdbs2
44523ce8 9 0x1 9 1 2048 N informix testdbs3
44523e40 10 0x1 10 1 2048 N informix testdbs4
10 active, 2047 maximum
Chunks
address chunk/dbs offset size free bpages flags pathname
4442e938 1 1 20 20000 12108 PO-- /opt/informix/datafile/rootdbs
445342f0 2 2 20 20000 19947 PO-- /opt/informix/datafile/tempdbs
44534478 3 3 20 20450 397 PO-- /opt/informix/datafile/logdbs
44534600 4 4 20 20450 19397 PO-- /opt/informix/datafile/phydbs
44534788 5 5 20 51150 39948 PO-- /opt/informix/datafile/workdbs
44534910 6 6 0 20000 19911 PO-- /opt/informix/datafile/testdbs0
44534a98 7 7 0 20000 19947 PO-- /opt/informix/datafile/testdbs1
44534c20 8 8 0 20000 19947 PO-- /opt/informix/datafile/testdbs2
44534da8 9 9 0 20000 19947 PO-- /opt/informix/datafile/testdbs3
4442eb08 10 10 0 20000 19947 PO-- /opt/informix/datafile/testdbs4
10 active, 2047 maximum
NOTE: The values in the "size" and "free" columns for DBspace chunks are
displayed in terms of "pgsize" of the DBspace to which they belong.
Expanded chunk capacity mode: disabled
往testdbs0中增加一些测试数据
informix@netsky ~]$ dbaccess dbmon -
Database selected.
>create table ttt (id char(10)) in testdbs0;
>insert into ttt values('000');
>insert into ttt values('111');
做onmode -c强制完全checkpoint,把数据刷回磁盘.
然后删除数据块testdbs0
[informix@netsky datafile]$ ll
drwxrwxr-x 2 informix informix 4096 Nov 27 06:06 bakup
-rw-rw---- 1 informix informix 41922560 Feb 10 00:06 logdbs
-rw-rw---- 1 informix informix 41922560 Feb 9 23:14 phydbs
-rw-rw---- 1 informix informix 41000960 Feb 10 00:06 rootdbs
-rw-rw---- 1 informix informix 41000960 Feb 9 23:17 tempdbs
-rw-rw---- 1 informix informix 40960000 Nov 27 06:01 testdbs1 --testdbs0被删除.
-rw-rw---- 1 informix informix 104796160 Feb 9 23:13 workdbs
此时可以通过lsof查找数据库打开的文件testdbs0,可以看到该文件已经被标识删除了.
[root@netsky datafile]# lsof | egrep '(COMMAND|deleted)'
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
oninit 23864 root 261u REG 253,0 40960000 620162 /opt/informix/datafile/testdbs0 (deleted)
oninit 23868 root 258u REG 253,0 40960000 620162 /opt/informix/datafile/testdbs0 (deleted)
此时再查看testdbs0上的数据,并往testdbs0中增加一些数据.
informix@netsky ~]$ dbaccess dbmon -
Database selected.
> select * from ttt;
id
000
111
2 row(s) retrieved.
> insert into ttt values('333');
1 row(s) inserted.
做onmode -c强制完全checkpoint,把数据刷回磁盘.
然后把已经删除的testdbs0恢复出来备份.
在这里,结合lsof的输出信息PID进入相应的目录,再通过FD号进行dd恢复.
[root@netsky fd]# cd /proc/23864/fd
[root@netsky fd]# ll
total 13
lr-x------ 1 root root 64 Feb 9 23:36 0 -> /opt/informix/msg/en_us/0333/olmsglog.iem
lrwx------ 1 root root 64 Feb 9 23:36 1 -> /dev/pts/2
lrwx------ 1 root root 64 Feb 9 23:36 2 -> /dev/pts/2
lrwx------ 1 root root 64 Feb 9 23:36 256 -> /opt/informix/datafile/rootdbs
lrwx------ 1 root root 64 Feb 9 23:36 257 -> /opt/informix/datafile/tempdbs
lrwx------ 1 root root 64 Feb 9 23:36 258 -> /opt/informix/datafile/logdbs
lrwx------ 1 root root 64 Feb 9 23:36 259 -> /opt/informix/datafile/phydbs
lrwx------ 1 root root 64 Feb 9 23:36 260 -> /opt/informix/datafile/workdbs
lrwx------ 1 root root 64 Feb 9 23:36 261 -> /opt/informix/datafile/testdbs0 (deleted)
lrwx------ 1 root root 64 Feb 9 23:36 262 -> /opt/informix/datafile/testdbs1
lrwx------ 1 root root 64 Feb 9 23:36 263 -> /opt/informix/datafile/testdbs2
lrwx------ 1 root root 64 Feb 9 23:36 264 -> /opt/informix/datafile/testdbs3
lrwx------ 1 root root 64 Feb 9 23:36 265 -> /opt/informix/datafile/testdbs4
这里在PID 23864的FD(File Descriptor)为261即为我们所要的.将其dd出来到/tmp/testdbs0
[root@netsky fd]# dd if=261 of=/tmp/testdbs0
80000+0 records in
80000+0 records out
完成以上操作后,停止数据库.
[informix@netsky datafile]$ onmode -ky
将恢复的数据文件拷回原目录,并修改权限
[informix@netsky datafile]$ cp /tmp/testdbs0 /opt/informix/datafile/testdbs0
[informix@netsky datafile]$ chmod 660 testdbs0 ;chown informix:informix testdbs0
重新启动数据库
[informix@netsky datafile]$ oninit -vy
验证数据文件恢复.
[informix@netsky datafile]$ dbaccess dbmon -
Database selected.
> select * from ttt;
id
000
111
333
3 row(s) retrieved.
例子验证,在testdbs0被删除后,文件被删除后,数据上并未完全删除的,只是其inode信息在系统上被删除.但正在使用其的程序仍保留了这个inode信息,程序仍可以往里面写入信息..在程序关闭前,可通过FD(File Descriptor)的方式进行恢复.
注意:要求的是文件必须仍被打开..这样的操作并不是十分保险的,可能会造成数据损坏或者缺少.
-rw-rw---- 1 informix informix 40960000 Nov 27 06:01 testdbs2
-rw-rw---- 1 informix informix 40960000 Nov 27 06:01 testdbs3
-rw-rw---- 1 informix informix 40960000 Nov 27 06:01 testdbs4