DB2 9.5 中多线程架构的工作原理

概述

DB2® 9.5 for Linux®, UNIX®, and Windows®(代号为 “Viper 2”)中引入了新的多线程功能。了解当您需要经常性地监视进程或线程、需要理解数据库正在使用多少内存,或者当您需要简化备份、恢复和前滚等任务关键型工作时,DB2 9.5 中的新功能如何提供帮助。您将了解到这些新特性如何影响配置参数,并学习 DB2 9.5 中的新技术。

Shashank Kharche, 专职软件工程师, WSO2 Inc

作者照片:Shashank KharcheShashank Kharche 是位于澳大利亚悉尼 IBM Australia Development Lab 的一名专职软件工程师。他是一名 IBM 认证的 DB2 管理员。Shashank 目前在亚太地区 Down Systems Division 工作,在 DB2 数据库和关键问题的诊断与解决方面有广泛的经验。他为 IBM 发表了一些技术札记。他拥有计算机科学与工程学士学位。可以通过 shashank.kharche@au1.ibm.com 与他联系。



2008 年 11 月 06 日

简介

IBM 为社区提供了 DB2 免费版本 DB2 Express-C,它提供了与 DB2 Express Edition 相同的核心数据特性,为构建和部署应用程序奠定了坚实的基础。

为了理解 DB2 9.5 中新的多线程功能,本文首先讨论 DB2 进程模型。整个 DB2 进程模型是由 Base System Utilities(BSUs)控制的。BSU 为实例和数据库分配内存,拦截和处理信号,并处理发送到 DB2 的异常。图 1显示了用于 Linux 和 UNIX 平台的旧的 DB2 进程模型。

图 1. Linux 和 UNIX 上旧的 DB2 进程模型
Linux 和 UNIX 上旧的 DB2 进程模型

图 2 显示了 Linux 和 UNIX 上新的进程模型。

图 2. Linux 和 UNIX 上新的 DB2 进程模型
Linux 和 UNIX 上新的 DB2 进程模型

数据库服务器、客户机与应用程序之间的通信由一个框架来处理。这种框架正是所有 DB2 服务器都使用的进程模型。它确保内部使用的数据库文件不会干扰用户或数据库应用程序。

引擎分派单元(engine dispatchable units,EDU)负责执行各种任务,例如处理数据库应用程序请求、读取数据库日志文件以及将日志记录从日志缓冲区刷新到磁盘上的日志文件。通常,DB2 服务器将每个任务作为一个单独的 EDU 进行处理。在 DB2 9.5 之前,大多数这样的 EDU 在 UNIX 和 Linux 环境中是进程,而在 Windows 环境中是线程。而在 9.5 中,DB2 的进程模型得到统一,现在 EDU 在 Linux、 UNIX 和 Windows 环境中都是线程。

下面是这种新的内存模型的一些优点:

  • 这种新的内存模型更加简单,而且更易于配置。请参阅 DB2 Information Center 中的以下内容:
  • 这种模型可以节省资源:
    使用的系统文件描述符明显减少。进程与线程之间最明显的区别就是,一个进程的所有线程都共享相同的内存空间和系统定义的设施。这些设施包括打开文件句柄(文件描述符)、共享内存、进程同步原语和当前目录。一个进程中的所有线程可以共享相同的文件描述符。这里不需要让每个代理维护它自己的文件描述符表。
  • 性能得到提高:
    操作系统通常可以在相同进程中的不同线程之间更快速地切换(上下文切换),而不是在不同进程之间切换。这种切换不需要切换地址空间。由于全局内存是共享的,几乎不必分配新的内存,因此创建一个线程比创建一个进程更简单、更快捷。就处理器周期和使用的内存而言,创建进程的代价较高。
  • 有更高的自动化程度和动态的可配置参数,因此 DBA 更轻松。
    本文的 进程模型配置简化 小节中将对此加以阐述。
  • 现在,进程模型在所有三个平台上是一样的:Linux、UNIX 和 Windows。

用 db2pd 监视线程,并用 ps 输出与之映射

