【问题标题】:Table of datapump taking so much time while inserting数据泵表在插入时花费了很多时间
【发布时间】:2023-01-31 13:32:06
【问题描述】:

首先,对不起我的英语,我是西班牙人而且我不太擅长。

我在使用数据泵导出和导入两个克隆数据库之间的一些模式时遇到了一些麻烦(以制作单个更新数据)。

首先,我尝试用这个 parfile 制作一个 expdp:

[oracle@ES-NAW-ORACLEVM-PRO backup]$ cat /u01/app/oracle/EXPORTS/FEDBPRE/EXP_FEDBPRE_para_CLON.par
directory=EXPORT_TEMP
dumpfile=EXP_FEDBPRE_%U.dmp
logfile=EXP_FEDBPRE.log 
schemas=AQADM,ASPNETOP,ASSISTANT,AUTOPUB,AUTOPUBOP,AVANTTIC,AVAN_SPA,DBAWKE,JAUSER,JURIMETRIA,JURIMETRIA_OLD,JURI_OPW,MONDB,NAGIOS,NASPOP,NTTAM,PREOP,PREOP_TEST,PRESENTATION,PRESENTATION_TEMP,PRESENT_ACT,PUB,PUBOP,SCOTT,TRACE,TRACEOP,WKE
FILESIZE=10g
parallel=4

然后:

expdp \'/ as sysdba\' PARFILE=/u01/app/oracle/EXPORTS/FEDBPRE/EXP_FEDBPRE_para_CLON.par

导出所有模式大约需要 15 分钟。 我将 DMP 文件移动到克隆的服务器,在数据库上使用 CASCADE 选项删除了用户,然后我让导入使用这个 parfile 运行了一整夜:

[oracle@ES-NAW-ORACLEVM-PRO FEDBPRE_bkp]$ cat /backup/FEDBPRE_bkp/IMP_FEDBPRE_para_CLON.par
directory=EXPORT_TEMP
dumpfile=EXP_FEDBPRE_%U.dmp
logfile=IMP_FEDBPRE.log
ignore=yes
PARALLEL=8
impdp \'/ as sysdba\' PARFILE=/backup/FEDBPRE_bkp/IMP_FEDBPRE_para_CLON.par

第二天,我看了它,花了 4 小时 30 分钟完成导入。我认为导出 15 分钟的时间太长了,所以我重新运行导入以实时查看发生了什么。

在它运行时,我正在查看它在数据库中的运行情况,以使用此查询搜索处理它的会话:

select s.sid, s.module, s.state, substr(s.event, 1, 21) as event, 
s.seconds_in_wait as secs, substr(sql.sql_text, 1, 30) as sql_text
from v$session s
join v$sql sql on sql.sql_id = s.sql_id
where s.module like 'Data Pump%'
order by s.module, s.sid;

一开始,看起来一切正常:

Import: Release 12.1.0.2.0 - Production on Mon Jan 16 13:44:55 2023

Copyright (c) 1982, 2014, Oracle and/or its affiliates.  All rights reserved.

