Oracle 连接池(Connection Pooling)与 DRCP

Oracle 连接池(Connection Pooling)与 DRCP

适用版本:Oracle Database 11g / 12c / 19c / 23ai 文档版本:v1.0 / 2026-07


1. 概述

连接池(Connection Pooling) 通过复用数据库连接,减少连接建立开销[1]:

方案实现层适用场景
应用层连接池应用(Tomcat/HikariCP)通用
共享服务器(Shared Server)数据库中等连接数
DRCP数据库海量短连接
CMAN Multiplexing中间层多路复用

2. 应用层连接池

2.1 工作原理

应用启动 → 创建 N 个数据库连接 → 放入连接池


应用请求 → 从池中取连接 → 执行 SQL → 归还连接到池

2.2 HikariCP 配置示例(Java)

HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:oracle:thin:@//dbhost:1521/orcl");
config.setUsername("scott");
config.setPassword("tiger");

// 连接池配置
config.setMaximumPoolSize(20);       // 最大连接数
config.setMinimumIdle(5);            // 最小空闲
config.setConnectionTimeout(30000);  // 连接超时 30 秒
config.setIdleTimeout(600000);       // 空闲超时 10 分钟
config.setMaxLifetime(1800000);      // 连接最长生命 30 分钟

HikariDataSource ds = new HikariDataSource(config);

2.3 优缺点

优点

  • 应用层控制
  • 灵活配置
  • 性能高

缺点

  • 每个应用独立
  • 进程数仍较多(每个应用 N 个连接)

3. 数据库共享服务器(Shared Server)

3.1 工作模型

客户端 1 ─┐
客户端 2 ─┼─> Dispatcher ─> Request Queue ─> Shared Server 1
客户端 3 ─┤                                ─> Shared Server 2
客户端 N ─┘                                └> Shared Server 3
                                            └> Response Queue ─> Dispatcher ─> 客户端

3.2 配置

ALTER SYSTEM SET shared_servers=5 SCOPE=BOTH;
ALTER SYSTEM SET max_shared_servers=20 SCOPE=BOTH;
ALTER SYSTEM SET dispatchers='(PROTOCOL=TCP)(DISPATCHERS=3)' SCOPE=BOTH;
ALTER SYSTEM SET shared_server_sessions=200 SCOPE=BOTH;

详细内容见:Oracle 进程模型:专用 vs 共享服务器


4. DRCP(Database Resident Connection Pool)

4.1 概念

11g 引入,数据库驻留连接池,比共享服务器更高效[2]:

客户端 1 ─┐
客户端 2 ─┼─> Connection Broker ─> Pool Servers(4-100 个)
客户端 3 ─┤
客户端 N ─┘

4.2 DRCP vs 共享服务器

维度共享服务器DRCP
粒度SQL 语句级会话级
复用多客户端轮流使用池化复用
适用中等连接数海量短连接
客户端支持需配置 tnsnamesOCI/JDBC 直接支持
进程数Dispatcher + Shared ServerBroker + Pool Server

4.3 DRCP 配置

-- 启动 DRCP
EXEC DBMS_CONNECTION_POOL.START_POOL;

-- 配置池参数
EXEC DBMS_CONNECTION_POOL.ALTER_PARAM(
  param_name => 'MINSIZE', 
  param_value => '4'
);

EXEC DBMS_CONNECTION_POOL.ALTER_PARAM(
  param_name => 'MAXSIZE', 
  param_value => '100'
);

EXEC DBMS_CONNECTION_POOL.ALTER_PARAM(
  param_name => 'INACTIVITY_TIMEOUT', 
  param_value => '300'
);

EXEC DBMS_CONNECTION_POOL.ALTER_PARAM(
  param_name => 'MAX_THINK_TIME', 
  param_value => '120'
);

-- 查看状态
SELECT connection_pool, status, MINSIZE, MAXSIZE 
FROM dba_cpool_info;

4.4 客户端使用

# tnsnames.ora 指定 POOL
ORCL_DRCP =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = dbhost)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = POOLED)            # 使用 DRCP
      (SERVICE_NAME = orcl)
    )
  )

# 连接
sqlplus scott/tiger@orcl_drcp

4.5 Java 使用 DRCP

// JDBC 连接字符串
String url = "jdbc:oracle:thin:@//dbhost:1521/orcl?oracle.jdbc.ReadTimeout=60000";
Properties props = new Properties();
props.setProperty("user", "scott");
props.setProperty("password", "tiger");
// 启用 DRCP
props.setProperty("oracle.jdbc.v8styleConnectionPool", "true");

