LoginMode:作用于 JDBC、dm_svc.conf 等客户端配置,指定优先登录的服务器模式。定义客户端节点筛选、连接优先级规则,
LoginMode取值范围 0~4,缺省为 4。
LoginMode = 0:优先连接 PRIMARY 模式的库,NORMAL 模式次之,最后选择 STANDBY 模式;
LoginMode = 1:只连接主库;
LoginMode = 2:只连接备库;
LoginMode = 3:优先连接 STANDBY 模式的库,PRIMARY 模式次之,最后选择 NORMAL 模式;
LoginMode = 4:优先连接 NORMAL 模式的库,PRIMARY 模式次之,最后选择 STANDBY 模式;
| LoginMode | 连接匹配逻辑 | 连接结果 |
|---|---|---|
| 0 | PRIMARY>NORMAL>STANDBY | 连接成功 |
| 1 | 仅允许 PRIMARY,单机无主库角色 | 连接失败 |
| 2 | 仅允许 STANDBY,单机无备库角色 | 连接失败 |
| 3 | STANDBY>PRIMARY>NORMAL | 连接成功 |
| 4 | 优先级最高匹配 NORMAL 单机 | 连接成功 |
package java_jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class jdbc_login {
static String jdbcString = "dm.jdbc.driver.DmDriver";
static String urlString = "jdbc:dm://DM_SVC?logLevel=all&logDir=D:\\资料\\达梦\\jdbclog";
static String userName = "SYSDBA";
static String password = "DMdata456";
static Connection conn = null;
public static void main(String[] args) {
try {
System.out.println("Loading JDBC Driver...");
Class.forName(jdbcString);
System.out.println("Connect via dm_svc.conf service name [DM_SVC] ...");
conn = DriverManager.getConnection(urlString, userName, password);
System.out.println("=== 连接建立成功 ===");
printConnectionInfo(conn);
keepAliveLoop(conn);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
System.err.println("数据库连接异常:");
e.printStackTrace();
} finally {
closeResource();
}
}
/**
* 查询实例、会话信息
*/
public static void printConnectionInfo(Connection conn) throws SQLException {
if(conn == null || conn.isClosed()){
System.out.println("当前连接已关闭");
return;
}
Statement stmt = conn.createStatement();
// SESSID() 获取当前会话ID
String sql = "SELECT i.NAME, i.MODE$, s.SESS_ID " +
"FROM V$INSTANCE i, V$SESSIONS s " +
"WHERE s.SESS_ID = SESSID()";
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()){
String instName = rs.getString("NAME");
String modeStr = rs.getString("MODE$");
long sessionId = rs.getLong("SESS_ID");
System.out.println("实例名称 : " + instName);
System.out.println("实例MODE$角色: " + modeStr);
System.out.println("当前会话SESS_ID : " + sessionId);
}
rs.close();
stmt.close();
}
public static void keepAliveLoop(Connection conn){
System.out.println("\n进入保活等待循环,每隔5s执行探测SQL;手动终止程序结束。");
System.out.println("提示:空闲sleep不会自动切换;只有执行SQL才触发故障切换逻辑。\n");
Connection localConn = conn;
while(true){
try {
if(localConn.isClosed()){
System.out.println("连接已经关闭,尝试重新获取连接...");
localConn = DriverManager.getConnection(urlString, userName, password);
System.out.println("重连成功!");
printConnectionInfo(localConn);
}
Statement st = localConn.createStatement();
st.execute("select 1");
st.close();
System.out.printf("[%tT] 链路探测正常,当前角色:%s%n",System.currentTimeMillis(), getCurrentMode(localConn));
Thread.sleep(5000);
} catch (SQLException e) {
System.err.printf("[%tT] 链路出现SQLException: %s%n",System.currentTimeMillis(),e.getMessage());
} catch (InterruptedException e) {
System.out.println("线程被中断,退出等待循环");
break;
}
}
}
private static String getCurrentMode(Connection conn) {
String mode = "unknown";
try(Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT MODE$ FROM V$INSTANCE")){
if(rs.next()){
mode = rs.getString(1);
}
} catch (SQLException ignored) {}
return mode;
}
public static void closeResource(){
try {
if(conn != null && !conn.isClosed()){
conn.close();
}
System.out.println("\n资源已关闭");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
TIME_ZONE=(480)
LANGUAGE=(cn)
DM_SVC=(192.168.43.3:5234)
[DM_SVC]
LOGIN_MODE=(4)
SWITCH_TIMES=(5)
SWITCH_INTERVAL=(300)
login_mode=1 or 2时,不能连接单库
login_mode=0,3,4时可以正常连接
TIME_ZONE=(480)
LANGUAGE=(cn)
# 填入你的集群/单机节点IP端口,这里示例服务名叫 DM_SVC
DM_SVC=(192.168.43.4:5236,192.168.43.5:5236)
[DM_SVC]
LOGIN_MODE=(0) ## primary>normal>standby
SWITCH_TIMES=(5)
SWITCH_INTERVAL=(300)
login_mode=0 时
优先连接主库
若主库异常关闭,则进行重连,连接备库
login_mode=1 时,只连接主库
此时,重连并不会连接到备库中
login_mode=2 时,只连接备库
同理,此时,重连并不会连接到主库中
login_mode=3 时,standby>primary>normal
若备库异常关闭,则进行重连,连接主库
中途若备库恢复,则连接指向备库
login_mode=4 时,normal>primary>standby,验证逻辑同上。
文章
阅读量
获赞
