注册
Linux环境下误删达梦数据库表空间文件恢复两法
培训园地/ 文章详情 /

Linux环境下误删达梦数据库表空间文件恢复两法

爞爞 2023/04/23 1781 2 0

在Linux环境下,不小心删除了达梦数据库表空间文件,导致表空间为离线状态,从而影响数据库正常工作。对于DBA而言,数据恢复是必备的基本功,在此以一个例子来说明如何恢复,本文操作都用命令行操作完成。

1、环境说明

测试环境为虚拟机,操作系统为麒麟Linux高级服务器版,达梦数据库为DM8 (dm8_20220525_x86_rh6_64) ,具体版本信息如下:

操作系统版本信息:

# cat /etc/os-release NAME="Kylin Linux Advanced Server" VERSION="V10 (Lance)" ID="kylin" VERSION_ID="V10" PRETTY_NAME="Kylin Linux Advanced Server V10 (Lance)" ANSI_COLOR="0;31"

达梦数据库版本信息:

$ disql sysdba/SYSDBA:5236 服务器[LOCALHOST:5236]:处于普通打开状态 登录使用时间 : 10.199(ms) disql V8 SQL> select * from v$version; 行号 BANNER ---------- --------------------------------- 1 DM Database Server 64 V8 2 DB Version: 0x7000c 3 03134283890-20220525-161267-10045 已用时间: 2.921(毫秒). 执行号:500.

2、初始化数据库及基础数据

为避免影响现有学习环境,因此单独创建一个实例来进行演示说明,我的数据库安装位置为/dm8,具体数据库软件的安装则不再演示。

2.1创建测试实例及数据库

su - dmdba cd /dm8/bin ./dminit path='/dm8/data' db_name='DMTMP' instance_name='TMPINST' sysdba_pwd=Dameng123 port_num=5238 page_size=8 --数据库创建在/dm8/data/DMTMP initdb V8 db version: 0x7000c file dm.key not found, use default license! License will expire on 2023-05-25 Normal of FAST Normal of DEFAULT Normal of RECYCLE Normal of KEEP Normal of ROLL log file path: /dm8/data/DMTMP/DMTMP01.log log file path: /dm8/data/DMTMP/DMTMP02.log write to dir [/dm8/data/DMTMP]. create dm database success. 2023-04-19 13:43:31 ## 创建完成后,启动数据库实例(本演示不创建系统服务,仅以前台启动演示) $ /dm8/bin/dmserver /dm8/data/DMTMP/dm.ini file dm.key not found, use default license! version info: develop DM Database Server 64 V8 03134283890-20220525-161267-10045 startup... ... ...(略) pseg_crash_trx_rollback end SYSTEM IS READY. ## 检查数据库服务是否在侦听5238端口(建库时指定的端口) ## 在另外一个终端中执行下面的命令进行检查 $ netstat -antlp|grep -i listen (Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.) tcp 0 0 0.0.0.0:5901 0.0.0.0:* LISTEN - tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN - tcp6 0 0 :::4236 :::* LISTEN 1313/dmap tcp6 0 0 :::5901 :::* LISTEN - tcp6 0 0 :::5236 :::* LISTEN 43860/dmserver tcp6 0 0 :::5238 :::* LISTEN 44204/dmserver ###这个就是我新创建的演示实例 tcp6 0 0 :::22 :::* LISTEN -

2.2测试实例登录验证

$ disql sysdba/Dameng123:5238 服务器[LOCALHOST:5238]:处于普通打开状态 登录使用时间 : 3.367(ms) disql V8 SQL> select * from v$instance; 行号 NAME INSTANCE_NAME INSTANCE_NUMBER HOST_NAME SVR_VERSION DB_VERSION START_TIME STATUS$ MODE$ OGUID DSC_SEQNO DSC_ROLE BUILD_VERSION ---------- ------- ------------- --------------- --------- -------------------------- ------------------- ------------------- ------- ------ ----------- ----------- -------- ---------------------------------- BUILD_TIME -------------------- 1 TMPINST TMPINST 1 KylinDCA1 DM Database Server x64 V8 DB Version: 0x7000c 2023-04-19 13:50:25 OPEN NORMAL 0 0 NULL 1-2-114-22.05.25-161267-10045-ENT May 25 2022 11:22:12 已用时间: 18.921(毫秒). 执行号:55200. SQL> select * from v$database; 行号 NAME CREATE_TIME ARCH_MODE LAST_CKPT_TIME STATUS$ ROLE$ MAX_SIZE TOTAL_SIZE DSC_NODES OPEN_COUNT STARTUP_COUNT LAST_STARTUP_TIME ---------- ----- ------------------- --------- ------------------- ----------- ----------- -------------------- -------------------- ----------- ----------- -------------------- ------------------- 1 DMTMP 2023-04-19 13:43:30 N 2023-04-19 13:56:26 4 0 0 20992 1 1 1 2023-04-19 13:50:30 已用时间: 1.036(毫秒). 执行号:55201.

