首批通过分布式安全可靠测评,为关键业务系统打造
Oracle Store 调优
更新时间:2025-06-11 06:01
本文介绍 Oracle Store 性能相关的参数以及性能问题排查及调优方法。
查看 Oracle Store 是否频繁 FGC
当 Oracle Store 位点推进慢时,首先查看 Oracle Store 是否在频繁 FGC。频繁 FGC 将导致 Oracle Store 处理慢。
通过 metric.log 日志查看 FGC
如果使用的是 OMS V4.0.0 及之后版本,请搜索 log/connector/metric.log 中的 gc.G1-Old-Generation.count。如果一直在增大,即可判断进程在 FGC,您需要调大 JVM 内存。
使用 jstat 命令查看实时 GC
登录到 OMS 所在容器中,用以下命令查看对应 Oracle Store 的实时 GC 情况:
jstat -gcutil `ps -ef | grep storeXXXX | grep java | awk '{print $2}'` 3000
说明
执行以上命令前,您必须将 storeXXXX 替换为待查看的 Oracle Store。例如,store7100。
此命令执行后,将每隔 3s 打印一次实时的 GC。重点关注 FGC 和 FGCT,即自进程启动以来 FGC 的次数和消耗的时间。当 FGC 次数在不断增加或者时间占用进程的运行时间比例超过 10% 时,则调大 Oracle Store 的 JVM 内存。
调整 Oracle Store JVM 内存
调整指定的 Oracle Store JVM 内存
按以下步骤调整指定的 Oracle Store JVM 内存:
登录 OMS 控制台。
在左侧导航栏中单击 运维监控 > 组件,默认进入 Store 页面。
在 Store 页面,单击目标 Store 后的 更新。
在 更新配置 对话框,鼠标悬停至目标配置
deliver2store.subreader.jvm_param,单击显示的编辑图标。在文本框中输入修改后的参数后,单击确认图标。
例如,修改为
-Xms32g -Xmx32g -Xmn8g。通常这三个值的大小比例为 4:4:1,您可以根据机器内存调整为合理的值。在 更新配置 对话框,单击 确定。
如果调整内存大小后,依旧频繁 FULL GC 但不会发生 OOM,请进行下述操作。
进入 Docker 容器。
切换至 ds 用户。
su - ds获取 Store 组件的 Java 进程 PID。
ps -ef|grep storeXXX获取内存 dump 文件。
/opt/alibaba/java/bin/jmap -dump:format=b,file=文件路径/文件名.hprof pid如果会发生 OOM,则需要在对应 Store 组件的
deliver2store.subreader.jvm_param参数后面加上-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=文件路径/文件名.hprof,在程序 OOM 后获取 dump 文件。获取内存 dump 文件后,请联系技术支持人员。
调整所有的 Oracle Store JVM 内存
根据以下步骤调整所有的 Oracle Store JVM 内存:
进入 OMS 容器中的
/home/admin/conf/config.yaml配置文件下,获取元数据库的信息。进入 cm 库,在 cm 库的
config_template插入 JVM 参数的默认配置。示例如下:SELECT * FROM config_template WHERE task_type='deliver2store' AND db_type='Oracle';需要插入的 Key 为
subreader.jvm_param,Value 为具体的 JVM 参数配置。例如,-Xms8g -Xmx8g -Xmn4g -XX:+UseG1GC -XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35 -XX:+DisableExplicitGC。启动新的 Store 组件后,您在 运维监控 > 组件 > Store 页面的 Store 参数中查看到更改后的结果,即为修改成功。
升级 Oracle Store 相关组件
如果您迁移的 Oracle 数据库的归档总量(RAC 则是多个实例的总和)大于 500GB /天,或者 Oracle 数据库单个实例的日志高峰期大于 6MB/s 且持续时间较长,而要求 Oracle Store 的延迟尽可能小,则您需要升级 Oracle Store 相关组件。具体的版本信息请联系技术支持人员。
根据归档量提前调整 Oracle Store 性能相关参数
alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';
--最近 3 天每小时的日志量
select THREAD#,logtime,count(*),round(sum(blocks * block_size) / 1024 / 1024 / 1024) GBSIZE from (select a.THREAD#,trunc(first_time, 'hh') as logtime,a.BLOCKS,a.BLOCK_SIZE from v$archived_log a where a.DEST_ID = 1 and a.FIRST_TIME > trunc(sysdate - 2)) group by THREAD#, logtime order by THREAD#, logtime;
--最近 3 天每天的日志量
select THREAD#,logtime,count(*),round(sum(blocks * block_size) / 1024 / 1024 / 1024) GBSIZE from (select a.THREAD#,trunc(first_time, 'dd') as logtime,a.BLOCKS,a.BLOCK_SIZE from v$archived_log a where a.DEST_ID = 1 and a.FIRST_TIME > trunc(sysdate - 2)) group by THREAD#, logtime order by THREAD#, logtime;
以上 SQL 可查询 Oracle 最近 3 天内每小时和每天产出的归档数量和归档的大小。RAC 环境中,THREAD# 有多个不同的值,请注意区分不同的节点。如果需要修改查询区间,可修改 SQL 中的 sysdate - 2 参数。
如果 Oracle 是 RAC 多实例,请协调客户将流量均衡写入多个 Oracle 实例,这样 Oracle 上各实例的日志量将比较均衡,Oracle Store 的处理也将更快。
如果 Oracle 单个归档文件的大小远大于 2GB,请协调客户调整归档文件到 1~2GB,这样 Oracle Store 处理更快,且需要的内存也更小。
如果 Oracle 单个实例的归档量大于 500GB/天,或者 Oracle 上单个实例的日志高峰期大于 6MB/s 且持续较长时间,而要求 Oracle Store 的延迟尽可能小,则可以提前根据归档量来调整日志拉取并发度等参数(默认日志拉取时不开并发)。
日志拉取并发度的调整根据 1 个并发处理单个实例上的 500GB/天的日志来计算,同时也请关注 Oracle 的配置和负载,1 个日志拉取并发将消耗 Oracle 上 N 个逻辑核( N 为 Oracle 的实例数)。日志拉取并发开得越高,对 Oracle 的开销越大,超过 Oracle 处理能力后,性能反而会下降,同时也可能影响业务数据的写入,甚至可能由于并发的 LogMiner 任务过多,导致 Oracle 服务中断。(需要考虑 1 个 Oracle 数据库可能创建了多条链路,每条链路又创建了多个 Store。对于同一个 Oracle 数据库,创建的多条链路多个 Store 需要统一来考虑日志拉取并发度和 Oracle 的负载)。具体的调整参数如下:
日志拉取并发度调整为
deliver2store.logminer.fetch_arch_logs_max_parallelism_per_instance = 日志量大的那个实例的每天日志量 / 500GB + 1。默认值为1。日志拉取后每个 Oracle 实例对应的归档文件暂存个数
deliver2store.logminer.max_actively_staged_arch_logs_per_instance调整为deliver2store.logminer.fetch_arch_logs_max_parallelism_per_instance的 2 倍。Oracle 上日志量越大,开的并发越多,对 Oracle 的开销也越大。同时 Oracle Store 的内存和 CPU 开销也越大。
根据 Oracle Store Metric 排查调优性能
Oracle Store 每隔 10s 会在 log/connector/metric.log 中打印一次 metric 日志,用于监控各个队列中的数据积压情况,协助排查处理的瓶颈。您可以通过 grep 命令搜索以下队列的关键字并找到对应队列的信息,统计一段时间内的变化,每个队列默认的大小为 20000。
Oracle Store 的处理是 pipeline 模型,如下图。

