DB2数据库

概述

安装与配置

实例

在安装完DB2数据库后,首先需要做的就是创建实例。因为要创建数据库,就必须先创建实例,数据库是运行在实例之上的。

实例的概念

从DB2体系结构的方面来看,实例实际上就是DB2的执行代码和数据库对象的中间逻辑层。实例可以看成关于所有的数据库及其对象的逻辑集合,也可以认为是所有的数据库及其对象和DB2代码之间的联系和结合。实例为数据库运行提供环境。这样一来,数据库只负责前台正常的运行,而一些后台的事情由实例来进行管理。实例对用户和开发人员来说是透明的。实例本质上由一组后台进程和共享内存组成。实例和数据库不一样的地方是,数据库是物理的,我们的表、索引存放在数据库中是要占用物理存储的;而实例是逻辑的,是共享内存、进程和一些配置文件(实例目录)的集合。当实例停止时,共享内存释放,进程停止。实例就相当于windows中服务的概念。

在实际生产系统中,我们可能需要创建多个实例来执行下列操作:

  • 将一个实例用于开发环境,而将另一个实例用于生产环境
  • 为特定环境调整实例
  • 限制存取机密信息
  • 控制为每个实例指定SYSADM、SYSCTRL、SYSMAINT和SYSMON权限
  • 优化每个实例的数据库管理器配置
  • 限制实例故障的影响。如果发生实例故障,那么只有一个实例受影响,其他实例可以继续正常工作

当然,系统中的实例不是越多越好,如果在系统中创建的实例过多,不仅会造成额外的资源消耗(内存、硬盘空间等),还会增大管理开销。过多的实例数量可能会有下面的影响:

  • 每个实例都需要额外的系统资源(虚拟内存和磁盘空间)
  • 由于要管理其他的实例,因此增加了管理工作量
  • 更多管理任务,因为要管理附加实例

注意:

在许多数据库产品中都有类似实例的这个概念,例如在Oracle中也叫实例(instance),在Informix数据库中有Server的概念,Sybase和SQL Server中的Server概念也和实例类似。

创建实例

在Linux/UNIX上,要想创建实例,就必须首先创建和实例名一样的用户及该用户所属的组。之所以需要创建用户,主要是因为需要以该用户的home目录作为实例目录,存放实例相关的实例目录结构。

实例可以在DB2向导安装期间创建,但业务需求可能需要我们手工创建其他实例。创建实例需要使用db2icrt(db2 Instance Create)命令,db2icrt命令的语法如下所示:

有一点我们需要特别注意,在Linux和UNIX上创建实例时,必须有和实例同名的用户存在。如果该用户不存在,那么创建实例会报错而无法创建。如果用户存在,确保该用户未被锁定并且密码未到期。

使用db2icrt命令创建实例的步骤如下:

  1. 使用root权限登录;
  2. 首先利用操作系统命令(mkuser、useradd;mkgroup、groupadd)创建实例的用户和组,一般来说我们需要创建下表所示的用户和组并设置密码。下表中的用户名和组名是使用db2安装向导期间由db2默认生成的。实际生产中,我们可以根据自己需要创建自己特定的组名和用户名,此处仅为说明作用。

用户

示例用户名

示例组名

实例所有者

db2inst1

db2iadm1

受防护的用户

db2fenc1

db2fadm1

  • 实例所有者的home目录(例如为/home/db2inst1)是将其中创建实例目录的位置。
  • 受防护的用户(db2fenc1)用于在db2数据库所使用的地址空间之外运行用户定义的函数(UDF)和存储过程。这个用户和应用开发有关,通常没有什么用,但是作为创建实例却是必须的。很多初学者往往被这个用户迷惑,其实不创建这个用户,也可以使用实例用户作为受防护的用户。但是从应用程序安全和维护角度而言,建议创建这个用户。
  1. 运行db2icrt命令。例如,在Linux或UNIX操作系统上:

DB2DIR/instance/db2icrt -a AuthType -u FencedID InstName

其中,DB2DIR是db2安装目录。在Linux/UNIX操作系统上,默认的db2安装目录是/opt/IBM/db2/v10.5。

-a AuthType(linux或unix)

表示实例的认证方式。AuthType可为SERVER、CLIENT、SERVER_ENCRYPT其中之一。SERVER是默认值。此参数是可选的,这些认证类型和安全有关。

-u FencedID

表示将用来运行受防护用户定义的函数(UDF)和受防护存储过程的用户的名称。这个用户和应用开发有关,虽然通常用不到,但对于创建实例是必须的。

InstName

表示实例的名称。实例的名称必须与拥有实例的用户的名称相同。指定创建的拥有实例的用户的名称。在拥有实例的用户的主目录中创建该实例。

例如,如果正在使用服务器认证,受防护用户为db2fenc1,并且拥有实例的用户为db2inst1,那么使用以下命令在AIX系统上创建实例:

/opt/IBM/db2/V10.5/instance/db2icrt -a server -u db2fenc1 db2inst1

db2icrt命令除了上述必需选项外,还有一些可选选项,如下所示∶

  • -s 指定所创建实例的类型,有以下几种类型∶
  • dsf 支持 DB2 pureScale 特性的数据库服务器。
  • ese 用于创建具有 DPF支持的 DB2数据库服务器的实例,DB2数据库服务器带有本地和远程客户机。此类型是 DB2企业服务器版的默认实例类型。
  • wse 用于创建 DB2数据库服务器的实例,DB2数据库服务器带有本地和远程客户机。此类型是 DB2工作组版、DB2易捷版或 Expres-C版的默认实例类型。
  • standalone 用于创建 DB2数据库服务器的实例,DB2数据库服务器带有本地客户机。此类型是 DB2个人版的默认实例类型。
  • client 用于创建IBM数据库服务器客户机的实例。
  • -p 如果想要在不同于DB2PATH的路径中创建目录,那么输入db2icrt命令之前必须设置环境变量 DB2INSTPROF。
  • -u 用于指定 DB2服务的账户名和密码,创建 ese 实例时需要此选项。
  • -h 用于覆盖默认 TCP/IP 主机名。在创建默认节点(节点0)时,将使用TCP/IP 主机名。
  • -r 用于指定当在 MPP(数据库分区)方式下运行时,分区数据库实例要使用的一系列TCP/IP 端口。如果指定此选项,那么本地机器的 services 文件将使用下列条目进行更新∶

DB2_InstName baseport/tcp

DB2 InstName_1 baseport+1/tcp

DB2_InstName_2 baseport+2/tcp

DB2_InstName_END endport/tcp

2.1.3 实例目录

实例创建后,会生成实例目录,实例目录存储着与数据库实例相关的所有信息。实例目录一旦创建,就不能更改其位置。在Linux/UNIX中为了拥有实例目录,必须创建和实例名相同的用户,其最终目的是为了以这个用户的 home 目录作为实例目录。

实例目录包含∶

  • 数据库管理器配置文件(db2systm)
  • 系统数据库目录(SQLDBDIR)
  • 节点目录(SQLNODIR)
  • 节点配置文件(db2nodes.cfg),db2nodes.cfg 文件用来定义参与 DB2 实例的数据库分区服务器。如果想要将高速互联用于数据库分区服务器通信, 那么还可以使用db2nodes.cfg 文件来指定高速互联的IP 地址或主机名。
  • 诊断文件、数据库错误日志等。

Linux/UNIX操作系统上,实例目录位于INSTHOME/sqllib 目录中,其中INSTHOME是实例所有者的主目录,图2-1是实例db2inst1的实例目录。

在 Windows 操作系统上,实例目录位于安装了DB2数据库产品的目录下。实例名与服务名相同,因此应该不会发生冲突。实例名不应与别的服务名相同。你必须有创建服务所需的正确权限。可在 DB2PATH中使用 DB2INSTPROF 环境变量更改实例目录的位置,这需要实例目录的写访问权。如果想要在不同于 DB2PATH 的路径中创建目录,那么输入db2icrt 命令之前必须设置DB2INSTPROF。

实例目录非常重要,下面我们举例来说明实例目录。在讲这个例子之前,我们先讲解一下 db2set命令,之所以讲解这个命令是因为我们特殊定制实例时,需要用到这个命令。我们都知道,在操作系统中可以使用 set、setenv 或 export命令来修改操作系统的环境变量。同样DB2实例本身也有实例级别的注册变量,为了修改这些默认的变量,我们使用 db2set 命令——在 set 前加上db2 以表示设置 DB2级别的变量。这个命令使用起来很简单。

要查看已经设置的注册变量,请从命令行执行下面这个命令∶

db2set -al1

你可能会得到类似下面这样的输出∶

C:\>db2set -all

[e] DB2PATH=C:\Program Files\IBMySQLLIB

[i]DB2INSTPROF=C:\DOCUMENTS AND SETTINGS\ALL USERS\APPLICATION DATA\IBM\DB2cOPY1

[g] DB2ADMINSERVER=DB2DASO0

正如你可能已经猜测到的那样,[i]表明该变量是在实例级别定义的,而[g]表明是在全局级别为系统中所有实例定义的;[e]表示是操作系统级别的环境变量。

要查看可以在 DB2中进行定义的所有注册变量,请使用下面这个命令∶

db2set -1r

要在全局级设置特定变量(在下面这个示例中为 DB2INSTPROF)的值,请使用∶

db2set DB2INSTPROF="C:\INSTDIR" -g

要在实例级为实例"DB2"设置变量,请使用∶

db2set DB2INSTPROF="C:\MY FILES\SQLLIB" -i DB2

请注意上面的示例,在两个级别(实例级和全局级)设置了同一个变量。当同一个注册变量在不同级别上进行定义时,DB2总是会选择最低级别的值;在本例中,将选择实例级的值。

注意∶

db2set 命令的等号(=)前后不该留有空格。某些注册变量为了使更改生效,要求停止和启动实例(db2stop/db2start,这两个命令后面会讲解)。另一些注册变量则没有这个要求。为了安全起见,建议在对注册变量作出更改后总是停止和启动实例。

现在你已经知道 db2set 命令的用法,下面首先设置 DB2INSTPROF注册变量,然后在Windows 上创建一个新的实例并查看这个实例的实例目录∶

C:\>db2set -all

[e] DB2PATH=C:\Program Files\IBM\SQLLIB

[i] DB2INSTPROF=C:\DOCUMENTS AND SETTINGS\ALL USERS\APPLICATIONDATA\IBM\DB2COPY1

......略

C:\>db2set DB2INSTPROF=C∶\INSTDIR --重新设置DB2INSTPROF注册变量

C:\>db2icrt prod --创建prod实例

DB20000I DB2ICRT命令成功完成

在创建完prod实例后,我们发现在 DB2INSTPROF目录下生成了一个和实例同名的目录。这就是实例PROD的实例目录,如图2-2所示。

实例创建后,我们可以发现在windows的服务面板中,多了一项刚创建实例名的服务。

这是因为在windows上实例是作为服务存在的,而在Linux/UNIX上,实例是作为一组后台进程存在的。

在Linux/UNIX上可以通过db2_ps 或ps -ef|grep -i db2sysc 查看db2进程的状态。

实例的相关命令

在实例创建后,可以执行实例相关的命令来管理实例。在使用实例之前,必须更新每个用户的数据库环境,以便该环境可以访问实例并运行DB2实例相关命令。在运行这些命令之前,首先要配置好实例的运行环境,这适用于所有用户(包括管理用户)。而且在执行这些命令时一定要确保具有足够的权限。实例相关的命令对权限要求很高,例如 db2icrt 和db2idrop需要root 权限才能执行。而除了这两个命令,其他实例命令需要具有SYSADM、SYSCTRL 或 SYSMAINT的权限才能运行。

1.配置实例的运行环境

我们都知道在 Linux/UNIX 环境中,在用户级上强制实施高安全策略时,与某个用户账户关联的文件和进程不能被其他用户直接访问。默认情况下,创建新的实例时,会在实例目录下生成特殊的 DB2 环境脚本 db2profile(Windows下为 db2profile.bat),每次实例所有者登录到系统时都要使用该文件配置其环境。这些脚本设置对数据库环境的访问,允许实例所有者执行 DB2命令。为了让系统上的其他用户访问实例和 DB2 环境,他们也必须运行同样的脚本,否则将无法访问 DB2 实例运行环境。如下所示是由于没有设置 DB2 实例运行环境而导致无法执行相关 DB2命令的例子∶

可以通过设置DB2实例所有者的.profile 文件(或是由.profile 文件引用的db2profile 文件)来配置其他用户的 DB2运行环境。如果使用 Bourne 或Korn shell,那么可以编辑目标用户账户的.profile 文件,使目标用户登录到系统时自动运行db2profile脚本(创建实例时默认会加到实例用户的.profile 文件中)。对于C shell用户,可以编辑.login 文件来运行 db2cshrc 脚本文件。为了选择要使用的实例的用户,请在用户的.profile 或.login 脚本文件中添加下列语句,或者在用户需要访问 DB2的终端窗口中执行下列语句(注意需要句点(.)和空格)∶

Bourne或Korn shell∶.INSTHOME/sqllib/db2profile----注意前面的"."INSTHOME

----是实例目录

C shell: source INSTHOME/sqllib/db2cshrc

当成功创建实例后,检查实例目录下的.profile 是否调用db2profile,如下所示∶

# The following three lines have been added by IBM DB2 instance utilities.

if [ -f INSTHOME/sqllib/db2profile ]; then

. INSTHOME/sqllib/db2profile

fi

在配置好 DB2的运行环境后,下面讲解一些实例相关的命令。

列出实例

db2ilist命令列出机器上的 DB2 实例∶

DS8K:/db2$ db2ilist

PROD

DEV

DB2

--系统中存在三个实例

更新实例配置

如果通过安装"程序临时性修订(PTF)"或补丁更新了数据库管理器,那么应使用db2iupdt 命令来更新所有现有数据库实例。

db2iupdt 命令可在 DB2PATH\bin目录中找到。要更新实例配置,请使用db2iupdt 命令。按如下所示使用该命令∶

db2iupdt InstName

/u:username, password

[/p:instance profile path]

[/r:baseport,endport]

[/h:hostname]

[/?]

[/q]

[/a:authType]

InstName 实例名

/u 用于指定 DB2服务的账户名和密码。当创建分区数据库实例时,此选项是必需的

/p 用于指定已更新实例的新的实例概要文件路径

/r 用于指定当在MPP方式下运行时,分区数据库实例要使用的一系列TCP/IP 端口。如果指定此选项,那么本地机器的 services 文件将使用下列条目进行更新∶ DB2_InstName baseport/tcp

DB2_InstName_END endport/tcp

/h 用于覆盖默认 TCP/IP 主机名 (假设当前机器有多个 TCP/IP 主机名)

/? 此用法信息

/q 安静方式

/a authType 是实例的认证类型(SERVER、CLIENT或 SERVER ENCRYPT))

示例∶如果在创建实例后安装了DB2 工作组服务器版或 DB2 企业服务器版,可输入以下命令来更新实例:

db2iupdt -u db2fencl db2inst1

注意∶

db2iupgrade和 db2iupdt 的区别是∶db2iupdt 通常是小版本打补丁,而 db2iupgrade 通常是大版本迁移。例如从DB2 V10.1到DB2 V10.5用 db2iupgrade,而从DB2 V10.5.1到DB2V10.5.2用db2iupdt。

2.自动启动实例

在Windows 操作系统中,默认情况下,安装期间创建的数据库实例设置为自动启动,使用db2icrt创建的实例设置为手动启动。要更改启动类型,需要转至"服务"面板并在其中更改 DB2服务的属性(手动或自动)。

在 UNIX 或Linux 操作系统中,要允许实例在每次系统重新启动后自动启动,请输入以下命令∶

db2iauto -on <instance name> --其中<instance name>是实例的登录名

在 UNIX 或Linux操作系统中,要阻止实例在每次系统重新启动后自动启动,请输入以下命令∶

db2iauto -off <instance name> --其中<instance name>是实例的登录名

  1. 启动实例

在正常业务操作期间,可能需要启动或停止DB2数据库。例如,必须启动一个实例,然后才能执行下列某些任务∶连接至该实例中的数据库、预编译应用程序、将程序包绑定至数据库或访问主机数据库。

