как импортировать дамп oracle в другое табличное пространство

<p>я хочу импортировать дамп oracle в другое табличное пространство.</p><p>у меня есть табличное пространство a, используемое пользователем a. я отозвал администратора этого пользователя и дал ему соединение и ресурс для предоставления грантов. тогда я бросил все с помощью команды</p><blockquote> <p>exp// *** владелец = файл = oracledump.dmp log = log.log compress = y</p> </blockquote><p>теперь я хочу импортировать дамп в табличное пространство b, используемое пользователем b. поэтому я дал ему права на подключение и ресурсы (без dba). затем я выполнил следующий импорт:</p><blockquote> <p>imp b/*** file = oracledump.dmp log = import.log fromuser = a touser = b </p> </blockquote><p>результатом является журнал с большим количеством ошибок:</p><blockquote> <p>imp-00017: следующий оператор завершился ошибкой с ошибкой oracle 20001: "begin dbms\_stats.set\_table\_stats imp-00003: обнаружена ошибка oracle 20001 ora-20001: неверные или несогласованные входные значения</p> </blockquote><p>после этого я попробовал ту же команду импорта, но с опцией statistics = none. это привело к следующим ошибкам:</p><blockquote> <p>ora-00959: табличное пространство 'a\_tblspace' не существует</p> </blockquote><p>как это должно быть сделано?</p><p>примечание. многие столбцы имеют тип clob. похоже, проблемы как-то связаны с этим.</p><p>примечание 2: версии oracle представляют собой смесь 9.2, 10.1 и 10.1 xe. но я не думаю, что это связано с версиями.</p>

