首页 > 代码库 > 中小型数据库 RMAN CATALOG 备份恢复方案(一)

中小型数据库 RMAN CATALOG 备份恢复方案(一)

   对于数据库的稳定性,高可用,跨平台以及海量数据库的处理,Oracle 数据库通常是大型数据库和大企业的首选。尽管如此,仍然不乏很多中小企业想要品尝一下Oracle腥味,因此在Oracle环境中也有不少中小型数据库。出于成本的考虑,通常有可能就搞个标准版了,跑在Linux上。谁叫Oracle太贵呢?对于中小企业而言,选择合理的才是最好的。对我们这些个搞DB的,贵的一定有贵的道理,我们也可以都进多几斗米。哈哈......典型的打工者的心态哟。言归正传,中小企业的成本限制了我们搞高可用,RAC和DG也就比较少了。最近就碰到这样的情形,就是能否模拟DataGuard来保护数据库。我们知道DataGuard可以实时将数据库从主库切换到备库,或者从备库再切换回主库,实现无缝对接,从而避免由于硬件故障所带来的数据损失。下文即是基于上面的情形来使用rman catalog方式从某种程度上模拟DataGuard来更大程度地保护数据。

 

1、模拟DataGuard可行性分析
      a、能否将生产数据库整个结构以相同的结构存在于备份服务器? 可以,热备,冷备,RMAN备份,方式多样化。首次选用冷备初始化数据库。
      b、抛开DG的什么逻辑物理Standy来考虑,即不考虑实现自动或手动failover。只考虑的Prod机器硬件故障,DB在备份服务器可用。可行。
      c、能否将数据库损失减小到最少?DG可以定时传送archivelog,自动apply,那我们也可以定时传送archivelog,不过自动apply有难度。
      d、对于定时传送的archivelog,能否最终应用的备份服务器?可以,不论是添加/减少表空间/数据文件,数据变化更是没有问题的了。
      e、数据丢失的程度取决于最后剩余未及时传送的archivelog以及Prod的redo log,这个会损失,没有办法,毕竟不是DG。

 

2、备份恢复方案规划  
    下面是数据库备份的方案规划
        系统环境: Linux,Oracle 10g Standard
        数据库环境: 主数据库位于Prod服务器,备份数据库位于Bak服务器,数据库容量<=200GB
        备份频度: 每天做一个level 0级备份,也可以根据需要每2天实现0级备份。当然,如果中型或大型,建议使用0,1,2级增量备份
        备份位置:Prod服务器放置备份文件,同时将当次的备份文件ftp到Bak服务器
        归档日志:定时将归档日志ftp到Bak服务器上与原数据库相同的归档位置
        还原频度:每天定时使用新的备份文件在Bak服务器上进行还原
        恢复频度:不作任何恢复操作,因为恢复操作为不完全恢复,且需要使用resetlogs打开数据库,会生成新的incarnation
        故障处理:如果Prod服务器主库损坏,则将剩余的archivelog及redo复制到Bak(如果可能的话),接下来在Bak服务器手动恢复数据库并open
        恢复目录数据库:建议对恢复目录数据库备份,方案多样不表

 

3、创建恢复目录数据库及其脚本
      由于Prod服务器数据库较多,因此创建恢复目录数据库。如果你的环境库较少,可以直接使用控制文件替代恢复目录。
      其次创建基于恢复目录数据库的备份与恢复的全局脚本供所有数据库调度。
      关于如何创建恢复目录数据库及恢复目录脚本,此处省略,请参考:
            RMAN catalog 的创建和使用
            基于catalog 创建RMAN存储脚本 
            基于catalog 的RMAN 备份与恢复    