Connected to: Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
Legacy Mode Active due to the following parameters:
Legacy Mode Parameter: "ignore=TRUE" Location: Parameter File, Replaced with: "table_exists_action=append"
Master table "SYS"."SYS_IMPORT_FULL_02" successfully loaded/unloaded
Starting "SYS"."SYS_IMPORT_FULL_02":  SYS/******** PARFILE=/backup/FEDBPRE_bkp/IMP_FEDBPRE_para_CLON.par 
Processing object type SCHEMA_EXPORT/USER
Processing object type SCHEMA_EXPORT/SYSTEM_GRANT
Processing object type SCHEMA_EXPORT/ROLE_GRANT
Processing object type SCHEMA_EXPORT/DEFAULT_ROLE
Processing object type SCHEMA_EXPORT/TABLESPACE_QUOTA
Processing object type SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMA
Processing object type SCHEMA_EXPORT/SYNONYM/SYNONYM
Processing object type SCHEMA_EXPORT/TYPE/TYPE_SPEC
Processing object type SCHEMA_EXPORT/SEQUENCE/SEQUENCE
Processing object type SCHEMA_EXPORT/SEQUENCE/GRANT/OWNER_GRANT/OBJECT_GRANT
Processing object type SCHEMA_EXPORT/TABLE/TABLE
Processing object type SCHEMA_EXPORT/TABLE/TABLE_DATA
. . imported "PUB"."PUBLICATIONS"                        1.582 GB 23242881 rows
. . imported "ASSISTANT"."ASSIST_NODES_RESOURCES"        1.319 GB 74670288 rows

使用查询我看到一切正常:

  SID MODULE            STATE               EVENT                       SECS SQL_TEXT
----- ----------------- ------------------- --------------------- ---------- ------------------------------
  312 Data Pump Master  WAITING             wait for unread messa          1 BEGIN :1 := sys.kupc$que_int.r
   65 Data Pump Worker  WAITING             log file switch (chec         46  BEGIN    SYS.KUPW$WORKER.MAIN
   75 Data Pump Worker  WAITING             log file switch (chec         39  BEGIN    SYS.KUPW$WORKER.MAIN
  127 Data Pump Worker  WAITING             log file switch (chec         55  BEGIN    SYS.KUPW$WORKER.MAIN
  187 Data Pump Worker  WAITING             wait for unread messa          4 BEGIN :1 := sys.kupc$que_int.t
  187 Data Pump Worker  WAITING             wait for unread messa          4 BEGIN :1 := sys.kupc$que_int.t
  194 Data Pump Worker  WAITING             wait for unread messa          4 BEGIN :1 := sys.kupc$que_int.t
  194 Data Pump Worker  WAITING             wait for unread messa          4 BEGIN :1 := sys.kupc$que_int.t
  247 Data Pump Worker  WAITING             wait for unread messa          3 BEGIN :1 := sys.kupc$que_int.t
  247 Data Pump Worker  WAITING             wait for unread messa          3 BEGIN :1 := sys.kupc$que_int.t
  249 Data Pump Worker  WAITING             direct path sync               1 INSERT /*+ APPEND PARALLEL("TR
  301 Data Pump Worker  WAITING             log file switch (chec         55 INSERT /*+ APPEND PARALLEL("TR
  361 Data Pump Worker  WAITING             log file switch (chec         55 INSERT /*+ APPEND PARALLEL("AS
  371 Data Pump Worker  WAITING             direct path sync               2 INSERT /*+ APPEND PARALLEL("TR
  418 Data Pump Worker  WAITING             direct path sync               2 INSERT /*+ APPEND PARALLEL("TR
  428 Data Pump Worker  WAITING             PX Deq: Execute Reply          1 INSERT /*+ APPEND PARALLEL("TR

但是突然之间,impdp 在表 ASSISTANT.ASSIST_NODES 之后看起来像冻结了,我想知道发生了什么:

[...]
. . imported "ASSISTANT"."ASSIST_NODES_DA"               307.6 MB 4322248 rows
. . imported "ASSISTANT"."ASSIST_TYPES_CHANGED"          21.15 MB 1249254 rows
. . imported "ASSISTANT"."STR_RESOURCES"                 845.4 MB 10994245 rows
. . imported "ASSISTANT"."ASSIST_NODES"                  6.526 GB 74638678 rows
  SID MODULE            STATE               EVENT                       SECS SQL_TEXT
----- ----------------- ------------------- --------------------- ---------- ------------------------------
  312 Data Pump Master  WAITING             wait for unread messa          1 BEGIN :1 := sys.kupc$que_int.r
   65 Data Pump Worker  WAITING             wait for unread messa          2 BEGIN :1 := sys.kupc$que_int.t
   65 Data Pump Worker  WAITING             wait for unread messa          2 BEGIN :1 := sys.kupc$que_int.t
   75 Data Pump Worker  WAITING             wait for unread messa          4 BEGIN :1 := sys.kupc$que_int.t
   75 Data Pump Worker  WAITING             wait for unread messa          4 BEGIN :1 := sys.kupc$que_int.t
  127 Data Pump Worker  WAITING             wait for unread messa          2 BEGIN :1 := sys.kupc$que_int.t
  127 Data Pump Worker  WAITING             wait for unread messa          2 BEGIN :1 := sys.kupc$que_int.t
  187 Data Pump Worker  WAITING             wait for unread messa          3 BEGIN :1 := sys.kupc$que_int.t
  187 Data Pump Worker  WAITING             wait for unread messa          3 BEGIN :1 := sys.kupc$que_int.t
  194 Data Pump Worker  WAITING             wait for unread messa          4 BEGIN :1 := sys.kupc$que_int.t
  194 Data Pump Worker  WAITING             wait for unread messa          4 BEGIN :1 := sys.kupc$que_int.t
  247 Data Pump Worker  WAITING             wait for unread messa          2 BEGIN :1 := sys.kupc$que_int.t
  247 Data Pump Worker  WAITING             wait for unread messa          2 BEGIN :1 := sys.kupc$que_int.t
  361 Data Pump Worker  WAITED KNOWN TIME   direct path sync               0 INSERT /*+ APPEND PARALLEL("AS
  428 Data Pump Worker  WAITING             wait for unread messa          2 BEGIN :1 := sys.kupc$que_int.t
  428 Data Pump Worker  WAITING             wait for unread messa          2 BEGIN :1 := sys.kupc$que_int.t

我搜索了 SID=361 的会话并执行了以下 SQL_ID=bh6qct41h9bth 并且文本是:

INSERT /*+ APPEND PARALLEL("ASSIST_NODES_METADATA",1)+*/ 
INTO RELATIONAL("ASSISTANT"."ASSIST_NODES_METADATA" NOT XMLTYPE) 
("NODE_ID", "AST_NODES_MT_TYPE", "XML_DATA")     SELECT "NODE_ID", 
"AST_NODES_MT_TYPE", SYS.XMLTYPE.CREATEXML("XML_DATA")      FROM 
"SYS"."ET$0169B1810001" KU$

