内容


对具有数据库分区功能的 DB2 UDB for Linux, UNIX and Windows Version 8 的生动介绍(第 2 部分)

Comments

简介

本系列文章的 第 1 部分 介绍了 Linux、UNIX® 和 Windows® 环境下的 IBM® DB2® Universal Database™(UDB)。其中还描述了一些实例、配置参数、连通性(connectivity)信息以及各种不同的数据库对象。作为本系列的第 2 部分,本文介绍了 DB2 UDB Enterprise Server Edition (ESE) 上提供的数据库分区功能(Database Partitioning Feature,DPF)。有了 DPF 功能,数据库就具有可扩展性,从而可以添加新的机器,并将数据库延伸到这些机器上。这意味着可以从为数据库新添加的每一台机器上获得更多的 CPU、更多的内存和更多的磁盘。具有 DPF 功能的 DB2 UDB ESE 是管理数据仓库、数据挖掘和在线分析处理(online analytical processing,OLAP)等工作的理想选择。它同样适用于在线事务处理(online transaction processing,OLTP)工作。注意,启用该功能并没有什么技术需求,只需购买所需的许可就行了。从用户的角度来看,可以像往常一样连接到数据库,然后发出查询,而不需要知道实际上数据库是分布在数台机器上的。

第 1 部分 讨论的是单分区(single-partition)环境,不过其中的知识仍然适用于多分区(multi-partition)环境。所有的概念仍然是一样的,不过我们需要指出一些实现上的不同之处。例如,我们将解释配置文件、连通性信息等驻留在哪一台机器上。我们还将介绍一些新的概念,比如分区(partition)、分区组(partition group)、协调节点(coordinator node)等等,这些概念都与单分区环境无关。

与第 1 部分一样,这里也使用一些图来可视化地解释概念。在本文中,我用 DB2 这个词来指代 DB2 Universal Database Enterprise Server Edition Version 8.1 for Linux, UNIX and Windows。我建议您将本文打印出来,而不是在线阅读,因为后面我会经常引用到这些图。首先我们会简要地解释一些概念,在最后一节中,我们会将这些概念联系到一个案例学习当中去。

数据库分区

将一个数据库分区时,我们把它分成一些独立的部分,每一部分都包含各自的数据、配置文件、索引和事务日志。每一部分就是一个数据库分区。可以将多个分区分派到一台物理机器上。有时候,这些分区也叫做逻辑分区(logical partition),这些逻辑分区共享机器上的资源。

单分区数据库是一种只有一个分区的数据库。在本系列的第 1 部分中,我们就谈到了这种类型的环境。

多分区数据库(也称分区数据库),是具有两个或多个分区的数据库。这种类型的数据库正是我们在本系列的当前部分所要讨论的。取决于硬件环境,您可以按照几种配置来对数据库分区。图 1 展示了物理分区的配置,每台机器上有一个分区。

图 1 - 每台机器一个分区的数据库分区配置
每台机器一个分区的数据库分区配置
每台机器一个分区的数据库分区配置
注意: 在图 1 中,SMP 系统可以用单处理器(uniprocessor)系统代替。对于使用 DB2 with DPF 的环境来说,单处理器系统目前已经相当少见了,因此在图中我们将其省略了。

图 2 展示了更多的多分区配置,其中每台机器上有数个分区。

图 2 - 每台机器有数个分区的数据库分区配置
图 2 - 每台机器有数个分区的数据库分区配置
图 2 - 每台机器有数个分区的数据库分区配置
注意: 在版本 8 之前,使用的是术语“节点(node)”,而不是“分区(partition)”。随着版本 8 的发行,仍然有一些概念、命令和消息在使用这个术语。还应注意的是, 节点目录这一概念与 分区 的概念没有丝毫的关系。

为了利用在 第 1 部分中所学到的知识,同时也为了想像出如何在 DPF 系统中拆分 DB2 环境,我们在图 3 中展示了在本系列 第 1 部分 中那个图的部分复制,并且还展示了它是如何被拆分成三个分区、每台 SMP 机器一个分区的。这样,我们就展示了如何将 DB2 环境从一种单分区多处理器配置(如图 1 中的 I 所示)变为一种多分区多处理器配置(如图 1 中的 II 所示)。

我们已经将原始图中的机器更改为使用 Linux 操作系统,而不是使用 Windows 操作系统。DPF 在 Linux/UNIX 环境中要比在 Windows 环境中更流行一些,因此我们主要讨论 Linux/UNIX 这两种平台,不过大多数概念在 Windows 中是一样的。

图 3 - DB2 UDB ESE with DPF 中的 DB2 环境
DB2 UDB ESE with DPF 中的 DB2 环境
DB2 UDB ESE with DPF 中的 DB2 环境

从图 3 中可以看出,DB2 环境是“劈开”的,现在它驻留在三台不同的多处理器机器上,这些机器运行着相同的操作系统(对于我们这里的例子是 Linux),并且在相同的 fixpak 级别上运行着相同的 DB2 版本(版本 8.1)。注意,这个图的目的 不是说明如何从一个单分区数据库系统迁移到一个多分区数据库系统,而是可视化地展示在一个多分区系统的 安装上,文件将被放置在什么地方。

