быстрый экспорт - импорт / fast exp - imp
Export/Import нельзя считать полноценным средством для выполнения задачи backup'а. Тот же RMAN справляется с этой задачей более эффективно и естественно.
Однако, если рассматривать export/import как вспомогательное средство для backup'а, то они вполне имеют право на существование. Если девелопер случайно удалил данные из небольшой справочной таблицы, то проще восстановить её из export-файла. То же относится к ненамеренному удалению пакета (если у Вас не используется система контроля версий).
Export/Import также можно применять при копировании схемы на другую базу или при переносе базы на другую платформу.
Только скорость этой операции (особенно импорта) не всегда удовлетворительна, а часто просто наоборот. Как же можно ускорить export/import? Вот несколько рекомендаций.
- Export
- указать direct=true
- установить recordlength=65535 (это максимальное значение)
- экспортируйте не схему, а таблицы схемы. И распараллеливайте export, даже
если у Вас однопроцессорная машина. Вот, к примеру, python скрипт, который
может так делать:
#!/usr/bin/env python # paraller export # http://oracledba.ru import os,sys,threading,time,re def getTables(un): return os.popen("""sqlplus -s "/ as sysdba" <<EOS whenever sqlerror exit sql.sqlcode set pause off set pages 0 set linesiz 132 set feedb off set termout off set trims on select segment_name||decode(segment_type,'TABLE PARTITION',':'||partition_name,'') from dba_segments where segment_type in ('TABLE','TABLE PARTITION') and owner = upper('%s') order by segment_name desc; exit EOS; """ % un).readlines() # # begin # Prefix = '/path/to/export' Threads_num = 4 os.environ['ORACLE_HOME'] = '/u/app/oracle/product/9.2.0' os.environ['ORACLE_SID'] = 'oracle_sid' os.environ['ORA_NLS33'] = '/u/app/oracle/product/9.2.0/ocommon/nls/admin/data' os.environ['NLS_LANG'] = 'AMERICAN_AMERICA.CL8MSWIN1251' os.environ['PATH'] = '/bin:/usr/bin:/u/app/oracle/product/9.2.0/bin' try: User = sys.argv[1] except IndexError: print "Error: User should be specified" sys.exit(1) if User: exptabs = getTables(User) # recreate prefix dir and log dir try: os.mkdir(Prefix) except OSError: pass try: os.mkdir("%s/logs" % Prefix) except OSError: pass print time.asctime()," begin oracle_sid %s export" % User def exptab(id,lck): while True: try: lck.acquire(1) curtab = exptabs.pop().rstrip("\n") lck.release() except IndexError: lck.release() break curtab = re.escape(curtab) print time.asctime(),"[%s] %s" % (id,curtab) os.system("exp \\'/ as sysdba\\' file=%s/%s.dat log=%s/logs/%s.log tables=%s.%s \ direct=y recordlength=65535 compress=n 2>/dev/null" % \ (Prefix,curtab,Prefix,curtab,User,curtab)) fLock = threading.Lock() th = [] for i in range(Threads_num): th.append(threading.Thread(target=exptab,args=(i,fLock))) th[i].start() for i in range(Threads_num): th[i].join() # now export full user schema print time.asctime(),"[-1] schema" os.system("exp \\'/ as sysdba\\' file=%s/%s_schema.dat log=%s/logs/%s_schema.log owner=%s \ direct=y recordlength=65535 compress=n 2>/dev/null" % \ (Prefix,User,Prefix,User,User)) print time.asctime()," end oracle_sid %s import" % User
Как вариант, скрипт можно поправить так, чтобы он писал каждый export файл в отдельную файловую систему.
- Import
(Здесь рассматривается случай, когда надо серьезно ускорить import, например при переливе всей схемы или при переходе на другую платформу)
- отключить archive log mode
- установить _disable_logging=true. Опция достаточно "суровая" -- не пытайтесь сделать 'shutdown abort' после этого, иначе база может не подняться. Обязательно убедитесь, что при этом у Вас отключен archive log mode. После окончания импорта и перед 'shutdown immediate' выставите _disable_logging=false (alter system set "_disable_logging"=false)
- установите очень большое значение db_block_buffers (8i и ниже) или db_cache_size (9i и выше).
- установите очень большое значение sort_area_size (8i и ниже) или pga_aggregate_target (9i и выше).
- импортируйте таблицы параллельно. Для этого, к примеру, достаточно слегка изменить вышеуказанный python скрипт. В конце импортируйте схему.
- на время импорта создайте очень большие redologs, rollback segments и temporary tablespace.
- проведите предварительное тестирование, во время которого оттрассируйте
imp сессию по заливке таблицы среднего размера. Для этого можно создать
следующий системный триггер, который включает трассировку сессии, если это
imp:
create or replace trigger traceimp after logon on database begin for tr in ( select * from ( select sid,serial# serial from v$session where username = user and substr(program,1,4)='imp@' order by logon_time desc ) where rownum < 2 ) loop dbms_system.set_ev(tr.sid,tr.serial,10046,8,''); end loop; end; /
Полученный trace файл обработайте с помощью OraSRP, чтобы увидеть узкие места. Например, если Вы увидите, что слишком много времени тратится на "free buffer waits" -- это значит, что Вы установили недостаточно большое значение db_cache_size.
Следуя этим рекомендациям, Вы без проблем сможете ускорить export/import минимум в три раза. А на многопроцессорных машинах вполне достижимо ускорение на порядок (т.е. в десять раз).