DB2 HADR环境下,应用的改变

最近根据项目的需求,搭建了
DB2 HADR (一个primary,2个standby), with a virtual ip
Dprop
搭建按部就班的进行,每个server上都有两个网卡,其中一个是HADR使用的,另个一个是对外服务使用
先加载了数据,然后构建HADR,设置dprop,最后部署数据库维护脚本。

关于和应用结合的技术方面的实现,做一个小的总结

在DB2 HADR环境下,对于WAS, 和backend 程序,需要做一点改动,这样当primary和principal standby切换的时候,WAS和backend不用改,实现自动切换。
WAS和backend和数据库连接使用的是一个DB2 HADR的virtual ip,virtual ip是存在primary server上面的浮动ip,当principal standby变成primary 的时候,浮动ip就会自动切换
primary和principal standby servers在同一个城市,实现的是数据库的HA(高可用性),基于非常好的网络情况,同步方式是SYNC来确保数据的不会丢失,还有一个DR server在另外一个城市,对于DR,只能采用superasync的方式
从primary到DR的网络传输是4 MB每秒,测试表明,在系统业务量的高峰期,DR会在10分钟内完成日志的重做,这种程度的数据丢失是符合客户的要求的。

对于HA的两个server,要求全自动切换
对于DR server,需要手工切换
这个全自动切换涉及三个方面的内容
1. DB2 Database以及相关的DB2 SQL Replication(和其他项目的数据库关联来pull, push data),这就要求在HADR切换的时候,dprop也需要自动切换
对于这个问题,是通过修改下面的两个脚本来实现的,加上dprop启停脚本的调用就可以了,但是因为多个dprop,需要进行一点逻辑判断,判断是哪个实例的哪个数据库,然后调用哪个脚本
/usr/sbin/rsct/sapolicies/db2/hadrV105_stop.ksh
/usr/sbin/rsct/sapolicies/db2/hadrV105_start.ksh
可能并不是所有的HADR的脚本的位置都是上面这样的,可以通过类似下面的命令进行查看
lsrsrc IBM.Application StartCommand StopCommand MonitorCommand
2. 对于WAS部分的datasource的设置,在原来的基础上,要加上一个custome property: Seamless failover
这样当principal standby变成primary的时候,一个正在进行的应用连接会等待,然后连接会自动切换到新的primary db2 database,继续执行。
3. 对于后台的一些应用,关于数据库的连接信息是放在一个property file中的,现在需要两个property file了
其中一个property file,设置的是virtual ip的信息和enableSeamlessFailover=true等方面的信息
### JCC Properties read through -Ddb2.jcc.propertiesFile=./conn.properties
#db2.jcc.traceFile=./jcc.trace
db2.jcc.outputDirectory=.

### Connection level properties used by
### DriverManager.getConnection(url, conProperties);
user=db2psc
password=password
portNumber=50000
deferPrepares=false        
retrieveMessagesFromServerOnGetMessage=true
clientApplicationInformation=hadrrosProg
clientProgramName=mixedwl
clientWorkstation=node03
defaultIsolationLevel=2
driverType=4

### Properties for the Automatic Client Reroute
#enableSysplexWLB=true
#enableConnectionConcentrator=true
enableSeamlessFailover=true
clientRerouteAlternateServerName=192.168.142.100,192.168.142.100
clientRerouteAlternatePortNumber=50000,50000
enableClientAffinitiesList=1
maxRetriesForClientReroute=4
retryIntervalForClientReroute=120

### properties read by the application such as server, port,
### dbName, taskprefix, autoCommit, fetchsize
server=192.168.142.100
port=50000
dbName=hadb

Java代码读取这个信息放到一个Properties对象中,在建立数据库连接的时候,采用下面的方式
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Properties;

public class Test1 {

    /**
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        String propFile = "C:\\Users\\IBM_ADMIN\\IBM\\rationalsdp\\ds1\\hadr\\src\\hadr.properties";
        Properties connProp = new Properties();

        FileInputStream dsPropFile = null;
        try {
            dsPropFile = new FileInputStream(propFile);
        } catch (FileNotFoundException fe) {
            System.out.println(fe.getMessage());
            throw fe;
        }
        connProp.load(dsPropFile);

        String server = connProp.getProperty("server");
        String port = connProp.getProperty("port");
        String dbName = connProp.getProperty("dbName");
        String url = "jdbc:db2://" + server + ":" + port + "/" + dbName;

        Connection bladeConn = null;
        PreparedStatement pstmt = null;

        try {
            bladeConn = DriverManager.getConnection(url, connProp);
            bladeConn.setAutoCommit(false);
            pstmt = bladeConn.prepareStatement("insert into t values(?,?)");
            for (int i = 0; i < 100000000; i++) {
                pstmt.setInt(1, i);
                pstmt.setInt(2, i);
                pstmt.addBatch();
                
                boolean retry=false;
                do
                {
                    retry=false;
                    try
                    {
                        if (i % 50 == 0) {
                            pstmt.executeBatch();
                            bladeConn.commit();
                            System.out.println(i);
                        }
                    }catch(SQLException se) {
                        //deal with client reroute exception
                        int errorcode = se.getErrorCode();
                        System.out.println("SQLException: " + se);
                        System.out.println("SQLCode: " + errorcode);
                        if(bladeConn != null){
                        try{
                            bladeConn.rollback();
                        }catch(Exception e)
                        { e.printStackTrace(); }
                        } //endif
                        
                        if((errorcode == -30108) || (errorcode == -4498)){
                            System.out.println("connection is re-established, re-executing the failed transaction.");
                            retry = true;
                        }
                    }                    
                }
                while(retry);
            }
            System.out.print("Batch execution completed.");
        } catch (Exception ex) {
            ex.printStackTrace();
            System.exit(-1);
        } finally {
            try {
                pstmt.close();
                bladeConn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

另外一个property file就是包括了DR数据库的信息,这样如果HA的两个服务器都down了以后,手工改动crontab的调用。

另外注意的一点是,WAS的DR和DB2的DR是对应的,就是说,当DB2使用到DR的时候,WAS及时没有出现问题,也会使用DR
考虑到使用DR的机会还是非常小的,这点客户可以忍受。


请使用浏览器的分享功能分享到微信等