您所在的位置: 首页>>数据库>>DB2>>

DB2中内存的使用(6)

http://database.51cto.com  2005-12-01 10:17    IBM中国  我要评论(0)
  • 摘要:本文将向您讲解 DB2 内存使用的基础,以及共享内存和私有内存的概念。这些内容同时适用于 32 位和 64 位的系统。
  • 标签:DB2

图 10 - pmap 命令对于 db2sysc 进程的示例输出(/usr/proc/bin/pmap -x 15444)

从 图 10 中可以观察到下面一些情况:

  • 从 0x00010000 到 0x023F8000 这一部分被预留给 db2sysc 可执行程序(~36MB)。
  • 橙色的那部分(堆),即从 0x023F8000 到 0x10000000,被用于代理私有内存(~220MB)。
  • 实例共享内存,即绿色那部分,始于默认地址 0x10000000。这意味着没有设置 DB2DBMSADDR。
  • 所有 3 个绿色的段被用于共享内存,包括实例共享内存和数据库共享内存。pmap 输出并没有说出哪一个段是实例共享内存,哪一个段是数据库共享内存。我们只知道,数据库共享内存在 0xFE002000 结束,因为从这个地址开始的是一个用于匿名内存的段。因此,实例共享内存和数据库共享内存总共的大小是 0xFE002000 - 0x10000000 = 3,992,985,600 字节 = ~3.7 GB。
  • 从 0xFFBC0000 到 0xFFFFFFFF 是用于堆栈的内存段(~4MB)。

注意:在 32 位 Solaris 中,我们通常将 DB2 数据库共享内存限制在大约 3.5 GB。

如果设置了 DB2DBMSADDR 注册表变量,那么实例共享内存将从该变量指定的地址开始。下面的例子展示了这一点是如何实现的。

例子 设置 DB2DBMSADDR 注册表变量:

  • db2set DB2DBMSADDR = 0x12000000
  • db2stop
  • db2start (需要重新启动实例,以使更改生效)。

获得 db2sys 进程的进程 ID

  • ps -ef | grep sylviaq ('sylviaq' 是实例名)。
  • -ef | grep sylviaq
  • sylviaq 13166 1 0 13:09:12 pts/2 0:00 /export/home/sylviaq/sqllib/bin/db2bp 13049C11221 5
  • sylviaq 13263 13256 0 13:11:02 ? 0:00 db2sysc
  • sylviaq 13265 13256 0 13:11:03 ? 0:00 db2sysc
  • sylviaq 13257 13254 0 13:10:59 pts/3 0:00 -ksh
  • sylviaq 13256 13253 0 13:10:59 ? 0:00 db2sysc
  • sylviaq 13262 13256 0 13:11:00 ? 0:00 db2sysc
  • sylviaq 13360 13049 0 13:11:41 pts/2 0:00 grep sylviaq
  • sylviaq 13264 13256 0 13:11:02 ? 0:00 db2sysc
  • sylviaq 13266 13261 0 13:11:03 ? 0:00 db2sysc

以 root 的身份 cd 到 /usr/proc/pmap,并对任何 db2sysc 进程运行 pmap:
./pmap -x 13263

pmap 输出:

  • 13263: db2sysc
  • Address Kbytes Resident Shared Private Permissions Mapped File
  • 00010000 35808 4064 1608 2456 read/exec db2sysc
  • 02316000 896 168 48 120 read/write/exec db2sysc
  • 023F6000 744 264 8 256 read/write/exec [ heap ]
  • 12000000 243472 243472 - 243472 read/write/exec/shared [shmid=0xbc3]
  • 21000000 22512 22512 - 22512 read/write/exec/shared [shmid=0xbc4]
  • FCC00000 8328 8328 - 8328 read/write/exec/shared [shmid=0xa96]
  • FE002000 8 - - - read/write/exec [ anon ]

注意,实例共享内存现在从 0x12000000 开始,而不是从默认地址 0x10000000 开始。代理私有内存的大小(由 'heap' 标出)从 220MB ( 图 10)增加到了 252 MB。(0x12000000 - 0x023F6000 = 0xFC0A000 = 264282112 (十进制) = ~252MB)

您可能注意到, 图 9中给出的 4GB 地址空间没有包括任何内核内存。这就对了,在 Solaris 中,内核有其自己的地址空间,该地址空间与进程的地址空间是分开的。这样就将更多的空间留给了其他内存集,例如数据库共享内存。

虽然与 AIX 相比,在 Solaris 中我们有更大的地址空间用于数据库共享内存(在 AIX 上是 2GB),但是在 Solaris 上所有共享内存都是固定在物理 RAM 中。如果 RAM 比较小,那么对于可以并发运行的数据库数目就有很大的影响。请参阅 “Sun Solaris 中与分配数据库共享内存有关的常见问题”一节中的例 2。

需要从这种结构中了解到的最重要的事情是:

  • 与 AIX 不同,Solaris 的内存段其大小不是固定的。我们可以通过设置 DB2DBMSADDR DB2 注册表变量,将实例共享内存移到更高的地址,从而增加代理私有内存。
  • 数据库共享内存的限制大约是 3.5GB。
  • 功能内存与 RAM 固定,因而不能交换出去。

32 位 Sun Solaris 中与分配数据库共享内存有关的常见问题
没有充分配置内核参数以及初始化数据库共享内存失败可能导致如下失败:

  • 在数据库启动时(激活数据库或第一次连接到数据库) - SQL1478W, SQL1084C, hang condition
  • 在运行时 - SQL2043N, 挂起条件

在 Solaris 系统中,DB2 提供了一个叫做 db2osconf的工具。该工具根据系统的大小对内核参数的值给出建议。对于一个给定的系统,建议的值要足够高,以便能够容纳最合理的工作负载。

