DB2V97高可用性灾难恢复中的备机可读.docx
《DB2V97高可用性灾难恢复中的备机可读.docx》由会员分享,可在线阅读,更多相关《DB2V97高可用性灾难恢复中的备机可读.docx(21页珍藏版)》请在冰豆网上搜索。
![DB2V97高可用性灾难恢复中的备机可读.docx](https://file1.bdocx.com/fileroot1/2023-1/1/876df5ab-b104-4221-a33a-38f2f1053630/876df5ab-b104-4221-a33a-38f2f10536301.gif)
DB2V97高可用性灾难恢复中的备机可读
、八,、■
刖言
在最新的DB2V9.7.1中,引入了一项高可用性灾难恢复(HighAvailabilityDisasterRecovery,简称HADR)环境下的新功能:
备机可读(ReadsOnStandby,简称RoS)。
利用该功能,能够有效分担主机数据库(PrimaryDB)的工作负载,充分利用备机数据库
(StandbyDB)运行一些读操作的应用,以达到资源更加优化的目的。
为了更好理解备机可读这一新功能,我们先从高可用性灾难恢复的基本概念开始。
高可用性灾难恢复基础
从V8.2(当时称作DB2UniversalDatabase,DB2通用数据库)开始,DB2引入了一
种新的、源自于Informix的高可用性解决方案:
咼可用性灾难恢复(即
HADR)。
在咼可
用性灾难恢复环境中,通常有两台物理的数据库服务器,即主数据库(
PrimaryDB)和备
机数据库(StandbyDB),它们分别位于两个有
定距离间隔的数据中心
(如图1所示)。
图1.高可用性灾难恢复的组织结构
离负命
I1fiwi.i
主数据库(PrimaryDB),能够接受日常的增删改查等应用操作,这些操作产生的数据库
日志(Log)通过TCP/IP协议传送给备机数据库(StandbyDB)。
由于数据库事务都是基于日志的,备机数据库通过重做(Replay)这些日志,就能够重现主数据库服务器上相二
应的操作,从而使得两个数据库中的数据能够基本保持在一致的状态。
在主数据库出现宕机,如地震、火灾、断电等灾难或问题,导致数据库不可访问或者损坏的
时候,备机数据库能够很快接管(Takeover)主数据库的工作和任务,成为新的主机数据
库(如图2所示)。
由于备机数据库中的数据在主数据库出现问题之前一致保持着与主数据库相接近状态,因此应用程序能够直接连接到新的主数据库(即旧的备机数据库)上,这
样就能把业务中断够减小到最低限度。
图2.接管之后的高可用性灾难恢复组织结构
最初在引入HADR作为高可用性方案的时候,备机数据库仅仅是作为主数据库的备用设备,
其唯一功能就是重做主数据库传递来的数据库日志,使其数据状态跟主数据库保持一致,以
便在主数据库出现问题的时候接管应用。
所以,备机数据库一直处于脱机(offline)状态,
也就是说,在接管之前,不允许用任何应用程序连接,这样在一定程度上导致了资源的浪费。
因此,在最新的DB2LUWV9.7.1(DB2LinuxUnixandWindows,Version9.7FixPack1)
中,引入了备机可读的功能,提高了备机数据库的利用率,这正是本文要讨论的主题。
回页首
备机可读
上文已经提到,在最新的DB2版本中,在备机上已经支持可读操作,原先在主数据库上的
只读应用,例如生成报告、决策支持、商业智能应用等,现在都可以迁移到备机数据库上进
行,这样,即在一定程度上减轻了主数据库的负载,又提高了备机数据库的利用率。
如图3
所示。
图3.备机可读的高可用灾难恢复组织结构
忙/I
高可用性灾难恢复中的备机可读环境的设置
接下来,让我们来快速配置一个备机可读的环境,体验一下这项令人激动的新功能吧!
1.安装DB2V9.7.1,并配置高可用性灾难恢复环境。
这并不是本文讨论的重点,请读者参
考相应文档。
2.打开高可用性灾难恢复的备机可读功能。
这需要在备机数据库上设置一个DB2的注册变量(RegistryVariable)
DB2_HADR_ROS。
将该变量设置为
1,或者yes,或者on,可将备机可读功能打开;设
置为空,或者不设置该注册变量的值,
则表示不启用备机可读功能,这时候备机数据库跟之
前版本DB2中的备机数据库一样,只进行数据库日志重做,不接受任何应用连接。
清单1.启用高可用性灾难恢复中的备机可读
$db2setDB2_HADR_ROS=1
小窍门:
设置DB2中的注册变量
注意:
跟其他DB2注册变量一样,设置DB2_HADR_ROS(静态变量)之后,需要重新启
动DB2数据库实例(Instanee),以使其生效。
要重启数据库实例,使用db2stop命令停
止DB2数据库实例,然后用db2start启动DB2数据库实例:
清单2.重新启动DB2实例
$db2stop
SQL1064NDB2STOPproeessingwassuccessful.
$db2start
SQL1063NDB2STARTprocessingwassuccessful.
3.激活备机数据库
要激活备机数据库,使用ACTIVATEDB命令(这里使用名为HADRDB的数据库作为例
子):
清单3•激活备机数据库
$db2ACTIVATEDBhadrdb
DB20000ITheACTIVATEDATABASEcommandcompletedsuccessfully.
小窍门一一激活数据库
注意:
激活备机数据库与激活主数据库有所不同。
通常主数据库或者标准环境下的数据库,不需要显示使用ACTIVATEDB命令激活,该类数据库会在第一个应用连接的时候被激活。
在备机可读环境下的备机数据库,需要显示运行ACTIVATEDB命令来激活数据库,才能_
使数据库处于在线(online)状态。
若不使用ACTIVATEDB来激活备机数据库,这时候尝试连接备机数据库会得到以下错误:
清单4.尝试连接未激活的备用数据库的错误消息
$db2CONNECTTOhadrdb
SQL1776NThecommandisnotsupportedonanHADRstandbydatabaseoronanHADRstandbydatabasewiththecurrentconfigurationorstate.Reasoncode="1".
至此,备机可读环境已经配置完成,接下来验证一下。
高可用性灾难恢复中的备机可读环境的验证首先,在主数据库上建立一张新表,并插入若干条记录:
清单5.在主机上建立表并插入数据
$db2CONNECTTOhadrdb
DatabaseConnectionInformation
Databaseserver=DB2儿INUXX86649.7.1
SQLauthorizationID=XUJING
Localdatabasealias=HADRDB
$db2"CREATETABLEtest(C1INT,C2CHAR
(1))"
DB20000ITheSQLcommandcompletedsuccessfully.
$db2"INSERTINTOtestVALUES(1,'A'),(2,'B'),(3,'C')"
DB20000ITheSQLcommandcompletedsuccessfully.
然后在备机数据库上查询该表,如果可以看到这些记录已经出现在备机数据库中了,此时说
明高可用性灾难恢复的备机可读已经配置成功:
清单6.验证高可用性灾难恢复备机可读环境配置成功
$db2CONNECTTOhadrdb
DatabaseConnectionInformation
Databaseserver=DB2/LINUXX86649.7.1
SQLauthorizationID=XUJING
Localdatabasealias=HADRDB
$db2"SELECT*FROMtest"
C1C2
1A
2B
3C
3record(s)selected.
小窍门尽早提交主数据库上的事务
注意:
在验证上述命令时,在主服务器上运行完CREATETABLE和INSERT命令后,请
务必要提交该事务,否则会导致备机数据库进入不可读窗口
(ReplayOnlyWindow,参
见本文第四部分)。
要提交事务,可以使用下列两种方法中的任意
•种:
*
显示使用COMMIT命令提交事务
*
将命令行选项中的自动提交打开(该参数默认打开)
清单7.打开数据库命令行的自动提交
$db2UPDATECOMMANDOPTIONSUSINGCON
打开该选项之后,随后输入的SQL命令都会被自动提交。
在提供备机可读功能之前,要验证高可用性灾难恢复环境是否配置成功,相对来说比较麻烦。
类似的,首先在主数据库建表、插入数据,要检查这些数据是否已经传递到备机上,随后必
须使备机数据库接管成为新的主数据库之后,才能在上面检查之前的操作是否已经生效。
从
此可以看出,高可用性灾难恢复的备机可读功能,同时也为快速配置高可用性灾难与恢复环
境提供了一个快速有效的验证方法。
回页首
备机可读的隔离级别
在开始介绍备机可读的隔离级别之前,先简单介绍一下隔离级别的基本概念。
隔离级别的基础知识
在数据库系统中,并发(Concurrency)控制和事务(Transaction)的实现离不开锁(Locks)
和隔离级别(IsolationLevels)。
在DB2中,有以下五种隔离级别:
■
可重复读(RepeatableRead,简称RR)
■
读稳定(ReadStability,简称RS)
*
游标稳定(CursorStability,简称CS)
当前已提交(CurrentlyCommitted,简称CC,DB2V9.7新加入)
*
未提交读(UncommittedRead,俗成脏读”简称UR)
关于这些隔离级别的具体定义和最佳实践,不是本文讨论的重点,读者如果感兴趣,可以参
考相应文档。
]
一般DB2应用程序的默认隔离级别是游标稳定(CS),并且可以根据需要改变隔离级别。
在DB2
中,应用程序的隔离级别可以通过以下几种方式来指定:
1.在绑定(bind)应用程序时指定隔离级别,例如:
清单8.在绑定是设置隔离级别
$db2BINDsample.bndISOLATIONURLINEMESSAGESFORsample.bnd
SQL0061WThebinderisinprogress.
SQL0091NBindingwasendedwith"0"errorsand"0"warnings.
2.在应用程序中使用SETCURRENTISOLATION命令指定隔离级别,例如:
清单9.使用SETCURRENTISOLATION设置隔离级别
$db2SETCURRENTISOLATIONUR
DB20000ITheSQLcommandcompletedsuccessfully.
3.在SQL语句中指定隔离级别,例如:
清单10.在SQL语句中设置隔离级别
$db2"SELECT*FROMtestWITHUR"
3record(s)selected.
通常来说,在SQL语句中设置的隔离级别优先级最高,其次是应用程序中使用SET
CURRENTISOLATION命令设置的隔离级别,最后才是在绑定时使用的隔离级别,也就是
说,在语句中设置的隔离级别,会覆盖当前应用SETCURRENTISOLATION命令所设置
的隔离级别;而当前应用SETCURRENTISOLATION命令设置的隔离级别,会覆盖在绑
定时设定的隔离级别。
高可用性灾难恢复中备机可读的隔离级别
现在,回到高可用性灾难恢复的备机可读功能的主题上来。
在备机可读环境下,只读的应用
程序只能使用未提交读(UR,即脏读”来读取数据,并且该隔离级别不能改变。
原因很简单,高可用性灾难与恢复的基础是数据库日志的传输(LogShipping)。
主数据库上的数
据操作会产生数据库日志,这些日志通过TCP/IP传输到备机数据库,备机数据库通过重
做这些操作,重现在主数据库上的数据操作,实现隔离级别的重要工具一一锁,并没有从主
数据库传递到备机数据库上,因而在备机数据库进行日志重做的时候,也就无法对数据库对
象施加锁保护。
这时候只读的应用程序连接到备机数据库上,必然只能以未提交读(UR)
的隔离界别读取数据,无法用其他更高级别的隔离级别来。
备机可读的环境下,备机数据库不支持第一种指定隔离级别的方式,因为绑定(bind)实质
上是一种写操作。
如果在备机上运行带有写操作的命令,会得到错误SQL1773N,原因代
码5,该错误消息的具体含义,请参考DB2LUWInformationCenterV9.7的在线文档。
关于备机可读环境下不支持的操作,请参考本文的第五部分:
不支持的操作。
例如,使用绑定在备机上指定隔离级别,会得到以下错误:
清单11.在备机数据库上绑定时的错误消息
$db2BINDsample.bndISOLATIONCSl_INEMESSAGESFORsample.bnd
SQL0061WThebinderisinprogress.
SQL1773NThestatementorcommandrequiresfunctionality
thatisnotsupportedonaread-enabledHADRstandbydatabase.Reasoncode="5".
SQL0082CAnerrorhasoccurredwhichhasterminatedprocessing.
SQL0092NNopackagewascreatedbecauseofpreviouserrors.
SQL0091NBindingwasendedwith"3"errorsand"0"warnings.
在备机可读的环境下,使用SETCURRENTISOLATION
命令设置应用程序的隔离级别为
非未提交读(UR),可以设置成功,但是实际上该应用程序还是使用为提交读(
UR)的隔
离级别。
例如:
清单12.在备机数据库上通过SETCURRENTISOLATION设置隔离级别
$db2SETCURRENTISOLATIONRR
DB20000ITheSQLcommandcompletedsuccessfully.
$db2VALUESCURRENTISOLATION
1
RR
1record(s)selected.
在备机可读环境中,在SQL语句中也可指定隔离级别,例如:
清单13.在备机数据库上的SQL中设置隔离级别
$db2"SELECT*FROMtestWITHRR"
C1C2
1A
2B
3C
3record(s)selected.
类似的,该设置依然不会生效,该查询语句依然使用的是未提交读(UR)的隔离级别。
高可用性灾难恢复中备机可读隔离级别的验证
要验证这些在备机上的查询语句使用的隔离级别是未提交读(UR),步骤比较复杂。
首先,假设在主数据库上已经建好相应的表,此时在主数据库上关闭自动提交,并插入数据,
不提交也不回滚,使当前事务处于开放状态。
其他事务如果使用非未提交读(UR)隔离级
别,就应该看不到当前事务插入的、但是未提交的这些记录,输出如下所示:
清单14.在验证备机可读环境下隔离级别时,主数据库上的命令:
连接1
db2=>CONNECTTOhadrdb
DatabaseConnectionInformation
Databaseserver=DB2/LINUXX86649.7.1
SQLauthorizationID=XUJING
Localdatabasealias=HADRDB
db2=>UPDATECOMMANDOPTIONSUSINGCOFF
DB20000ITheUPDATECOMMANDOPTIONScommandcompletedsuccessfully.
db2=>INSERTINTOtestVALUES(4,'A'),(5,'B'),(6,'C')
DB20000ITheSQLcommandcompletedsuccessfully.
然后,在主数据库上,再开始一个事务,然后运行如下查询:
I
清单15.在验证备机可读环境下隔离级别时,主数据库上的命令:
连接2
$db2connecttohadrdb
DatabaseConnectionInformation
Databaseserver=DB2/LINUXX86649.7.1
SQLauthorizationID=XUJING
Localdatabasealias=HADRDB
$db2"SELECT*FROMtestWITHCS"
C1C2
0record(s)selected.
$db2"SELECT*FROMtestWITHUR"
C1C2
3record(s)selected.
$db2"INSERTINTOtestVALUES(0,'Z')"
DB20000ITheSQLcommandcompletedsuccessfully.
从上面的结果可以看出,第一条查询语句使用了游标稳定(
CS)的隔离级别,读取不到前
一个事务中未提交的记录,第二条查询语句使用了未提交读(
UR)的隔离级别,得到了前
一事务中未提交的记录。
最后,向表中插入一条记录,由于自动提交在这个事务中是打开的,所以这条记录会被自己
动提交,能够被其他事务中读取。
我们用这条已提交的记录,
作为接下来在备机上查询的参
考基准。
现在,在备机上运行查询:
清单16.在验证备机可读环境下隔离级别时,备机数据库上的命令
$db2SETCURRENTISOLATIONCS
DB20000ITheSQLcommandcompletedsuccessfully.
$db2"SELECT*FROMtest"
C1C2
0Z
4A
5B
6C
4record(s)selected.
$db2"SELECT*FROMtestWITHUR"
C1C2
0Z
4A
5B
6C
4record(s)selected.
$db2"SELECT*FROMtestWITHCS"
C1C2
4A
5B
6C
4record(s)selected.
从上面的运行结果可以看出,备机上的查询不论是游标稳定(CS)还是未提交读(UR)的
隔离级别,都获取了主数据库上未提交和已提交的数据。
即使在应用程序中使用SET
CURRENTISOLATION命令设置非UR的隔离级别,查询依旧能够读取到主数据库上已提交和未提交的数据。
能够获取其他事务未提交的数据,应用程序必然是在未提交读(UR)
的隔离级别上进行的读操作。
从上面的结果我们可以得出结论,事实上在备机上不论指定任
何隔离级别,查询都会并且只能以未提交读(UR)的隔离级别运行。
控制备机数据库上应用程序的隔离级别
为了控制高可用性灾难恢复的备机可读环境下备机上应用程序的隔离级别,在DB2V9.7.1
中引入了一个新的注册变量:
DB2_DEFAULT_ISO_SECONDARY。
在应用程序使用高于
未提交读(UR)的隔离级别读取数据时,通过设置该注册变量的值,能够控制备机数据库的行为。
既可以没有任何错误或警告信息,强制把该应用程序的隔离级别转化成未提交读,也可以抛出相应错误消息。
7
刚才提到,在DB2中,应用程序的默认隔离级别是游标稳定(CS)。
要改变或设置改默认隔离级别,可以通过设置注册变量DB2_DEFAULT_ISOLATION_VALUE来实现。
由此,上述两个注册变量组合起来,备机数据库会有以下几种行为:
1.
当DB2DEFAULTISOSECONDARY=on.
时
DB2_DEFAULT_ISOLATION_VALUE=anyvalue
此时,不论应用程序使用何种隔离级别,都会被强制转换成未提交读(UR)。
2.
当DB2DEFAULTISOSECONDARY=off,
DB2DEFAULTISOLATIONVALUE=notUR
时
使用咼于未提交读(UR)隔离级别的应用程序,
在备机上运行时,会得到错误消息」
SQL1773N,原因代码1。
3.
当DB2_DEFAULT_ISO_SECONDARY=off,J
DB2DEFAULTISOLATIONVALUE=UR时
隔离级别咼于未提交读(UR)的动态应用程序,
不会收到任何出错消息,隔离级别
会被强制转换成未提交读(UR);对于动态应用程序,若隔离级别高于未提交读(UR),则会收到错误消息SQL1773N,原因代码1。
关于隔离级别的建议
在高可用性灾难恢复的备机可读环境中,由于在备机上的应用程序只能以未提交读的隔离级
别进行读操作,有以下几条建议:
1.如果有应用程序需要使用高于未提交读的隔离级别,此时只能在主数据库上进行。
2.在编写应用程序时,如果可能,尽量使用未提交读的隔离级别。
3.对于现有的、隔离级别高于未提交读的应用程序,如果它们在未提交读的隔离级别
下也能正常工作,那么,可以设置注册变量
DB2_DEFAULT_ISO_SECONDARY=off「
回页首
不可读窗口(ReplayOnlyWindow)
在备机可读的环境下,备机并不是每时每刻都能够接受应用程序的连接、提供查询服务的。
备机不能提供连接和查询功能的时间区间,被称为不可读窗口(ReplayOnlyWindow,即
只重做(日志)窗口)。
在此窗口的时间区间内,备机数据库只进行数据库日志重做,不提供连接和只读的服务,类似于没有启用备机可读功能的备机数据库。
备机进入此窗口时,对
于已经连接到备机数据库上的应用程序,连接会被服务器断开;从此刻开始,应用程序再向
备机数据库发起连接的请求会被拒绝。
直到不可读窗口结束后,备机才能接受新的连接,进
而提供查询服务。
不可读窗口的外部行为
如下所示,在备机数据库上的连接被断开后,尝试访问数据库对象,会得到一下错误信息:
清单17.备机数据库处于不可读窗口时,尝试访问备机数据库对象时的错误消息
$