Владимир Пржиялковский
Проблема переноса данных в Oracle, так же как и многие другие, не имеет одного общего приемлемого решения. С одной стороны, прикладные требования к такому переносу всегда конкретны: частота, объем, скорость осуществления и так далее. С другой стороны, предлагаемые Oracle варианты технических решений разнообразны и обладают каждый своими плюсами и минусами. В версии 8.1 появился способ физического переноса частей БД (то есть на уровне файлов, в противовес логическому переносу - на уровне объектов), точнее переноса табличных пространств. Учтя оговорку, сделанную первой фразой этого абзаца, вспомним основное (типичное) достоинство метода физического переноса данных - скорость и основной (типичный) недостаток - невозможность переносить данные между разными платформами и версиями Oracle. Сославшись еще раз на ту же оговорку, разумно будет предположить, что в определенных приложениях физический перенос будет не только допустим, но и выгоден, а потому описание техники такого переноса заслуживает внимание администратора БД.
Итак, посмотрим, как можно быстро перенести из базы в базу табличное пространство целиком. Возможность Oracle, которая при этом используется, носит оригинальное название transportable tablespace. Технически эта возможность реализуется переносом
- описаний всех пользовательских данных в табличном пространстве - средствами программ exp и imp, а также
- самих файлов с данными - средствами файловой системы.
Постановка задачи
Пусть имеются две БД: DOLLY и DOLLY1, работающие в ОС Windows NT под управлением СУБД Oracle версии 8.1.7. В БД DOLLY имеется пользователь DNA, имеющий какие-то объекты в табличном пространстве HEART. Покажем, как это табличное пространство можно перенести в базу DOLLY1. После этого сделаем изменения в пространстве HEART и выполним обратный перенос.
То, что пример приводится для Windows NT, вовсе не критично и оговаривается здесь лишь для оправдания синтаксиса имен файлов, а также во избежание недоразумений.
Выход на исходные позиции: подготовка тренировочных баз
Если Вы работаете на одной машине, удобно будет завести на терминале два консольных окошка: первое , настроенное на работу с БД DOLLY и второе , настроенное на DOLLY1.
В первом окошке войдем в SQL*Plus от имени SYS и наберем
CREATE TABLESPACE heart
DATAFILE ‘d:\oracle\oradata\dolly\heart1.dbf’ SIZE 1M;
CREATE USER dna IDENTIFIED BY dna
DEFAULT TABLESPACE heart TEMPORARY TABLESPACE temp;
GRANT CONNECT, RESOURCE TO dna;
Во втором окошке от имени SYS наберем в SQL*Plus
CREATE USER dna IDENTIFIED BY dna;
GRANT CONNECT, RESOURCE TO dna;
Комментарий. С помощью команды GRANT новым пользователям полномочия были выданы посредством ролей CONNECT и RESOURCE. Это удобно для примера, однако не стоит забывать, что в рабочей БД необходимо иметь существенно более продуманную и регламентированную систему раздачи полномочий. |
Снова в первом окошке от имени SCOTT наберем
GRANT SELECT ON emp TO dna;
CONNECT dna/dna
CREATE TABLE empa AS SELECT * FROM scott.emp;
Теперь у DOLLY в HEART завелось 14 человек - если, конечно, в типовой схеме SCOTT Вы ничего не меняли. Наша задача - перенести HEART из DOLLY в DOLLY1, а значит и перенести туда же этих сотрудников.
Переносим табличное пространство из первой базы во вторую
Прежде чем делать сам перенос, нужно убедиться в том, что переносимое табличное пространство - замкнутое, то есть не имеет связей с прочими табличными пространствами. Иначе перенос такого пространства был бы некорректен. Для такой проверки имеется процедура TRANSPORT_SET_CHECK в системном пакете DBMS_TTS. От имени SYS выдадим в первом окошке последовательно:
EXEC DBMS_TTS.TRANSPORT_SET_CHECK( -
ts_list => ‘HEART’, -
incl_constraints => TRUE)
SELECT * FROM TRANSPORT_SET_VIOLATIONS;
Последний SELECT - это проверка результата отработки непосредственно предшествующей процедуры. В нашем случае проверка даст пустое множество, однако если бы табличное пространство HEARTS имело внешние связи, в специальную системную выводимую таблицу SYS.TRANSPORT_SET_VIOLATIONS поступил бы их перечень, и эта таблица не была бы пуста.
Комментарий. Название первого параметра процедуры TRANSPORT_SET_CHECK намекает на то, что в нем может указываться список табличных пространств, а не отдельное пространство, как в нашем случае. Это правда. Например, мы могли бы хранить в одном пространстве таблицы, а в другом - их индексы. У этих пространств по определению будут "межтабличные связи", поэтому по отдельности переносить их будет невозможно, а, в то же время, вдвоем - вполне допустимо. В этом случае в параметре ts_list нужно будет их привести через запятую, и будет проверена замкнутость пары пространств.
Второй параметр процедуры нужно установить в TRUE, если данные планируется передавать вместе с ограничениями целостности, и FALSE - в противном случае.
Функционально идентичной процедуре TRANSPORT_SET_CHECK должна быть булева функция ISSELFCONTAINED с теми же параметрами. Она не описана в документации, но в коде приложения может оказаться удобнее. |
Теперь можно выдать:
ALTER TABLESPACE HEART READ ONLY;
HOST EXP TRANSPORT_TABLESPACE=Y TABLESPACES=(HEART) -
CONSTRAINTS=N GRANTS=Y TRIGGERS=N FILE=DHEART.DMP
Здесь понадобится в диалоге указать пользователя, выполняющего этот специфичный вид экспорта. Например, INTERNAL/ORACLE AS SYSDBA, или же другого пользователя, обладающего полномочием (grant) EXECUTE_CATALOG_ROLE. Пользователь SYS этим полномочием изначально обладает.
Теперь на уровне файловой системы скопирует файл heart1.dbf из d:\oracle\oradata\dolly в d:\oracle\oradata\dolly1.
Прежде, чем покинуть первое окошко, не забудем выдать
ALTER TABLESPACE HEART READ WRITE;
Во втором окошке от имени SYS наберем:
CREATE USER dna IDENTIFIED BY dna;
GRANT CONNECT, RESOURCE TO dna;
HOST IMP TRANSPORT_TABLESPACE=Y -
DATAFILES=(d:\oracle\oradata\dolly1\heart1.dbf)
FILE=DHEART.DMP
Снова в диалоге указываем INTERNAL/ORACLE AS SYSDBA. Как только все проработает, данные перенесены. Не помешает, однако, выполнить еще
ALTER TABLESPACE HEART READ WRITE;
ALTER USER dna DEFAULT TABLESPACE heart TEMPORARY
TABLESPACE temp;
Табличное пространство в DOLLY1 полностью готово к эксплуатации.
Переносим табличное пространство из второй базы в первую
Наберем для проверки во втором окошке от имени dna
INSERT INTO empa SELECT * from empa;
COMMIT;
SELECT * from empa;
У DOLLY в HEART образовалось в два раза больше человек: 28.
Теперь рассмотрим обратный перенос того же пространства из DOLLY1 в DOLLY. В принципе он зеркально повторяет выполненные действия, но с одним нюансом: пространство HEART в DOLLY уже существует. Поэтому в первом окошке наберем
DROP TABLESPACE hearts INCLUDING CONTENTS;
А дальше - все, как и раньше; во втором окошке:
EXEC DBMS_TTS.TRANSPORT_SET_CHECK( -
ts_list => ‘HEART’, -
incl_constraints => FALSE)
SELECT * FROM TRANSPORT_SET_VIOLATIONS;
ALTER TABLESPACE HEART READ ONLY;
HOST EXP TRANSPORT_TABLESPACE=Y TABLESPACES=(HEART)
FILE=DHEART.DMP
… Здесь прервемся и скопируем файл файл heart1.dbf из d:\oracle\oradata\dolly1 в d:\oracle\oradata\dolly ...
ALTER TABLESPACE HEART READ WRITE;
Переключаемся на первое окошко и пользователя SYS:
HOST IMP TRANSPORT_TABLESPACE=Y -
DATAFILES=(d:\oracle\oradata\dolly\heart1.dbf)
FILE=DHEART.DMP
Укажем в диалоге INTERNAL/ORACLE AS SYSDBA, ждем конца подключения пространства системой и выполняем
ALTER TABLESPACE HEART READ WRITE;
Все. Можно проверять, сколько людей у DOLLY.
О чем не было сказано, но стоит упомянуть
Прежде всего нужно сказать, что в одной БД после экспорта, а в другой - после импорта, нужно выполнить резервное копирование контрольного файла; можно в облегченном варианте:
ALTER DATABASE BACKUP CONTROLFILE TO TRACE;
Во-вторых, выше был приведен работающий, но всего лишь один возможный вариант, и ничего не говорилось о массе разных вариаций, полезных для разных случаев. Что, например, насчет таких деталей, как экспорт полномочий, ограничений или описаний триггеров, которые упоминались при выполнении экспорта выше ? Есть ли особенности при переносе секционированных таблиц (а они есть) ?
В-третьих, о возможностях такого метода. Переносить табличные пространства можно между любыми двумя БД, работающими под управлением одной версии СУБД на одной платформе. Разумный пример использования подхода предлагает фирма Oracle: это тиражирование данных БД с помощью CD-ROM.
Есть и некоторые ограничения по части содержания, например, переносимый набор табличных пространств не должен (в текущих версиях Oracle) иметь в себе "фотоснимки" (snapshots, разновидность materialized view); индексы, построенные с использованием функционального преобразования; очереди в смысле advanced queue; некоторые другие более специальные виды объектов.
Ссылки по теме