浅谈exp/imp(上) (r5笔记第81天)

时间:2022-05-04
本文章向大家介绍浅谈exp/imp(上) (r5笔记第81天),主要内容包括作为DBA,经常需要在不同数据库环境间做数据的导入导出,exp/imp就是这样的轻便快捷的客户端工具,可以很方便的在不同数据库之间转移数据对象,即使数据库位于不同的硬件或者软件平台上。exp会转储产生对应的二进制文件,里面包含数据的定义信息,数据内容等,也就是我们通常所说的dump文件。、使用exp/imp的场景、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。

作为DBA,经常需要在不同数据库环境间做数据的导入导出,exp/imp就是这样的轻便快捷的客户端工具,可以很方便的在不同数据库之间转移数据对象,即使数据库位于不同的硬件或者软件平台上。exp会转储产生对应的二进制文件,里面包含数据的定义信息,数据内容等,也就是我们通常所说的dump文件。

exp/imp是比较经典的数据导出导入工具,不过自expdp/impdp推出以来,exp/imp还是受到了不少的冷落,在新的数据库版本中,支持力度都集中在了expdp/impdp上面。Expdp/impdp是基于服务端的数据导入导出工具,性能上和功能上要更胜一筹,不过不管怎样,exp/imp确实是一款比较轻巧的工具,对于小表的处理效果还是相当不错的。

使用exp/imp的场景

使用exp/imp主要有4种模式:数据库模式,表模式,用户模式,可传输表空间模式,在此基础上使用比较多的还有基于query选项的数据选择性抽取和数据结构导出。

数据库模式

数据库模式主要是作为全库备份使用的,可以导出除sys之外的数据库里的所有对象,在数据量较小的情况下是一个不错的选择。

exp n1/n1 file=db_backup.dmp full=y

表模式

表模式可以导出某个用户下指定的表,比如我们需要导出的表名为:test1,test2

exp n1/n1 file=table_mode.dmp tables=test1,test2

用户模式

用户模式可以导出指定用户下所有的对象,比如导出用户user1下所有的对象

exp n1/n1 file=user_mode.dmp owner=user1

传输表空间模式常作为数据迁移时的一种方法,在数据迁移篇中会有详细的描述 海量数据迁移之传输表空间(一) http://blog.itpub.net/23718752/viewspace-1703358/

同理,imp中也会存在同样的四种模式,使用方法都是类似的。

除了常用的4种模式之外,使用query选项选择性导出数据也是一种很使用的方法。比如存在一个表test,我们希望根据字段object_type=’TABLE’的条件来选择性导出数据,可以使用query选项完成。

使用Query选项做选择性数据导出

exp n1/n1 file=query_bak.dmp query=" where  object_type= 'TABLE' "  tables=test

得到对象的ddl语句

还有一个功能点可能大家不太注意,就是能够很方便得到ddl相关的语句。

比如我们希望得到表test的建表语句,可以通过exp/imp这么做。

exp n1/n1 rows=n compress=n tables=test file=test.dmp log=exp_test.log   buffer=10240000
imp n1/n1 rows=n full=y  ignore=y show=y file=test.dmp log=imp_test.log  buffer=10240000

得到的建表语句就会是下面的样子。

