2.5 缓冲池管理
DB2性能管理与实战
在介绍数据库共享内存的时候,讲到了数据库缓冲池,这里介绍一下缓冲池的工作原理。
缓冲池指的是从磁盘读取表和索引数据时,数据库管理器分配的用于高速缓存这些表或索引数据的主存储器区域。每个DB2数据库都必须具有一个缓冲池。
每个新数据库都定义了一个称为IBMDEFAULTBP的缺省缓冲池。可以使用CREATE BUFFERPOOL、DROP BUFFERPOOL和ALTER BUFFERPOOL语句来创建、删除和修改缓冲池。SYSCAT.BUFFERPOOLS目录视图访问数据库中所定义的缓冲池的信息。
在DB2 pureScale环境中,每个成员都有自己的本地缓冲池(LBP)。还有一个附加组缓冲池(GBP),此缓冲池由集群高速缓存设施维护。GBP由所有成员共享,它被用作DB2 pureScale实例中的个别成员使用的页的高速缓存,它包含所有成员的修改页的缓存,以改进性能并确保一致性。
2.5.1 缓冲池使用方法
首次访问表中的数据行时,数据库管理器会将包含该数据的页放入缓冲池中。这些页将一直保留在缓冲池中,直到关闭数据库或者其他页需要使用某一页所占用的空间为止。
缓冲池中的页可能正在使用,也可能没有使用,它们可能是脏页,也可能是干净页。
boll 正在使用的页就是当前正在读取或更新的页。为了保持数据一致性,数据库管理器只允许一次只有一个代理程序更新缓冲池中的给定页。如果正在更新某页,那么它正在内一个代理程序互斥地访问。如果正在读取该页,那么多个代理程序可以同时读取该页。
boll “脏”页包含已更改但尚未写入磁盘的数据。
boll 将一个已更改的页写入磁盘之后,它就是一个“干净”页,并且可能仍然保留在缓冲池中。
大多数情况下,调整数据库涉及设置用于控制将数据移入缓冲池以及等待将数据从缓冲区写入磁盘的配置参数。如果最近的代理程序不需要页空间,那么可以将页空间用于新应用程序中的新页请求。额外的磁盘I/O会使数据库管理器性能下降。
2.5.2 页清除程序代理程序
在经过认真调整的系统中,通常由页清除程序代理程序将已更改的页(即脏页)写入磁盘。页清除程序代理程序作为后台进程执行I/O,它们使应用程序能够更快地运行,这是因为,其代理程序可以执行实际的事务工作。页清除程序代理程序有时被称为异步页清除程序或异步缓冲区写程序,这是因为它们不与其他代理程序的工作协调进行,而只是在有需要时才工作。
为了提高需要执行大量更新操作的工作负载的性能,可以启用主动页清除功能,以使页清除程序在任何给定时刻选择要写哪些脏页时更为主动。当快照揭示有许多同步数据页或索引页写操作与异步数据页或索引页写操作相关时尤其如此。
图2-6所示为页清除程序代理程序与数据库代理程序之间如何共享缓冲池管理工作。
2.5.3 数据预取
在数据访问中,在应用程序需要一页或多页之前,提前从磁盘中检索那些页到缓冲池,将索引和数据页预取至缓冲池可以缩短I/O等待时间,因此有助于提高性能。此外,并行I/O也有助于提高预取效率。
1.预取分类
有如三个类别的预取。
boll 顺序预取——在应用程序需要这些页之前,将连续的页读入缓冲池。
boll 提前读预取——提前查看索引以确定ISCAN-FETCH和索引扫描操作访问的确切页并预取这些页。
boll 列表预取(有时称为列表顺序预取)——高效地预取一组不连续的数据页。
智能数据提前读预取是一种方法,其中使用顺序检测还是提前读预取将取决于数据集群的程度。顺序存储数据页时,会使用顺序检测预取;数据页高度集群时,使用提前读预取。智能数据预取使数据库系统能够利用顺序页中存储的数据的潜在性能优点,它也允许高效预取高度集群的数据。因为高度集群的数据不再有害于查询性能,所以这会降低对高成本操作(例如,表重组)的需求。
智能索引提前读预取是另一种方法,其中使用顺序检测还是提前读预取将取决于索引的密度。顺序存储索引时,会使用顺序检测预取;索引的密度很低时,使用提前读预取。智能索引预取使数据库系统能够利用顺序存储的索引的潜在性能优点,它也允许高效预取低密度索引。智能索引预取降低了对高成本操作(例如,索引重组)的需求。
智能数据预取和智能索引预取仅适用于索引扫描操作,并且不支持XML索引、扩展索引和文本搜索文本索引。扫描全局范围集群表索引期间,不能使用智能数据预取,因为它们是逻辑索引而不是物理索引。而且,对于智能数据预取,如果ISCAN-FETCH扫描全局范围分区索引,那么不会使用数据提前读预取。如果针对智能数据预取执行索引扫描期间对索引谓词求值,并且优化器确定符合该索引扫描资格的行不多,那么会禁用提前读预取。也不能对范围集群表索引使用智能索引预取。
注:优化器确定应允许执行ISCAN-FETCH或索引扫描操作的数据或索引预取类型。以下是用于智能数据预取和智能索引预取的预取技巧类型:
boll 顺序检测预取;
boll 提前读预取;
boll 顺序检测预取和提前读预取。
对于此技巧,将启用顺序检测预取和提前读预取,这是缺省值。在此技巧中,一开始会使用顺序检测预取直到达到非预取页数的阈值或(在某些情况下)超过优化器执行的MAXPAGES估算。达到非预取页的阈值或超过估算的MAXPAGES时,将启用提前读预取。
但是在某些情况下,优化器可能未选择任何预取技巧(如果针对标准关键字执行索引扫描),索引是唯一的,并且优化器针对索引扫描的估算页数(MAXPAGES)小于或等于1。在这种情况下,MAXPAGES估算可能是可靠的,并且不需要预取。
预取数据页与数据库管理器代理程序读方法不同,后一种方法用于检索一页或少量连续页但只将一页数据传送给应用程序时的情况。
2.预取与分区内并行性
分区内并行性使用多个子代理程序来扫描索引或表,预取会对分区内并行性的性能产生重要的影响。此类并行扫描将产生较高的数据使用率,从而要求较高的预取率。
并行扫描与串行扫描相比,预取不足的成本更高。如果串行扫描期间未进行预取,那么由于代理程序需要等待I/O,所以查询的运行速度更慢。如果并行扫描期间未进行预取,那么当一个子代理程序等待I/O时,所有子代理程序都可能需要进行等待。
在此上下文中,分区内并行性下的预取极为重要,因此更为主动地执行;顺序检测机制允许相邻页之间有更大的间隔,以便可以将这些页视为顺序页。这些间隔的宽度随着扫描中涉及的子代理程序数目的增加而增大。
2.5.4 缓冲池命中率
缓冲池命中率反映在内存中查找查询所需数据(相对于必须从外部存储器读取)的程度。度量在内存中找到成员所需页(相对于在磁盘上找到所需页)的程度的一种方法是计算缓冲池命中率。缓冲池命中率指示数据库管理器在缓冲池中找到所请求页的次数(又称为命中速率)与必须从磁盘读取此页的次数之比。
DB2 V9.7以后提供了表功能MON_GET_BUFFERPOOL,可以获取缓冲池监控信息,下面列举了其中一些主要参数。
boll pool_data_p_reads:“缓冲池数据物理读取数”监视器元素,指示从常规表空间和大型表空间的物理表空间容器中读取的数据页数。
boll pool_temp_data_p_reads:“缓冲池临时数据物理读取数”监视器元素,指示从临时表空间的物理表空间容器中读取的数据页数。
boll pool_index_p_reads:“缓冲池索引物理读取数”监视器元素,指示从常规表空间和大型表空间的物理表空间容器中读取的索引页。
boll pool_temp_index_p_reads:“缓冲池临时索引物理读取数”监视器元素,指示从临时表空间的物理表空间容器中读取的索引页数。
boll pool_xda_p_reads:“缓冲池XDA数据物理读取数”监视器元素,指示从常规表空间和大型表空间的物理表空间容器中读取的XML存储器对象(XDA)数据页数。
boll pool_temp_xda_p_reads:“缓冲池临时XDA数据物理读取数”监视器元素,指示从临时表空间的物理表空间容器中读取的XML存储器对象(XDA)数据页数。
boll pool_data_writes:“缓冲池数据写次数”监视器元素,以物理方式将缓冲池数据页写入磁盘的次数。
boll pool_index_writes:“缓冲池索引写次数”监视器元素,指示缓冲池索引页物理写至磁盘的次数。
boll pool_xda_writes:“缓冲池XDA数据写次数”监视器元素,指示以物理方式将XML存储对象(XDA)的缓冲池数据页写入磁盘的次数。
boll unread_prefetch_pages:“未读取的预取页数”监视器元素,指示预取读入但从未使用的页数。
boll pool_async_data_reads:“缓冲池异步数据读次数”监视器元素,指示异步引擎可派遣单元(EDU)从所有类型的表空间的物理表空间容器中读取的数据页数。
boll pool_async_index_reads:“缓冲池异步索引读取数”监视器元素,指示异步引擎可派遣单元(EDU)从所有类型的表空间的物理表空间容器中读取的索引页数。
boll pool_async_xda_reads:“缓冲池异步XDA数据读取数”监视器元素,指示异步引擎可派遣单元(EDU)从所有类型的表空间的物理表空间容器中读取的XML存储器对象(XDA)数据页数。
boll pool_data_l_reads:“缓冲池数据逻辑读取数”监视器元素,从常规表空间和大型表空间的逻辑缓冲池中请求获取的数据页的数目。
boll pool_index_l_reads:“缓冲池索引逻辑读取数”监视器元素,指示从常规表空间和大型表空间的逻辑缓冲池中请求获取的索引页数。
boll pool_xda_l_reads:“缓冲池XDA数据逻辑读取数”监视器元素,指示向常规表空间和大型表空间的逻辑缓冲池请求的XML存储器对象(XDA)数据页数。
如果要计算一个缓冲区的命中率,可以通过下面公式:1-((pooldata_p_reads + pool_xda_p_reads + pool_index_p_reads + pool_temp_data_p_reads + pool_temp_xda_p_reads + pool_temp_index_p_reads)/(pool_data_l_reads + pool_xda_l_reads + pool_index_l_reads + pool_temp_data_l_reads + pool_temp_xda_l_reads + pool_temp_index_l_reads ))×_100%
用户可以通过下面查询语句取出对应缓冲区的命中率:
WITH BPMETRICS AS(
SELECT bp_name,
pool_data_l_reads + pool_temp_data_l_reads +
pool_index_l_reads + pool_temp_index_l_reads +
pool_xda_l_reads + pool_temp_xda_l_reads as logical_reads,
pool_data_p_reads + pool_temp_data_p_reads +
pool_index_p_reads + pool_temp_index_p_reads +
pool_xda_p_reads + pool_temp_xda_p_reads as physical_reads,
member
FROM TABLE(MON_GET_BUFFERPOOL('',-2))AS METRICS)
SELECT
VARCHAR(bp_name,20)AS bp_name,
logical_reads,
physical_reads,
CASE WHEN logical_reads > 0
THEN DEC((1-(FLOAT(physical_reads)/ FLOAT(logical_reads)))* 100,5,2)
ELSE NULL
END AS HIT_RATIO,
member
FROM BPMETRICS;
结果如下:
BP_NAME LOGICAL_READS PHYSICAL_READS HIT_RATIO MEMBER
----------------------------------------------------------------
IBMDEFAULTBP 619 385 37.80 0
IBMSYSTEMBP4K 0 0 - 0
IBMSYSTEMBP8K 0 0 - 0
IBMSYSTEMBP16K 0 0 - 0
IBMSYSTEMBP32K 0 0 - 0
从这个例子可以看出,缓冲池IBMDEFAULTBP的命中率只有37.8%,非常低。这是由于物理读在逻辑读中占的比重比较大。这往往也是由于缓冲池的大小不够大引起的。一般增大缓冲池的大小可以提高缓冲池的命中率,也就提高了缓冲池的I/O性能。
同时应该注意的另外一个指标pool_async_data_reads(“缓冲池异步数据读次数”),它也是pool_data_p_reads(“缓冲池数据物理读取数”)的一个组成部分。如果pool_data_p_reads中pool_async_data_reads的比例占的很高,就是说从磁盘上读取的数据大多都是由预取得来的,说明预取效率很高,缓冲池的I/O性能很好。在这种情况下,即使在缓冲池命中率很低,I/O也不会是瓶颈。
在非pureScale环境下,可以用如下公式以百分比形式表示命中率。
此外,DB2 V9.7以后可以通过SYSIBMADM.MON_BP_UTILIZATION视图来查看缓冲区的使用情况,这里只列举其中一些参数。
当然也可以通过InfoShpere Optim Performance Manager的仪表板查看缓冲区使用情况。
本文仅用于学习和交流目的,不代表异步社区观点。非商业转载请注明作译者、出处,并保留本文的原始链接。