还应谨记的是,所有参与 DPF 环境的机器都必须通过某种通信设备互联起来,这种通信设备可以是使用 TCPIP 协议的网络。每台机器上都预留了一些 TCPIP 端口,用于这种“分区间(interpartition)”通信。例如,默认情况下,Linux 中的服务文件(/etc/services)在安装之后会作如下更新(假设您选择创建 db2inst1 实例):

DB2_db2inst1		60000/tcp
DB2_db2inst1_1		60001/tcp
DB2_db2inst1_2		60002/tcp
DB2_db2inst1_END	60003/tcp
db2c_db2inst1		50000/tcp

默认情况下,端口 60000 到 60003 被预留用于分区间通信。您需要根据当前配置的分区数目,以正确的条目号更新服务文件。

在只涉及同一台机器内的分区时,这些分区之间的通信仍然需要上述设置。只有在 AIX 中,才可以通过将 DB2 注册变量 DB2_FORCE_FCM_BP 设置为 YES 来迫使分区间的通信在内存中执行。

默认情况下,端口 50000 用于连接到 db2inst1 实例。当客户机需要连接到一个 DPF 系统时,它需要发出本系列 第 1 部分中描述到的,并且在 连通性快捷表一文中也作了解释的一些命令。在这些命令中使用的主机名可以来自任何参与 DPF 环境的机器。除非在 CONNECT 语句中使用了 NODE 选项,否则所选择的机器将成为协调节点。本文的后面会对协调节点的概念加以描述。

注意:对于参与 DPF 环境的每台机器,服务文件中的 DB2 条目应该是相同的。

节点配置文件(db2nodes.cfg)

db2nodes.cfg 文件包含关于数据库分区和这些分区所在的服务器的信息,这些服务器将参与到一个实例中。在某些情况下,该文件的信息用于判定命令的作用域。本文后面的“在 DPF 环境中发出命令和 SQL 语句”一节将更详细地讨论命令的作用域。

图 4 展示了 db2nodes.cfg 文件的一个例子,它用于 4 台 UNIX 服务器的一个群集,其中每台服务器上创建两个分区(图 2 中的选项 IV)。

图 4 - 每台服务器上 2 个逻辑分区的 4 台 UNIX 服务器的群集所使用的 db2nodes.cfg
每台服务器上 2 个逻辑分区的 4 台 UNIX 服务器的群集所使用的 db2nodes.cfg
每台服务器上 2 个逻辑分区的 4 台 UNIX 服务器的群集所使用的 db2nodes.cfg

在 Linux/UNIX 环境中,对应于 db2nodes.cfg 文件的列是:

Partition_number Hostname  Logical_Port netname  resourcename

分区号(partition number),即 db2nodes.cfg 文件中的首列,表明了用于标识 DB2 内分区的数字。在这个图中,我们可以看到总共有 8 个分区,分区号从 0 开始。对分区的编号必须按照升序进行,但是可以从任何数字开始。数字之间允许有间隔。注意,编号的方式很重要,因为这在命令或 SQL 语句中要考虑到,在本文接下来的几节中就可以看到这一点。

第 2 列是创建分区时所在服务器的 TCP/IP 主机名。

第 3 列是可选的,但是如果要在一台服务器上创建不止一个分区,那么就必须使用这一列。该列指定服务器内分区的逻辑端口,它在一台服务器内必须是惟一的。对于图 4 中高亮显示的例子,我们可以看到用于服务器“myserverb”的 db2nodes.cfg 条目与物理机器之间的映射。

第 4 列,即 netname,也是可选的,用于支持有多个活动 TCP/IP 接口、每个接口有其自己的主机名的主机。

第 5 列,即 resourcename,是可选的,仅适用于 AIX、HP-UX 和 Solaris 操作系统。它指定了分区应该从哪个操作系统资源开始。

在 Windows 平台上,还存在一个列,即计算机名(computer name),这一列包含一个分区所在机器的计算机名。这些列的顺序是:

Partition_number  Hostname	Computer_name    Logical_Port    netname

db2nodes.cfg 文件必须作如下放置:

  • 在 Linux 和 UNIX 平台上,放置在实例属主的 SQLLIB 目录下。
  • 在 Windows 平台上,放置在 SQLLIB\\<Instance name> 目录下。

在图 3 中,它应该包括在 Linux3 机器中(在那里没有显示出,因为我们不想在那个图中引入新的概念)。

在 Linux 和 UNIX 系统上,可以用任何 ASCII 编辑器或使用 DB2 命令来编辑 db2nodes.cfg 文件。在 Windows 上,只能使用 db2ncrt 和 db2ndrop 命令来创建和删除数据库分区,而不应该直接编辑 db2nodes.cfg 文件。

