Skip to content

Oracle 日志轮换与归档

概述

Oracle数据库生成多种日志文件,包括告警日志、监听日志、审计日志、跟踪日志等。这些日志文件会随着时间不断增长,如果不进行适当的管理,可能会占用大量磁盘空间,影响数据库性能,甚至导致磁盘空间不足的问题。

日志轮换与归档是日志管理的重要组成部分,通过定期轮换和归档日志文件,可以:

  • 控制日志文件大小,避免磁盘空间不足
  • 提高日志文件的可读性和可管理性
  • 便于日志分析和故障诊断
  • 满足合规要求,保留必要的日志记录
  • 优化数据库性能,减少I/O开销

日志类型与默认位置

1. 主要日志类型

日志类型描述默认位置19c/21c差异
告警日志(Alert Log)记录数据库关键事件和错误$DIAGNOSTIC_DEST/diag/rdbms/$DB_UNIQUE_NAME/$INSTANCE_NAME/trace/alert_$INSTANCE_NAME.log无明显差异
监听日志(Listener Log)记录监听器活动$ORACLE_HOME/network/log/listener.log无明显差异
审计日志(Audit Log)记录数据库安全事件$ORACLE_BASE/admin/$DB_UNIQUE_NAME/adump 或 UNIFIED_AUDIT_TRAIL21c默认使用统一审计
跟踪日志(Trace Log)记录数据库进程详细信息$DIAGNOSTIC_DEST/diag/rdbms/$DB_UNIQUE_NAME/$INSTANCE_NAME/trace/无明显差异
重做日志(Redo Log)记录数据库修改操作数据文件目录无明显差异
归档日志(Archive Log)重做日志的归档副本归档目录无明显差异

2. 查看日志位置

sql
-- 查询诊断目的地
SELECT name, value FROM V$PARAMETER WHERE name = 'diagnostic_dest';

-- 查询告警日志位置
SELECT value FROM V$DIAG_INFO WHERE name = 'Alert Log';

-- 查询审计文件目录
SELECT name, value FROM V$PARAMETER WHERE name = 'audit_file_dest';

-- 查询归档日志位置
SELECT DEST_NAME, DESTINATION FROM V$ARCHIVE_DEST WHERE STATUS = 'VALID';

日志轮换机制

1. 自动轮换

Oracle数据库对某些日志文件提供自动轮换机制:

  • 告警日志:Oracle 11g及以后版本,告警日志会自动轮换,当文件达到一定大小时,会创建新的日志文件,旧文件重命名为alert_$INSTANCE_NAME.log.$n

  • 跟踪日志:跟踪日志会自动轮换,每个进程的跟踪日志会在进程重启时创建新文件,旧文件保留

  • 归档日志:归档日志会自动生成,每个日志序列对应一个归档文件,文件名包含日志序列信息

2. 手动轮换

对于没有自动轮换机制或需要手动控制的日志文件,可以使用手动轮换的方式:

  • 监听日志:使用lsnrctl set log_status off/on命令轮换
  • 审计日志:手动重命名审计日志文件,或使用DBMS_AUDIT_MGMT包管理
  • 自定义日志:手动重命名或使用脚本轮换

3. 日志轮换策略

轮换策略描述适用场景
按大小轮换当日志文件达到指定大小时进行轮换告警日志、监听日志
按时间轮换按固定时间间隔进行轮换,如每天、每周审计日志、跟踪日志
按事件轮换当发生特定事件时进行轮换,如数据库重启告警日志、跟踪日志
混合策略结合大小和时间进行轮换所有日志类型

各种日志的轮换配置

1. 告警日志轮换

1.1 自动轮换配置

Oracle 11g及以后版本,告警日志自动轮换功能默认启用。可以通过以下参数调整自动轮换行为:

sql
-- 查看告警日志自动轮换配置
SELECT * FROM V$DIAG_INFO WHERE name LIKE '%Alert%';

-- 调整诊断目的地大小限制(如果需要)
ALTER SYSTEM SET diag_adr_enabled = TRUE SCOPE = SPFILE;
ALTER SYSTEM SET diag_max_size = 10G SCOPE = SPFILE;

1.2 手动轮换

bash
# 手动轮换告警日志
# 方法1:使用ADRCI工具
adrci
adrci> SHOW HOMES
adrci> SET HOME diag/rdbms/orcl/orcl
adrci> PURGE -age 720 -type alert

