外观
Oracle 连接控制与管理
连接控制是Oracle数据库安全与性能管理的核心组成部分,通过合理限制和管理数据库连接,可以防止资源耗尽、拒绝服务攻击和恶意连接,确保数据库资源的高效利用。对于DBA而言,掌握连接控制策略的配置、监控和优化是保障数据库稳定运行的关键。
连接控制核心概念
连接控制的主要维度
连接控制涉及以下几个关键维度:
- 连接数限制:控制全局、用户或会话级别的最大连接数量
- 连接超时:自动断开长时间空闲或未响应的连接
- 连接来源:限制允许连接的IP地址或主机名
- 连接资源:限制每个连接可使用的CPU、内存、I/O等资源
- 连接认证:验证连接用户的身份和权限
- 连接加密:保护连接数据的传输安全
连接相关的核心参数
| 参数名称 | 功能描述 | 默认值 |
|---|---|---|
| PROCESSES | 数据库允许的最大进程数(包括连接进程) | 300 |
| SESSIONS | 数据库允许的最大会话数 | PROCESSES * 1.1 + 5 |
| TRANSACTIONS | 数据库允许的最大事务数 | SESSIONS * 1.1 |
连接数管理
全局连接数配置
查看当前连接状态
sql
-- 查看当前连接数统计
SELECT
COUNT(*) AS total_connections,
SUM(CASE WHEN STATUS = 'ACTIVE' THEN 1 ELSE 0 END) AS active_connections,
SUM(CASE WHEN STATUS = 'INACTIVE' THEN 1 ELSE 0 END) AS inactive_connections
FROM V$SESSION;
-- 查看每个用户的连接数
SELECT USERNAME, COUNT(*) AS connection_count
FROM V$SESSION
WHERE USERNAME IS NOT NULL
GROUP BY USERNAME
ORDER BY connection_count DESC;
-- 查看每个应用程序的连接数
SELECT PROGRAM, COUNT(*) AS connection_count
FROM V$SESSION
WHERE PROGRAM IS NOT NULL
GROUP BY PROGRAM
ORDER BY connection_count DESC;
-- 查看每个机器的连接数
SELECT MACHINE, COUNT(*) AS connection_count
FROM V$SESSION
WHERE MACHINE IS NOT NULL
GROUP BY MACHINE
ORDER BY connection_count DESC;调整全局连接数
sql
-- 查看当前连接数参数
SELECT name, value
FROM V$PARAMETER
WHERE name IN ('processes', 'sessions', 'transactions');
-- 计算合适的连接数
-- 建议值:PROCESSES = CPU核心数 * 10-20(根据服务器配置调整)
-- SESSIONS = PROCESSES * 1.1 + 5
-- TRANSACTIONS = SESSIONS * 1.1
-- 修改连接数参数(需要重启数据库)
ALTER SYSTEM SET PROCESSES = 500 SCOPE = SPFILE;
ALTER SYSTEM SET SESSIONS = 555 SCOPE = SPFILE;
ALTER SYSTEM SET TRANSACTIONS = 610 SCOPE = SPFILE;
-- 重启数据库使参数生效
SHUTDOWN IMMEDIATE;
STARTUP;用户级连接限制
使用Profile限制用户连接数
sql
-- 创建应用用户连接限制Profile
CREATE PROFILE app_user_profile LIMIT
SESSIONS_PER_USER 10 -- 每个用户最大10个并发连接
IDLE_TIME 60 -- 空闲60分钟后断开
CONNECT_TIME 1440; -- 最大连接时长24小时
-- 创建管理员用户连接限制Profile
CREATE PROFILE admin_profile LIMIT
SESSIONS_PER_USER 5 -- 管理员用户最大5个并发连接
IDLE_TIME 30 -- 空闲30分钟后断开
CONNECT_TIME 720; -- 最大连接时长12小时
-- 将Profile分配给用户
ALTER USER app_user PROFILE app_user_profile;
ALTER USER sysadmin PROFILE admin_profile;
-- 查看用户Profile配置
SELECT USERNAME, PROFILE
FROM DBA_USERS
WHERE USERNAME IN ('APP_USER', 'SYSADMIN');监控用户连接数
sql
-- 查看用户当前连接数
SELECT USERNAME, COUNT(*) AS current_connections
FROM V$SESSION
WHERE USERNAME IS NOT NULL
GROUP BY USERNAME
HAVING COUNT(*) > 5; -- 查找连接数超过5的用户
-- 查看用户连接历史趋势(需要AWR)
SELECT SNAP_ID, BEGIN_INTERVAL_TIME,
MAX(ACTIVE_SESSIONS) AS max_active_sessions
FROM DBA_HIST_SYSMETRIC_SUMMARY
WHERE METRIC_NAME = 'Active Sessions'
GROUP BY SNAP_ID, BEGIN_INTERVAL_TIME
ORDER BY SNAP_ID;连接超时管理
SQL*Net连接超时配置
服务端配置(sqlnet.ora)
# 启用TCP keepalive(建议启用)
TCP.KEEPALIVE = YES
# 空闲连接检测间隔(分钟)
SQLNET.EXPIRE_TIME = 15
# 入站连接超时(秒)
INBOUND_CONNECT_TIMEOUT = 30
# 出站连接超时(秒)
SQLNET.OUTBOUND_CONNECT_TIMEOUT = 30
# 连接建立超时(秒)
SQLNET.INBOUND_CONNECT_TIMEOUT_LISTENER = 60监听器超时配置(listener.ora)
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = db-server)(PORT = 1521))
)
)
# 监听器入站连接超时(秒)
INBOUND_CONNECT_TIMEOUT_LISTENER = 60
# 监听器响应超时(秒)
CONNECT_TIMEOUT_LISTENER = 10Profile连接超时配置
sql
-- 创建超时限制Profile
CREATE PROFILE timeout_profile LIMIT
IDLE_TIME 45 -- 空闲45分钟后断开
CONNECT_TIME 1080 -- 最大连接时长18小时
IDLE_TIME 45 -- 空闲45分钟后断开
INACTIVE_ACCOUNT_TIME 365; -- 账号365天不活动后锁定
-- 应用到用户
ALTER USER app_user PROFILE timeout_profile;清理空闲连接
sql
-- 查找空闲时间超过1小时的会话
SELECT SID, SERIAL#, USERNAME, MACHINE, PROGRAM,
LAST_CALL_ET/60 AS idle_minutes
FROM V$SESSION
WHERE STATUS = 'INACTIVE'
AND LAST_CALL_ET > 60 -- 空闲超过1小时
AND USERNAME IS NOT NULL
ORDER BY idle_minutes DESC;
-- 批量终止空闲会话(示例)
DECLARE
CURSOR idle_sessions IS
SELECT SID, SERIAL#
FROM V$SESSION
WHERE STATUS = 'INACTIVE'
AND LAST_CALL_ET > 3600 -- 空闲超过1小时
AND USERNAME IS NOT NULL
AND USERNAME != 'SYS'; -- 排除SYS用户
BEGIN
FOR s IN idle_sessions LOOP
EXECUTE IMMEDIATE 'ALTER SYSTEM KILL SESSION ''' || s.SID || ',' || s.SERIAL# || ''' IMMEDIATE';
DBMS_OUTPUT.PUT_LINE('终止会话: ' || s.SID || ',' || s.SERIAL#);
END LOOP;
END;
/连接来源控制
SQL*Net节点检查
# 启用节点检查
TCP.VALIDNODE_CHECKING = YES
# 允许连接的IP地址/主机名列表
TCP.INVITED_NODES = (
192.168.1.0/24, # 允许整个网段
10.0.0.10, # 允许特定IP
db-application-server # 允许特定主机名
)
# 拒绝连接的IP地址/主机名列表
TCP.EXCLUDED_NODES = (
192.168.1.100, # 拒绝特定IP
untrusted-host # 拒绝特定主机名
)防火墙连接控制
Linux iptables配置
bash
# 允许应用服务器网段访问数据库
iptables -A INPUT -p tcp -s 192.168.1.0/24 --dport 1521 -j ACCEPT
# 允许管理网段访问数据库
iptables -A INPUT -p tcp -s 10.0.0.0/24 --dport 1521 -j ACCEPT
# 拒绝其他所有IP访问数据库端口
iptables -A INPUT -p tcp --dport 1521 -j DROP
# 保存iptables规则
iptables-save > /etc/sysconfig/iptablesWindows防火墙配置
powershell
# 创建入站规则,允许特定IP访问1521端口
New-NetFirewallRule -DisplayName "Oracle Database Access" `
-Direction Inbound `
-Protocol TCP `
-LocalPort 1521 `
-RemoteAddress 192.168.1.0/24,10.0.0.0/24 `
-Action Allow连接资源限制
Profile资源限制配置
sql
-- 创建资源限制Profile
CREATE PROFILE resource_limit_profile LIMIT
-- CPU资源限制
CPU_PER_SESSION 1000000 -- 每个会话最多使用10秒CPU时间
CPU_PER_CALL 100000 -- 每个调用最多使用1秒CPU时间
-- 内存/IO资源限制
LOGICAL_READS_PER_SESSION 1000000 -- 每个会话最多100万次逻辑读
LOGICAL_READS_PER_CALL 100000 -- 每个调用最多10万次逻辑读
-- 会话限制
SESSIONS_PER_USER 10 -- 每个用户最多10个会话
CONNECT_TIME 1440 -- 每个会话最多24小时
IDLE_TIME 60 -- 空闲60分钟后断开
-- 并发事务限制
COMPOSITE_LIMIT 5000000; -- 复合资源限制(CPU+I/O)
-- 启用资源限制
ALTER SYSTEM SET RESOURCE_LIMIT = TRUE SCOPE = BOTH;
-- 应用到用户
ALTER USER app_user PROFILE resource_limit_profile;监控连接资源使用
sql
-- 查看会话资源使用情况
SELECT SID, SERIAL#, USERNAME,
CPU_TIME/100 AS cpu_seconds, -- CPU使用时间(秒)
BLOCK_GETS + CONSISTENT_GETS AS logical_reads, -- 逻辑读数量
PHYSICAL_READS AS physical_reads, -- 物理读数量
ROWS_PROCESSED -- 处理的行数
FROM V$SESSION
WHERE USERNAME IS NOT NULL
ORDER BY cpu_seconds DESC;
-- 查看资源使用超过阈值的会话
SELECT SID, SERIAL#, USERNAME, CPU_TIME/100 AS cpu_seconds
FROM V$SESSION
WHERE CPU_TIME > 50000 -- CPU使用超过5秒
AND USERNAME IS NOT NULL;连接池管理
连接池类型与选择
Oracle数据库支持多种连接池技术:
| 连接池类型 | 适用场景 | 优势 |
|---|---|---|
| Oracle UCP | Java应用,需要高度可定制性 | 官方支持,功能丰富,监控能力强 |
| HikariCP | 性能要求高的Java应用 | 轻量级,性能优异,配置简单 |
| DBCP/C3P0 | 传统Java应用 | 稳定可靠,广泛使用 |
| 应用服务器连接池 | 企业级应用,如WebLogic、WebSphere | 与应用服务器深度集成,管理方便 |
| Oracle Database Resident Connection Pool (DRCP) | 短连接频繁的应用 | 减少数据库进程开销,提高并发能力 |
Oracle DRCP配置
DRCP适合大量短连接的应用场景,可以显著减少数据库进程数量:
sql
-- 查看DRCP状态
SELECT NAME, STATUS FROM V$CPOOL_INFO;
-- 启用DRCP
EXEC DBMS_CONNECTION_POOL.START_POOL();
-- 配置DRCP
EXEC DBMS_CONNECTION_POOL.CONFIGURE_POOL(
pool_name => 'SYS_DEFAULT_CONNECTION_POOL',
minsize => 4, -- 最小连接数
maxsize => 40, -- 最大连接数
incrsize => 2, -- 每次增加的连接数
session_cached_cursors => 20,
inactivity_timeout => 300, -- 连接池空闲超时(秒)
max_think_time => 60, -- 会话最大思考时间(秒)
max_use_session => 1000, -- 每个会话最大使用次数
max_lifetime_session => 3600 -- 会话最大生命周期(秒)
);
-- 查看DRCP配置
SELECT * FROM DBA_CPOOL_INFO;UCP连接池配置示例
java
import oracle.ucp.jdbc.PoolDataSource;
import oracle.ucp.jdbc.PoolDataSourceFactory;
// 创建UCP数据源
PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource();
// 基本配置
pds.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource");
pds.setURL("jdbc:oracle:thin:@//db-server:1521/PDB1");
pds.setUser("app_user");
pds.setPassword("SecurePass_2023");
// 连接池大小配置
pds.setInitialPoolSize(10);
pds.setMinPoolSize(5);
pds.setMaxPoolSize(50);
// 连接超时配置
pds.setConnectionWaitTimeout(30); // 连接获取超时(秒)
pds.setInactiveConnectionTimeout(300); // 空闲连接超时(秒)
pds.setAbandonedConnectionTimeout(1800); // 废弃连接超时(秒)
// 连接验证配置
pds.setValidateConnectionOnBorrow(true);
pds.setSQLForValidateConnection("SELECT 1 FROM DUAL");
pds.setValidationTimeout(5); // 连接验证超时(秒)
// 连接回收配置
pds.setConnectionHarvestMaxCount(10); // 最大回收连接数
pds.setConnectionHarvestTriggerCount(40); // 触发回收的连接数阈值多租户环境连接管理
CDB与PDB连接控制
在多租户环境中,连接控制可以在CDB和PDB级别分别配置:
sql
-- CDB级别查看连接数
SELECT CON_ID, COUNT(*) AS connection_count
FROM V$SESSION
WHERE TYPE != 'BACKGROUND'
GROUP BY CON_ID
ORDER BY CON_ID;
-- 查看特定PDB的连接数
ALTER SESSION SET CONTAINER = PDB1;
SELECT COUNT(*) AS pdb1_connections
FROM V$SESSION
WHERE TYPE != 'BACKGROUND';
-- PDB级别设置资源限制
ALTER SESSION SET CONTAINER = PDB1;
CREATE PROFILE pdb1_app_profile LIMIT
SESSIONS_PER_USER 15
IDLE_TIME 45
CONNECT_TIME 1080;
-- 为PDB用户分配Profile
ALTER USER pdb1_app_user PROFILE pdb1_app_profile;多租户连接监控
sql
-- 查看所有PDB的连接数
SELECT
P.PDB_NAME,
COUNT(S.SID) AS connection_count
FROM
CDB_PDBS P
LEFT JOIN
V$SESSION S ON P.CON_ID = S.CON_ID AND S.TYPE != 'BACKGROUND'
GROUP BY
P.PDB_NAME
ORDER BY
connection_count DESC;
-- 查看PDB资源使用情况
SELECT
P.PDB_NAME,
S.CON_ID,
COUNT(S.SID) AS sessions,
SUM(S.CPU_TIME)/100 AS total_cpu_seconds,
SUM(S.BLOCK_GETS + S.CONSISTENT_GETS) AS total_logical_reads
FROM
CDB_PDBS P
JOIN
V$SESSION S ON P.CON_ID = S.CON_ID
WHERE
S.TYPE != 'BACKGROUND'
GROUP BY
P.PDB_NAME, S.CON_ID
ORDER BY
total_cpu_seconds DESC;Oracle 19c与21c连接管理差异
| 特性 | Oracle 19c | Oracle 21c |
|---|---|---|
| DRCP增强 | 基础DRCP支持 | 增强的DRCP,支持自动伸缩和更细粒度监控 |
| 连接池监控 | 基础UCP监控 | 增强的UCP监控,提供实时连接池状态和性能指标 |
| 临时会话支持 | 不支持 | 支持临时会话,适合短期连接场景 |
| 连接加密 | TLS 1.2 | 支持TLS 1.3,提供更强的加密保护 |
| 多租户连接 | PDB级连接限制 | 增强的PDB连接管理,支持每个PDB独立的连接池 |
| 连接超时 | 基础超时支持 | 增强的超时配置,支持更细粒度的超时控制 |
| 连接溯源 | 基础连接信息 | 增强的连接溯源,提供更详细的连接元数据 |
| 自动连接管理 | 无 | 支持自动调整连接数,根据负载动态伸缩 |
生产环境最佳实践
1. 连接数规划与配置
- 根据硬件资源规划:PROCESSES参数建议设置为CPU核心数的10-20倍
- 预留系统资源:为后台进程预留10-20%的PROCESSES额度
- 分用户组配置:为不同类型用户(管理员、应用用户、只读用户)设置不同的连接限制
- 启用资源限制:通过Profile限制每个用户的连接数和资源使用
2. 连接超时与回收
- 配置合理的超时时间:
- 应用用户:IDLE_TIME = 60分钟,CONNECT_TIME = 24小时
- 管理员用户:IDLE_TIME = 30分钟,CONNECT_TIME = 12小时
- 启用SQL*Net检测:SQLNET.EXPIRE_TIME = 15分钟
- 定期清理空闲连接:使用脚本或工具定期清理长时间空闲的连接
- 监控连接超时事件:通过审计或日志监控连接超时情况
3. 连接来源控制
- 限制连接IP范围:只允许应用服务器、管理终端等必要IP连接
- 结合防火墙使用:同时使用SQL*Net节点检查和操作系统防火墙
- 定期审查允许列表:每季度审查一次允许连接的IP列表
- 记录连接来源:启用审计记录所有连接的来源信息
4. 连接池优化
- 选择合适的连接池类型:根据应用特点选择UCP、HikariCP或DRCP
- 配置合理的池大小:
- 初始池大小 = 平均并发连接数
- 最大池大小 = 峰值并发连接数
- 最小池大小 = 初始池大小的50%
- 启用连接验证:设置validateConnectionOnBorrow = true
- 配置合理的超时参数:连接获取超时、空闲超时、废弃超时
5. 监控与告警
- 监控连接数趋势:通过AWR或第三方工具监控连接数变化趋势
- 设置连接数告警:当连接数超过阈值(如PROCESSES的80%)时发送告警
- 监控异常连接:监控连接数突增、长时间运行的会话、资源消耗异常的会话
- 审计连接事件:启用统一审计记录连接建立、断开、授权等事件
常见问题(FAQ)
Q:如何快速查看数据库当前连接数?
A:可以使用以下SQL查询:
sql
SELECT COUNT(*) AS total_connections,
SUM(CASE WHEN STATUS = 'ACTIVE' THEN 1 ELSE 0 END) AS active_connections
FROM V$SESSION;Q:如何处理数据库连接数满的情况?
A:处理步骤:
- 查看当前连接状态,识别异常连接
- 终止空闲时间过长的连接
- 检查是否有连接泄漏(应用未正确关闭连接)
- 考虑临时增加PROCESSES参数
- 长期解决方案:优化应用连接池配置,增加数据库硬件资源
Q:如何限制特定IP的连接数?
A:可以通过以下方法:
- 使用SQL*Net的TCP.INVITED_NODES限制允许连接的IP
- 结合防火墙规则限制IP访问
- 使用数据库触发器在连接时检查IP并限制连接数
Q:DRCP和传统连接池有什么区别?
A:DRCP(Database Resident Connection Pool)是数据库端的连接池,而传统连接池是应用端的连接池。DRCP适合大量短连接场景,可以减少数据库进程数量,降低内存消耗,提高并发能力。
Q:如何监控连接池的使用情况?
A:对于UCP连接池,可以使用UCP监控API或Oracle Enterprise Manager;对于HikariCP,可以通过其内置的监控指标或集成Prometheus/Grafana;对于DRCP,可以查询V$CPOOL*视图。
Q:Oracle 21c的临时会话有什么用途?
A:临时会话是Oracle 21c的新特性,适合短期连接场景,会话结束后资源会被自动回收,无需手动清理,有助于提高资源利用率和减少管理开销。
Q:如何优化应用连接池配置?
A:优化建议:
- 根据应用负载调整池大小
- 设置合理的超时参数
- 启用连接验证
- 配置连接回收机制
- 监控连接池指标,如连接等待时间、连接使用率等
- 考虑使用DRCP处理大量短连接
Q:如何防止连接泄漏?
A:防止连接泄漏的方法:
- 确保应用程序正确关闭连接(使用try-with-resources或finally块)
- 配置连接池的废弃连接超时
- 监控连接池的连接使用时间
- 定期检查长时间运行的会话
- 使用连接池的连接泄漏检测功能
总结
连接控制是Oracle数据库管理的核心内容,合理的连接管理策略可以有效保障数据库的安全性、可用性和性能。DBA需要根据数据库的硬件资源、应用特点和业务需求,配置适当的连接数限制、超时参数、资源限制和连接池设置。
随着Oracle版本的演进,连接管理功能不断增强,特别是Oracle 21c引入的临时会话、增强的DRCP和多租户连接管理等特性,为DBA提供了更强大的连接管理能力。通过结合监控工具和自动化脚本,DBA可以实现连接的精细化管理,确保数据库资源的高效利用,防止资源耗尽和安全威胁。
定期审查连接配置、监控连接状态、优化连接池设置是DBA日常工作的重要组成部分,也是保障数据库稳定运行的关键措施。
