Skip to content

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_file

2. 监听日志配置参数

参数名称描述默认值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 reload

3.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 off

4. 监听日志格式

监听日志的格式如下:

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.log

1.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.sh

2.2 使用ELK Stack分析

使用ELK Stack(Elasticsearch + Logstash + Kibana)实现监听日志的集中管理和分析:

  1. 配置Filebeat:收集监听日志文件
  2. 配置Logstash:解析监听日志内容,提取关键字段(时间戳、事件类型、客户端信息、返回码等)
  3. 配置Elasticsearch:存储解析后的日志数据
  4. 配置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 on

1.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工具自动轮换监听日志:

  1. 创建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
  1. 测试logrotate配置:
bash
logrotate -d /etc/logrotate.d/oracle-listener
  1. 手动执行logrotate:
bash
logrotate /etc/logrotate.d/oracle-listener

2. 监听日志清理策略

制定合理的监听日志清理策略,平衡日志保留时间和磁盘空间使用:

清理策略描述适用场景
按大小清理当日志文件达到一定大小时进行清理磁盘空间有限的环境
按时间清理保留指定天数的日志,定期清理旧日志需要保留一定历史记录的环境
压缩存储对旧日志进行压缩存储,减少磁盘占用需要长期保留日志的环境
集中归档将旧日志归档到集中存储系统大规模数据库环境

19c与21c监听日志差异

特性19c21c
日志格式标准文本格式增强的文本格式,包含更多元数据
日志级别基本日志级别支持更细粒度的日志级别
日志轮换基本的日志轮换功能增强的日志轮换策略
安全特性基本的安全日志增强的安全审计功能,支持细粒度审计
性能良好优化的日志写入性能,减少I/O开销

差异处理策略

  1. 日志格式差异

    • 更新日志分析工具,支持21c增强的日志格式
    • 调整Logstash解析规则,提取新增的元数据字段
  2. 日志级别差异

    • 调整监听日志级别配置,适应21c的细粒度级别
    • 更新监控规则,匹配新的日志级别
  3. 性能优化

    • 利用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需要及时更新管理方法,适应新版本的变化。

通过遵循最佳实践,可以建立一个高效、可靠的监听日志管理体系,确保数据库的安全稳定运行。