|
Навигация
|
Главная » Sql Экспорт - импорт БД oracle большого размераИсточник: surgutnet Евгений Воронянский Если вы читаете данную статью, то скорее всего Вас настигло несчастье. Экземпляр продуктивной БД доживает последние дни и вот вот перестанет вообще запускаться. Из RMAN-а вы восстановиться не можете, так как пользователи "наработали" достаточно большое количество данных, а архивные журналы с момента аварии безнадежно утеряны. Забегая вперед, отмечу, что с помощью ниже описываемого метода был произведен экпорт-импорт БД размером около 160GB за 18 часов. Платформа:
Итак, приступим: Будем считать что для восстановления мы добавили отдельный диск для расположения на нем исполняемых файлов, а также журналов импорта/экспорта, и для того чтобы не путаться в достаточно большом количестве журналов выполнения создадим структуру дирректорий: mount /dev/dsk/c1t1d0s0 /mnt/drive mkdir /mnt/drive/exp-imp chown oracle:dba /mnt/drive/exp-imp su - oracle cd /mnt/drive/exp-imp mkdir pipe ilog elog sql Внимание! В данной статье приводится вариант экспорта/импорта от владельца объекта. Т.е. прежде чем стартовать экспорт/импорт, необходимо убедиться что:
Для этого используем SQL приведенный ниже: cd sql cat > lockuser.sql Код: #Список заблокированных пользователей whenever sqlerror exit sql.sqlcode; set pause off; set pages 0; set linesize 140; set feedback off; set termout off; spool lockuser.spool.sql select 'alter user "'//username//'" account lock;' from dba_users where account_status <> 'OPEN'; exit; ^D cat >user_password.sql Код: #Создание спаска хэшей паролей и #скрипта подстановки времменного пароля для всех пользователей whenever sqlerror exit sql.sqlcode; set pause off; set pages 0; set linesize 140; set feedback off; set termout off; column cmd_line format a80 column tick format a3 column sum_bytes format 999,999,999,999 spool return_pass.spool.sql; select 'alter user "'//username//'" identified by values '''//password//''';' from dba_users; spool off; spool change_pass.spool.sql; select 'alter user "'//username//'" identified by qqq;' from dba_users; spool off; exit; ^4D cat > unlockuser.sql Код: #Разблокировка пользователей whenever sqlerror exit sql.sqlcode; set pause off; set pages 0; set linesize 140; set feedback off; set termout off; spool unlockuser.spool.sql select 'alter user "'//username//'" account unlock;' from all_users / spool off; exit; ^D Ниже приведен скрипт создания пользовательских схем (без данных) в БД приемнике. В нем необходимо исправить SID, домашнюю дирректорию Oracle, а также установить правильные языковые настройки и пароль не схему system, т.е "system/pass@source" и "system/pass@dest" должно являться строкой подключения. cat > full_export_no_rows.sh Код: ORACLE_HOME=/u01/app/oracle/products/8.1.7.4; export ORACLE_HOME ORACLE_SID=ORCL; export ORACLE_SID EXP=$ORACLE_HOME/bin/exp IMP=$ORACLE_HOME/bin/imp NLS_LANG=AMERICAN_AMERICA.CL8MSWIN1251; export NLS_LANG DUMP_DIR=/mnt/drive/exp-imp PIPE=$DUMP_DIR/pipe/exp_full_pipe ELOG=$DUMP_DIR/elog/$ORACLE_SID-full-`date +%Y%m%d`.elog ILOG=$DUMP_DIR/ilog/$ORACLE_SID-full-`date +%Y%m%d`.ilog rm -f $PIPE mknod $PIPE p # Make the pipe date >> $ELOG date >> $ILOG $EXP system/pass@source FULL=Y ROWS=N CONSTRAINTS=N INDEXES=Y TRIGGERS=N log=$ELOG file=$PIPE& #2>/dev/null 1>/dev/null & # Export to the pipe $IMP system/pass@dest FULL=Y IGNORE=Y log=$ILOG file=$PIPE #Import from the pipe date >> $ELOG date >> $ILOG rm -f $PIPE ^D По аналогии создаем скрипт, с помощью которого можно перенести отдельный объект. cd .. cat > table_export.sh Код: ORACLE_HOME=/u01/app/oracle/products/8.1.7.4; export ORACLE_HOME ORACLE_SID=ORCL; export ORACLE_SID EXP=$ORACLE_HOME/bin/exp IMP=$ORACLE_HOME/bin/imp NLS_LANG=AMERICAN_AMERICA.CL8MSWIN1251; export NLS_LANG DUMP_DIR=/mnt/drive/exp-imp PIPE=$DUMP_DIR/pipe/$1.$2 ELOG=$DUMP_DIR/elog/$ORACLE_SID-$1.$2-`date +%Y%m%d`.elog ILOG=$DUMP_DIR/ilog/$ORACLE_SID-$1.$2-`date +%Y%m%d`.ilog rm -f $PIPE mknod $PIPE p # Make the pipe date >> $ELOG date >> $ILOG $EXP $1/temp_pass@source TABLES=$2 COMPRESS=Y FEEDBACK=1000 log=$ELOG file=$PIPE 2>/dev/null& # Export to the pipe $IMP $1/temp_pass@dest TABLES=$2 COMMIT=Y IGNORE=Y log=$ILOG file=$PIPE 2>/dev/null # Import from the pipe date >> $ELOG date >> $ILOG rm -f $PIPE ^D Для полного счастья строим отсортированный по размеру список таблиц, данные которых необходимо перенести с помощью следующего SQL: cat >list_tbls.sql Код: whenever sqlerror exit sql.sqlcode; set pause off; set pages 0; set linesize 150; set feedback off; set termout off; column cmd_line format a80 column tick format a3 column sum_bytes format 999,999,999,999 spool master.list; --select '/mnt/drive/exp-imp/full_export_no_rows.sh' from dual; select '/mnt/drive/exp-imp/table_export.sh '//owner//' '//segment_name cmd_line,' # ' tick, sum(bytes) sum_bytes from dba_segments where segment_type = 'TABLE' and owner <> 'SYS' and owner not like 'AURORA%' group by owner, segment_name order by sum(bytes) desc; spool off; exit; ^D Далее создем скрипт который позволит пускать необходимые процессы в параллели: cat >paresh Код: #!/bin/bash #Исправте количество запускаемых процессов #А также путь к командному файлу message() { timestamp=`date +%Y.%m.%d:%H:%M` echo "$timestamp $*" / tee -a $logfile return } get_shell() { echo "`date` $1 Shell Request $$" >> $lklogfile while : do next_shell="" if [ ! -s ${workfile} ] then break fi if [ ! -f $lockfile ] then. echo $$ > $lockfile echo "`date` $1 Lock Obtained $$" >> $lklogfile if [ "$$" = "`cat $lockfile`" ] then next_shell=`sed -e q $workfile` sed -e 1d $workfile > ${workfile}.tmp mv ${workfile}.tmp $workfile rm -f $lockfile echo "`date` $1 Shell Issued " >> $lklogfile return else echo "`date` $1 Lock FAULTED $$" >> $lklogfile fi fi sleep 1 done return } paresh_slave() { shell_count=0 get_shell $1 while [ "$next_shell" != "" ] do shell_count=`expr $shell_count + 1` message "Slave $1: Running Shell $next_shell" $next_shell shell_status=$? if [ "$shell_status" -gt 0 ] then message "Slave $1: ERROR IN Shell $next_shell 2status=$shell_status" echo "Slave $1: ERROR IN Shell $next_shell status=$shell_status" >> $errfile fi get_shell $1 done message "Slave $1: Done (Executed $shell_count Shells)" return } paresh_driver() { rm -f $lklogfile if [ "$1" = "" ] then master_file="/mnt/drive/exp-imp/master.list" echo $master_file else if [ ! -f "$1" ] then echo "$0: Unable to find File $1" exit 1 else master_file="$1" fi fi if [ "$2" = "" ] then parallel_count=24 #(CPU*2) else if [ "$2" -lt 1 ] then echo "$0: Parallel Process Count Must be > 0" exit 1 else parallel_count=$2 fi fi message "------------------------------" message "Master Process ID: $PARESH" message "Processing File: $master_file" message "Parallel Count: $parallel_count" message "Log File: $logfile" message "------------------------------" cp $master_file $workfile while test $parallel_count -gt 0 do if [ ! -s $workfile ] then message "All Work Completed - Stopped Spawning at $parallel_count" break fi $0 $parallel_count & message "Spawned Slave $parallel_count [pid $!]" parallel_count=`expr $parallel_count - 1` done wait message "All Done" return } # main if [ "$PARESH" != "" ]; then workfile=/tmp/paresh.work.$PARESH lockfile=/tmp/paresh.lock.$PARESH lklogfile=/tmp/paresh.lklog.$PARESH ogfile=/tmp/paresh.log.$PARESH errfile=/tmp/paresh.err.$PARESH paresh_slave $* else PARESH="$$"; export PARESH workfile=/tmp/paresh.work.$PARESH lockfile=/tmp/paresh.lock.$PARESH lklogfile=/tmp/paresh.lklog.$PARESH logfile=/tmp/paresh.log.$PARESH errfile=/tmp/paresh.err.$PARESH rm -f $errfile paresh_driver $* rm -f $workfile rm -f $lklogfile if [ -f $errfile ] then message "*************************************************" message "FINAL ERROR SUMMARY. Errors logged in $errfile" cat $errfile / tee -a $logfile message "*************************************************" exit 1 fi fi exit ^D После создания всех необходимых файлов, а также базы данных на целевом хосте со всеми необходимыми табличными пространствами ставим перед фактом руководство, и приступаем к использованию только что созданных файлов: Построение списков: cd sql sqlplus system/pass@source @lockuser.sql sqlplus system/pass@source @user_password.sql sqlplus system/pass@source @unlockuser.sql cd .. sqlplus system/pass@source @list_tbls.sql cd sql Изменение паролей пользователей и снятие блокировок с аккаунтов. sqlplus system/pass@source @change_pass.spool.sql sqlplus system/pass@source @unlockuser.spool.sql Экспорт/импорт пользовательских схем без данных: cd .. ./full_export_no_rows.sh Далее внимательно проверяем все что в дирректории ilog, elog и только после окончания экспорта/импорта схем запускаем ./paresh и анализируем лог-файлы процессов импорта/экспорта. По завершению всех процессов для определения "потерянных" объектов (constraints, index…) используем Toad for Oracle (DBA->Compare Schemas, DBA->Compare Databases), собираем статистику, а также выполняем скрипт для определения разницы в таблицах на уровне количества строк, для работоспособности которого необходимо связать БД линком MIGRATION.WORLD : cd /mnt/drives/exp-imp/sql cat > rows_tables_diff.sql Код: whenever sqlerror exit sql.sqlcode; set pause off; set pages 0; set linesize 150; set feedback off; set termout off; column cmd_line format a80 column name format a3 column Diff format 999,999,999,999 spool rows_tables_diff.spool.sql; select 'whenever sqlerror exit sql.sqlcode;'//chr(10)// 'set pause off;'//chr(10)// 'set pages 0;'//chr(10)// 'set linesize 150;'//chr(10)// 'set feedback off;'//chr(10)// 'set termout off;'//chr(10)// 'column cmd_line format a80'//chr(10)// 'column tick format a3'//chr(10)// 'column sum_bytes format 999,999,999,999'//chr(10)// 'spool rows_tables_diff.txt' from dual; select 'select name, sum(Dest) - sum(Source) diff '//chr(10)// 'from ( '//chr(10)// 'select '''//table_name//''' name,count(1) Dest, 0 Source '//chr(10)// 'from '//owner//'.'//table_name//'@MIGRATION.WORLD union '//chr(10)// 'select '''//table_name//''' name,0 Dest, count(1) Source '//chr(10)// 'from '// owner //'.'//table_name//' )'//chr(10)// 'group by name;' Str from all_tables where owner not in ('SYSTEM','SYS') and owner not like 'AURORA%' select chr(10)//'exit;' //chr(10) from dual; exit; ^D И в зависомости от того в какой из БД был создан линк выполняем rows_tables_diff.spool.sql. Результат сравнения наблюдаем в rows_tables_diff.txt. Значительно ускорить экспорт/импорт позволяет установка параметра скрытого параметра oracle - _disable_logging в true на БД в которую производится импорт, но при запуске БД в эксплуатацию его необходимо установить в false. Удачи. Как выполнять аудит производительности SQL Server. Как отслеживать работу приложений и их составных частей в Oracle. Автоматизация настройки запросов в версии Oracle 10g: некоторые дополнительные возможности. Не самые известные сведения о внешних ключах. Заморочки от Oracle, или знать бы, где упасть…. Главная » Sql |
© 2024 Team.Furia.Ru.
Частичное копирование материалов разрешено. |