X86比小型机要慢很多?--技术人生系列第四十八期-我和数据中心的故事

来源:这里教程网 时间:2026-03-03 12:31:41 作者:

一、问题描述

某大型国有银行的一套业务系统,近期由小型机迁移至X86环境。据项目组反映部分DB_LINK查询比原来小型机慢。这不对啊,相同的存储,CPU也更多,内存也更大。

于是 DBA随手挑出一张大表,做个简单的COUNT(*)查询,发现Linux比AIX慢了6倍 。重复执行多次,结果也类似。难道委屈项目组了,这套 X86 就是比小机慢? 于是找上中亦,深入分析下问题原因。

执行时间对比

AIX 下执行时间为 3 10

Linux 执行 时间为 19分 3

相同 SQL 语句在, AIX 环境下执行时间为 Linux 下执行时间快 6 倍。

二、问题排查

环境有何差异

现场的环境配置如下表:

看得出, Linux配置确实比AIX 来的高

其他表试试?

既然每次 执行 TAB1 Linux 都会比AIX慢6 ~7 倍,那不如我们换张表试试,这边我随机测试了5 表,结果 Linux 都会比 AIX 快20 % 。那么问题肯定和这张表有关。

 

是不是 Linux 环境上该表上碎片太多了?不对,我们先看执行计划和等待事件

执行计划

检查 2 环境的执行计划是否一致,都是走 Index   Fast Full Scan

等待事件应该为“ db file scattered read

AWR 对比分析

抓取当时的 AWR 报告进行对比 分析

AIX 环境:

多块读仅仅等待了 694 次,每次 11 毫秒。

Linux环境:

多块读等待了 98921 次,单次等待 9 毫秒

现场真实执行一次

AIX Linux 环境, 同时对 TAB1 表执行 COUNT(*) 查询,观察ASH视图。

Linux 环境:

首先查询到此次执行的 SQL_EXEC_ID 11 g 引入该字段真的是太好用了,标记出每个连接在执行相同的 SQL 语句时候的执行序号

AS H 默认 抓取间隔是 1 ,该次执行 花费 了至少 943

考虑到 db file scattered read   等待事件可能受到参数 db_file_multiblock_read_count 的影响,当数据存储不够连续时候,可能增加多块读等待次数。

该等待事件 P3 代表 BLOCKS 其含义可以从 P3TEXT 列看出,为此次等待请求读取的数据块数目。

该次执行中, P3 的平均值为 31.96 ,接近主机参数 db_file_multiblock_read_count=32 ,可以判断出数据存储,基本是连续的。

AIX 环境:

查询到此次执行的 SQL_EXEC_ID, 继续查看该次执行等待多块读的次数

在AIX环境下没有进行一次多块读, 让我们看看等待事件是什么?

不对, AIX和 Linux 环境好像都开启了 EVENT 10949 ,不应该出现直接路径读

三、寻找规律

多块读的执行方式

在Oracle 11.2版本,对表或者索引的大小存在2个界限。

进行 全表扫描 ( Table Full Scan) 或者索引 快速全 扫描( Index Fast Full Scan) 时候 将对象的大小 ,和 STT VLOT 进行对比 。所以 当表 或者 索引的大小超过 某个 阈值, 即使 设置 EVENT 10949 仍然 出现直接路径读

为了验证 Oracle 数据库 如何选择多块读的执行方式,我们开启的 NSMTIO 跟踪,从 Trace 文件 中可以看到 VLOT 的计算值

生成 Trace文件 示例如下 包含了 Object Size和 VLOT ,其单位都是 BLOCK

验证 _small_table_threshold 参数

这次 需要查询 Oracle 数据库 的隐藏参数, 可以建立 视图 方便 查询:

H$PARAMETER 视图的 DESCRIPTION ,我们可以 得知参数信息

测试环境, 调整 SGA 大小,计算 STT 值:

计算公式如下

这里隐藏 参数 _db_block_buffers ”, 在数据库实例 启动时候 自动 生成的 。早期版本 ORACLE 数据库 通过“ db_block_buffers ”参数用来 调整 BufferCache 大小 参数,单位是 BLOCK ,在 ORACLE 9 时代 变成 隐藏 参数, ORACLE 数据库内部的一些参数计算 仍然 可能使用到

验证 _very_large_object_threshold 参数

查询 H$PARAMETER视图, 参数描述 如下 默认值为 500

百度 一番 ,存在 下面 2种 说法:

1. VLOT 就是 5倍 Buffer Cache 大小 那么 这参数 存在 什么意义。

2. 单位为 MB,在当今 单表容量随便 TB 时代 500 MB的上限, 基本 是错误的

在测试环境,通过调整SGA的大小,开启跟踪测试VLOT计算值

通过计算得知,其单位应该为百分比 计算公式如下:

关参数_serial_direct_read

查询H$PARAMETER视图,该参数决定是否使用直接路径读,相当于总开关

参数_direct_read_decision_statistics_driven

查询H$PARAMETER视图,参数描述如下

ORACLE 采用表上统计信息来决定是否使用 DPR ,而不是 DBA_SEGMENTS 里面真实记录数。该参数在 ORACLE 11.2 .0.2 以后版本默认为 TRUE