import done in AL32UTF8 character set and AL16UTF16 NCHAR character set
. importing N1's objects into N1
. importing N1's objects into N1
 "CREATE TABLE "TEST" ("OWNER" VARCHAR2(30) NOT NULL ENABLE, "OBJECT_NAME" VA"
 "RCHAR2(30) NOT NULL ENABLE, "SUBOBJECT_NAME" VARCHAR2(30), "OBJECT_ID" NUMB"
 "ER NOT NULL ENABLE, "DATA_OBJECT_ID" NUMBER, "OBJECT_TYPE" VARCHAR2(19), "C"
 "REATED" DATE NOT NULL ENABLE, "LAST_DDL_TIME" DATE NOT NULL ENABLE, "TIMEST"
 "AMP" VARCHAR2(19), "STATUS" VARCHAR2(7), "TEMPORARY" VARCHAR2(1), "GENERATE"
 "D" VARCHAR2(1), "SECONDARY" VARCHAR2(1), "NAMESPACE" NUMBER NOT NULL ENABLE"
 ", "EDITION_NAME" VARCHAR2(30))  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 2"
 "55 STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 FREELISTS 1 FREELIST GRO"
 "UPS 1 BUFFER_POOL DEFAULT) TABLESPACE "USERS" LOGGING NOCOMPRESS"
 "CREATE INDEX "IDX_TEST" ON "TEST" ("OBJECT_ID" DESC , "OBJECT_NAME" , "OBJE"
 "CT_TYPE" )  PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE(INITIAL 65536 NEXT 1"
 "048576 MINEXTENTS 1 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT) TABL"
 "ESPACE "USERS" LOGGING"

看起来确实是不太直观,如果自己想直接使用还得手工格式化,这个时候我们可以借助awk来格式化一下。看起来好像挺抽象,但是功能还是很强大的。

awk '
  / "BEGIN /   { N=1; }
  / "CREATE /   { N=1; }
  / "CREATE INDEX/   { N=1; }
  / "CREATE UNIQUE INDEX/  { N=1; }
  / "ALTER /   { N=1; }
  / " ALTER /   { N=1; }
  / "ANALYZE /   { N=1; }
  / "GRANT /    { N=1; }
  / "COMMENT /   { N=1; }
  / "AUDIT /     { N=1; }
  N==1 { printf "n/n"; N++ }
  /"$/ {
    if (N==0) next;
    s=index( $0, """ );
    ln0=length( $0 )
    if ( s!=0 ) {
      lcnt++
      if ( lcnt >= 30 ) {
        ln=substr( $0,s+1,length( substr($0,s+1))-1)
        t=index( ln, ")," )
        if ( t==0 ) { t=index( ln, ", " ) }
        if ( t==0 ) { t=index( ln, ") " ) }
        if ( t > 0 ) {
          printf "%sn%s",substr( ln,1,t+1), substr(ln, t+2)
          lcnt=0
        }
        else {
          printf "%s", ln
          if ( ln0 < 78 ) { printf "n" ; lcnt=0 }
        }
      }
      else {
        printf "%s",substr( $0,s+1,length( substr($0,s+1))-1 )
        if ( ln0 < 78 ) { printf "n" ; lcnt=0 }
      }
    }
  }
  END { printf "n/n"}
' imp_test.log |sed '1,2d; /^$/ d;
s/STORAGE *(INI/~    STORAGE (INI/g;
s/, "/,~    "/g;
s/ ("/~   &/g;
s/PCT[FI]/~    &/g;
s/[( ]PARTITION /~&/g;
s/) TABLESPACE/)~    TABLESPACE/g;
s/   , / ,~/g;
s/ DATAFILE  /&~/' | tr "~" "n"

看看格式化后的结果,如此显著的结果是不是有一种马上想试试的冲动。

  CREATE TABLE "TEST"
    ("OWNER" VARCHAR2(30) NOT NULL ENABLE,
    "OBJECT_NAME" VARCHAR2(30) NOT NULL ENABLE,
    "SUBOBJECT_NAME" VARCHAR2(30),
    "OBJECT_ID" NUMBER NOT NULL ENABLE,
    "DATA_OBJECT_ID" NUMBER,
    "OBJECT_TYPE" VARCHAR2(19),
    "CREATED" DATE NOT NULL ENABLE,
    "LAST_DDL_TIME" DATE NOT NULL ENABLE,
    "TIMESTAMP" VARCHAR2(19),
    "STATUS" VARCHAR2(7),
    "TEMPORARY" VARCHAR2(1),
    "GENERATED" VARCHAR2(1),
    "SECONDARY" VARCHAR2(1),
    "NAMESPACE" NUMBER NOT NULL ENABLE,
    "EDITION_NAME" VARCHAR2(30)) 
    PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
    STORAGE (INITIAL 65536 NEXT 1048576 MINEXTENTS 1 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
    TABLESPACE "USERS" LOGGING NOCOMPRESS
/
CREATE INDEX "IDX_TEST" ON "TEST"
    ("OBJECT_ID" DESC ,
    "OBJECT_NAME" ,
    "OBJECT_TYPE" ) 
    PCTFREE 10 INITRANS 2 MAXTRANS 255
    STORAGE (INITIAL 65536 NEXT 1048576 MINEXTENTS 1 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
    TABLESPACE "USERS" LOGGING
/