(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

Экспорт - импорт БД oracle большого размера

Источник: surgutnet
Евгений Воронянский

Если вы читаете данную статью, то скорее всего Вас настигло несчастье. Экземпляр продуктивной БД доживает последние дни и вот вот перестанет вообще запускаться. Из RMAN-а вы восстановиться не можете, так как пользователи "наработали" достаточно большое количество данных, а архивные журналы с момента аварии безнадежно утеряны. Забегая вперед, отмечу, что с помощью ниже описываемого метода был произведен экпорт-импорт БД размером около 160GB за 18 часов. Платформа:

  1. Хост с "испорченным" экземпляром - RAM 8G, 4CPU, дисковый массив Clariion, SunOS Solaris, Oracle 8.1.7.4-64
  2. Хост приемник - RAM 24G, 12CPU, дисковый массив Clariion, SunOS Solaris, Oracle 8.1.7.4-64.

 Дополнительное программное обеспечение: ToadForOracle (Quest).

 Итак, приступим:

 Будем считать что для восстановления мы добавили отдельный диск для расположения на нем исполняемых файлов, а также журналов импорта/экспорта, и для того чтобы не путаться в достаточно большом количестве журналов выполнения создадим структуру дирректорий:

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


 Внимание! В данной статье приводится вариант экспорта/импорта от владельца объекта. Т.е. прежде чем стартовать экспорт/импорт, необходимо убедиться что:

  1. В БД источнике все пользователи имеют право подключаться.ъ
  2. Нет заблокированных пользователей.

 В связи с пунктом 3 необходимо создать список заблокированных пользователе, а также сохранить хэши паролей пользователей.
 Для этого используем 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.

 Удачи.

Ссылки по теме


 Распечатать »
 Правила публикации »
  Написать редактору 
 Рекомендовать » Дата публикации: 14.05.2012 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
Oracle Database Personal Edition Named User Plus Software Update License & Support
Oracle Database Standard Edition 2 Processor License
Oracle Database Standard Edition 2 Named User Plus License
Oracle Database Personal Edition Named User Plus License
TeeChart for .NET Standard Business Edition 2017 single license
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Новости ITShop.ru - ПО, книги, документация, курсы обучения
Программирование на Microsoft Access
CASE-технологии
СУБД Oracle "с нуля"
Corel DRAW - от идеи до реализации
ЕRP-Форум. Творческие дискуссии о системах автоматизации
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100