[sql] view plain copy
 
 print?
  1. --下面列出恢复目录下部署的所有脚本  
  2. --注,没有指定备份路径,使用缺省的闪回区  
  3. RMAN> list global script names;  
  4.   
  5. List of Stored Scripts in Recovery Catalog  
  6.   
  7.   
  8.     Global Scripts  
  9.   
  10.   
  11.        Script Name  
  12.        Description  
  13.        -----------------------------------------------------------------------  
  14.        global_arch  
  15.   
  16.        global_del_obso  
  17.   
  18.        global_inc0  
  19.   
  20.        global_restore  
  21.   
  22. RMAN> print global script global_arch;  
  23.   
  24. printing stored global script: global_arch  
  25. {  
  26. allocate channel ch1 type disk maxpiecesize=2g;  
  27. allocate channel ch2 type disk maxpiecesize=2g;  
  28. set limit channel ch1 readrate=10240;     
  29. set limit channel ch1 kbytes=2048000;     
  30. set limit channel ch2 readrate=10240;     
  31. set limit channel ch2 kbytes=2048000;  
  32. crosscheck archivelog all;  
  33. delete noprompt archivelog all;  
  34. sql " alter system archive log current";  
  35. backup as compressed backupset archivelog all delete input tag=‘Archbk‘;  
  36. release channel ch1;     
  37. release channel ch2;  
  38. }  
  39.   
  40. --Author : Robinson Cheng  
  41. --Blog   : http://blog.csdn.net/robinson_0612  
  42.   
  43. RMAN> print global script global_del_obso;  
  44.   
  45. printing stored global script: global_del_obso  
  46. {  
  47. allocate channel ch1 device type disk;  
  48. delete noprompt obsolete redundancy 1;   
  49. release channel ch1;   
  50. }  
  51.   
  52. RMAN> print global script global_inc0;  
  53.   
  54. printing stored global script: global_inc0  
  55. {  
  56. configure retention policy to redundancy 1;  
  57. configure backup optimization on;     
  58. configure controlfile autobackup on;  
  59. allocate channel ch1 device type disk maxpiecesize=5g;  
  60. allocate channel ch2 device type disk maxpiecesize=5g;  
  61. set limit channel ch1 readrate=10240;  
  62. set limit channel ch1 kbytes=4096000;  
  63. set limit channel ch2 readrate=10240;     
  64. set limit channel ch2 kbytes=4096000;   
  65. backup as compressed backupset incremental level 0 database tag=‘Inc0‘;  
  66. release channel ch1;  
  67. release channel ch2;  
  68. execute global script global_arch;  
  69. execute global script global_del_obso;  
  70. }  
  71.   
  72. RMAN> print global script global_restore;  
  73.   
  74. printing stored global script: global_restore  
  75. {  
  76. restore controlfile;  
  77. sql ‘alter database mount‘;  
  78. crosscheck backup;  
  79. delete noprompt expired backup;  
  80. crosscheck copy;  
  81. delete noprompt expired copy;  
  82. allocate channel ch1 type disk;  
  83. allocate channel ch2 type disk;  
  84. restore database;  
  85. release channel ch1;  
  86. release channel ch2;  
  87. shutdown immediate;  
  88. }  

4、创建RMAN备份shell脚本      