Connection conn = DriverManager.getConnection(url, props);

4.6 DRCP 监控

-- 池状态
SELECT 
  connection_pool, 
  status, 
  MINSIZE, 
  MAXSIZE,
  SESSION_CACHED_CUR
FROM dba_cpool_info;

-- 池统计
SELECT 
  POOL_NAME,
  NUM_OPEN_SERVERS,
  NUM_REQUESTS,
  NUM_HITS,
  NUM_MISSES
FROM v$cpool_stats;

-- 池连接详情
SELECT 
  SESSKEY, 
  STATE, 
  SERVER_NAME,
  PROGRAM
FROM v$cpool_conn_info;

5. Connection Manager(CMAN)Multiplexing

5.1 概念

CMAN 在中间层多路复用多个客户端连接,减少数据库端进程数。

5.2 配置

# cman.ora
CMAN =
  (ADDRESS=(PROTOCOL=TCP)(HOST=cman_host)(PORT=1630))

CMAN_PROFILE =
  (PARAMETER_LIST=
    (MAXIMUM_RELAYS=128)
    (LOG_LEVEL=1)
    (MULTIPLEXING=ON)
    (RELAY_STATISTICS=YES)
  )

详细内容见:Oracle Connection Manager(CMAN)


6. FCF(Fast Connection Failover)

6.1 概念

RAC + ONS(Oracle Notification Service)实现的快速故障切换。

6.2 配置

// Java 配置
OracleDataSource ods = new OracleDataSource();
ods.setURL("jdbc:oracle:thin:@//rac-scan:1521/orcl");
ods.setUser("scott");
ods.setPassword("tiger");
ods.setConnectionCachingEnabled(true);
ods.setFastConnectionFailoverEnabled(true);

Properties cacheProps = new Properties();
cacheProps.setProperty("MinLimit", "5");
cacheProps.setProperty("MaxLimit", "20");
cacheProps.setProperty("InitialLimit", "5");
cacheProps.setProperty("ConnectionWaitTimeout", "10");
ods.setConnectionCacheProperties(cacheProps);

7. 连接池选择

7.1 决策树

连接数 < 100:
  → 应用层连接池(HikariCP)

连接数 100-1000:
  → 应用层连接池 + 共享服务器

连接数 1000-10000+:
  → 应用层连接池 + DRCP

需要负载均衡:
  → RAC + FCF + SCAN

7.2 对比

方案适用规模实现复杂度性能
应用层连接池小-中
共享服务器
DRCP
CMAN

8. 常见坑与排错

8.1 ORA-12520: no available handler

现象:连接数过多,无可用处理进程。

修复

-- 增大 PROCESSES
ALTER SYSTEM SET processes=500 SCOPE=SPFILE;
-- 重启生效

-- 或启用 DRCP/共享服务器

8.2 DRCP 连接失败

现象ORA-56609: DRCP not started

修复

EXEC DBMS_CONNECTION_POOL.START_POOL;
SELECT status FROM dba_cpool_info;

8.3 连接泄漏

现象:连接数持续增长。

修复

// 应用层确保连接关闭
try (Connection conn = ds.getConnection()) {
  // 使用连接
}  // 自动关闭

// 设置 maxLifetime 避免泄漏
config.setMaxLifetime(1800000);

8.4 连接超时

现象:连接等待时间长。

修复

-- 检查等待事件
SELECT event, total_waits, time_waited
FROM v$system_event
WHERE event LIKE '%queue%';

-- 增加共享服务器
ALTER SYSTEM SET shared_servers=10 SCOPE=BOTH;

9. 最佳实践

  1. 应用层用 HikariCP:性能最佳
  2. 海量连接用 DRCP:减少进程数
  3. 中等连接用共享服务器:折中方案
  4. RAC 用 FCF:快速故障切换
  5. 合理设置连接数:避免过度
  6. 连接泄漏检测:定期监控
  7. 连接超时配置:避免资源耗尽
  8. 监控 v$session:发现异常连接
  9. DRCP 池大小动态调整:根据负载
  10. 应用与 DBA 协作:统一连接管理

10. 参考资料

[1] Oracle Database Net Services Administrator’s Guide 19c, “Connection Pooling” https://docs.oracle.com/en/database/oracle/oracle-database/19/netag/

[2] Oracle Database Administrator’s Guide 19c, “Database Resident Connection Pooling” https://docs.oracle.com/en/database/oracle/oracle-database/19/admin/managing-processes.html