技术开发 频道

调优DB2 v8.1及其数据库的非常好的实践

创建缓冲池

恰当地定义缓冲池是拥有一个运行良好的系统的关键之一。对于 32 位操作系统,知道共享存储器的界限十分重要,因为这种界限将限制数据库的缓冲池(即数据库的全局存储器),使其不能超出以下界限(64 位系统没有这样的界限):

  • AIX - 1.75 GB
  • Linux - 1.75 GB
  • Sun - 3.35 GB
  • HP-UX - approximately 800 MB
  • Windows - 2-3 GB (在 NT/2000 上的 boot.ini 中使用的是 ' 3GB' switch)

用下面的公式计算近似的数据库全局存储器的使用:

清单 2. 计算全局存储器的使用(共享存储器)

buffer pools + dbheap + util_heap_sz + pkgcachesz + aslheapsz + locklist + approx 10% overhead 

 

如果启用了 INTRA_PARALLEL,那么将 sheapthres_shr 的值加到总和中。

确定有多少缓冲池

对于数据库中一个表空间所使用的每一种页面大小,都需要至少一个缓冲池。通常,缺省的 IBMDEFAULTBP 缓冲池是留给系统编目的。为处理表空间的不同页面大小和行为,须创建新的缓冲池。

对于初学者,一开始为每种页面大小使用一个缓冲池,对于 OLAP/DSS 类型的工作负载更是如此。DB2 在其缓冲池的自我调优方面十分擅长,并且会将经常被访问的行放入内存,因此一个缓冲池就足够了。(这一选择也避免了管理多个缓冲池的复杂性。)

如果时间允许,并且需要进行改进,那么您可能希望使用多个缓冲池。其思想是将访问最频繁的行放入一个缓冲池中。在那些随机访问或者很少访问的表之间共享一个缓冲池可能会给缓冲池带来“污染”,因为有时候要为一个本来可能不会再去访问的行消耗空间,甚至可能将经常访问的行挤出到磁盘上。如果将索引保留在它们自己的缓冲池中,那么在索引使用频繁的时候(例如,索引扫描)还可以显著地提高性能。

这与我们对表空间的讨论是紧密联系的,因为要根据表空间中表的行为来分配缓冲池。如果采用多缓冲池的方法,对于初学者来说使用 4 个缓冲池比较合适:

  • 一个中等大小的缓冲池,用于临时表空间。
  • 一个大型的缓冲池,用于索引表空间。
  • 一个大型的缓冲池,用于那些包含经常要访问的表的表空间。
  • 一个小型的缓冲池,用于那些包含访问不多的表、随机访问的表或顺序访问的表的表空间。

对于 DMS 只包含 LOB 数据的表空间,可以为其分配任何缓冲池,因为 LOB 不占用缓冲池空间。

确定为缓冲池分配的内存

千万不要为缓冲池分配多于所能提供的内存,否则就会招致代价不菲的 OS 内存分页(memory paging)。通常来讲,如果没有进行监控,要想知道一开始为每个缓冲池分配多少内存是十分困难的。

对于 OLTP 类型的工作负载,一开始将 75% 的可用内存分配给缓冲池比较合适。

对于 OLAP/DSS,经验法则告诉我们,应该将 50% 的可用内存分配给一个缓冲池(假设只有一种页面大小),而将剩下的 50% 分配给 SORTHEAP。

使用基于块(block-based)的缓冲池

倚重于预取技术的 OLAP 查询可以得益于基于块的缓冲池。缺省情况下,所有缓冲池都是基于页的,这意味着预取操作将把磁盘上相邻的页放入到不相邻的内存中。而如果采用基于块的缓冲池,则 DB2 将使用块 I/O 一次将多个页读入缓冲池中,这样可以显著提高顺序预取的性能。

一个基于块的缓冲池由标准页区和一个块区同时组成。CREATE 和 altER BUFFERPOOL SQL 语句的 NUMBLOCKPAGES 参数用于定义块内存的大小,而 BLOCKSIZE 参数则指定每个块的大小,即在一次块 I/O 中从一个磁盘读取的页的数量。

共享相同区段大小的表空间应该成为一个特定的基于块的缓冲池的专门用户。将 BLOCKSIZE 设置为等于正在使用该缓冲池的表空间的 EXTENT SIZE。

确定分配多少内存给缓冲区内的块区要更为复杂一些。如果要碰到大量的顺序预取操作,那么您很可能会想要更多基于块的缓冲池。NUMBLOCKPAGES 应该是 BLOCKSIZE 的倍数,并且不能大于缓冲池页面数量的 98%。先将它设小一点(不大于缓冲池总共大小的 15% 或刚好 15%)。在后面还可以根据快照监视(snapshot monitoring)对其进行调整。

DB2 v8 Documentation:

  • Concepts ==> Administration ==> Database objects ==> Buffer Pool Management
  • Reference ==> SQL ==> SQL Statements ==> CREATE BUFFERPOOL
  • Reference ==> SQL ==> SQL Statements ==> altER BUFFERPOOL
  • Concepts ==> Administration ==> Performance tuning ==> Operational performance ==> Memory-use organization

创建表空间

既然要为表空间分配缓冲池, 关于缓冲池的上一节就跟涉及表空间的性能问题十分相关。使用 DB2 Control Center 是创建和配置表空间的最容易的方法,也是我们推荐的方法(右键单击数据库的 Table Spaces文件夹并选择 Create...)。

