本文档详细介绍DM数据库单表恢复与不完全恢复的实战操作,包括恢复原理、恢复策略规划、单表恢复操作、不完全恢复操作、恢复验证等内容,风哥教程参考DM官方文档《DM8备份与还原》手册,适合DBA人员进行数据恢复操作。
Part01-基础概念与理论知识
1.1 DM数据库单表恢复原理
DM数据库单表恢复是指仅恢复单个表的数据,而不需要恢复整个数据库。单表恢复适用于表数据误删除、表损坏等场景,是一种精细化的恢复方式。
单表恢复的工作原理:
- 基于备份集:从备份集中提取表数据
- 表结构重建:先重建表结构
- 数据恢复:将备份数据导入表中
- 一致性保证:确保恢复的数据与表结构一致
DM数据库单表恢复特点:
- 只恢复指定表,不影响其他表
- 恢复速度快,节省时间
- 适用于表数据误操作场景
- 需要有包含该表的备份集
1.2 DM数据库不完全恢复原理
DM数据库不完全恢复是指将数据库恢复到指定的时间点或SCN,而不是恢复到最新状态。不完全恢复适用于数据库误操作、数据损坏等需要回滚到特定时间点的场景。
不完全恢复的特点:
- 时间点恢复:恢复到指定时间点
- SCN恢复:恢复到指定SCN
- 日志应用:应用归档日志到指定点
- 数据库重置:需要重置日志
1.3 DM数据库恢复场景分析
DM数据库常见的恢复场景:
- 表数据误删除:用户误删除表数据
- 表结构损坏:表结构被破坏
- 数据库误操作:执行了错误的SQL语句
- 数据文件损坏:数据文件物理损坏
- 介质故障:存储介质故障
风哥提示:不同的恢复场景需要采用不同的恢复策略,DBA人员需要根据具体情况选择合适的恢复方法。
Part02-生产环境规划与建议
2.1 DM数据库恢复策略规划
生产环境DM数据库恢复策略规划要点:
# DM数据库恢复策略规划
#
# 单表恢复策略
– 备份策略:定期执行表级备份或全库备份
– 恢复工具:使用dexp/dimp或DMRMAN
– 恢复时间:根据表大小和备份情况,一般在分钟级 风哥提示:
#
# 不完全恢复策略
– 备份策略:确保有全库备份和完整的归档日志
– 恢复工具:使用DMRMAN
– 恢复时间:根据数据库大小和日志量,可能需要小时级
#
# 恢复演练
– 定期进行恢复演练
– 验证备份的可恢复性
– 测试不同场景的恢复时间
#
# 单表恢复策略
– 备份策略:定期执行表级备份或全库备份
– 恢复工具:使用dexp/dimp或DMRMAN
– 恢复时间:根据表大小和备份情况,一般在分钟级 风哥提示:
#
# 不完全恢复策略
– 备份策略:确保有全库备份和完整的归档日志
– 恢复工具:使用DMRMAN
– 恢复时间:根据数据库大小和日志量,可能需要小时级
#
# 恢复演练
– 定期进行恢复演练
– 验证备份的可恢复性
– 测试不同场景的恢复时间
2.2 DM数据库恢复准备工作
DM数据库恢复准备工作:
- 备份验证:确保备份集可用
- 归档日志:确保归档日志完整
- 恢复环境:准备恢复所需的环境
- 恢复工具:确保恢复工具可用
- 恢复计划:制定详细的恢复计划
2.3 DM数据库恢复工具选择
DM数据库恢复工具选择建议:
恢复工具选择:
- 单表恢复:dexp/dimp、DMRMAN
- 不完全恢复:DMRMAN
- 快速恢复:使用dexp/dimp导出导入
- 完整恢复:使用DMRMAN
Part03-生产环境项目实施方案
学习交流加群风哥微信: itpux-com
3.1 DM数据库单表恢复操作
3.1.1 使用dexp/dimp进行单表恢复
# 1. 从备份集中提取表数据
# 假设我们有一个全库备份,需要恢复fgedu.employee表
# 2. 创建临时表空间和用户
SQL> create tablespace temp_recover datafile ‘/dm/fgdata/fgedudb/temp_recover.dbf’ size 100m;
SQL> create user recover_user identified by “Recover123” default tablespace temp_recover;
SQL> grant dba to recover_user;
# 3. 恢复表结构
# 从备份中恢复表结构
$ dimp SYSDBA/SYSDBA@192.168.1.10:5236 \
file=/dm/backup/full/backup_full_20250409.bak \
owner=fgedu \
tables=employee \
include=table_structure \
log=/dm/backup/log/imp_table_structure.log
# 4. 恢复表数据
$ dimp SYSDBA/SYSDBA@192.168.1.10:5236 \
file=/dm/backup/full/backup_full_20250409.bak \
owner=fgedu \
tables=employee \
include=data \
log=/dm/backup/log/imp_table_data.log
# 5. 验证恢复结果
SQL> select count(*) from fgedu.employee;
行号 COUNT(*)
———- ———-
1 1000
# 6. 清理临时对象
SQL> drop user recover_user cascade;
SQL> drop tablespace temp_recover including contents and datafiles;
# 假设我们有一个全库备份,需要恢复fgedu.employee表
# 2. 创建临时表空间和用户
SQL> create tablespace temp_recover datafile ‘/dm/fgdata/fgedudb/temp_recover.dbf’ size 100m;
SQL> create user recover_user identified by “Recover123” default tablespace temp_recover;
SQL> grant dba to recover_user;
# 3. 恢复表结构
# 从备份中恢复表结构
$ dimp SYSDBA/SYSDBA@192.168.1.10:5236 \
file=/dm/backup/full/backup_full_20250409.bak \
owner=fgedu \
tables=employee \
include=table_structure \
log=/dm/backup/log/imp_table_structure.log
# 4. 恢复表数据
$ dimp SYSDBA/SYSDBA@192.168.1.10:5236 \
file=/dm/backup/full/backup_full_20250409.bak \
owner=fgedu \
tables=employee \
include=data \
log=/dm/backup/log/imp_table_data.log
# 5. 验证恢复结果
SQL> select count(*) from fgedu.employee;
行号 COUNT(*)
———- ———-
1 1000
# 6. 清理临时对象
SQL> drop user recover_user cascade;
SQL> drop tablespace temp_recover including contents and datafiles;
3.1.2 使用DMRMAN进行单表恢复
# 1. 启动DMRMAN
$ dmrman
dmrman V8
# 2. 恢复表空间到临时位置
RMAN> restore database ‘/dm/fgdata/fgedudb/dm.ini’ \ 学习交流加群风哥QQ113257174
tablespace fgedutbs \
to ‘/dm/temp_restore’ \
from backupset ‘/dm/backup/full/backup_full_20250409.bak’;
# 3. 挂载临时数据库
RMAN> mount database ‘/dm/temp_restore/dm.ini’;
# 4. 导出表数据
$ dexp SYSDBA/SYSDBA@192.168.1.11:5237 \
file=/dm/backup/exp/employee.dmp \
owner=fgedu \
tables=employee \
log=/dm/backup/log/exp_employee.log
# 5. 导入到目标数据库
$ dimp SYSDBA/SYSDBA@192.168.1.10:5236 \
file=/dm/backup/exp/employee.dmp \
owner=fgedu \
tables=employee \
log=/dm/backup/log/imp_employee.log
# 6. 清理临时文件
$ rm -rf /dm/temp_restore
$ rm -f /dm/backup/exp/employee.dmp
$ dmrman
dmrman V8
# 2. 恢复表空间到临时位置
RMAN> restore database ‘/dm/fgdata/fgedudb/dm.ini’ \ 学习交流加群风哥QQ113257174
tablespace fgedutbs \
to ‘/dm/temp_restore’ \
from backupset ‘/dm/backup/full/backup_full_20250409.bak’;
# 3. 挂载临时数据库
RMAN> mount database ‘/dm/temp_restore/dm.ini’;
# 4. 导出表数据
$ dexp SYSDBA/SYSDBA@192.168.1.11:5237 \
file=/dm/backup/exp/employee.dmp \
owner=fgedu \
tables=employee \
log=/dm/backup/log/exp_employee.log
# 5. 导入到目标数据库
$ dimp SYSDBA/SYSDBA@192.168.1.10:5236 \
file=/dm/backup/exp/employee.dmp \
owner=fgedu \
tables=employee \
log=/dm/backup/log/imp_employee.log
# 6. 清理临时文件
$ rm -rf /dm/temp_restore
$ rm -f /dm/backup/exp/employee.dmp
3.2 DM数据库不完全恢复操作
3.2.1 基于时间点的不完全恢复
# 1. 关闭数据库
$ disql SYSDBA/SYSDBA@192.168.1.10:5236
SQL> shutdown immediate;
# 2. 启动到mount状态
SQL> startup mount;
# 3. 执行不完全恢复
SQL> recover database until time ‘2025-04-09 10:00:00’;
# 4. 打开数据库(需要resetlogs)
SQL> alter database open resetlogs;
# 5. 验证恢复结果
SQL> select sysdate from dual;
行号 SYSDATE
———- ——————–
1 2025-04-09 10:00:00
# 6. 重新备份数据库
SQL> backup database full to ‘/dm/backup/full/backup_after_resetlogs.bak’; 更多视频教程www.fgedu.net.cn
$ disql SYSDBA/SYSDBA@192.168.1.10:5236
SQL> shutdown immediate;
# 2. 启动到mount状态
SQL> startup mount;
# 3. 执行不完全恢复
SQL> recover database until time ‘2025-04-09 10:00:00’;
# 4. 打开数据库(需要resetlogs)
SQL> alter database open resetlogs;
# 5. 验证恢复结果
SQL> select sysdate from dual;
行号 SYSDATE
———- ——————–
1 2025-04-09 10:00:00
# 6. 重新备份数据库
SQL> backup database full to ‘/dm/backup/full/backup_after_resetlogs.bak’; 更多视频教程www.fgedu.net.cn
3.2.2 基于SCN的不完全恢复
# 1. 确定目标SCN
# 假设我们需要恢复到SCN 1234567
# 2. 关闭数据库
SQL> shutdown immediate;
# 3. 启动到mount状态
SQL> startup mount;
# 4. 执行不完全恢复
SQL> recover database until scn 1234567;
# 5. 打开数据库
SQL> alter database open resetlogs;
# 6. 验证恢复结果
SQL> select current_scn from v$database;
行号 CURRENT_SCN
———- ————
1 1234567
# 假设我们需要恢复到SCN 1234567
# 2. 关闭数据库
SQL> shutdown immediate;
# 3. 启动到mount状态
SQL> startup mount;
# 4. 执行不完全恢复
SQL> recover database until scn 1234567;
# 5. 打开数据库
SQL> alter database open resetlogs;
# 6. 验证恢复结果
SQL> select current_scn from v$database;
行号 CURRENT_SCN
———- ————
1 1234567
3.3 DM数据库恢复验证操作
3.3.1 单表恢复验证
# 验证表结构
SQL> desc fgedu.employee;
行号 列名 数据类型 长度 小数位 允许空 值
———- ———— ——————– ———- ———- —— —-
1 EMP_ID INTEGER 10 0 N
2 EMP_NAME VARCHAR2 50 0 N
3 DEPT_ID INTEGER 10 0 Y
4 SALARY NUMBER 10 2 Y
5 HIRE_DATE DATE 8 0 Y
# 验证表数据
SQL> select count(*) from fgedu.employee;
行号 COUNT(*)
———- ———-
1 1000
# 验证数据完整性
SQL> select min(emp_id), max(emp_id) from fgedu.employee;
行号 MIN(EMP_ID) MAX(EMP_ID)
———- ———– ———– 更多学习教程公众号风哥教程itpux_com
1 1 1000
# 验证业务数据
SQL> select emp_name, salary from fgedu.employee where emp_id=1;
行号 EMP_NAME SALARY
———- ———– ———-
1 张三 5000.00
SQL> desc fgedu.employee;
行号 列名 数据类型 长度 小数位 允许空 值
———- ———— ——————– ———- ———- —— —-
1 EMP_ID INTEGER 10 0 N
2 EMP_NAME VARCHAR2 50 0 N
3 DEPT_ID INTEGER 10 0 Y
4 SALARY NUMBER 10 2 Y
5 HIRE_DATE DATE 8 0 Y
# 验证表数据
SQL> select count(*) from fgedu.employee;
行号 COUNT(*)
———- ———-
1 1000
# 验证数据完整性
SQL> select min(emp_id), max(emp_id) from fgedu.employee;
行号 MIN(EMP_ID) MAX(EMP_ID)
———- ———– ———– 更多学习教程公众号风哥教程itpux_com
1 1 1000
# 验证业务数据
SQL> select emp_name, salary from fgedu.employee where emp_id=1;
行号 EMP_NAME SALARY
———- ———– ———-
1 张三 5000.00
3.3.2 不完全恢复验证
# 验证数据库状态
SQL> select open_mode, database_status from v$database;
行号 OPEN_MODE DATABASE_STATUS
———- ——————– —————–
1 READ WRITE ACTIVE
# 验证恢复时间点
SQL> select sysdate from dual;
行号 SYSDATE
———- ——————–
1 2025-04-09 10:00:00
# 验证业务数据
SQL> select count(*) from fgedu.orders;
行号 COUNT(*)
———- ———-
500
# 验证数据库一致性
SQL> check database;
操作已执行
已用时间: 00:01:30.456
SQL> select open_mode, database_status from v$database;
行号 OPEN_MODE DATABASE_STATUS
———- ——————– —————–
1 READ WRITE ACTIVE
# 验证恢复时间点
SQL> select sysdate from dual;
行号 SYSDATE
———- ——————–
1 2025-04-09 10:00:00
# 验证业务数据
SQL> select count(*) from fgedu.orders;
行号 COUNT(*)
———- ———-
500
# 验证数据库一致性
SQL> check database;
操作已执行
已用时间: 00:01:30.456
Part04-生产案例与实战讲解
from DB视频:www.itpux.com
4.1 DM数据库表数据误删除恢复
以下是一个表数据误删除的恢复案例:
#
# 场景描述
用户误执行了delete语句删除了fgedu.employee表的所有数据
#
# 恢复步骤
# 1. 确认误操作时间
# 假设误操作发生在2025-04-09 14:30:00
# 2. 检查最近的备份
$ disql SYSDBA/SYSDBA@192.168.1.10:5236
SQL> select backup_name, backup_time from v$backupset
where backup_time < to_date('2025-04-09 14:30:00', 'yyyy-mm-dd hh24:mi:ss') order by backup_time desc; 行号 BACKUP_NAME BACKUP_TIME ---------- ------------------------ -------------------- 1 DB_FULL_20250409_020015 2025-04-09 02:00:15 # 3. 使用dexp导出表数据 $ dexp SYSDBA/SYSDBA@192.168.1.10:5236 \ file=/dm/backup/exp/employee_backup.dmp \ owner=fgedu \ tables=employee \ log=/dm/backup/log/exp_employee.log # 4. 导入表数据 $ dimp SYSDBA/SYSDBA@192.168.1.10:5236 \ file=/dm/backup/exp/employee_backup.dmp \ owner=fgedu \ tables=employee \ ignore=y \ log=/dm/backup/log/imp_employee.log # 5. 验证恢复结果 SQL> select count(*) from fgedu.employee;
行号 COUNT(*)
———- ———-
1 1000
# 6. 确认数据完整性
SQL> select * from fgedu.employee where emp_id=1000;
行号 EMP_ID EMP_NAME DEPT_ID SALARY HIRE_DATE
———- ———– ———– ———– ———- ———-
1 1000 李四 10 8000.00 2025-01-15
# 场景描述
用户误执行了delete语句删除了fgedu.employee表的所有数据
#
# 恢复步骤
# 1. 确认误操作时间
# 假设误操作发生在2025-04-09 14:30:00
# 2. 检查最近的备份
$ disql SYSDBA/SYSDBA@192.168.1.10:5236
SQL> select backup_name, backup_time from v$backupset
where backup_time < to_date('2025-04-09 14:30:00', 'yyyy-mm-dd hh24:mi:ss') order by backup_time desc; 行号 BACKUP_NAME BACKUP_TIME ---------- ------------------------ -------------------- 1 DB_FULL_20250409_020015 2025-04-09 02:00:15 # 3. 使用dexp导出表数据 $ dexp SYSDBA/SYSDBA@192.168.1.10:5236 \ file=/dm/backup/exp/employee_backup.dmp \ owner=fgedu \ tables=employee \ log=/dm/backup/log/exp_employee.log # 4. 导入表数据 $ dimp SYSDBA/SYSDBA@192.168.1.10:5236 \ file=/dm/backup/exp/employee_backup.dmp \ owner=fgedu \ tables=employee \ ignore=y \ log=/dm/backup/log/imp_employee.log # 5. 验证恢复结果 SQL> select count(*) from fgedu.employee;
行号 COUNT(*)
———- ———-
1 1000
# 6. 确认数据完整性
SQL> select * from fgedu.employee where emp_id=1000;
行号 EMP_ID EMP_NAME DEPT_ID SALARY HIRE_DATE
———- ———– ———– ———– ———- ———-
1 1000 李四 10 8000.00 2025-01-15
4.2 DM数据库表损坏恢复
以下是一个表损坏的恢复案例:
#
# 场景描述
fgedu.employee表由于存储介质故障导致损坏
#
# 恢复步骤
# 1. 确认表损坏
SQL> select count(*) from fgedu.employee;
执行失败,出现错误:表损坏
# 2. 使用DMRMAN恢复表空间
$ dmrman
# 3. 恢复表空间
RMAN> restore database ‘/dm/fgdata/fgedudb/dm.ini’ \
tablespace fgedutbs \
from backupset ‘/dm/backup/full/backup_full_20250409.bak’;
# 4. 恢复表空间
RMAN> recover database ‘/dm/fgdata/fgedudb/dm.ini’ \
tablespace fgedutbs;
# 5. 验证表恢复
SQL> select count(*) from fgedu.employee;
行号 COUNT(*)
———- ———-
1 1000
# 6. 验证表数据
SQL> select emp_name, salary from fgedu.employee where emp_id=1;
行号 EMP_NAME SALARY
———- ———– ———-
1 张三 5000.00
# 场景描述
fgedu.employee表由于存储介质故障导致损坏
#
# 恢复步骤
# 1. 确认表损坏
SQL> select count(*) from fgedu.employee;
执行失败,出现错误:表损坏
# 2. 使用DMRMAN恢复表空间
$ dmrman
# 3. 恢复表空间
RMAN> restore database ‘/dm/fgdata/fgedudb/dm.ini’ \
tablespace fgedutbs \
from backupset ‘/dm/backup/full/backup_full_20250409.bak’;
# 4. 恢复表空间
RMAN> recover database ‘/dm/fgdata/fgedudb/dm.ini’ \
tablespace fgedutbs;
# 5. 验证表恢复
SQL> select count(*) from fgedu.employee;
行号 COUNT(*)
———- ———-
1 1000
# 6. 验证表数据
SQL> select emp_name, salary from fgedu.employee where emp_id=1;
行号 EMP_NAME SALARY
———- ———– ———-
1 张三 5000.00
4.3 DM数据库基于时间点的不完全恢复
以下是一个基于时间点的不完全恢复案例:
#
# 场景描述
用户执行了错误的批量更新操作,需要回滚到操作前的状态
#
# 恢复步骤
# 1. 确认错误操作时间
# 假设错误操作发生在2025-04-09 15:00:00
# 2. 关闭数据库
SQL> shutdown immediate;
# 3. 启动到mount状态
SQL> startup mount;
# 4. 执行不完全恢复
SQL> recover database until time ‘2025-04-09 14:59:59’;
# 5. 打开数据库
SQL> alter database open resetlogs;
# 6. 验证恢复结果
SQL> select count(*) from fgedu.orders;
行号 COUNT(*)
———- ———-
500
# 7. 确认错误操作已回滚
SQL> select * from fgedu.orders where order_id=100;
行号 ORDER_ID CUSTOMER_ID AMOUNT ORDER_DATE
———- ———– ———– ———- ———-
1 100 101 1000.00 2025-04-08
# 8. 重新备份数据库
SQL> backup database full to ‘/dm/backup/full/backup_after_recovery.bak’;
# 场景描述
用户执行了错误的批量更新操作,需要回滚到操作前的状态
#
# 恢复步骤
# 1. 确认错误操作时间
# 假设错误操作发生在2025-04-09 15:00:00
# 2. 关闭数据库
SQL> shutdown immediate;
# 3. 启动到mount状态
SQL> startup mount;
# 4. 执行不完全恢复
SQL> recover database until time ‘2025-04-09 14:59:59’;
# 5. 打开数据库
SQL> alter database open resetlogs;
# 6. 验证恢复结果
SQL> select count(*) from fgedu.orders;
行号 COUNT(*)
———- ———-
500
# 7. 确认错误操作已回滚
SQL> select * from fgedu.orders where order_id=100;
行号 ORDER_ID CUSTOMER_ID AMOUNT ORDER_DATE
———- ———– ———– ———- ———-
1 100 101 1000.00 2025-04-08
# 8. 重新备份数据库
SQL> backup database full to ‘/dm/backup/full/backup_after_recovery.bak’;
Part05-风哥经验总结与分享
5.1 DM数据库恢复最佳实践
基于多年DM数据库运维经验,总结以下恢复最佳实践:
- 备份策略:建立完善的备份策略,确保有可用的备份
- 恢复演练:定期进行恢复演练,验证备份的可恢复性
- 恢复计划:制定详细的恢复计划,明确恢复步骤
- 时间点确定:准确确定恢复时间点,避免数据丢失
- 验证测试:恢复后进行充分的验证测试
- 文档记录:记录恢复过程,便于后续分析
生产环境建议:恢复操作是高风险操作,建议在测试环境演练后再在生产环境执行。恢复前应备份当前状态,以便在恢复失败时回滚。
5.2 DM数据库恢复常见问题
DM数据库恢复常见问题及解决方案:
#
# 问题1:恢复失败,提示缺少归档日志
#
# 原因分析
– 归档日志不完整
– 备份集中缺少必要的日志
#
# 解决方案
– 确保归档日志完整
– 从其他备份中获取缺失的日志
– 考虑使用不完全恢复
#
# 问题2:单表恢复后数据不一致
#
# 原因分析
– 表依赖关系未考虑
– 外键约束冲突
#
# 解决方案
– 同时恢复相关表
– 暂时禁用外键约束
– 恢复后重建约束
#
# 问题3:不完全恢复后数据库无法打开
#
# 原因分析
– 恢复时间点选择不当
– 日志应用不完整
#
# 解决方案
– 重新执行恢复,选择合适的时间点
– 确保所有必要的归档日志可用
– 使用resetlogs打开数据库
# 问题1:恢复失败,提示缺少归档日志
#
# 原因分析
– 归档日志不完整
– 备份集中缺少必要的日志
#
# 解决方案
– 确保归档日志完整
– 从其他备份中获取缺失的日志
– 考虑使用不完全恢复
#
# 问题2:单表恢复后数据不一致
#
# 原因分析
– 表依赖关系未考虑
– 外键约束冲突
#
# 解决方案
– 同时恢复相关表
– 暂时禁用外键约束
– 恢复后重建约束
#
# 问题3:不完全恢复后数据库无法打开
#
# 原因分析
– 恢复时间点选择不当
– 日志应用不完整
#
# 解决方案
– 重新执行恢复,选择合适的时间点
– 确保所有必要的归档日志可用
– 使用resetlogs打开数据库
5.3 DM数据库恢复检查清单
DM数据库恢复检查清单:
- 恢复前检查:
- 确认备份集可用
- 确认归档日志完整
- 制定恢复计划
- 备份当前状态
- 恢复中检查:
- 监控恢复过程
- 检查恢复日志
- 确认无错误发生
- 恢复后检查:
- 验证数据库状态
- 验证业务数据
- 测试应用连接
- 重新备份数据库
风哥提示:恢复操作是数据库运维中的重要技能,DBA人员需要熟练掌握各种恢复方法,并定期进行恢复演练,确保在关键时刻能够快速、准确地完成恢复操作。
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
