вторник, 5 августа 2014 г.

oracle datapump перенос схем

Утилита DataPump появилась начиная с 10-й версии Oracle как замена устаревшим утилитам exp и imp в более ранних версиях. Она имеет больше возможностей, чем классические exp и imp, автоматически настраивает некоторые параметры, такие как размер буфера приёма/передачи, число потоков, etc. Одной из самых интересных возможностей DataPump является осуществление "перекачки" данных из одной базы данных в другую используя Database Link, что заметно упрощает импорт, если целевая и исходная базы находятся в одной сети. Итак, задача: на исходной БД есть пользователь cube в табличном пространстве cube. Нужно перенести все объекты в новую базу в схему cube2 табличном пространстве cube2. Оба пользователя, исходный и целевой, не привилегированны. Решение: На исходной базе нужно временно дать пользователю роль EXP_FULL_DATABASE.
GRANT EXP_FULL_DATABASE TO cube;
На целевой базе также нужна некоторая подготовка:
-- Через этот database link и будут передаваться данные
CREATE PUBLIC DATABASE LINK test1 CONNECT TO cube IDENTIFIED BY cube USING 'test1';
-- Сюда impdp будет записывать лог импорта
CREATE DIRECTORY test1_log AS '/usr/oracle/test1/test1_log';
-- Дадим пользователю cube2 права на чтоение и запись в эту директорию:
GRANT READ, WRITE ON DIRECTORY test1_log TO cube2;
Теперь, собственно, импорт:
impdp cube2/cube2@test2 NETWORK_LINK=test1 REMAP_SCHEMA=cube:cube2 \
REMAP_TABLESPACE=cube:cube2 DIRECTORY=test1_log
Если импорт прошёл без ошибок, убедимся, что все объекты скопировались:
SELECT object_name, object_type FROM user_objects@test1
MINUS
SELECT object_name, object_type FROM user_objects;
Если запрос ничего не возвращает, то всё ok.
Теперь уберём за собой. Удалим dblink и директорию на целевой базе:
DROP PUBLIC DATABASE LINK test1;
DROP DIRECTORY test1_log;
и отнимем роль EXP_FULL_DATABASE на исходной:
REVOKE EXP_FULL_DATABASE FROM cube;
Кстати, краткую справку по утилитам можно получить, запустив их с параметром HELP=y:

Перенос данных с 11g на 10g.

Экспорт данных.
expdp system@db02_11g version=10.0.2.4 schemas=user_01 directory=EXPBKP dumpfile=dump.dmp logfile=dump_exp.log
где:
  • schemas - список экспортируемых схем, разделённых запятой;
  • directory - Oracle-директория, в которой нужно создать файл экспорта;
  • dumpfile - имя файла экспорта;
  • logfile - имя файла-журнала;
  • version - версия базы данных, в которую будет осуществлён перенос данных.
Импорт данных.
impdp system@db02_10g directory=DP dumpfile=dump.dmp logfile=dump_imp.log remap_tablespace=TEMP0:TEMP
где:
  • directory - Oracle-директория, в которой нужно искать файл для импорта;
  • dumpfile - имя файла для импорта;
  • logfile - имя файла-журнала;
  • remap_tablespace - переназначение табличного пространства, может быть перечислено несколько табличных пространств по принципу OLD_TS:NEW_TS,OLD_TS1:NEW_TS1.

Импорт данных через database link.

