目录
一、环境信息
|------|------------------------------------------------------------------------------------------------------------------------------|
| 名称 | 值 |
| CPU | Intel(R) Core(TM) i5-1035G1 CPU @ 1.00GHz |
| 操作系统 | CentOS Linux release 7.9.2009 (Core) |
| 内存 | 5G |
| 逻辑核数 | 6 |
| DM版本 | 1 DM Database Server 64 V8 2 DB Version: 0x7000c 3 03134284194-20240703-234060-20108 4 Msg Version: 12 5 Gsu level(5) cnt: 0 |
二、问题描述
工作中经常可以遇到一种情况数据页损坏了,需要恢复数据,之前我们只能通过全库恢复来进行数据救援,但现在我们可以通过指定坏页进行修复,大大减少了停业务时间,提升恢复效率。
三、介绍
1、数据页还原
(1)语法树
sql
RESTORE PAGE '['<表空间 ID>, <文件 ID>, <数据页号>']' DATABASE '<ini_path>' [WITH CHECK]
<from_clause> [<device_type_stmt>]
[IDENTIFIED BY <<密码>|"<密码>">[ENCRYPT WITH <加密算法>] ]
[[WITH BACKUPDIR '<基备份搜索目录>' {,'<基备份搜索目录>'}]
[TASK THREAD <任务线程个数>];
<from_clause>::= FROM BACKUPSET '<备份集路径>' | FROM BACKUPNAME <备份名>
<device_type_stmt>::= DEVICE TYPE <介质类型> [PARMS '<介质参数>']]
(2)注意事项
|----|----------------------------------------------|
| 序号 | 描述 |
| 1 | 指定数据页必须是目标库存在的数据页。 |
| 2 | 指定备份集必须是完全备份集。 |
| 3 | 数据页所在表空间必须处于非还原状态(未执行还原操作)。 |
| 4 | 数据页在目标库存在,但是备份集中不包含该页时忽略错误,认为数据页在重演REDO 时创建。 |
| 5 | 还原后的库及表空间不支持还原数据页。 |
| 6 | 还原数据页后,不影响库级及表空间还原。 |
| 7 | 指定表空间还原数据页后,恢复操作执行前不支持再次还原数据页。 |
| 8 | 不支持还原系统表空间数据页。 |
2、数据页恢复
(1)语法树
sql
RECOVER PAGE '[' 表空间 ID, 文件 ID, 数据页号 ']' DATABASE '<ini_path>' [WITH ARCHIVEDIR '归档日志目录'{,'归档日志目录'}] [USE DB_MAGIC <db_magic>] [UNTIL TIME '<时间串>' | UNTIL LSN <lsn>];
数据页恢复是通过指定 LSN 或时间戳实现。因为 LSN 或时间戳可能相对陈旧,所以恢复后该数据页相对陈旧。陈旧的数据页会导致数据库数据的不一致,甚至导致系统崩溃。因此,用户须慎用此操作,或者在使用数据页还原操作前,尽量使用最新的 LSN 或时间戳。
(2)注意事项
|----|---------------------------------------------------|
| 序号 | 描述 |
| 1 | 恢复操作指定的数据页必须和还原操作匹配。 |
| 2 | 未指定 UNTIL LSN 或 UNTIL TIME 时,归档目录下必须包含备份开始后的完整归档。 |
四、实验
1、测试数据生成
sql
DROP TABLE SUN;
CREATE TABLE SUN (A INT);
INSERT INTO SUN SELECT LEVEL FROM DUAL CONNECT BY LEVEL <= 10;
COMMIT;
CHECKPOINT(100);
2、全库备份
sql
BACKUP DATABASE BACKUPSET 'SUN_FULL_20260625';
3、测试数据追加
sql
INSERT INTO SUN VALUES(55);
COMMIT;
CHECKPOINT(100);
4、数据展示
sql
17:19:54 SYSDBA@LOCALHOST:5236 SQL> SELECT * FROM SUN;
A
-----------
1
2
3
4
5
6
7
8
9
10
55
11 rows got
已用时间: 3.509(毫秒). 执行号:513.
1-10在备份中,55不在。
5、测试表数据位置
sql
SELECT ID,GROUPID,ROOTFILE,ROOTPAGE,ROOTPAGE*PAGE AS PAGEOFFSET,TYPE$ FROM SYSINDEXES
WHERE ID = (SELECT REPLACE(INDEX_NAME,'INDEX','') FROM DBA_INDEXES WHERE TABLE_NAME = 'SUN' AND TABLE_OWNER = 'SYSDBA');
ID GROUPID ROOTFILE ROOTPAGE PAGEOFFSET TYPE$
----------- ----------- ----------- ----------- ----------- -----
33555469 4 0 1040 8519680 BT
已用时间: 110.002(毫秒). 执行号:514.
GROUPID :所属的表空间 ID
ROOTFILE :数据库文件 ID
ROOTPAGE :页号
PAGEOFFSET : 页偏移量
sql
SELECT GROUP_ID,ID,PATH FROM V$DATAFILE;
GROUP_ID ID PATH
----------- ----------- -------------------------------
4 0 /opt/Dm8/Data/DAMENG/MAIN.DBF
3 0 /opt/Dm8/Data/DAMENG/TEMP.DBF
1 0 /opt/Dm8/Data/DAMENG/ROLL.DBF
0 0 /opt/Dm8/Data/DAMENG/SYSTEM.DBF
已用时间: 3.259(毫秒). 执行号:515.
对应表空间数据文件 /opt/Dm8/Data/DAMENG/MAIN.DBF。
sql
17:26:44 SYSDBA@LOCALHOST:5236 SQL> SELECT PAGE() * 1040;
PAGE()*1040
-----------
8519680
已用时间: 3.571(毫秒). 执行号:516.
计算出的偏移量和上面视图中显示的一样。
6、生成坏数据页
bash
dd if=/dev/zero of=/opt/Dm8/Data/DAMENG/MAIN.DBF bs=1 count=15 seek=8519680 conv=notrunc
7、查询数据库宕机
开库的情况下查询,有可能查询的是数据缓冲区中的数据,可以重启一次数据库再进行查询。
sql
17:53:41 SYSDBA@LOCALHOST:5236 SQL> SELECT * FROM SUN;
DISQL-10036: 连接丢失
DISQL-10036: 连接丢失
DISQL-10036: 连接丢失
DISQL-10034: 未连接
查询失败。
bash
[dmdba@dw01:/home/dmdba]$ dmserver /opt/Dm8/Data/DAMENG/dm.ini
file dm.key not found, use default license!
version info: develop
csek2_vm_t = 9672
nsql_vm_t = 336
prjt2_vm_t = 208
ltid_vm_t = 272
nins2_vm_t = 1160
nset2_vm_t = 272
ndlck_vm_t = 192
ndel2_vm_t = 736
slct2_vm_t = 352
nli2_vm_t = 200
aagr2_vm_t = 312
pscn_vm_t = 416
dist_vm_t = 1000
DM Database Server 64 V8 03134284488-20260212-314192-20200 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 2027-02-12
begin redo pwr log collect, last ckpt lsn: 70358 ...
redo pwr log collect finished
main rfil[/opt/Dm8/Data/DAMENG/DAMENG01.log]'s grp collect 0 valid pwr record, discard 0 invalid pwr record
EP[0]'s cur_lsn[70360], file_lsn[70360]
begin redo log recover, last ckpt lsn: 70358 ...
redo log recover finished 0
ndct db load finished, code:100
ndct second level fill fast pool finished
ndct third level fill fast pool finished
浮点数例外(吐核)
数据无法正常启停,所以不能使用dmdbchk。
8、数据库日志报错
sql
2026-06-25 17:56:04.179 [ERROR] database P0000017461 T0000000000000017461 [EID:48]Server page check error! page:(4, 0, 1040) page_type(20) index_id(33555469)
2026-06-25 17:56:04.190 [FATAL] database P0000017461 T0000000000000017461 [EID:316][for dem]SYSTEM SHUTDOWN ABORT.
2026-06-25 17:56:04.190 [FATAL] database P0000017461 T0000000000000017461 Server page check error!
2026-06-25 17:56:04.190 [FATAL] database P0000017461 T0000000000000017461 [EID:617]code = -1, dm_sys_halt now!!!
2026-06-25 17:56:04.190 [INFO] database P0000017461 T0000000000000017461 total 3 rfil opened!
2026-06-25 17:56:04.190 [INFO] database P0000017461 T0000000000000017461 os_sema2_free, sema_id:30, sema_value:1!
2026-06-25 17:56:04.190 [INFO] database P0000017461 T0000000000000017461 os_sema2_free, sema_id:31, sema_value:1!
2026-06-25 17:56:04.190 [FATAL] database P0000017461 T0000000000000017461 [EID:326]sigterm_handler receive signal 8
2026-06-25 17:56:04.191 [FATAL] database P0000017461 T0000000000000017461 [EID:316][for dem]SYSTEM SHUTDOWN ABORT.
Server page check error! page:(4, 0, 1040)损坏了。
正好是我们刚刚修改的这个页。
9、dmrman恢复数据
sql
[dmdba@dw01:/home/dmdba]$ dmrman
dmrman V8
RMAN> RESTORE PAGE [4, 0, 1040] DATABASE '/opt/Dm8/Data/DAMENG/dm.ini' FROM BACKUPSET '/opt/Dm8/Data/DAMENG/bak/SUN_FULL_20260625';
RESTORE PAGE [ 4 , 0 , 1040 ] DATABASE '/opt/Dm8/Data/DAMENG/dm.ini' FROM BACKUPSET '/opt/Dm8/Data/DAMENG/bak/SUN_FULL_20260625';
file dm.key not found, use default license!
[Percent:100.00%][Speed:0.00M/s][Cost:00:00:02][Remaining:00:00:00]
restore successfully.
time used: 00:00:02.812
RMAN> RECOVER PAGE [4, 0, 1040] DATABASE '/opt/Dm8/Data/DAMENG/dm.ini' WITH ARCHIVEDIR '/opt/Dm8/Data/DAMENG/Arch';
RECOVER PAGE [ 4 , 0 , 1040 ] DATABASE '/opt/Dm8/Data/DAMENG/dm.ini' WITH ARCHIVEDIR '/opt/Dm8/Data/DAMENG/Arch';
[Percent:100.00%][Speed:0.00PKG/s][Cost:00:00:00][Remaining:00:00:00]
recover successfully.
time used: 00:00:01.383
10、数据库启动
bash
[dmdba@dw01:/home/dmdba]$ dmserver /opt/Dm8/Data/DAMENG/dm.ini
file dm.key not found, use default license!
version info: develop
csek2_vm_t = 9672
nsql_vm_t = 336
prjt2_vm_t = 208
ltid_vm_t = 272
nins2_vm_t = 1160
nset2_vm_t = 272
ndlck_vm_t = 192
ndel2_vm_t = 736
slct2_vm_t = 352
nli2_vm_t = 200
aagr2_vm_t = 312
pscn_vm_t = 416
dist_vm_t = 1000
DM Database Server 64 V8 03134284488-20260212-314192-20200 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 2027-02-12
begin redo pwr log collect, last ckpt lsn: 70358 ...
redo pwr log collect finished
main rfil[/opt/Dm8/Data/DAMENG/DAMENG01.log]'s grp collect 0 valid pwr record, discard 0 invalid pwr record
EP[0]'s cur_lsn[70361], file_lsn[70361]
begin redo log recover, last ckpt lsn: 70358 ...
redo log recover finished 0
ndct db load finished, code:100
ndct second level fill fast pool finished
ndct third level fill fast pool finished
ndct second level fill fast pool finished
ndct third level fill fast pool finished
ndct fill fast pool finished
pseg_set_gtv_trxid_low next_trxid in mem:[54089]
pseg_collect_mgr_items, total collect 0 active_trxs, 0 cmt_trxs, 0 pre_cmt_trxs, 0 to_release_trxs, 0 active_pages, 0 cmt_pages, 0 pre_cmt_pages, 0 to_release_pages, 0 used mgr pages, 0 mgr recs!
next_trxid in mem:[56091]
next_trxid = 58093.
pseg recv finished
nsvr_startup end.
uthr_pipe_create, create pipe[read:11, write:12]
uthr_pipe_create, create pipe[read:13, write:14]
uthr_pipe_create, create pipe[read:15, write:16]
uthr_pipe_create, create pipe[read:17, write:18]
aud sys init success.
aud rt sys init success.
systables desc init success.
ndct_db_load_info finished, code:100.
nsvr_process_before_open begin.
nsvr_process_before_open success.
SYSTEM IS READY.
11、查询数据
sql
17:54:51 SYSDBA@LOCALHOST:5236 SQL> SELECT * FROM SUN;
服务器[LOCALHOST:5236]:处于普通打开状态
已连接
A
-----------
1
2
3
4
5
6
7
8
9
10
55
11 rows got
已用时间: 3.650(毫秒). 执行号:500.
查询数据正常,这个功能还是很给力的。
五、参数介绍
1、PTX_ROLLBACK

2、PAGE_CHECK_POLICY

六、其他点
如果想查询时不宕机,可以尝试调整参数:
sql
SP_SET_PARA_VALUE(2,'PTX_ROLLBACK',1);
SP_SET_PARA_VALUE(1,'PAGE_CHECK_POLICY',0);
查询时就会提示报错:
sql
09:36:37 SYSDBA@LOCALHOST:5236 SQL> SELECT * FROM SUN;
服务器[LOCALHOST:5236]:处于普通打开状态
已连接
SELECT * FROM SUN;
[-4563]:无效的页,页(4, 0, 1040).
已用时间: 9.362(毫秒). 执行号:0.