2.3开启归档模式

-- 在disql中执行 -- 开启归档 alter database mount; alter database ARCHIVELOG; alter database ADD ARCHIVELOG 'type=local, dest=/dm8/arch2,file_size=64,space_limit=10240'; -- 归档路径为/dm8/arch2 alter DATABASE OPEN; select arch_mode from v$database; 行号 ARCH_MODE ---------- --------- 1 Y 已用时间: 1.958(毫秒). 执行号:55202.

目前数据库已经是归档模式,归档文件存放位置为/dm8/arch2

2.4创建测试用表空间及验证表

创建表空间:

create tablespace TBS1 DATAFILE 'TBS01.DBF' size 32; SQL> select PATH,CREATE_TIME from v$datafile; 行号 PATH CREATE_TIME ---------- -------------------------- ------------------- 1 /dm8/data/DMTMP/SYSTEM.DBF 2023-04-19 13:43:30 2 /dm8/data/DMTMP/ROLL.DBF 2023-04-19 13:43:30 3 /dm8/data/DMTMP/TEMP.DBF 2023-04-19 13:50:25 4 /dm8/data/DMTMP/MAIN.DBF 2023-04-19 13:43:30 5 /dm8/data/DMTMP/TBS01.DBF 2023-04-19 14:14:13 -- 新创建的表空间文件 已用时间: 1.187(毫秒). 执行号:55205.

创建测试表:

create table mytable(id int, name VARCHAR(20)) TABLESPACE TBS1; insert into mytable(id,name) values(1,'赵'); insert into mytable(id,name) values(2,'钱'); insert into mytable(id,name) values(3,'孙'); insert into mytable(id,name) values(4,'李'); insert into mytable(id,name) values(5,'周'); insert into mytable(id,name) values(6,'吴'); commit; select * from mytable; 行号 ID NAME ---------- ----------- ---- 1 12 23 34 45 56 66 rows got 已用时间: 1.421(毫秒). 执行号:55214.

3、数据库备份

3.1全备份

虽然本次恢复两法中,不会用全备份进行恢复,但为了养成好习惯,还是先来个全备份,归档也来个备份。

-- 全备份 disql中执行 SQL> BACKUP DATABASE FULL TO FULLBAK10 BACKUPSET '/dm8/backup/full/FULLBAK10' ; -- [-8117]:等待归档刷盘,请稍后重试. -- 遇到这个情况,我处理是把数据库重启下,估计是因为修改归档后没有重启数据库。 -- 查看备份是否存在{结果还把另外一个实例的备份给找出来了} SQL> SF_BAKSET_BACKUP_DIR_ADD('DISK','/dm8/backup/full'); SQL> select DEVICE_TYPE,BACKUP_PATH,OBJECT_NAME,BACKUP_TIME from SYS."V$BACKUPSET" order BY BACKUP_TIME desc; 行号 DEVICE_TYPE BACKUP_PATH OBJECT_NAME BACKUP_TIME ---------- ----------- -------------------------- ----------- -------------------------- 1 DISK /dm8/backup/full/FULLBAK10 DMTMP 2023-04-19 14:46:42.562072 -- DMTMP的全库备份 2 DISK /dm8/backup/full/FULLBAK02 DMDB 2023-04-19 12:28:17.869941 3 DISK /dm8/backup/full/FULLBAK01 DMDB 2023-04-18 16:04:20.590783 已用时间: 31.062(毫秒). 执行号:506.

3.2表空间备份