最常见的未能正确设置的内核参数是 shmmax。该参数按字节指定系统中可以分配的共享内存段的最大大小。如果把 DB2 配置成创建大于这个值的数据库共享内存,那么请求就会失败。其他要知道的内核参数是 shmsegshmmni

Solaris 中另一个与分配数据库共享内存有关的常见问题是由于这样的一个事实导致的,即共享内存段的所有页都是固定在物理 RAM 中的。如果在 RAM 中没有足够的空闲页可用,或者没有足够的可以被 OS 为满足数据库段而调出的其他页,那么启动数据库的请求就会遭到失败。

下面的例子展示了会导致问题的不恰当配置。

例 1 考虑如下配置: (所有页的大小都为 4K)

服务器:

  • 服务器上的物理 RAM 16GB
  • shmsys:shminfo_shmmax = 2097152 (2GB)

数据库:

  • IBMDEFAULTBP 400,000 页
  • UTILHEAP 17,500 页
  • DBHEAP 30,000 页
  • LOCKLIST 1000 页
  • PCKCACHE 5000 页
  • CATALOGCACHE 2500 页

限制: DB2 发出的任何创建大于 shmmax 值(这里是 2GB)的数据库共享内存集的请求都将失败,并返回一个 out of memory type 错误。

计算:
数据库共享内存 = (456,000 页 x 4KB/页) x 1.1 = ~2.0GB

问题: 可能仍然可以激活数据库或者连接到数据库。但是,尝试运行一个应用程序时可能返回如下错误消息:
SQL1224N A database agent could not be started to service request, or was terminated as a result of a database system shutdown or a force command. SQLSTATE=55032

这是 DB2 经常返回的一个错误。不过,如果不是在 AIX 服务器上,而是在 UNIX 服务器上,那么这就很可能与内存资源问题有关。特别地,可能是内核参数没有进行适当的调优。

为解决这个问题,可以适当地配置内核参数。设置:
shmsys:shminfo_shmmax = 15099494 (~90% of 16GB)

例 2 考虑如下配置: (所有页的大小都为 4K)

服务器上的物理 RAM 是 1 GB。

数据库 A:

  • IBMDEFAULTBP 137,500 页
  • INTRA_PARALLEL ON
  • UTILHEAP 10,000 页
  • DBHEAP 10,000 页
  • SHEAPTHRES_SHR 20,000 页
  • LOCKLIST 1000 页
  • PCKCACHE 5000 页
  • CATALOGCACHE 2500 页
  • APPGROUP_MEM_SZ 20,000 页

数据库 B:

  • IBMDEFAULTBP 92,500 页
  • INTRA_PARALLEL ON
  • UTILHEAP 5,000 页
  • DBHEAP 10,000 页
  • SHEAPTHRES_SHR 15,000 页
  • LOCKLIST 1000 页
  • PCKCACHE 5000 页
  • CATALOGCACHE 2500 页
  • APPGROUP_MEM_SZ 20,000 页

限制: 因为共享内存是固定到物理 RAM 的,所以这种内存不会被换出。因此,我们只能分配最多 1GB (可用的物理 RAM)的共享内存给数据库使用。

计算:

  • 数据库 A 共享内存 = (186,000 页 x 4KB/页) x 1.1% = ~818MB
  • 数据库 A 应用程序组内存 = 20,000 页 x 4KB/页 = 80MB
  • 数据库 B 共享内存 = (131,000 页 x 4KB/页) x 1.1% = ~576MB
  • 数据库 B 应用程序组内存 = 20,000 页 x 4KB/页 = 80MB
  • 为了启动数据库 A,要求: 818MB + 80MB = ~898MB
  • 为了启动数据库 B,要求: 576MB + 80MB = ~656MB

问题: 假设数据库 A 是激活的。至少有 898MB 的共享内存固定在物理 RAM 中。当尝试激活数据库 B 时,就会碰到如下错误消息:
SQL1084C Shared memory segments cannot be allocated. SQLSTATE=57019

如果同时启动数据库 A 和数据库 B,我们将请求至少 1.55GB (898MB + 656MB) 的可用物理 RAM,以便同样地将共享内存固定在 RAM 中。显然,1GB 的 RAM 不够。为解决这一问题:

  • 尝试减少这两个数据库的缓冲池大小。或者
  • 尝试减少应用程序组内存。或者
  • 更可能的是,增加更多的物理 RAM。在这种情况下,您将需要至少 1.55GB 的物理 RAM,才能同时启动这两个数据库。

在这种情况下,按照上面的数据库配置参数,在任何时刻启动某一个数据库(数据库 A 或数据库 B)是可行的,但是不能同时启动两个数据库。这是必须增加更多的物理 RAM。

这个问题在 AIX 中不会出现,因为在 AIX 中共享内存没有固定在物理 RAM 中。在这种场景中,可以启动数据库 B。但是,这意味着数据库 A 的数据库内存必须调出。当一个应用程序访问数据库 A 时,又得将数据库 B 的数据库内存调出。您可以想象未来要发生的调页次数有多少。


共12页: 上一页 [1] [2] [3] [4] [5] 6 [7] [8] [9] [10] [11] [12] 下一页
【内容导航】
DB2 9数据库技术入门
DB2数据库应用手册
深入SQL Server 2008
Sun以10亿美元并购开源数据库厂商MySQL
甲骨文Oracle 11g正式发布
 
 验证码: (点击刷新验证码)   匿名发表
  • Visual C++ 6.0完全自学宝典

  • 作者:强锋科技,朱洪波
  • Visual C++ 6.0是微软公司为程序人员提供的Visual Studio 6.0工具套件中的重要组成部分。本书由浅入深地介绍使用Visual C++ 6.0..
Copyright©2005-2008 51CTO.COM 版权所有