刘秉春,王晓虹,王志文,马玉想,肖永平
数据库备份两例故障的恢复与解决方法
刘秉春,王晓虹,王志文,马玉想,肖永平
数据库;故障;备份
数据库系统的正常是“军字一号”系统运行的基础,当用户使用一个数据库时,数据库中的数据必须是可靠的、正确的。但是,由于计算机系统的原因或是人为操作不当会直接影响数据库系统的安全性,甚至破坏数据库,造成数据库中全部或部分数据丢失。笔者所在医院最近由于数据库备份问题和人为操作不当出现2次故障,总结经验教训如下。
1.1 数据库热备份没有完成引起的故障可能是因为长期没有DOWN机,用户登录数过多造成数据库死锁,上午工作中客户端数据库无法登录,发现服务器响应速度慢,这时是工作高峰期,没有查看数据库状态而直接重启oracle服务,可是发现数据库无法启动,查看“D:oracleadminorcldumporclALRT.LOG”文件,分析原因是热备份还没有结束,这时才想起在重启服务时有一活动窗口没有运行完毕而直接关闭了,导致还有“SQL>alter tablespace表空间end backup”这样的语句没有执行完毕。这时没有进行其它操作,在命令提示符下输入:Sqlmgrl>Startup;Database mounted;Ora-01113:file7needrecovery;Ora-01110:datafile7:’d:oracleoradataorclapacct.dbf’;Sqlmgrl>Recover database;Sqlmgrl>Alter database open resetlogs;之后数据库启动正常。数据文件在备份时检验点号(SCN)不变,而其他数据文件SCN发生改变,这样数据文件中SCN不一致,导致数据库无法正常启动。
1.2 人为操作不当引起的故障最近医院患者在出院结算时无法结帐,发现应交费用和实收费用不一致,开始认为是个别患者出现的情况,可是核算室反馈的是大部分结算患者存在这样的问题。利用LogMiner进行Oracle数据日志分析,发现在最后出现错误情况时有一个误操作。有很多下面这样的语句:时间:2010-09-02-17:25:36语句update"INPBILL"."INP_BILL_DETAIL"set"AMOUNT"=39,"COSTS"=39,"CHA RGES"=39 where ROWID='AAAD5yAARAAAAUXAAO'。很多收费项目统一变成了39元,原因是一次错误提交,使inp_bill_items中所有Item_no为72的实收和应收全为39;但由于是2 d前的操作,可是医院的备份只保留了1 d的数据,并且这次备份做了恢复性试验,无法再进行数据库介质恢复。恢复过程如下:首先查看备用服务器数据的时间,发现备用服务器和主服务器误操作时间差18 d,备用服务器上数据存在的可以直接导入,所以主要问题是备用服务器上没有的这段时间的数据恢复问题。药品根据摆药记录drug_rec中的数据进行恢复,开始用2台机器1台查看错误数据,1台提取摆药记录正确数据,但这样存在数万条数据,所需修改时间很长,经过试验用PB做一数据窗口,提取inp_bill_items中这段时间内错误数据,根据drug_rec中的记录修改数量和费用;非药品记录可以按每天的费用清单来对照,但这样每人每天对照不太现实,可行的方法是把出问题的记录根据价表修改相关费用。主要语句如下:
总结这2次故障的经验教训,主要原因是热备份数量太少,周期比较短,修改备份方案如下:
2.1 扩大备份空间原来是双机热备,另加1台普通计算机,挂2个2TB硬盘,保证有足够备份空间。
2.2 修改备份程序修改热备份目的地于本机硬盘,加快备份时间。之后由本机硬盘拷贝到映射硬盘。alter tablespace tsp_...begin backup;host copy d:oracleoradataorcl....dbf E:orclbak;alter tablespace tsp_...end backup;alter system switch logfile;host copy d:oracleoradataorcllog*.dbf E:orclbak(本机硬盘);host copy d:oracleoradataorcl*.log E:orclbak;alter database backup controlfile to'e:control01.ctl'reuse;host copy e:control01.ctl E:orclbak;host copy e:archive*.*E:arbak;host copy e:orclbak*.*M:(映射盘符);host copy e:arbak*.*n:
2.3 增加循环周期在备份时由原来只保留1 d备份改为备份数据保存1个月,并1个月做1次全备份,每天备份计划任务由1个改为7个,每星期做循环备份,确保数据发生错误时能够完全恢复。
2.4 标记存储介质根据备份的内容,日期将介质统一编号,以免备份和恢复时弄错介质,造成原有的备份丢失。
2.5 做好异地备份介质应存放在与计算机设备不同的地点,以免机房发生意外时,备份与计算机设备一同损坏。
现在大部分医院采用热备份,热备份必须将数据库运行在(Archive Log)归档方式下,优点是数据备份期间用户可以继续访问数据库,保证医院信息系统不间断运行;而且可以达到秒级恢复(恢复到某一时间点上),这样在出现问题时可以快速恢复到出问题的前一刻,这一点在双机热备恢复时是非常有用的;再就是热备份数据恢复快,基本上不占用太多时间。但是热备份的缺点是难于维护,热备份尽量在数据库不使用或使用率低的情况下进行,不能出错,否则后果严重。例1主要原因是没有每天查看备份是否完成,窗口中仍有活动窗口,仍然强行宕机造成oracle中SCN处于不一致的状态,导致数据库无法正常启动。
随着医院信息化程度的不断提高,数据库作为信息系统的核心,担当着十分重要的角色,做好数据库备份尤为重要。因此,必须要有完备的备份与恢复策略,并通过模拟故障对每种可能的情况进行严格测试,这样才能保证数据的高可用性,保证日常工作的正常运行。
[1]王慧琴.“军字一号”工程数据库系统的备份及恢复策略研究[J].中国数字医学,2008,12(48):
[2]潘哲毅,陈国军,杜开齐,等.“军字一号”医院信息系统的备份和Oracle错误恢复[J].武警医学,2008,1(92):
[3]袁姗,刘长生,施伟.Oracle数据库热备份过程中被中断的数据恢复方法[J].计算机工程应用技术,2009,3(2315):
[2010-12-13收稿,2011-01-20修回]
TP311.53
B
264002山东烟台,107医院信息科(刘秉春,王晓虹,王志文,马玉想,肖永平)
1.2.1 修改药品记录long ll_row;ll_row=dw_1.retrieve();int i,li,lii;string ls_patid,ls;decimal ld_p;for i=1 to ll_row;ld_p=dw_1.GetItemDecimal(i,"drug_dispense_rec_costs");ls_patid=dw_1.getitemstring(i,"inp_bill_detail_patient_id");li=dw_1.GetItemDecimal(i,"inp_bill_detail_visit_id");lii=dw_1.GetItemDecimal(i,"drug_dispense_rec_dispense_amount")UPDATE"INP_BILL_DETAIL";SET"AMOUNT"=:lii,"COSTS"=:ld_p,"CHARGES"=:ld_p;WHERE("INP_BILL_DETAIL"."PATIENT_ID"=:ls_patid)AND("INP_BILL_DETAIL"."VISIT_ID"=:li)AND("INP_BILL_DETAIL"."ITEM_NO"=72);commit;next messagebox(STRING(i),"ok")。
1.2.2 修改非药品记录long ll_row;ll_row=dw_1.retrieve();int i,li,lii;string ls_patid,ls;decimal ld_p;for i=1 to ll_row;ld_p=dw_1.GetItemDecimal(i,"price_list_price");ls_patid=dw_1.getitemstring(i,"inp_bill_detail_patient_id");li=dw_1.GetItemDecimal(i,"inp_bill_detail_visit_id");UPDATE"INP_BILL_DETAIL";SET"COSTS"=:ld_p,"CHARGES"=:ld_p;WHERE("INP_BILL_DETAIL"."PATIENT_ID"=:ls_patid)AND("INP_BILL_DETAIL"."VISIT_ID"=:li)AND("INP_BILL_DETAIL"."ITEM_NO"=72);commit;nextmessagebox("数据修改完毕","ok")。这样基本完成了没有备份时间段空白数据记录的恢复,个别数据不对的情况可以根据科室明细单进行修改。这样正常运行10 d左右后基本没有无法结账的情况发生。
[本文编辑:羡秋盛]