分类: DB2/Informix
2008-05-31 16:58:01
并行数据库查询和 Memory Grant Manager
并行数据库查询(Parallel database query,PDQ)是 IDS 从 7.3 版开始引入的功能。Informix 数据库服务器的这个特性可以大大提高性能。PDQ 使数据库服务器可以分散查询的工作。例如,如果需要在一个大型表上创建索引,那么可以将这项工作分散到多个线程和进程。
PDQ 包括资源管理功能。
当数据库服务器使用 PDQ 并行执行一个查询时,可以在操作系统上执行较重的负载。可以调优以下资源:
在配置数据库服务器时,必须考虑 PDQ 的使用对其他用户的影响。例如,如果运行的查询要占用所有 CPU 资源,那么数据库服务器就不能对其他通常运行得非常快的查询作出响应。因此必须小心,使关键的非 PDQ 查询仍然能够以可以接受的性能运行。
可以用以下方法控制数据库服务器对资源的使用:
PDQPRIORITY
环境变量确定资源的并行度,它和 MAX_PDQPRIOIRTY
一起用作关于数据库服务器如何分配资源的比例因子。
setenv--PDQPRIORITY--+-HIGH-------------------------------+- +-LOW--------------------------------+ +-OFF--------------------------------+ '-resources--+---------------------+-' | (1) | '----------high_value-' |
设置 | 描述 |
---|---|
High | 当数据库服务器在所有用户之间分配资源时,它将尽可能多的资源提供给查询 |
Low 或 1 | 并行地从分段表中取数据值 |
OFF | PDQ 处理被关闭 |
resources | 0 到 100 之间的整数;设置实际分配给查询的用户请求的 PDQ 资源的百分比 |
可选的较高值 | 请求最大百分比的内存的可选整数值。当在 resources 值之后指定这个值时,将请求用百分比表达的一定范围的内存 |
数据库服务器专用于一个查询的资源越多,通常就能越快地完成查询。但是,如果其他查询也尝试获取那些相同的资源,就会发生对那些资源的竞争。这会导致性能下降。
可以使用 SQL 语句 SET PDQPRIORITY
手动调整特定会话的优先级。
限制数据库服务器可分配给任意 DSS 查询的 PDQ 资源的 onconfig 参数是 MAX_PDQPRIORITY
。 MAX_PDQPRIORITY
用作任何特定客户机请求的资源占 PDQPRIORITY
的百分比。例如,假设一个用户急于获得数据,因而将 PDQPRIORITY
设为 100。但是 DBA 认识到每天晚上的同一个时候需要运行一些批处理任务,因此将 MAX_PDQPRIORITY
设为 50。100 的 50% 是 50,因此用户实际上可以获得的最大 PDQPRIORITY
资源数为 50。
当数据库服务器联机时,可以使用 onmode -D
修改 MAX_PDQPRIORITY
的值。
在同时具有 OLTP 和 DSS 查询的系统上,必须采取均衡动作。如果 MAX_PDQPRIORITY
设置得太高,则不利于 OLTP 查询。如果 MAX_PDQPRIORITY
设置得太低,则 DSS 查询不能获得令人满意的性能。所以,DBA 必须小心地调优这个变量。
可以将 MAX_PDQPRIORITY
设置为表 7 中描述的以下值:
设置 | 描述 |
---|---|
0 | 关闭 PDQ。DSS 查询不使用并行 |
1 | 并行地从分段表中取数据(并行扫描),但是不使用其他形式的并行 |
100 | 使用所有可用的资源并行地处理查询 |
任意数值 | 0 到 100 之间的一个整数;设置实际分配给查询的用户请求的 PDQ 资源的百分比 |
DS_TOTAL_MEMORY onconfig
参数指定可用于 PDQ 查询的内存大小。这个值单位为 KB。
DS_TOTAL_MEMORY
应该被设置得足够大,以便可以一次性地将较大的工作装入内存。但是,在配置 DS_TOTAL_MEMORY
时需要考虑以下方面:
SHMTOTAL
指定用于数据库服务器的所有内存(常驻内存、虚拟内存和消息内存这几部分的总和)。SHMVIRTSIZE
指定共享内存中虚拟内存的初始大小。
所有分配给 DS_TOTAL_MEMORY
的内存都在共享内存的虚拟内存中。某些操作系统对于每个添加到共享内存的附加段有一定的性能开销。所以应适当地调优 SHMVIRTSIZE
和 SHMTOTAL
,以分配较少数量的段。
对于 OLTP 应用程序,基本建议是将 DS_TOTAL_MEMORY
设置为 SHMTOTAL
值的 20% 到 50%,单位为 KB。
如果 DSS 查询独占地使用数据库服务器,则将 DS_TOTAL_MEMORY
设置为 SHMTOTAL
的 90% 到 100%。
对于同时使用两种类型的查询的系统,基本建议是将 DS_TOTAL_MEMORY
设置为 SHMTOTAL
的 50% 到 80%。
可以用 onmode -M
命令动态地设置 DS_TOTAL_MEMORY
。
注意: DS_TOTAL_MEMORY
允许使用的值与平台有关。对于 32 位平台,这个值必须是 128 * DS_MAX_QUERIES 到 1,048,576 之间的一个无符号整数。而在 64 位系统上,限制范围通常更大一些,并且因操作系统而异。例如,在 HP 9000 平台上,最大值是 4,294,967,296。
DS_MAX_SCANS ONCONFIG
参数限制可以并发运行的 PDQ 扫描线程的数量。如果这个参数设置得太高,那么数据库服务器就有太多来自多个并发运行的决策支持查询的扫描线程。这将导致资源竞争和就绪队列增长,因为扫描线程会等待时机开始工作。
可以使用下面的公式计算分配给一个查询的扫描线程的数量:
scan_threads = min (nfrags, (DS_MAX_SCANS * pdqpriority / 100 * MAX_PDQPRIORITY / 100) ) |
项 | 描述 |
---|---|
nfrags | 具有最大数量的片段的表中的片段的数量 |
PDQPRIORITY | 用于那个特定查询的 PDQPRIORITY 设置 |
可以使用 onmode -S
选项动态地设置最大数量的扫描线程。
这个值必须是 10 到 1,048,576 之间的一个无符号整数。
例如,假设一个大型表包含 50 个片段。如果没有设置 DS_MAX_SCANS
,那么数据库服务器将分配 50 个扫描线程。所以,引擎将尝试运行 50 个扫描线程读这个表。
现在,假设这是任何用户都可以运行的一个报告。如果 50 个人尝试运行那个报告会怎样呢?引擎将为那个报告的每次运行分配 50 个线程。所以,一共要派生 2500 个线程。如果增加其他报告和其他 DSS 查询的开销,可以看到存在很多竞争。DS_MAX_SCANS
就是用于解决这个问题。
和所有性能方面的考虑一样,这是一种均衡动作。为了减少大型查询的扫描线程在就绪队列中的等待时间,可以减少分配的扫描线程数量。但是,如果一个查询的扫描线程数量少于片段数量,查询需要花更长的时间执行。
DS_MAX_QUERIES
是指定可以并发运行的 PDQ 查询的最大数量的 ONCONFIG
参数。Memory Grant Manager (MGM) 根据清单 11 中的公式为一个查询预留内存。下面的公式也表明数据库服务器如何决定将多少内存分配给一个查询:
memory_reserved = DS_TOTAL_MEMORY * (PDQ-priority / 100) * (MAX_PDQPRIORITY / 100) |
可以使用 onmode -Q
动态地设置 DS_MAX_QUERIES
。
onstat -g mgm
选项打印 Memory Grant Manager (MGM) 资源信息。可以使用 onstat -g mgm
选项监视 MGM 如何协调内存使用和扫描线程。
让我们看看一个示例输出:
IIBM Informix Dynamic Server Version 11.10.FB5TL -- On-Line -- Up 10 days 01:35:2 7 -- 61440 Kbytes Memory Grant Manager (MGM) -------------------------- MAX_PDQPRIORITY 50 DS_MAX_QUERIES: 2 DS_MAX_SCANS: 1048576 DS_NONPDQ_QUERY_MEM: 128 KB DS_TOTAL_MEMORY: 256 KB Queries: Active Ready Maximum 0 0 2 Memory: Total Free Quantum (KB) 256 256 128 Scans: Total Free Quantum 1048576 1048576 1 Load Control: (Memory) (Scans) (Priority) (Max Queries) (Reinit) Gate 1 Gate 2 Gate 3 Gate 4 Gate 5 (Queue Length) 0 0 0 0 0 Active Queries: None Ready Queries: None Free Resource Average # Minimum # -------------- --------------- --------- Memory 0.0 +- 0.0 32 Scans 0.0 +- 0.0 1048576 Queries Average # Maximum # Total # -------------- --------------- --------- ------- Active 0.0 +- 0.0 0 0 Ready 0.0 +- 0.0 0 0 Resource/Lock Cycle Prevention count: 0 |
Memory Grant Manager 利用一系列的门以确保 PDQ 查询有足够的资源以适当地运行。
门号 | 描述 |
---|---|
1 | 是否有足够的可用内存? |
2 | 是否超过了 DS_MAX_SCANS? |
3 | 这个门是所有具有相同优先级的查询的一个队列 |
4 | 是否超过了 DS_MAX_QUERIES? |
5 | 确保在允许队列运行之前不动态更改资源 |
在 onstat -g mgm
输出显示的一种资源中,一个单位的内存称作一个份额(quantum)。内存份额表示一个单位的内存:
份额是在分配内存时确定的。它不是一个静态的大小。
memory quantum = DS_TOTAL_MEMORY / DS_MAX_QUERIES |
例如,回到 清单 13 中的示例输出,让我们插入一些数字:
memory quantum = (256 * 1024) / 2 |
示例运行生成一个 131072 字节的份额。
可以看到,允许并发运行的查询越多,每个份额就越小。