|
|
|||||||||||||||||||||||||||||
|
Как перенести табличное пространство из базы в базуВладимир Пржиялковский
Проблема переноса данных в Oracle, так же как и многие другие, не имеет одного общего приемлемого решения. С одной стороны, прикладные требования к такому переносу всегда конкретны: частота, объем, скорость осуществления и так далее. С другой стороны, предлагаемые Oracle варианты технических решений разнообразны и обладают каждый своими плюсами и минусами. В версии 8.1 появился способ физического переноса частей БД (то есть на уровне файлов, в противовес логическому переносу - на уровне объектов), точнее переноса табличных пространств. Учтя оговорку, сделанную первой фразой этого абзаца, вспомним основное (типичное) достоинство метода физического переноса данных - скорость и основной (типичный) недостаток - невозможность переносить данные между разными платформами и версиями Oracle. Сославшись еще раз на ту же оговорку, разумно будет предположить, что в определенных приложениях физический перенос будет не только допустим, но и выгоден, а потому описание техники такого переноса заслуживает внимание администратора БД. Итак, посмотрим, как можно быстро перенести из базы в базу табличное пространство целиком. Возможность Oracle, которая при этом используется, носит оригинальное название transportable tablespace. Технически эта возможность реализуется переносом
Постановка задачи Пусть имеются две БД: 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;
Снова в первом окошке от имени 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 поступил бы их перечень, и эта таблица не была бы пуста.
Теперь можно выдать: 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; некоторые другие более специальные виды объектов. Ссылки по теме
|
|