外观
Oracle 监听日志管理
概述
Oracle监听器(Listener)是数据库的重要组件,负责接收和处理客户端的连接请求。监听日志记录了监听器的活动情况,包括连接请求、连接建立和断开等事件。通过管理和分析监听日志,可以监控数据库的连接情况,进行故障诊断和安全审计。
监听日志管理的主要内容包括:
- 监听日志配置
- 监听日志分析
- 监听日志轮换和清理
- 监听日志安全管理
监听日志配置
1. 监听日志位置
监听日志的默认位置由监听器配置文件listener.ora中的LOG_DIRECTORY_LISTENER参数决定,默认存放在以下路径:
$ORACLE_HOME/network/log/listener.log可以通过以下命令查看监听器配置:
bash
# 查看监听器状态,包含日志位置信息
lsnrctl status
# 查看监听器详细配置
lsnrctl show log_directory
lsnrctl show log_file2. 监听日志配置参数
| 参数名称 | 描述 | 默认值 | 19c/21c差异 |
|---|---|---|---|
| LOG_DIRECTORY_LISTENER | 监听日志存放目录 | $ORACLE_HOME/network/log | 无明显差异 |
| LOG_FILE_LISTENER | 监听日志文件名 | listener.log | 无明显差异 |
| LOGGING_LISTENER | 日志记录级别(ON/OFF) | ON | 无明显差异 |
| LOG_STATUS | 日志状态(ENABLE/DISABLE) | ENABLE | 无明显差异 |
| TRACE_DIRECTORY_LISTENER | 跟踪日志存放目录 | $ORACLE_HOME/network/trace | 无明显差异 |
| TRACE_FILE_LISTENER | 跟踪日志文件名 | listener.trc | 无明显差异 |
| TRACE_LEVEL_LISTENER | 跟踪级别 | OFF | 无明显差异 |
3. 修改监听日志配置
3.1 通过listener.ora配置文件修改
编辑监听器配置文件$ORACLE_HOME/network/admin/listener.ora:
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
)
)
# 监听日志配置
LOGGING_LISTENER = ON
LOG_DIRECTORY_LISTENER = /u01/app/oracle/diag/tnslsnr/oracle-server/listener/log
LOG_FILE_LISTENER = listener.log
LOG_STATUS = ENABLE
# 跟踪日志配置
TRACE_LEVEL_LISTENER = OFF
TRACE_DIRECTORY_LISTENER = /u01/app/oracle/diag/tnslsnr/oracle-server/listener/trace
TRACE_FILE_LISTENER = listener.trc修改配置后,需要重启监听器使配置生效:
bash
lsnrctl reload3.2 通过lsnrctl命令动态修改
可以通过lsnrctl命令动态修改监听日志配置,无需重启监听器:
bash
# 启用/禁用日志记录
lsnrctl set log_status enable
lsnrctl set log_status disable
# 修改日志文件名
lsnrctl set log_file listener_new.log
# 修改日志目录
lsnrctl set log_directory /u01/app/oracle/logs
# 设置日志级别
lsnrctl set logging on
lsnrctl set logging off4. 监听日志格式
监听日志的格式如下:
20-JUN-2023 10:00:00 * (CONNECT_DATA=(SID=orcl)(CID=(PROGRAM=sqlplus)(HOST=client-host)(USER=oracle))) * (ADDRESS=(PROTOCOL=tcp)(HOST=192.168.1.100)(PORT=12345)) * establish * orcl * 0
20-JUN-2023 10:05:00 * service_update * orcl * 0
20-JUN-2023 10:10:00 * (CONNECT_DATA=(SID=orcl)(CID=(PROGRAM=JDBC Thin Client)(HOST=client-host)(USER=appuser))) * (ADDRESS=(PROTOCOL=tcp)(HOST=192.168.1.101)(PORT=23456)) * establish * orcl * 0
20-JUN-2023 10:15:00 * (ADDRESS=(PROTOCOL=tcp)(HOST=192.168.1.102)(PORT=34567)) * establish * * 12514日志条目包含以下信息:
- 时间戳
- 事件类型(CONNECT_DATA、service_update、establish等)
- 客户端信息(程序名、主机名、用户名)
- 客户端地址(IP地址和端口)
- 数据库服务名
- 返回码(0表示成功,其他表示失败)
监听日志分析
1. 手动分析
1.1 使用文本工具查看
bash
# 使用tail命令实时查看监听日志
tail -f $ORACLE_HOME/network/log/listener.log
# 使用grep命令搜索特定内容
grep "establish" $ORACLE_HOME/network/log/listener.log
grep "12514" $ORACLE_HOME/network/log/listener.log
grep "JDBC" $ORACLE_HOME/network/log/listener.log
# 统计连接请求数量
grep -c "establish" $ORACLE_HOME/network/log/listener.log
# 统计失败连接
grep -v "establish.*0" $ORACLE_HOME/network/log/listener.log1.2 常见监听日志事件
| 事件类型 | 描述 | 示例 |
|---|---|---|
| establish | 连接建立事件 | * establish * orcl * 0 |
| service_register | 服务注册事件 | * service_register * orcl * 0 |
| service_update | 服务更新事件 | * service_update * orcl * 0 |
| connect_data | 连接数据信息 | * (CONNECT_DATA=(SID=orcl)(CID=(PROGRAM=sqlplus)(HOST=client-host)(USER=oracle))) |
| address | 客户端地址信息 | * (ADDRESS=(PROTOCOL=tcp)(HOST=192.168.1.100)(PORT=12345)) |
2. 自动化分析
2.1 使用Shell脚本分析
创建一个自动分析监听日志的Shell脚本:
bash
#!/bin/bash
# Oracle监听日志分析脚本
# 环境变量设置
export ORACLE_HOME=/u01/app/oracle/product/19.3.0/dbhome_1
export PATH=$ORACLE_HOME/bin:$PATH
# 获取监听日志位置
LISTENER_LOG=$(lsnrctl status | grep -i "Listener Log File" | awk -F: '{print $2}' | sed 's/^[[:space:]]*//')
if [ -z "$LISTENER_LOG" ]; then
LISTENER_LOG="$ORACLE_HOME/network/log/listener.log"
fi
echo "=== Oracle监听日志分析报告 ==="
echo "分析时间: $(date)"
echo "监听日志: $LISTENER_LOG"
echo ""
# 统计总连接数
total_connections=$(grep -c "establish" $LISTENER_LOG)
echo "=== 连接统计 ==="
echo "总连接请求数: $total_connections"
# 统计成功连接数
success_connections=$(grep -c "establish.*0" $LISTENER_LOG)
echo "成功连接数: $success_connections"
# 统计失败连接数
failed_connections=$((total_connections - success_connections))
echo "失败连接数: $failed_connections"
# 统计失败连接码
echo ""
echo "=== 失败连接码统计 ==="
grep -o "establish.*[1-9][0-9]*$" $LISTENER_LOG | awk '{print $NF}' | sort | uniq -c | sort -nr
# 统计客户端程序分布
echo ""
echo "=== 客户端程序分布 ==="
grep -o "PROGRAM=[^)]*" $LISTENER_LOG | awk -F= '{print $2}' | sort | uniq -c | sort -nr | head -10
# 统计客户端IP分布
echo ""
echo "=== 客户端IP分布 ==="
grep -o "HOST=[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}" $LISTENER_LOG | awk -F= '{print $2}' | sort | uniq -c | sort -nr | head -10
# 统计最近的10个失败连接
echo ""
echo "=== 最近10个失败连接 ==="
grep -v "establish.*0" $LISTENER_LOG | tail -10设置脚本执行权限并运行:
bash
chmod +x listener_log_analyzer.sh
./listener_log_analyzer.sh2.2 使用ELK Stack分析
使用ELK Stack(Elasticsearch + Logstash + Kibana)实现监听日志的集中管理和分析:
- 配置Filebeat:收集监听日志文件
- 配置Logstash:解析监听日志内容,提取关键字段(时间戳、事件类型、客户端信息、返回码等)
- 配置Elasticsearch:存储解析后的日志数据
- 配置Kibana:创建可视化仪表盘,展示监听日志统计信息(连接趋势、客户端分布、失败连接等)
3. 监听日志安全审计
监听日志可以用于安全审计,监控数据库的访问情况:
- 识别异常连接:检测来自未知IP或异常时间的连接请求
- 监控特权用户访问:跟踪特权用户的连接情况
- 检测暴力破解:识别多次失败的连接尝试
- 审计应用程序访问:监控应用程序的数据库访问模式
监听日志轮换和清理
1. 监听日志轮换
监听日志会随着时间不断增长,需要定期进行轮换,避免占用过多磁盘空间。监听日志轮换的主要方法包括:
1.1 使用lsnrctl命令手动轮换
bash
# 关闭当前监听日志
lsnrctl set log_status off
# 重命名当前监听日志
mv $ORACLE_HOME/network/log/listener.log $ORACLE_HOME/network/log/listener.log.$(date +%Y%m%d)
# 重新打开监听日志
lsnrctl set log_status on1.2 使用Shell脚本自动轮换
创建一个自动轮换监听日志的Shell脚本:
bash
#!/bin/bash
# Oracle监听日志轮换脚本
# 环境变量设置
export ORACLE_HOME=/u01/app/oracle/product/19.3.0/dbhome_1
export PATH=$ORACLE_HOME/bin:$PATH
# 日志目录和文件名
LOG_DIR="$ORACLE_HOME/network/log"
LOG_FILE="listener.log"
DATE_SUFFIX=$(date +%Y%m%d%H%M%S)
# 检查日志文件是否存在
if [ ! -f "$LOG_DIR/$LOG_FILE" ]; then
echo "监听日志文件不存在: $LOG_DIR/$LOG_FILE"
exit 1
fi
# 检查日志大小(单位:MB)
LOG_SIZE=$(du -m "$LOG_DIR/$LOG_FILE" | awk '{print $1}')
MAX_SIZE=100 # 最大日志大小,单位:MB
# 如果日志大小超过阈值,进行轮换
if [ $LOG_SIZE -gt $MAX_SIZE ]; then
echo "开始轮换监听日志,当前大小: ${LOG_SIZE}MB"
# 关闭当前日志
lsnrctl set log_status off
# 重命名日志文件
mv "$LOG_DIR/$LOG_FILE" "$LOG_DIR/${LOG_FILE}.${DATE_SUFFIX}"
# 重新打开日志
lsnrctl set log_status on
echo "监听日志轮换完成,新日志文件: ${LOG_FILE}.${DATE_SUFFIX}"
# 清理7天前的日志文件
find "$LOG_DIR" -name "${LOG_FILE}.*" -mtime +7 -delete
echo "已清理7天前的旧日志文件"
else
echo "监听日志大小正常: ${LOG_SIZE}MB,无需轮换"
fi设置脚本执行权限并添加到crontab:
bash
chmod +x listener_log_rotate.sh
# 每小时执行一次日志轮换
echo "0 * * * * $PWD/listener_log_rotate.sh >> $PWD/listener_log_rotate.log 2>&1" | crontab -1.3 使用logrotate工具轮换
配置logrotate工具自动轮换监听日志:
- 创建logrotate配置文件:
bash
cat > /etc/logrotate.d/oracle-listener << EOF
$ORACLE_HOME/network/log/listener.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
create 640 oracle oinstall
postrotate
$ORACLE_HOME/bin/lsnrctl set log_status off > /dev/null 2>&1
$ORACLE_HOME/bin/lsnrctl set log_status on > /dev/null 2>&1
endscript
}
EOF- 测试logrotate配置:
bash
logrotate -d /etc/logrotate.d/oracle-listener- 手动执行logrotate:
bash
logrotate /etc/logrotate.d/oracle-listener2. 监听日志清理策略
制定合理的监听日志清理策略,平衡日志保留时间和磁盘空间使用:
| 清理策略 | 描述 | 适用场景 |
|---|---|---|
| 按大小清理 | 当日志文件达到一定大小时进行清理 | 磁盘空间有限的环境 |
| 按时间清理 | 保留指定天数的日志,定期清理旧日志 | 需要保留一定历史记录的环境 |
| 压缩存储 | 对旧日志进行压缩存储,减少磁盘占用 | 需要长期保留日志的环境 |
| 集中归档 | 将旧日志归档到集中存储系统 | 大规模数据库环境 |
19c与21c监听日志差异
| 特性 | 19c | 21c |
|---|---|---|
| 日志格式 | 标准文本格式 | 增强的文本格式,包含更多元数据 |
| 日志级别 | 基本日志级别 | 支持更细粒度的日志级别 |
| 日志轮换 | 基本的日志轮换功能 | 增强的日志轮换策略 |
| 安全特性 | 基本的安全日志 | 增强的安全审计功能,支持细粒度审计 |
| 性能 | 良好 | 优化的日志写入性能,减少I/O开销 |
差异处理策略
日志格式差异:
- 更新日志分析工具,支持21c增强的日志格式
- 调整Logstash解析规则,提取新增的元数据字段
日志级别差异:
- 调整监听日志级别配置,适应21c的细粒度级别
- 更新监控规则,匹配新的日志级别
性能优化:
- 利用21c优化的日志写入性能,适当调整日志级别
- 考虑使用更高的日志级别,获取更详细的监控信息
监听日志最佳实践
1. 日志配置最佳实践
- 合理设置日志目录:将监听日志存放在独立的目录,便于管理和备份
- 启用适当的日志级别:根据需求设置日志级别,平衡日志详细程度和性能开销
- 配置日志文件名格式:使用包含时间戳的日志文件名,便于识别和管理
- 定期备份配置文件:备份listener.ora文件,避免配置丢失
2. 日志分析最佳实践
- 实时监控:实时监控监听日志,及时发现异常情况
- 定期分析:定期分析监听日志,识别潜在问题和安全风险
- 建立基线:建立正常连接模式的基线,便于识别异常变化
- 关联分析:结合告警日志和审计日志进行关联分析,获取更全面的信息
3. 日志轮换和清理最佳实践
- 制定合理的轮换策略:根据日志增长速度和磁盘空间,制定合理的日志轮换策略
- 自动轮换:使用自动化工具进行日志轮换,减少手动操作
- 合理设置保留时间:根据合规要求和业务需求,设置合理的日志保留时间
- 压缩存储:对旧日志进行压缩存储,减少磁盘占用
- 定期清理:定期清理过期日志,避免磁盘空间不足
4. 安全管理最佳实践
- 限制日志访问权限:设置合适的日志文件权限,只允许授权用户访问
- 加密存储:对包含敏感信息的日志进行加密存储
- 审计日志访问:记录日志文件的访问情况,便于安全审计
- 防止日志篡改:使用文件完整性监控工具,防止日志被篡改
5. 性能优化最佳实践
- 优化日志写入性能:将日志存放在高性能存储上,减少I/O瓶颈
- 避免过度日志记录:根据需求设置适当的日志级别,避免过多日志影响性能
- 使用异步日志写入:在21c中,考虑使用异步日志写入功能,减少对监听器性能的影响
- 定期监控日志性能:监控日志写入对监听器性能的影响,及时调整配置
常见问题(FAQ)
1. 监听日志增长过快怎么办?
问题:监听日志增长过快,占用大量磁盘空间怎么办?
解决方案:
- 检查是否存在大量连接请求,特别是失败的连接尝试
- 调整日志级别,减少不必要的日志记录
- 配置更频繁的日志轮换策略
- 增加日志清理频率,缩短日志保留时间
- 考虑使用压缩存储,减少磁盘占用
2. 如何查看监听日志的详细信息?
问题:如何查看监听日志的详细信息,包括连接时间、客户端信息等?
解决方案:
- 使用文本工具直接查看监听日志文件
- 使用lsnrctl status命令查看监听器状态,包含基本日志信息
- 使用lsnrctl show命令查看详细的日志配置
- 使用日志分析脚本,提取和统计日志信息
3. 监听日志中出现大量失败连接怎么办?
问题:监听日志中出现大量失败的连接尝试,如何处理?
解决方案:
- 分析失败连接的返回码,确定失败原因
- 检查客户端配置,确保连接字符串正确
- 检查监听器配置,确保服务正确注册
- 检查网络连接,确保客户端可以访问数据库服务器
- 检查防火墙设置,确保1521端口开放
- 检查是否存在恶意攻击,如暴力破解尝试
4. 如何禁用监听日志?
问题:在某些情况下,需要禁用监听日志,如何操作?
解决方案:
- 使用lsnrctl命令禁用监听日志:
lsnrctl set log_status off - 在listener.ora文件中设置
LOGGING_LISTENER = OFF - 注意:禁用监听日志会影响故障诊断和安全审计,谨慎使用
5. 如何将监听日志和告警日志集成管理?
问题:如何将监听日志和告警日志集成到统一的管理平台?
解决方案:
- 使用ELK Stack集中管理所有日志文件
- 配置Filebeat同时收集监听日志和告警日志
- 在Kibana中创建统一的仪表盘,展示所有日志信息
- 配置关联分析规则,关联不同日志文件的相关事件
6. 监听日志轮换时监听器会中断吗?
问题:执行监听日志轮换时,监听器是否会中断服务?
解决方案:
- 使用lsnrctl set log_status命令轮换日志时,监听器不会中断服务
- 日志轮换过程中,监听器会短暂停止写入日志,但不会影响现有连接
- 建议在低峰期执行日志轮换,减少对业务的影响
总结
Oracle监听日志管理是数据库运维的重要组成部分,通过合理配置、分析和管理监听日志,可以监控数据库的连接情况,进行故障诊断和安全审计。
在实际运维中,应该建立完善的监听日志管理机制,包括:
- 合理配置监听日志参数
- 定期分析监听日志,识别异常情况
- 制定合理的日志轮换和清理策略
- 加强监听日志的安全管理
- 优化监听日志的性能
随着Oracle数据库版本的演进,监听日志的功能和性能不断优化,DBA需要及时更新管理方法,适应新版本的变化。
通过遵循最佳实践,可以建立一个高效、可靠的监听日志管理体系,确保数据库的安全稳定运行。