[python] view plain copy
 
 print?
  1. oracle@BKDB01p:/u02/database/common/rman_scripts> more db_bak_rman_catalog.sh  
  2. ##===========================================================  
  3. ##   File name: db_bak_rman_catalog.sh  
  4. ##   Usage: db_bak_rman_catalog.sh <$ORACLE_SID>  
  5. ##   Desc:  
  6. ##        The script uses to backup database with level 0.  
  7. ##   Author: Robinson  
  8. ##   Blog  : http://blog.csdn.net/robinson_0612  
  9. ##============================================================  
  10. #!/bin/bash  
  11. # User specific environment and startup programs  
  12.   
  13. if [ -f ~/.bash_profile ];  
  14. then  
  15. . ~/.bash_profile  
  16. fi  
  17.   
  18. # --------------------------  
  19. #   Check SID  
  20. # --------------------------  
  21. if [ -z "${1}" ];then  
  22.     echo "Usage: "  
  23.     echo "      `basename $0` ORACLE_SID"  
  24.     exit 1  
  25. fi  
  26.   
  27. # -------------------------------  
  28. #  Set environment here  
  29. # -------------------------------  
  30. ORACLE_SID=${1};                                    export ORACLE_SID  
  31. TIMESTAMP=`date +%Y%m%d%H%M`;                       export TIMESTAMP  
  32. LOG_DIR=/u02/database/${ORACLE_SID}/backup          export LOG_DIR  
  33. RMAN_LOG=${LOG_DIR}/${ORACLE_SID}_bak_${TIMESTAMP}.log  
  34. SSH_LOG=${LOG_DIR}/${ORACLE_SID}_bak_full_${TIMESTAMP}.log  
  35. MAIL_DIR=/users/oracle/sendEmail-v1.56  
  36. MAIL_FM=oracle@BKDB01p  
  37. RETENTION=5  
  38.   
  39. echo "----------------------------------------------------------------" >>${SSH_LOG}  
  40. echo "Step 1. Start rman to backup at `date`."                          >>${SSH_LOG}  
  41. echo "----------------------------------------------------------------" >>${SSH_LOG}  
  42.   
  43. $ORACLE_HOME/bin/rman log=${RMAN_LOG} <<EOF  
  44. connect target sys/xxx@${ORACLE_SID}  
  45. connect catalog rman_user/xxx@CATADB  
  46. resync catalog;  
  47. run {execute global script global_inc0;}  
  48. exit;  
  49. EOF  
  50. RV=$?  
  51.   
  52. cat ${RMAN_LOG}>>${SSH_LOG}  
  53. echo ""        >>${SSH_LOG}  
  54. echo "=====>MSG1: RMAN backup end at `date`." >>${SSH_LOG}  
  55.   
  56. if [ $RV -ne "0" ]; then  
  57.     echo "" >>${SSH_LOG}  
  58.     echo "=====>MSG2: RMAN backup error at `date`." >>${SSH_LOG}  
  59.     $MAIL_DIR/sendEmail -f $MAIL_FM -u "Failed RMAN backup for $ORACLE_SID on `hostname`." -t dba@12306.com -o message-file=${SSH_LOG}  
  60.     exit  
  61. else  
  62.     echo "" >>${SSH_LOG}  
  63.     echo "=====>MSG2: No error found during RMAN backup peroid at `date`" >>${SSH_LOG}  
  64.     rm -rf ${RMAN_LOG} 2>/dev/null  
  65. fi  
  66.   
  67. echo "-------------------------------------------------------------------------" >>${SSH_LOG}  
  68. echo "Step 2. Start ftp backupset to backup server at `date`."                   >>${SSH_LOG}  
  69. echo "-------------------------------------------------------------------------" >>${SSH_LOG}  
  70.   
  71. SRC_DB_BAK_DIR=/u02/database/${ORACLE_SID}/flash_recovery_area/${ORACLE_SID}  
  72. SRC_ADD=10.1.2.101  
  73. TARG_DB_BAK_DIR=/u02/database/${ORACLE_SID}/flash_recovery_area  
  74. RSYN_LOG=${LOG_DIR}/rsync_${TIMESTAMP}.log  
  75.   
  76. # rsync is used to ftp backup set to bak server.  
  77. rsync -avzSH --progress --delete-after oracle@${SRC_ADD}:${SRC_DB_BAK_DIR} ${TARG_DB_BAK_DIR} >${RSYN_LOG} 2>&1  
  78. RV=$?  
  79.   
  80. cat ${RSYN_LOG}>>${SSH_LOG}  
  81. if [ $RV -ne "0" ]; then  
  82.     echo ""                                                    >>${SSH_LOG}  
  83.     echo "=====>MSG3: FTP backupset error at `date`."          >>${SSH_LOG}  
  84.     MAIL_SUB="Failed archive log sync for $ORACLE_SID on `hostname` at `date`."  
  85.     $MAIL_DIR/sendEmail -f $MAIL_FM -u $MAIL_SUB -t dba@12306.com -o message-file=${SSH_LOG}  
  86.     exit  
  87. else  
  88.     echo ""                                                 >>${SSH_LOG}  
  89.     echo -e "=====>MSG3: No error found during FTP peroid." >>${SSH_LOG}  
  90.     rm -rf $FTP_LOG 2>/dev/null  
  91. fi  
  92.   
  93. echo "-------------------------------------------------------------------------"  >>${SSH_LOG}  
  94. echo "Step 3. RMAN backup and ftp backupset finished at `date`."                  >>${SSH_LOG}  
  95. echo "-------------------------------------------------------------------------"  >>${SSH_LOG}  
  96.   
  97. MAIL_SUB="Sucessful completed for ${ORACLE_SID} RMAN backup and ftp backupset at `date`."  
  98. $MAIL_DIR/sendEmail -f $MAIL_FM -u $MAIL_SUB -t dba@12306.com -o message-file=${SSH_LOG}  
  99.   
  100. # ------------------------------------------------  
  101. # Removing files older than $RETENTION parameter  
  102. # ------------------------------------------------  
  103.   
  104. find ${LOG_DIR} -name "*.*" -mtime +$RETENTION -exec rm {} \;  
  105.   
  106. exit  