所以直接修改表的统计信息,可以直接影响的DPR的选择

测试执行 DPR 规则

测试环境: ORACLE 11.2.0.4 + Linux

开启跟踪

建立测试表 隐藏参数查询视图 系统参数 计算各个阈值 收集统计信息

修改统计信息 测试结果汇总: 可以看到在 11.2 版本下,小于 SST 不走 DirectRead ,大于 VLOT 一定走 DirectRead ,介于 SST VLOT 的表,需要考虑是否为本地表或者压缩表 MTT 11.2 版本已经淘汰。

DPR  算法总结

Oracle 11.2版本,全表扫描或者索引快速全扫描,是否走直接路径读,与STT和VLOT值有关

总结出执行规律:

参数验证

回到 案例中,为什么在 AIX环境下选择了直接路径读,而Linux环境选择 进入 Buffer Cache 缓存;

该SQL语句采用对索引PK_TAB1进行Index Fast Full Scan,这边我列举出2套环境各个参数的真实值,并且开启跟踪验证了VLOT计算值

IX 环境 :索引 大小 94716MB   >   VLOT 大小 39920MB

Linux环境 :索引 大小 94632MB  <   VLOT大小160040MB

 

这下终于搞清楚真相了,因为Linux环境的Buffer Cache内存配置较大,小于VLOT大小,所以不执行Direct Path Read;而在AIX环境下,Buffer Cache内存配置较小,超过了VLOT大小,所以执行Direct Path Read

四、问题延伸

分区表如何计算

前面我们已经知道普通表或者索引的VLOT算法和DRP选择机制,那么如果是分区表,ORACLE怎么进行选择呢?

测试环境: ORACLE  11.2.0.4 + Linux

相关系统参数

计算各个阈值

收集统计信息

通过不断 的修改 统计信息, 进行测试验证

测试结果汇总

可以看出 DPR 的评估,不会考虑分区的格式,只是取整个分区表的统计信息

如果 将每个分区的 BLOCKS 修改到最大值,表级别的 BLOCK 修改为较小值, 会出现什么情况?

重复刚才的测试,发现其执行规则没有发生改变。分区级别的统计信息不会影响 DPR 的判断

索引快速全扫描如何计算

测试环境: ORACLE  11.2.0.4 + Linux;

建立测试表, 4 HASH 分区,建立普通索引;

修改索引的统计信息

再次查询索引统计信息

确认执行计划走上 IFFS

测试结果汇总:

可以看出DPR在评估IFFS时候不会考虑STT参数。超过VOLT大小,就走直接路径读,也就是说EVENT 10949 与索引快速全扫描无关

新版本改进

+

+

思考一个问题,为什么很多客户的ORACLE数据库中,EVENT 10949变成必调参数?

个人见解:理想情况下,OLTP系统中大于2% Buffer Cache的表,应该大部分会走索引扫描,偶尔一两次大表全表查询走直接路径读,这样可以让Buffer Cache中的内容保持稳定,提高Buffer Cache的命中率;

但是很多客户都遇到过,开发商没有建立合适的索引,导致SQL查询走上全表查询,同时该SQL执行较为频繁,没有Buffer Cache做缓冲,大量高并发的直接路径读很容易将一台存储压垮,导致业务系统出现严重的性能问题。

可是设置了10949一定有益吗?经常进行大表全表扫描,可能拉低的Buffer Cache的命中率,也会影响其他SQL语句的执行效率;并且全扫描的问题一直被忽视,不容易被发现。

除了对问题SQL进行优化,还有没有其他方法解决?在ORACLE 12.1.0.2 引入了Automatic Big Table Caching (ABTC)为功能,数据库将Buffer Cache中的一部分划分为大表缓存,并且统计哪些大表或者索引的热度,将其存放到ABTC中,避免了频繁的Direct Path Read。

+

+

ABTC测试

RAC 环境中启用 ABTC 前提条件是参数 parallel_degree_policy 设置为  AUTO ADAPTIVE

在单机环境,不依赖 parallel_degree_policy 参数;

配置ABTC参数,同时需要确认force_full_db_caching是关闭的

配置参数db_big_table_cache_percent_target,为ABTC占Buffer Cache的比例,最大值为90

特性存在 2张相关视图:

视图v$bt_scan_cache统计ABTC的使用情况,里面MEMORY_BUF_ALLOC列显示消耗CACHE的大小

视图 v$bt_scan_obj_temp s存放 ABTC中对象信息 ,可以查询到ABTC中缓存表信息, TEMPERATURE 描述 对象的 热度。每执行一次全表扫描,TEMPERATURE列值加1000。

POLICY 显示对象在 ABTC中的状态 MEM_ONLY MEM_PART DISK INVALID

在大内存环境中,配置了ABTC后,当表大小超过STT时,不会执行直接路径读,而是进入ABTC中进行缓存,这样就可以节省很多物理IO

总结:

小型机迁移至X86平台是行业大趋势。迁移过程评估平台优缺点、性能差异、迁移方案、维护成本等因素;不仅需要全面的知识,更需要参考业内成功案例,不妨联系中亦科技,帮您达成目标!

本文转载于中亦安图

相关推荐

热文推荐