大家好,今天我们想和大家聊一聊我们在 19c 中通过 expdp / impdp 进行迁移时发生的一件非常奇怪的事情。
原库是11g,目标库是19c rac,使用逻辑方式迁移,我们使用 parallel=4 dumpfile=test_%U.dmp导出以加快迁移时间,当使用相同参数时,我们发现在目标库花费的导入时间非常长,而且是极不正常的,要查看每个步骤使用的时间,我们使用了 LOGTIME = ALL 参数,其中包括我们在日志文件中需要的信息。当我们再次检查导入时,我们看到以下内容:
10-MAR-23 14:53: 54.121: Processing object type DATABASE_EXPORT / SCHEMA / PROCEDURE / PROCEDURE
10-MAR-21 15:55: 56.577: Processing object type DATABASE_EXPORT / SCHEMA / PROCEDURE / GRANT / OWNER_GRANT / OBJECT_GRANT
仅在创建存储过程的步骤中就花费了 1 个半小时!?? 😨😨
让我们看看为什么要查看导入会话的等待时间时,我们看到它们保留在库缓存锁中,单个过程可能需要近 200 秒,如果有很多,时间会比必要的长。看到数据库中唯一的会话是导入的会话;
我们尝试使用 PARALLEL = 1 执行导入以查看行为。在这种情况下,程序的步骤很快就解决了,但是表的导入却很慢了,所以我们遇到了问题。
select event,count(*),module from gv$session where type='USER' group by event,module;
会看到大量的LIBARARY CACHE LOCK;
在 metalink 中研究我们发现了这个注释:
在 12.2 RAC 环境中导入 DataPump 期间出现“库缓存锁定”(循环)(文档 ID 2407491.1)
好像是 12.2 以后导入过程中的锁机制出现的 bug。当我们看到可能的解决方案时,我们会看到:
1 / 使用 parallel = 1(默认)运行元数据导入。
– 或 –
2 / 使用以下方法禁用 S-Optimization:
ALTER SYSTEM SET "_lm_share_lock_opt" = FALSE SCOPE = SPFILE SID = '*';
srvctl stop database -d orcl
srvctl start database -d orcl
我们已经看到选项 1 不可行,所以我们继续测试选项 2。
恢复迁移
我们更改参数并重新启动两个实例。完成后,我们再次尝试使用 parallel 8 导入,结果是:
10-MAR-23 16:10:54.121: Processing object type DATABASE_EXPORT / SCHEMA / PROCEDURE / PROCEDURE
10-MAR-21 16:11:10.577: Processing object type DATABASE_EXPORT / SCHEMA / PROCEDURE / GRANT / OWNER_GRANT / OBJECT_GRANT
导入程序用了不到20S !!
有了这些时间,已经可以毫无问题地执行迁移,因此我们保存参数以供将来迁移使用。迁移完成后,我们将按原样返回参数:
alter system reset "_lm_share_lock_opt" scope = spfile sid = '*';
srvctl stop database -d orcl
srvctl start database -d orcl