数据的高可用性对于商业问题的随需应变解决方案来说是至关重要的。如果您是 developerWorks 的老读者,就可能已经熟悉用于提供高可用性的解决方案,这在 DB2 Universal Database 和高可用数据存储等文章中已进行了讨论。那篇文章向您介绍了获得高可用性的理由,并就您可能的选择加以讨论。
但是如果您正接近于实现阶段,那么可能会发现参考一个特定实例,对于了解如何在客户现场针对 AIX 上的 DB2 UDB Enterprise Server Edition(ESE)设置高可用性和灾难恢复场景是很有价值的。
我们例子中的应用程序是一个由技术服务雇员所使用的系统,这些雇员将技术问题发送给遍及美国的技术解决单位。这是一个联机事务处理(OLTP)应用程序,有 10,000 位用户访问该系统以发送技术问题。
该系统对于高可用性具有特殊的需求。该系统是一个在接近于现实生产环境中实现的概念验证(proof-of-concept,POC)系统。在该 POC 中,我们测试了 DB2 UDB V8.1 ESE 的高可用性和复制。复制用于灾难恢复目的,这里将要使用带有更新冲突检测的对等式复制。本文重点关注 POC 的高可用性方面,将不介绍复制那部分。
通过该 POC,我们还测试了 DB2 UDB 架构的扩展性和可伸缩性能力,因为该项目正在其他地区扩展更多群集。现在,该系统在纽约地区仅部署了一个带有两个服务器的群集。将来,马里兰州还将有一个附加的群集,以及在佛罗里达将会有一台独立的服务器,用以提供附加的可用性和灾难恢复功能。在 POC 中,我们模拟了所有的三种环境和服务器集合的存在(一个群集在纽约,两台单独的服务器在佛罗里达和马里兰州),惟一的区别就是出于测试目的,它们在物理上都位于纽约的客户实验室里。
我们需要测试性能、可靠性、稳定性,并需要取得最快的故障转移时间,其目标故障转移时间要少于 60 秒。在不到一周的时间里,我们设置了一个完全高可用性的相互接管场景,以及带有冲突更新设置的三向对等式复制。这是在总共四台服务器上实现的,其中有两台服务器处于群集中。每台服务器都拥有两个 DB2 实例,因为我们使用的是不带分区功能的 DB2 UDB ESE,所以我们还需要实现相互接管。
出于下列两个理由,我们选择了相互接管,而非备用配置:
- 客户需要最大的可用性。这意味着当一台服务器关闭时,另一台就在不间断地运行。因此,直接向一台服务器发出的一半应用程序请求不会产生任何问题,而直接向失效服务器发出的另一半请求就必须迁移到故障转移服务器上。这在备用场景中是不可能的,因为所有的客户机/应用程序请求都直接发向一台服务器,如果主服务器发生故障,它们就都将失败。其代价就是必须将两台机器都配置为处理双倍工作负载,尽管在常规操作下,仅仅使用了一半容量。同样,如果两个应用程序是不同的,且使用不同的数据库,就只能实现相互接管。
- 客户需要同时使用两台服务器,且在任何时刻都没有空闲服务器。在备用配置中,备用服务器在等待生产服务器发生故障时是空闲的。这是个很重要的理由,虽然我们可以回答说,在相互接管的环境中,两台服务器都只运行了一半容量,因此在常规环境中,我们都未充分利用它们。
第一个因素强烈地驱使我们决定对这个特定的项目实施相互接管,特别是因为该客户要运行两个应用程序和两个数据库。
用于在 AIX 上实现群集和故障转移过程的软件是 IBM HACMP。HACMP 完成下列工作:
- 它在群集中的服务器之间连续发送心跳(heartbeat),指定是否以及何时关闭其中的服务器。
- 它提供工具以定义和管理参与高可用性设置的资源组,包括共享磁盘、网络适配器以及将处理数据库启动和停止的应用程序服务器。
- 发生故障或者服务器从故障中恢复之后,它按需处理从一个系统到另一个的资源组的故障转移。
DB2 UDB 带有一组脚本,这些脚本定义了发生系统故障或恢复时它的行为。在 DB2 UDB 单分区环境中,该脚本执行下列动作:
- 如果一台服务器发生故障,它就将启动备用服务器上的 DB2 UDB。
- 如果失效服务器重新集成到 HA 群集中(即重新变得可用),它将停止备用服务器上的数据库,并启动重新集成的服务器上的数据库。这还取决于 HA 群集的配置。
基本脚本名为
db2.pe 。它具有两个版本:
-
db2.pe.ee- 用于带有单个分区的数据库。该脚本极其简单,仅包含数据库的启动和停止。 -
db2.pe.eee- 用于多分区的环境。该脚本更为复杂一些,因为它要启动多个分区,清理系统,以及为每个分区进行适当的故障转移更新一些配置参数和文件。
实际上,该脚本(当发生故障转移时,启动另一服务器上的数据库或分区,或者当修复故障时,停止备用服务器上的数据库,并重新启动原来的那个)是 DB2 UDB 在高可用性环境中执行的最重要的任务。这是由于其无共享(shared-nothing)的架构。(关于无共享架构的更多信息,请参阅 DB2 Information Center中的解释。在非并发访问的环境中,两个服务器会同时访问磁盘,DB2 故障转移中的延迟主要是由于需要 varyon 和 varyoff 共享卷组(HACMP 术语),或者换言之,是由于需要将共享磁盘和资源的控制和访问从一台服务器移动到另一服务器上。将共享磁盘的控制和访问从一台服务器转移到另一服务器的这项任务在分区和非分区环境中都必须进行。
取决于磁盘的大小和数量,单单是该任务(将共享磁盘的访问从一台服务器移动到另一服务器)就可能占用相当多的时间。本例中,因为我们使用两个卷组,每个卷组包含一个磁盘,而磁盘空间并不大(每个磁盘仅仅有 9GB,两个磁盘总共是 18GB),所以磁盘的故障转移时间大约是 20 秒。如果您使用原始设备,或者使用并发访问,那么就可以极大地减少这一时间。
我们使用了系统管理的表空间(SMS)和日志记录文件系统(JFS)。AIX 上的 SMS 需要 JFS,而本例中不可能进行并发访问。如果我们必须添加更多磁盘,那么将增加故障转移时间。通过使用原始设备将减少此开销。为了进一步提高故障转移的性能,我们可以使用原始设备,特别是如果我们有许多磁盘,而不像本例一样只有一两个,就更要使用原始设备。通过数据库管理的空间(DMS)和原始设备,我们可以减少磁盘资源的故障转移时间,因为在故障转移时将不会进行磁盘检查。我们还可以对原始磁盘进行 并发访问,甚至可以进一步减少故障转移时间。HACMP 还必须对所有其他资源(如网络适配器)进行故障转移,但是,将会最小化时间最长的磁盘故障转移。因此,您将使用并发访问以获得更快的故障转移时间。
在 HACMP version 5.1 中,通过在设置共享磁盘访问时使用增强的并发访问选项,以一种简单却优雅的方式实现了该功能。该功能免除了将磁盘访问从一台服务器切换至另一台的需要。在我们进行设置时,HACMP 5.1 还处在不可用的阶段。
群集需要尽可能地用最高可用性时间来实现高可用性。为了负载平衡和灾难恢复,客户需要将群集放置在不同的位置。本例中,复制用于灾难恢复。数据库相对较小,此时大小仅为 5-10 GB。应用程序是一个 C 应用程序,并使用 WebSphere® 作为 Web 应用程序服务器。
该 POC 的目标就是实现高可用性,且目标是要取得高于 99.999% 的可用性。
用以在 AIX 上用 HACMP 设置高可用性环境的工作是:
- 定义卷组合逻辑卷
- 定义适配器
- 安装 DB2 UDB
- 安装并定制 DB2 HA 脚本
- 定义应用程序服务器
- 同步群集
- 调优 DB2 性能
- 定制应用程序,以便在返回 连接失败的错误消息时重新进行连接
- 测试
配置包括两台 RISC/6000 服务器 7026H70,每台带有四个 CPU,1GB 内存,运行于 AIX 5.1 维护级别 3。这是一个安装了 HACMP 4.4.1 的群集(最初是 4.4.0,但是该版本不支持 AIX 5L)。这两台服务器连接到一个 SSA 共享磁盘阵列 7133-020,该磁盘阵列带有 RAID 5 镜像以及 136.1GB 的存储总量。虽然一共有 15 个磁盘,但是我们只能看到 5 个磁盘,每个 9.1GB。对于该测试,我们仅仅使用两个磁盘,每个实例一个磁盘。这是一个由两台服务器组成的群集。服务器的名称是 HADB1和 HADB2。
客户需要实现主-主(active-active)或相互接管(mutual-takeover)功能。因为要运行不同的应用程序,且带有两个不同的数据库,客户还需要在每个环境中建立两个的实例用以隔离其系统。
因此,总体需求就是要为两个不同的应用程序以及两个不同的数据库保持隔离环境。他们需要分隔实例以及同时运行两台服务器的理由就是为了降低多个并发应用程序发生故障的可能性。在分隔的环境中,如果一台服务器失效,仍然可以继续并连接第二台服务器上的另一个实例。如果在热备用配置中的一台服务器上运行两个应用程序,那么当该服务器发生故障时,两个应用程序以及访问这些应用程序的两组用户就都必须进行故障转移。现在,通过两台不同的服务器、两个实例和两个数据库,即使一台服务器发生了故障,总还是有一组用户可以是活动的。如果两台服务器都发生了故障,就使用到第三个灾难恢复服务器集的副本将应用程序引导至复制节点。
我们决定用 DB2 UDB ESE V8.1 获得相互接管场景,每个服务器有两个实例。每个实例如果在某台服务器上是活动的(active),那在另一台服务器上就是被动的(passive)。 图 1展示了一个常规操作图:
图 1. 常规的相互接管场景
通过该图,您可以看到每台服务器都具有三个适配器。(实际上有四个适配器。我们没有展示第四个,因为第四个适配器是仅供管理员使用的后门适配器。)
- 第一个是带有独立或持久的 IP 地址的启动适配器。机器就是通过这里启动的。
- 服务适配器具有一个浮动的 IP 地址。所有的应用程序就是在该适配器中连接到每个服务器的主实例。该适配器的 IP 地址是浮动的,这意味着无论实例在何处运行,在服务器 HADB1 上或在服务器 HADB2 上,此浮动的 IP 地址都保持相同,而应用程序也不会看到任何改变 -- 当然除了断开连接和重新连接之外。
- 第三个适配器是备用适配器。在常规操作中,该适配器是被动的,并一直等待发生故障。当一台服务器上发生故障时,那么该备用适配器就从另一服务器上接管所有连接。该备用适配器就成为服务适配器,用于进行故障转移的实例。因此,当发生故障时,该适配器就成为服务器适配器的浮动地址背后的物理地址。
在该拓扑中,有一个单点故障。该故障就是如果处于故障转移(failover)模式下,一台服务器上的两个实例都将是活动的(active)。如果那时两个适配器中有一个发生故障,那么就没有额外的备用适配器来用作备份了。为了恢复,我们将需要第四个适配器来作为备用适配器。对于两个适配器同时发生故障的罕有情况,我们将需要两个额外的备用适配器,来处理所有潜在的单点故障。
名称 en0、en1 和 en2 对应于适配器的物理设备名。当在群集拓扑中配置适配器和应用程序使用适配器时,它们的名称是:
对于服务器 HADB1:
- En0 -> db1aboot,启动适配器,用于启动机器。它总是具有独立的地址
- En1 -> db1asvc,带有浮动 IP 地址 128.209.61.3 的服务适配器
- En2 -> db1astby,备用适配器,可以从服务器 HADB2 接管服务器的浮动 IP 地址
对于服务器 HADB2:
- En0 -> db2aboot,启动适配器,用于启动机器。它总是具有独立的地址
- En1 -> db2asvc,带有浮动 IP 地址 128.209.61.4 的服务适配器
- En2 -> db2astby,备用适配器,可以从服务器 HADB1 接管服务器的浮动 IP 地址
图 2展示了服务器 HADB1 上发生故障,第二台服务器 HADB2 接管该应用程序之后的状态。
图 2. 故障之后的相互接管
当发生故障时,例如服务器 HADB1 失效,那么连接到 HADB1 的所有用户都要断开到数据库的连接。应用程序只会得到一条信息,说明目前没有到数据库的连接。
应用程序应该了解 表 1中所列的错误代码,HA 环境中进行故障转移时可能碰到这些错误代码。应用程序还会尝试重新建立连接以继续执行:
| SQLCODE | SQLSTATE |
| -900 | 08003 |
| -1015 | 55025 |
| -1034 | 58031 |
| -1035 | 57019 |
| -1224 | 55032 |
| -1229 | 40504 |
| -6036 | n/a |
| -30081 | 08001 |
因此当服务器 HACDB1 发生故障时,应用程序将接收上表中的一条消息。本例中,应用程序将进入循环,并尝试重新进行连接,直到完成故障转移,以及服务器 HADB1 上的实例 db2admin 在备用服务器 HADB2 上重新可用。
当完成故障转移时,就可以使用该实例,应用程序中的连接语句就会成功。然后,应用程序退出该循环,并继续常规操作。
这就是在应用程序端所发生的过程。您可以在 HACMP 目录的 hacmp.out 文件中找到关于故障转移期间所发生的一系列事件的极为详细的描述及其计时(每个事件在整个故障转移中所占用的时间)。从 DB2 端来看,可以在 DB2 UDB 的
sqllib 目录下的
db2diag.log 文件中追踪所有的 DB2 活动。
首先,我们需要准备将用于配置中的磁盘和卷组。
我们需要定义卷组。基于我们的设计,每个实例将分配一个卷组,该卷组将是一个共享磁盘,能够在服务器发生故障时从一台服务器故障转移到另一台并恢复。我们决定不要自动进行故障恢复到初始服务器。这意味着当初始服务器返回正常状态时,该磁盘将不会自动切回。这是因为当服务器再次恢复时,管理员很可能需要执行维护工作,并且不需要立即将实例送回初始服务器。因此,对于测试的第一个阶段来说,将会禁止群集中服务器的自动再集成。
因为我们具有两个实例,所以需要两个卷组。每个实例都需要其自己的卷组。为了获得更快的故障转移时间,最佳配置是使用 DMS 表空间和原始设备,甚至最好允许对磁盘的并发访问。这意味着在进行故障转移时,HACMP 软件不必 varyoff 和 varyon 磁盘 -- 表示将连接从失效服务器转移到活动服务器,以便活动服务器由于并发访问而访问共享磁盘。如果数据库很大,那原始设备的使用也能减少故障转移时间,因为进行故障转移时,操作系统不必对文件系统进行文件检查(fsck)。
本例中,因为数据库是如此小,仅有 1-2GB,所以我们简化了设计,仅仅使用默认的 SMS 表空间,因此,我们只能使用 JFS(日志记录文件系统)。卷组仅仅将持有一个磁盘,并且在该磁盘上,我们定义了三个共享的实例目录,分别是实例所有者的主目录、用于受保护(fenced)ID 的目录以及用于管理服务器的目录。
对于 DB2 实例 db2admin,我们将使用卷组 vgA,而对于 DB2 实例 db2adma,则使用卷组 vgB。实例 db2admin 将拥有主服务器 HADB1,而 db2adma 将拥有主服务器 HADB2。每个都将另一服务器当作故障转移的目标服务器。这两个实例的用户 ID 会在下面给出,而两个服务器中的定义必须完全相同。这甚至包括 TCP/IP 连接的端口号和服务名称的定义。两个服务器中 DB2 UDB 的所有定义和设置都必须一样。当然,两台服务器中的每个实例之所以必须具有完全相同的配置、用户标识、文件系统、端口号等的原因就是,应用程序不应看到两台服务器之间存在任何区别。如果一台服务器故障转移到第二台服务器上,那么应用程序将不会由于目录名等不同而产生任何问题。
以下就是我们的配置:
系统:HADB1
- 管理服务器的用户 ID:radmin
- 密码:radmin
- 32 位实例
- 单个分区
- 用于第一个实例的实例用户 ID:db2admin
- 密码:db2admin
- 服务名:db2c_db2admin
- 端口号:50000
- 受保护的用户 ID:db2fence
- 受保护的用户的密码:db2fence
- 用于第二个实例的实例用户 ID:db2adma
- 服务名:DB2_db2adma
- 端口号:60004
- 受保护的用户 ID:db2fenca
- 受保护的用户的密码:db2fenca
- 身份验证:客户机
- 自动启动关闭
我们需要向 etc/group 文件手工添加两项,该文件中定义了 SYSADM/ 实例所有者的组 ID。我们添加一行:
- db2admg: db2admin, db2adma
- 安装路径是:/home/db2amdin,
- /home/db2fence
- /usr/opt/db2_v08_01 for binaries
- /home/db2amda,/home/db2fenca
系统:HADB2
- 管理服务器用户 ID:radmin
- 密码:radmin
- 32 位实例
- 单个分区
- 用于第一个实例的实例用户 ID:db2admin
- 密码:db2admin
- 服务名:db2c_db2admin
- 端口号:50000
- 受保护的用户 ID:db2fence
- 受保护的密码:db2fence
- 用于第二个实例的实例用户 ID:db2adma
- 服务名:DB2_db2adma
- 端口号:60004
- 受保护的用户 ID:db2fenca
- 受保护的密码:db2fenca
- 身份验证:客户机
- 自动启动关闭
我们需要向 etc/group 文件手工添加两项,该文件中定义了 SYSADM/ 实例所有者的组 ID。我们添加一行:
- db2admg: db2admin, db2adma
- 安装路径:/home/db2admin,
- /home/db2fence
- /usr/opt/db2_v08_01 for binaries
- /home/db2amda,/home/db2fenca
安装 DB2 UDB 之前,我们应配置 HACMP,以便卷组和磁盘都早已适合于 DB2 UDB 的安装和配置。
因此,第一步就是在 HACMP 中定义共享的 DASD。
1. 定义磁盘驱动器。本系统中,我们每个实例仅仅必须使用一个磁盘。用于第一个实例的磁盘物理名称是 pdisk10,它在服务器 HADB1 和 HADB2 上将分配卷组 vgA以及逻辑名 hdisk16。至于 vgB,将分配给第二个实例,它在服务器 HADB1 和 HADB2 上的物理磁盘名和逻辑名分别是 pdisk11 和 hdisk17。
|
| 第一个实例(db2admin) | 第二个实例(db2adma) |
| 卷组名 | vgA | vgB |
| 物理磁盘名 | pdisk10 | pdisk11 |
| 逻辑磁盘名 | HADB1 上是 Hdisk16,HADB2 上是 hdisk17 | HADB1 上是 Hdisk16,HADB2 上是 hdisk17 |
服务器 HADB1
| PDISK | HDISK |
序列号 | PVID | 卷 |
| 组 |
|
|
|
|
| pdisk10 | hdisk16 | 294CF915 | 00015198ad4cd369 | vgA |
| pdisk11 | hdisk17 | 294D02DD | 00011233737e8532 | vgB |
| pdisk12 | hdisk8 | 29CC9F0A | 无 | 无 |
| pdisk13 | hdisk9 | 29D27E33 | 无 | 无 |
| pdisk14 | hdisk10 | 29D291A8 | 无 | 无 |
|
| hdisk11 | 3E42AE12 | 0001156073b90800 | 无 |
服务器 HADB2
|
PDISK |
HDISK |
序列号 |
PVID |
卷 |
| 组 |
|
|
|
|
| pdisk10 | hdisk16 | 294CF915 | 00015198ad4cd369 | vgA |
| pdisk11 | hdisk17 | 294D02DD | 00011233737e8532 | vgB |
| pdisk12 | hdisk18 | 29CC9F0A | 无 | 无 |
| pdisk13 | hdisk19 | 29D27E33 | 无 | 无 |
| pdisk14 | hdisk20 | 29D291A8 | 无 | 无 |
|
| hdisk6 | 3E42AE12 | 0001156073b90800 | 无 |
使用
lsdev
命令来获取系统中的所有磁盘列表。为了使该配置正常工作,两台服务器上应具有相同数目的磁盘。本例中,我们仅仅使用了一个磁盘,但是如果您打算在每台服务器上安装不止一个磁盘,就要确保每台服务器上的磁盘数目相同。关于磁盘对称性和确切 AIX 命令的更多细节,请阅读
DB2 Universal Database and the highly available data store上第 6 页的白皮书 DB2 Universal Database Enterprise Edition for AIX and HACMP/ES。
2. 定义了磁盘之后,您就可以定义卷组了。AIX 上的卷组是一些将用于共享磁盘环境中的磁盘组,且它们也是可以根据需要从一台服务器到另一台进行故障转移并恢复的对象。这些磁盘收集在一个组中,称作 卷组。
本例中,我们在 HADB1 上定义了所有一切,然后使另一台服务器 HADB2 上的定义同步。我们不必进行两次相同的定义。本实例中,我们在 HADB2 上定义了两个卷组,vgA 和 vgB,分别包含磁盘 hdisk16 和 hdisk6。该定义自动应用到了 HADB2。然后,我们将每个卷组挂到了其主服务器上。
对于 vgA,我们通过从 HADB1 使用命令将之挂到了 HADB2 上:
# varyonvg vgA
从 HADB2,我们使用命令:
# varyonvg vgB
现在,两个卷组都可用了,并按照在常规操作中一样挂到了各自的服务器上。
3. 在位卷组创建逻辑卷之前,创建 JFS 日志。这样做是因为 JFS 日志的名称必须是惟一的。本例中,因为每个卷组仅将创建一个 JFS,所以我们不必专门给 JFS 日志命名,因此跳过了该步骤。在白皮书“DB2 Universal Database Enterprise Edition for AIX and HACMP/ES”的第 7 页上有更多细节。
4. 创建逻辑卷和 JFS 系统。它们必须具有惟一的名字,且当前未在任何节点上进行了定义。同样,应设置该文件系统,以使重新启动时不会挂载它们。
本例中,每个卷组都创建了逻辑卷。每个逻辑卷对应于一个目录。
表 2. 卷组目录
| 卷组 | 目录 | 逻辑名 |
| vgA | /HOME/db2admin | admin |
| vgA | /HOME/db2fence | fence |
| vgA | /dbA | dbA |
| vgB | /HOME/db2adma | db2adma |
| vgB | /HOME/db2fenca | fencea |
| vgB | /dbB | dbB |
每个逻辑名都将创建一个新的 JFS。让每个磁盘(若为原始设备)或文件系统(如果是 SMS,就是 JFS)都具有一个不同的逻辑名既有其优点,也有不足。( 注意:在 AIX 中,您对于 SMS 表空间只能使用 JFS。)
具有多个 JFS 的优点就是通过并行 I/O 优化了性能。这在大型数据库中更加重要。为了获得更快的故障转移性能,文件系统越小越好。
我们使用的是 RAID5,因此不会镜像逻辑卷。
然后挂载所创建的文件系统,因为它们不会自动被挂载。在创建文件系统的过程中,我们定义不自动挂载它们。在修改文件系统的所有权,将之指派给实例所有者用户 ID 之后,我们就卸载文件系统,并且 varyoff 卷组。然后,我们通过相同的主编号将 HADB1 服务器上所创建的卷组导入 HADB2 服务器。它在重新启动时将不会自动激活,以便仅当 HACMP 启动它时,才被激活。
最后,设置完两台服务器之后,就返回常规操作,这意味着我们需要将 vgA 挂到(varyonvg vgA)HADB1 服务器上,并从 HADB2 发出 varyonvg vgB 将 vgB 挂到 HADB2。
通过该工作,我们就完成了存储磁盘的设置。
1. 在 HADB1 上,初始创建 DB2 UDB 的用户 ID,并使用
db2setup 命令安装 DB2。本例中,初始安装 DB2 之后,我们还使用命令
db2icrt -u db2denca db2adma
安装了附加实例。
db2fenca 是受保护的用户 ID,而
db2adma 是第二个实例的 ID。我们还更新了
etc 目录下的
tcpip 组文件,用以反映第二个实例。并且检查 etc/services 文件,以确认正确分配了端口号。
在 HADB1 上安装了 DB2 UDB 之后,就使用
db2_inst_ha.local 脚本来安装 HACMP 脚本。该脚本位于
/usr/opt/db2_08_01/sample/hacmp/es 。仅通过下列命令,您就可以运行它:
#./db2_inst_ha.local db2admin.SAMPLE
(其中 db2admin 就是实例所有者的 ID,“.”代表我们发出命令的目录,而 SAMPLE 就是在故障转移时需要使用的数据库名。)
这会将 HA 脚本安装到
/usr/bin 目录中。该配置中将使用的惟一脚本就是
rc.db2pe 脚本。请确保已链接到
rc.db2pe.ee 版本,因为还有用于多个分区的
rc.db2pe.eee 版本。
该脚本只是基于在发出脚本时所发送的参数来启动和停止数据库实例。HACMP 使用该脚本,作为
rc.db2pe start 或者作为
rc.db2pe stop 。第一种情况中,该脚本读取 start 选项并启动实例,而在第二种情况中,它仅仅用 force 选项停止实例。
现在,从 DB2 UDB 的角度来设置 HADB1 节点,您要卸载文件系统并 varyoffvg vgA 和 vgB。然后在 HADB2 节点上,varyonvg vgA 和 vgB 并重新在 HADB2 服务器上挂载所有的文件系统。
2. 在 HADB2 上,我们需要删除与 HADB1 上所创建实例有关的目录,因为我们不允许在第二台服务器上安装两个实例,因为 vgA 和 vgB 上的共享磁盘已经包含这些目录。因此,我们需要在 HADB2 上卸载它们,再重新安装。
因此,使用
#rm -rf /home/db2admin/sqllib
和
#rm -rf /home/db2adma/sqllib
命令在 HADB2 上删除目录
/home/db2admin/sqllib 和
/home/db2adma/sqllib 。
- 然后使用 db2setup命令创建用户 ID,并安装 DB2 UDB。对 HADB1 重复相同的步骤,创建两个实例以及安装 HACMP 脚本。
完成两个实例的设置并检查可以启动和停止实例之后,就卸载所有目录,并在 HADB2 上发出:
varyoffvg vgA
varyoffvg vgB
这将使我们准备完成 HACMP 配置的设置。
我们应总是小心维护相同的级别、软件、ID,并在移至的两台服务器上小心设置实例和数据库等的配置,以便 HA 正常工作。对于 maxuproc、端口号和 AIX 维护级别等系统参数也应如此。
在服务器 HADB1 上,Db2nodes.cfg 如下列所示之一:
0 floating IP address 0
0 128. 209.61.3 0
在服务器 HADB2 上,Db2nodes.cfg 如下所示:
0 128. 209.61.4 0
因为 db2nodes.cfg 中的地址是浮动的,所以在从一台服务器故障转移至另一台时无需编辑该文件。对于这两个实例,我们使用两台应用程序服务器和两个资源组。每个实例一个资源组。每个资源组将包含一个启动和停止该实例的脚本。.rhosts 文件包含所有 IP 地址的列表,但不包含用户 ID。我们将使用 .rhosts 文件,而不使用 hosts.equiv。在使用 hosts.equiv 的时候,错误代码
SQL6048N 对应的诊断文件不能给出正确信息。所以我们不使用它,而是使用了 .rhosts。对于 TCPIP,我们必须编辑
etc 下的 TCPIP 组文件,用以定义该文件中的第二个实例。
为了使故障转移时间更快,要调优这些 DB2 UDB 配置设置:
db2empfa 以互斥方式连接数据库分区。在 SMS 中,对于大于一个区段的所有索引和数据文件,它将分配空页以填充其中的最后一个区段。它将 multipage_alloc 配置参数修改为 Yes,并断开连接。
multipage_alloc 仅仅用于 SMS 表空间,用以提高插入性能。一旦设置为 Yes,它就无法返回为 No 了。它适用于所有的 SMS 表空间,而不适用于单个空间。使用以上命令的理由就是为了确保在 SMS 表空间上有足够的可用空间,以便在故障转移之后,没有不必要的额外延迟来分配页面。
将 softmax 参数设置为较低的数字,以便更频繁地将日志控制文件写入磁盘,因而在崩溃恢复之后,数据库的恢复时间更少。这是因为日志控制文件将是最新的,并将避免对磁盘不必要的写入。这在 DB2 Performance Guide 中进行了说明。
更多的 I/O 清除器(cleaner)意味着如果进行软件恢复,将在磁盘上更多地更新数据库的内容,因为 I/O 清除器清除缓冲池的内容,因此,这将减少恢复时间。
logfilesz=1000(默认值)Chngpgs_thresh=20(30)
缓冲池需要触发异步页面清除器启动清除缓冲池,而该值越低,缓冲池中页面的修改百分率就越低。这提高了性能。在 HA 中,这还意味着将更多页面/数据更频繁地写入磁盘,因此在崩溃恢复时,需要的恢复时间更少,因为所提交的数据通常都写入了磁盘。
心跳率(heartbeat rate)不应低于 8 秒。实际上,心跳率最小是 1 秒。周期值最小是 4 秒。我们用 4 乘以 2,就是每隔 2 分钟就监控心跳(heartbeat)以获得最小的 8 秒。
只有系统负载相当受控制时,这才变成 8 秒间隔 2x4(仅每 2 秒就监控心跳)。这意味着它将不是一个超载的 OLTP 应用程序。对于负担较重的事务性数据库和商业智能应用程序,心跳应更高一些。同样,网络不能完全充满数据包;否则,将丢失心跳。
有两个主要原因使心跳保持高于最小值。一个原因就是心跳与系统中的其他资源竞争,而另一原因就是如果获得响应的过程中存在延迟,而心跳未等待足够长时间,那么就会无缘无故地发生故障转移。网络不能完全充满数据包;否则,将丢失心跳。您应使用一个非 IP 的心跳,如 RS232 或目标模式 SSA 或目标模式 SCSI。那么,只有两个心跳,RSCT 和非 IP 的心跳都发生故障,才会进行故障转移。使用双心跳网络总是比较好。
数据库管理员通常不熟悉 HACMP 术语。因此,我将在这里花些时间做个简短介绍,因为 HA 实际上是由 HACMP 执行的。DB2 仅仅使用一个脚本,HACMP 触发该脚本以根据故障转移的需要启动和停止实例。
资源组(Resource group):这是一组需要从一台服务器进行故障转移至另一台的全部资源。在资源组中,我们定义了将挂到需要进行故障转移的 DB2 UDB 服务器的所有资源。这些资源包括卷组中所定义的磁盘、我们将定义并且将构成 DB2 HA 脚本的应用程序、网络和适配器。
定义群集 ID 和名称。本例中,它的 ID 编号是 999,而名称是 db2cluster。 接着,定义群集节点,本例中是 HADB1和 HADB2。然后,我们添加适配器。本例中,每台服务器有四个适配器,但我们仅仅使用三个。这在所提供的图片中已经进行了描述。其中一个适配器是启动适配器,并非用于 HACMP。那么,服务适配器就是每台服务器的主适配器,用于每台服务器上的主实例,并分配了一个浮动的地址。因此,对于其主实例为 db2admin 的 HADB1,服务器适配器将保存所有到实例 db2admin 的连接,而在 HADB2 上,服务器适配器将接收所有到实例 db2adma 的连接。例如,当 HADB2 发生故障时,那么 HADB1 上的服务适配器将继续获得 db2admin 的连接,而 HADB1 上的备用适配器将获得 HADB1 上当前活动的 db2adma 第二实例的连接。如果没有故障转移,备用适配器就一直闲置。
以下是适配器拓扑:
群集 db2cluster 的群集描述
群集 db2cluster 的群集描述
群集 ID:999
群集安全级别标准
定义了两个网络:ether1、snet1
该群集中有两个节点:
节点 HAdb1:
该节点具有两个服务接口:
服务接口 db1asvc:
- IP 地址:128.209.61.3
- 硬件地址:
- 网络:ether1
- 属性:public
- 别名地址?:未知
服务接口 db1asvc 有一个启动接口
- 启动(或服务)接口 1:db1aboot
- IP 地址:128.209.61.75
- 网络:ether1
- 属性:public
服务接口 db1asvc 有一个备用接口
- 备用接口 1:db1astby
- IP 地址:128.209.67.54
- 网络:ether1
- 属性:public
服务接口 db1atty2:
- 硬件地址:
- 网络:snet1
- 属性:serial
- 别名地址:False
(INVALID)服务接口 db1atty2 没有启动接口
服务接口 db1atty2 没有备用接口
节点 HAdb2:
该节点具有两个服务接口:
服务接口 db2asvc:
- IP 地址:128.209.61.4
- 硬件地址:
- 网络:ether1
- 属性:public
- 别名地址?:未知
服务接口 db2asvc 有一个启动接口
启动(或服务)接口 1:db2aboot
- IP 地址:128.209.61.76
- 网络:ether1
- 属性:public
服务接口 db2asvc 有一个备用接口
备用接口 1:db2astby
- IP 地址:128.209.67.55
- 网络:ether1
- 属性:public
服务接口 db2atty2:
- IP 地址:/dev/tty2
- 硬件地址:
- 网络:snet1
- 属性:serial
- 别名地址?:False
(INVALID)服务接口 db2atty2 没有启动接口
服务接口 db2atty2 没有备用接口
网络连接故障:
到网络 ether1 的连接
节点 HAdb1 通过这些接口连接到网络 ether1:
- db1aboot
- db1asvc
- db1astby
节点 HAdb2 通过这些接口连接到网络 ether1:
- db2aboot
- db2asvc
- db2astby
到网络 snet1 的连接
节点 HAdb1 通过这些接口连接到网络 snet1:
- db1atty2
节点 HAdb2 通过这些接口连接到网络 snet1:
- db2atty2
然后,与其他节点 HADB2 的设置同步。
此时,我们就完成了每台服务器上所有资源的定义;现在需要定义资源组。我们将添加两个资源组:rgA 和 rgB。
对于每个资源组,我们将添加主次两台服务器。对于资源组 rgA,主服务器是 HADB1,定义中首先就必须放置它。对于资源组 rgB,主服务器是 HADB2,在新资源组定义下的参与节点名称定义中必须首先放置它。
在每个资源组中,我们添加了一台应用程序服务器。该应用程序服务器将管理各种故障转移场景中数据库的启动和停止。对于第一个实例,该应用程序服务器称作 app1,而对于第二个则称作 app2。对于两台服务器,启动脚本将是
/usr/bin/rc.db2pe db2admin start ,而停止脚本将是
/usr/bin/rc.db2pe db2admin stop 。对于第二个实例 db2adma 同样如此。
以下是其输出:
Resource Group Name: rgA
|
运行时参数:
节点名:
HAdb1
调试级别:high
主机使用 NIS 或名称服务器:false
hacmp.out 的格式:Standard
节点名:HAdb2
调试级别:high
主机使用 NIS 或名称服务器:false
hacmp.out 的格式:Standard
资源组名:rgB
节点关系:cascading
参与节点名称:HAdb2 HAdb1
节点优先权
服务 IP 标签:db2asvc
文件系统:/dbB /home/db2adma /home/db2fenca
文件系统一致性检查:fsck
文件系统恢复方法:sequential
成为导出文件系统的文件系统/目录恢复方法:sequential
成为 NFS 挂载文件系统的文件系统恢复方法:sequential
用于 NFS 挂载文件系统的网络恢复方法:sequential
卷组 vgBFilesystems 恢复方法:sequential
并发卷组文件系统恢复方法:sequential
磁盘文件系统恢复方法:sequential
AIX 连接服务文件系统恢复方法:sequential
AIX 快速连接服务文件系统恢复方法:sequential
共享磁带资源文件系统恢复方法:sequential
应用程序服务器 app2 文件系统恢复方法:sequential
高可用通信链接文件系统恢复方法:sequential
混合数据文件系统恢复方法:sequential
自动导入的卷组 falseFilesystems 恢复方法:sequential
非活动接管 falseFilesystems 恢复方法:sequential
无撤退的级联 falseFilesystems 恢复方法:sequential
9333 磁盘保护 falseFilesystems 恢复方法:sequential
SSA 磁盘保护 falseFilesystems 恢复方法:sequential
配置 IP 之前挂载的文件系统:false
运行时参数:
节点名:
HAdb2
调试级别:high
主机使用 NIS 或名称服务器:false
hacmp.out 的格式:Standard
节点名:
HAdb1
调试级别:high
主机使用 NIS 或名称服务器:false
hacmp.out 的格式:Standard
然后,同步并验证群集。设置就完成了。
高可用性可以使 DB2 发挥极好的效果。我们成功达到了此 POC 的目标,因为大多数情况下所测的故障转移时间约为 60 秒。。启动数据库本身仅仅花费 1 秒。在服务器之间,特别是磁盘之间移动资源消费了大部分时间。在 HACMP Version 5.1 中,通过对磁盘使用增强的并发访问模式消除了该时间。总之,相互接管场景也是需要两个单独数据库的环境的极佳解决方案。
作者想要感谢 Alan Barnes 为本文的撰写所提供的帮助和建议。
作者想要感谢 Enzo Cialini,多伦多实验室 HA 系统测试小组经理,在该工作中不断提供的宝贵帮助。
作者还要感谢 Glenn Miller 在考虑 AIX 和 HACMP 设置的所有事情中所提供的出色支持。
- 您可以参阅本文在 developerWorks 全球站点上的
英文原文。
-
DB2 Information Center允许您访问各种 DB2 UDB 的有关信息。
-
The Linux Documentation Project是一个 Linux 的文档库,包括关于单个软件、HOWTO 文档、FAQ 等的文档。
-
Build a better GUI(
developerWorks,2001 年 10 月)讨论了 Java 布局管理器的使用,以获得更好的 GUI 总体设计,。
- Garfinkel 和 Spafford 的
Practical UNIX & Internet Security
(O'Reilly & Associates;1996)是非常好的参考资料,介绍了系统安全性的各个方面,从用户管理到拟定安全策略。