总的排查思路为:针对各个队列分别分析一段时间(例如 1 个小时)的大小,从上往下找到第一个空的队列(长时间接近 0 ),那么该队列即为瓶颈。
当 Oracle 是 RAC 多实例时,队列的名称前会加上 instance_${instance_num}_,对于前面 3 个队列的分析需要针对每个实例单独分析。例如,分别 grep 'instance_1_log_entry_queue_size' connector.log 和 grep 'instance_2_log_entry_queue_size' connector.log。所有实例的 log_entry_queue 分析完成,判断出非本阶段的瓶颈后,再去分析下一个阶段,即 log_analyse_queue。
各队列说明见下表:
| 队列名称 | 队列说明 |
|---|---|
log_entry_queue_size |
通过 logminer 拉取 Oracle 日志的输出队列 |
log_analyse_queue_size |
日志预解析的输出队列 |
log_aggregator_queue_size |
事务聚合后的输出队列。该阶段会丢弃 rollback 的事务。只有当收到事务 commit 的记录后,才会将该事务的 record 放到该 queue 中 |
log_prepared_converter_queue_size |
从 log_aggregator_queue 中获取的预 convert 的 record 的记录数。当 Oracle 是单节点时,该指标无参考意义。当 Oracle 是 RAC 时,是将多条 log_aggregator_queue 中的记录进行合并排序的结果。合并排序的前提是每条日志流上 log_aggregator_queue 中都有一条还未处理的 commit 记录,然后根据每个日志流里 commit 的先后顺序进行合并排序。例如,Oracle 是 RAC 2 节点,其中一个节点的 log_aggregator_queue_size 是满的,而另一个 log_aggregator_queue_size 为空,则 log_prepared_converter_queue_size 也将为空,因为需要等待另一个节点上有 commit 的记录才能进行合并排序,此时需要根据 log_prepared_converter_queue_size 为空的那个实例的前 3 个 queue 来分析瓶颈点。 |
log_converter_queue_size |
日志解析的输出队列 |
log_after_select_queue_size |
回查的输出队列 |
connect_task_queue_size |
logminer reader 的输出队列 |
下面是根据队列为空的调优方法和调优后的效果观察方法。
| 队列名称 | 为空的调优方法 | 调优后的效果观察方法 |
|---|---|---|
log_entry_queue_size |
可能的原因:
connector.log 中搜索 start loading log entries from log file 查看当前正在分析的日志文件是否为归档文件。如果为归档文件,则可能是单线程的 logminer 达到了性能极限,需要配置为并发拉取归档。具体的调整策略请参见《根据归档量提前调整 Oracle Store 性能相关参数》章节。 |
log_entry_tps:日志拉取通过 logminer 拉取到的 entry 的tps(实际是 rps )。可结合 log_entry_redo_size_avg 来计算拉取的吞吐。log_entry_redo_size_avg:日志拉取通过 logminer 拉取到的 entry 的平均每条的大小,单位:字节。log entries from:可以查看每个归档/redo文件的拉取情况。 |
log_analyse_queue_size |
增加 deliver2store.logminer.analyser_thread_num,默认值为 4。 |
log_entry_analyse_tps:日志 analyse 阶段的 tps(实际是 rps)long_analyse_tps:日志 analyse 阶段生成的 record 的 tps(实际是 rps)。该值会比 log_entry_analyse_tps 小,因为有一部分非白名单里的表被过滤了,同时还存在多条 entry 组装成一条 record 的情况。 |
log_aggregator_queue_size |
需要结合log_aggregator_local_store_size:Oracle Store 缓存的未提交事务记录的数量,Oracle 未提交事务的记录数越多,这个值越大,可收集一段时间内的值,如果这个值涨到了很大,比如几十万,则说明 Oracle 中有大事务,大事务只有在提交之后,Oracle Store 才会开始处理,所以产生一定的延迟,此时应从业务上看能否把大事务拆分开来,使 Oracle Store 能够及时处理数据,将数据输出。log_aggregator_in_disk_transaction_num:缓存到磁盘的事务数量,当一个事务的记录数超过 deliver2store.logminer.max_num_in_memory_one_transaction 参数的值(默认值为 1000)时,会将事务缓存到磁盘中,当有大事务,并且 JVM 内存可调大的话,可以调大deliver2store.logminer.level_store_data_threshold,使事务尽可能放在内存中,提高处理效率。另一方面看从业务上是否能将事务拆小。 |
log_aggregator_local_store_size log_aggregator_in_disk_transaction_num |
log_converter_queue_size |
增加 deliver2store.logminer.converter_thread_num,默认值为 8。 |
log_converter_tps:日志 convert 阶段的 tpslog_converter_rps:日志 convert 阶段的 rps |
log_after_select_queue_size |
增加 deliver2store.logminer.selector_thread_num,默认值为 32。 |
log_select_tps:日志回查阶段的 tps (实际是 rps)。 |
connect_task_queue_size |
增加 deliver2store.logminer.max_landing_message_num,默认值为 40000。调整 deliver2store.logminer.flush_threshold_bytes,默认值为 12288。 |
connect_record_poll_tps:logminer reader 输出的 tps(实际是 rps) |
调整 Store 参数
登录 OMS 控制台。
在左侧导航栏,单击 数据迁移。
在 数据迁移 页面,单击目标任务后的 更多操作 > 查看组件监控。
在 查看组件监控 对话框,单击目标组件后的 更新。
在 更新配置 对话框,鼠标悬停至目标配置,单击显示的编辑图标。在文本框中输入修改后的参数后,单击确认图标。
如果没有要配置的参数,您需要将鼠标悬停至 root 参数旁边的空白处,单击添加图标,配置需要添加的 Key Name 和值。

单击 确定。
完成更新后,Store 会自动重启,以生效变更的参数配置。