Ни когда не задумывался о другом способе резервных копий базы данных oracle, так как холодное копирование вполне устраивало, но приходится развиваться и смотреть на другие стороны создания резервных копий баз данных.
Доброго времени суток всем.Работаю администратором баз данных далеко не первый год, но всегда работал в больших компаниях. За это время работал с Linux, Solaris, HP-UX. Но примерно год назад попал в небольшую компанию, и о ужас, все сервера на Windows, как такового резервного копирования не делалось, точнее только экспорт.Было необходимо делать нормальный физический backup, решил писать скрипт, как требования для себя выделил несколько моментов:
- Скрипт должен работать должен работать с любой ОС начиная с win 2003 сервер, при этом не требовать дополнительного софта.
- Скрипт должен работать на любом Oracle начиная с версии 9i, при этом делать полный, инкрементальный бэкап, и бэкап архивлогов.
- Скрипт должен быть, как можно проще, переносим с сервера на сервер, желательно чтобы это был один файл.
Первая мысль была поставить cygwin или perl, сделать Windows похожей на unix, но тогда будут трудности с переносом на другие сервера. Решил писать простой пакетный файл ms-dos, правда ничего сложнее, чем copy con my_text.txt в батниках я не писал. Реализация пункта 3, вообще получилось кошмаром, у меня нет встроенных документов, я не могу написать:
|
1 |
sqlplus "/ as sysdba" << SQL select sysdate from dual; SQL |
Решил все дополнительные скрипты записывать во временные файлы, а вывод програм в переменные. Неожиданно вылезла ещё одна проблема если переменная не задана echo %AAA% выводит %AAA%, пришлось переменной присваивать пробел.Для 10g и выше архивлоги собираются в бэкапсет, так как есть компрессия. Для 9i архивлоги копируются как есть, так как нет команды catalog, при восстановление из нескольких бекапсетов придется восстанавливать контрол файлы. При полном бэкапе все содержимое директории DEST переносится в OLD. И вот что у меня в итоге получилось:
Спасибо за внимание. Ссылка на скрипт
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
echo off REM version 1.4 REM Использовать "rman_Backup_DB.cmd [t|a|d|0-1]" REM 0-1 уровень инкрементального бекапа (0 - полный) REM a бекап только архив логи REM t или ничего тест, проверяется запуск sqlplus,rman, запись в DEST REM d быстрое удаление архивлогов, если место уже кончилось, после этого НЕОБХОДИМ ПОЛНЫЙ БЕКАП REM -------------------Далее задаются переменные--------------------------------- REM Директория назначения set DEST=\\SMB_server\share REM Директория назначения Старых файлов set OLD=%DEST%\OLD set ORACLE_SID=ORCL set ORACLE_HOME=C:\APP\orabase\product\11.2.0\dbhome_1 set NLS_LANG=AMERICAN_AMERICA.CL8MSWIN1251 set NLS_DATE_FORMAT=YYYY.MM.DD HH24.MI.SS REM COMPRESS=пробел для 9i и ниже (пробел обязательно) REM для 10 и выше =as compressed backupset set COMPRESS=as compressed backupset REM Строка подключения Rman к базе set CONSTRING=target / REM строка подключения sqlplus set CONSQL="/ as sysdba" REM Местоположение Rman set RMAN=%ORACLE_HOME%\bin\rman REM Местоположение SQLPLUS set SQLPL=%ORACLE_HOME%\bin\sqlplus REM Временный файл set TFILE=%TEMP%\backup_%ORACLE_SID%.tmp REM --------------------------------------------- set ERR=0 set EXEC=%0 %1 if "%EXEC%"=="%0 " goto prov if %1==t goto prov if %1==a goto backarc if %1==d goto delarc echo alter system archive log current; > %TFILE% echo select upper ('posled '),(max (SEQUENCE#)-5) from v$archived_log where DELETED='NO'; >> %TFILE% echo exit >> %TFILE% for /F "tokens=1,2 usebackq " %%1 in (`%SQLPL% %CONSQL% @%TFILE%`) do if %%1==POSLED set SEQN=%%2 IF %1==0 ( move /Y %DEST%\*.BK? %OLD% goto backdb ) IF %1==1 goto backdb :prov echo 1.Testing sqlplus connection echo select 'POSLED ','Test_SQLPLUS_OK' from dual; > %TFILE% echo exit >> %TFILE% for /F "tokens=1,2 usebackq " %%1 in (`%SQLPL% %CONSQL% @%TFILE%`) do if %%1==POSLED set SEQN=%%2 echo Test Complete echo 2.Testing write to destination dir echo 2. Test write on destination dir OK > %DEST%\test_file.txt if ERRORLEVEL 1 ( echo Write Error goto eof ) echo Test Complete echo 3.Testing rman conection echo backup format '%DEST%\test_backup.bak' spfile; > %TFILE% %RMAN% %CONSTRING% @%TFILE% echo Test Complete echo Results: echo 1. %SEQN% type %DEST%\test_file.txt del /q /f %DEST%\test_file.txt if EXIST %DEST%\test_backup.bak ( echo 3. Testing rman OK del /q /f %DEST%\test_backup.bak ) ELSE ( echo 3. Test RMAN failed ) goto eof :delarc echo crosscheck archivelog all; > %TFILE% echo delete FORCE NOPROMPT archivelog all; >> %TFILE% %RMAN% %CONSTRING% @%TFILE% echo *********************************************************** echo *** Do not forget to do FULL BACKUP OF THE DATABASE !!! *** echo *********************************************************** goto eof :backdb echo run { > %TFILE% echo sql 'alter system archive log current'; >> %TFILE% echo sql 'alter system checkpoint'; >> %TFILE% echo allocate channel d1 type disk; >> %TFILE% echo set limit channel d1 kbytes 4000000; >> %TFILE% echo backup %COMPRESS% incremental level %1 skip inaccessible filesperset 1 format '%DEST%\%%d_%%T_%%U.bkd' database include current controlfile; >> %TFILE% echo sql 'alter system checkpoint'; >> %TFILE% echo sql 'alter system archive log current'; >> %TFILE% echo backup %COMPRESS% filesperset 40 format '%DEST%\%%d_%%T_%%U.bka' archivelog from sequence %SEQN% ; >> %TFILE% echo backup format '%DEST%\%%d_%%T_%%U.bkc' current controlfile; >> %TFILE% echo backup format '%DEST%\%%d_%%T_%%U.bks' spfile; >> %TFILE% echo } >> %TFILE% %RMAN% %CONSTRING% @%TFILE% set /a ERR=%ERR%+%ERRORLEVEL% :backarc echo %COMPRESS%|findstr compressed if ERRORLEVEL 1 ( echo alter system archive log current; > %TFILE% echo set feedback off pagesize 0 heading off verify off linesize 200 trimspool off >> %TFILE% echo spool %TFILE%.bat >> %TFILE% echo select 'move /Y '^|^|name^|^|' %DEST%' from v$archived_log where DEST_ID=1 and STATUS='A'; >> %TFILE% echo spool off >> %TFILE% echo exit >> %TFILE% %SQLPL% %CONSQL% @%TFILE% call %TFILE%.bat set /a ERR=%ERR%+%ERRORLEVEL% echo crosscheck backup; > %TFILE% echo crosscheck archivelog all; >> %TFILE% echo DELETE FORCE NOPROMPT EXPIRED backup; >> %TFILE% %RMAN% %CONSTRING% @%TFILE% ) else ( echo crosscheck backup; > %TFILE% echo crosscheck archivelog all; >> %TFILE% echo DELETE FORCE NOPROMPT EXPIRED backup; >> %TFILE% echo sql 'alter system checkpoint'; >> %TFILE% echo sql 'alter system archive log current'; >> %TFILE% echo backup %COMPRESS% filesperset 40 format '%DEST%\%%d_%%T_%%U_all.bka' archivelog all delete input; >> %TFILE% echo backup format '%DEST%\%%d_%%T_%%U.bkc' current controlfile; >> %TFILE% %RMAN% %CONSTRING% @%TFILE% ) set /a ERR=%ERR%+%ERRORLEVEL% :eof exit /b %ERR% |