Appearenlty,数据插入正在一个接一个地进行,甚至知道我在 parfile 上设置了 PARALLEL=8。 我不知道这个表的 XML_DATA 列是否是导致它的原因。

搜索这种缓慢,我发现了这个 oracle 文档: Doc ID 2014960.1 我在哪里可以看到从版本 11.2.0.3 到 12.1.0.2 的 Oracle 数据库企业版可能会受到错误 19520061 的影响。

所以...他们提出了 3 种解决方案:

1. Upgrade the database to 12.2, when available, where issue is fixed.
- OR -
2. For earlier database releases please check Patch 19520061, if available 
for your platform and RDBMS version.
- OR -
3. Run the DataPump import job with an user other than SYS.

确认此表使 impdp 花费了这么长时间,我不得不告诉我我做了另一个导入,不包括表,它花了大约 20 分钟。

我用授予 DBA 角色的用户尝试了第三个,但没有任何改变,所以......第 3 个解决方案被驳回。

我看过一些文章谈论增加表的并行度 DEGREE 但它也没有用。

我正在考虑“强制”oracle 插入具有特定并行的行,但不将其设置在 parfile 中的方法。就像oracle这样插入的方式一样,在table_name后面有特定的并行(8):

INSERT /*+ APPEND PARALLEL("ASSIST_NODES_METADATA",8)+*/ INTO 
RELATIONAL("ASSISTANT"."ASSIST_NODES_METADATA" NOT XMLTYPE)...

除了应用补丁或升级之外,还有什么解决方案可以减少这个 impdp 时间?

