- 论坛徽章:
- 0
|
图 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 配置成创建大于这个值的数据库共享内存,那么请求就会失败。其他要知道的内核参数是 shmseg和 shmmni。
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 的数据库内存调出。您可以想象未来要发生的调页次数有多少。
例 3 考虑如下配置: (所有页的大小都是 4K)
服务器:
服务器上的物理 RAM 16GB
shmsys:shminfo_shmmax = 15099494 (16GB 的 ~90%)
数据库:
IBMDEFAULTBP 350,000 页
UTILHEAP 17,500 页
DBHEAP 10,000 页
LOCKLIST 1000 页
PCKCACHE 5000 页
CATALOGCACHE 2500 页
ESTORE_SEG_SZ = 400000 页
NUM_ESTORE_SEGS = 1
计算:
数据库共享内存 = (386,000 页 x 4KB/页 + 400,000 页的 estore * 100 字节) x 1.1 = ~1.66GB
ESTORE memory = 400000 x 4KB = 1.6GB
问题: 数据库共享内存是 1.66GB。这个数小于 3.35GB 的数据库共享内存限制。shmmax 参数设置得比较恰当。但是在启动数据库时可能返回下面的错误消息!您可以在 db2diag.log 中看到如下错误消息:
2003-12-04-10.10.13.362027 Instance:db2inst1 Node:000
PID:18327(db2agent (SAMPLE) 0) TID:1 Appid:*LOCAL.sample.047844091013
oper system services sqloVLMAttachVLMSegment Probe:20 Database:SAMPLE
sqloVLMAttachVLMSegment - shmat failed
0xFFBE833C : 0x0000000C
shmat 是一个 UNIX 函数,它将与 shmid(另一个 Solaris 函数)所标识的共享内存相关的共享内存段附加到调用进程的数据段上。shmat 失败于 0x000000C,即 ENOMEM 或可用数据空间不足以容纳共享内存段。
换句话说,不能激活数据库或连接到数据库,因为没有足够的共享内存来满足请求。
那么该怎么办呢?答案在于我们分配 ESTORE 的方式。每个 ESTORE 段必须是一个连续的块。在我们的例子中,我们试图为 ESTORE 分配很大的一块(连续的)内存(1.6GB)。即使有 16GB 的 RAM,它也可能会被分段,从而没有一块连续的 1.6GB 的内存。
为解决这个问题,在数据库配置文件中像下面这样设置 ESTORE 的值:
ESTORE_SEG_SZ = 40000 页
NUM_ESTORE_SEGS = 10
通过设置上面的 ESTORE 值,实际上我们仍然试图为 ESTORE 分配总共 1.6 GB 的内存。然而,我们将尝试为 ESTORE 分配 10 块 160MB 的内存。这样分配的连续空间就要小得多,因此最有可能解决问题。 |
|