# 方法2:手动重命名
ALERT_LOG=$(sqlplus -S / as sysdba << EOF
SELECT value FROM V$DIAG_INFO WHERE name = 'Alert Log';
EOF
)
ALERT_LOG=$(echo $ALERT_LOG | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')

# 关闭数据库(可选)
sqlplus / as sysdba << EOF
SHUTDOWN IMMEDIATE;
EOF

# 重命名告警日志
mv $ALERT_LOG $ALERT_LOG.$(date +%Y%m%d%H%M%S)

# 启动数据库(如果之前关闭了)
sqlplus / as sysdba << EOF
STARTUP;
EOF

2. 监听日志轮换

2.1 自动轮换

监听日志默认不会自动轮换,需要手动配置或使用脚本进行轮换。

2.2 手动轮换

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

2.3 使用logrotate工具轮换

bash
# 创建logrotate配置文件
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配置
logrotate -d /etc/logrotate.d/oracle-listener

# 手动执行logrotate
logrotate /etc/logrotate.d/oracle-listener

3. 审计日志轮换

3.1 标准审计日志轮换

bash
# 手动轮换标准审计日志
# 重命名审计日志目录中的旧文件
find $ORACLE_BASE/admin/$DB_UNIQUE_NAME/adump -name "*.aud" -mtime +30 -exec mv {} {}.old \;

# 清理过期审计日志
find $ORACLE_BASE/admin/$DB_UNIQUE_NAME/adump -name "*.aud.old" -mtime +7 -delete

3.2 统一审计日志轮换

sql
-- 清理统一审计日志
EXEC DBMS_AUDIT_MGMT.SET_LAST_ARCHIVE_TIMESTAMP(
  AUDIT_TRAIL_TYPE => DBMS_AUDIT_MGMT.AUDIT_TRAIL_UNIFIED,
  LAST_ARCHIVE_TIME => SYSTIMESTAMP - 30
);

EXEC DBMS_AUDIT_MGMT.CLEAN_AUDIT_TRAIL(
  AUDIT_TRAIL_TYPE => DBMS_AUDIT_MGMT.AUDIT_TRAIL_UNIFIED,
  USE_LAST_ARCH_TIMESTAMP => TRUE
);

4. 跟踪日志轮换

4.1 自动轮换

跟踪日志会在进程重启时自动轮换,旧文件会保留。可以通过以下方式管理跟踪日志:

sql
-- 查看跟踪日志位置
SELECT value FROM V$DIAG_INFO WHERE name = 'Diag Trace';

-- 使用ADRCI工具管理跟踪日志
adrci
adrci> SHOW HOMES
adrci> SET HOME diag/rdbms/orcl/orcl
adrci> PURGE -age 24 -type trace
adrci> PURGE -age 168 -type cdump

4.2 手动清理

bash
# 手动清理跟踪日志
TRACE_DIR=$(sqlplus -S / as sysdba << EOF
SELECT value FROM V$DIAG_INFO WHERE name = 'Diag Trace';
EOF
)
TRACE_DIR=$(echo $TRACE_DIR | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')

# 清理24小时前的跟踪日志
find $TRACE_DIR -name "*.trc" -mtime +1 -delete
find $TRACE_DIR -name "*.trm" -mtime +1 -delete

5. 归档日志管理

5.1 归档日志配置

sql
-- 查看归档日志配置
SELECT LOG_MODE FROM V$DATABASE;
SELECT * FROM V$ARCHIVE_DEST WHERE STATUS = 'VALID';

-- 启用归档模式(如果未启用)
ALTER DATABASE ARCHIVELOG;

-- 配置归档日志位置
ALTER SYSTEM SET log_archive_dest_1 = 'LOCATION=/u01/app/oracle/archive' SCOPE = SPFILE;
ALTER SYSTEM SET log_archive_format = '%t_%s_%r.dbf' SCOPE = SPFILE;

5.2 归档日志清理

sql
-- 使用RMAN清理归档日志
RMAN target / << EOF
DELETE ARCHIVELOG ALL COMPLETED BEFORE 'SYSDATE-7';
EXIT;
EOF

-- 配置归档日志自动删除策略
ALTER SYSTEM SET log_archive_dest_1 = 'LOCATION=/u01/app/oracle/archive DELETE INPUT' SCOPE = SPFILE;

自动化日志轮换

1. 使用Shell脚本自动化

创建一个统一的日志轮换脚本,定期执行所有日志的轮换和清理:

bash
#!/bin/bash

# Oracle日志轮换与清理脚本

# 环境变量设置
export ORACLE_HOME=/u01/app/oracle/product/19.3.0/dbhome_1
export ORACLE_SID=orcl
export PATH=$ORACLE_HOME/bin:$PATH

# 获取数据库名称
db_unique_name=$(sqlplus -S / as sysdba << EOF
set heading off feedback off
SELECT DB_UNIQUE_NAME FROM V$DATABASE;
EOF
)
db_unique_name=$(echo $db_unique_name | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')

# 获取实例名称
instance_name=$(sqlplus -S / as sysdba << EOF
set heading off feedback off
SELECT INSTANCE_NAME FROM V$INSTANCE;
EOF
)
instance_name=$(echo $instance_name | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')

echo "=== Oracle日志轮换与清理脚本 ==="
echo "执行时间: $(date)"
echo "数据库: $db_unique_name"
echo "实例: $instance_name"
echo ""

# 1. 轮换监听日志
echo "1. 轮换监听日志"
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
echo "监听日志轮换完成"
echo ""

# 2. 清理审计日志
echo "2. 清理审计日志"
audit_dir=$ORACLE_BASE/admin/$db_unique_name/adump
find $audit_dir -name "*.aud" -mtime +30 -delete
echo "已清理30天前的审计日志"
echo ""

# 3. 清理跟踪日志
echo "3. 清理跟踪日志"
trace_dir=$(sqlplus -S / as sysdba << EOF
set heading off feedback off
SELECT value FROM V$DIAG_INFO WHERE name = 'Diag Trace';
EOF
)
trace_dir=$(echo $trace_dir | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
find $trace_dir -name "*.trc" -mtime +7 -delete
find $trace_dir -name "*.trm" -mtime +7 -delete
echo "已清理7天前的跟踪日志"
echo ""

# 4. 清理告警日志(可选,Oracle会自动轮换)
echo "4. 清理旧告警日志"
alert_dir=$(dirname $(sqlplus -S / as sysdba << EOF
set heading off feedback off
SELECT value FROM V$DIAG_INFO WHERE name = 'Alert Log';
EOF
))
alert_dir=$(echo $alert_dir | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
find $alert_dir -name "alert_${instance_name}.log.*" -mtime +30 -delete
echo "已清理30天前的旧告警日志"
echo ""

# 5. 清理归档日志
echo "5. 清理归档日志"
rman target / << EOF > /dev/null 2>&1
DELETE NOPROMPT ARCHIVELOG ALL COMPLETED BEFORE 'SYSDATE-7';
EXIT;
EOF
echo "已清理7天前的归档日志"
echo ""

echo "=== 日志轮换与清理完成 ==="

设置脚本执行权限并添加到crontab:

bash
chmod +x oracle_log_rotation.sh
# 每天凌晨2点执行日志轮换
echo "0 2 * * * $PWD/oracle_log_rotation.sh >> $PWD/oracle_log_rotation.log 2>&1" | crontab -

2. 使用Oracle Scheduler自动化

sql
-- 创建日志轮换作业
BEGIN
  DBMS_SCHEDULER.CREATE_JOB(
    job_name        => 'LOG_ROTATION_JOB',
    job_type        => 'EXECUTABLE',
    job_action      => '/u01/app/oracle/scripts/oracle_log_rotation.sh',
    start_date      => SYSTIMESTAMP,
    repeat_interval => 'FREQ=DAILY; BYHOUR=2; BYMINUTE=0; BYSECOND=0',
    enabled         => TRUE,
    comments        => 'Daily log rotation job'
  );
END;
/

-- 查看作业状态
SELECT job_name, enabled, state FROM DBA_SCHEDULER_JOBS WHERE job_name = 'LOG_ROTATION_JOB';

19c与21c日志轮换差异

特性19c21c
告警日志轮换自动轮换,默认启用增强的自动轮换,支持更多配置选项
监听日志轮换需手动配置支持更灵活的轮换策略
审计日志轮换标准审计需手动配置,统一审计支持自动清理统一审计默认启用,自动清理功能更完善
跟踪日志轮换自动轮换,旧文件保留优化的跟踪日志管理,支持更细粒度的清理策略
归档日志管理基本的归档管理功能增强的归档管理,支持更多自动化选项
日志管理工具ADRCI工具基本功能增强的ADRCI工具,支持更多命令和选项

差异处理策略

  1. 利用增强的自动轮换功能

    • 在21c中,充分利用增强的自动日志轮换功能,减少手动配置
    • 配置合理的自动轮换参数,适应21c的新特性
  2. 更新自动化脚本

    • 更新日志轮换脚本,支持21c的新日志格式和位置
    • 利用21c提供的新命令和工具,简化日志管理
  3. 优化清理策略

    • 根据21c的日志增长特点,调整清理策略
    • 利用21c优化的清理命令,提高清理效率
  4. 监控日志性能

    • 监控21c中日志轮换对数据库性能的影响
    • 根据监控结果,调整日志轮换配置

日志轮换最佳实践

1. 制定合理的轮换策略

  • 根据日志类型制定策略:不同类型的日志采用不同的轮换策略
  • 考虑磁盘空间:根据磁盘空间大小,设置合理的日志保留时间和大小限制
  • 考虑合规要求:根据行业监管要求,保留必要的日志记录
  • 考虑性能影响:避免在高峰期执行日志轮换,减少对数据库性能的影响

2. 自动化管理

  • 使用自动化工具:利用Shell脚本、logrotate、Oracle Scheduler等工具实现自动化日志轮换
  • 定期执行:根据日志增长速度,设置合理的轮换频率
  • 监控执行结果:监控日志轮换作业的执行情况,确保轮换成功
  • 记录执行日志:记录日志轮换的执行日志,便于问题诊断

3. 优化存储管理

  • 使用高性能存储:将日志存放在高性能存储上,减少I/O瓶颈
  • 分离存储:将不同类型的日志存放在不同的存储设备上,提高管理效率
  • 压缩存储:对旧日志进行压缩存储,减少磁盘占用
  • 分层存储:将近期日志存放在高性能存储上,将旧日志迁移到低成本存储上

4. 安全管理

  • 限制日志访问权限:设置合适的日志文件权限,只允许授权用户访问
  • 加密存储:对包含敏感信息的日志进行加密存储
  • 防止日志篡改:使用文件完整性监控工具,防止日志被篡改
  • 审计日志访问:记录日志文件的访问情况,便于安全审计

5. 监控与告警

  • 监控日志大小:实时监控日志文件大小,及时发现异常增长
  • 监控磁盘空间:监控日志所在磁盘的空间使用情况,避免磁盘空间不足
  • 配置告警机制:当日志文件大小或磁盘空间达到阈值时,发送告警通知
  • 定期检查:定期检查日志轮换作业的执行情况,确保日志管理正常

常见问题(FAQ)

1. 日志轮换会影响数据库性能吗?

问题:执行日志轮换操作时,会影响数据库性能吗?

解决方案

  • 日志轮换操作通常是轻量级的,对数据库性能影响较小
  • 建议在数据库低峰期执行日志轮换,减少对业务的影响
  • 使用自动化工具执行日志轮换,避免手动操作的不确定性
  • 优化日志存储,使用高性能存储减少I/O影响

2. 如何确定合适的日志保留时间?

问题:如何确定不同类型日志的合适保留时间?

解决方案

  • 根据行业监管要求,确定合规性保留时间
  • 根据业务需求,确定故障诊断所需的日志保留时间
  • 根据磁盘空间大小,确定实际可保留的日志时间
  • 采用分层保留策略,近期日志保留时间长,旧日志保留时间短

3. 日志文件过大怎么办?

问题:日志文件增长过快,很快达到GB级别,怎么办?

解决方案

  • 检查日志内容,确定日志增长过快的原因
  • 调整日志级别,减少不必要的日志记录
  • 增加日志轮换频率,缩短日志保留时间
  • 优化日志存储,使用更快的存储设备
  • 考虑使用日志压缩,减少磁盘占用

4. 如何监控日志轮换作业的执行情况?

问题:如何确保日志轮换作业正常执行,及时发现执行失败的情况?

解决方案

  • 配置作业执行日志,记录作业的执行情况
  • 使用Oracle Scheduler的通知功能,作业失败时发送通知
  • 监控作业的执行状态,定期检查作业日志
  • 配置外部监控工具,监控作业的执行结果

5. 如何处理归档日志过多的问题?

问题:归档日志生成过快,占用大量磁盘空间,怎么办?

解决方案

  • 检查归档日志生成频率,确定是否存在异常
  • 优化数据库事务,减少重做日志生成
  • 增加归档日志清理频率,缩短归档日志保留时间
  • 配置归档日志自动删除策略
  • 考虑使用压缩归档日志,减少磁盘占用
  • 增加归档存储容量,或使用分层存储

6. 日志轮换后,如何确保日志的连续性?

问题:执行日志轮换后,如何确保日志记录的连续性,避免日志丢失?

解决方案

  • 使用原子操作进行日志轮换,避免日志丢失
  • 确保日志轮换过程中,数据库不会写入旧日志文件
  • 验证新日志文件是否正常生成,包含轮换后的日志记录
  • 保留旧日志文件一段时间,确保数据完整
  • 定期检查日志的连续性,确保没有日志丢失

总结

Oracle日志轮换与归档是数据库运维的重要组成部分,通过合理的日志管理,可以控制日志文件大小,避免磁盘空间不足,提高日志的可读性和可管理性,便于故障诊断和合规审计。

在实际运维中,应该:

  • 了解不同类型日志的特点和默认位置
  • 制定合理的日志轮换策略,根据日志类型和业务需求调整
  • 利用自动化工具实现日志轮换,减少手动操作
  • 兼顾19c和21c的版本差异,调整日志管理策略
  • 遵循最佳实践,优化日志存储和安全管理
  • 监控日志轮换作业的执行情况,确保日志管理正常

通过建立完善的日志轮换与归档机制,可以有效管理Oracle数据库的日志文件,确保数据库的安全稳定运行,满足合规要求。