5、自动FTP archivelog脚本

[python] view plain copy
 
 print?
  1. oracle@BKDB01p:/u02/database/common/rman_scripts> more autoftp_arch.sh  
  2. #!/bin/bash  
  3.   
  4. ORACLE_SID=${1};                        export ORACLE_SID  
  5. TIMESTAMP=`date +%Y%m%d%H%M`;           export TIMESTAMP  
  6. LOG_DIR=/u02/database/${ORACLE_SID}/backup   
  7.   
  8. #Define FTP variable  
  9. SRC_DB_BAK_DIR=/u02/database/${ORACLE_SID}/archive  
  10. SRC_ADD=10.1.2.101  
  11. TARG_DB_BAK_DIR=/u02/database/${ORACLE_SID}  
  12. RSYN_LOG=${LOG_DIR}/rsync_arc_${TIMESTAMP}.log  
  13. RSYN_ERR_LOG=${LOG_DIR}/rsync_arc_${TIMESTAMP}_err.log  
  14.   
  15. rsync -avzSH --progress --delete-after oracle@${SRC_ADD}:${SRC_DB_BAK_DIR} ${TARG_DB_BAK_DIR} >${RSYN_LOG} 2>${RSYN_ERR_LOG}  
  16. RV=$?  
  17.   
  18. if [ ! -s ${RSYN_ERR_LOG} ];then  
  19.     rm -rf ${RSYN_ERR_LOG} 2>/dev/null  
  20. else  
  21.     mail -s "Failed FTP archive log for $ORACLE_SID on `hostname`" dba@12306.com <${SYN_ERR_LOG}  
  22. fi  
  23.   
  24. exit  

6、部署备份脚本到crontab
      如果你的数据库比较少,则直接将上面的备份脚本与自动FTP archivelog脚本部署到crontab。
      如果你的数据库比较多,建议将上面的脚本封装到另外的一个文件,然后部署到crontab。
      如下面的full_bak_by_rman.sh实际上是包含了多个db_bak_rman_catalog.sh <$ORACLE_SID> ,后面的多个full开头的使用类是的原理。

      #Rman backup and restore database
      0 1 * * 1-6 /u02/database/common/rman_scripts/full_bak_by_rman.sh
      0 3 * * 1-6 /u02/database/common/rman_scripts/full_resotre_by_rman.sh  #这个是用来还原的脚本

      #Auto ftp archive log from prod to bak server
      */16 7-20 * *  1-6 /u02/database/common/rman_scripts/full_autoftp_arch.sh 

转:http://blog.csdn.net/leshami/article/details/9815271

中小型数据库 RMAN CATALOG 备份恢复方案(一)