【彭建军】IBM DB2 内存分配与使用策略 (中)

上一篇 / 下一篇  2008-06-19 10:31:35 / 个人分类:IBM

32 位 AIX 中的 DB2 内存配置
        
        在 32 位的 AIX 上,4GB 的可寻址内存空间被拆分为 16 个段,每段 256MB。 图 6展示了用于一个 DB2 代理进程的 32位 内存地址空间。(假设 DB2_MMAP_READ 和 DB2_MMA_WRITE 这两个 DB2 注册表变量都被设为 NO。如果这两个变量没有设为 NO,则表示方法会有点不同。我们将在后面解释。) 
        
        图 6 - AIX 中的 DB2 32 位内存地址空间
        

        
        段 0 - 预留给 AIX 内核。
        
        段 1 - 预留给 db2sysc 进程。
        
        段 2 - 预留给代理私有内存。
        
        段 3 - 预留给实例共享内存。
        
        段 4 到段 B - 数据库共享内存始于段 4,这些段必须紧挨在一起。所有这 8 个段(2GB)可能都被用于数据库共享内存。但是,下面的每种配置都会从数据库共享内存中拿出一个段(256MB)。
        
        注意: 对于下面的每种配置,DB2 将从数据库共享内存中拿出一个段,这个段始于段 B。 
        
        如果数据库是分区的,或者启用了 intra-parallel 或连接集中器,那么数据库共享内存中有一个段被预留给应用程序组共享内存。 
        
        Fast Communication Manager (FCM):FCM 用于系统物理节点上不同分区之间的通信。默认情况下,这种通信是通过 UNIX socket 进行的。如果 DB2_FORCE_FCM_BP 被设为 YES,那么 FCM 通信发生在共享内存内。这意味着数据库共享内存中有一个段被预留给 FCM 通信。虽然 FCM 通信变得更快,但是它也令数据库共享内存减少了一个段。 
        
        fenced UDF 和存储过程:如果数据库上运行着一个 fenced 函数或过程,那么数据库共享内存中有一个段要预留给 fenced 模式的通信。 
        
        如果数据库允许任何本地连接,那么数据库共享内存中有一个段要预留给代理/本地应用程序通信。如果将所有本地连接配置为 loopback 连接,那么就可以为这些连接使用 TCP/IP,而不需要共享内存(即使数据库就在服务器本地)。这样就有效地为数据库共享内存空出一个段来。 然而,如果您不想使用 loopback 解决方案,还有一种方法可以迫使 DB2 选择段 E 来用于代理/本地应用程序通信,这样数据库共享内存就不受影响(即不会减少)。请参阅后面的解释。
        
        如果启用了 ESTORE,那么还要从数据库共享内存中拿出另一个段。因此,如果启用 ESTORE,则应确保它至少是 256MB,否则就不起作用,因为要从数据库共享内存中拿出一个 256 MB 的段来仅用于管理这个 ESTORE。建议将 estore 段的大小( estore_seg_sz)设为 256MB,然后根据可用的内存更改段的数目( num_estore_segs)。 
        
        段 C - 预留给 DB2 跟踪使用程序。
        
        段 D 和 F- 预留给 DB2 共享库
        
        段 E - 在默认情况下,这个段是不用的。不过,如果设置 DB2_MMAP_READ=NO 和 DB2_MMAP_WRITE=NO,那么该段用于 DB2 代理以及本地应用程序之间的通信(如 图 6所示)。这将有效地为数据库共享内存一个段。 
        
        注意: 为了最大化数据库共享内存的空间,应使用以下注册表变量设置:DB2_FORCE_FCM_BP=NO (该值是默认值),DB2_MMAP_READ=NO,DB2_MMAP_WRITE=NO。 
        
        需要从这种结构中了解到的最重要的事情是: 
        
        对于禁用了 intra-parallel 的单分区系统,我们可以得到至多 2GB 的空间用于数据库共享内存(段 4 到段 B)。 
        下面每种配置都将数据库共享内存减少了一个段(256MB):带 fenced UDF 或存储过程的数据库、带本地连接的数据库、DB2_FORCE_FCM_BP=YES 情况下的数据库、支持 intra_parallel、或支持集中器以及分区的数据库,以及启用了 ESTORE 的数据库。 
        
        如果允许与数据库进行本地连接,那么应该将 DB2_MMAP_READ 和 DB2_MMAP_WRITE 都设置成 NO,以便使用段 E。否则,任何本地连接都要从数据库共享内存中拿走一个段。
        
        这些限制规定了我们该如何配置数据库共享内存集中的每个内存池。可以使用前面给出的公式来计算数据库共享内存。得到的总和不能超过这个限制。
        
        注意:内存可以分配,释放,也可以当数据库正在运行时在不同区域之间交换。例如,您可以减少 locklist 而增加相同数量的任何一个给定的缓冲池。 
        
        使用 svmon 监控 AIX 上的内存使用情况
        
        在 AIX 上,除了 db2mtrk 工具外,还可以使用 svmon 工具来监控 DB2 代理进程的内存消耗情况(需要 root 权限)。这个命令是: "svmon -P PID",其中 PID是 DB2 代理(db2agent 或 db2agentp)的进程 ID。 
        
        图 7 展示了 svmon 对于一个名为 db2agent 的进程的示例输出。与这个 db2agent 进程相关的数据库有如下特征: 
        

        
        数据库名是 TEST。 
        
        INTRAP_PARALLEL = YES (get dbm cfg) 
        DB2_FORCE_FCM_BP = YES (db2set -all) 
        DB2_MMAP_READ=NO, DB2_MMAP_WRITE=NO (db2set -all)
        图 7 - svmon 对于一个 DB2 代理进程 (svmon -P 11649046) 的输出
        
        从 图 7中观察到的一些情况: 
        
        进程 ID 是 11649046,进程名为 db2agent(左上角)。这个代理被连接到数据库 TEST(数据库的名称在 svmon 输出中已经被截断,只显示了 'TES')。
        Esid 列显示已经分配的内存段: 
        段 4 (绿色)被分配给数据库共享内存。 
        段 2 (橙色)被分配给代理私有内存。 
        段 3 (蓝色)被分配给实例共享内存。 
        段 B (紫色)被分配给应用程序组共享内存,因为数据库支持 intra_parallel。 
        段 A (粉红色)被分配给 FCM,因为 DB2_FORCE_FCM_BP=YES。 
        本地连接段被移到段 E(红色)。这是因为 DB2_MMAP_READ 和 DB2_MMAP_WRITE 都被设为 NO。否则,就必须将段 8 用于代理和本地连接通信,因为段 A 和段 B 都已经被占用,而段 9 被预留给 fenced 模式的通信。
        观察到的这些情况与 图 6中说明的相匹配。 
        
        设置 32 位 AIX 系统上数据和堆栈的 ulimit
        
        我们早先说过, 图 6中的段 #2 是用于代理私有内存的。实际上,并非完全如此。 
        
        确切地说,段 #2 被预留给数据和堆栈。数据包含用户数据(即代理私有内存)。而堆栈则包含要执行的指令。在这个 256M 的段中,数据是从地址 0x20000000 向下增长的。而堆栈是从地址 0x2FFFFFFF 向上增长的。为了不让数据和堆栈有冲突,设置它们的限制就十分重要。如果数据和堆栈真的有冲突,那么实例就会崩溃,并产生信号 4 或信号 11。
        
        图 8 - 数据段和堆栈段   


        
        数据和堆栈的限制是在 ulimits(/etc/security/limits)中设置的。使用 SMIT 将它们设置成如下值: 
        
        Data = 491519, Stack = 32767 (512 字节) 
        
        上述值以 512 字节为单位,其中对于数据是 240MB,对于堆栈是 16MB。当使用 "ulimit -a" 显示这两个限制时,显示的值以 1K 字节为单位,而不是以 512 字节为单位。因此这两个值变为: 
        
        Data = 245760, Stack = 16384 
        
        注意: /etc/security/limits 包含了以 512 字节为单位的限制,而不是以 1 KB 为单位的限制。 
        
        
