目录
前言
最近有客户的 shareplex 因为一些稀奇古怪的原因又挂了,由于邮件告警问题,没有及时通知到,并且归档已经被删除,备份也追溯不回丢失的归档日志。
经过与客户确认repo库没有历史数据需保留,直接重建修复!
准备
确认以下条件均已具备:
- 有可用备份;
- 磁盘空间足够;
- 由于使用 networker 备份,需要提前安装备份恢复所需客户端;
本次重建目标端使用 rman 进行全库恢复。
重建过程
确认数据库大小
selectsum(bytes/1024/1024/1024) fromdba_segments; selectsum(bytes/1024/1024/1024) fromdba_data_files;
确认目标端磁盘空间足够!
确认备份可用
--查询备份setline222setpagesize100colstatusfora10colinput_typefora20colINPUT_BYTES_DISPLAYfora10colOUTPUT_BYTES_DISPLAYfora10colTIME_TAKEN_DISPLAYfora10selectinput_type, status, to_char(start_time, 'yyyy-mm-dd hh24:mi:ss'), to_char(end_time, 'yyyy-mm-dd hh24:mi:ss'), input_bytes_display, output_bytes_display, time_taken_display, COMPRESSION_RATIOfromv$rman_backup_job_detailswherestart_time>date'2021-08-10'orderby3desc;
listbackupofcontrolfile;
ctrl_mesdbtj_65271_1_1081487814
确认最新的有效备份,记录控制文件。
安装 networker 客户端
安装包上传目标端安装
lgtoclnt-9.2.1.4-1.x86_64.rpmlgtonmda-9.2.1.4-1.x86_64.rpm
建议使用 yum install
进行安装,防止依赖包缺失,前提是 yum 源已配置。
按顺序安装:
yuminstall-ylgtoclnt-9.2.1.4-1.x86_64.rpmsystemctlstartnetworkersystemctlstartnetworkeryuminstall-ylgtonmda-9.2.1.4-1.x86_64.rpm
lgtoclnt
安装完成后,确保服务正常运行,再安装 lgtonmda
。
配置解析
必须将目标端和源端,networker 服务端的ip和主机名解析全部写入 /etc/hosts 文件。
目标端链接 NMO 库文件
cd$ORACLE_HOME/libln–s/usr/lib/libnwora.solibobk.so
至此,networker 目标端已安装完成。
清理 shareplex 旧环境
源端和目标端关闭 shareplex
sp_ctrlshutdown
源端和目标端执行清理脚本
/quest/bin/ora_cleanspsplex2300/splex2300/data/quest/bin/ora_cleanspsplex2300/splex2300
源端和目标端重新开启 shareplex 环境
sp_cop-u2300&
本文 shareplex 使用端口为 2300,读者需根据实际情况更换,如 2400、2500 等。
目标端停止 post 进程
stoppost
最后全部恢复完毕之后再开启。
开始 rman 恢复
确保目标端数据库已开启到 nomount 状态。
恢复控制文件
连接 rman 客户端后执行恢复控制文件:
run { allocatechannelc1type'SBT_TAPE'; send'NSR_ENV=(NSR_SERVER=这里填写 networker 服务端主机名,NSR_CLIENT=这里填写源端备份主机名)'; restorecontrolfilefrom'这里填写最新备份控制文件名称'; releasechannelc1; } ``恢复完之后开启目标端数据库到mount状态。###恢复数据由于数据库大概有1-2T的大小,恢复时间很长,因此建议将恢复脚本放在后台进行执行,脚本如下:```bash#!/bin/bashsource~/.bash_profilebacktime=`date+"20%y%m%d%H%M%S"`rmantarget/log=/home/oracle/rman_repo_$backtime.log<<EOFrun { allocatechannelc1type'SBT_TAPE'; allocatechannelc2type'SBT_TAPE'; allocatechannelc3type'SBT_TAPE'; allocatechannelc4type'SBT_TAPE'; send'NSR_ENV=(NSR_SERVER=这里填写 networker 服务端主机名,NSR_CLIENT=这里填写源端备份主机名)'; setnewnamefordatabaseto'/data/mesdb/%b'; restoredatabase; switchdatafileall; recoverdatabase; releasechannelc1; releasechannelc2; releasechannelc3; releasechannelc4; } exit; EOF
执行 sh rman_sp.sh &
进行后台恢复。
📢 注意: 通道根据实际情况进行修改,由于源端是 rac 环境,目标端是单机环境,因此数据文件路径需要 set newname
进行转换,最后执行初次 recover database
。
备份恢复完之后,由于缺少归档,所以需要追归档。
追归档日志
由于备份时间与当前时间存在较大时差,在获取当前源端的 scn 进行 recover 时,必然需要追大量的归档日志文件,为了减少 shareplex 积压,因此提前追归档日志到当前时间。
源端备份归档日志到当前最新:
backuparchivelogfromsequence71457untilsequence71986thread1; backuparchivelogfromsequence65247untilsequence65780thread2;
备份成功后拷贝至目标端,注册目录后执行 recover
:
catalogstartwith'/data/archivelog/'; recoverdatabase;
追完归档之后,激活源端 shareplex 的 config 文件。
激活源端 config 配置文件
listconfigactivateconfigORA_config_20210825nolockshowconfig
激活成功后,检查源端数据库中是否存在 长事务。
selectstart_timefromgv$transaction;
如果有长事务,可以确实是否可以杀掉,杀掉后才能继续操作。
根据以下 SQL 可以获取到事务的详细情况:
setlinesize260pagesize10000columnsessformata21heading"SESSION"columnprogramformata18columnclnt_pidformata8columnmachineformata25columnusernameformata12columnosuserformata13columneventformata32columnwaitsecformat999999columnstart_timeformata18columnsql_idformata15columnclnt_userformata10columnsvr_ospidformata10ALTERSESSIONSETNLS_DATE_FORMAT='yyyy/mm/dd hh24:mi:ss'; setfeedbackoffsetechooffsetheadoffselectchr(9) fromdual; select'Waiting Transactions'||chr(10)||'===================='fromdual; setheadonselect/*+ rule */lpad(nvl(s.username,' '),8)||'('||s.sid||','||s.serial#||')'assess, p.spidassvr_ospid, nvl(osuser,' ') asclnt_user, s.processasclnt_pid, substr((caseinstr(s.PROGRAM, '@') when0thens.programelsecaseinstr(s.PROGRAM, '(TNS V1-V3)') when0thensubstr(s.program, 1, instr(s.PROGRAM, '@') -1) ||substr(s.program, instr(s.PROGRAM, '(') -1) elsesubstr(s.program, 1, instr(s.PROGRAM, '@') -1) endend), 1, 18) asprogram, (casewhenlength(s.MACHINE) >8thensubstr(s.machine,1,8)||'~'elses.machineend ) ||'('||nvl(s.client_info, 'Unknown IP')||')'asmachine, s.sql_id, substr(s.event, 1, 32) asevent, s.seconds_in_waitaswaitsecfromv$transactiont,v$sessions,v$processpwheret.ses_addr=s.saddrands.paddr=p.addrorderbys.seconds_in_wait, s.program, s.machine;
可以通过 SESSION
字段来杀掉事务:
altersystemkillsession'1841,44697';
如果杀不掉,则使用 svr_ospid
系统层进行 kill:
kill-927353
确认没有长事务后,继续下一步操作。
源端获取 scn 号
colcurrent_scnformat9999999999999999selectcurrent_scnfromv$database;
记录获取到的 SCN 号:72863106548
。
目标端 rman 恢复至指定 scn
recoverdatabaseuntilscn72863106548;
因为源端一直在运行,激活期间到SCN号必然会有新的归档产生,提示缺少归档日志,因此需要去源端拷贝缺少的归档日志,再次进行 recover。
目标端开启 resetlogs 状态
alterdatabaseopenresetlogs;
确认 recover 完成恢复之后,基本恢复结束,可以开启目标端到 resetlogs 状态。
rman 恢复后收尾
目标端 reconcile 至指定SCN号
reconcilequeueq1foro.mesdb2-o.mesdbscn72863106548reconcilequeueq2foro.mesdb2-o.mesdbscn72863106548reconcilequeueq3foro.mesdb2-o.mesdbscn72863106548reconcilequeueq4foro.mesdb2-o.mesdbscn72863106548reconcilequeueq5foro.mesdb2-o.mesdbscn72863106548
非必须操作,如果出现 hang
住的情况,需要在源端 shareplex 执行 flush 操作疏通通道:
flusho.mesdb2tomes-repoqueueq1flusho.mesdb2tomes-repoqueueq2flusho.mesdb2tomes-repoqueueq3flusho.mesdb2tomes-repoqueueq4flusho.mesdb2tomes-repoqueueq5
📢 注意: 源端执行过 flush 的通道,目标端 start post
之后需要再次执行 start post queue 指定队列名
,否则无法开启 post。
目标端运行 cleanup.sql 来清空内部表信息
cd/data/quest/bin/sqlplussplex用户账号/splex账户密码
该步骤用于清理源端 splex 用户相关数据。
目标端禁用所有 trigger
SELECT'alter trigger '||owner||'.'||trigger_name||' disable;'fromdba_triggerswhereownerin (需要同步的用户);
将输出结果复制执行即可!
目标端禁用所有约束
SELECT'alter table '||owner||'.'||table_name||' disable constraint '||constraint_name||';'fromdba_constraintswhereconstraint_type='R'andownerin (需要同步的用户);
将输出结果复制执行即可!
禁用job
altersystemsetjob_queue_processes=0;
确保 job 任务不会运行!
目标端开启 post 进程
sp_ctrlstartpost
确保所有队列均已处于正常 running 状态。
由于目标端执行 reconcile 时 2,4 队列 hang
住,因此需要单独 start post queue 指定队列名
来开启:
startpostqueueq2startpostqueueq4
状态已全部正常 running。
重建后检查
qstatusshowpostqueueq2showlogreverse
通过命令查看同步是否正常,以及同步速度是否正常。再次确认邮件告警是否恢复正常。
写在最后
shareplex 重建恢复的流程还算复杂,因此需要做好必备的告警措施,防止遇到停止导致问题发生,无法及时补救的情况。
分享两个告警脚本:
1、监控 shareplex 进程是否正常运行:
#!/bin/bashif [ -f~/.bash_profile ]; then . ~/.bash_profileficount=`ps-ef|grepsp_cop|wc-l`if [ "${count}"-ne2 ]; thenps-ef|grepsp_cop>/tmp/sp_cop.logmail-s"Shareplex sp_cop process shutdown"邮箱地址</tmp/sp_cop.logfi
2、监控 shareplex 队列是否存在异常:
#!/bin/bashif [ -f~/.bash_profile ]; then . ~/.bash_profilefirm-rf/data/quest/error.logecho"show "|sp_ctrl|grep"Idle">>/data/quest/error.logecho"show "|sp_ctrl|grep"Stopped">>/data/quest/error.log#-s文件大小非0时为真if [ !-s/data/quest/error.log ] thenrm-rf/data/quest/error.log#文件大小为0删除fiif [ -s/data/quest/error.log ] thenmail-s"Shareplex error"邮箱地址</data/quest/error.logfi
📢 如有问题,请及时指正,谢谢!