在 DB2 9.5 之前,在 UNIX 和 Linux 环境中,通过 ps 系统命令或 db2_local_ps 命令,可以列出所有活动的 DB2 EDU。然而,在 DB2 9.5 中,这些命令不再列出 db2sysc 进程中的任何 EDU 线程。因此,当 DB2 用户和 DBA 使用一个 OS 命令查看系统上正在运行的进程时,一个变化是,他们只能看到一个进程,而不是多个进程。从 DBA 的角度来看,这正是您期望的管理方面的变化。

$ ps -fu db2ins10
     UID     PID    PPID   C    STIME    TTY  TIME CMD
db2ins10 1237176 2109662   0   Feb 28      -  0:12 db2acd 0
db2ins10 1921136 2109662   0   Feb 28      -  0:14 db2sysc 0
db2ins10 2101494 1941686   0 14:22:34  pts/1  0:00 -ksh
db2ins10 2420958 2101494   0 15:25:33  pts/1  0:00 ps -fu db2ins10

在 AIX 上
查看 db2sysc 进程(PID = 1921136)中的所有线程:

清单 1. 在 AIX 系统上查看 db2sysc 进程的所有线程
$ ps -mo THREAD -p 1921136

    USER     PID    PPID       TID ST  CP PRI SC    WCHAN        F     TT BND COMMAND
db2ins10 1921136 2109662         - A    0  60 26        *    40401      -   - db2sysc 0
       -       -       -   1273899 S    0  60  1 f1000100403674b0   410400      -   - -
       -       -       -   1327331 Z    0  60  1        -   c00001      -   - -
       -       -       -   1392805 Z    0  60  1        -   c00001      -   - -
       -       -       -   1601705 Z    0  60  1        -   c00001      -   - -
       -       -       -   1814627 Z    0  60  1        -   c00001      -   - -
       -       -       -   1851457 S    0  60  1 f1000004f010de00   410400      -   - -
       -       -       -   1961987 Z    0  60  1        -   c00001      -   - -
       -       -       -   1974311 Z    0  60  1        -   c00001      -   - -
       -       -       -   2023571 S    0  60  1 f100010041b401b0   410400      -   - -
       -       -       -   2068591 Z    0  60  1        -   c00001      -   - -
       -       -       -   2179161 Z    0  60  1        -   c00001      -   - -
       -       -       -   2187515 Z    0  60  1        -   c00001      -   - -
       -       -       -   2216003 S    0  60  1        -   400400      -   - -
       -       -       -   2412647 Z    0  60  1        -   c00001      -   - -
       -       -       -   2551911 Z    0  60  1        -   c00001      -   - -
       -       -       -   2592969 Z    0  60  1        -   c00001      -   - -
       -       -       -   2621455 S    0  60  1 f1000100407f7e30   410400      -   - -
       -       -       -   2658531 S    0  60  1        -   418400      -   - -
       -       -       -   3031171 Z    0  60  1        -   c00001      -   - -
       -       -       -   3457047 Z    0  60  1        -   c00001      -   - -
       -       -       -   3899477 Z    0  60  1        -   c00001      -   - -
       -       -       -   4157609 Z    0  60  1        -   c00001      -   - -
       -       -       -   4390991 S    0  60  1        -   400400      -   - -
       -       -       -   4636819 Z    0  60  1        -   c00001      -   - -
       -       -       -   5628153 S    0  60  1        -   400400      -   - -
       -       -       -   6783009 Z    0  60  1        -   c00001      -   - -

在 Linux 上

查看 db2sysc 进程(PID = 1921136)的所有线程: ps -lLfp 1921136

DBA 现在变得更轻松了。db2pd 也得到增强,可以列出进程和线程。现在可以使用 db2pd 命令和 -edu 选项列出所有活动的 EDU 线程。该命令在 UNIX、Linux 和 Windows 系统上都可以使用。

清单 2. 在 Linux 系统上查看 db2sysc 进程的所有线程
$ db2pd -edu

Database Partition 0 -- Active -- Up 1 days 01:05:54
List of all EDUs for database partition 0

db2sysc PID: 1921136
db2wdog PID: 2109662
db2acd  PID: 1237176


