|
Навигация
|
Главная » Ross Как запустить скрипт операционной системы из Oracle или Не совсем традиционный способ снятия бэкапаИсточник: habrahabr Некоторое время назад потребовалось сделать бэкап базы данных на RAC. Задача, на самом деле, вполне тривиальная, если бы не несколько но: у заказчика паранойя по поводу безопасности (не удивительно и понятно), у заказчика нет своего DBA (ну так уж вышло) и у меня есть доступ только к консоли сервера с базой данных. Таким образом, пришлось отказаться от использования красивого и удобного Enterprise Manager и придумать банальные консольные скрипты. И вот тут-то и возникла загвоздка.Стандартное решение: написать скрипты бэкапа, настроить cron, который будет их вызывать по расписанию, и на этом успокоиться до тех пор, пока база таки не упадёт. Но поскольку мы имеем дело с кластером из нескольких нод, встал вопрос, на которой из них дёргать бэкап. На всех - как-то многовато. На одной - а что, если именно она-то и упадёт, а все остальные останутся в строю? По очереди - а что, если упадёт именно та, чья очередь делать бэкап как раз и наступила? На каком-нибудь третьем сервере - нету лишней железки для дополнительной базы данных. Тогда вспомнилась одна любопытная штука, которая появилась в версии 11.2 и с которой, кроме прочего, давно хотелось разобраться. А именно, внешние таблицы с возможностью предобработки подключаемого файла. Понятно, что изобретённое решение - это нецелевое использование любопытной фичи. Но получилось забавно. Сначала - скрипты (скрипт RMAN может быть любым, для примера пускай такой). /u01/app/oracle/rman_backup/backup.rmn RUN { BACKUP SPFILE FORMAT '+FRA/racdb/backupset/spfile_%d_%s_%T' DATABASE INCLUDE CURRENT CONTROLFILE FORMAT '+FRA/racdb/backupset/data_%d_%s_%T' ARCHIVELOG ALL FORMAT '+FRA/racdb/backupset/arc_%d_%s_%T'; BACKUP DEVICE TYPE DISK FORMAT '/backup/data_%d_%s_%T_%U' BACKUPSET COMPLETED AFTER 'SYSDATE - 1/24'; CROSSCHECK BACKUP; CROSSCHECK BACKUPSET; CROSSCHECK ARCHIVELOG ALL; DELETE NOPROMPT EXPIRED ARCHIVELOG ALL; DELETE NOPROMPT EXPIRED BACKUP; DELETE NOPROMPT OBSOLETE; } /u01/app/oracle/rman_backup/run_backup.sh #!/bin/bash /u01/app/oracle/product/11.2.0/dbhome_1/bin/rman target / cmdfile=$* Скрипты бэкапа (run_backup.sh и backup.rmn) должны быть сложены на все имеющиеся ноды кластера по одинаковому пути (в данном примере - /u01/app/oracle/rman_backup/). И путь к утилите rman должен быть указан полностью. После чего начинается интересное. Предоставляем базе доступ к каталогу, в котором живут скрипты бэкапа. $ sqlplus / as sysdba SQL> create or replace directory bkp_dir as '/u01/app/oracle/rman_backup/'; Создаём пользователя, который будет дёргать скрипты бэкапа, и предоставляем ему необходимые привилегии. $ sqlplus / as sysdba SQL> create user bkp identified by rmanbkp; SQL> grant connect to bkp; SQL> grant create table to bkp; SQL> grant create procedure to bkp; SQL> grant create type to bkp; SQL> grant create job to bkp; SQL> grant read, write, execute on directory bkp_dir to bkp; Создаём внешнюю таблицу, основной смысл которой - запускать бэкап. SQL> connect bkp/rmanbkp SQL> create table bkp ( 2 line varchar2(255) 3 ) 4 organization external ( 5 type oracle_loader 6 default directory BKP_DIR 7 access parameters ( 8 records delimited by newline 9 preprocessor BKP_DIR:'run_backup.sh' 10 fields terminated by ';' ldrtrim 11 reject rows with all null fields 12 ) 13 location ('backup.rmn') 14 ) 15 reject limit unlimited; Затем - хранимку, которая будет дёргаться по расписанию (во второй части, где проверка успешности и оповещение DBA о результатах, можно, например, сообщение отправить на нужный адрес, но это немножко другая история). SQL> create or replace procedure run_backup is 2 arrBackupLog backup_log; 3 4 cursor curBackupErrorsExist is 5 select 1 from dual 6 where exists ( 7 select 1 from table (arrBackupLog) 8 where column_value like 'RMAN-%' 9 ); 10 11 nDummy number(1); 12 bErrorsFound boolean; 13 begin 14 -- run weekly rman backup script 15 select line 16 bulk collect into arrBackupLog 17 from bkp; 18 -- report backup 19 open curBackupErrorsExist; 20 fetch curBackupErrorsExist into nDummy; 21 bErrorsFound := curBackupErrorsExist%found; 22 close curBackupErrorsExist; 23 24 if bErrorsFound then 25 dbms_output.put_line ('BACKUP FAILED'); 26 else 27 dbms_output.put_line ('BACKUP SUCCEEDED'); 28 end if; 29 end run_backup; 30 / Ну и, наконец, job, который будет нашу хранимку дёргать. SQL> begin 2 dbms_scheduler.create_job ( 3 job_name => 'DAILY_BACKUP' 4 , job_type => 'STORED_PROCEDURE' 5 , job_action => 'run_backup' 6 , start_date => systimestamp 7 , repeat_interval => 'FREQ=DAILY;BYHOUR=04;BYMINUTE=0;BYSECOND=0' 8 , comments => 'Run daily RMAN backup' 9 , enabled => true 10 ); 11 end; 12 / Такая вот штука. Oracle, оказывается, и так умеет. Особенности национального внедрения: ERP-система iRenaissance.ERP на предприятиях США и России. Совершенствование системы управления на Липецком хладокомбинате. Главная » Ross |
© 2024 Team.Furia.Ru.
Частичное копирование материалов разрешено. |