Welcome 微信登录

首页 / 数据库 / MySQL / 使用awk来解析dump文件

dump文件是平时工作中经常碰见的,有时候得到一个dump,但是没有提供一些更多的信息,导入的时候就很可能会有问题。如果某个用户默认表空间是user,但是dump中的表所属的表空间是datas01,则导入的时候会自动转换表空间。
 但是如果表中存在lob字段且dump的表空间和目标环境的表空间不一致,就有在导入dump的时候,经典的00959问题,错误类似下面的形式。
 
IMP-00017: following statement failed with Oracle error 959:
  "CREATE TABLE "XXXX_RULEGROUP" ("RULE_GROUP_ID" NUMBER(12, 0) NOT NULL ENABLE"
  ", "RULE_GROUP_NAME" VARCHAR2(60), "ENABLED" NUMBER(1, 0), "RULE_GROUP_RULES"
  "" CLOB, "SCHEDULING_START_TIME" TIMESTAMP (6), "SCHEDULING_INTERVAL" NUMBER"
  "(12, 0))  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 STORAGE(INITIAL 104"
  "8576 NEXT 1048576 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT) TABLES"
  "PACE "DATAS01" LOGGING NOCOMPRESS LOB ("RULE_GROUP_RULES") STORE AS  (TABLE"
  "SPACE "INDXS01" ENABLE STORAGE IN ROW CHUNK 8192 RETENTION NOCACHE LOGGING "
  " STORAGE(INITIAL 1048576 NEXT 1048576 FREELISTS 1 FREELIST GROUPS 1 BUFFER_"
  "POOL DEFAULT))"
 IMP-00003: ORACLE error 959 encountered
 ORA-00959: tablespace "DATAS01" does not exist当然了,可能还有更复杂的场景,比如我们需要在得到一个dump的时候,只希望运行指定的一部分脚本。可能稍候再导入部分数据,这种场景就不能满足了。
 可以考虑使用awk来解析dump文件,当然了直接解析dump文件的话很容易有性能问题,而且可能使用perl速度会快一些。AWK简介及使用实例 http://www.linuxidc.com/Linux/2013-12/93519.htmAWK 简介和例子 http://www.linuxidc.com/Linux/2012-12/75441.htmShell脚本之AWK文本编辑器语法 http://www.linuxidc.com/Linux/2013-11/92787.htm正则表达式中AWK的学习和使用 http://www.linuxidc.com/Linux/2013-10/91892.htm文本数据处理之AWK 图解 http://www.linuxidc.com/Linux/2013-09/89589.htm
 这里我们可以过滤一下信息。转储一下dump文件,生成相关的dump日志。只需要解析指定格式的dump日志就可以了。
 这里我们假定dump文件名为test.dmp,生成的转储文件为imp_test.log,不会导入数据的。
 imp rows=n full=y  ignore=y show=y file=test.dump log=imp_test.log userid=tests/oracle buffer=10240000接下来,使用awk来解析,假定这个脚本文件名字为gettabddl.sh
 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++ }
 /"$/ {
   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 "%s %s",substr( ln,1,t+1), substr(ln, t+2)
         lcnt=0
       }
       else {
         printf "%s", ln
         if ( ln0 < 78 ) { printf " " ; lcnt=0 }
       }
     }
     else {
       printf "%s",substr( $0,s+1,length( substr($0,s+1))-1 )
       if ( ln0 < 78 ) { printf " " ; lcnt=0 }
     }
   }
 }
 END { printf " / "}
 " $* |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 "~" " "
 
这样运行即可。imp_test.log是刚刚生成的转储imp日志。只会生成一些ddl相关的脚本。就是awk来解析和格式化的。最终生成的脚本是gen_tabddl.sql
 ksh gettabddl.sh imp_test.dmp > gen_tabddl.sql生成脚本的格式如下所示 。可以自己在里面做一些改动。
CREATE TABLE "XXX_PARAMS"
("PARAM_KEY" NUMBER(6, 0) NOT NULL ENABLE,
"PARAM_TYPE" VARCHAR2(50) NOT NULL ENABLE,
"PARAM_VALUE" VARCHAR2(100))
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
STORAGE (INITIAL 1048576 NEXT 1048576 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "TEST" LOGGING NOCOMPRESS
/
CREATE UNIQUE INDEX "XXX_PARAMS_PK" ON "XXX_PARAMS"
("PARAM_KEY" )
PCTFREE 10 INITRANS 2 MAXTRANS 255
STORAGE (INITIAL 1048576 NEXT 1048576 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "TEST" LOGGING
/
ALTER TABLE "XXXX_PARAMS" ADD CONSTRAINT "XXX_PARAMS_PK" PRIMARY KEY
("PARAM_KEY") USING INDEX
PCTFREE 10 INITRANS 2 MAXTRANS 255
STORAGE (INITIAL 1048576 NEXT 1048576 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "TEST" LOGGING ENABLE
/更多Oracle相关信息见Oracle 专题页面 http://www.linuxidc.com/topicnews.aspx?tid=12本文永久更新链接地址