32 位 AIX 上与分配数据库共享内存有关的常见问题
        
        初始化数据库共享内存失败可能产生如下问题: 
        
        在数据库启动时(激活数据库或第一次连接数据库) - SQL1478W, SQL0987C, SQL1084C。 
        在运行时 - SQL10003N, SQL1042C。
        下面的例子展示了会导致问题的不恰当配置。
        
        例 1 考虑以下配置:(所有页的大小为 4KB) 
        
        单分区,禁用集中器,INTRA_PARALLEL OFF,DB2_MMAP_READ=NO,DB2_MMAP_WRITE=NO,无 fenced 函数或过程 
        IBMDEFAULTBP 450,000 页 
        UTILHEAP 17,500 页 
        DBHEAP 10,000 页 
        LOCKLIST 1000 页 
        PCKCACHE 5000 页 
        CATALOGCACHE 2500 页
        
        限制:在此配置中,对于数据库共享内存的限制是 2GB 或 8 个段。
        
        计算:使用公式计算数据库共享内存,我们得到: 
        
        数据库共享内存 = (486,000 页 x 4KB/页的总数) x 1.1 (考虑到 10% 的开销) = ~2.1GB = 9 个段 
        
        注意:我们会将 4 个隐藏缓冲池排除在计算之外,因为它们太小了,不会产生明显的不同。 
        
        问题:这超出了 2GB 的限制。当激活数据库或第一次连接到数据库时,您将收到如下警告: 
        
        SQL1478W The defined buffer pools could not be started. Instead, one small buffer pool for each page size supported by DB2 has been started. SQLSTATE=01626 
        
        在 db2diag.log 中,您将看到有消息说 DB2 将利用隐藏缓冲池启动。要解决这个问题,可以减少主缓冲池的大小。
        
        例 2 考虑如下配置: (所有页的大小都是 4K) 
        
        单分区,无 fenced 函数或过程,INTRA_PARALLEL=ON 
        IBMDEFAULTBP 300,000 页 
        UTILHEAP 17,500 页 
        DBHEAP 10,000 页 
        SHEAPTHRES_SHR 50,000 页 
        LOCKLIST 1000 页 
        PCKCACHE 5000 页 
        CATALOGCACHE 2500 页
        限制: 1.5GB (6 个段)。一个段用于应用程序组内存,因为 INTRA_PARALLEL 是 ON。另一个段用于本地连接,因为 DB2_MMAP_READ 和 DB2_MMAP_WRITE 都被设为 YES (该值是默认值)。
        
        计算:数据库共享内存 = (386,000 页 x 4KB/页的总数) x 1.1 = ~1.67GB = 7 个段 
        
        问题:这超出了 1.5GB 的限制。当尝试激活数据库或第一次连接到数据库时,您将得到以下错误消息: 
        
        SQL1042C An unexpected system error occurred. SQLSTATE=58004 
        
        要解决这一问题: 
        
        使用 db2set 将 DB2_MMAP_READ 和 DB2_MMAP_WRITE 设为 NO。这样便迫使 DB2 将段 E 用于本地连接,从而为数据库共享内存空出一个段。
        
        例 3 考虑如下配置: (所有页的大小都为 4K) 
        IBMDEFAULTBP 250,000 页 
        INTRA_PARALLEL=ON 
        UTILHEAP 17,500 页 
        DBHEAP 10,000 页 
        SHEAPTHRES_SHR 20,000 页 
        LOCKLIST 1000 页 
        PCKCACHE 5000 页 
        CATALOGCACHE 2500 页 
        存在 Fenced UDF
        限制: 以下各占一个段:Intra-parallel ON,本地连接,以及 fenced UDFB。这样还剩下 5 个段,或者 1.25G 给数据库共享内存。
        
        计算: 
        
        数据库共享内存 = (306,000 页 x 4KB/页的总数) x 1.1% = ~1.35GB = 6 个段 
        
        问题: 引用了 fenced UDF 的查询就会失败,并返回错误 sql10003C。要解决这个问题,可以在 unfenced 模式下运行 UDF,或者将数据库共享内存减少至不多于 5 个段。
        
        待续……



TAG: db2 内存分配与使用

 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

我的栏目

日历

« 2009-07-05  
   1234
567891011
12131415161718
19202122232425
262728293031 

数据统计

  • 访问量: 18660
  • 日志数: 110
  • 建立时间: 2008-03-27
  • 更新时间: 2008-06-24

RSS订阅

Open Toolbar