DB2 Universal Database™ 使用日志文件作为确保数据一致性和可恢复性的主要方法。在前一篇文章 DB2 通用数据库中事务性日志记录概述中, 我介绍了事务性日志记录的概念并说明了如何管理日志。在本文中,我将带您做进一步的探讨,并说明 DB2 UDB 可以如何使用用户出口程序来归档和检索数据库日志文件。另外,我还将提供循序渐进的示例来说明如何修改、编译和测试 db2uext2.cdisk 样本用户出口程序,该程序随已安装的 DB2 UDB 服务器产品附带。您将在本文末尾找到关于用 DB2 UDB 进行用户出口编程的其它参考资料 链接。
本 文讨论了 Windows 2000 和 AIX 5L 上的 DB2 V8.1 企业服务器版修订包 1(单分区版)服务器。虽然也有其它样本用户出口程序(例如至磁带的用户出口或 Tivoli 存储管理器(Tivoli Storage Manager)),但我没在本文讨论它们。
在 DB2 UDB 中使用用户出口程序是为了提供一种归档和检索数据库日志文件的方法以便进行日志冗余处理以及将日志存储在非易失性的介质上。我们要知道的重要一点是:根据您的特定需求,可以在用户出口中实现包括归档和检索日志在内的其它操作。
如果需要使用归档日志文件来恢复数据库,则在 DB2 UDB 中实行用户出口策略不会恢复 100% 的事务。用户出口程序只是一种通过将现有日志文件复制到安全位置来提供更多保护的方法。它是数据完整性策略的一部分,但却是重要部分。
编译了用户出口程序之后,db2uext2 可执行文件将被放在数据库管理器可以发现它的目录中。在 UNIX® 上,该目录是 <instance home>/sqllib/adm
,在 Windows® 上,该目录是 <drive letter>Program FilesIBMSQLLIBBIN
。
除 非数据库管理器知道可以使用用户出口程序,否则它不会调用 db2uext2。数据库管理器知道可以调用 db2uext2 的唯一方法是将数据库配置参数 userexit 设置成 on。一旦设置了该参数并且重复利用了 DB2 实例,数据库管理器就会每五分钟调用一次用户出口程序以检查某些日志文件,这些日志文件可以被归档到特定于程序的归档目录。
如果需要进行数据库恢复,则数据库管理器将在前滚操作期间调用 db2uext2,以将归档的日志文件复制回活动日志目录中。日志文件就会被重新应用到已恢复的数据库。
让我们看一看数据库管理器调用用户出口程序的调用格式。请注意,也可以在用户出口样本程序的注释部分找到该信息:
db2uext2 -OS<os> -RL<release> -RQ<request> -DB<dbname> -NN<nodenumber> -LP<logpath> -LN<logname> [-AP<adsmpasswd>]
其中:
os = 操作系统
release = DB2 发行版
request = “ARCHIVE”或“RETRIEVE”
dbname = 数据库名称
nodenumber = 节点号
logpath = 日志文件路径
logname = 日志文件名
logsize = 日志文件大小(可选)
startingpage = 以 4K 页大小为单位的起始偏移(可选)
adsmpasswd = ADSM 密码(可选)
注:只有在 logpath 是裸设备时才使用 logsize 和 startingpage。
用以下命名约定来归档和从磁盘检索日志文件:
归档:归档路径+数据库名+节点号+日志文件名
检索:检索路径+数据库名+节点号+日志文件名
例如:如果归档路径是“c:mylogs”,
检索路径是“c:mylogs”,
数据库名是“SAMPLE”,
节点号是 NODE0000,
文件名是 S0000001.LOG,
日志文件将是:
归档到 - c:mylogsSAMPLENODE0000S0000001.LOG
检索自 - c:mylogsSAMPLENODE0000S0000001.LOG
下面展示了用户出口中逻辑是如何流动的:
1) 安装信号处理程序。
2) 验证传递的参数数目。
3) 验证请求的操作。
4) 启动审计跟踪(如果请求的话)。
5) 根据所请求的操作采取以下路径之一:
a) 如果请求的操作是归档文件,则将该日志文件从日志路径复制到归档路径。
i) 如果没找到日志文件,则到第 6 步。
b) 如果请求的操作是检索文件,则将该日志文件从检索路径复制到日志路径。
i) 如果没找到日志文件,则到第 6 步。
6) 将错误记入日志(如果请求和需要的话)。
7) 终止审计跟踪(如果请求的话)。
8) 退出并给出适当的返回码。
可以手工调用用户出口程序以归档日志文件,但最好使用 ARCHIVE LOG 命令以便在指定以上参数时不会因为您的原因而出错。可以在本文的末尾找到 ARCHIVE LOG 命令的 链接。
![]() ![]() |
![]()
|
DB2 中用户出口程序的基本功能是将日志文件复制到活动日志目录或从中复制。需要在这里指出一些术语以澄清活动日志目录的位置以及数据库日志文件的状态。
该目录位于您的数据库目录中。在 Windows 上,如果在 C: 创建了名为 SAMPLE 的单一数据库,并且实例名称是 db2inst1,则将存在以下目录结构:
C:DB2INST1NODE0000SQL000001SQLOGDIR
SQL00001 是 SAMPLE 数据库的数据库目录,SQLOGDIR 是活动日志目录。
下面的图 1 显示了 Windows 操作系统上的活动日志目录:
![]() ![]() |
![]()
|
在活动日志目录中,日志文件可以是 活动日志,也可以是 联机归档日志。活动日志是 DB2 为进行当前事务处理和崩溃恢复而需要的那些日志。联机归档日志是 DB2 UDB 进行常规处理时不再需要的日志,但进行数据库恢复时可能还会需要它。当实现用户出口程序时,这些联机归档日志应该最终作为归档日志目录中的副本出现。
既 然 DB2 UDB 中用户出口程序的目的是将数据库日志复制到归档目录中,您最终将在活动日志目录(缺省是 SQLOGDIR)中得到重复的日志文件。您可能考虑除去这些重复的联机归档日志以释放文件系统空间。在从数据库目录中除去这些日志之前,要十分细心地验 证是否已经将它们成功地复制到归档目录中。还必须确保数据库管理器进行崩溃恢复时不再需要它们。要确定活动日志目录中哪些日志文件不为正常处理所需,可用 以下命令检查数据库配置:
db2 "get db cfg for sample"
该命令的数据库配置输出将包括第一个活动日志文件,例如:
First active log file = S000009.LOG
上面输出中所示的日志文件 S000009.LOG
是数据库的当前活动日志。任何小于该编号的日志文件都被认为是联机归档日志。
下面是一个示例:
在下面的方案中,活动日志目录中有日志文件 S000000.LOG - S000009.LOG
,归档日志目录中有 S000000.LOG - S000008.LOG
。因为 S000009.LOG
是第一个活动日志文件,所以,可以从活动日志目录中删除 S000001.LOG - S000008.LOG
以释放磁盘空间。必须将 S000009.LOG
文件留在活动日志目录中,因为当前事务仍然在使用它。
也可以检查数据库历史文件,以查看活动日志目录中不再需要哪些日志文件。以下命令将列出数据库备份信息:
db2 "list history backup all for database sample"
下面是该命令的输出示例:
|
在上面的输出中,最早的日志将表明:需要 S0000010.LOG
及其之后的任何日志。可以安全地删除 S00000010.LOG
之前的任何日志。再次提醒,在从活动日志目录中删除日志文件之前,验证在活动日志目录中存在这些日志文件的副本是非常重要的。
尽管可以从活动日志目录手工删除日志文件,但是除去联机归档日志文件的更安全方法是通过 prune logfile 命令。可以使用该命令来删除活动日志目录中的日志文件。在下面的示例中,以下命令将删除日志文件 S000000.LOG - S000008.LOG
:
db2 "prune logfile prior to S000009.LOG"
注:根据您的恢复策略,在有些情况下前面的前滚操作可能会在数据库上执行。归档目录中旧的日志文件可能会被具有相同名称的新日志文件覆盖,从而会阻止您使用旧日志文件对数据库进行时间点恢复。用户出口程序的程序员需要考虑这种情况,这一点非常重要。
![]() ![]() |
![]()
|
在本文中,我们将使用 DB2 所提供的 db2uext2.cdisk
样本 c 程序,它位于您的 c 目录中。在 Unix 上,该目录位于 <instance home>/sqllib/samples
。在 Windows 上,该目录位于 Program Files/IBM/<instance name>/samples
中。
修改并编译用户出口程序
1. 创建名为 C:mylogs
的目录。
2. 将 C:Program filesIBMSQLLIBsamplescdb2uext2.cdisk
复制到工作目录中。
3. 对于本示例,应该验证用户出口程序的以下部分以反映路径 c:mylogs
。
|
4. 确保在系统上安装了受支持的 C 编译器(例如 Microsoft Visual Studio)并且环境中具有该编译器的路径。
5. 在命令行上,将 db2uext2.cdisk
重新命名为 db2uext2.c
,然后构建它:
cl db2uext2.c
一旦编译了程序,将创建 db2uext2.exe
和 db2uext2.obj
文件。
6. 将 db2uext2.exe
可执行文件放在 /SQLLIB/BIN
目录中,这样数据库管理器可以找到并执行它,以便归档和检索日志。
创建并准备用户出口的数据库
7. 在 DB2 命令窗口中用 db2sampl 命令创建 SAMPLE 数据库。这将允许您对下面的示例使用样本表。
db2sampl
8. 更新数据库配置文件以便对数据库打开用户出口。请注意:因为 bin 目录由所有 DB2 实例共享,所以只能将用户出口程序分配给一个数据库。
|
请注意: logretain数据库配置参数不一定必须是 on 才允许对日志文件进行前滚恢复,因为 userexit参数也可以做到这点。
9. 为了测试的目的,可以通过降低 logfilsiz 数据库配置参数的值来更多地归档日志文件。
db2 "update db cfg for sample using logfilsiz 200"
值 200 是每个日志文件可以有的 4k 页的数目。在我们的示例中,每个日志文件的大小将被初始化为 800k(200×4k)。
10. 既然将 userexit数据库配置参数设置成 YES,则必须进行完整的数据库备份之后才能连接到数据库。记下备份命令所产生的时间戳记,因为这在数据库恢复期间将被用到。
db2 "backup db sample to c:backups"
现在,您的用户出口程序已被启用并可以使用了。您的用户出口程序每 5 分钟将被调用一次,以检查活动日志目录中是否有需要归档的日志文件。请注意:用 logfilsiz数 据库配置参数指定的日志文件越大,填充该日志文件所需的时间就越长,从而使该日志文件越容易受到磁盘故障和磁盘毁坏等问题的影响。根据您的事务负载,您应 该只指定一个合适的日志文件大小以便可以在适当的时间间隔内填充好该文件,这样用户出口程序可以将该日志文件归档到安全的目录中。
在更理想的情况下,最好的做法是将日志文件归档到另一个系统的不同磁盘中。这减少了主磁盘的 I/O 流量并且在磁盘或系统崩溃时提供第二层次的保护。
修改并编译用户出口程序
1. 创建以下目录结构:
/mylogs/SAMPLE/NODE0000
然后授予该目录结构中的每个目录递归的许可权:
chmod -R 777 /mylogs
2. 将 db2uext2.cdisk 复制到工作目录并授予文件许可权:
cp /home/db2v8_32/sqllib/samples/c/db2uext2.cdisk /home/db2v8_32/db2uext2.c
chmod 777 /home/db2v8_32/db2uext2.c
3. 对于该示例,应该更新用户出口程序的以下部分以反映路径 /mylogs/
。
|
4. 确保在系统上安装了 C 编译器,并且您的环境中具有该编译器的库和路径。
5. 在命令行中构建 db2uext2.c
程序:
cc -o db2uext2 db2uext2.c
一旦编译了程序,将创建 db2uext2 可执行文件。
6. 将 db2uext2 可执行文件移至 sqllib/adm
目录。
mv db2uext2 /home/db2v8_32/sqllib/adm/
创建并准备用户出口的数据库
7. 用 db2sampl 命令创建 SAMPLE 数据库。这将允许您对下面的示例使用样本表。
db2sampl
8. 更新数据库配置文件以便对数据库打开用户出口。
|
请注意: logretain数据库配置参数不一定必须是 on 才允许对日志文件进行前滚恢复,因为 userexit参数也可以做到这点。
9. 为了测试的目的,可以通过降低 logfilsiz数据库配置参数的值来更多地归档日志文件。
db2 "update db cfg for sample using logfilsiz 200"
值 200 是由 logprimary和 logsecond参数指定的每个日志文件可以有的 4k 页数量。
10. 既然将 userexit数据库配置参数设置成 YES,则必须进行完整的数据库备份之后才能连接到数据库。记下备份命令所产生的时间戳记,因为这在数据库恢复期间将被用到。
db2 "backup db sample to /home/db2v8_32/backups"
现在,您的用户出口程序已被启用并可以使用了。您的用户出口程序每 5 分钟将被调用一次,以检查活动日志目录中是否有需要归档的日志文件。请注意:用 logfilsiz数 据库配置参数指定的日志文件越大,填充该日志文件所需的时间就越长,从而使该日志文件越容易受到磁盘故障和磁盘毁坏等问题的影响。根据您的事务负载,您应 该只指定一个合适的日志文件大小以便可以在适当的时间间隔内填充好该文件,这样用户出口程序可以将该日志文件归档到安全的目录中。
在更理想的情况下,最好的做法是将日志文件归档到另一个系统的不同磁盘中。这减少了主磁盘的 I/O 流量并且在磁盘或系统崩溃时提供第二层次的保护。
在下面的方案中,Windows 用来为与用户出口程序相关的特定文件位置提供可视的表示。改变路径之后,我们还在 AIX 上测试了这些步骤。
注:对于 Windows 用户,在用用户出口程序进行第一次归档时,将在 mylogs 目录中创建归档目录结构 SAMPLENODE0000
。在 AIX 上手工创建的归档日志路径类似于下面的路径: /sample/NODE0000
(请参阅 在 AIX 上设置用户出口程序)。
促进日志文件的归档
方案 1:
|
(必须释放所有的数据库连接,以便数据库释放资源并关闭日志文件)
检查 c:mylogsSAMPLENODE0000
目录。
上面的方案将截断当前活动的日志文件并将它复制到 c:mylogs
目录。被截断的日志文件的大小将小于 800k,以防止浪费空间。
下面的图 2 演示了被移至归档目录的被截断的日志文件。
方案 2:
还可以通过用数据填充日志文件来进行测试。数据库管理器将检查全部日志文件,并将它们复制到归档目录中。
|
(执行该插入语句 10 次以填充日志文件)
请记住您将数据库配置参数 logfilsiz更新成了 200 个 4k 页(800k),以便迅速填充日志文件。
现在可以检查 c:mylogs
目录。
下面的图 3 显示了已归档日志的位置。
如果您的用户出口程序工作正常,您应该在 c:mylogs
中看到 ARCHIVE.LOG,并且一个或多个日志文件应该被复制到 c:mylogsSAMPLENODE0000
。
下面的图 4 显示了 ARCHIVE.LOG
文件的位置:
在数据库恢复期间检索已归档日志文件
现在我们将执行数据库恢复。恢复过程将调用用户出口程序以从 c:mylogs 目录将日志文件取回活动日志目录,在那里,日志文件可以在前滚恢复期间被应用到数据库。
|
恢复命令中的值 20030416114420 是取自前一次数据库备份的时间戳记。既然我们是在现有样本数据库的基础上进行恢复,您会接收到以上警告消息。选择 Y,然后按 Enter 键。
|
下面的图 5 显示了创建 RETRIEVE.LOG
的位置。
对于传递回活动日志目录的每一个日志文件,都会有一条消息写入 c:mylogsRETRIEVE.LOG
文件中。
|
![]() ![]() |
![]()
|
我 已经简单介绍了如何在 DB2 UDB 中使用用户出口程序。需要重点说明的是:可以编写和修改 DB2 UDB 的用户出口程序以适合您的需要。其它编程注意事项包括:删除归档日志目录中的重复日志文件(它们可能是在某些情况下被创建的),考虑到时间点恢复之后存在 同名的不同日志文件,从归档目录中除去不再需要的日志文件以及错误处理。这些是您在修改或创建自己的用户出口程序时需要考虑的事项。可以在下面的链接中找 到有关用户出口编程方面的更多信息。
![]() ![]() |
![]()
|
User exit for database recovery
Managing log files with a user exit program
Configuration parameters for database logging