在Linux或UNIX系统中,启动实例之前需要以具有SYSADM、SYSCTRL或SYSMAINT 权限的用户标识或名称进行登录;或者作为实例所有者登录。在 Windows 中启动实例,用户账户必须具有 Windows 操作系统定义的、用于启动 Windows 服务的正确特权。用户账户可以是 Administrators、Server Operators 或 Power Users 组的某个成员。启用了扩展安全性之后,默认情况下,只有DB2ADMNS 和 Administrators 组的成员才能启动数据库。

要使用命令行启动实例,请输入∶

db2start

在 Windows 中,db2start 命令将 DB2数据库实例作为 Windows 服务来启动。通过在调用db2start 时指定"/D"开关,仍然可以在 Windows 中将 DB2数据库实例作为进程运行。还可使用"控制面板"或 NET START命令将 DB2数据库实例作为服务启动。

4.连接至实例和从实例断开

在所有平台上,要与另一个可能是远程的数据库管理器的实例连接,请使用 ATTACH 命令。要从实例断开,请使用DETACH命令。

要使用命令行与实例连接,请输入∶

db2 attach to <instance name>

例如,要连接至节点目录中先前编目的称为 testdb2的实例∶

db2 attach to testdb2

再如,在对 testdb2实例执行维护活动后,要使用命令行从实例断开,请输入∶

db2 detach

或者输入∶

db2 terminate

注意∶

这两个命令在实际生产中很少用到,因为在 Linux/UNIX 环境中,每次都会通过某个用户登录操作系统,这已经隐含地连接了实例。

5.停止实例

我们有时可能需要停止数据库管理器的当前实例。要在Linux 或 UNIX 系统中停止实例,必须以具有 SYSADM、SYSCTRL 或 SYSMAINT 权限的用户标识或名称登录或连接至实例;或者作为实例所有者登录。在 Windows 中,停止实例的用户账户必须具有Windows 操作系统定义的正确特权。用户账户可以是 Administrators、Server Operators 或 Power Users 组的某个成员。在停止实例之前,要停止与数据库连接的所有应用程序和用户,要确保没有关键性的或极重要的应用程序在运行。

要使用命令行停止实例,请输入∶

db2stop

如果停止期间仍然有应用连接,这时会出现"数据库管理器未停止,因为数据库仍在活动"的错误∶

DS8K:/db2$ db2stop

2012-08-24 10:49:19 0 0 SQL1025N The database manager was not

stopped because databases are still active.

SQL1025N The database manager was not stopped because databases are still active.

如果要强制所有应用程序和用户与数据库断开,那么需要输入如下命令∶

db2stop force

这时,所有连接上数据库且未提交的应用被强制回滚。

在 Windows 中,除了使用命令行之外,还可以通过"控制面板-服务"或 NET STOP 命令停止实例。

2.1.5 DB2INSTANCE变量介绍

如果系统中有多个实例,那么如何在各个实例之间进行切换以及如何同时启动多个实例呢?这就需要使用DB2INSTANCE 环境变量。环境变量是操作系统层面的,是在操作系统级别上定义的变量。最常使用的DB2 环境变量是DB2INSTANCE,该环境变量允许指定当前活动实例,所有命令都将应用于该实例。例如,如果将 DB2INSTANCE设置成"PROD",那么发出命令"create database mydb"会创建出与实例"PROD"相关的数据库。但是如果想创建与实例"DB2"相关的数据库,那么首先必须将 DB2INSTANCE 变量的值更改成"DB2"。

可以使用控制面板(在 Windows中/db2profile(在 UNIX中)来设置环境变量的值,从而保证下次打开窗口/会话时改值不变。但是,如果想在给定的窗口/会话中临时更改该值,那么在Windows中可以使用操作系统的"set"命令,在UNX中可以使用"export"或"setenv"命令。例如,在Windows 平台上,下面这个命令∶

set DB2INSTANCE=DB2

会将环境变量DB2INSTANCE 的值设置成"DB2"。使用set 命令时常犯的错误是在等号(=)前后留有空格。绝对不能有空格!

要查看该变量的当前设置,可以使用下面三个方法中的任何一个∶

echo %DB2INSTANCE%(Windows only);echo SDB2INSTANCE(Linux/UNIX)

set DB2INSTANCE

db2 get instance

示例∶假设系统中有多个实例,下面举例说明如何通过设置 DB2INSTANCE 环境变量来启动多个实例。

C:\Program Eiles\IBM\SQLLIB\BIN>db2ilist

PROD

DEV

DB2

--系统中存在三个实例

C:\Program Files\IBMNSQLLIB\BIN>set DB2INSTANCE

DB2INSTANCE=DB2

--当前活动实例是DB2实例

C:\Program Files\IBM\SQLLIB\BIN>set DB2INSTANCE=PROD

C:\Program Files\IBM\SQLLIB\BIN>set DB2INSTANCE

DB2INSTANCE=PROD

C:\Program Files\IBM\SQLLIB\BIN>db2 get instance --当前数据库管理器实例是 PROD

--db2 get instance 命令用来判断当前在哪个实例下

C:\Program Files\IBM\SQLLIB\BIN>db2start --这时启动的是prod实例

其实,DB2INSTANCE环境变量类似Oracle 中的变量ORACLE_SID、Informix中的变量INFORMIXSERVER,主要用于在多个实例间进行切换。这个变量在 Windows中很常用,在 Linux/UNIX中由于每个实例都有同名的用户,因此当使用这个用户登录时已经隐含地连接了这个实例。所以相对来说在Linux/UNIX中很少用到这个变量。

2.1.6 删除实例

要删除实例,必须具有root权限,在windows中必须具有系统管理员权限。删除实例之前,确保所有的应用已经断开实例并且实例已经停止。

要使用命令行删除实例,请输入:

db2idrop <instance name>

db2idrop命令从实例列表中删除实例条目,并删除实例所有者 home 目录下的sqllib子目录。所以删除实例时千万要小心,如有必要请在删除实例之前备份实例目录。

注意∶

在 Linux/UNIX操作系统中,试图使用 db2idrop命令删除实例时,会生成一条消息,说明不能删除 sqllib子目录,并且正在 adm子目录中生成几个具有.nfs 扩展名的文件。adm 子目录是安装了NFS的系统,而这些文件在服务器上是受控的。必须从安装目录的文件服务器中删除*.nfs 文件,然后方可删除 sqllib子目录。

2.1.7 配置实例

每个实例在创建后,都有实例配置文件(db2systm),实例配置文件控制实例的安全、通信、管理和资源的分配。可以根据需要查看、更改和复位这个配置参数。这个配置文件是二进制的,只能通过命令来修改。

可使用db2 get dbm cfg 命令来查看当前实例的配置参数。

要查看当前实例配置参数的当前值,请输入∶

db2 get dbm cfg

这会显示在安装该产品期间指定为默认配置参数的当前值,或在先前更新配置参数期间指定的那些值。

可在命令行使用 update dbm config 更新实例配置文件。要更新实例配置文件中的个别条目,请输入∶

db2 update dbm cfg using ..

要将配置参数复位为建议的默认值,请输入∶

db2 reset dbm cfg

在某些情况下,对实例配置文件的更改仅在将更改装入内存后才生效(在执行 db2stop 之后,执行db2start 时生效)。

关于实例配置文件,已超出了本章的讨论范围,我们会在后面的章节中为大家详细讲解如何合理地设置实例设置参数以使实例稳定、安全、高效地运行

创建数据库和表空间

3.1 Db2数据库的概念

在db2中,一个db2实例可以同时管理多个db2数据库,而一个db2数据库只能由一个db2实例管理,db2数据库与db2实例是一种松散耦合的关系。在unix或linux中,创建数据库所生成文件所属的用户和组都是db2实例的所有者,即创建实例的用户和组。实例和数据库的关系如图。

DB2数据库实际上由对象集合组成。从用户的角度来看,数据库是一组通常以某种方式相关联的表。从数据库管理员的角度来看,数据库比这要复杂一些。实际的数据库包含许多逻辑对象和物理对象∶

● 表、视图、索引、模式、触发器、存储过程、程序包等数据库对象

● 缓冲池、日志文件、表空间

● 物理存储、容器、目录、文件系统或裸设备

这些对象中的一部分(比如表或视图)帮助决定如何对数据进行组织;其他对象(比如表空间)涉及数据库的物理实现;最后,一些对象(比如缓冲池和其他内存对象)处理如何管理数据库性能;另外一些对象(比如日志文件)处理数据库的可恢复性。数据库的逻辑结构如图所示。

DBA应该首先关注数据库的物理设计,而不是直接研究所有可能的参数和对象组合。而数据库的逻辑设计,比如表的字段属性设计,则主要由应用设计人员完成。DBA的核心工作之一就是研究如何创建数据库并分配数据库所需的磁盘存储。要正确地解决这个问题,需要了解数据库中的基本对象以及它们如何映射到物理磁盘存储。

3.1.1 DB2数据库存储模型

DB2 利用逻辑存储模型和物理存储模型来处理数据。用户操作的实际数据存放在表中。表由行和列组成,用户并不知道数据的物理表示。这一事实有时候称为数据的物理独立性。

表本身存放在表空间中,一个表空间可以包含多个表。同时,表空间在物理上又对应着若干个容器。容器可以由目录名、裸设备名或文件名标识。容器被分配给表空间。表空间可以跨许多容器,这意味着可以突破操作系统对于一个容器可以包含的数据量的限制。这样一来,表空间就作为逻辑设计中的表与物理设计中的容器之间的桥梁,表通过表空间实实在在地将数据存放到容器(文件或目录)中。图3-3说明了所有这些对象之间的关系。

从图 3-3 中可以看到∶数据库中有很多表空间,可以把数据库看作很多个表空间的集合;可以根据需要创建多个表空间。而用户创建的表、索引等数据库对象存放在表空间中。表直接面向应用。而同时表空间又和底层的物理存储对应,表空间可以有多个容器,而容器处在底层存储之上。所以通过表空间数据库实现了物理存储和逻辑存储的统一。表空间是DB2中最重要的概念之一。

下面首先讲解数据库的物理存储。我们都知道操作系统的最小存储单位是块block),在Linux和UNIX中,最小的块是512字节;在Windows中,最小的存储单位为1KB。而数据库中最小的存储单位是数据页(datapage),它是 DB2 读写的最小单位。DB2数据库中有4KB、8KB、16KB和32KB几种数据页。可以根据业务类型(OLAP、OLTP等)和表的大小来选择合适的数据页。DB2数据库在写物理存储时,为了保证写的吞吐量,引入了更大的单位extent,它是整数倍的 datapage 的大小。这个可以在创建表空间时指定extentsize大小来确定。而容器又由很多个extent 组成,同时表空间又由很多容器组成,它们之间的关系如图3-4所示。

在数据库的物理存储和逻辑存储模型中,表空间链接了物理存储模型和逻辑存储模型,扮演了承上启下的角色。在逻辑上,它向上面对的是数据库,向下它是存放表的容器,面向的是表;而同时表空间又在物理上映射底层的容器——物理存储。表空间是数据库性能调优的重点,而数据库创建工作的绝大部分都是围绕着表空间进行的。

3.1.2 表空间管理类型

Db2支持3种管理类型的表空间:

  • 系统管理的空间(System-Managed Space , SMS):在这里,由操作系统的文件系统管理器分配和管理空间。这种表空间依赖底层的操作系统来进行空间管理。
  • 数据库管理的空间(Database-Managed Space,DMS)∶在这里,由 DB2数据库管理程序控制存储空间。容器可使用文件系统或裸设备。
  • DMS的自动存储(Automatic Storage With DMS)∶自动存储实际上不是一种单独的表空间类型,而是一种处理DMS存储的不同方式。因为数据库管理的空间需要比较多的维护。

SMS表空间需要的维护非常少。但是,与DMS表空间相比,SMS表空间提供的优化选项少且性能不好。

那么,应该选择哪种表空间设计呢?下面我们来看看这几种表空间的比较。

1.DMS、SMS与 DMS自动存储的比较

尽管下面的表 3-1并不全面,但却包含在DMS、DMS自动存储和 SMS表空间之间进行选择时要考虑的一些因素。

SMS 表空间可以简化管理,DMS表空间可以提高性能,除此之外,这两种存储模型之间最显著的差异是表空间的最大大小。在使用 SMS表空间时,DBA 最多只能在表空间中存放64GB(4KB页大小)的数据。将页面大小改为32KB,可以将这个限制扩大到512GB,但代价是每个页面上的可用空间可能会更少。DMS 模型会将大型表空间的限制扩大到8TB(4KB 页面大小的情况下)。如果将页面大小改为 32KB,可用空间可以增长到64TB。尽管还有让表大小突破 64GB 限制的其他方法,但是最简单的方法可能是一开始就使用DMS的大型表空间。

2. DMS与DMS自动存储

DBA 可以为数据库设置存储路径,然后 DMS 自动存储的表空间就会使用这些存储路径。DBA不必显式地定义表空间的位置和大小,系统将自动地分配表空间。

启用 DMS自动存储的数据库有一个或多个相关联的存储路径。表空间可以定义为"由自动存储进行管理",容器由 DB2根据这些存储路径进行分配。数据库只能在创建时启用自动存储。未启用自动存储的现有数据库现在可转换为使用自动存储,同样,现有的DMS 表空间现在可转换为使用自动存储,可使用 ALTERDATABASE 语句来为现有数据库启用自动存储。

下面的表3-2总结了管理DMS非自动存储和 DMS 自动存储之间的一些差异。

引入自动存储模型的主要目的是简化 DMS 表空间的管理,同时保持其性能特征。有的时候,DBA必须定义使用的表空间的所有特征,但是许多应用程序都会从自动存储提供的简化管理获益。

3. DB2存储模型小结

经过上面的讲解,我们对数据库、表空间、容器和数据库对象做个总结∶

● 数据库是对象集合,包括表、索引、视图、大对象和触发器等。

● 这些对象存储在表空间中,表空间由容器组成。

● 表空间可以由操作系统管理(SMS),也可以由 DB2管理(DMS、自动存储)。● 容器可以选择使用底层存储—文件系统、裸设备或操作系统目录。

● 表空间由很多扩展数据块(extent)组成,而 extent 又由 extentsize(可自己定义)个数据页(datapage)组成,数据页是最小的存储单位。

● 应该主要根据性能和维护因素决定要使用的表空间类型、扩展数据块的大小、数据页的大小和容器类型。

创建数据库

从命令行创建 DB2数据库是相当简单的。要创建数据库,必须调用DB2命令行处理程序(Command Line Processor,CLP)。调用方法是在DB2程序组的Command Line Tools 文件夹中选择 Command Line Processor,或者从操作系统命令行执行命令db2cmd db2。

创建DB2数据库的语法如下∶

CREATE DATABASE MYDB

你可能会问"就这么简单?",是的,就这么简单!CREATE DATABASE语句中唯一必需的选项就是数据库的名称。数据库的命名规则是∶

● 数据库的名称可以由以下字符组成∶ a-z、A-Z、0-9、@、#和$。

● 名称中的第一个字符必须是字母表字符、@、#或$;不能是数字或字母序列 SYS、DBM或IBM。注意,数据库的名称不能超过8个字符。

● 数据库名称或数据库别名是唯一的字符串,包含前面描述的1到8个字母、数字或键盘字符。

当然,有很多选项可供使用;不必只输入名称。下面研究一下这个命令实际上会导致什么情况。

DB2创建了什么

在发出CREATE DATABASE 命令时,db2会创建许多文件。这些文件包括日志文件、配置信息、历史文件和3个默认的表空间。这些表空间是:

  • SYSCATSPACE:这是保存db2系统编目的地方,系统编目跟踪与db2对象相关联的所有元数据,即通常所说的“数据字典”。
  • TEMPSPACE1:db2用来放置分组、排序、连接和重组中间结果的临时工作区域。
  • USERSPACE1:默认情况下存放所有用户对象(表、索引)的地方。

在linux/unix系统下,这些文件默认都放在实例用户的home目录下,对于简单的应用程序,这个默认配置应该可以满足需要。但是,我们可能希望改变数据库文件的位置,或者改变DB2管理这些对象的方式。接下来,我们将更详细地研究 CREATE DATABASE 命令。

CREATE DATABASE 命令

DB2CREATEDATABASE命令的完整语法很复杂,下面说明了DBA感兴趣的大多数选项∶

数据库位置

CREATE DATABASE命令的参数之一是 ON path/drive 选项。这个选项告诉DB2希望在哪里创建数据库。如果没有指定路径,就会在数据库管理程序设置(DFTDBPATH 参数)中指定的默认数据库路径上创建数据库。