EDU ID    TID         Kernel TID     EDU Name                 USR            SYS
===================================================================================
1801      1801           2216003        db2agent (idle) 0     0.706935     1.071737
1543      1543           5628153        db2resync 0           0.002641     0.004271
1286      1286           1851457        db2ipccm 0            0.082388     0.044037
1029      1029           2023571        db2licc 0             0.000211     0.001055
772       772            4390991        db2thcln 0            0.000244     0.000105
515       515            2621455        db2aiothr 0           2.740874     6.287562
2           2            1273899        db2alarm 0            0.274076     0.408226
258       258            2658531        db2sysc 0             2.085981     1.379128

DB2 使用多少内存?

下面是查看内存使用情况的一些方法:

  • db2pd -dbptnmem
  • 使用 db2 get 按样获得应用程序快照
  • select * from table(admin_get_dbp_mem_usage())
  • db2mtrk -a 和 db2mtrk -p

注意以下信息:

  • db2pd 显示共享内存分级结构的准确表示
  • db2pd 仍不能报告私有内存的分配情况
  • db2mtrk 可以报告私有内存的分配情况,但在其他方面比较弱
  • 私有内存的使用情况不再那么值得关心
  • db2pd -dbpntmem 高级报告可能已经足够

使用 db2pd

清单 3. db2pd 示例
$ db2pd -dbptnmem

Database Partition 0 -- Active -- Up 1 days 01:11:27

Database Partition Memory Controller Statistics

Controller Automatic: Y
Memory Limit:         13994636 KB
Current usage:           76608 KB
HWM usage:            332736 KB
Cached memory:        16064 KB

Individual Memory Consumers:

Name             Mem Used(KB) HWM Used(KB) Cached(KB)
========================================================
DBMS-db2ins10            46784         46784       10048
FMP_RESOURCES            22528         22528           0
PRIVATE                   7296          7296        6016

字段信息:

如果 INSTANCE_MEMORY 配置参数被设为 AUTOMATIC,则 Controller Automatic 被设为 Y。这意味着数据库管理器自动确定内存使用的上限。

Memory Limit 是 DB2 服务器可使用内存的上限。它是 INSTANCE_MEMORY 配置参数的值。

Current usage 是服务器当前使用的内存量。

HWM usage 是当 db2start 命令在运行时,自数据库分区激活以来的最高水位标记(high water mark,HWM)或峰值内存使用量。

Cached memory 是当前使用量(current usage)当中目前没有被使用,而是由于性能原因缓存起来用于将来的内存请求的内存。

Individual Memory Consumers 部分:

  • 列出了 DB2 服务器中所有注册的内存 “消耗者”,以及它们消耗的总内存量。
  • Name:内存 “消耗者” 的一个简洁、易于辨别的名称。例如:
    • 对于用于数据库 <dbname> 的应用程序内存,名称为:APPL-<dbname>
    • 对于全局数据库管理器内存需求,名称为:DBMS-xxx
    • 对于与 db2fmps 通信所需的内存,名称为 FMP_RESOURCES
    • 对于各种私有内存需求,名称为 PRIVATE
    • 对于 Fast Communication Manager 资源,名称为 FCM_RESOURCES
    • 对于用于与本地应用程序通信的内存段,名称为:LCL-<pid>
    • 对于用于数据库 <dbname> 的数据库内存,名称为 DB-<dbname>
  • Mem Used(KB):当前有多少内存被分配给某个消耗者。
  • HWM Used(KB):该消耗者曾使用的内存的高水位标记或峰值。
  • Cached(KB):在 Mem Used(KB)当中,当前没有使用,而是备用于将来内存分配的内存量。

使用 db2 get 快照

清单 4. db2 get 快照示例
$ db2 get snapshot for applications on sample

Memory usage for application:

  Memory Pool Type                         = Application Heap
     Current size (bytes)                  = 65536
     High water mark (bytes)               = 65536
     Configured size (bytes)               = 1048576

Agent process/thread ID                    = 6463
  Agent Lock timeout (seconds)             = -1
  Memory usage for agent:

    Memory Pool Type                       = Other Memory
       Current size (bytes)                = 196608
       High water mark (bytes)             = 196608
       Configured size (bytes)             = 16710107136

使用 SQL