确定要创建的表空间的类型(DMS 或 SMS)

对于系统临时表空间和系统编目表空间,应该使用 System Managed Storage(SMS),因为它允许表空间动态地增长和收缩。如果有大量临时表要刷新到磁盘上(或者是没有足够的排序空间,或者是显式地创建临时表),则 DMS 会更有效一些。当使用 SMS 时,应该运行实用程序 'db2empfa',这个实用程序将支持多页文件分配,从而一次一个区段地增长表空间,而不是一次一页地增长表空间。

对于所有其他的表空间,应该使用 Database Managed Storage(DMS)。DMS 允许一个表跨越多个表空间(索引、用户数据和 LOB),这样就减少了在预取和更新操作时索引、用户和 LOB 数据之间的争用,从而缩短了数据访问的时间。通过使用 DMS raw 甚至还可以挤出额外的 5-10% 的性能提升。

确定页面大小

为了创建一个表,必须有一个表空间,其页面大小应足以容纳一行。您可以选择使用 4、8、16 或 32 KB 这几种页面大小。有时候必须使用较大的页面大小,以回避某些数据库管理器的限制。例如,表空间的最大尺寸与表空间的页面大小成比例。如果使用 4K 的页面大小,那么表空间的大小(每个分区)最大是 64 GB,如果使用 32K 的页面大小,那么最大是 512 GB。

对于执行随机更新操作的 OLTP 应用程序,采用较小的页面大小更为可取,因为这样消耗的缓冲池中的空间更少。

对于要一次访问大量连续行的 OLAP 应用程序,通常使用较大页面大小效果会更好些,因为这样可以减少在读取特定数量的行时发出的 I/O 请求的数量。较大的页面大小还允许您减少索引中的层数,因为在一页中可以保留更多的行指针。然而,也有例外情况。如果行长度小于页面大小的 255 分之 1,则每一页中都将存在浪费的空间,因为每页最多只能有 255 行(对于索引数据页不适用)。在这种情况下,采用较小的页面大小或许更合适一些。

例如,如果要使用 32K 的页面大小来存储平均大小为 100 字节的行,则一个 32 KB 的页只能存储 100 * 255 = 25500 byte (24.9 KB)。这意味着每 32 KB 中就有大约 7 KB 要浪费掉。

确定表空间的数量

与缓冲池一样,一开始应该为每种页面大小使用一个缓冲池。对于所使用的每种页面大小,必须存在一个具有匹配页面大小的系统临时表空间(以支持排序和重组)。然后将所有享用匹配页面大小的表空间指派给具有相同页面大小的缓冲池。

如果您还关心性能问题,并且有时间投入,那么可以使用 DMS 表空间,并且根据使用情况来组织表。另外,还要遵循前面给出的关于使用多个缓冲池的建议。

对于每种页面大小,创建一个:

  • 系统临时表空间。
  • 用于索引的常规表空间。
  • 用于频繁访问的表的常规表空间。
  • 用于访问不多的表、随机访问的表以及顺序访问的表的常规表空间。
  • 用于 LOB 数据的大型表空间。

容器布局

一开始最好是对于每个 CPU 分配 6-10 个磁盘给表空间。每个表空间应该跨越多个磁盘,也就是说,在每个可用磁盘上有一个(且不多于一个)容器。

有多少个表空间,就应该在每个磁盘上创建相同数量的逻辑卷(UNIX)。这样一来,每个表空间在每个磁盘上都有自己的逻辑卷(logical volume),用以放置容器。如果不是使用 raw device,那么就需要在每个逻辑卷内创建一个文件系统。

磁盘阵列和存储子系统

对于大型磁盘系统,应该使用单个容器。此外,还需要为表空间设置 DB2 Profile Registry 变量 DB2_PARALLEL_IO。这一点放在 概要注册表一节中讨论。

区段大小

Extent Size 指定在跳到下一个容器之前,可以写入到一个容器中的 PAGESIZE 页面的数量,这个参数是在创建表空间时定义的(之后不能轻易修改)。处理较小的表时,使用较小的区段效率会更高一些。

下面的经验法则是建立在表空间中每个表的平均大小的基础上的:

  • 如果小于 25 MB,Extent Size 为 8
  • 如果介于 25 到 250 MB 之间,则 Extent Size 为 16
  • 如果介于 250 MB 到 2 GB 之间,则 Extent Size 为 32
  • 如果大于 2 GB,则 Extent Size 为 64

对于 OLAP 数据库和大部分都要扫描(仅限于查询)的表,或者增长速度很快的表,应使用较大的值。

如果表空间驻留在一个磁盘阵列上,则应将区段大小设置成条纹大小(也就是说,写入到阵列中一个磁盘上的数据)。

预取大小

通过使用 altER TABLESPACE 可以轻易地修改预取大小。最优设置差不多是这样的:

 Prefetch Size = (# Containers of the table space on different physical disks) * Extent Size 

 

如果表空间驻留在一个磁盘阵列上,则设置如下:

  PREFETCH SIZE = EXTENT SIZE * (# of non-parity disks in array)。 

 

DB2 v8 Documentation:

  • Concepts ==> Administration ==> Database design ==> Physical ==> Table Space Design
  • Reference ==> SQL ==> SQL Statements ==> CREATE TABLESPACE
  • Reference ==> SQL ==> SQL Statements ==> altER TABLESPACE
0
相关文章