test2:/home/db2inst4$ db2 get dbm cfg | grep -i DFTDBPATH

Default database path (DFTDBPATH) = /home/db2inst4

例如,以下 CREATE DATABASE命令将数据库存放在UNIX操作系统的/db2/mydb 目录中∶

CREATE DATABASE MYDB ON /db2/mydb

选择自动存储(默认设置)将允许 DBA为数据库设置在创建所有容器时可以使用的存储路径。DBA不必显式地定义表空间的位置和大小,系统将自动地分配表空间。例如,下面的数据库创建语句将为数据库中的所有表空间设置自动存储∶

CREATE DATABASE MYDB AUTOMATIC STORAGE YES ON /db2/mydbpath001,/db2/mydbpath002,/db2/mydbpath003

在 ON 选项后面,给出了3个文件目录(路径)。这3个路径是容器的位置,数据库路径默认放在第一个路径下。当使用 AUTOMATIC STORAGE 定义表空间时,不需要提供其他参数∶

CREATE TABLESPACE TEST MANAGED BY AUTOMATIC STORAGE;

在这个命令中,可以提供与表空间相关联的任何参数;虽然使用自动存储可以大大简化日常的表空间维护工作,但是与重要的大型生产表相关联的表空间可能需要 DBA 更多地干预。

在没有启用自动存储的数据库中创建表空间时,必须指定 MANAGED BY SYSTEM或MANAGED BY DATABASE 子句。使用这些子句会分别创建 SMS表空间和 DMS表空间。在这两种情况下,必须提供容器的显式列表。

如果数据库启用了自动存储,那么在定义表空间时还有另一个选择。可以指定MANAGED BYAUTOMATIC STORAGE子句,或者完全去掉 MANAGED BY子句(这意味着自动存储)。在这种情况下,不提供容器定义,因为 DB2会自动地分配容器。

代码页和整理次序

所有 DB2字符数据类型(CHAR、VARCHAR、CLOB、DBCLOB)都有相关联的字符代码页。可以认为代码页是对照表,用来将字母数字数据转换为数据库中存储的二进制数据。

一个 DB2 数据库只能使用一个代码页。

代码页是在 CREATE DATABASE 命令中使用CODESET和 TERRITORY选项设置的。代码页可以使用单一字节来表示字母数字字符(单一字节可以表示256个独特元素),也可以使用多个字节。英语等语言包含的独特字符相当少,因此单字节代码页(SBCS)对于存储数据足够了。东亚国家语言(中文、日文、韩文等)需要超过 256 个元素才能表示所有的独特字符,因此需要多字节代码页(通常是双字节代码页DBCS)。

在默认情况下,数据库的整理次序根据 CREATE DATABASE 命令中使用的代码集进行定义。默认选项COLLATE USING SYSTEM,会根据为数据库指定的TERRITORY 对数据值进行比较。如果使用选项COLLATE USING IDENTITY,那么以逐字节的方式使用二进制表示来比较所有值。

例如中文代码页为1386,代码集为GBK,TERRITORY为CN。创建数据库时要注意选择合适的代码页,这些参数在数据库创建好后都不能再进行修改,务必慎重选择。如果客户端访问数据库服务器时代码页不一样,将无法访问。

对于需要使用 XML数据的应用程序,有如下特殊的注意事项。当前,DB2只在定义为 Unicode 数据库才能同时存储 XML 文档和 SOL数据的更多传统格式,比如整数、日期/时间、变长字符串等等。随后,你将在这个数据库中创建对象来管理 XML 和其他类型的数据。如果数据库在创建时没有启用 Unicode 支持,就不能在其中创建 XML 数据。

假如要创建同时支持 XML 和 SOL 的数据库,请执行如下命令∶

create database xmldb using codeset UTF-8 territory us

一旦创建 Unicode 数据库,就不需要发出任何专门的命令或采取任何进一步措施来使DB2能够以自身分层的格式存储 XML 数据和关系数据。

表空间定义

3个表空间(SYSCATSPACE、TEMPSPACE1、USERSPACE1)都是在默认目录中自动创建的(ON 关键字),除非指定它们的位置。对于每个表空间,DBA 可以指定表空间应该使用的文件系统的特征。

3个表空间使用以下语法进行定义∶

如果省略任何关键字,db2将使用默认值来生成表空间。表空间定义采用这些选项,语法如下:

注意,上面的语法不包括与自动存储数据库相关联的选项。

我们来详细看看这种语法。MANAGED BY 选项让 DB2生成这些表空间并决定如何管理表空间。SMS表空间使用 SYSTEM USING关键字,如下所示∶

SYSTEM USING ('container string')

对于SMS 表空间,容器字符串(container string)标识一个或多个将属于这个表空间的容器,表空间数据将存储在这些容器中。每个容器字符串可以是绝对的或相对的目录名。如果目录名不是绝对的,就相对于数据库目录。如果目录的任何部分不存在,数据库管理程序就会创建这个目录。容器字符串的格式取决于操作系统。

使用DATABASE USING关键字定义 DMS表空间∶

DATABASE USING ( FILE/DEVICE 'container string' number of pages|K|M|G )

对于DMS表空间,容器字符串标识一个或多个将属于这个表空间的容器,表空间数据将存储在这些容器中。指定容器的类型(FILE 或 DEVICE)和大小(按照 PAGESIZE 大小的页面)。大小还可以指定为整数,后面跟着 K(表示千字节)、M(表示兆字节)或G(表示千兆字节)。可以混合指定 FILE 和 DEVICE容器。

对干 FILE 容器,容器字符串必须是绝对或相对的文件名。如果文件名不是绝对的,就相对于数据库目录。如果目录名的任何部分不存在,数据库管理程序就会创建这个目录。如果文件不存在,数据库管理程序就会创建这个文件并初始化为指定的大小。

对于DEVICE 容器,容器字符串必须是设备名而且这个设备必须已经存在;并且对于DEVICE容器,通常需要使用操作系统 root 权限创建逻辑卷并且赋予 DB2 实例使用的权限,一般通过UNIX/Linux的chown命令来实现这一点。

重要提示∶所有容器必须在所有数据库中唯一;一个容器只能属于一个表空间。

EXTENTSIZE number of pages

EXTENTSIZE 指定数据库可以写到容器中的 PAGESIZE 页面数量,达到这个数量之后将跳到下一个容器。对于含有多个容器的表空间,DB2 以循环方式使用这些容器,以EXTENTSIZE 为切换容器的单位,即先写满第一个容器的EXTENT,再写第二个容器的一个EXTENT,依次执行。EXTENTSIZE的值还可以指定为整数,后面跟着K或M,如果用这种方式,EXTENTSIZE 的值必须是 PAGESIZE 的整数倍。EXTENTSIZE 的大小是在表空间级定义的。一旦为表空间指定扩展数据块大小,就不能改变了。数据库配置参数DFT_EXTENT_SZ指定数据库中所有表空间的默认扩展数据块大小。这个值的范围是2到256个页面;因此,绝对大小是从 8KB 到 1024KB(对于 4KB 页面),或者从 16 KB 到2048KB(对于8KB 页面)。可以在 CREATE TABLESPACE 语句中使用EXTENTSIZE 参数覆盖这个数字。

PREFETCHSIZE number of pages

PREFETCHSIZE 指定在执行数据预获取时将从表空间中读取的 PAGESIZE 页面数量。连续的预读取是指数据库管理程序能够提前预测查询,在实际引用页面之前读取这些页面。这样查询就不需要等待底层操作系统执行 I/O操作。这种异步的检索可以显著减少执行时间。可以通过修改 CREATE TABLESPACE 语句中的 PREFETCHSIZE参数来控制执行预获取的大小。在默认情况下,这个值设置为 DFT PREFETCH SZ数据库配置参数,这个值代表在 DB2触发预读取请求时每次读取多少个页面。通过将这个值设置为扩展数据块大小的倍数, 可以并行地读取多个扩展数据块。当表空间的容器在不同的硬盘上时,这个功能甚至效率更高。预读取大小还可以指定为整数,后面跟着K、M或G。

关于PREFETCHSIZE 的设置,我们在后面介绍表空间性能时还会详细讲解。

CREATE DATABASE命令示例

下面是CREATE DATABASE 命令示例,这里使用了前面讨论的许多选项∶

CREATE DATABASE MYDB

DET_EXTENT_SZ 4

CATALOG TABLESPACE MANAGED BY DATABASE USTNG

(FILE '/datal/CATALOG.DAT' 20000,FILE '/data2/CATALOG.DAT' 20000)

EXTENTSIZE 8

PREFETCHSIZE 16

TEMPORARY TABLESPACE MANAGED BY SYSTEM USING

('/datal/TEMPTS1','/data2/TEMPTS2')

USER TABLESPACE MANAGED BY DATABASE USING

(FILE '/datal/USERTS.DAT' 1200)

EXTENTSIZE 24

PREFETCHSIZE 48

我们来详细地看看每一行∶

● CREATE DATABASE∶这条语句定义要创建的数据库的名称。

● DFT_EXTENT_SZ 4∶这个参数告诉 DB2默认的扩展数据块大小是4个页面,除非

在创建表空间时显式地声明,否则默认使用这个值。

● CATALOG TABLEPSACE MANAGED BY DATABASE USING∶DB2编目空间将由数据库管理。

● FILE '/data...'∶数据库编目表空间的位置将跨两个文件,每个文件有20000个页面的空间。

● EXTENTSIZE 8∶EXTENTSIZE是8个页面。这个设置会覆盖 DFT_EXTENT _SZ。

● PREFETCHSIZE 16∶在查询处理期间,同时预读取 16个页面。

● TEMPORARY TABLESPACE MANAGED BY SYSTEM USING∶DB2使用的临时空间将由操作系统处理。

● 'TEMPTS...'...∶临时空间将跨两个文件,文件的大小在 DB2执行期间自动地调整。

● USER TABLESPACE MANAGED BY DATABASE USING∶用户表空间(放置真正的表的地方)将由 DB2直接管理。

● EXTENTSIZE 24∶ USER表空间的 EXTENTSIZE 是24个页面。

● PREFETCHSIZE 48∶查询处理期间,同时预读取 48个页面。

上面介绍了关于如何创建DB2数据库的背景知识。在大多数情况下,CREATEDATABASE 命令的默认值提供了可以满足开发和测试需要的数据库。一旦决定将数据库转入生产环境,就需要对DB2使用的数据布局和表空间定义付出更大的努力。尽管这需要做更多的规划工作,但是产生的数据库更容易管理,性能也可能更好。

3.1.4 数据库目录

我们在第2章创建实例时讲过,当创建实例时,就会生成实例目录。同样,当创建数据库时,关于数据库的信息(包括默认信息)会存储在目录层次结构中,这就是数据库目录。此分层目录结构的创建位置取决于你在CREATE DATABASE 命令中提供的路径信息。如果在创建数据库时未指定目录路径或驱动器的位置,那么将使用默认位置。建议创建数据库时明确数据库路径。数据库目录中存放的是数据库表空间、表、索引、容器等信息,这个目录至关重要,一定要注意它的安全性。

在CREATE DATABASE 命令中,在指定为数据库路径的目录中,将创建使用实例名的子目录。这个子目录确保在同一目录下的不同实例中创建的数据库不会使用相同的路径。在实例名子目录下面,将创建名为NODE0000的子目录。这个子目录可以区分逻辑分区数据库环境中的数据库分区。在节点名目录下面,将创建名为SQL00001的子目录。此子目录的名称使用了数据库标记并表示正在创建的数据库。SQL00001包含与第一个创建的数据库以及随后创建的具有更高编号(SQL00002等)的数据库相关联的对象。这些子目录可以区分在CREATEDATABASE命令中,在指定目录的实例中创建的数据库。

目录结构如下所示

<your_database_path>/<your_instance>/NODE0000/SQL0001/

详细的信息如图3-7所示。

数据库目录中包含下列作为CREATE DATABASE命令一部分进行创建的文件:

● 文件 SQLBP.1和 SQLBP.2中包含缓冲池信息。这两个文件互为副本以实现备份。

● SQLSPCS.1 和 SQLSPCS.2 文件中包含表空间信息。这两个文件互为副本以实现备份。

● 文件 SQLSGF.1和 SQLSGF.2包含与数据库自动存储有关的存储路径信息。这两个文件互为副本以实现备份。

● SQLDBCONF 文件中包含数据库配置信息。切勿编辑此文件。

注意∶

SQLDBCON文件在先前发行版中使用,并且包含在 SOLDBCONF损坏时可以使用的类似信息。

要更改配置参数,请使用UPDATE DATABASE CONFIGURATION 和RESET DATABASE CONFIGURATION 语句。

● DB2RHIST.ASC历史记录文件及其备份 DB2RHIST.BAK中包含关于备份、复原、表装入、表重组、表空间改变和其他数据库更改的历史记录信息。

DB2TSCHG.HIS 文件中包含日志文件级别的表空间更改的历史记录。对于每个日志文件,DB2TSCHG.HIS 中包含有助于标识日志文件影响哪些表空间的信息。表空间恢复使用此文件中的信息来确定在进行表空间恢复期间要处理哪些日志文件。可以在文本编辑器中检查这两个历史记录文件中的内容。

● 日志控制文件SQLOGCTL.LFH.1及其镜像副本SQLOGCTL.LFH.2和SQLOGMIR.LFH中包含有关活动日志的信息。崩溃恢复处理过程使用这些文件中的信息来确定要在日志中后退多远来开始崩溃恢复。SQLOGDIR子目录包含实际的日志文件。

注意∶

应确保不要将日志子目录映射到用于存储数据的磁盘。这样一来,在磁盘发生问题时,只会影响到数据或日志,而不会同时影响这两者。由于日志文件与数据库容器不会争用同一磁盘磁头的移动,因此这可提供很多性能方面的好处。要更改日志子目录的位置,请更改 newlogpath 数据库配置参数。

● SQLINSLK文件用于确保数据库只能由数据库管理器的单个实例使用。

● 在创建数据库的同时,还创建了详细的死锁事件监视器。详细的死锁事件监视器文件存储在目录节点的数据库目录中,名为db2detaildeadlock。

在非自动存储数据库中,SMS数据库目录的其他信息

在非自动存储数据库中,SQLT*子目录包含运作数据库所需的默认“系统管理的空间”(SMS)表空间。创建数据库时会生成3个默认表空间∶

● SQLT0000.0子目录中包含带有系统目录表的目录表空间

● SQLT0001.0子目录中包含默认临时表空间

● SQLT0002.0子目录中包含默认用户数据表空间

每个子目录或容器中都会创建名为SQLTAG.NAM的文件。这个文件可以标记正在使用中的子目录,因此在以后创建其他表空间时,不会尝试使用这些子目录。

此外,名为SQL*.DAT的文件中还存储有关子目录或容器包含的每个表的信息。星号(*)将被唯一的一组数字取代,用来识别每个表。对于每个SQL*.DAT文件,可能有一个或多个下列文件,这取决于表类型、表的重组状态或者表是否存在索引、LOB或LONG 字段

● SQL*.BKM(如果是MDC表,那么包含块分配信息)

● SQL*LF(包含LONG VARCHAR或LONG VARGRAPHIC数据)

● SQL*LB(包含BLOB、CLOB或DBCLOB数据)

● SQL*.XDA(包含 XML 数据)

● SQL*LBA(包含关于SQL*LB文件的分配和可用空间信息)

● SQL*.INX(包含索引表数据)● SQL*.IN1(包含索引表数据)

● SQL*DTR(包含用于重组SQL*DAT文件的临时数据)

● SQL*.LFR(包含用于重组SQL*.LF文件的临时数据)

● SQL*.RLB(包含用于重组SQL*.LB文件的临时数据)

● SQL*.RBA(包含用于重组SQL*.LBA文件的临时数据)

如果创建了多个数据库,那么可以通过 db2 list db directory on dbpath 查看每个数据库的目录。

数据库目录对于应用和数据库用户来说是透明的,他们看到的是数据库逻辑层面的表、索引等对象。而数据库目录是面向DBA的,所以DBA了解数据库的物理存储模型和逻辑存储模型。逻辑模型和物理模型是用系统编目表来统一的。

3.2 设计表空间

3.2.1 创建表空间