SQL> BACKUP TABLESPACE TBS1 to TBS1BAK11 BACKUPSET '/dm8/backup/full/TBS1BAK11'; 操作已执行 已用时间: 00:00:05.475. 执行号:507. SQL> select DEVICE_TYPE,BACKUP_PATH,OBJECT_NAME,BACKUP_TIME from SYS."V$BACKUPSET" order BY BACKUP_TIME desc; 行号 DEVICE_TYPE BACKUP_PATH OBJECT_NAME BACKUP_TIME ---------- ----------- -------------------------- ----------- -------------------------- 1 DISK /dm8/backup/full/TBS1BAK11 TBS1 2023-04-19 15:04:17.417713 -- 多了个表空间的备份 2 DISK /dm8/backup/full/FULLBAK10 DMTMP 2023-04-19 14:46:42.562072 3 DISK /dm8/backup/full/FULLBAK02 DMDB 2023-04-19 12:28:17.869941 4 DISK /dm8/backup/full/FULLBAK01 DMDB 2023-04-18 16:04:20.590783 已用时间: 28.842(毫秒). 执行号:508.

3.3归档日志备份

SQL> BACKUP ARCHIVE LOG ALL to ARCHIVEBAK12 BACKUPSET '/dm8/backup/full/ARCHIVEBAK12' ; -- 归档日志备份 操作已执行 已用时间: 00:00:05.759. 执行号:510. SQL> select DEVICE_TYPE,BACKUP_PATH,OBJECT_NAME,BACKUP_TIME from SYS."V$BACKUPSET" order BY BACKUP_TIME desc; 行号 DEVICE_TYPE BACKUP_PATH OBJECT_NAME BACKUP_TIME ---------- ----------- ----------------------------- ----------- -------------------------- 1 DISK /dm8/backup/full/ARCHIVEBAK12 ARCHIVE 2023-04-19 15:22:52.356470 -- 新增一个归档日志备份 2 DISK /dm8/backup/full/TBS1BAK11 TBS1 2023-04-19 15:04:17.417713 3 DISK /dm8/backup/full/FULLBAK10 DMTMP 2023-04-19 14:46:42.562072 4 DISK /dm8/backup/full/FULLBAK02 DMDB 2023-04-19 12:28:17.869941 5 DISK /dm8/backup/full/FULLBAK01 DMDB 2023-04-18 16:04:20.590783 已用时间: 30.748(毫秒). 执行号:511.

以上通过disql执行的备份,都是联机热备份。

4、模拟故障及还原恢复

故障发生前,我们先看下目前数据库的魔数和唯一魔数信息

SQL> select 'db_magic' "参数",db_magic as "值" union ALL select 'permanent_magic',permanent_magic; 行号 参数 值 ---------- --------------- -------------------- 1 db_magic 754488622 2 permanent_magic 458133940 已用时间: 1.188(毫秒). 执行号:509.

4.1模拟故障

$ cd /dm8/data/DMTMP $ ls -l 总用量 856156 drwxr-xr-x 2 dmdba dinstall 6 4月 19 13:43 bak drwxr-xr-x 2 dmdba dinstall 258 4月 19 14:46 ctl_bak -rw-r--r-- 1 dmdba dinstall 338 4月 19 14:03 dmarch.ini -rw-r--r-- 1 dmdba dinstall 6144 4月 19 14:46 dm.ctl -rw-r--r-- 1 dmdba dinstall 59132 4月 19 14:03 dm.ini -rw-r--r-- 1 dmdba dinstall 895 4月 19 13:43 dminit20230419134328.log -rw-r--r-- 1 dmdba dinstall 633 4月 19 13:43 dm_service.prikey -rw-r--r-- 1 dmdba dinstall 268435456 4月 19 15:27 DMTMP01.log -rw-r--r-- 1 dmdba dinstall 268435456 4月 19 14:46 DMTMP02.log drwxr-xr-x 2 dmdba dinstall 6 4月 19 13:43 HMAIN -rw-r--r-- 1 dmdba dinstall 134217728 4月 19 13:43 MAIN.DBF -rw-r--r-- 1 dmdba dinstall 12 4月 19 13:50 rep_conflict.log -rw-r--r-- 1 dmdba dinstall 134217728 4月 19 15:25 ROLL.DBF -rw-r--r-- 1 dmdba dinstall 481 4月 19 13:43 sqllog.ini -rw-r--r-- 1 dmdba dinstall 27262976 4月 19 14:46 SYSTEM.DBF -rw-r--r-- 1 dmdba dinstall 33554432 4月 19 14:30 TBS01.DBF -rw-r--r-- 1 dmdba dinstall 10485760 4月 19 14:46 TEMP.DBF drwxr-xr-x 2 dmdba dinstall 6 4月 19 13:50 trace $ rm -f TBS01.DBF