清单 5. 使用 SQL 示例
$ db2 "select * from table(admin_get_dbp_mem_usage())"

DBPARTITIONNUM MAX_PARTITION_MEM    CURRENT_PARTITION_MEM PEAK_PARTITION_MEM
-------------- -------------------- --------------------- --------------------
             0          14330507264             340590592            340852736

  1 record(s) selected.

使用 db2mtrk

清单 6. db2mtrk -a 示例
$ db2mtrk -a
Tracking Memory on: 2008/02/29 at 15:51:00

Application Memory for database: SAMPLE
   appshrh
   128.0K

  Memory for application 546
   apph        other
   64.0K       192.0K

  Memory for application 545
   apph        other
   64.0K       192.0K

  Memory for application 544
   apph        other
   64.0K       320.0K

  Memory for application 543
   apph        other
   64.0K       576.0K

  Memory for application 547
   apph        other
   64.0K       192.0K
清单 7. db2mtrk -p 示例
$ db2mtrk -p
Tracking Memory on: 2008/02/29 at 15:51:37

Memory for agent 6463
   other
   192.0K

Memory for agent 6206
   other
   192.0K
Memory for agent 5949
   other
   320.0K

Memory for agent 2094
   other
   576.0K

Memory for agent 6720
   other
   192.0K

注意:默认情况下,INSTANCE_MEMORY 被设为 AUTOMATIC,这意味着实例被允许使用 RAM 的一个最大百分值(对于较小的系统,范围是 75%,对于较大的系统,范围是 95%)。这包括一个单独的实例的所有本地分区。

db2 get dbm cfg show detail|grep INSTANCE_MEMORY
Size of instance shared memory(4KB)(INSTANCE_MEMORY)=AUTOMATIC(3498659)AUTOMATIC(3498659)

不能永久地为不同的数据库分区设置不同的 INSTANCE_MEMORY 值。对于一个 DB2 Express 许可,INSTANCE_MEMORY 的上限被进一步限制为至多 4GB 内存(1,048,576 * 4KB 页)。DB2 Workgroup 许可被限制为至多 16GB 内存(4,194,304 * 4KB 页)。如果尝试将 INSTANCE_MEMORY 配置参数更新为大于这些限制的值,那么会遭到失败,并收到 SQL5130N 返回码,指定该许可允许的限制范围。其他许可类型没有附加的限制。不能将 INSTANCE_MEMORY 设为大于 RAM。


解决 DPF 备份和恢复问题

每个分区获得一个不同的时间戳

在之前的 DB2 版本上:

$ db2_all " db2 backup db test"

Backup successful. The timestamp for this backup image is : 20080304124529
eva88: db2 backup db test completed ok

Backup successful. The timestamp for this backup image is : 20080304124544
eva88: db2 backup db test completed ok

Backup successful. The timestamp for this backup image is : 20080304124554
eva88: db2 backup db test completed ok

然而,在 DB2 9.5 中,BACKUP 命令得到增强,现在可以接收一组数据库分区,并提供一个单独的系统视图。

$ db2 backup db test on all dbpartitionnums
Part  Result
----  -------------------------------
0000  DB20000I  The BACKUP DATABASE command completed successfully.
0010  DB20000I  The BACKUP DATABASE command completed successfully.

Backup successful. The timestamp for this backup image is : 20080304135942

如何确定前滚期间需要什么日志文件?

$ db2 rollforward db test to 2008-03-01 and stop
SQL1275N  The stoptime passed to roll-forward must be greater than or equal to 
"2008-03-04-12.45.54.000000 UTC", because  database "TEST" on node(s) "0,1" 
contains information later than the specified time.

$ db2 rollforward db test to 2008-03-04-12.45.54.000000 and stop
DB20000I  The ROLLFORWARD command completed successfully.

以上例子表明,在前滚期间,如果命令中指定的时间点(PIT)过早,那么会收到错误消息(SQL1275N)。该错误消息告诉您正确的 PIT。可以考虑使用 BACKUP 和 INCLUDE 日志。但是,在 DPF 数据库中,BACKUP 和 INCLUDE 日志会生成错误消息(SQL2032N)。因此,不能使用该方法。