Возникла на днях проблема. Надо перенести несколько схем с одного сервера на другой, но на исходном сервере нет места для дампа. В качестве решения выбрал импорт данных через database link средствами DataPump. Моя задача разложилась на следующие шаги:
  1. Формируем команды создания табличных пространств
    select 'create tablespace '
        || tablespace_name
        || ' datafile '''
        || regexp_replace(file_name,'ONE','TWO')
        || ''' size '||bytes||decode(AUTOEXTENSIBLE,'YES',' autoextend on next '||INCREMENT_BY,'')
        || ' maxsize '||decode(maxbytes,34359721984,'unlimited',maxbytes)||';'
    from dba_data_files
    where tablespace_name in (
       select default_tablespace ts from dba_users where username in ('SCHEMA1','SCHEMA2','SCHEMA2')
       union
       select tablespace_name ts from dba_ts_quotas where username in ('SCHEMA1','SCHEMA2','SCHEMA2')
       )
    order by 1;
    /
    На обоих серверах одинаковый ORACLE_HOME и данный запрос из
    D:\ORACLE\PRODUCT\10G\ORADATA\ONE
    делал
    D:\ORACLE\PRODUCT\10G\ORADATA\TWO
    Получалось что-то в виде:
    create tablespace TS1 datafile 'D:\ORACLE\PRODUCT\10G\ORADATA\TWO\TS1.DBF' size 524288000 autoextend on next 12800 maxsize 524288000;
  2. На целевой системе :
    • выполняем команды создания табличных пространств, полученные в п.1;
    • создаём database link в исходную систему:
      create database link dlsrc connect to system identified by <PASSWORD> using '<SRCTNS>';
    • создаём oracle directory (предварительно создав в ОС соответствующий каталог):
      create directory ddump as 'D:\dump';
  3. Ну, и импортируем схемы, используя database link:
    impdp system@<DSTTNS> directory=DDUMP schemas=SCHEMA1,SCHEMA2,SCHEMA2 network_link=dlsrc
    При выполнение импорта от имени system, пользователей можно не создавать — они создадутся автоматически.
Как всегда, у Oracle есть ложка дёгтя в бочке мёда, а именно: при переносе таким образом данных может всплыть ошибка, приведённая ниже.
ORA-31679: Table data object "SCHEMA1"."TABLE_NAME" has long columns, and longs can not be loaded/unloaded using a network link
Это вынуждает нас не пользоваться database link? Возможно. Но я перенёс только указанную таблицу тем же DataPump, но без database link. Для этого места оказалось достаточно.

Получение списка схем в дамп-файле.

Бывает, что необходимо выяснить, какие схемы включены в дамп-файл созданный DataPump'ом. В *nix-системах это можно сделать так:
strings DUMP.DMP | grep OWNER_NAME | sed -e 's/.*<OWNER_NAME>\([^<]*\)<\/OWNER_NAME>.*/\1/g' | sort -u
результат выглядит примерно так:
SCHEMA1
MDSYS
SYSTEM
На дампах большого размера возможно выполняться будет долго.

Перенос схем через database link.

  • Целевая система - TWO;
  • Исходная система - ONE;
Т.к. для переноса схемы табличное пространство уже должно быть создано, формируем команды создания табличных пространств:
select 'create tablespace '||
       tablespace_name||
       ' datafile '''||
       regexp_replace(file_name,'ONE','TWO')||
       ''' size '||bytes||' autoextend on next '||increment_by||' maxsize '||maxbytes||';'
from dba_data_files 
where tablespace_name in (
select default_tablespace ts from dba_users where username in ('SCHEMA1','SCHEMA2')
union
select tablespace_name ts from dba_ts_quotas where username in ('SCHEMA1','SCHEMA2'))
/
  • regexp_replace(file_name,'ONE','TWO') замените под свои нужны. У меня пути размещения файлов данных выглядели так:
    • исходная система - D:\ORACLE\PRODUCT\10.2.0\ORADATA\ONE\
    • целевая система - D:\ORACLE\PRODUCT\10.2.0\ORADATA\TWO\
  • username in ('SCHEMA1','SCHEMA2')) тоже поменяйте под свои схемы.
Далее. На целевой системе (на той, куда переносим схемы) выполняем следующее:
  • создаём public database link в исходную систему (в ту, откуда переносим схему):
    create public database link dlone connect to system identified by <PASSWORD> using 'one';
  • создаём oracle directory (предварительно создав соответствующий каталог в файловой системе ОС):
    create directory ddump as 'D:\dump';
  • импортируем схемы, используя database link:
    impdp system@two directory=DDUMP schemas=SCHEMA1,SCHEMA2 network_link=dlone

Экспорт partitions.

Экспорт конкретных партиций таблицы можно выполнить следующим образом:
expdp system@db directory=DP tables=SCHEMA.TABLE_NAME:PARTITION dumpfile=dump.dmp logfile=dump_exp.log

Экспорт с делением на несколько dump-файлов.

Для выполнения экспорта с делением на несколько dump-файлов выполняется такая команда:
expdp system@db directory=DP schemas=SCHEMA1 dumpfile=schema1_%U.dmp filesize=2G logfile=schema_exp.log
В этом случае dump-файлы будут выглядеть так:
schema1_01.dmp
schema1_02.dmp
schema1_03.dmp
...
Импорт в этом случае должен выполняться с указанием dump-файла в том же формате:
impdp system@db01 directory=DP dumpfile=schema1_%U.dmp logfile=schema_imp.log

Комментариев нет:

Отправить комментарий