在disql中检查文件被删除后表空间及表数据

SQL> select * from mytable; 行号 ID NAME ---------- ----------- ---- 1 12 23 34 45 56 66 rows got 已用时间: 1.193(毫秒). 执行号:512. SQL> SP_FILE_SYS_CHECK(); -- 执行系统文件检查 DMSQL 过程已成功完成 已用时间: 0.658(毫秒). 执行号:513. SQL> select * from mytable; select * from mytable; -- 无法查询到表数据 [-3433]:表空间处于脱机状态. 已用时间: 0.308(毫秒). 执行号:0.

4.2还原恢复方法一

这个方法利用数据库备份来进行还原恢复,因为是表空间文件意外被删除,我们首先用表空间还原恢复法。此种方法,前提是开启了归档和有备份

第一步:表空间还原

利用之前备份的表空间备份,进行还原。要还原表空间,首先要关闭数据库实例,然后进入到dmrman中进行操作,否则在dmrman中会报告下面的错误:
-137:服务器正在运行或者存在其他进程正在操作同一个库

$ ./dmrman dmrman V8 RMAN> RESTORE database '/dm8/data/DMTMP/dm.ini' TABLESPACE TBS1 FROM BACKUPSET '/dm8/backup/full/TBS1BAK11'; -- 第一步还原表空间

第二步:恢复数据库

RECOVER DATABASE '/dm8/data/DMTMP/dm.ini' TABLESPACE "TBS1" WITH ARCHIVEDIR '/dm8/arch2'; RMAN> RECOVER DATABASE '/dm8/data/DMTMP/dm.ini' TABLESPACE "TBS1" WITH ARCHIVEDIR '/dm8/arch2'; -- 第二步恢复表空间 Database mode = 0, oguid = 0 Normal of FAST Normal of DEFAULT Normal of RECYCLE Normal of KEEP Normal of ROLL EP[0]'s cur_lsn[41125], file_lsn[41125] [Percent:100.00%][Speed:0.00PKG/s][Cost:00:00:00][Remaining:00:00:00] recover successfully. time used: 445.261(ms) -- 这两步就完成了表空间的恢复,特别提醒,不需要更新db_magic

在dmdba用户下启动数据库

$ /dm8/bin/dmserver /dm8/data/DMTMP/dm.ini file dm.key not found, use default license! version info: develop DM Database Server 64 V8 03134283890-20220525-161267-10045 startup... Normal of FAST Normal of DEFAULT Normal of RECYCLE Normal of KEEP Normal of ROLL Database mode = 0, oguid = 0 License will expire on 2023-05-25 file lsn: 41125 ndct db load finished ...(略) SYSTEM IS READY. # 启动数据库正常

disql中查询数据

SQL> select * from mytable; 服务器[LOCALHOST:5238]:处于普通打开状态 已连接 行号 ID NAME ---------- ----------- ---- 1 12 23 34 45 56 66 rows got 已用时间: 2.070(毫秒). 执行号:500. SQL> select sysdate(); 行号 SYSDATE() ---------- ------------------- 1 2023-04-19 15:55:48 已用时间: 0.984(毫秒). 执行号:501. SQL> select PATH,CREATE_TIME,status$ from v$datafile; 行号 PATH CREATE_TIME STATUS$ ---------- -------------------------- ------------------- ----------- 1 /dm8/data/DMTMP/SYSTEM.DBF 2023-04-19 13:43:30 1 2 /dm8/data/DMTMP/ROLL.DBF 2023-04-19 13:43:30 1 3 /dm8/data/DMTMP/TEMP.DBF 2023-04-19 15:51:07 1 4 /dm8/data/DMTMP/MAIN.DBF 2023-04-19 13:43:30 1 5 /dm8/data/DMTMP/TBS01.DBF 2023-04-19 15:44:06 1 已用时间: 1.282(毫秒). 执行号:503.