然而,在 DB2 9.5 中,可以使用 “TO END OF BACKUP” 子句和 ROLLFORWARD 命令将一个分区数据库中的所有分区前滚到最小恢复时间。这个最小恢复时间是前滚期间数据库处于一致状态(数据库编目中列出的对象与磁盘上物理存在的对象相匹配)的最早时间点。手动地确定前滚一个数据库的正确时间点比较困难,对于分区数据库更是如此。而 “END OF BACKUP” 选项可以使这件事变得容易起来。

$ db2 rollforward db test to end of backup and stop
DB20000I  The ROLLFORWARD command completed successfully

关于用户限制,什么是重要的?

用户限制(User limits)设置或显示一个 shell 在资源使用方面的不同限制。它是一个很好的实践,可用于设置一些限制,防止诸如一个有错误的 shell 脚本开始无限制的自我复制之类的问题,或者防止系统上的用户启动永远运行的进程。但是,将它设置成什么呢?下面是对于资源的不同限制的一些考虑:

  • 在 db2 启动时,数据和 nofile 是无限制的。
  • 栈限制不重要,因为 DB2 创建它自己的栈空间(AGENT_STACK_SZ dbm cfg)

    在 64 位 UNIX 上
    Default : 4 MB
    Minimum : 1 MB
    Maximum : 128 MB

    在 32 位 LINUX 上
    Default : 1MB
    Minimum : 64 KB
    Maximum : 4MB
  • MAXFILOP 是每数据库每分区的最大值。对于 32 位,新的默认最大值是 ~32K,对于 64 位,新的默认最大值是 ~64K。
  • 当前 ulimit 设置(或者,在 AIX 上,如果 ulimit 被设为 unlimited,则为 8GB)。DB2 改写了一个 unlimited 的内核限制。为了得到一个大于 8GB 的内核,必须显式地将内核限制设为大于 8GB 的值,而不是设为 unlimited。

进程模型配置简化

在本节中,您将看到在 DB2 9.5 中配置参数有什么不同的行为。注意默认值和范围,因为它们与之前不同。

图 3. 配置参数
配置参数

如果有性能关键型、非隔离的(unfenced)外部存储过程(SP)或用户定义函数(UDF),那么应确保它们是线程安全的。在迁移时,所有外部的、非隔离 SP 和 UDF 都将变为有隔离(fenced)。
按照惯例,为确保数据完整性,非隔离 SP 和 UDF 应该已经是线程安全的,但是,这不是强制性的。在一个多线程的进程中运行一个非线程安全的 SP 或 UDF 会导致不可预测的问题。因此,在迁移过程中,应创建一个脚本,以便实现对非隔离的转换。

在开始使用之前,先快速查看一下新引入的线程和进程:

  • db2thcln(线程栈清理):当一个 EDU 终止时回收资源(仅在 UNIX 上)。
  • db2aiothr(aio 收集器线程):管理数据库分区的异步 I/O 请求(仅在 UNIX 上)。
  • db2alarm(报警线程):当 EDU 请求的计时器到期时通知 EDU(仅在 UNIX 上)。
  • db2vend(隔离的供应商进程):代表一个 EDU 执行供应商代码,使实例执行用户退出程序,以便进行日志归档(仅在 UNIX 上)。
  • db2extev(外部事件处理程序线程):与 SIGUSR2 相同。
  • db2acd:一个健康监视器进程。

最后,如果升级到 DB2 9.5,会影响当前已有的应用程序吗?
答案是不会,完全不会。这个内部变化根本不会影响应用程序。实际上,从管理和应用程序编程的角度来看,它很大程度上是透明的。


致谢

特别感谢 Amar Thakkar 和 Samir Kapoor 对本文作出的技术审校。

参考资料

学习

获得产品和技术

  • 用可直接从 developerWorks 下载的 IBM 试用软件 构建您的下一个开发项目。
  • 下载 IBM 试用软件,并获取来自 DB2®、Lotus®、Rational®、Tivoli® 和 WebSphere® 的应用程序开发工具和中间件产品。

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Information Management
ArticleID=350224
ArticleTitle=DB2 9.5 中多线程架构的工作原理
publish-date=11062008