表空间建立数据库系统使用的物理存储设备与用来存储数据的逻辑对象或表之间的关系。我们在前面创建数据库部分讲解了表空间的类型,对于非自动存储表空间,在创建表空间时,必须知道将引用的容器的设备名或文件名。另外,必须知道要分配给表空间的每个设备名或文件名及分配空间大小。对于自动存储表空间,数据库管理器将根据与数据库关联的存储路径将容器指定给表空间。

在数据库内创建表空间,会将容器分配到表空间,并在数据库系统目录表中记录定义和属性,然后就可以在此表空间内创建表。当创建数据库时,会创建3个初始表空间。这3个初始表空间的页大小基于使用CREATE DATABASE命令时建立或接受的默认值。此默认值还表示所有将来 CREATE BUFFERPOOL 和 CREATE TABLESPACE 语句的默认页大小。如果在创建数据库时不指定页大小,那么默认页大小是4KB。如果在创建表空间时不指定页大小,那么默认页大小是创建数据库时设置的页大小。

1.创建用户表空间

要使用命令行创建 SMS表空间,请输入∶

CREATE TABLESPACE <NAME> MANAGED BY SYSTEM USING ('<path>')

要使用命令行创建 DMS表空间,请输入∶

CREATE TABLESPACE <NAME> MANAGED BY DATABASE USING (DEVICE |FILE '<path>' <size>)

要使用命令行创建自动存储表空间,请输入下列任一语句∶

CREATE TABLESPACE <NAME>

CREATE TABLESPACE <NAME> MANAGED BY AUTOMATIC STORAGE

通过使用3个不同的驱动器上的3个目录,下列SQL语句在UNIX中创建了一个SMS 表空间∶

CREATE TABLESPACE TS1 MANAGED BY SYSTEM USING('/datal/nxz _tbsp','/data2/nxz_tbsp','/datal/nxz_tbsp')

以下SQL语句使用各自有5000页的两个文件容器创建一个DMS表空间:

CREATE TABLESPACE TS2 MANAGED BY DATABASE

USING(FILE '/datal/acc_tbsp' 5000,FILE '/data2/acc_tbsp' 5000)

注意在创建 DMS表空间时,表空间文件容器不需要创建,DB2会自动创建(裸设备容器无法自动创建,需要 root 用户参与)。

在前面两个示例中,为容器提供了显式的名称。但是,如果指定相对容器名,那么将在为数据库创建的子目录中创建容器。

在创建容器时,数据库管理器会创建任何不存在的目录和文件。例如,如果将容器指定为/prod/user_data/containerl,而目录/prod 不存在,那么数据库管理器会创建目录 /prod 和/prod/user_data。

在 Linux/UNIX 中,数据库管理器创建的任何目录都是使用权限位711 创建的,这意味着只有实例所有者才拥有读写访问权和执行访问权。因为只有实例所有者具有这种访问权,所以当正在创建多个实例时,可能会出现下列情况∶

● 使用与上面描述的相同的目录结构,假定目录级别/prod/user_data 不存在。 ● userl创建实例(默认情况下命名为 user1),接着创建数据库,然后创建表空间,并且/prod/user data/container1将作为表空间的容器。

● user2创建实例(默认情况下命名为 user2),接着创建数据库,然后尝试创建表空间,并且/prod/user_data/container2将作为表空间的容器。

因为数据库管理器根据第一个请求使用权限位700 创建了目录级别/prod/user_data,所以 user2没有对这些目录级别的访问权,因此不能在这些目录中创建container2。在这种情况下,CREATE TABLESPACE 操作将失败。

解决此冲突有两种方法∶

● 在创建表空间之前创建目录/prod/user_data,并将许可权设置为userl和 user2创建表空间所需的任何访问权。如果所有级别的表空间目录都存在,那么数据库管理器不会修改访问权。

● 在 userl创建/prod/user_data/container1之后,将/prod/user data 的许可权设置为 user2创建表空间所需的任何访问权。

如果数据库管理器创建了子目录,那么在删除表空间时,数据库管理器也可能将子目录删除。

下列SQL语句在AIX系统中创建了使用具有10000页的3个裸设备作为容器的DMS 表空间,并指定它们的I/O特征∶

CREATE TABLESPACE TS1 MANAGED BY DATABASE

USING (DEVICE '/dev/rdblv6' 10000,DEVICE '/dev/rdblv7' 10000,DEVICE

'/dev/rdblv8' 10000) OVERHEAD 7.5 TRANSFERRATE 0.06

在此 SQL语句中提到的裸设备必须已经存在,并且实例所有者和SYSADM组必须能够写入这些设备。

还可以创建表空间,使用的页大小比默认的4KB更大。下列SOL语句在Linux和UNIX 系统中创建具有8KB页大小的SMS表空间∶

CREATE TABLESPACE SMS8K PAGESIZE 8192 MANAGED BY SYSTEM

USING ('FSMS 8K 1') BUFFERPOOI BUFFPOOL8K

注意,相关联的缓冲池也必须具有相同的8KB页大小,而且只有在激活了由创建的表空间引用的缓冲池之后才能使用该表空间。

2.创建系统临时表空间

系统临时表空间用来存储分组、排序、连接、重组、创建索引操作等中间结果。数据库必须始终至少有一个这样的表空间。创建数据库时,定义的3个默认表空间之一便是名为"TEMPSPACE1"的系统临时表空间。

要创建另一个系统临时表空间,可使用CREATE TABLESPACE 语句。例如∶

CREATE SYSTEM TEMPORARY TABLESPACE tmp_tbsp

MANAGED BY SYSTEM USING('/datal/tmp_tbsp','/data2/tmp_tbsp')

对于每个页大小,至少应具有一个和该页大小匹配的系统临时表空间。

3.创建用户临时表空间

用户临时表空间不是在创建数据库时默认创建的。如果应用程序需要使用临时表,那么需要创建将驻留临时表的用户临时表空间。用户临时表空间通常用来批量插入、批量更新和批量删除以加快速度

使用DECLARE GLOBAL TEMPORARY TABLE 语句声明临时表时,必须要求用户临时表空间存在。

要创建用户临时表空间,可使用 CREATE TABLESPACE 语句∶

CREATE USER TEMPORARY TABLESPACE usr_tbsp MANAGED BY DATABASE USING (FILE '/datal/user tbsp' 5000,FILE '/data2/user_tbsp' 5000)

3.2.2 维护表空间

1.查看表空间

可以使用DB2 LIST TABLESPACES [SHOW DETAIL]来查看表空间的详细信息。

LIST TABLESPACES 命令的输出信息如下:

上面所示的这3个表空间是通过 CREATE DATABASE 命令自动创建的。用户可以通过在该命令中定制表空间选项来覆盖默认的表空间创建选项。但是在创建数据库时必须创建系统编目表空间和至少一个常规表空间,以及至少一个系统临时表空间。通过使用CREATE DATABASE 命令或以后使用CREATE TABLESPACE命令,可以创建更多的所有类型的表空间(系统表空间除外)。在上述 3 个表空间中,系统编目表空间和系统临时表空间都是只读的,用户不可以在上面创建用户表,如下所示。

查看表空间及容器的属性

指定LIST TABLESPACES命令的SHOW DETAIL选项将显示其他信息:

LIST TABLESPACES SHOW DETAIL

默认情况下,将列出创建数据库时创建的那3个表空间。LIST TABLESPACES SHOW DETAIL命令的输出信息如下:

要列出容器,需要使用以上输出中的Tablespace ID:

LIST TABLESPACE CONTAINERS FOR 2

为了查看容器的情况,可以使用LIST TABLESPACE CONTAINERS命令:

该命令将列出指定表空间中的所有容器。如上所示的路径指向容器物理上的位置。

表空间状态

为了查看数据库中表空间的状态,可以使用命令:

List tablespaces show detail

表空间可以有多种不同的状态,如下所示:

0x0 Normal

0x1 Quiesced: SHARE

0x2 Quiesced: UPDATE

Ox4 Quiesced:EXCLUSIVE

0x8 Load pending

Ox10 Delete pending

0x20 Backup pending

O0x40 Rollforward in progress

Ox80 Rollforward pending

0x100 Restore pending

0x100 Recovery pending(not used)

0x200 Disable pending

0x400 Reorg in progress

0x800 Backup in progress

0x1000 Storage must be defined

0x2000 Restore in progress

0x4000 Offline and not accessible

0x8000 Drop pending

0x2000000 Storage may be defined

0x4000000 StorDef is in 'final'state

Ox8000000 StorDef was changed prior to rllforward

0x10000000 DMS rebalancer is active

0x20000000 TBS deletion in progress

0x40000000 TBS creation in progress

0x8 For service use only

2.修改表空间

可使用 ALTER TABLESPACE 语句。可以改变 SMS、DMS和自动存储容器,还可以重命名表空间,并将表空间从脱机方式切换至联机方式。

对于 SMS表空间,我们只能增加容器;对于DMS表空间,可以添加、扩展、重新平衡、删除或减少容器,或者调整容器大小。我们重点讲解 DMS表空间的修改。

添加或扩展 DMS容器

通过将一个或多个容器添加至 DMS表空间(即使用MANAGED BY DATABASE 子句创建的表空间),可以增大 DMS表空间的大小。

当将新容器添加到表空间或扩展现有容器时,可能会发生表空间重新平衡(rebanlance)。重新平衡过程涉及将表空间扩展数据块从一个位置移至另一位置。在此过程中,将尝试在表空间内分割数据。重新平衡不必在所有容器上进行,但这取决于许多因素,例如现有容器的配置、新容器的大小和表空间满的程度。

在重新平衡期间,不限制对表空间的访问。如果需要添加多个容器,那么应该同时添加这些容器以减少重新平衡的次数。虽然重新平衡期间表空间仍然可以访问,但我们还是尽量避免在业务高峰期间增加容器,因为数据重新平衡期间系统中有很多的I/O活动。关于表空间重新平衡,其实DB2还有一些高级选项,但这部分内容超出了本书讲解范围。如果读者感兴趣,可以参考《高级进阶DB2(第2版)》一书。

要使用命令行将容器添加到DMS表空间,请输入以下内容∶

ALTER TABLESPACE <name> ADD (DEVICE '<path>' <size>,FILE '<filename>' <size>)

以下示例说明如何将两个新设备容器(各含10000页)添加到Linux和UNIX系统的表空间中:

ALTER TABLESPACE TS1 ADD (DEVICE '/dev/rhd9’ 10000, DEVICE '/dev/rhd10' 10000)

添加容器会涉及容器的重新平衡,如果不想这样,可以使用表空间扩展来修改容器大小,因为extend不会重新平衡表空间数据。

以下示例说明如何将所有容器扩展10000页(各含10000页)后添加到Linux和UNIX 系统的表空间中∶

ALTER TABLESPACE TSI EXTEND (ALL 10000)

调整DMS容器的大小

不能手动调用自动存储表空间中容器的大小,否则将报错,如下所示 test2:/Sdb2 "alter tablespace userspacel extend (all 20)"

DB21034E The command was processed as an SQL statement because it was not a valid Command Line Processor command. During SQI processing it returned:

SQL20318N Table space "USERSPACE1" of type "AUTOMATIC STORAGE" cannot be altered using the "EXTEND" operation. SQLSTATE=42858

只能将每个操作系统裸设备用作容器。创建裸设备之后,其大小是固定的。当考虑使用调整大小或扩展选项来增大裸设备容器时,应先用操作系统命令检查裸设备大小以确保使用ALTER TABLESPACE命令并未将裸设备容器大小增大到大于裸设备大小。

要缩小现有容器的大小,可使用RESIZE或REDUCE选项。使用RESIZE选项时,作为语句一部分列示的所有容器都必须增大或减小大小。不能在同一条语句中增大某些容器而缩小其他容器。如果知道容器大小的新下限,应考虑调整大小方法。如果不知道(或不关心)容器的当前大小,那么应该考虑缩小方法。

要使用命令行来缩小DMS表空间中一个或多个容器的大小,请输入

ALTER TABLESPACE <name> REDUCE(FILE '<filename>' <size>)

以下示例说明如何在 UNIX系统的表空间中缩小文件容器(原来为1000 页)∶

ALTER TABLESPACE PAYROLL REDUCE (FILE '/data/finance' 200)

在完成此操作之后,文件大小就从1000 页减少至800 页。

要使用命令行来增大DMS表空间中一个或多个容器的大小,请输入∶

ALTER TABLESPACE <name> RESIZE (DEVICE '<path>' <size>)

以下示例说明如何在 Linux 和 UNIX 系统的表空间中增大两个设备容器(原来大小为1000 页)∶

ALTER TABLESPACE HISTORYR ESIZE(DEVICE '/dev/rhd7' 2000, DEVICE '/dev/rhd8' 2000)

在完成此操作之后,两个设备的大小都从1000页增加至 2000页。要使用命令行来扩展 DMS表空间中一个或多个容器的大小,请输入∶

ALTER TABLESPACE <name> EXTEND (FILE1 '<filename>' <size>)

以下示例说明如何在 Windows系统的表空间中增大文件容器(原来大小为1000页)∶

ALTER TABLESPACE PERSNEL EXTEND(FILE '/datal/wrkhist1' 200, FILE '/data2/wrkhist2' 200)

在完成此操作之后,两个文件的大小都从 1000页增大至1200页。

删除或减少 DMS容器

对于DMS表空间,可以使用ALTER TABLESPACE 语句从表空间中删除容器或缩小容器的大小。要缩小容器,可以在 ALTER TABLESPACE语句中使用 REDUCE或 RESIZE 选项。要删除容器,可以在 ALTER TABLESPACE 语句中使用DROP选项。

仅当正在删除或缩小其大小的扩展数据块数目小于或等于表空间中"高水位标记"之上的可用数据块数目时,才允许删除现有容器以及缩小现有容器的大小。高水位标记是表空间中分配的最高页的页数。此标记与表空间中已使用的页的数目不同,高水位标记下的某些扩展数据块可能可供复用。

表空间中高水位标记之上的可用扩展数据块数非常重要,原因是直至高水位标记(包括高水位标记)的所有扩展数据块必须位于表空间内的同一逻辑位置。结果表空间必须有足够的空间才能容纳所有数据。如果没有足够的可用空间,那么会产生一条错误消息(SQL20170N或 SQLSTATE 57059)。

要删除容器,可在ALTER TABLESPACE 语句中使用 DROP选项。例如∶

ALTER TABLESPACE TS1 DROP (FILE 'filel',DEVICE'/dev/rdisk1')

改变自动存储表空间

对于自动存储表空间,不能手动调整自动存储表空间的大小,数据库管理器将在需要时自动调整容器大小。

3.重命名表空间

可以使用RENAME TABLESPACE 语句来重命名表空间。不能重命名 SYSCATSPACE 表空间。不能重命名处于"前滚暂挂"或"正在前滚"状态的表空间。

可以给予现有表空间新名称,而无须关心表空间中的个别对象。重命名表空间时,将更改引用表空间的所有目录记录。例如∶

RENAME TABLESPACE TS1 TO TS2

注意∶

当复原在备份后已被重命名的表空间时,必须在RESTORE DATABASE命令中使用新的表空间名。如果使用先前的表空间名,那么将找不到该名称。同样,如果使用ROLLFORWARD DATABASE命令前滚表空间,也需要确保使用新名称。如果使用先前的表空间名,那么将找不到该名称。

4.将表空间从脱机状态切换至联机状态

如果与表空间相关的容器不可访问,这时表空间处于 OFFLINE 状态。要使用命令行从表空间中除去OFFLINE 状态,请输入∶

ALTER TABLESPACE <name> SWITCH ONLINE

什么情况下会处于OFFLINE 状态呢?下面举一个实际生产中的例子。在双机热备 HA 的环境中,客户在主机上重新创建了使用裸设备的表空间后,未同步HA 环境,结果导致主机故障切换到备机时,由于裸设备权限不正确而导致表空间处于 OFFLINE 状态。

5.删除表空间

当删除表空间时,也会删除表空间中的所有数据,释放容器,除去目录条目,并导致表空间中定义的所有对象都被删除或标记为无效。可以通过删除表空间来重用空表空间中的容器,但是在试图重用这些容器之前,必须落实 DROP TABLESPACE 语句。

删除用户表空间

可删除包含所有表数据的用户表空间,包括在单个用户表空间中的索引和LOB数据。也可删除其中包含的表跨几个表空间的用户表空间。也就是说,可能表数据在一个表空间,索引在另一个表空间且任何LOB数据在第3个表空间。必须在一条语句中同时删除所有3 个表空间。包含跨越的表的所有表空间必须全部纳入此单条语句中,否则该删除请求将失败。例如创建表的定义如下:

create table xinzhuang pic(picno int, pic clob(1g))in data_space index in index_space long in lob_space

只能同时删除3个表空间

DROP TABLESPACE DATA_SPACE,INDEX_SPACE,LOB_SPACE

删除用户临时表空间

仅当用户临时表空间中当前未定义已声明临时表时,才能删除用户临时表空间。当删除表空间时,不会尝试删除表空间中的所有已声明临时表。

注意:

已声明临时表是在说明应用程序与数据库断开连接时隐式删除的。

删除系统临时表空间

对于默认4KB页大小的数据库,如果不首先创建另一系统临时表空间,那么不能删除页大小为4KB的默认系统临时表空间。新的系统临时表空间必须具有4KB页大小,原因是数据库必须始终存在至少一个具有 4KB 页大小的系统临时表空间。对于默认 8KB、16KB、32KB 页大小的数据库,同样也必须存在一个相应页大小的系统临时表空间。例如,如果具有页大小为 4KB 的单个系统临时表空间,并且想要将一个容器添加到该表空间(为SMS表空间)中,那么必须首先添加一个具有适当数目容器的新4KB页大小的系统临时表空间,然后删除旧的系统临时表空间(如果正在使用 DMS,那么可以添加容器而不必删除并重新创建表空间)。

默认系统临时表空间的页大小是创建数据库时使用的页大小(默认情况下为4KB),但也可以为8KB、16KB或32KB。

下面是用来创建系统临时表空间的语句∶

CREATE SYSTEM TEMPORARY TABLESPACE <name> MANAGED BY SYSTEM USING ('<directories>')

创建之后,要使用命令行删除系统表空间,请输入

DROP TABLESPACE <name>

以下SQL语句创建名为TEMPSPACE2的新的系统临时表空间∶

CREATE SYSTEM TEMPORARY TABLESPACE TEMPSPACE2

MANAGED BY SYSTEM USING ('/data/systemp2')

一旦创建TEMPSPACE2,就可使用以下命令删除原来的系统临时表空间TEMPSPACE1∶

DROP TABLESPACE TEMPSPACE1

3.2.3 表空间设计注意事项

1. 表空间类型的选择

在确定应使用哪种类型的表空间来存储数据时,需要考虑一些问题。

SMS表空间的优点

● 根据需要,系统按需分配空间

● 由于不必预定义容器,因此创建表空间需要的初始工作较少

DMS表空间的优点∶

● 通过使用ALTER TABLESPACE语句,可添加或扩展容器来增加表空间的大小。现有数据可以自动在新的容器集合中重新平衡以保持最佳I/O效率

● 根据存储的数据的类型,可以把表长字段(LF)和大对象(LOB)数据、索引和常规表数据分割存放在多个表空间中以提高性能和空间存储容量。通过分隔表数据,可以提高性能和增加每个表存储的数据量。例如,如果要使用4KB页大小的大型表空间,那么可以有一个包含8TB正规表数据的表、一个包含8TB索引数据的单独表空间和另一个包含8TB长型数据的单独表空间。如果这3种类型的数据存储在一个表空间中,那么总空间将限制为8TB。使用较大的页大小将允许存储更多数据

● 对范围分区数据创建的索引可以与表数据存储在不同的表空间中

● 可控制数据在磁盘上的位置(如果操作系统允许的话)

● 通常,精心设计的一组DMS表空间的性能将优于SMS表空间

注意:

对于性能要求很高的应用程序,特别是涉及大量DML操作的应用程序,建议使用DMS 表空间。

其实 DMS的优势,就是数据在物理磁盘上的连续性。SMS使用操作系统来管理空间,虽然从逻辑上看,看似所有的文件都是连续的,但是在物理磁盘上,每次文件的增大都必须分配新的空间。所以从操作系统的角度来看,所谓的“分配”不过是在 inode 节点中增加一个指向页的偏移,这个页是操作系统寻找出来没有被使用的,因此从磁盘的角度来看,文件可以被切分成很多块存储在不同的地方——尽管逻辑上它们是连续的。这也就是能够动态增加大小的 SMS 文件的致命伤。不像DMS,分配完成之后一般不会随意增加或减少大小,SMS的大小增加有时可能非常频繁,因此每个文件在物理磁盘上的存储会被划分成一个个小块。这样的话,尽管在逻辑上它们的条带化还是连续的,但是从物理磁盘的角度来看,它们的每个extent 之间可能并非连续,无法使用 range prefetch直接从磁盘上读取几个连续的 extent。

而且在这两种类型的表空间中,数据的放置也会有所不同。例如,进行高效表扫描要求扩展数据块中的页在物理上是连续的。对于 SMS,操作系统的文件系统决定了每个逻辑文件页的物理放置位置。根据文件系统中其他活动的级别以及用来确定放置位置的算法的不同,可能会连续分配这些页,也可能不会。但是对于DMS,因为数据库管理器直接与磁盘打交道,所以可以确保这些页在物理上是连续的。

通常,小型个人数据库用 SMS 表空间管理最容易。另一方面,对于不断增长的大型数据库,建议将 SMS表空间当成临时表空间和系统编目表空间使用,而将具有多个容器的单独的DMS表空间用于每个表。另外,建议将长字段(LF)数据和索引存储在它们自己的表空间中。

在深刻理解上述两种表空间的优缺点后,选择表空间时要综合考虑如下因素:

表中的数据量

如果计划在一个表空间中存储许多小表,那么考虑使用SMS 充当表空间。对于小表,DMS 表现在 I/O 和空间管理效率方面的优点就没有那么重要。SMS 的优点(仅在需要时使用)却对小表更具吸引力。如果表较大或者需要更快地访问表中的数据,应考虑具有较小扩展数据块大小的 DMS表空间。

设计数据库时,可以考虑对每个非常大的表都使用单独的 DMS表空间,而将所有的小表组合在单个SMS 表空间中。这种分隔还允许根据表空间的使用选择适当的扩展数据块大小。

表数据的类型

例如,有的表可能包含不经常使用的历史记录数据;最终用户可能愿意接受较长的响应时间,等待对此数据执行的查询。在这种情况下,可以为历史记录表使用单独的表空间,并将此表空间分配给访问速率较低的较便宜的物理设备。

此外,对于某些表,数据的快速响应时间是非常必要的,需要将这些表分配给快速物理设备的表空间中,这样将有助于支持这些重要的数据需要。如果可以的话,可以使用固态硬盘来存放访问最频繁的表。

通过使用 DMS 表空间,还可以将表数据分发在 3个不同的表空间中∶一个存储索引数据;一个存储大对象(LOB)和长字段 LF)数据;一个存储常规表数据。这允许选择表空间特征和支持最适合该数据的那些表空间的物理设备。例如,可能会将索引数据置于可找到的最快的设备上,这样性能可显著提高。如果将表分布在各个DMS表空间中,那么在启用表空间级备份恢复时,应考虑一起备份和复原那些表空间。SMS表空间不支持以此方式将数据分发在所有表空间中。

管理问题

某些管理功能可以在表空间级执行,但不能在数据库或表级执行。例如, 备份表空间(而不是数据库)可以帮助更好地利用时间和资源,允许频繁地备份带有大量更改的表空间,同时仅偶尔地备份带有少量更改的表空间。

可以复原数据库或表空间。如果不相关的表在同一个表空间中,就可以选择仅复原数据库中较小的部分以降低成本。一种好方法是将相关的表存放在表空间中。这些表可以通过参考约束相关,也可以通过定义的其他业务约束相关。

如果需要经常删除并重新创建特定表,那么应给这样的表单独创建 DMS 表空间,因为删除 DMS表空间比删除表更有效率

2.选择合适的数据页大小

创建表空间时,需要考虑页大小。可以使用 4KB、8KB、16KB 或 32KB页大小。在选择数据页大小时需要综合考虑空间需求和业务类型(性能需求)以做出选择。

空间需求

因为DB2中每个页大小限定了可存储行的最大长度和可存储表空间的最大值,所以选择数据页大小时需要考虑这些。对于4KB数据页来说,最多可以存放的行的长度是 4005 字节(4096-91 头部;8KB为 8192-91;依此类推),所以首先要根据行的长度来选择数据页大小。表 3-3 列出了每种数据页大小的空间使用限制,以及不同类型的表空间的数据库和索引页大小限制。

如果数据页大小选择不当,还可能造成空间浪费。例如,如果要使用32KB页大小的常规表空间来存储平均大小为100字节的行,那么32KB的页只能存储100*255=25500 字节(24.9KB)。这意味着每32KB中就有大约7KB要浪费掉。所以建议创建表空间时,尽量创建大型表空间,大型表空间的数据页可以存放更多的容量和行数。

业务类型

建议根据业务类型选择合适的数据页大小。通常的业务类型有 OLTP、OLAP、批处理、报表,以及这几种业务的混合类型。下面介绍主要业务类型的特点。

联机事务处理(OLTP)工作负载的特征是∶事务需要对数据进行随机访问,通常涉及频繁插入或更新活动和返回一小组数据的查询。通常访问是随机的,并且是访问一页或几页,一般不太可能发生预存取(prefetch)。这里顺便讲一下,其实对于性能要求很高的 OLTP 应用,可以考虑把一些频繁访问的表创建在固态硬盘上。

使用裸设备容器的 DMS表空间在这种情况下表现得最好。请注意,在 FILE SYSTEM CACHING 关闭的情况下,将 DMS 表空间与文件容器配合使用在某种程度上相当于DMS裸设备容器。如果业务逻辑存在大量的随机读,那么 CREATE TABLESPACE 语句中的 EXTENTSIZE 和PREFETCHSIZE 参数的设置对于I/O 的效率就显得不是那么重要。

OLAP 查询工作负载的特征是∶ 事务需要对数据进行顺序访问或部分顺序访问,并常常返回大的数据集。使用多个设备容器且每个容器都在单独磁盘上的 DMS 表空间最有可能提供有效的并行预存取。应该将 CREATE TABLESPACE 语句中的 PREFETCHSIZE 参数的值设置为 EXTENTSIZE 参数的值乘以容器设备数之积。此外,可以将预取大小指定为-1,此时数据库管理器将自动(automatic)选择合适的预取大小。这允许数据库管理器以并行方式从所有容器中预取。如果容器的数目发生更改,或者需要使预取更多或更少,那么可以使用 ALTER TABLESPACE语句相应地更改 PREFETCHSIZE 值;如果把 PREFETCHSIZE 设置为 AUTOMATIC,添加容器后,数据库会自动调整 PREFETCHSIZE 的大小,所以强烈建议把 PREFETCHSIZE 设置为 AUTOMATIC或-1。

混合工作负载的目标是∶对于OLTP 工作负载,使单个 I/O请求尽可能有效率;而对于查询工作负载,最大程度地提高并行I/O的效率。

选择表空间页大小的注意事项如下所示∶

● 对于执行随机行读写操作的 OLTP 应用程序,通常最好使用较小的页大小(4KB、8KB),这样一来,不需要的行就不会浪费缓冲池空间。

● 对于一次访问大量连续行的决策支持系统(DSS)和OLAP应用程序,页大小大一些(16KB、32KB)会比较好,这样就能减少读取特定数目的行所需的 I/O 请求数。较大的页大小还允许减少索引中的层数,因为在一页中可以保留更多的行指针。

● 越大的页,支持的行越长。应根据业务需求选择合适的数据页。

● 在默认的4KB页上,表只能有500列,而更大的页大小(8KB、16KB和32KB)支持1012列。

● 表空间的最大大小与表空间的页大小成正比,见表3-3。

3.扩展数据块在进行大小选择时的注意事项

EXTENTSIZE指定在跳到下一个容器之前,可以写入容器中的PAGESIZE页面的数量。存储数据时数据库管理器反复均衡使用所有容器。该参数只有在表空间中有多个容器时才起作用。选择合理的EXTENTSIZE 会对表空间的性能产生重大影响。因为这个参数是在创建表空间时定义的,之后不能修改,所以在创建时必须选择合理的EXTENTSIZE。

表空间的大小和类型

DMS表空间中的空间一次分配给表一个扩展数据块。当插入该表而一个扩展数据块变满时,会分配新的扩展数据块,直到彻底用完容器为止。

将 SMS 表空间中的空间一次分配给表一个扩展数据块或者一次分配给表一页。当插入该表而一个扩展数据块或页变满时,会分配新的扩展数据块或页,直到使用了文件系统中的所有扩展数据块或页为止。当使用SMS表空间时,允许进行多页文件分配,多页文件分配允许分配扩展数据块而不是一次分配一页。

每个表对象都是单独存储的,每个对象按需要分配新的扩展数据块。每个 DMS 表对象还与称为扩展数据块映像的元数据对象配成一对,该元数据对象描述表空间中属于表对象的所有扩展数据块。用于扩展数据块映像的空间也是以一次一个扩展数据块的方式分配。因此,DMS表空间中对象的初始空间分配是两个扩展数据块(SMS表空间中对象的初始空间分配是一页)。

如果在 DMS 表空间中有多个较小的表,那么可能要分配相对大的空间来存储相对少量的数据。在这种情况下,应该指定小的扩展数据块大小。另一方面,如果有一个增长速率较高的、非常大的表,并且使用具有较小扩展数据块大小的 DMS 表空间,那么可能会产生与其他扩展数据块的频繁分配相关的不需要的开销。

下面的经验法则建立在表空间中每个表的平均大小的基础上∶

● 如果小于50 MB,EXTENTSIZE 为8

● 如果介于50MB 到 500MB之间,EXTENTSIZE 为16

● 如果介于500 MB到5GB之间,EXTENTSIZE 为32

● 如果大于5GB,EXTENTSIZE 为64

针对这些表的访问类型

OLAP 数据库和大部分对表的访问包括许多查询或处理大量数据的事务(仅限于查询)的表,或者增长速度很快的表,从表中预取数据可以显著改善性能,应使用较大的 extent。反之,对于较小的频繁更改、频繁随机读取的小的配置表,建议使用较小的 extent。

如果打算在表的设计中使用多维聚簇(MDC),扩展数据块就是重要的设计决定之一。MDC 表将为创建的每个新的维集分配扩展数据块。如果扩展数据块太大,那么扩展数据块的很大一部分有可能是空的(对于包含很少记录的维集),这会造成非常大的空间浪费。关于MDC及其对 EXTENTSIZE 影响的更多信息,请参见《高级进阶DB2(第2版)》一书。

3.2.4 prefechsize 大小选择

为了提高数据库缓冲池的命中率,数据库通过预取操作在查询使用所需的数据之前读入这些数据,因为数据已经存在于内存中了,这样一来,查询在使用这些数据的时候就不必等待执行 I/O了。当数据库管理器确定顺序 I/O是适当的,并且确定预取操作可能有助于提高性能时,就选择预取操作。

通过使用 ALTER TABLESPACE 可以轻易地修改预取大小。最优设置差不多是下面这样的∶