【问题讨论】:

    标签: oracle performance parallel-processing insert datapump


    【解决方案1】:

    如果您想专注于优化表 ASSISTANT.ASSIST_NODES_METADATA 的 XML 列的缓慢导入,我相信如果将列存储为 SECUREFILE(如果还没有,但我预计目前它是 BASICFILE,您可以获得大部分好处,考虑到您遇到并要求解决的性能问题)。

    主要有两种方法 - 您可以将 XML 列 XML_DATA 转换为源数据库(在导出之前)或目标数据库上的 SECUREFILE。最好是在 Source DB 上执行此操作,因为您应该执行一次,然后每次必须执行模式的 Exp/Imp 时,都不需要任何额外的步骤。但这取决于您的应用程序和其他条件——您是否能够/被允许执行此类更改。

    如果转换为 SECUREFILE 应该在目标数据库上完成 - 以下注意事项:

    • impdp 实用程序的某些版本引入了新的转换参数,TRANSFORM =LOB_STORAGE:SECUREFILE - 检查,您的 12.1.0.2 版本中是否有它
    • 然后添加了其他类似的选项LOB_STORAGE=SECUREFILE - 这两个参数都允许您在导入过程中(在表的时刻)将LOB列(您的XML_DATA列)自动转换为SECUREFILE存储类型段创建)
    • 另一种方法是单独导入所有模式和对象/它们的数据,并单独导入有问题的表ASSISTANT.ASSIST_NODES_METADATA(就像您已经做的那样)。导入表时,首先只导入表的定义(使用METADATA_ONLY方式,或者直接从Source DB中手动复制DDL),修改STORAGE AS部分CREATE TABLE语句为SECUREFILE
    • 然后仅导入该表的数据(DATA_ONLY模式)
    • 您可以尝试使用参数文件中的 QUERY 参数模拟并行导入,并以并行 8(或任何其他首选并行度)单独的 impdp 进程开始,并在 QUERY 参数中使用适当的过滤器值。对于 QUERY 值,您应该在 NODE_IDAST_NODES_MT_TYPE 列上使用过滤器 - 分析这些列的内容,是否可以将表拆分成或多或少相同的块或块

    很少有cmets,只是关于导入过程:

    • 在您的参数文件选项中设置 METRICS=YESLOGTIME=ALL - 然后就不需要坐下来观察导入过程是如何运行的 - 您将有每个步骤的时间戳和持续时间,即对于每个处理的表,如何导入它花了很长时间。您还将看到为每个表选择的“路径”数据泵 - CONVENTIONALDIRECT_PATH 插入路径
    • 对于表和索引,通过EXLUDE=TABLE_STATISTICS,INDEX_STATISTICS参数排除优化器统计也很重要(适用于导出和导入阶段)。这种排除的理由是——无论如何,好的做法是在所有对象导入新数据库后重新收集优化器的统计信息。因此,如果统计信息无论如何都会被新的收集过程覆盖,那么导入统计信息是无用的。但排除将在导入过程中确保可测量的时间。
    • 在您发布的输出之一中,显示了事件 "log file switch (checkpoint incomplete)" 的长时间等待事件 - 似乎在导入期间,您的重做日志配置无法有效地赶上此类负载。检查重做日志配置和可能添加更多重做日志组和/或使用更大的重做日志成员的事项。同时,无需尝试实现(有时)推荐的“每 20 分钟/每小时 3 次”左右的重做日志切换频率 - 因为您的导入过程很少见。所以,需要一些平衡。
    • 也是一个有时使用的技巧 - 考虑在导入阶段将数据库切换到NOARCHIVELOG模式,并在导入完成后切换回ARCHIVELOG模式并立即执行数据库备份
    • 或者,如果您不想更改 NOARCHIVELOG / ARCHIVELOG 模式(因为这将需要 2 次 DB 重启),那么您可以通过放置 Tablespace(-es) 实现几乎相同的效果,将存储导入的段,进入NOLOGGING模式,执行导入,将表空间切换回LOGGING模式,然后立即进行DB备份

    几个关于,阅读和学习聪明人推荐的关于数据泵导入优化的 URL:

    附言我相信,您想要优化导入阶段,因为您计划定期执行它(例如,使用来自源数据库的最新数据刷新目标数据库)。也就是说,Export/Import exercise 计划是周期性任务,不是一次性任务?

    【讨论】:

    • 我已经使用并行 16 进行了新测试,但 impdp 仅对插入使用并行 5:INSERT /*+ APPEND PARALLEL("ASSIST_NODES_METADATA",5)+*/ INTO RELATIONAL("ASSISTANT"."ASSIST_NODES_METADATA" NOT XMLTYPE. .. 这是为什么?
    【解决方案2】:

    感谢您的回答,这一切都非常清楚并且包含大量信息。

    我试过在 Source DB 上将 XML_DATA 列更改为 securefile(它是 basicfile):

    SYS@FEDBPRE> alter table ASSISTANT.ASSIST_NODES_METADATA move lob(SYS_NC00004$) store as securefile(tablespace ASSISTANT_DAT) parallel 10;
    
    Table altered.
    
    Elapsed: 00:04:52.35
    

    制作 ALTER TABLE 花了大约 5 分钟,但它起作用了。

    我发现的原始陈述是这样的:

    alter table ASSISTANT.ASSIST_NODES_METADATA move lob(SYS_NC00004$) store as securefile( tablespace ASSISTANT_DAT compress high deduplicate )  parallel 10;
    

    但是我害怕使用“压缩高”和“重复数据删除”选项,因为我在 oracle 注释上读到我需要一个名为“Oracle Advanced Compression”的许可证: https://docs.oracle.com/database/121/ADLOB/adlob_smart.htm#ADLOB45944

    无论如何,我在没有这些选项的情况下尝试了这个 ALTER TABLE,如果这可以增加 INSERTS,我会保持并行 10。

    我仅从 de SourceDB 中导出表并将其导入到 DestinationDB 中,并行 6,最后我可以看到 7 个从属在 INSERT 上工作(我想是因为我有 7 个 DMP 文件并且表并行设置为 10):

     SID MODULE             STATE               EVENT                       SECS SQL_TEXT
    ---- ------------------ ------------------- --------------------- ---------- ------------------------------
     187 Data Pump Master   WAITING             wait for unread messa          1 BEGIN :1 := sys.kupc$que_int.r
      75 Data Pump Worker   WAITED SHORT TIME   PX Deq Credit: send b          0 INSERT /*+ APPEND PARALLEL("AS
     191 Data Pump Worker   WAITING             PX Deq Credit: send b          0 INSERT /*+ APPEND PARALLEL("AS
     247 Data Pump Worker   WAITING             PX Deq Credit: send b          0 INSERT /*+ APPEND PARALLEL("AS
     314 Data Pump Worker   WAITING             PX Deq Credit: send b          0 INSERT /*+ APPEND PARALLEL("AS
     361 Data Pump Worker   WAITING             PX Deq Credit: send b          0 INSERT /*+ APPEND PARALLEL("AS
     423 Data Pump Worker   WAITED SHORT TIME   PX Deq: Execute Reply          0 INSERT /*+ APPEND PARALLEL("AS
     428 Data Pump Worker   WAITED KNOWN TIME   PX Deq Credit: send b          0 INSERT /*+ APPEND PARALLEL("AS
    

    寻找正在执行的 SQL_ID 现在正在应用并行 6:

    INSERT /*+ APPEND PARALLEL("ASSIST_NODES_METADATA",6)+*/ INTO RELATIONAL("ASSISTANT"."ASSIST_NODES_METADATA" NOT XMLTYPE) 
    ("NODE_ID", "AST_NODES_MT_TYPE", "XML_DATA")     SELECT "NODE_ID", "AST_NODES_MT_TYPE", SYS.XMLTYPE.CREATEXML("XML_DATA")
          FROM "AVANTTIC"."ET$01A739BA0001" KU$
      
    

    最终在 1 小时 39 分结束,比之前的进口减少了 3 小时。

    我将再次尝试使用 filesize=4g(而不是 10g)导出以生成更多 DMP 文件并使用 parallel=16 导入以查看结果如何。

    非常感谢 Shane,您的帮助非常有用,感谢您抽出宝贵的时间来做这件事:D

    【讨论】:

    • 您对 LOB 段的重复数据删除和压缩是正确的——这些是企业版单独许可的选项 Oracle Advanced Compression 的特性。
    猜你喜欢
    • 1970-01-01
    • 2023-03-05
    • 2017-05-10
    • 2015-08-02
    • 1970-01-01
    • 1970-01-01
    • 2011-06-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多