拓冰建站拓冰建站
首页 / 资讯中心 / 正文

RMAN异机恢复保姆级教程:从备份到Oracle完整恢复

去年年中我接手了一套Oracle 11g生产库的容灾改造客户的核心诉求很直接万一服务器硬件挂了要在4小时内把业务拉起来。最有意思的是客户还补了一句——新机器还没采购等机器到了再演练。到了演练那天新机器倒是到了可源库已经因为存储控制器故障彻底起不来了。说实话这种“假想敌式”的异机恢复是每个DBA迟早都会遇到的硬仗区别只是有人提前演练过有人只能临场发挥。当时我们手里的牌只有一份前天晚上自动跑的RMAN全量备份加上一个全新的Linux主机。我用RMAN走了一遍完整的异机恢复流程从参数文件、控制文件、数据文件到归档日志回放最后一次open成功业务提前一小时恢复。整套操作下来复盘时发现真正让新手翻车的地方其实是那些看起来“不是技术问题”的细节备份文件怎么传到新机器、目录结构怎么对齐、环境和权限怎么校验。所以这篇教程我想完全站在一个“新机器上什么都没有”的起点把RMAN异机恢复拆成保姆级步骤每一步都告诉你为什么要这么做以及做错了最惨会是什么后果。1. 为什么需要异机恢复RMAN在这里扮演什么角色1.1 什么样的场景必须走异机恢复大家最容易混淆的一个概念就是“同机恢复”和“异机恢复”。同机恢复比如我把数据文件误删了或者某个表空间损坏了直接在原机器上拿备份恢复这种操作相对简单因为实例名、数据库路径、操作系统环境都是现成的RMAN在恢复时基本不需要做额外的“环境适配”。异机恢复则完全不同。源库物理机彻底损坏、机房搬迁、云迁移、灾备演练或者像我们这次一样——原机器已经点不亮了只能在全新的主机上重建一套Oracle环境再从备份中把数据拉回来。这种场景下你面对的不只是数据文件本身还有一整套环境变量的重建目录结构、权限、监听、参数文件、口令文件、甚至数据库的DBID是否一致。任何一个环节对不上恢复流程就会在中途报错甚至恢复完成后数据库根本打不开。还有一个高频场景大家需要注意如果只是把数据库迁移到另一台配置更好的服务器但源库还活着那往往不会选RMAN异机恢复而是更倾向于DataGuard、逻辑导出导入或者可传输表空间。只有当源库不可用、或者你希望得到一个与源库完全一致的物理副本时RMAN异机恢复才是最优先方案。1.2 异机恢复的底层逻辑和潜在风险RMAN异机恢复的核心原理是通过备份集中保存的“数据库物理快照”外加归档日志的“增量回放”在目标机上重建出一个和源库在某一个时间点完全一致的数据库。从底层看就是三件事把数据文件复制到指定目录、利用控制文件获得文件清单与SCN信息、用归档日志把数据库前滚到一致性状态。但异机恢复之所以比同机恢复麻烦核心在于“环境差异”路径差异源库数据文件可能在/u01/app/oracle/oradata/PROD/目标机可能装在了/data/oradata/这需要参数转换或用文件挂载方式解决。实例名与数据库名差异目标机的ORACLE_SID往往与源库不同而控制文件内部记录的是源库名恢复后需要处理。DBID一致性问题如果目标机不小心用DBCA建了一个同名的空库DBID不同会导致RMAN在恢复控制文件时报“RMAN-06496: database id mismatch”之类的错误。归档日志缺失如果备份是全量备份但备份之后还有新的归档日志没有同步到目标机恢复时数据库会提示需要更多恢复也就是我们常说的“缺日志”。我在实际执行中会先把这些风险列成一张核对表一项项确认后才开始操作。很多人做异机恢复失败根本不是RMAN命令记错了而是环境差异没有提前处理。所以接下来这两节我会先讲清楚备份策略怎么做才够用以及目标机环境核查时要注意哪些细节。2. 动手之前备份策略与目标机环境准备2.1 源库备份怎么做才够用异机恢复能不能成功很大程度上在你按下“备份”按钮的那一刻就已经决定了。不要指望在生产库跑一个只有数据文件没有归档日志的裸备份就能异机恢复除非你能接受恢复到“备份开始的那个时间点”之后所有数据全部丢失。所以我们这边备份脚本有一个铁律全量备份必须带上前置和后置的归档日志备份。我推荐的最简可用备份策略是这样写的#!/bin/bash export ORACLE_SIDPROD export ORACLE_HOME/u01/app/oracle/product/11.2.0/dbhome_1 export PATH$ORACLE_HOME/bin:$PATH rman target / log/home/oracle/backup/rman_full_$(date %Y%m%d_%H%M%S).log EOF run { allocate channel c1 type disk maxpiecesize 5G; backup database plus archivelog delete input format /home/oracle/backup/full_%U.bak; backup current controlfile format /home/oracle/backup/ctl_%U.bak; backup spfile format /home/oracle/backup/spfile_%U.bak; release channel c1; } crosscheck backup; delete noprompt obsolete; exit; EOF这里我用了plus archivelog意思是备份数据文件之前先备份归档日志数据文件备份完成后再备份一次归档日志这样备份集内部的SCN就是连续的恢复时不需要额外的归档也能把库拉到一致状态。另一个核心选项是current controlfile和spfile这俩文件在异机恢复中是“引路文件”没有它们你甚至没法把数据库启动到nomount状态。有一点要提醒大家如果源库是RAC环境或者开启了FRA但归档日志存放在共享存储上的切归档日志的时候一定要确认所有实例的归档都落盘了再执行备份。很多RAC环境下异机恢复失败就是因为某个节点实例的归档日志没有完全纳入备份集。2.2 目标机环境核对手册新机器到手后不要急着装数据库。先把下面这几项逐一确认每确认一项就打一个勾这一步能帮你过滤掉七成以上的中途报错。目标机环境核对项操作系统版本与架构x86_64还是aarch64必须和源库兼容这不要求完全一致但Oracle对操作系统有认证列表安装前建议查一下。Oracle软件版本与补丁级别。注意这里的核心原则是小版本可以跨一两个补丁集但尽量保持一致。比如源库是11.2.0.4目标机也装11.2.0.4不要用11.2.0.1否则恢复成功后部分内部表结构不兼容会导致异常。磁盘分区与空间规划。数据文件需要的空间至少是源库数据文件总大小的1.2倍再加一份归档日志的空间建议是数据文件的30%以上不要算得太紧。安装路径是否一致。这一步最关键也是新手最容易踩的坑。如果目标机的ORACLE_BASE或ORACLE_HOME路径和源库不一致那恢复控制文件之后RMAN会拿着控制文件里的原路径去找数据文件结果当然是“文件不存在”。要么你就让目标机的数据文件路径和源库完全一致要么提前想好路径转换方案。数据库DBID记录。备份完成后源库的DBID可以通过sqlplus / as sysdba然后执行select dbid from v$database;查到。把这个值记下来目标机建实例时不要去创建任何同名的数据库避免DBID冲突。这里顺便解释一下为什么很多教程都强调“最好用一致的文件系统路径”。因为Oracle控制文件内部保存的是绝对路径RMAN恢复时默认会按照控制文件记录的路径去定位文件。如果你在目标机上把ORACLE_HOME和ORACLE_BASE按照源库的习惯安装数据文件就能原路径落盘省去后面所有路径转换的麻烦。这也是我个人的习惯——异机恢复时尽量“一比一复刻”目录结构减少变量。3. 实操恢复全流程按这个顺序做一次成功3.1 搭建基础实例环境并启动到nomount目标机装好Oracle软件后我们需要先手动建一个空的实例但注意不要用DBCA建库。这一步的目的只有一个实例进程能起来能通过SQL*Plus连上。DBCA建库会生成数据文件、控制文件这些后面反而要删掉属于画蛇添足。正确做法是手工创建参数文件和密码文件。先以oracle用户登录设置环境变量export ORACLE_SIDRMANDB export ORACLE_HOME/u01/app/oracle/product/11.2.0/dbhome_1 export PATH$ORACLE_HOME/bin:$PATH export NLS_LANGAMERICAN_AMERICA.AL32UTF8然后创建密码文件orapwd file$ORACLE_HOME/dbs/orapwRMANDB passwordoracle forcey接着创建一个最简的pfile先放在$ORACLE_HOME/dbs/initRMANDB.oradb_nameRMANDB db_block_size8192 db_files200 memory_target2G control_files/u01/app/oracle/oradata/RMANDB/control01.ctl,/u01/app/oracle/oradata/RMANDB/control02.ctl这里要注意db_name这个参数先随便写后面恢复spfile时会覆盖。创建好之后启动到nomountsqlplus / as sysdbastartup nomount;如果这里报错比如ORA-01565: unable to open control file多半是控制文件路径不存在先手动创建目录再启动。3.2 恢复参数文件并确认关键参数实例进入nomount状态后我们就要把源库的spfile从备份中捞出来。这一步非常重要因为源库可能设置了很多自定义参数比如SGA大小、undo表空间名、审计目录、DB_FILES等如果用手工创建的pfile直接启动很可能因为某个参数配置缺失导致后续动作异常。RMAN中恢复spfile的常用方式有两种。第一种如果备份脚本里包含了spfile备份可以直接这样rman target /startup nomount; restore spfile from /home/oracle/backup/spfile_xxxx.bak; shutdown immediate; startup nomount;第二种如果没有单独备份spfile但是开启了自动备份控制文件那么控制文件备份集中会自动附带spfile可以这样写restore spfile from autobackup;恢复spfile之后实例会重新读取新参数文件所以需要重启一次实例。重启之后立刻执行show parameter db_name; show parameter control_files;这时候你就会看到源库真实的数据库名和控制文件路径。如果你在目标机上用的目录和源库不一样这里就要开始做路径转换了。最简单的方式是重建一个pfile在源库spfile基础上添加db_file_name_convert和log_file_name_convert参数把原路径映射到新路径。举个例子*.db_file_name_convert/u01/app/oracle/oradata/PROD/,/data/oradata/RMANDB/ *.log_file_name_convert/u01/app/oracle/oradata/PROD/,/data/oradata/RMANDB/然后重启实例。这一步决定了后面恢复数据文件到底落盘到哪里务必先确认路径没问题再继续。3.3 恢复控制文件并注册备份集参数文件就位之后接下来是异机恢复中最容易翻车的一步——恢复控制文件。控制文件里藏着全库的数据文件清单、SCN信息、日志文件序列号没有它RMAN完全没法工作。先确保实例处于nomount状态然后执行restore controlfile from /home/oracle/backup/ctl_xxxx.bak;如果备份集用的是autobackup方式命令则写成restore controlfile from autobackup;控制文件恢复成功后实例会自动把控制文件写到参数文件指定的路径。紧接着我们需要把数据库切到mount状态alter database mount;到这一步数据库就能读到控制文件了。但此时RMAN的备份集信息还没有注册到新控制文件里所以我们要让RMAN重新扫描备份目录catalog start with /home/oracle/backup/;这一步会把目录下所有备份片都登记到控制文件中。如果你的备份文件是通过网络传过来的或者做过改名那就更依赖这条命令。随后可以执行list backup summary;验证一下确认数据文件备份集和归档日志备份集都已经可见。3.4 restore数据文件与归档日志回放控制文件就绪后就可以正式恢复数据文件了。这一步逻辑非常简单但耗时会比较长中途千万不要中断。在RMAN中执行restore database;RMAN会按照控制文件里的文件清单从备份集中把数据文件逐一还原到目标目录。如果你的路径做过db_file_name_convert转换那么此时应该可以看到RMAN正在把文件写到新路径下。如果一直报类似RMAN-06172: no autobackup found or handle is not a valid backup piece这种错误九成是catalog start with那一步漏掉了。restore完成后紧接着执行recover database;recover阶段会读取归档日志把数据文件从备份时间点前滚到归档日志能覆盖到的最新一致状态。如果备份是全量且带plus archivelog并且中间没有任何中断recover一般会很顺利。如果备份之后还产生了新的归档日志且没有传到目标机recover就会提示需要更多日志这时候请把源库最新归档日志传过来再执行一遍recover database;否则数据库会缺少数据。这里专门提醒一下recover阶段不要使用until time或者until scn这类条件子句除非你有明确的恢复目标时间点。我们做异机恢复的默认目标就是把数据库恢复到“备份集加归档能恢复到的最近一致点”不加条件的recover正好能做到这一点。3.5 重建redo日志组与打开数据库到这一步很多教程会直接教你执行alter database open resetlogs;但其实有个细节需要先处理——联机重做日志redo log。RMAN备份时默认不会备份联机重做日志控制文件里记录的redo日志路径还是源库的直接open的话大概率会报ORA-00313: cannot open member这类错误。解决办法是先清理旧的redo日志组再重建。注意所有redo日志文件必须存在且可写才能正常open数据库。在SQL*Plus中执行alter database backup controlfile to trace as /tmp/controlfile.sql;这步先把控制文件的创建脚本导出以防后面需要重建控制文件。然后查看当前日志组成员select group#, member from v$logfile;如果路径不存在可以先通过文件系统创建目录然后将日志文件重新定位alter database rename file /u01/app/oracle/oradata/PROD/redo01.log to /u01/app/oracle/oradata/RMANDB/redo01.log;当然如果控制文件里的redo日志路径和目标机的实际路径不一致且无法修改最省事的办法是先删除redo日志组再重建。但请注意删除redo log group必须保证当前组至少有两个可用成员且不能删除active状态所在的组。所以我更推荐直接用alter database rename file或者确保路径一致。处理好redo日志后就可以打开数据库了alter database open resetlogs;resetlogs的含义是重置重做日志序列号同时会建立一个新的数据库incarnation。这是异机恢复之后几乎必做的一步因为我们的恢复过程用到了归档日志控制文件里的日志序列和源库已经不一致了。open成功后会看到“Database altered.”这时候打个select status from v$instance;确认一下如果显示OPEN恭喜主力数据已经回来了。4. 恢复后的收尾与验证别急着交差4.1 临时表空间与密码文件的处理数据库成功open之后有至少三个收尾动作不能漏否则业务一连上就开始报错。第一是临时表空间。RMAN恢复不会自动重建临时表空间文件tempfile需要手动添加。先看当前临时表空间有哪些select tablespace_name from dba_tablespaces where contentsTEMPORARY;然后重建默认临时表空间alter tablespace temp add tempfile /u01/app/oracle/oradata/RMANDB/temp01.dbf size 2G autoextend on next 512M maxsize 32G; alter database default temporary tablespace temp;第二是口令文件。前面我们创建的是orapwRMANDB如果实际数据库名和实例名不同或者密码文件路径对不上远程连接时sys用户会认证失败。建议直接重建一次口令文件把sys密码设置成业务方提供的密码orapwd file$ORACLE_HOME/dbs/orapwRMANDB passwordYourStrongPass forcey第三是监听配置。很多DBA做完恢复后本地连接一切正常但应用服务器连不上。这通常是listener.ora里还没配上这个实例。最简单的做法是用netca配置一个监听或者手工编辑$ORACLE_HOME/network/admin/listener.ora把数据库服务名注册进去。改完之后重启监听lsnrctl stop lsnrctl start lsnrctl status4.2 业务连通性验证清单验证阶段不要光看数据库能open就宣布成功必须按下面的清单走一遍用业务账号远程连接测试。例如sqlplus biz_user/password//目标IP:1521/RMANDB确认监听和口令都对。做一次全表扫描级联查询。挑几张数据量较大的表跑一个select count(*) from big_table;确认数据文件IO正常。查看告警日志。到$ORACLE_HOME/diag/rdbms/下找到对应实例的alert_*.log重点看有没有ORA-00600、ORA-07445这类内部错误。检查无效对象。执行select count(*) from dba_objects where statusINVALID;如果和源库的无效对象基数差不太多就是正常的如果激增需要重点排查。确认归档日志是否正常写入。执行archive log list;确认Automatic archival是Enabled否则后续没有归档日志数据库只能恢复到当前点再出问题就麻烦了。5. 常见问题与排查实录5.1 问题速查表我把这次异机恢复期间遇到的和朋友反馈过的问题整理成了速查表方便大家真到报错时快速定位。报错信息含义解决思路ORA-01194: file 1 needs more recovery to be consistent数据文件缺少后续归档日志无法前滚到一致点把源库备份之后的归档日志补传到目标机再次执行recover database;ORA-00313: cannot open member of log groupredo日志路径不对或文件不存在用alter database rename file重新定位到目标机实际路径或重建日志组RMAN-06172: no autobackup found or handle is not a valid backup piece控制文件恢复时指定了错误的备份片或autobackup路径不对确认备份片完整路径或者检查FRA中是否有autobackup文件RMAN-06496: database id mismatch目标库的DBID和备份集不匹配确认没有在目标机上用DBCA建过同名数据库必要时重建控制文件或用force选项ORA-01589: must use RESETLOGS or NORESETLOGS option for database open由于恢复导致的日志序列不匹配必须指定open模式执行alter database open resetlogs;ORA-00376: file not readable数据文件处于offline或路径不可读检查文件系统权限确认数据文件在线状态必要时alter database datafile ... online;数据库open后业务账号登录失败口令文件密码和业务期望密码不一致或监听未注册服务重建口令文件检查监听状态重启监听5.2 几个我踩过的坑和心得做异机恢复这么多次印象最深的一次翻车是在restore完数据文件后recover不停报缺少某个归档日志。排查了半天发现是因为源库开了FRA归档日志同时写了本地目录和FRA而RMAN备份时plus archivelog把FRA里的归档也当作数据文件备份的一部分处理了但传输备份集的时候只拷了磁盘上的一部分文件。所以我现在做备份时习惯用backup database plus archivelog delete input把归档日志从源库直接删掉不给“漏拷”留任何余地。另一个很实用的心得是恢复前先把备份集完整传到目标机磁盘不要在恢复过程中用NFS或远程挂载直接读。NFS在大量IO时会不稳定一旦中途断掉RMAN会话直接挂掉所有数据文件前功尽弃。传完文件后可以用cksum或rman validate校验一下备份集完整性特别是一次性传大量小文件的场景。最后想强调一个经常被忽略的细节恢复完成后立刻做一次全库备份。因为此时数据库刚经历过resetlogs重新生成了一套新的incarnation这个新incarnation没有任何历史备份保护万一接下来几天出问题唯一的恢复路径就是这次备份。很多人觉得刚恢复完没必要马上备份结果几天后误删数据才发现没有可用的备份集这种教训实在太常见了。根据我的实际操作经验RMAN异机恢复并没有想象中那么高不可攀它更像是把备份、控制文件、参数文件、归档日志这些基础概念串成一个完整闭环的过程。只要提前把环境差异、路径规划和备份完整性这三件事做到位按这个教程一步步执行一次成功的概率非常高。真到需要你操作的时候深呼吸先核对环境再走流程别跳步。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门