Доброго времени суток всем.Работаю администратором баз данных далеко не первый год, но всегда работал в больших компаниях. За это время работал с Linux, Solaris, HP-UX. Но примерно год назад попал в небольшую компанию, и о ужас, все сервера на Windows, как такового резервного копирования не делалось, точнее только экспорт.Было необходимо делать нормальный физический backup, решил писать скрипт, как требования для себя выделил несколько моментов:
- Скрипт должен работать должен работать с любой ОС начиная с win 2003 сервер, при этом не требовать дополнительного софта.
- Скрипт должен работать на любом Oracle начиная с версии 9i, при этом делать полный, инкрементальный бэкап, и бэкап архивлогов.
- Скрипт должен быть, как можно проще, переносим с сервера на сервер, желательно чтобы это был один файл.
sqlplus "/ as sysdba" << SQL
select sysdate from dual;
SQL
Решил все дополнительные скрипты записывать во временные файлы, а вывод програм в переменные. Неожиданно вылезла ещё одна проблема если переменная не задана echo %AAA% выводит %AAA%, пришлось переменной присваивать пробел.Для 10g и выше архивлоги собираются в бэкапсет, так как есть компрессия. Для 9i архивлоги копируются как есть, так как нет команды catalog, при восстановление из нескольких бекапсетов придется восстанавливать контрол файлы. При полном бэкапе все содержимое директории DEST переносится в OLD. И вот что у меня в итоге получилось: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%
Спасибо за внимание.Ссылка на скрипт