还可以使用 db2start 命令,分别通过 add dbpartitionnum 和 drop dbpartitionnum 子句,向 DB2 实例和 db2nodes.cfg 文件添加分区或从中删除分区。

在 DPF 环境中安装 DB2

在 DPF 环境中,需要在每台参与进来的机器上本地安装 DB2。为了方便在其他机器上安装 DB2,我们建议在第一台机器上第一次安装 DB2 的时候创建一个响应文件。创建好这个响应文件后,就可以将这个文件传输到其他机器上,并在每台机器上使用命令 db2setup -r <response file> 来运行无人值守安装。

安装盘里的 DB2 安装代码也可以放在一个共享磁盘上,然后就可以从这个磁盘本地安装 DB2。例如,在图 3 中,假设 Linux2 机器上有一个磁盘,我们已经将安装盘上的安装代码复制到了这个磁盘中。这个磁盘是供其他两台机器(Linux1 和 Linux3)共享的。接着,可以从每台机器上执行 db2setup 命令来本地安装 DB2,这样每台机器将拥有它自己的本地目录 /opt/IBM/db2/V8.1,该目录包含安装的 DB2 二进制文件。您可能会想,另一种方法是只在 Linux2 这台机器上安装 DB2,而将安装的二进制文件与 Linux1 和 Linux3 共享,但是这种配置是不受支持的。

注意:在 Linux 中,安装的 DB2 二进制文件是存放在本地目录 /opt/IBM/db2/V8.1 中的。在其他平台上,DB2 安装在其他目录中。应使用 db2level 命令确定安装的代码存放在本地机器的哪个地方。

DPF 环境中的一个实例

分区这个概念只适用于数据库这一级,而不适用于实例这一级。图 3 可能会令您觉得实例也可以分区。然而,在 DPF 环境中的实际情况是,每台机器上会单独创建一个实例,这些实例都使用相同的特征:同样的实例名,同样的口令,以及共享的主目录(home directory)。

在 Linux 和 UNIX 中,一个实例映射到一个操作系统用户,因此,当创建一个实例时,该实例将拥有自己的主目录。例如,在大多数安装中,/home/<user name> 被用作主目录。在 DPF 环境中,在每台分区的机器上单独创建的所有实例都必须使用相同的名称和口令。此外,对于所有实例,相应操作系统用户的主目录必须是相同的目录,这个目录必须在一个共享磁盘(NFS 共享)上创建。图 5 展示了一个例子。

图 5 - 分区环境中的一个实例
分区环境中的一个实例
分区环境中的一个实例

在图 5 中,三台 Linux 机器(Linux1、Linux2 和 Linux3)中的每一台机器上都已创建了实例“myInst”。myInst 映射到一个有相同名称的操作系统用户,在此图中它有一个主目录 /db2home/myInst。注意,/db2home/myInst 这个目录是由所有这三台 Linux 机器共享的,因为它驻留在 Linux3 中的一个共享磁盘上。既然该实例的主目录存放在 Linux3 机器本地,因而这台机器被认为是 DB2 实例属主机器。

图 5 还显示了 Database Administration Server (DAS) 用户 db2as 是在 DPF 环境中每台分区的机器上本地创建的。不管机器上所包含的分区有多少个,每台物理机器上只能有一个 DAS。DAS 用户的主目录不能放置在共享磁盘上。有一种选择是,使用不同的用户 id 和口令在不同机器上创建 DAS。

注意:在 DPF 环境中的每台分区机器上,应确保实例的口令是一致的,否则分区的系统看上去就像被挂起一样,因为各分区之间不能相互交谈。

实例属主机器

前面已指出,在 DPF 环境中,DB2 实例属主机器是拥有物理地存有实例主目录的磁盘的机器。图 3 所示的实例属主机器在主目录中的 sqllib 目录或该目录的子目录下有一些文件:

  • 实例级概要注册表(instance level profile registry)。
  • 数据库管理器配置文件(dbm cfg)。
  • System db 目录。
  • Node 目录。
  • DCS 目录。

如果更改了这些文件中任何参数的值或连通性信息,那么参与该环境的所有机器都将能够看到更改,因为只是更新了一个共享的文件。例如,如果在 Linux1 这台机器上通过下面的命令将 dbm cfg 参数 intra_parallel 的值从 NO 改为 YES:

db2 update dbm cfg using intra_parallel yes

然后在 Linux2 机器上发出以下命令:

db2 get dbm cfg

那么就可以从 Linux2 看到更改生效了,因为只是更新了物理地存放在机器 Linux3 上单独的一个共享文件。从任何分区发出这些命令都将影响在 db2nodes.cfg 文件中指定的所有分区。在 Linux/UNIX 环境中,您将收到来自每个分区的消息。 案例学习 这一节将演示如何执行上述操作。

将一个数据库分区

为了将数据库“分区”,在每台参与该环境的不同机器上以相同的名称本地创建一个目录。以图 1 为例,假设已经在每台机器的本地上创建了目录 /data。然后,执行命令:

create database MYDB2 on /data

就会自动建立下面的目录结构:

/data/<instance name>/NODExxxx/SQLyyyyy

其中:

/data: 在 create database 命令中指定的目录。在执行 create database 命令之前,这个目录必须已经存在。

<instance name>: 实例名。例如“myInst”。

NODExxxx: 用于区分将要使用哪个分区,其中“xxxx”代表在 db2nodes.cfg 文件中所指定的分区号,在本文的后面我们将讨论这个文件。

SQLyyyyy: 用于标识数据库,其中“yyyyy”代表一个号码。如果在系统中只创建了一个数据库,那么 yyyyy 就等于 00001,如果在系统中有 3 个数据库,那么就有三个不同的目录:SQL00001、SQL00002 和 SQL00003。为了将数据库名映射到这些目录上,可以使用以下命令查看本地数据库目录:

db2 list db directory on /data

在 SQLyyyyy 目录中,存在一些用于表空间的子目录,而这些子目录中的文件又包含数据库数据(假设所有表空间都被定义为 SMS)。图 6 展示了分区的数据库的一个可视化例子。

图 6 - 在 /data 目录中创建的一个分区的数据库
在 /data 目录中创建的一个分区的数据库

在 /data 目录中创建的一个分区的数据库

如果没有在 create database 命令中指定路径,那么就会默认地在由 dbm cfg 参数 DFTDBPATH 指定的目录中创建数据库,这个目录默认为实例属主机器的主目录。于是在此场景中创建的目录结构如下:

/db2home
   /myInst
      /NODE0000
          /SQL00001
      /NODE0001
          /SQL00001
      /NODE0002
          /SQL00001

这种分区并不是最佳的,因为所有数据库数据都放在一个与其他机器共享的磁盘上。在 DPF 环境中,按照这种方法创建数据库实际上违背了分区的本意。

注意:在创建数据库之前,应更改 dbm cfg 参数 DFTDBPATH 的值,或确保在 create database 命令中包括了一个路径。不管采用何种方式,DFTDBPATH 或路径都应指向在 DPF 系统中所有参与的机器上以相同名称本地创建的一个目录。这个目录必须提前创建好。同样,为了创建 SAMPLE 数据库,需在命令中指定路径,如下所示:db2sampl <path>

DPF 环境中的配置文件

在前一节中我们已指出,实例级概要注册表、数据库管理器配置(dbm cfg)文件、系统数据库目录、节点目录和 DCS 目录都是实例属主机器的一部分,它们是没有被分区的。那么,对于其他配置文件,情况又是怎样呢?

环境变量:
在分区的环境中,每台参与进来的机器都可以有不同的环境变量。

全局级概要注册表(global level profile registry)变量:
存放在文件 default.env 中,该文件位于 /var 下的一个子目录中。对于每台机器,都存在该文件的一个不同的本地副本。

数据库配置文件(db cfg):
db cfg 存放在文件 SQLDBCON 中,该文件位于所指的数据库的相应目录中。在分区的数据库环境中,对于每个数据库分区都存在一个单独的 SQLDBCON 文件。

本地数据库目录:
本地数据库目录存放在所指的数据库相应目录下的 SQLDBDIR 文件中。本地数据库目录的目录名与系统数据库目录相同,系统数据库目录存放在实例目录中。对于每个数据库分区都存在一个独立的 SQLDBDIR 文件。

注意:全局级概要注册表变量、数据库配置文件参数以及本地数据库目录条目等的值在每个数据库分区上可能不相同,不过我们还是建议这些值在所有分区上都应该是相同的。

DPF 环境中的日志

每个数据库分区都应该独立地维护自己的日志。因此,每个分区中的 db cfg 参数“path to log files”不应该都指向共享磁盘目录,而应该指向本地目录。在每个分区中,默认的日志路径将包括一个 NODE000x 子目录,作为该日志路径的一部分。例如,在图 3 中所示的 DPF 环境中,这个参数的值是:

For Partition 0:  /datalogs/db2inst1/NODE0000/SQL00001/SQLOGDIR/
For Partition 1:  /datalogs/db2inst1/NODE0001/SQL00001/SQLOGDIR/
For Partition 2:  /datalogs/db2inst1/NODE0002/SQL00001/SQLOGDIR/

如果要手动地更新这个路径,可以使用 db cfg 参数 NEWLOGPATH。在后面的小节中我们将看到,db2_all 这个命令只需执行一次就可以影响所有分区。

编目分区

当创建一个数据库时,也会默认地创建一些表空间。其中有一个表空间就是 SYSCATSPACE,它包含了 DB2 编目(Catalog)。在 DPF 环境中,SYSCATSPACE 不能分区,但是它必须驻留在一个分区内,这个分区就是编目(Catalog)分区。发出 create database 命令时所在的那个分区就成为新数据库的编目分区。所有对系统表的访问都必须经过这个数据库分区。

图 3 展示了驻留在 Linux1 机器上的 SYSCATSPACE,create database 命令就是从这个分区发出的,因而它就成为编目分区。如果要为某个特定实例创建了多个数据库,那么应确保从不同分区发出 create database 命令,以使得这些数据库相应的编目表都创建在不同的分区上。