Prefetch Size=(# Containers of the table space on different physical disks)* Extent Size

如果表空间驻留在某个磁盘阵列上,那么进行如下设置∶

PREFETCH SIZE = EXTENT SIZE *(# of non-parity disks in array)

注意∶

在DB2 V9版本以后,可以在创建表空间的时候自动预取大小。

在添加或删除容器后,可能忘记更新表空间的预取大小,此时应考虑允许数据库管理器自动确定预取大小。如果忘记更新预取大小,那么数据库性能可能会明显降低。所以可以在创建表空间时指定 PREFETCHSIZE 为 AUTOMATIC,这样就可以设置自动预取大小,并可以通过下面的快照监控来查看是否设置自动预取:

当然,PREFETCHSIZE的大小设置还和EXTENTSIZE的设置有关,所以首先要合理地设置EXTENTSIZE的大小,然后再根据EXTENTSIZE的大小设置PREFETCHSIZE。比较好的建议是创建数据库时采用自动存储。这样可由数据库管理器自动设置EXTENTSIZE 和PREFETCHSIZE的大小。

3.2.5 文件系统(CIO/DIO)和裸设备

在创建 DMS 容器时可以选择使用裸设备或文件系统,下面来看看两者的区别。我们知道,内存的读写效率比磁盘高近万倍,因此数据库通常会在内存中开辟一片区域,称为Buffer Pool,使数据的读写尽量在这部分内存中完成。同样,在文件系统中,操作系统为了提高读写效率,也会为文件系统开辟一块Buffer用于读写数据的缓存。这样,数据库中的数据会被缓存两次。为了避免操作系统的这次缓存,可以采用裸设备作为数据文件的存储设备。裸设备也称为裸分区(Raw Partition),是没有被加载(mount)到操作系统的文件系统中的磁盘分区,通过字符设备驱动来访问。裸设备的I/O读写不由操作系统控制,而是由应用程序(如数据库)直接控制。

裸设备的优点

● 由于屏蔽了文件系统缓冲区而进行直接读写,因此具有更好的性能。对硬盘的直接读写就意味着取消了硬盘与文件系统的同步需求。这一点对于纯OLTP系统非常有用,因为在这种系统中。读写的随机性非党大,以至于一旦数据被读写之后,它们在今后较长的一段时间内不会得到再次使用。除了OLTP,裸设备还能够从以下几个方面改善DSS(决策支持系统)应用程序的性能∶

  • 排序∶对于DSS环境中大量存在的排序需求,裸设备提供的直接写功能也非常有用,因为对临时表空间的写动作速度更快。
  • 顺序访问:裸设备非常适合于顺序I/O动作。同样,DSS中常见的顺序I/O(表/索引的全表扫描)使得裸设备更加适用于这种应用程序。

● 直接读写,不需要经过操作系统级的缓存。节约了内存资源,在一定程度上避免了内存的竞争。

● 避免了操作系统的cache预读功能,减少了I/O。

● 采用裸设备避免了文件系统的开销,比如维护i-node、空闲块等。

裸设备的缺点

● 裸设备的空间大小管理不灵活。在放置裸设备的时候,需要预先规划好裸设备的空间使用。还应当保留一部分裸设备以应付突发情况,这也是对空间的浪费。● 需要操作系统root用户干预,因为裸设备的创建、更改权限、扩展大小等都需要由root用户完成,这增加了管理的成本。

文件系统的优点

文件系统易于管理和维护,比如文件的基本管理以及安全和备份等。

文件系统的缺点∶

性能比不上裸设备。

我们在选择容器时,从性能上考虑尽量采用裸设备,但是如果使用自动存储方式创建数据库和表空间,这种方式不支持裸设备。或者为了便于管理而采用文件系统方式,这时候需要合理设置文件系统相关选项和表空间相关选项。下面讲解文件系统方面应该注意的事项。

CIO/DIO

直接 I/O(DIO)由于可以绕过在文件系统级别进行高速缓存,因此能改进内存性能。此过程可减少CPU开销并使得更多的内存可用于数据库实例。并发I/O(CIO)具有DIO的优点,并且还可以消除串行化写访问权。与使用文件系统缓冲I/O相比,在具有大量事务处理工作负载和回滚时,CIO/DIO机制可增大吞吐量。

DIO和CIO在HP-UX、Solaris、Linux和Windows操作系统的最新版本中都受支持,具体的支持列表请查看最新的DB2信息中心。

关键字NO FILE SYSTEM CACHING和FILE SYSTEM CACHING是CREATE和ALTER TABLESPACESQL语句的一部分,允许指定将对每个表空间使用DIO还是CIO。当 NO FILE SYSTEM CACHING有效时,只要可能,数据库管理器都会尝试使用“并发I/O"。在不支持CIO的情况下(例如,当使用了JFS时),将取而代之使用DIO。

建议在表空间级别启用或禁用UNIX、Linux和Windows中的非缓冲I/O。这将允许在特定表空间上启用或禁用非缓冲 I/O,同时避免数据库物理布局中的任何依赖性。另外还允许数据库管理器确定每个文件最适合使用哪种I/O,缓冲的还是非缓冲的。

NO FILE SYSTEM CACHING子句用于启用非缓冲I/O,从而禁用特定表空间的文件高速缓存。一旦启用非缓冲I/O,数据库管理器就会根据平台自动确定将使用直接I/O还是并发I/O。由于使用CIO可以提高性能,因此CIO只要受支持,数据库管理器就会使用。

FILE SYSTEM CACHING选项并不是总没有好处,例如当应用程序检索LOB或LONG 数据时,这些大对象数据不能经过数据库缓冲池,每次应用程序需要其中一个页时,数据库管理器必须从磁盘对之进行直接读取。但是,如果LOB或LONG数据存储在SMS或DMS文件容器中,文件系统的高速缓存可提供缓冲,因此也就改善了性能。

未在CREATE TABLESPACE 语句或CREATE DATABASE 命令中指定此属性时,数据库管理器将使用基于平台和文件系统类型的默认行为处理请求。为了查看是否启用FILE SYSTEM CACHING 属性,可以使用

● GET SNAPSHOT FOR TABLESPACES 命令

例如,以下是DB2 GET SNAPSHOT FOR TABLEPSACES ON SAPMPLE命令的输出∶

● db2pd -d <dbname> -tablespaces命令

● db2pd -d <dbname> l 命令

下面举几个关于文件缓存的例子。

例3-1 假定数据库和所有相关容器位于AIXJFS文件系统中,并且发出了以下语句∶

DB2 "CREATE TABLESPACE DATA_SPACE MANAGED BY DATABASE USING(file '/data/db2data' 800M)"

在先前版本中,如果未指定该属性,那么数据库管理器将使用缓冲I/O(FILE SYSTEM CACHING)作为I/O机制;对于DB2 V9.5及后续版本,数据库管理器使用NO FILE SYSTEM CACHING。

例3-2 在以下语句中,NO FILE SYSTEM CACHING子句指示对于此特定表空间,文件系统的高速缓存将OFF∶

CREATE TABLESPACE table space name ...NO FILE SYSTEM CACHING

例3-3 以下语句对现有表空间禁用文件系统的高速缓存∶

ALTER TABLESPACE table space name...NO FILE SYSTEM CACHING

例3-4 以下语句对现有表空间启用文件系统的高速缓存∶

ALTER TABLESPACE table space name..FILE SYSTEM CACHING

经过上面的讲解,建议创建表空间时,表空间的容器采用裸设备或支持并发 I/O或直接I/O的文件系统。

3.2.6 设置OVERHEAD和 TRANSFERRATE

这两个参数用于确定查询优化期间的 I/O 成本。这两个值的测量单位都是毫秒,而且它们应当分别是所有容器开销和传送速率的平均值。开销是与I/O 控制器活动、磁盘寻道时间和旋转延迟时间相关联的时间。传送速率是将一页读入内存所必需的时间量。它们的默认值分别是 24.1和0.9。可以根据硬件规格计算这些值。

Transrate =(1/传送速率)*1000/1024000*4096(假设用4KB页大小)

Overhead = 平均寻道时间+(((1/磁盘转速)*60*1000)/2)

而平均寻道时间、磁盘旋转速度和传送速率是由硬盘本身决定的(可以使用操作系统命令或从硬盘厂商获得底层硬盘的物理特性)。

所以我们必须合理地设置这两个值,以便让优化器了解底层存储的物理特性,从而制订最优的执行计划。

3.2.7 优化RAID设备上表空间的性能

3.2.8 合理设置系统临时表空间

系统临时表空间主要用于分组、排序、连接、重组和创建索引等。要确保系统临时表空间的最大页大小对于查询或定位更新来说足够大。

DB2 中大记录标识符(RID)的使用增加了来自查询或定位更新的结果集的行大小。如果结果集中的行大小接近于现有系统临时表空间的最大行长度限制,那么可能需要创建具有更大页大小的系统临时表空间。下面举个例子∶

假如表T1具有20个字段,T2具有18个字段,每行最大长度分别为3500字节和3000 字节,它们能正常地存放在4KB表空间中。但是如果发出如下这条 SQL 语句∶

select T1.*,2.* from T1,T2 where T1.id=T2.id

对于上面这条 SQL语句,在临时表空间中一行的长度已经达到6500(3500+3000)字节大小,这时原来 4KB的临时表空间已经不能存放,必须使用更大页大小的临时表空间。

所以要确保系统临时表空间的最大页大小对于查询或定位更新足够大,否则会显著影响性能。可以使用如下方法∶

● 确定来自查询或定位更新的结果集的最大行大小。使用曾用来创建表的 DDL 语句监控查询或者计算最大行大小。

● 检查结果集中的最大行大小是否适合系统临时表空间的页大小∶

maximum_row_size>maximum_row_length-8字节(单分区结构开销)

其中,maximum row size 是结果集的最大行大小,maximum row length 是基于所有系统临时表空间的最大页大小所允许的最大长度,应根据表空间页大小确定最大行长度。

● 创建系统临时表空间,其大小应至少比创建了表的表空间页大小大一页大小(假设还没有这样大小的系统临时表)。例如,在 UNIX操作系统中,如果在具有4KB页大小的表空间中创建了表,那么使用 8KB页大小创建额外系统临时表空间以备需要的时候使用∶

CREATE SYSTEM TEMPORARY TABLESPACE tmp_tbsp PAGESIZE 8K

MANAGED BY SYSTEM USING ('/datal/tmp tbsp','/data2/tmp_tbsp')

如果表空间页大小是 32KB,那么可以减少在查询中选择的信息或者分开这些查询以适合系统临时表空间页。例如,如果选择了表的所有列,那么可以改为仅选择真正需要的列或者选择某些列的子串来避免超出页大小限制。

3.3 缓冲池

缓冲池指的是从磁盘读取表和索引数据时,数据库管理器分配的用于高速缓存这些表或索引数据的内存区域。每个DB2数据库都必须具有至少一个缓冲池。数据库中的数据访问都需要经过缓冲池∶读的数据需要先读到缓冲池才能提交给应用,写的数据也是要先写到缓冲池才能进行 I/O。缓冲池是影响数据库性能的最大参数,所以必须合理地设计缓冲池。

创建数据库时,DB2会自动地创建名为IBMDEFAULTBP 的默认缓冲池,所有的表空间都共享该缓冲池。可以使用CREATE BUFFERPOOL、DROP BUFFERPOOL 和 ALTER BUFFERPOOL 语句来创建、删除和修改缓冲池。SYSCAT.BUFFERPOOLS 目录视图记录数据库中定义的缓冲池的信息。从 DB2 V9开始,缓冲池的默认大小都是自动调整,如果想取消自动调整,可以通过在 CREATE BUFFERPOOL 命令中指定 SIZE 关键字来设置固定值。足够的缓冲池大小是数据库拥有良好性能的关键所在,因为这可以减少磁盘 I/O 这一最耗时操作。大型缓冲池还会对查询优化产生影响,因为更多的工作可在内存中完成,而无须进行I/O。

3.3.1 缓冲池的使用方法

首次访问表中的数据行时,数据库管理器会将包含数据的页放入缓冲池中。这些页将一直保留在缓冲池中,直到关闭数据库或者其他页需要使用某一页占用的空间为止上。缓冲池中的页可能正在使用,也可能没有使用,它们可能是脏页,也可能是干净页。

● 正在使用的页就是当前正在读取或更新的页。为了保持数据的一致性,数据库管理器只允许一次只有一个代理程序更新缓冲池中的给定页。如果正在更新某页,那么只能允许一个代理程序互斥地访问。如果正在读取页,那么多个代理程序可以同时读取该页。

● "脏"页包含已更改但尚未写入磁盘的数据。

● 将已更改的页写入磁盘之后,该页就是"干净"页,并且可能仍然保留在缓冲池中。

大多数情况下,调整数据库涉及设置用于控制将数据移入缓冲池以及等待将数据从缓冲池写入磁盘的配置参数。如果最近的代理程序不需要页空间,那么可以将页空间用于新应用程序中的新页请求。额外的磁盘 I/O会使数据库管理器性能下降。

可使用数据库监控工具来计算缓冲池的命中率,缓冲池的命中率可帮助你调整缓冲池。

3.3.2 缓冲池和表空间之间的关系

设计缓冲池时,需要了解表空间与缓冲池之间的关系。每个表空间都与特定的缓冲池相关。IBMDEFAULTBP 是默认缓冲池。数据库管理器还会分配下列系统缓冲池∶IBMSYSTEMBP4K、IBMSYSTEMBP8K、IBMSYSTEMBP16K 和 IBMSYSTEMBP32K(以前称为"隐藏缓冲池")。要使另一个缓冲池与表空间相关,该缓冲池必须存在并且它们具有相同的页大小。关联是在使用CREATE TABLESPACE语句创建表空间时定义的,但以后可使用 ALTER TABLESPACE 语句更改关联。

如果拥有多个缓冲池,那么可以配置数据库使用更多的内存以改善整体性能。例如,对于OLAP类型的应用,我们建议采用大的缓冲池以利于大块顺序读取;用于联机事务应用程序的表空间可以根据业务特点使用多个小的缓冲池,以便可以更长时间地高速缓存应用程序使用的数据页,使响应时间更快。

图3-9是一个表空间和缓冲池设计示例。

该数据库有6个表空间∶数据库创建时默认生成的3个表空间——系统编目表空间、系统临时表空间和 USERSPACE1(使用默认的缓冲池 IBMDEFAULTBP);用户定义的常规表空间 MYREGSPACE(使用 MYBUFF1 缓冲池)、MYTEMPSPACE(使用MYBUFF2缓冲池);最后一个表空间用于放置一些频繁随机读写的比较重要的静态配置表(使用MYBUFF3缓冲池)。在图 3-9 中。我们没有看到为LONG表空间设置的缓冲池,这是因为大对象的读取不能经过内存,从磁盘直接读取。

3.3.3 维护缓冲池

缓冲池的页大小

默认缓冲池的页大小是在使用CREATE DATABASE 命令时设置的,此默认值表示所有将来 CREATE BUFFERPOOL和 CREATE TABLESPACE 语句的默认页大小。如果在创建数据库时不指定页大小,那么默认页大小是 4KB。

注意∶

如果确定数据库需要8KB、16 KB或32KB的页大小,那么必须至少定义一个具有相匹配的页大小并且与数据库中表空间相关联的缓冲池。选择用于缓冲池的页大小是很重要的,这是因为创建缓冲池之后就不能改变页大小了。

基于块(block)的缓冲池

DB2 允许留出缓冲池的一部分(最高可达 98%)用于基于块的预取操作。基于块的 I/O 可以通过将块读入相邻的内存区而不是将块分散装入单独的页,从而提高预取操作的效率。每个缓冲池的块大小必须相同,并且由 BLOCKSIZE 参数进行控制。该值等于块的大小(单位为页),取值范围从2到256,默认值为 32。

注意∶

基于块的缓冲池主要用于数据仓库、DSS之类的连续大块读写的应用中。

在创建新的缓冲池之前,应解决下列问题∶

● 想要使用什么缓冲池名称?

● 是立即创建缓冲池,还是在下一次取消激活,然后重新激活数据库之后创建缓冲池?

● 希望缓冲池的页大小是多大?

● 是将缓冲池设为固定大小,还是由数据库管理器自动调整缓冲池大小以对工作负载做出响应?建议在创建缓冲池期间不指定 SIZE 参数,从而允许数据库管理器自动调整缓冲池。

● 是否想保留一部分缓冲池用于基于块的I/O?

● 设计缓冲池时,还应根据机器上已安装的内存量以及与数据库管理器在同一机器上同时运行的其他应用程序所需要的内存来考虑内存要求。当没有足够内存来保存所访问的所有数据时,操作系统就会进行数据交换。将某些数据写入或交换到临时磁盘存储器中以为其他数据腾出空间时,就会进行数据交换。当需要临时磁盘存储器上的数据时,又会将数据交换回内存中。

创建缓冲池

恰当地定义缓冲池是拥有运行良好的系统的关键之一。对于 32 位操作系统,知道内存的寻址空间十分重要(AIX是1.75 GB;Linux是1.75 GB;Sun Solaris是3.35 GB;HP-UX 是大约 800MB;Windows 是2GB~3GB)。64 位系统没有这样的界限。

使用CREATE BUFFERPOOL 语句定义数据库管理器要使用的新缓冲池。以下是基本CREATE BUFFERPOOL 语句的示例∶

CREATE BUFFERPOOL BP3 SIZE 2000 PAGESIZE 8K

创建缓冲池的两个关键参数是 IMMEDIATE 和 DEFERRED。当使用 IMIMEDIATE 参数时,将立即更改缓冲池大小,而不必等到下一次激活数据库时才生效。默认情况下,新的缓冲池是使用IMIMEDIATE 关键字创建的。对于立即请求,不需要重新启动数据库,将立即激活缓冲池。如果数据库共享内存不足以分配新空间,那么会延迟(DEFERRED)运行该语句。

如果发出 CREATE BUFFERPOOL DEFERRED,那么不会立即激活缓冲池;将在下一次启动数据库时创建缓冲池。在重新启动数据库之前,任何新的表空间都将使用现有缓冲池,即使创建表空间时显式使用延迟缓冲池也是如此。

创建缓冲池时,应查看机器上是否有足够的内存用于已创建的所有缓冲池。要综合考虑操作系统中别的应用和操作系统本身的内存需求。

修改缓冲池

有许多理由要修改缓冲池,例如,为了启用自调整内存功能。为此,可以使用ALTER BUFFERPOOL 语句。可以修改缓冲池的如下属性∶

● 启用缓冲池自调整功能,从而允许数据库管理器根据工作负载调整缓冲池大小。

● 修改基于块的I/O的缓冲池的块区域。

● 修改部分缓冲池的大小。

使用 ALTER BUFFERPOOL 语句改变缓冲池对象的单个属性。例如∶

ALTER BUFFERPOOL buffer pool name SIZE number of pages

buffer pool name 是缓冲池名称,number of pages 是要分配给特定缓冲池的新页数。也可以使用值-1,用于指示缓冲池大小应该是在 BUFFPAGE数据库配置参数中设置的值。

查看缓冲池属性

通过查询 SYSCAT.BUFFERPOOLS系统视图可以列出缓冲池信息∶

要找出哪个缓冲池被分配给了表空间,请运行下面这个查询∶

可以在上一个查询中找到 BUFFERPOOLID,该查询使你能够看到每个表空间与哪个缓冲池相关联。

删除缓冲池

删除缓冲池时,应确保没有任何表空间已指定给这些缓冲池。不能删除 IBMDEFAULTBP 缓冲池。

可以使用 DROP BUFFERPOOL语句删除缓冲池,如下所示∶

DROP BUFFERPOOL <buffer pool name>

3.3.4 缓冲池的设计原则

缓冲池的命中率

使用多个用户表空间的最重要原因是管理缓冲池的命中率。一个表空间只能与一个缓冲池相关联,而一个缓冲池则可用于多个表空间。

缓冲池调优的目标是帮助 DB2尽可能好地利用可用于缓冲池的内存。整个缓冲池大小对 DB2性能有巨大影响,这是因为缓存大量的页可以显著地减少I/O这一最耗时操作。但是,如果总的缓冲池设置太大,并且没有足够的物理内存来分配给它们,那么系统将会使用隐藏缓冲池,性能就会急剧下降。要计算最大的缓冲池大小,需要综合考虑DB2、操作系统以及其他任何应用程序内存的使用率。一旦确定db2总的可用内存大小,就可以将这个区域划分成不同的缓冲池以提高命中率。如果有一些具有不同页大小的表空间,那么每种页大小必须至少有一个缓冲池。

拥有多个缓冲池可以最大限度地将数据保存在缓冲池中。例如,假设数据库有许多频繁使用的小型表,这些表通常都位于缓冲池中,因此访问起来就非常快。现在假设有针对非常大的表运行的查询,使用同一缓冲池并且需要读取比总的缓存池大小还多的页。当查询运行时,之前来自这些频繁使用的小型表的页将会丢失,这使得再次需要这些数据时就必须重新读取它们。

如果小型表拥有自己的缓冲池,那么它们就必须拥有自己的表空间,在这种情况下其他的查询就不能覆盖它们的页。这有可能产生更好的整体系统性能,虽然这会对大型查询造成一些小的负面影响。经常性地进行调优是为了实现整体性能的提高,而且时常需要在不同的系统功能之间做出权衡。区分功能的优先级并记住总吞吐量和使用情况,同时对系统性能进行调整,这是非常重要的。

DB2能够在不关闭数据库的情况下更改缓冲池大小。带有IMIMEDIATE选项的 ALTER BUFFERPOOL 语句会立刻生效,只要数据库共享的内存中有足够的保留空间可以分配给新空间。可以使用这个功能,根据使用过程中的周期变化(例如从白天的交互式使用转换到夜间的批处理工作)来调优数据库性能。

确定有多少缓冲池

对于由数据库中表空间使用的每一种页面大小,都需要至少一个缓冲池。通常,默认的IBMDEFAULTBP缓冲池是留给系统编目的。为处理表空间的不同页面大小和行为,需要创建新的缓冲池。

建议为每种页面大小使用缓冲池,对于 OLAP/DSS类型的工作负载更是如此。DB2在缓冲池的自我调优方面十分擅长,并且会将经常被访问的行放入内存,因此多数情况下对于每一种页的大小创建一个缓冲池就足够了(这一选择也避免了管理多个缓冲池的复杂性)。

如果时间允许,并且需要进行改进,那么可能希望使用多个缓冲池。其思想是将访问最频繁的行放入缓冲池中。在那些随机访问或者很少访问的表之间共享缓冲池可能会给缓冲池带来"污染",因为有时候要为本来可能不会再去访问的行消耗空间,甚至可能将经常访问的行挤出到磁盘上。如果将索引保留在它们自己的缓冲池中,那么在索引使用频繁的时候(例如索引扫描),还可以显著地提高性能。

这与我们对表空间的讨论是紧密联系的,因为要根据表空间中表的行为来分配缓冲池。如果采用多缓冲池的方法,对于初学者来说使用4个缓冲池比较合适∶

● 一个中等大小的缓冲池,用于临时表空间。

● 一个大型的缓冲池,用于索引表空间。

● 一个大型的缓冲池,用于那些包含经常要访问的表的表空间。

● 一个小型的缓冲池,用于那些包含访问不多的表、随机访问的表或顺序访问的表的表空间。

对于只包含LOB 数据的 DMS 表空间,可以为其分配任何缓冲池,因为LOB不占用缓冲池空间。

确定为缓冲池分配的内存

干万不要为缓冲池分配多于所能提供的内存,否则就会招致代价不菲的操作系统内存分页(memory paging)。通常来讲,如果没有进行监控,要想知道一开始为每个缓冲池分配多少内存是十分困难的。

对于OLTP类型的工作负载,一开始将25%(仅为参考,实际大小请参考自己操作系统中的内存资源和运行在操作系统中的应用情况)的可用内存分配给缓冲池比较合适。

对于OLAP/DSS,经验法则告诉我们,应该将40%(仅为参考,实际大小请参考自己操作系统中的内存资源和运行在操作系统中的应用情况)的可用内存分配给缓冲池(假设只有一种页面大小),同时监控排序情况,并对 SHEAPTHRES _SHR 和 SORTHEAP进行相应调整。

使用基于块(block-based)的缓冲池

连续读写频繁的OLAP查询可以得益于基于块的缓冲池。默认情况下,所有缓冲池都是基于页的,这意味着预取操作将把磁盘上相邻的页放入不相邻的内存中。而如果采用基于块的缓冲池,DB2将使用块 I/O 一次将多个页读入缓冲池中,这样可以显著提高顺序预取的性能。

基于块的缓冲池由数据页和扩展数据块同时组成。CREATE 和 ALTER BUFFERPOOLSQL 语句的 NUMBLOCKPAGES 参数用于定义块内存的大小,而 BLOCKSIZE 参数则指定每个块的大小,即在一次块I/O中从磁盘读取的页的数量。

共享相同扩展数据块大小的表空间应该成为特定的基于块的缓冲池的专门用户。将BLOCKSIZE 设置为等于正在使用缓冲池的表空间的 EXTENTSIZE 的整数倍。下面举一个创建基于块的缓冲池的例子∶

test2:/home/db2inst4$db2 create bufferpool block_bp size 40960 numblockpages

20480 blocksize 128

DB20000I The SQL command completed successfully.

确定分配多少内存给缓冲池内的块区要更为复杂一些。如果碰到大量的顺序预取操作,那么很可能会想要更多基于块的缓冲池。NUMBLOCKPAGES 应该是 BLOCKSIZE 的倍数,并且不能大于缓冲池页面数量的 98%。建议开始时先将其设小一点(不大于缓冲池总共大小的 15%或刚好 15%),在后面还可以根据快照监视(snapshot monitor)对其进行调整。

3.4 多温度存储器

多温度存储器是 DB2V10中新增加的特性之一,可以将不同访问频率的数据放置到不同的存储空间中。相对于以前的自动存储表空间和 DMS 表空间,这一特性增加了STORAGE GROUP 的概念,更加方便DBA对不同热度的数据进行管理,降低了维护成本和硬件成本。

在数据大爆炸的今天,每天都会产生数以万计的数据,但是只有一小部分数据是需要频繁被访问的,大部分历史数据在数据库里是很难被访问检索到的,我们称频繁被访问的数据为热数据,不经常被访问的数据为冷数据。我们通常希望将热数据放到快速的存储上,而将冷数据放到更加廉价的存储上,但是随着时间的推移,冷热数据有可能经常发生变化,如何将冷热数据在不同类型的存储上进行迅速调整,对于 DBA 来说是巨大挑战。在DB2V9.7中,通常做法是选择合适的存储来创建新的表空间,使用ADMIN_MOVE_TABLE 存储过程将原表空间所有的表都移动到新的表空间中,期间涉及大量的参数配置、存储过程的调用,难以监控和诊断,是一项非常艰巨的任务。但是在DB2 V10里面,只需要通过ALTER TABLESPACE改变 STORAGE GROUP即可。那么,STORAGE GROUP到底是什么东西呢?

3.4.1 存储器组

存储器组(STORAGE GROUP)是可存储数据的存储器路径的指定集合。存储器组配置为表示可供数据库系统使用的不同存储器类。可对存储器组指定最适合于数据的表空间。只有自动存储表空间才使用存储器组。

一个表空间只能与一个存储器组相关联,但一个存储器组可与多个表空间关联。要管理存储器组对象,可使用 CREATE STOGROUP、ALTER STOGROUP、RENAME STOGROUP、DROP和 COMMENT 语句。

  1. 查看存储器组

可以采用db2pd工具来查看STORAGE GROUP的详细信息,后面加-storagegroup参数:

也可以通过SYSCAT.STOGROUPS的系统视图来查看:

还可以通过系统函数ADMIN_GET_STORAGE_PATHS来查看STORAGE GROUP中包含的存储信息:

  1. 创建存储器组

为了创建存储器组,可以使用CREATE STOGROUP命令来完成,基本语法如下:

在下面这个例子中,我们创建了名为sg_cold的存储器组,将/db2/mydb/data_cold文件系统放到这个存储器组下:

  1. 修改存储器组

为了修改存储器组,可以使用ALTER STOGROUP命令来完成,基本语法如下:

比如,要增加某个容器的路径到sg_cold存储器组里,可以采用下面的命令:

查看新增加的存储路径:

  1. 删除存储器组

已存在的存储器组可以使用DROP STOGROUP命令来删除,在删除存储器组之前,必须确定是否有任何表空间使用该存储器组。如果有这样的表空间,那么在删除原始存储器组之前,必须更换这些表空间使用的存储器组并完成重新平衡操作。不能删除当前默认的存储器组。

PNBDBB:/home/db2test$db2 "drop stogroup sg_cold"

DB20000I The SQL command completed successfully.

  1. 默认存储器组

创建数据库时,会自动创建名为IBMSTOGROUP的默认存储器组。但是,使用AUTOMATIC STORAGE NO子句创建的数据库没有默认存储器组。使用CREATE STOGROUP 语句创建的第一个存储器组变为指定的默认存储器组。只有一个存储器组被指定为默认存储器组。如果数据库有存储器组,那么在未显式指定存储器组的情况下创建自动存储管理的表空间时会使用默认存储器组。

可以使用CREATE STOGROUP或 ALTER STOGROUP语句来指定默认存储器组。如果指定另一存储器组作为默认存储器组,那么对使用旧的默认存储器组的现有表空间没有影响。要改变与表空间相关联的存储器组,请使用 ALTER TABLESPACE 语句。

可以使用 SYSCAT.STOGROUPS目录视图来确定哪个存储器组是默认存储器组∶

3.4.2 表空间与存储器组

创建表空间时,可以通过 CREATE TABLESPACE 语句指定表空间使用的存储器组。如果创建表空间时未指定存储器组,那么会使用默认存储器组∶

对于已经存在的表空间,可以使用 ALTER TABLESPACE 语句修改存储器组,但是如果更改表空间使用的存储器组,那么落实 ALTER TABLESPACE 语句时会发出隐式REBALANCE操作。这会将数据从源存储器组移至目标存储器组。可使用表监视函数MON_GET_REBALANCE_STATUS监视REBALANCE操作的进度:

4.3 配置DB2服务器的TCP/IP通信

客户端要想访问db2数据库服务器,就必须先配置db2服务器的通信协议,db2服务器才会接受来自远程db2客户机的连接建立请求。

在配置db2实例的TCP/IP通信之前,必须检查以下内容:

● 如果 DB2 服务器正在使用 TCP/IP,那么 DB2客户机也必须正在使用TCP/IP 才能建立连接。

● 标识"连接服务名称"和"连接端口",,或仅标识"连接端口"。

连接服务名称和连接端口

连接服务名称用于更新服务器上数据库管理器配置文件中的"服务名称"(svcename)参数。当指定"连接服务名称"时,必须以相同的"服务名称"、端口号和协议更新 services 文件,services 文件包含在服务器上定义的服务及其端口号。"服务名称"是任意的,但是在 services 文件内必须唯一。服务名称的样本值可以是 serverl。"连接端口"在 services 文件中也必须唯一。端口号和协议的样本值可以是 50000/tcp。

连接端口

可以选择不使用"连接服务名称"而只是使用"连接端口号"更新服务器上数据库管理器配置文件中的"服务名称"(svcename)参数。这时就不会用到 services 文件,自然也不必更新 services 文件。如果正在使用分区格式的"DB2 企业服务器版",那么必须确保端口号与"快速通信管理器"(FCM)或系统中的任何其他应用程序使用的端口号没有冲突。端口号的样本值可以是 50000。

要配置DB2实例的TCP/IP服务器通信,需要以下几个步骤。

4.3.1 在服务器上更新 services 文件

TCP/IP services 文件指定服务器应用程序侦听客户机请求的端口。如果在 DBM 配置文件的 svcename字段中指定了服务名称,那么必须在 services 文件中添加一行,写入服务名称与端口号/协议的映射关系。如果在 DBM 配置文件的 svcename 字段中指定的不是服务名称而直接是端口号,那么不需要更新 services 文件。

在这里需要指出,services 文件的默认位置取决于操作系统,参考表4-2。

使用文本编辑器将"连接"条目添加至 services 文件。例如∶

db2c_db2inst1 50000/tcp #DB2连接服务端口

其中∶

● db2c_db2inst1表示连接服务名称。

●50000表示连接端口号(#50000是 DB2实例的默认端口),读者可以根据自己需要更改。

● tcp表示使用的通信协议。

注意∶

这个步骤在创建数据库实例的时候会自动更新services文件,在Windows平台上,5000 是DB2实例的默认端口,而在Linux/UNIX平台上,60000是DB2实例的默认端口,可以根据自己的需要更改成其他的端口号。

在UNIX平台上,在对应的/etc/services 文件中,默认配置为∶

4.3.2 在服务器上更新数据库管理器配置文件

更新数据库管理器配置文件在配置DB2实例的TCP/IP通信过程中是必不可少的一环。必须使用服务名称(svcename)参数更新数据库管理器配置文件。

要更新数据库管理器配置文件,必须完成以下操作∶

  1. 作为具有"系统管理员"(SYSADM)权限的用户登录系统。
  2. 启动DB2 命令行处理器(CLP)。
  3. 通过输入下列命令,用"服务名称"(svcename)参数更新数据库管理器配置文件∶

db2 update database manager configuration using svcename [service name|port_number]

db2stop

db2start

其中∶

  • Service_name是services文件中保留的服务名称。
  • Port_name是service_name的相应端口号或空闲的端口号(假设未保留service_name),如果正在指定服务名称,那么使用的svcename必须与在service文件中指定的“连接服务名称”相匹配。

这里需要注意,svcename不能联机配置,必须停启实例后才能生效。

在停止并再次启动数据库管理器之后,查看数据库管理器配置文件以确保这些更改已经生效。通过输入下列命令,查看数据库管理器配置文件∶

db2 get database manager configuration |find /i "svcename"

4.3.3 设置 DB2服务器的通信协议

要执行此任务,需要 sysadm 权限。为 DB2 实例设置通信协议是为 DB2 实例配置TCP/IP或SSL 通信的主要任务的一部分。

DB2COMM注册变量允许设置当前 DB2 实例的通信协议。如果 DB2COMM注册变量未定义或设置为空,那么启动数据库管理器时不会启动任何协议连接管理器。

可以使用下列其中一个关键字来设置 DB2COMM注册变量∶tcpip 启动TCP/IP支持,ssl启动SSL支持。

要为实例设置通信协议,可从 DB2命令窗口输入db2set DB2COMM命令∶

db2set DB2COMM=tcpip

例如,要将数据库管理器设置为对TCP/IP通信协议启动连接管理器,输入以下命令∶

db2set DB2COMM=tcpip

db2stop

db2start

4.3.4 查看服务器通信端口的状态

在执行完上面 3个步骤后,在系统中输入 netstat来查看通信端口的状态,如图 4-16 所示。通信端口必须处于"LISTENING"状态才能侦听来自客户端的TCP 请求。

4.4 配置客户机至服务器通信

4.4.1 客户机至服务器通信概述

要想配置客户机至服务器通信,必须先了解客户机至服务器通信有关的基本组件∶

● 客户机—指的是通信的发起方。

● 服务器—指的是来自客户机的通信请求的接收方。

● 通信协议——指的是用来在客户机和服务器之间发送数据的协议。DB2 产品支持以下几个协议∶

  • TCP/IP。可根据版本进行更进一步的区分∶TCP/IPv4或TCP/IPv6。O
  • IPC(进程间通信))。此协议用于本地连接。

客户机至服务器通信∶连接类型

通常,提到设置客户机至服务器通信时指的是远程连接,而不是本地连接。

本地连接是数据库管理器实例与由那个实例管理的数据库之间的连接。换句话说,CONNECT语句从数据库管理器实例发出给自己。本地连接是独特的,因为不需要设置通信并且使用了IPC。

远程连接是在其中发出 CONNECT语句到数据库的客户机和数据库服务器处于不同位置的连接。通常,客户机和服务器在不同的机器上。然而,如果客户机和服务器在不同的实例中,那么远程连接可能存在于同一台机器上。

另一个较不常用的连接类型是回送连接((loopback)。这是一种远程连接类型,该连接配置为从某个 DB2实例(客户机)到相同的 DB2实例(服务器)。

可以通过 CLP来配置客户机到服务器通信,下面讲解这种配置方式。

4.4.2 深入了解DB2节点目录、数据库目录

下面讲解如何使用命令行来配置客户机到服务器通信。在讲解客户机到服务器通信时,我们必须先弄清楚节点目录、系统数据库目录、本地数据库目录这几个概念。记得在刚开始学习 DB2 时,在成功地安装完之后,在配置客户机通信时,笔者被文档中的"cataloging nodes and databases"(编目节点和数据库)这件事给弄糊涂了。catalog 这个词与过去惹人喜爱的 SYSCAT和 SYSIBM目录相比有着动词化的意味。有时候,我会对着DB2 大声埋怨∶"我不想编目任何东西,我只是想在远程客户端通过运行一条 SELECT 语句来确保已正确地安装了 DB2。"经过对节点目录和数据库目录概念的仔细研究,我了解到只有在创建数据库之后DB2才会有数据库目录;不需要在本地机器上将节点和数据库编目—只有在连接到服务器的客户机上才需要编目。

在 DB2中,目录是存储有关系统、数据库及其连接信息的二进制文件。DB2中有以下几种目录∶

1.节点目录

节点目录用于存储远程数据库的所有连通性信息。下面只介绍 TCP/IP 协议。在节点目录中,大多数项将和TCP/IP信息有关,比如机器(其中包含了想连接的数据库)的主机名或IP 地址,还有相关的DB2实例的端口号。下面是一些与节点目录相关的命令∶

要列示本地节点目录的内容,可使用LIST NODE DIRECTORY命令。请从CLP发出下面这个命令∶

db2 list node directory

要将信息输入节点目录进行编目,请从CLP发出catalog命令∶

db2 catalog TCPIP node <node name> remote <hostname or IP address>

server <port_name or port number>

例如∶

db2 catalog TCPIP node nl remote 9.26.138.35 server 50000

要除去节点目录,请从 CLP发出uncatalog 命令∶

db2 uncatalog node n1

为了得到想要连接的远程实例的端口号,可以通过查看远程实例的dbm cfg中的svcename 参数来实现。该值通常对应于TCP/IP services 文件中的某一项。

在每个数据库客户机上都创建并维护节点目录。对于具有客户机可以访问的一个或多个数据库的每个远程客户端,该目录都包含一个条目。无论何时请求数据库连接或实例连接,DB2客户机都会使用该节点目录中的通信信息。该节点目录中的条目还包含客户机与远程实例通信时要使用的通信协议的类型信息。在图4-17中,如果想在Workstationl的instl 实例下访问同一台机器上的inst2实例和远程Workstations2上的inst3实例,那么必须在instl 下创建本地实例 inst2 和远程实例 inst3的节点目录。

可以这样理解, 要读取某个表,就必须先访问数据库; 可是要想访问数据库,就必须先访问实例,因为数据库是包含在实例中的。但是我们无法直接访问实例,因为实例不是"物理"的,而是逻辑的,实例是一组后端进程和共享内存的结合。所以在这种情况下,就需要为实例建立物理"映射",这就是节点目录的由来,所以节点目录是和实例对应的。如果实例就在本地,那么在创建实例的时候,默认会创建和实例同名的本地目录。这是隐式的,反正本地访问也用不到这个节点目录。但是如果在客户机上需要访问远程实例,就必须为该实例建立和实例对应的节点目录。这个节点目录告诉我们该实例驻留在哪个机器上(IP 地址,主机名),使用什么通信协议(设置 DB2COMM变量)和使用的通信端口(SVCENAME)。

节点目录默认在实例目录下,有两个文件∶SQLNODIR和 SQLNOBAK。其中,SQLNOBAK 是 SQLNODIR 的备份,当 SQLNODIR 被损坏时,把 SQLNOBAK 改名为 SQLNODIR 即可。这个文件是二进制的,不过在 Windows 中通过编辑器可以看到其中一些可读信息。

2.系统数据库目录(或系统 db 目录)

系统数据库目录包含本地数据库目录以及从远程映射到本地的数据库目录,是我们访问数据库的入口之一,连接数据库时首先去系统数据库目录中判断这个数据库是否存在,然后再判断这个数据库是本地数据库还是远程数据库。如果是本地数据库,就直接到本地物理目录上访问;如果是远程数据库,那么还要寻找这个远程数据库位于哪个节点上,然后再到节点目录中找到这个节点的通信信息。系统 db目录是在实例级上进行存储的;对于数据库管理器的每个实例,都存在系统数据库目录文件,该文件对于针对此实例编目的每个数据库都包含条目。因此,如果打算删除实例,那么应当考虑备份其中的内容。

要列出系统db目录的内容,请从 CLP发出下面这个命令∶

在上述命令输出中,任何包含单词"indirect"的项都意味着∶该项适用于本地数据库(也就是驻留在当前正在使用的机器上的数据库)。该项还会指向由"Database drive"项(在Windows 中)或"Local database directory"项(在 UNIX中)指示的本地数据库目录。

任何包含单词"Remote"的项都意味着∶该项适用于远程数据库(也就是驻留在其他机器上而非当前正在使用的机器上的数据库)。该项还会指向由"Node name"项指示的节点目录。

要将信息输入系统 db目录,需要使用 catalog 命令∶

db2 catalog db <db name> as <alias> at node <nodename>

例如∶

db2 catalog db mydb as yourdb at node mynode

节点名是指向节点目录中某一项的指针。在发出这条命令之前该项必须已经存在。要除去数据库目录,请从CLP发出 uncatalog 命令∶

db2 uncatalog db samplel

通常只有在将信息添加到远程数据库的系统 db 目录时才使用 catalog 命令。对于本地数据库来说,当发出 CREATE DATABASE命令创建数据库之后就自动创建 Catalog 项,将隐式地对数据库进行编目。

系统数据库目录中包含以下内容∶

●数据库名称、别名和注释

●本地数据库目录的位置

● 目录条目类型remote 表示数据库在远程数据库,indirect表示是本地数据库)

● 节点名(此节点名和节点目录中的节点名匹配)

系统数据库目录默认在实例目录下,有 3 个文件∶SQLDBDIR、SQLDBBAK 和SQLDBINS。其中,SQLDBBAK 是 SQLDBDIR 的备份,当 SQLDBDIR 被损坏时,把SQLDBBAK改名为SQLDBDIR即可。文件sqldbins只有分区数据库才会用到,是指向共享文件系统中另一个文件的符号链接。这些文件是二进制的,不过在windows中,通过编辑器可以看到其中一些可读信息。

本地数据库目录(或本地 db 目录)

本地数据库目录包含了有关本地数据库(也就是驻留在目前正在使用的机库)的信息。本地数据库目录驻留在数据库内部。当使用create database命令创建数据库时,将隐式地对数据库进行编目。在该目录中会添加一项。

要列出本地数据库目录的内容,请发出以下命令∶

其中,可以从系统db目录相应项中的"Database drive"项(Windows中)或"Lo directory"项(UNIX 中)获取<path>。

节点目录、系统数据库目录和本地数据库目录之间的关系,如图4-18所示

如果在workstation2连接inst3实例:

如果在workstation1连接远程实例和远程数据库:

图4-19完整地总结了节点目录、系统数据库目录和本地数据库目录之间的关系。

4.4.3 使用CLP配置客户机到服务器通信的案例

在了解了节点目录、系统数据库目录和本地数据库目录之后,如果想配置客户端到端的通信,那么可以参考下面的图4-20,其中归纳了客户端到服务器端通信的所有数,读者可以根据自己的实际情况填写这张表。

总的来说,要想配置客户端到服务器通信,需要经过下面几个步骤:

(1)更新 TCP/IP连接的 hosts 和 services 文件。

如果要建立到远程数据库服务器的连接(通过使用主机名),但是网络没有包含 DNS(均名服务器,用来解析主机名到IP 地址),那么必须更新 hosts 文件。如果要通过 IP 地址问远程数据库服务器,那么不需要此步骤。如果要在建立与远程数据库服务器的连接时指定连接服务名称,那么需要更新 services 文件。连接服务是表示连接端口号的任意名称。如果要访问远程数据库服务器的端口号,那么不需要此步骤。

要更新客户机上的hosts 文件以将远程服务器的主机名解析为IP地址,可以使用文本编辑器在hosts文件中添加条目,作为服务器的IP地址。例如:

其中,11.21.15.235表示ip_address,myserver表示hostname。

要更新客户机上的services文件以将服务名称解析为远程服务器的端口号,可以使用文本编辑器将"连接服务名称"和端口号添加到 services 文件中。例如∶

server1 50000/tcp #DB2connection service port

其中,server1 表示连接服务名称,50000表示连接端口号(50000为默认值)。 (2)使用CLP从客户机编目TCP/IP节点。

编目TCP/IP 节点会在数据在服务器的客户机节点目录中添加用于描述远程节点的条目。此条目指定客户机访问远程主机时选择的别名(node name)、hostname((或 ip address)和svcename(或 port_number)。catalog 命令如下∶

要编目端口号为50000、主机名为 serverl、节点名为db2node 的节点,应从 DB2提示符处输入以下内容∶

(3)使用CLP从客户机编目数据库。

必须先在客户机上编目数据库,客户机应用程序才能访问远程数据库。创建数据库时,除非指定不同的数据库别名,否则将自动在服务器上以与数据库名称相同的数据库别名编目数据库。在数据服务器客户机上使用数据库目录中的信息和节点目录中的信息(除非要编目不需要节点的本地数据库)来建立与远程数据库的连接。在编目远程数据库时需要数据库名称、数据库别名、节点名、认证类型(可选)、注释(可选)等信息。catalog db 命令如下∶

db2 catalog database database name as database_alias at node node_name [authentication auth_value]

要在使用认证 serverl的节点 db2node 上编目名为 sample 的远程数据库,以便具有本地数据库别名 mysample,可输入下列命令∶

db2 catalog database sample as mysample at node db2node authentication server

db2 terminate

(4)用于编目数据库的参数表。

使用表 4-3记录编目数据库所需的参数值。

(5)使用 CLP测试客户机至服务器的连接。

在编目节点和数据库之后,应连接至数据库以测试连接。在测试连接之前∶

● 数据库节点和数据库必须编目

● userid和 password 的值对于认证它们所在的系统必须有效

要测试客户机与服务器的连接,可在客户机的命令行输入以下命令以连接至远程数据库∶

db2 => connect to database alias user userid

例如∶

db2 => connect to sample user informix using informix

如果连接成功,会接收到一条消息,显示已连接数据库的名称。将给出类似图 4-21所示的消息。

现在就可以使用数据库了。例如,要检索系统目录表中所有表名的列表,可输入以下SQL语句∶

db2 SELECT tabname from syscat.tables

当结束使用数据库连接时,输入 connect reset 命令以结束数据库连接。

(6)客户机至服务器的连接配置总结。

图4-22所示的这个检查列表总结了配置客户机到服务器通信时的主要检查项。

上面演示了配置客户机到服务器 TCP 通信的过程,其实在实际生产中,除了TCP 通信,还有 APPC、APPN 和 NETBIOS等很多通信协议。但是这些通信协议我们都不常用到,在这里就不讲解了。而且在某些环境中,我们还会遇到一些其他组件∶

● DB2 Connect 网关。这里指的是DB2 Connect 服务器产品,该产品提供了一个网关,IBM 数据服务器客户机可通过该网关连接到中型机和大型机产品上的 DB2 服务器。

● LDAP(轻量级目录访问协议)。在启用了LDAP的环境中,不必配置客户机至服务器通信。当客户机试图连接至数据库时,如果本地机器的数据库目录中不存在该数据库,那么在 LDAP目录中搜索连接数据库必需的信息。

当服务器设置为使用开发环境时(例如 IBM Data Studio),可能会在初始 DB2连接时遇到错误信息SQL30081N。可能的根本原因是远程数据库服务器的防火墙阻止建立连接。在这种情况下,请验证是否正确配置了防火墙来接受客户机的连接请求。

4.6 案例:数据库连接问题诊断

下面以实际生产中遇到的数据库连接问题为例来说明针对该类问题的解决思路,供读者参考。

现象∶

某项目组向 DBA组报数据库故障,197.3.135.62上的数据库通过远程方式无法连接,而197.3.135.62本机却可以连接。并且昨天还好好的,今天就突然不行了。

解决思路∶

首先,先了解问题并重现问题。

在197.3.135.62上可以连接本地数据库∶

检查必要的参数配置,均正确无误∶

重现远程连接数据库失败的问题∶在另外一台服务器 197.3.137.200 上,catalog 197.3.135.62上的数据库PESDB∶

连接PESDB,报错SQL30081N,说明通信存在错误:

为了测试通信情况,我们直接telnet 197.3.135.62的60000端口,发现建立的连接会被瞬间关闭,说明数据库的60000端口的连接存在问题:

然后,对问题进行分析。

通过上面的现象,基本可以初步定位为数据库服务器的60000端口连接有问题。

于是,在197.3.135.62上分析60000端口的占用情况:

端口60000处于侦听状态,那么是哪个程序占用了60000端口并且在侦听呢?

我们看到如下奇怪的现象:除了数据库进程db2sys在60000端口侦听之外,WSH程序也占用了60000端口,是昨天晚上21:05启动的,如下所示:

WSH是 tuxedo 的进程,WSH用的端口是随机分配的,-p指定了最小端口,-P指定了最大端口。针对上面的情况,可以分配 2048~65535 之间的随机端口,因为分配了 60000 端口,所以与数据库端口发生冲突。

最后,解决问题。在将WSH进程重启后,为之随机分配了其他端口57982和57983,释放对60000端口的占用,数据库可以正常连接了。当然,基本解决办法是规范 tuxedo 程序占用的端口范围,避开数据库端口。

创建表空间

创建存储器

创建缓冲池

创建数据库对象

模式

索引

视图

序列

表表达式

触发器

备份、恢复和迁移

迁移

备份

恢复

SQL基础

监控

管理

设计和优化(拓展)

数据库配置参数调整(拓展)

锁和并发(拓展)

举报
评论 0