结论:通过之前表空间备份和归档日志,可以将意外删除的表空间文件给恢复。
注意,上面的操作,我们并没有修改魔数

SQL> select 'db_magic' "参数",db_magic as "值" 2 union ALL 3 select 'permanent_magic',permanent_magic; 行号 参数 值 ---------- --------------- -------------------- 1 db_magic 754488622 2 permanent_magic 458133940 已用时间: 22.413(毫秒). 执行号:517. SQL>

4.3还原恢复方法二

该方法可以在没有数据库文件备份的情况下,恢复误删除的表空间文件。但是前提条件是有时间限制,并且不能重启服务器,不能重启数据库服务,并且不能删除关键的系统表空间。
该恢复方法主要是利用了在Linux系统中,只要其文件句柄(file handle)没有被关闭,可以在/proc/<pid>/fd中找到其对应的文件副本。利用该方法,结合操作系统命令,我们可以在数据库不停的情况下,实现表空间的恢复。
具体演示过程如下:

$ ls -l 总用量 856160 drwxr-xr-x 2 dmdba dinstall 6 4月 19 13:43 bak drwxr-xr-x 2 dmdba dinstall 4096 4月 19 15:51 ctl_bak -rw-r--r-- 1 dmdba dinstall 338 4月 19 14:03 dmarch.ini -rw-r--r-- 1 dmdba dinstall 6144 4月 19 15:51 dm.ctl -rw-r--r-- 1 dmdba dinstall 59132 4月 19 14:03 dm.ini -rw-r--r-- 1 dmdba dinstall 895 4月 19 13:43 dminit20230419134328.log -rw-r--r-- 1 dmdba dinstall 633 4月 19 13:43 dm_service.prikey -rw-r--r-- 1 dmdba dinstall 268435456 4月 19 16:14 DMTMP01.log -rw-r--r-- 1 dmdba dinstall 268435456 4月 19 15:51 DMTMP02.log drwxr-xr-x 2 dmdba dinstall 6 4月 19 13:43 HMAIN -rw-r--r-- 1 dmdba dinstall 134217728 4月 19 13:43 MAIN.DBF -rw-r--r-- 1 dmdba dinstall 12 4月 19 13:50 rep_conflict.log -rw-r--r-- 1 dmdba dinstall 134217728 4月 19 16:12 ROLL.DBF -rw-r--r-- 1 dmdba dinstall 481 4月 19 13:43 sqllog.ini -rw-r--r-- 1 dmdba dinstall 27262976 4月 19 15:54 SYSTEM.DBF -rw-r--r-- 1 dmdba dinstall 33554432 4月 19 15:48 TBS01.DBF -rw-r--r-- 1 dmdba dinstall 10485760 4月 19 15:51 TEMP.DBF drwxr-xr-x 2 dmdba dinstall 6 4月 19 13:50 trace [dmdba@KylinDCA1 DMTMP]$ rm -f TBS01.DBF ## 删除文件

disql中执行

SQL> SP_FILE_SYS_CHECK(); DMSQL 过程已成功完成 已用时间: 1.785(毫秒). 执行号:504. SQL> select PATH,CREATE_TIME,status$ from v$datafile; 行号 PATH CREATE_TIME STATUS$ ---------- -------------------------- ------------------- ----------- 1 /dm8/data/DMTMP/SYSTEM.DBF 2023-04-19 13:43:30 1 2 /dm8/data/DMTMP/ROLL.DBF 2023-04-19 13:43:30 1 3 /dm8/data/DMTMP/TEMP.DBF 2023-04-19 15:51:07 1 4 /dm8/data/DMTMP/MAIN.DBF 2023-04-19 13:43:30 1 5 /dm8/data/DMTMP/TBS01.DBF 2023-04-19 15:44:06 0 已用时间: 0.339(毫秒). 执行号:505. SQL> select * from mytable; select * from mytable; [-3433]:表空间处于脱机状态. 已用时间: 134.618(毫秒). 执行号:0. SQL> SP_TABLESPACE_PREPARE_RECOVER('TBS1'); -- 第一步执行系统函数

