在数据库运行过程中,如果访问到损坏数据页,将导致数据库意外崩溃,此时可通过从备份集中还原目标库指定数据页来进行修复指定的数据页。页级还原与文件级还原(库级,表空间级)相比,因为只有损坏的数据页需要还原,所以数据修复时间大幅减少。
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 '<介质参数>']]
PAGE:指定待还原数据页的表空间 ID、文件 ID 和数据页号。
BACKUPSET:指定用于还原数据页的备份集路径。此备份集必须是库级或表空间级的完全备份集。若指定为相对路径,会在默认备份目录下搜索备份集。
BACKUPNAME:指定用于还原数据页的备份名称。此备份集必须是库级或表空间级的完全备份集。在备份集搜索目录下搜索备份集。
RECOVER PAGE '[' 表空间 ID, 文件 ID, 数据页号 ']' DATABASE '<ini_path>' [WITH ARCHIVEDIR '归档日志目录'{,'归档日志目录'}] [USE DB_MAGIC <db_magic>] [UNTIL TIME '<时间串>' | UNTIL LSN <lsn>];
PS:数据页恢复是通过指定 LSN 或时间戳实现。因为 LSN 或时间戳可能相对陈旧,所以恢复后该数据页相对陈旧。陈旧的数据页会导致数据库数据的不一致,甚至导致系统崩溃。因此,用户须慎用此操作,或者在使用数据页还原操作前,尽量使用最新的 LSN 或时间戳。
SQL> create table test(c1 int,c2 varchar2(200));
SQL> insert into test values(1,'ABC');
SQL> insert into test values(2,'AAA');
SQL> commit;
SQL> select checkpoint(100);
SQL> backup database backupset '/dmbak/DB_BAK_FULL_20260602';
--查看TEST表的聚集索引根页信息
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 = 'TEST' AND TABLE_OWNER = 'HR');
行号 ID GROUPID ROOTFILE ROOTPAGE PAGEOFFSET TYPE$
---------- ----------- ----------- ----------- ----------- ----------- -----
1 33555553 5 0 2912 95420416 BT
偏移量(字节) = 物理页号 × 页大小,即:
偏移量 = 2912 × 32768 = 95,420,416 字节
--通过dd修改页头前4个字节,制造页校验错误
dd if=/dev/zero of=tbs_01.DBF bs=1 count=4 seek=95420416 conv=notrunc
记录了4+0 的读入
记录了4+0 的写出
4字节已复制,0.000183259 s,21.8 kB/s
--查询TEST表,扫描坏页直接宕机
SQL> select * from test;
DISQL-10036: 连接丢失
DISQL-10036: 连接丢失
DISQL-10036: 连接丢失
DISQL-10034: 未连接
--DB运行日志发生报错
2026-06-02 18:11:57.428 [ERROR] database P0000029932 T0000000000000030048 [EID:48]Server page check error! page:(5, 0, 2912) page_type(20) index_id(33555553)
2026-06-02 18:11:57.428 [FATAL] database P0000029932 T0000000000000030048 [EID:316][for dem]SYSTEM SHUTDOWN ABORT.
2026-06-02 18:11:57.428 [FATAL] database P0000029932 T0000000000000030048 Server page check error!
2026-06-02 18:11:57.428 [FATAL] database P0000029932 T0000000000000030048 [EID:617]code = -1, dm_sys_halt now!!!
--此时如果不希望宕机,可以修改参数
sp_set_para_value(2,'PTX_ROLLBACK',1);
sp_set_para_value(1,'PAGE_CHECK_POLICY',0);
参数释义:
PTX_ROLLBACK
针对磁盘 IO 读请求超时、DMDSC 环境下 LBS 请求 GBS 授权超时场景的处理策略。静态,默认值0
0:故障退出;
1:正常报错。
针对访问数据页损坏的场景(建库参数 PAGE_CHECK 非零可以校验数据页损坏)的处理策略。
0:此时处理策略取决于 INI 参数 PAGE_CHECK_POLICY;
1:绝大部分情况可以正常报错,当损坏的数据页是文件 0 号页、系统表空间数据页、文件系统 INODE 页或者描述页等时,无法正常报错,此时的处理策略取决于 INI 参数 PAGE_CHECK_POLICY
PAGE_CHECK_POLICY
建库参数 PAGE_CHECK 非 0 时,若数据页校验失败,对于 INI 参数 PTX_ROLLBACK 为 0 或 PTX_ROLLBACK 为 1 但无法报错处理的情况的处理策略。动态,系统级,默认值1
0:忽略失败;
1:系统主动 HALT
修改后重启实例
--再次查询表直接报错,不会发生宕机
SQL> select * from test;
[-4563]:无效的页,页(5, 0, 2912).
--正常停止实例
SQL> shutdown immediate;
操作已执行
--执行全库dbcheck,确认损坏页个数,校验后仅有TEST表对应页损坏
dmdbchk path=/dmdata/5236/DMDB/dm.ini
[2026-06-02 18:26:04]INDEX=(id=33555553, name=INDEX33555553, table_name=TEST)
[2026-06-02 18:26:04][FAILED] check index error. index_id=33555553, table_name=TEST, location:
[2026-06-02 18:26:04][CHK] nbtr_check_index error: page(5, 0, 2912) is broken.
[2026-06-02 18:26:04]DM DB CHECK END......
[2026-06-02 18:26:04]
Checked Files Total: 4
Checked Indexes Total: 182
Error Indexes Total: 1
Checked Pages Total: 6477
Corrupted Pages Total: 0
Data Error Pages Total: 0
Invalidate Pages Total: 1
Checked Tablespaces Total: 4
Error List Total: 0
Checked Inodes Total: 2458
Error Inodes Total: 0
--确定损坏页号后,即可通过备份集进行修复
dmrman
--还原
RMAN> RESTORE PAGE [5, 0, 2912] DATABASE '/dmdata/5236/DMDB/dm.ini' FROM BACKUPSET '/dmbak/DB_BAK_FULL_20260602';
[Percent:100.00%][Speed:0.00M/s][Cost:00:00:02][Remaining:00:00:00]
restore successfully.
time used: 00:00:02.472
--恢复
RMAN> RECOVER PAGE [5, 0, 2912] DATABASE '/dmdata/5236/DMDB/dm.ini';
[Percent:100.00%][Speed:0.00PKG/s][Cost:00:00:00][Remaining:00:00:00]
recover successfully.
time used: 00:00:01.223
--再次进行数据页校验,损坏页已修复
dmdbchk path=/dmdata/5236/DMDB/dm.ini
[2026-06-02 18:34:40]INDEX=(id=33555553, name=INDEX33555553, table_name=TEST)
[2026-06-02 18:34:41]DM DB CHECK END......
[2026-06-02 18:34:41]
Checked Files Total: 4
Checked Indexes Total: 182
Error Indexes Total: 0
Checked Pages Total: 6477
Corrupted Pages Total: 0
Data Error Pages Total: 0
Invalidate Pages Total: 0
Checked Tablespaces Total: 4
Error List Total: 0
Checked Inodes Total: 2458
Error Inodes Total: 0
--修复后正常启库
[dmdba@DMHOST bin]$ DmServiceDMSERVER start
Starting DmServiceDMSERVER: [ OK ]
文章
阅读量
获赞
