当DB2中出现执行计划不稳定或优化器选择了低效访问路径时,仅靠EXPLAIN输出有时看不到优化器在成本估算过程中尝试过的其他方案。DB2提供了一类部分访问日志机制,通过注册变量opt_enable_partial_access_log可以记录优化器在生成访问计划时未完整展开的部分访问路径信息。这个变量并不会生成完整的explain快照,而是把编译阶段被裁剪掉的候选访问方式记录下来,适合用来分析优化器为何没有选择某个索引或连接顺序。

在启用该参数之前,需要先理解它的作用边界。opt_enable_partial_access_log属于实例级注册变量,配置后会写入DB2注册表,并在实例重启后对所有数据库生效。它与诊断日志级别、优化器跟踪参数可以叠加使用,但不能代替db2exfmt生成的完整访问计划。它的价值在于补充解释工具看不到的中间裁剪过程,尤其在涉及多表连接、子查询展开、星型模型查询时更有参考意义。
一、启用前的环境检查与参数确认
首先确认当前实例名称和DB2版本。不同版本对部分访问日志的支持程度可能存在差异,但该注册变量在多数Linux、Unix和Windows平台的DB2企业版中都能使用。执行下面的命令查看当前实例和已经设置的注册变量,避免重复配置或与既有变量冲突。
# 查看当前实例 db2 get instance # 查看所有与OPT相关的注册变量 db2set -all | grep -i OPT # 查看当前诊断日志级别 db2 get dbm cfg | grep -i DIAGLEVEL
如果输出中没有与opt_enable_partial_access_log相关的配置,说明尚未启用。诊断日志级别建议至少设置为3,因为部分访问日志的详细程度会受诊断级别影响。级别过低时可能只记录发生错误的访问路径,而不会输出被裁剪的候选计划。
还需要确认实例是否有足够的空间存放诊断日志。部分访问日志会写入实例的诊断目录,如果诊断目录所在文件系统空间紧张,建议先扩容或设置日志轮转。可以使用df -h或操作系统命令查看目录占用情况。生产环境建议在启用前先记录磁盘基线,便于后续评估日志增长幅度。
二、启用opt_enable_partial_access_log的完整步骤
启用该参数使用db2set命令完成。注册变量名不区分大小写,但在脚本中建议统一使用大写,便于和IBM官方文档保持一致。执行命令前需要关闭所有数据库连接,并停止实例,因为注册变量写入后必须重启实例才能全面生效。
# 设置部分访问日志注册变量 db2set DB2_OPT_ENABLE_PARTIAL_ACCESS_LOG=YES # 确认写入成功 db2set -all # 停止实例 db2stop force # 启动实例 db2start
启动后可以通过数据库管理器配置确认实例状态正常。如果担心参数未生效,可以执行一条较复杂的查询,再检查诊断日志中是否出现partial access相关条目。不同版本中日志关键字可能是partial access或OPT_PARTIAL_ACCESS,具体以环境输出为准。
如果想在会话级临时验证而不影响整个实例,不建议使用该参数,因为opt_enable_partial_access_log不是会话级可切换的优化器开关。测试环境可以全局开启,生产环境如果要临时启用,必须评估重启实例带来的连接中断风险。建议在维护窗口操作,或在备节点先验证日志输出符合预期。
三、日志内容解读与SQL访问路径分析
启用后,诊断日志中会出现优化器在枚举访问路径时被记录下来的部分信息。这些信息通常包含表名、访问方式、估算成本、裁剪原因等字段。下面截取一个简化后的日志片段,展示部分访问日志可能输出的内容结构。
PARTIAL ACCESS LOG: Statement ID: 20240315_101200_0001 Table: SALES Access Path: IXSCAN Index: IDX_SALES_CUST_DATE Estimated Cost: 1847.32 Pruned Reason: High index key selectivity uncertainty Alternative Considered: TBSCAN Alternative Cost: 2120.18
从这个片段可以看出,优化器考虑了索引扫描和表扫描两种方式,最终因为统计信息不确定性裁掉了索引扫描。如果该表实际数据分布与统计信息不一致,就可能出现走表扫描反而更慢的情况。此时需要结合RUNSTATS重新收集统计信息,或检查索引的聚簇因子是否失真。
多表连接场景下,部分访问日志还能记录不同连接顺序的成本变化。例如优化器在评估A先连B再连C时,可能因为中间结果集过大而裁掉该顺序。日志中会出现JOIN ORDER PRUNED、INTERMEDIATE CARDINALITY等字样。DBA可以根据这些信息调整连接顺序或引入物化查询表,帮助优化器获得更准确的基数估计。
需要注意的是,部分访问日志只是辅助信息,不能单独作为修改优化器参数的依据。应该将日志中显示的裁剪原因与EXPLAIN输出、db2caem捕获的详细成本信息进行交叉验证,确认是否真的存在统计信息延迟、参数配置不当或SQL写法问题。
四、日志过多时的处理与关闭方法
如果在业务高峰期发现部分访问日志增长速度过快,可以通过调整诊断日志级别或直接关闭该注册变量来控制。诊断日志级别降低到2会减少普通优化信息输出,但可能影响其他排障能力,所以更稳妥的做法是按需关闭opt_enable_partial_access_log。
# 关闭部分访问日志 db2set DB2_OPT_ENABLE_PARTIAL_ACCESS_LOG= # 确认变量已清空 db2set -all | grep -i PARTIAL_ACCESS # 重启实例使配置生效 db2stop force db2start
关闭后诊断日志中不会再出现部分访问日志条目,优化器本身的行为不会因此改变。该参数只影响日志记录,不参与访问计划选择,所以关闭后SQL执行计划不会发生变化。如果关闭后SQL性能突然变化,通常与统计信息更新、缓冲池变化或其他参数调整有关,不应归因于该变量。
总体而言,opt_enable_partial_access_log适合在出现执行计划不稳定、优化器选择异常访问路径时临时开启,为定位问题提供裁剪过程依据。长期开启时建议配合诊断日志轮转和空间监控,确保不会因为日志膨胀影响实例可用性。