对于一个已有的数据库,可以通过发出命令 list db directory 来确定哪个分区是编目分区。该命令的输出就是每个条目的“Catalog database partition number”字段,该字段表明了给定数据库的编目分区号。有一种选择是,您可以从不同机器连接到数据库,然后发出 list tablespaces show detail 命令。只有编目分区会显示 SYSCATSPACE 表空间。

分区组

分区组是一个逻辑层,它允许将一个或多个分区组成一组,以便对该组中的所有分区统一执行某些操作。一个数据库分区可以同时属于多个分区组。当创建一个数据库时,DB2 将创建三个默认的分区组,这三个组是不能删除的:

  • IBMDEFAULTGROUP: 这是用于您所创建的任何表的默认分区组。它由在 db2nodes.cfg 中定义的所有数据库分区组成。这个分区组不能修改。表空间 USERSPACE1 就是在这个分区组中创建的。
  • IBMTEMPGROUP: 所有系统临时表将使用这个分区组。它也是由 db2nodes.cfg 中定义的所有数据库分区组成的。表空间 TEMPSPACE1 就是在这个分区组中创建的。
  • IBMCATGROUP: 这个分区组包含编目表(表空间 SYSCATSPACE),因此,它只包括数据库的编目分区。这个分区组不能修改。

要创建新的数据库分区组,可以使用 create database partition group 语句。该语句将在数据库中创建数据库分区组,将指定的数据库分区指派给这个分区组,然后在数据库系统编目表中记录下该分区组的定义。

例如,下列语句将在 db2nodes.cfg 文件中指定的所有分区上创建一个分区组“pgrpall”:

create database partition group pgrpall on all dbpartitionnums

要创建由分区 2 和分区 3 组成的数据库分区组“pg23”,可以发出下面这个命令:

create database partition group pg23 on dbpartitionnums (2,3)

其他相关的分区组语句/命令有:

  • alter database partition group,该语句用于添加或删除组中一个分区。
  • drop database partition group,该语句用于删除一个分区组。
  • list database partition group,该命令用于列出所有分区组(IBMTEMPGROUP 不会列出)。

DPF 环境中的缓冲池

在图 3 中,我们展示了分布在不同分区上的缓冲池。解释这个图时,对于缓冲池的解释不同于其他对象,因为缓存在缓冲池中的数据不是像图中隐含的那样分区的。实际情况是,在 DPF 环境中,缓冲池可以根据不同的分区来量身定做。通过使用带有 DATABASE PARTITION GROUP 子句的 CREATE BUFFERPOOL 语句,可以将一个缓冲池与一个给定的分区组关联起来。这意味着,您可以灵活地为分区组中定义的特定分区来定义缓冲池。此外,在分区组中每个分区上缓冲池的大小也可以因需求而变化。例如,下面的语句将在分区组“pg1”中创建缓冲池“bpool_1”,我们假设这个分区组由分区 2、3 和 4 组成:

CREATE BUFFERPOOL bpool_1 DATABASE PARTITION GROUP pg1 1 
       SIZE 10000 
      EXCEPT ON DBPARTITIONNUM (3 TO 4) SIZE 5000

分区组 pg1 中的每个分区上将定义一个缓冲池 bpool_1,其大小是 10000。分区 3 和 4 将有一个大小为 5000 的缓冲池。我们使用一个类比,假设在每个分区上单独地发出 CREATE BUFFERPOOL 语句,其中每个分区上缓冲池的名称是一样的,但是指定不同的大小,那么相应的语句就是:

在分区 2 中:   CREATE BUFFERPOOL bpool_1 SIZE 10000 
在分区 3 中:   CREATE BUFFERPOOL bpool_1 SIZE 5000 
在分区 4 中:   CREATE BUFFERPOOL bpool_1 SIZE 5000

注意,上述语句是为了让类比清晰化,执行以上所示的这些语句时,系统将试图使用所有分区创建一个缓冲池。这与使用 CREATE BUFFERPOOL 的 DATABASE PARTITION GROUP 子句有所不同。

此外,缓冲池可以与多个分区组相关联。这意味着,缓冲池的定义将被应用于给定的相关分区组中的所有分区。

DPF 环境中的表空间

可以在一些特定的分区中创建表空间,方法是将该表空间与一个给定的分区组相关联。我们可以使用带有 IN DATABASE PARTITION GROUP 子句的 CREATE TABLESPACE 语句来实现。该语句允许用户灵活地指定使用哪些分区来实际地存储他们的表。例如,语句:

CREATE REGULAR TABLESPACE mytbls IN DATABASE PARTITION GROUP pg1 
   MANAGED BY SYSTEM USING (' data'   BUFFERPOOL bpool_1

创建表空间 mytbls,这个表空间横跨分区 2、3 和 4(假设 pg1 是由这些分区组成的分区组)。此外,该表空间与前面一节中定义的缓冲池 bpool_1 相关联。注意,如果提供了表空间和相关缓冲池之间有冲突的分区信息,那么该表空间的创建将会失败。例如,如果缓冲池 bpool_1 是为分区 5 和 6 创建的,而表空间 mytbls 是为分区 2、3 和 4 创建的,那么在创建这个表空间时就会发生错误。

协调节点

通常,对于每个数据库连接,都会有一个相应的 DB2 代理来执行 DB2 工作。代理可以看作是一个进程(在 Linux/UNIX 中)或者是一个线程(在 Windows 中),它代表应用程序执行 DB2 工作。有很多不同类型的代理,其中有一种就是协调代理(coordinator agent)。协调代理与应用程序通信,接收请求和发送回复。它可以要么自己满足请求,要么将工作委托给多个子代理来处理请求。

一个给定应用程序的协调节点就是协调代理所在的那个分区。协调节点也可以用 SET CLIENT CONNECT_NODE 命令来设置。当应用程序发出一个查询时,协调节点将这些数据库请求的各部分发送给其他分区上的一些子代理,而来自其他分区的所有结果在发送回应用程序之前,又会在协调节点上合并起来。

任何分区都可能成为协调节点,因此在图 3 中,我们没有专门指出哪一个分区作为协调节点。如果想知道更多关于 DB2 代理和 DB2 进程模型的信息,请参阅本文参考资料那一节。

在 DPF 环境中发出命令和 SQL 语句

假设有 20 台物理机器,每台机器上有 2 个分区。如果要向每台物理机器或分区发出一条条的命令,那么任务量就比较可观了。幸运的是,DB2 提供了两个主命令,这两个命令可以执行所有机器或分区上的其他命令:

rah:
当想要为每台物理机器执行另一个命令时,就可以使用这个命令。例如,如果想为 20 台物理机器创建一个目录,那么可以发出下面的命令:

rah ")mkdir /tmp/$USER"

其中 ' ' 字符表明在 $RAHENV 中指定的用户概要表和文件是被限制长度的。另外,还可以使用一些其他字符。要得到对这些字符的解释,可以发出命令: rah ?

db2_all:
当想为每个数据库分区执行另一个命令时,就可以使用这个命令。例如,如果想更改每个分区中 SAMPLE 数据库的 db cfg 参数 logfilsiz,就可以发出以下命令:

db2_all ";db2 UPDATE DB CFG FOR sample USING LOGFILSIZ 500"

如果分号(;)字符放在双引号里面,那么请求就会在所有分区上同时运行。在 db2_all 命令中可以使用的字符与 rah 命令中可以使用的字符是一样的。

对于 rah 或 db2_all,执行的命令几乎可以是您在交互提示符下能输入的任何东西,包括依次执行的一些命令。在 Linux 和 UNIX 平台上,可以使用分号(;)隔开多个命令。在 Windows 上,可以使用“和”符号(&)隔开多个命令。但是在最后那个命令后面不要使用分隔符字符。

命令和 SQL 语句的作用域
一个命令(例如 db2 get db cfg,db2 list tablespaces 等等)的作用域受限于会话所依附的分区。
对于以 db2_all 打头的命令,其作用域就是从 db2nodes.cfg 中可以得到的整个分区列表。
一条 SQL 语句的作用域是 db2nodes.cfg 文件中所有分区的集合(如果使用了 WHERE DBPARTITIONNUM= 谓词则另当别论)。

使用数据库分区表达式
在一个分了区的数据库中,如果有不止一个数据库分区驻留在同一台物理机器上,则不能为这些数据库分区指定相同的设备或路径。您可以手动地指定一个惟一的容器来存放每个数据库分区,或者也可以在命令或语句中使用数据库分区表达式,以根据 db2nodes.cfg 文件中的分区号生成一些值。下面的例子应该可以澄清这一概念:假设您发出了如下命令:

CREATE TABLESPACE TS2 
       MANAGED BY DATABASE USING
       (file ' data/TS2/container $N+100' 5000)


在一个由 4 个数据库分区组成的系统中,上述命令将创建下面几个容器:

/data/TS2/container100 - on DATABASE PARTITION 0
/data/TS2/container101 - on DATABASE PARTITION 1
/data/TS2/container102 - on DATABASE PARTITION 2
/data/TS2/container103 - on DATABASE PARTITION 3

数据库分区表达式是由参数 ' $N (注意在 $N 之前有一个空格)指定的。表 1 展示了用于创建容器的其他一些参数。运算符是从左往右计算的,其中 ' ' 代表模数(除法的余数)。假设我们所指的分区号是 3,在表 1 中“值”列显示了解析数据库分区表达式所得到的结果。

v

数据库分区表达式

例子

[空格]$N

" $N"

3

[空格]$N+[数字]

" $N+500"

503

[空格]$N%[数字]

" $N%2"

1

[空格]$N+[数字]%[数字]

" $N+15%13"

5

[空格]$N%[数字]+[数字]

" $N%2+20"

21

DB2NODE 环境变量

在本系列的 第 1 部分 中,我们谈到了环境变量 DB2INSTANCE 用于在数据库系统中不同实例之间进行切换。环境变量 DB2NODE 的用途也是类似的,但它是用于在 DPF 系统中的不同分区之间切换。默认情况下,对于给定服务器,活动分区是在 db2nodes.cfg 文件中以逻辑端口 0 定义的那个分区。为了切换活动分区,在 Windows 中可以使用 SET 命令,在 Linux/UNIX 中可以使用 export 命令。在更改了这个变量以后,应确保终止从任何分区到数据库的所有连接,否则所作的更改就不能生效。

例如,使用图 4 中所示的 db2nodes.cfg 文件,您有 4 台服务器,每台服务器上有 2 个逻辑分区。如果登录到了服务器 myserverb,那么您所执行的任何命令将影响到分区 2,分区 2 也就是拥有逻辑端口 0 的那个分区,当然这个分区就是那台服务器的活动分区。如果要将分区 0 切换成活动分区,那么在 Linux 系统中可以这样来更改:

DB2NODE=0
export DB2NODE
db2 terminate

(仅仅是不存在来自任何分区的连接还不够,还应确保发出了“terminate”命令)。

注意,分区 0 是在服务器 myservera 中。我们甚至可以使这个分区成为服务器 myserverb 的活动分区。为了确定哪一个是活动节点,您可以在连接到一个数据库后发出如下语句:

db2 "values (current dbpartitionnum)"

分区图和分区键

至此,您应该对如何设立一个 DPF 环境有一个较好的理解了。现在是时候来理解如何跨不同分区执行数据行的分发了。图 7 展示了这种分发的一个例子。

图 7 - 在 DPF 环境中分发数据行
在 DPF 环境中分发数据行
在 DPF 环境中分发数据行

分区图(partitioning map)是内部生成的一个数组,它或者包含对应于多分区数据库分区组的 4,096 个条目,或者包含对应于单分区数据库分区组的一个条目。数据库分区组里的分区号是以一种循环(round-robin)方式指定的。

分区键(partitioning key)是一个列(或者一组列),用于确定某一行特定数据所在的那个分区。分区键是在一个表上使用 CREATE TABLE 语句来定义的。

当创建或修改一个数据库分区组时,会有一个分区图与之关联。DB2 使用分区图再加上分区键以及散列算法(hashing algorithm)来确定数据库分区组中哪一个数据库分区将存储给定的一行数据。

对于图 7 中的例子,假设我们已经在分区 0、1、2 和 3 上定义了分区组“pg0123”。这样将自动创建一个关联的分区图,也就是拥有 4096 个条目的一个数组,这些条目包含值 0,1,2,3,0,1,2,3... (默认情况下,分区号以循环的方式存储,不过这可以更改)。另外再假设已经创建了表“mytable”,它有一个分区键,这个分区键由 col1、col2 和 col3 这三列组成。对于每一行,分区键各列的值被传递给散列算法,散列算法将返回从 0 到 4095 的一个输出数字。这个数字对应于在分区图数组中的一个条目,这个条目包含了这一行数据所在分区的分区号的值。在图 5 中,如果散列算法返回了一个输出值 7,那么这一行就是存放在分区 p1 中。

案例学习

现在您已经熟悉了 DPF,让我们通过一个案例学习来回顾一下本文中的所有概念。

假设您的公司正在扩张,最近又买下了两家其他的公司。由于数据大约是呈两倍增长的,您想知道当前的单分区 DB2 数据库服务器是否能够处理负载,还是需要 DB2 with DPF。由于您不大熟悉 DB2 with DPF,于是决定使用测试机器来先试一试:用于测试的有两台 SMP 机器,每台机器有 4 个处理器,两台机器都运行 Linux 操作系统。之前的 DBA 已经在这两台机器上安装了 DB2 UDB ESE with DPF。他已经离开了公司,幸好他留下了如图 8 所示的图,其中有他的设计。

图 8 - DB2 UDB ESE with DPF - 一个案例学习
DB2 UDB ESE with DPF - 一个案例学习
DB2 UDB ESE with DPF - 一个案例学习

图 8 是物理和逻辑设计的结合。当您用自己的系统所具备的东西来核实这个图的正确性时,您注意到“mydb1”数据库已经被删除,因此决定重建这个数据库,作为一种实践。而实例“db2inst1”以及其他数据库仍在那里。下面是您所遵循的步骤:

1. 打开两个 telnet 会话,每台 SMP 机器使用一个会话。从其中的一个会话中,发出 db2stop 命令,之后是 db2start 命令,如图 9 所示。

图 9 - db2stop 和 db2start
db2stop 和 db2start
db2stop 和 db2start

首先注意到的是,对于这两个命令,没有必要从每个分区上发出它们。只需从任何分区发出这两个命令一次,就可以影响到所有分区。您还可以知道存在 4 个分区,因为您将从每个分区收到一条消息。

2. 接着,您想查看 db2nodes.cfg 文件,以检查分区的配置。通过使用一些操作系统命令,确定实例 db2inst1 的主目录,在这个例子中就是 /db2home/db2inst1。因而,文件 db2nodes.cfg 就存放在目录 /db2home/db2inst1/sqllib 中。这个文件的内容如图 10 所示。

图 10 - db2nodes.cfg
db2nodes.cfg
db2nodes.cfg

图 10 显示了这里有 4 个分区,每台服务器上两个分区。服务器的主机名是 65658572 和 65658161。

3. 再接着,您想创建数据库“mydb1”,但是想从分区 0 发出这个命令,因为您想让这个分区成为编目分区。所以您从会话中发出语句 db2 "values (current dbpartitionnum)" 来确定哪个分区是当前的活动分区。接下来再将环境变量 DB2NODE 改为 0。

就在创建这个数据库之前,您还需检查 dbm cfg 参数 DFTDBPATH 的值。这就是默认情况下这个数据库创建时所在的路径。您希望在所有分区中本地创建所指定的路径(在这个例子中就是 /db2database ),以便将数据分布在这些分区中。通过使用操作系统命令,您证实了情况正是如此,于是继续创建数据库。如图 11 所示。

图 11 - 确定并切换活动分区,然后创建数据库
确定并切换活动分区,然后创建数据库
确定并切换活动分区,然后创建数据库

4. 为了证实分区 0 的确是编目分区,只需发出一条 list db directory 命令,然后在对应于“mydb1”数据库的条目下找到“Catalog database partition number”字段。另外,也可以从每个分区上发出一条 list tablespaces 命令。应该只有编目分区才会列出 SYSCATSPACE 表空间。

5. 接下来,您需要在分区 2 和 3 上创建分区组 pg23。图 12 展示了如何完成这一任务。此外,该图还展示了如何列出分区组。这个命令不能列出 IBMTEMPGROUP。

图 12 - 创建分区组 pg23
创建分区组 pg23
创建分区组 pg23

6. 现在您想要创建和管理缓冲池。为了在分区组 pg23 上创建缓冲池 BP23,可以发出如下命令:

db2 "create bufferpool BP23 database partition group pg23 size 500 "

图 13 展示了该条语句。这个图还展示了如何使用 altER BUFFERPOOL 语句将此缓冲池与另一个分区组关联起来。

为了列出缓冲池和相关联的分区组,可以查询 syscat.bufferpools 视图或者 sysibm.sysbufferpools 编目表。

图 13 - 管理缓冲池
管理缓冲池
管理缓冲池

注意,一个缓冲池可以与任何分区组相关联。缓冲池的定义将适用于分区组内的所有分区,如果需要的话,可以为分区指定不同的大小。

7. 为了创建表空间 mytbls1,可发出如下命令:

db2 "create tablespace mytbls1 in database partition group pg23 
         managed by system using ('/data') bufferpool bp23"

8. 为了在表空间 mytbls1 中创建带有分区键 col1 和 col2 的表 table1,可发出如下命令:

db2 "create table table1 (col1 int, col2 int, col3 char(10)) 
            in mytbls1  
            partitioning key (col1, col2)"

9. 对于 DPF 环境,创建索引 index1 时没什么特别之处:

db2 "create index index1 on table1 (col1, col2)"

在每个分区上,都要为其数据行的子集构造该索引。

10. 接下来,假设您想如图 14 中所示的那样,使用带有 INTRA_PARALLEL YES 的命令 update dbm cfg 将参数 INTRA_PARALLEL 从 NO 更新为 YES。这里也应注意,与此同时还发出了 get dbm cfg 命令,只不过这个命令是从另一个 telnet 会话中发出的。这个参数值的更新版本显示在任何分区上,这说明您更新的是一个共享文件。

图 14 - Update dbm cfg
Update dbm cfg
Update dbm cfg

11. 然后,您想测试一下 db2_all 命令,以便只用一个命令就为所有分区更新 db cfg 文件。图 15 展示了一个例子。在该图中的第二个窗口显示了在一个没有执行过 db2_all 命令的分区上执行 db2_all 命令之前和之后的 get db cfg。

图 15 - 使用 db2_all 更新 db cfg
使用 db2_all 更新 db cfg
使用 db2_all 更新 db cfg

12. 您最后想测试的就是 rah 命令。图 16 展示了一个使用 rah 创建子目录的例子。

图 16 - 使用 rah
使用 rah
使用 rah

您可以看到,rah 命令在每台机器上工作,而 db2_all 命令则是在每个数据库分区上工作。

大功告成!

致谢

特别感谢 Bill Wilkins (IBM Content Management Partner Enablement 顾问)和 Scott Martin (IBM Innovation Center for Business Partners 顾问),他们对本文进行了技术性的审校。


相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Information Management
ArticleID=57698
ArticleTitle=对具有数据库分区功能的 DB2 UDB for Linux, UNIX and Windows Version 8 的生动介绍(第 2 部分)
publish-date=05012004