<p>у вас есть пара вопросов здесь.</p><p><strong> во-первых </strong>, причиной того, что ошибка статистики таблиц используется в разных версиях oracle, - у меня была такая же проблема, когда некоторые из наших баз данных oracle 10g были обновлены до выпуска 2, а некоторые все еще были в выпуске 1 и я обменивался файлами .dmp между ними.</p><p>решение, которое работало для меня, заключалось в том, чтобы использовать одну и ту же версию инструментов <code>exp</code> и <code>imp</code> для экспорта и импорта в разных экземплярах базы данных. это было проще всего сделать, используя один и тот же компьютер (или сервер oracle) для выдачи всех команд экспорта и импорта.</p><p><strong> во-вторых </strong>, я подозреваю, что вы получаете <code>ora-00959: tablespace 'a\_tblspace' does not exist</code>, потому что вы пытаетесь импортировать файл .dmp из полноценной базы данных oracle в базу данных 10g express edition (xe), которая по умолчанию создает одну предопределенное табличное пространство с именем <code>users</code> для вас.</p><p>если это так, то вам нужно сделать следующее ..</p><ol> <li><p>с вашим файлом .dmp создайте файл sql, содержащий структуру (таблицы):</p> <p><code>imp <xe\_username>/<password>@xe file=<filename.dmp> indexfile=index.sql full=y</code></p></li> <li><p>откройте файл индекса (index.sql) в текстовом редакторе, который может найти и заменить весь файл, и введите следующие операторы поиска и замены в порядке (игнорируйте одинарные кавычки .. '):</p> <p><code>find: 'rem<space>' replace: <nothing></code></p> <p><code>find: '"<source\_tablespace>"' replace: '"users"'</code></p> <p><code>find: '...' replace: 'rem ...'</code></p> <p><code>find: 'connect' replace: 'rem connect'</code></p></li> <li><p>сохраните индексный файл, затем запустите его для своей учетной записи oracle express edition (я считаю, что лучше создать новую, пустую учетную запись пользователя xe - или удалить и заново создать, если я обновляю):</p> <p><code>sqlplus <xe\_username>/<password>@xe @index.sql</code></p></li> <li><p>наконец, запустите тот же файл .dmp, с которым вы создали индексный файл, для той же учетной записи, чтобы импортировать данные, хранимые процедуры, представления и т.д.</p> <p><code>imp <xe\_username>/<password>@xe file=<filename.dmp> fromuser=<original\_username> touser=<xe\_username> ignore=y</code></p></li> </ol><p>вы можете получить страницы ошибок oracle при попытке создания определенных объектов, таких как задания базы данных, поскольку oracle будет пытаться использовать тот же идентификатор базы данных, который, скорее всего, потерпит неудачу, когда вы находитесь в другой базе данных.</p>

<p>если вы используете oracle 10g и datapump, вы можете использовать предложение remap\_tablespace. пример:</p><pre><code>remap\_tablespace=a\_tblspace:new\_tablespace\_goes\_here </code></pre>

<p>для меня это нормально работает (oracle database 10g express edition release 10.2.0.1.0):</p><pre><code>impdp b/b full=y dumpfile=dump.dmp remap\_tablespace=old\_tablespace:users </code></pre><p>но для нового восстановления вам нужно новое табличное пространство</p><p>постскриптум может быть полезно <a href="http://www.oracle-base.com/articles/10g/oracledatapump10g.php">http://www.oracle-base.com/articles/10g/oracledatapump10g.php</a> </p>

<p>какую версию oracle вы используете? если его 10g или больше, вы должны смотреть на использование data pump вместо импорта/экспорта в любом случае. я не уверен на 100%, сможет ли он справиться с этим сценарием, но я бы ожидал, что сможет.</p><p> <a href="http://www.oracle.com/technology/products/database/utilities/index.html">data pump</a> это замена для exp/imp для 10g и выше. он работает очень похоже на exp/imp, за исключением его (предположительно, я не использую его, так как я застрял в 9i земле) лучше.</p><p> <a href="http://download.oracle.com/docs/cd/b19306\_01/server.102/b14215/part\_dp.htm#cegjcchc">вот документы data pump</a> </p>

<p>я хочу улучшить для двух пользователей в разных табличных пространствах на разных серверах (базы данных)</p><p><strong> 1 . сначала создайте каталоги для временного дампа для обоих серверов (баз данных): </strong></p><p><em>server # 1:</em></p><pre><code>create or replace directory tempdump as '/temp/old\_datapump/'; grant read, write on directory tempdump to old\_user; </code></pre><p><em>сервер № 2:</em></p><pre><code>create or replace directory tempdump as '/temp/new\_datapump/'; grant read, write on directory tempdump to new\_user; </code></pre><p><strong> 2 . экспорт (сервер № 1): </strong></p><pre><code>expdp tables=old\_user.table directory=tempdump dumpfile=adump.dmp logfile=adump.log </code></pre><p><strong> 3 . импорт (сервер № 2): </strong></p><pre><code>impdp directory=tempdump dumpfile=adump\_table.dmp logfile=bdump\_table.log remap\_tablespace=old\_tablespace:new\_tablespace remap\_schema=old\_user:new\_user </code></pre>

<p>мое решение состоит в том, чтобы использовать утилиту gsar для замены имени табличного пространства в файле dump. когда вы делаете replce, убедитесь, что размер файла дампа не изменился, добавив пробелы . e.g.</p><pre><code>gsar -f -s"tsdat\_ov101" -r"users " rm\_schema.dump rm\_schema.n.dump gsar -f -s"tablespace """users """ enable storage in row chunk 8192 retention" -r" " rm\_schema.n1.dump rm\_schema.n.dump gsar -f -s"tablespace """users """ logging" -r" " rm\_schema.n1.dump rm\_schema.n.dump gsar -f -s"tablespace """users """ " -r" " rm\_schema.n.dump rm\_schema.n1.dump </code></pre>

<p>проблема связана со столбцами clob. кажется, что инструмент imp не может переписать оператор create для использования другого табличного пространства.</p><p>источник: <a href="http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::p11\_question\_id:66890284723848">http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::p11\_question\_id:66890284723848</a> </p><p>решение: создайте схему вручную в правильном табличном пространстве. если у вас нет сценария для создания схемы, вы можете создать его с помощью indexfile = инструмента imp.</p><p>вы сами должны отключить все ограничения, инструмент oracle imp не отключит их. </p><p>после этого вы можете импортировать данные с помощью следующей команды:</p><blockquote> <p>imp b/*** file = oracledump.dmp log = import.log fromuser = a touser = b статистика = нет игнорировать = y</p> </blockquote><p>примечание: мне все еще нужна статистика = нет из-за других ошибок.</p><p><strong><em>дополнительная информация о насосе данных</em></strong></p><p>начиная с oracle 10 улучшен импорт/экспорт: инструмент для сбора данных ([ <a href="http://www.oracle-base.com/articles/10g/oracledatapump10g.php][1]">http://www.oracle-base.com/articles/10g/oracledatapump10g.php][1]</a> )</p><p>используя это, чтобы повторно импортировать данные в новое табличное пространство:</p><ol> <li><p>сначала создайте каталог для временного дампа:</p> <blockquote> <p>create or замените справочник tempdump as '/ temp/tempdump /';<br> grant read, написать на каталог tempdump to a;</p> </blockquote></li> <li><p>экспорт:</p> <blockquote> <p>expdp a/* schemas = a directory = tempdump dumpfile = adump.dmp logfile = adump.log</p> </blockquote></li> <li><p>импортировать:</p> <blockquote> <p>impdp b/* directory = tempdump dumpfile = adump.dmp logfile = bdump.log remap\_schema = a: b</p> </blockquote></li> </ol><p>примечание: файлы дампа хранятся и читаются с диска сервера, а не с локального (клиентского) диска</p>

<p>ответ сложный, но выполнимый:</p><p>ситуация такова: пользователь<strong>a</strong>и табличное пространство<strong>x</strong></p><ol> <li>импортировать файл дампа в другую базу данных (это необходимо только в том случае, если вам нужно сохранить оригинальную копию)</li> <li><p>переименовать табличное пространство</p> <p>изменить табличное пространство<strong>x</strong>переименовать в<strong>y</strong></p></li> <li><p>создать каталог для команды expdp и предоставить права</p></li> <li>создать дамп с помощью expdp</li> <li>удалить старого пользователя и старое табличное пространство (<strong>y</strong>)</li> <li>создать новое табличное пространство (<strong>y</strong>)</li> <li>создать нового пользователя (с новым именем) - в этом случае<strong>b</strong>- и предоставить права (также на каталог, созданный на шаге 3)</li> <li><p>импортировать дамп с помощью impdp</p> <p>каталог impdp b/b = dir-файл дампа = dumpfile.dmp logfile = logfile.log remap\_schema =<strong>a</strong>:<strong>b</strong></p></li> </ol><p>и это все...</p>

<p>поскольку я хотел <code>imp</code>ort (для oracle 12.1 | 2) создать дамп, который был <code>exp</code>orted из локальной базы данных разработки (18c xe), и я знал, что все мои целевые базы данных будут иметь доступное табличное пространство с именем <code>database\_tablespace</code>, я просто создал свою схему/пользователя использовать новое табличное пространство с таким именем вместо <code>users</code> по умолчанию (к которому у меня нет доступа к целевым базам данных):</p><pre><code>-- don't care about the details create tablespace database\_tablespace datafile 'database\_tablespace.dat' size 10m reuse autoextend on next 10m maxsize 200m; alter database default tablespace database\_tablespace; create user username identified by userpassword container=all; grant create session to username; grant create table to username; grant create view to username; grant create any trigger to username; grant create any procedure to username; grant create sequence to username; grant create synonym to username; grant create synonym to username; grant unlimited tablespace to username; </code></pre><p><code>exp</code>, созданный из этого, делает <code>imp</code> счастливым для моей цели.</p>