此时表空间状态已经是0(离线状态),相关表也不能查询。
在bash终端中操作

$ ps -ef|grep dmserver dmdba 43860 1 0 13:04 pts/3 00:00:48 /dm8/bin/dmserver path=/dm8/data/DMDB/dm.ini -noconsole dmdba 45079 44116 0 15:51 pts/2 00:00:13 /dm8/bin/dmserver /dm8/data/DMTMP/dm.ini dmdba 45372 39357 0 16:20 pts/0 00:00:00 grep dmserver 进程ID为45079是我们演示库的进程 $ ls -la /proc/45079/fd 总用量 0 dr-x------ 2 dmdba dinstall 0 4月 19 16:21 . dr-xr-xr-x 9 dmdba dinstall 0 4月 19 15:51 .. lrwx------ 1 dmdba dinstall 64 4月 19 16:21 0 -> /dev/pts/2 lrwx------ 1 dmdba dinstall 64 4月 19 16:21 1 -> /dev/pts/2 lrwx------ 1 dmdba dinstall 64 4月 19 16:21 10 -> /dm8/data/DMTMP/ROLL.DBF lrwx------ 1 dmdba dinstall 64 4月 19 16:21 11 -> /dm8/data/DMTMP/MAIN.DBF lrwx------ 1 dmdba dinstall 64 4月 19 16:21 12 -> '/dm8/data/DMTMP/TBS01.DBF (deleted)' ## 该文件已经被删除,但其现在还被dmserver打开,文件句柄是12 lr-x------ 1 dmdba dinstall 64 4月 19 16:21 13 -> 'pipe:[543380]' l-wx------ 1 dmdba dinstall 64 4月 19 16:21 14 -> 'pipe:[543380]' lr-x------ 1 dmdba dinstall 64 4月 19 16:21 15 -> 'pipe:[543381]' $ cp /proc/45079/fd/12 /dm8/data/DMTMP/TBS01.DBF ## 12 为已经删除文件句柄 $ ll /dm8/data/DMTMP/TBS01.DBF -rw-r--r-- 1 dmdba dinstall 33554432 4月 19 16:24 /dm8/data/DMTMP/TBS01.DBF ## 将该文件句柄复制到一个文件,该文件名就指定为原来文件名

接下来在disql中执行

SQL> SP_TABLESPACE_RECOVER('TBS1'); -- 第二步 DMSQL 过程已成功完成 已用时间: 4.107(毫秒). 执行号:511. SQL> SP_FILE_SYS_CHECK(); -- 第三步 DMSQL 过程已成功完成 已用时间: 0.550(毫秒). 执行号:512. SQL> select PATH,CREATE_TIME,status$ from v$datafile; 行号 PATH CREATE_TIME STATUS$ ---------- -------------------------- ------------------- ----------- 1 /dm8/data/DMTMP/SYSTEM.DBF 2023-04-19 13:43:30 1 2 /dm8/data/DMTMP/ROLL.DBF 2023-04-19 13:43:30 1 3 /dm8/data/DMTMP/TEMP.DBF 2023-04-19 15:51:07 1 4 /dm8/data/DMTMP/MAIN.DBF 2023-04-19 13:43:30 1 5 /dm8/data/DMTMP/TBS01.DBF 2023-04-19 15:44:06 1 -- 表空间状态恢复正常 已用时间: 0.608(毫秒). 执行号:513. SQL> select * from mytable; 行号 ID NAME ---------- ----------- ---- 1 12 23 34 45 56 66 rows got 已用时间: 0.351(毫秒). 执行号:514.

4.4恢复方法总结

在Linux环境下,利用上述两种办法,我们都实现了表空间的恢复。方法一应当说是比较规范和通用的方法,它支持Windows、Linux以及其它Unix平台。它实现的前提条件是数据库开启了归档模式,并且有数据库全备份或者表空间备份,以及归档日志备份。而方法二是一种针对特定的操作系统,利用操作系统提供的特性,结合数据库系统函数实现。该方式有局限,但是也有在线操作、不重启数据库就能恢复的优点。

三天培训,收获良多!在此特谢谢程青讲师,谢谢达梦培训的其他老师。

2023年8期DCA学员虫虫于成都

评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服