无备份数据恢复实验
实验说明一、开启归档二、开启记录逻辑操作功能三、构建测试环境四、模拟操作业务五、破坏数据文件六、尝试重启数据库6.1 数据库实例无法启动。6.2 数据库服务无法启动6.3 手动启动无法启动 七、恢复数据库服务7.1 将控制文件导出为文本7.2 找到对应的内容并删除7.3 重建数据文件7.4 数据库启动成功7.5 登录数据库检查 八、数据恢复8.1 首先重建用户和表空间8.2 开始日志挖掘开挖之前需要恢复的数据在哪些归档日志里加载需要挖掘的日志开挖,配置具体的挖掘范围查看挖掘结果处理结果集导出SQL脚本执行脚本验证,数据恢复结果。 九、 来个备份吧实验说明
测试场景:某一个非核心表空间使用的数据文件丢失或损坏,无备份,有归档,对其进行恢复。
为什么一定是非核心表空间,因为SYSTEM这种系统表空间一旦损坏必须全库进行恢复,无法通过其他手段进行恢复。
敲重点:备份非常重要、备份非常重要、备份非常重要
一、开启归档
没有备份、也没有归档是无法进行数据恢复的,能够在无备份情况下恢复 一定是开启了归档,并且归档日志保存完整。
SQL> alter database mount;操作已执行已用时间: 359.952(毫秒). 执行号:0.SQL> alter database add archivelog 'type=local,dest=/dm8/arch1,file_size=64,space_limit=0';操作已执行已用时间: 0.712(毫秒). 执行号:0.SQL> alter database archivelog;操作已执行已用时间: 0.312(毫秒). 执行号:0.SQL> alter database open;操作已执行已用时间: 373.182(毫秒). 执行号:0.SQL> select name,status$,arch_mode from v$database;行号NAME STATUS$ARCH_MODE---------- ---- ----------- ---------1PROD 4 Y已用时间: 0.528(毫秒). 执行号:263982.SQL>
二、开启记录逻辑操作功能
RLOG_APPEND_LOGIC:(必须大于1才可以使用日志挖掘功能)
是否启用在日志中记录逻辑操作的功能, 取值范围 0、 1、 2、3
0: 不启用; 1、 2、 3 启用。
1: 如果有主键列, 记录 UPDATE 和 DELETE操作时只包含主键列信息,若没有主键列则包含所有列信息;
2:不论是否有主键列, 记录UPDATE 和 DELETE 操作时都包含所有列的信息;
3: 记录 UPDATE 时包含更新列的信息以及ROWID, 记录 DELETE 时只有 ROWID
SQL> sp_set_para_value(1,'RLOG_APPEND_LOGIC',1);DMSQL 过程已成功完成已用时间: 2.361(毫秒). 执行号:1403.SQL> select para_name, para_value from v$dm_ini where para_name in ('ARCH_INI','RLOG_APPEND_LOGIC');行号PARA_NAME PARA_VALUE---------- ----------------- ----------1RLOG_APPEND_LOGIC 12ARCH_INI1已用时间: 2.443(毫秒). 执行号:1404.
三、构建测试环境
在这一步里,我们要进行以下几步操作:
1、创建了一个名为TC01的表空间,创建一个用户TEST_TC 设置他的默认表空间为TC01。
2、然后在TEST_TC用户下创建一张表,在表里构造一些数据。
3、通过系统视图进行操作确认。
--创建表空间SQL> create tablespace TC01 datafile '/dm8/data/PROD/TC01.DBF' size 50;操作已执行已用时间: 13.068(毫秒). 执行号:263974.--创建用户,指定默认表空间SQL> CREATE user TEST_TC IDENTIFIED BY TEST00001 DEFAULT TABLESPACE TC01 DEFAULT INDEX TABLESPACE TC01;操作已执行已用时间: 33.409(毫秒). 执行号:263975.--在新建的用户下创建表SQL> CREATE TABLE TEST_TC.T1 (ID INT , NAME VARCHAR(50));操作已执行已用时间: 51.978(毫秒). 执行号:263976.--写入一条数据SQL> INSERT INTO TEST_TC.T1 VALUES (1,'数据文件恢复测试');影响行数 1已用时间: 0.519(毫秒). 执行号:263977.SQL> commit;操作已执行已用时间: 0.838(毫秒). 执行号:263978.--通过视图查询TC01表空间下已经有了T1表SQL> select tablespace_NAME,segment_name,segment_type from dba_segments where tablespace_name='TC01';行号TABLESPACE_NAME SEGMENT_NAME SEGMENT_TYPE---------- --------------- ------------ ------------1TC01 T1 TABLE已用时间: 87.608(毫秒). 执行号:263979.--查询TC01表空间的数据文件路径SQL> select tablespace_name,file_name,round(bytes/1024/1024) mb from dba_data_files where tablespace_name='TC01';行号TABLESPACE_NAME FILE_NAMEMB---------- --------------- ----------------------- --1TC01 /dm8/data/PROD/TC01.DBF 50已用时间: 3.026(毫秒). 执行号:263980.
四、模拟操作业务
在这里我们模拟一些业务操作,以便我们验证数据恢复是否成功。
SQL> update TEST_TC.t1 set id=id+1;影响行数 1已用时间: 0.547(毫秒). 执行号:263983.SQL> update TEST_TC.t1 set id=id+1;影响行数 1已用时间: 0.547(毫秒). 执行号:263983.SQL> commit;操作已执行已用时间: 0.672(毫秒). 执行号:263984.SQL> select * from TEST_TC.t1;行号IDNAME---------- ----------- ------------------------13 数据文件恢复测试已用时间: 0.951(毫秒). 执行号:263985.
五、破坏数据文件
通过控制台调用操作系统命令,使用其他文件覆盖数据文件TC01.DBF
SQL> host cp /dm8/bin/disql /dm8/data/PROD/TC01.DBFSQL>
六、尝试重启数据库
6.1 数据库实例无法启动。
数据库无法open
SQL> shutdown immediate;操作已执行已用时间: 0.224(毫秒). 执行号:0.SQL> startup2 ;连接丢失SQL>
6.2 数据库服务无法启动
数据库服务启动失败
[root@bogon bin]# systemctl start DmServiceTEST.serviceJob for DmServiceTEST.service failed because the control process exited with error code.See "systemctl status DmServiceTEST.service" and "journalctl -xe" for details.[root@bogon bin]#
6.3 手动启动无法启动
查看启动过程无法完成,报错信息也不是很有针对性,嗯~ o( ̄▽ ̄)o
[root@bogon bin]# ./dmserver path=/dm8/data/PROD/dm.inifile dm.key not found, use default license!version info: developDM Database Server x64 V8 1-2-18-21.11.11-150669-10013-ENT startup...Normal of FASTNormal of DEFAULTNormal of RECYCLENormal of KEEPNormal of ROLLDatabase mode = 0, oguid = 0License will expire on -11-11begin redo pwr log collect, last ckpt lsn: 173291 ...redo pwr log collect finishedmain rfil[/dm8/data/PROD/PROD01.log]'s grp collect 0 valid pwr record, discard 0 invalid pwr recordEP[0]'s cur_lsn[173291], file_lsn[173291]begin redo log recover, last ckpt lsn: 173291 ...redo log recover finishedndct db load finished浮点数例外
七、恢复数据库服务
现在整个数据库服务已经无法启动了,我们要通过修改控制文件先把数据库服务恢复。
表空间、数据库文件信息都写在控制文件里,我们只需要删除控制文件中损坏的数据文件信息就可以让服务启动。
7.1 将控制文件导出为文本
控制文件是一个ctl结尾的二进制文件,无法直接进行修改,需要转为文本。
[dmdba@bogon bin]$ ./dmctlcvt type=1 src=/dm8/data/PROD/dm.ctl dest=/dm8/dmctl.txtDMCTLCVT V8convert ctl to txt success!
7.2 找到对应的内容并删除
在控制文件里 找到 TC01 的描述和 /dm8/data/PROD/TC01.DBF 数据文件的表述,整段全部都删掉。
[dmdba@bogon bin]$ vi /dm8/dmctl.txt#===============================================# table space namets_name=TC01# table space IDts_id=12# table space statusts_state=0# table space cachets_cache=NORMAL# DSC node numberts_nth=0# table space create timets_create_time=DATETIME '-1-18 19:22:22'# table space modify timets_modify_time=DATETIME '-1-18 19:22:22'# table space encrypt flagts_encrypt_flag=0# table space copy numts_copy_num=0# table space region size flagts_size_flag=0#-----------------------------------------------# file pathfil_path=/dm8/data/PROD/TC01.DBF# mirror pathmirror_path=# file id# whether the file is auto extendautoextend=1# file create timefil_create_time=DATETIME '-1-18 19:22:22'# file modify timefil_modify_time=DATETIME '-1-18 19:22:22'# the max size of filefil_max_size=0# next size of filefil_next_size=0#===============================================
7.3 重建数据文件
将文件文本重新转为ctl文件,覆盖原来的控制文件
[dmdba@bogon bin]$ ./dmctlcvt type=2 src=/dm8/dmctl.txt dest=/dm8/data/PROD/dm.ctlDMCTLCVT V8convert txt to ctl success!
7.4 数据库启动成功
重启数据库成功,o( ̄▽ ̄)ブ
[root@bogon bin]# ./dmserver path=/dm8/data/PROD/dm.inifile dm.key not found, use default license!version info: developDM Database Server x64 V8 1-2-18-21.11.11-150669-10013-ENT startup...Normal of FASTNormal of DEFAULTNormal of RECYCLENormal of KEEPNormal of ROLLDatabase mode = 0, oguid = 0License will expire on -11-11begin redo pwr log collect, last ckpt lsn: 173291 ...redo pwr log collect finishedmain rfil[/dm8/data/PROD/PROD01.log]'s grp collect 0 valid pwr record, discard 0 invalid pwr recordEP[0]'s cur_lsn[173291], file_lsn[173291]begin redo log recover, last ckpt lsn: 173291 ...redo log recover finishedndct db load finishedndct fill fast pool finishediid page's trxid[49430]NEXT TRX ID = 49431pseg_collect_mgr_items, total collect 0 active_trxs, 0 cmt_trxs, 0 pre_cmt_trxs, 0 active_pages, 0 cmt_pages, 0 pre_cmt_pages, 0 mgr pages, 0 mgr recs!total 0 active crash trx, pseg_crash_trx_rollback sys_only(0) begin ...pseg_crash_trx_rollback end, total 0 active crash trx, include 0 empty_trxs, 0 empty_pages which only need to delete mgr recs.pseg_crash_trx_rollback endpseg recv finishednsvr_startup end.aud sys init success.aud rt sys init success.systables desc init success.ndct_db_load_info success.nsvr_process_before_open begin.nsvr_process_before_open success.total 0 active crash trx, pseg_crash_trx_rollback sys_only(0) begin ...pseg_crash_trx_rollback end, total 0 active crash trx, include 0 empty_trxs, 0 empty_pages which only need to delete mgr recs.pseg_crash_trx_rollback endSYSTEM IS READY.
7.5 登录数据库检查
登录数据库正常
[dmdba@bogon bin]$ ./disql SYSDBA/dameng123@localhost:5237服务器[localhost:5237]:处于普通打开状态登录使用时间 : 1.411(ms)disql V8SQL>
经过检查 用户、表空间、表 都已经不见了
SQL> select username,default_tablespace from dba_users where username='TEST_TC';未选定行已用时间: 5.974(毫秒). 执行号:500.SQL> select tablespace_name from dba_tablespaces WHERE tablespace_name='TC01';未选定行已用时间: 2.519(毫秒). 执行号:501.SQL> select tablespace_NAME,segment_name,segment_type from dba_segments where segment_name='T1';未选定行已用时间: 120.287(毫秒). 执行号:502.SQL>
八、数据恢复
下面开始进行数据恢复。
8.1 首先重建用户和表空间
我们这里对用户进行了重命名TEST_TC 改为了 TEST_TC01
SQL> create tablespace TC01 datafile '/dm8/data/PROD/TC01_1.DBF' size 50;操作已执行已用时间: 63.315(毫秒). 执行号:508.SQL> CREATE user TEST_TC01 IDENTIFIED BY TEST00001 DEFAULT TABLESPACE TC01 DEFAULT INDEX TABLESPACE TC01;操作已执行已用时间: 51.114(毫秒). 执行号:509.
8.2 开始日志挖掘
开挖之前需要恢复的数据在哪些归档日志里
通过归档日志的创建日志进行筛选
SQL> select NAME,FIRST_TIME from v$archived_log where FIRST_TIME >'-01-19 12:00:00';行号NAME FIRST_TIME---------- ------------------------------------------------------------------------ --------------------------1 /dm8/arch1/ARCHIVE_LOCAL3_0x6910E0E3[0]_-01-19_13-03-59.log-01-19 13:03:14.6065572 /dm8/arch1/ARCHIVE_LOCAL3_0x6910E0E3[0]_-01-19_13-39-42.log-01-19 13:37:31.9750003 /dm8/arch1/ARCHIVE_LOCAL3_0x6910E0E3[0]_-01-19_13-45-56.log -01-19 13:39:59.0130003 rows got已用时间: 1.523(毫秒). 执行号:520.
加载需要挖掘的日志
这里有几个日志文件就需要执行几次。
SQL> call dbms_logmnr.add_logfile('/dm8/arch1/ARCHIVE_LOCAL3_0x6910E0E3[0]_-01-19_13-03-59.log');DMSQL 过程已成功完成已用时间: 42.461(毫秒). 执行号:511.SQL> call dbms_logmnr.add_logfile('/dm8/arch1/ARCHIVE_LOCAL3_0x6910E0E3[0]_-01-19_13-39-42.log');DMSQL 过程已成功完成已用时间: 0.512(毫秒). 执行号:512.SQL> call dbms_logmnr.add_logfile('/dm8/arch1/ARCHIVE_LOCAL3_0x6910E0E3[0]_-01-19_13-45-56.log');DMSQL 过程已成功完成已用时间: 1.070(毫秒). 执行号:513.
开挖,配置具体的挖掘范围
SQL> Call dbms_logmnr.start_logmnr(options => 2128,starttime=> to_date('-01-18 00:00:00','yyyy-mm-dd hh24:mi:ss'),endtime => to_date('-01-18 23:59:59','yyyy-mm-dd hh24:mi:ss'));DMSQL 过程已成功完成已用时间: 188.525(毫秒). 执行号:514.
options整个参数用于配置挖掘模式。
提供如下表所列的可选模式,各模式可以通过 + 或者按位或来进行组合。
其它位的值 如 1、 4、 8等目前不支持,配置后不会报错,但是没有效果。
例如,组合全部模式,则取值 计算方法为 16+64+2048=2128,那么 OPTIONS值取就是 2128。
查看挖掘结果
这时已经可以看到我们之前执行的语句了。
SQL> select sql_redo from V$logmnr_contents where sql_redo like '%T1%' ORDER BY timestamp;行号SQL_REDO---------- -----------------------------------------------------------------------------------------1CREATE TABLE TEST_TC.T1 (ID INT , NAME VARCHAR(50))2INSERT INTO "TEST_TC"."T1"("ID", "NAME") VALUES(1, '数据文件恢复测试')3UPDATE "TEST_TC"."T1" SET "ID" = 2 WHERE "ID" = 1 AND "NAME" = '数据文件恢复测试'4UPDATE "TEST_TC"."T1" SET "ID" = 3 WHERE "ID" = 2 AND "NAME" = '数据文件恢复测试'
处理结果集
因为我们重建用户的时候修改了用户名,可以通过字符串替换的方式修改sql语句。
另外我们发现上面的语句查出来的数据结尾都没有分号,为了方便执行,我们也把分号拼接上。
SQL> select replace(sql_redo,'TEST_TC','TEST_TC01')||';' from V$logmnr_contents where sql_redo like '%T1%' ORDER BY timestamp;行号REPLACE(SQL_REDO,'TEST_TC','TEST_TC01')||';'---------- --------------------------------------------------------------------------------------------1CREATE TABLE TEST_TC01.T1 (ID INT , NAME VARCHAR(50));2INSERT INTO "TEST_TC01"."T1"("ID", "NAME") VALUES(1, '数据文件恢复测试');3UPDATE "TEST_TC01"."T1" SET "ID" = 2 WHERE "ID" = 1 AND "NAME" = '数据文件恢复测试';4UPDATE "TEST_TC01"."T1" SET "ID" = 3 WHERE "ID" = 2 AND "NAME" = '数据文件恢复测试';
导出SQL脚本
我们测试的环境SQL脚本比较少,所以手动执行都可以。
如果有大量的SQL语句需要执行,就需要生成一个脚本文件来批量运行。
首先:格式处理,除掉表头、去掉行号、去掉返回的行数等无用的提示。
这样我们就获得了干干净净的SQL查询结果集了
SQL> set HEA offSQL> select replace(sql_redo,'TEST_TC','TEST_TC01')||';' from V$logmnr_contents where sql_redo like '%T1%' ORDER BY timestamp;1CREATE TABLE TEST_TC01.T1 (ID INT , NAME VARCHAR(50));2INSERT INTO "TEST_TC01"."T1"("ID", "NAME") VALUES(1, '数据文件恢复测试');3UPDATE "TEST_TC01"."T1" SET "ID" = 2 WHERE "ID" = 1 AND "NAME" = '数据文件恢复测试';4UPDATE "TEST_TC01"."T1" SET "ID" = 3 WHERE "ID" = 2 AND "NAME" = '数据文件恢复测试';已用时间: 51.065(毫秒). 执行号:527.SQL> set LINESHOW offSQL> /CREATE TABLE TEST_TC01.T1 (ID INT , NAME VARCHAR(50));INSERT INTO "TEST_TC01"."T1"("ID", "NAME") VALUES(1, '数据文件恢复测试');UPDATE "TEST_TC01"."T1" SET "ID" = 2 WHERE "ID" = 1 AND "NAME" = '数据文件恢复测试';UPDATE "TEST_TC01"."T1" SET "ID" = 3 WHERE "ID" = 2 AND "NAME" = '数据文件恢复测试';已用时间: 47.678(毫秒). 执行号:530.SQL> set TIMING offSQL> /CREATE TABLE TEST_TC01.T1 (ID INT , NAME VARCHAR(50));INSERT INTO "TEST_TC01"."T1"("ID", "NAME") VALUES(1, '数据文件恢复测试');UPDATE "TEST_TC01"."T1" SET "ID" = 2 WHERE "ID" = 1 AND "NAME" = '数据文件恢复测试';UPDATE "TEST_TC01"."T1" SET "ID" = 3 WHERE "ID" = 2 AND "NAME" = '数据文件恢复测试';SQL>
将SQL的输出导出到/dm8/t1.sql 这个文件里。 输出完成后,对1.sql还要进行简单的编辑。
这个文件,把第一行的查询语句,和最后一个的spool off 关闭语句删掉 就可以了。
SQL> spool /dm8/t1.sql appendSQL> select replace(sql_redo,'TEST_TC','TEST_TC01')||';' from V$logmnr_contents where sql_redo like '%T1%' ORDER BY timestamp;CREATE TABLE TEST_TC01.T1 (ID INT , NAME VARCHAR(50));INSERT INTO "TEST_TC01"."T1"("ID", "NAME") VALUES(1, '数据文件恢复测试');UPDATE "TEST_TC01"."T1" SET "ID" = 2 WHERE "ID" = 1 AND "NAME" = '数据文件恢复测试';UPDATE "TEST_TC01"."T1" SET "ID" = 3 WHERE "ID" = 2 AND "NAME" = '数据文件恢复测试';SQL> spool off
执行脚本
通过 start 调用sql脚本,所有语句就都执行了。别忘了commti 提交事务。
SQL> start /dm8/t1.sqlSQL> CREATE TABLE TEST_TC01.T1 (ID INT , NAME VARCHAR(50));操作已执行SQL> INSERT INTO "TEST_TC01"."T1"("ID", "NAME") VALUES(1, '数据文件恢复测试');影响行数 1SQL> UPDATE "TEST_TC01"."T1" SET "ID" = 2 WHERE "ID" = 1 AND "NAME" = '数据文件恢复测试';影响行数 1SQL> UPDATE "TEST_TC01"."T1" SET "ID" = 3 WHERE "ID" = 2 AND "NAME" = '数据文件恢复测试';影响行数 1SQL> commit;操作已执行SQL>
验证,数据恢复结果。
最后 我们通过 查询T1 表里的数据来验证恢复结果。
可以看到已经恢复了文件损坏前的数据了。
SQL> select * from TEST_TC01.T1;3 数据文件恢复测试
九、 来个备份吧
恢复完别忘了对数据库进行备份。
以下为 备份数据库、备份表空间、备份表的语句。
SQL> backup database backupset '/dm8/backup/2029' ;操作已执行SQL> backup tablespace TC01 backupset '/dm8/backup/2029_TC01';操作已执行SQL> backup table test_tc01.t1 backupset '/dm8/backup/2029_TC01_T1';操作已执行
达梦技术社区地址:
如果觉得《达梦数据库DM8数据文件损坏无备份恢复》对你有帮助,请点赞、收藏,并留下你的观点哦!