简介:这是一份面向Oracle数据库运维与DBA人员的案例型PPT课件,聚焦RAC集群环境下的故障分析与处置流程。内容以真实错误日志为主线,逐一剖析IPC Send timeout、LMS/LMD锁管理进程通信异常、实例成员资格不一致、脑裂驱逐以及ORA-29740报错等典型现象,解释IPC超时通常源于网络延迟、丢包或进程阻塞,LMS/LMD分别负责处理与维护锁信息,脑裂机制会驱逐异常实例以保障数据一致性;同时也结合netstat确认网络丢包、资源瓶颈与Oracle已知BUG等诱因,并给出从日志分析、网络检查、资源监控到补丁排查的系统排错思路,对定位类似生产事故很有参考价值。压缩包共有1个文件,为pptx演示文稿,约1.83MB,适合具有一定集群基础、希望提升Oracle RAC故障排查能力的运维人员学习参考。该资源已有133人学习下载,可直接用于团队技术分享或个人复盘。
1. Oracle 数据库运维案例:从翻车现场到标准动作
凌晨一点,开发打电话说订单库查询卡死,你冲到工位查v$session,看到一片buffer busy waits。翻出同事留下的 Oracle数据库运维案例介绍.pptx,里面有十年前的同类故障记录,却只有截图和命令,没写先查什么、参数为什么这么改。这类运维案例的价值从来不在屏幕截图,而在把一次救火过程拆成可复用的标准动作:报错是什么、先查哪张视图、参数改多少、观察多久。这篇笔记就按这个思路,把 Oracle 数据库运维案例背后最常见的打法讲清楚:先分可用性、性能、安全三层,再落到 DG 同步搭建、AWR 定位、故障排查和巡检脚本。适合刚接手 Oracle 库的运维工程师,也适合准备从 MySQL 转过来的 DBA。
2. Oracle 数据库运维案例:先分清可用性、性能、安全三层
2.1 可用性层:同步、备份、恢复是一条保命线
我翻过的运维案例文件夹里,占比最大的永远是数据库起不来、主备不同步、数据文件报错、磁盘打满。这一层只回答一个问题:库真垮了,多久能站起来,数据丢多少。Oracle 在这一层有三个标配:归档模式、DG 数据同步、RMAN 备份。归档是一切的基础,不开归档就没有完整的恢复能力;DG 是数据库层最常用的同步软件方案,既能做主备容灾,也能把只读查询分到备库;RMAN 则是备份和恢复的主通道。很多案例把这三点分开记,实际运维里它们是一条线:归档产生连续性,DG 靠归档和日志同步,RMAN 靠归档做时间点恢复。
看这类案例不要只抄命令,要带着顺序看。我一般会先确认这个库是单实例还是 RAC,有没有备库,备份策略是什么。单实例和 RAC 的排查路径完全不同,DG 环境里出问题还要先分清主备角色。案例里只要出现alter database archivelog,就要追问一句:这条命令执行前,库是 mount 还是 open 状态。很多新人抄了命令,却不知道要先shutdown immediate再startup mount,结果在 open 状态直接报 ORA-01126,这就是案例没有写清“边界条件”的典型后果。
一份能复用的案例文档,我要求至少记五要素:环境版本、初始症状、定位命令、变更命令、验证结果。环境版本包括操作系统、Oracle 版本、单实例还是 RAC、是否 DG;初始症状要写原话报错,而不是人肉翻译后的描述;定位命令要写“执行后看哪一列”;变更命令要写“改了之后是否需要重启”;验证结果要写“观察多久、看什么指标”。没有这五要素,只能算截图收藏夹,收藏了一百个,遇到问题还是从零开始。
2.2 性能层:AWR、等待事件和 SQL 定位
一年里真正让运维睡不着的,不是数据库挂掉,而是库没挂、业务天天被投诉。这类案例看起来玄学,实际路径非常固定:先抓 AWR 快照,看 Top 10 事件,再定位到 SQL 和执行计划,最后评估是加索引、改参数还是改应用。Oracle 性能文档里出现频率最高的词是“等待事件”,它回答的是“数据库当前在等什么资源”。等 CPU、等数据文件读、等日志写、等行锁,原因完全不同,处理手段也完全不同。
我见过不少案例把用户等待时间和 DB 时间混在一起讲,这是第一个坑。看 AWR 先看DB Time / Elapsed,比值大于 1 说明数据库确实忙,小于 1 说明周期里有大量空闲,问题可能不在数据库段。还有开发拿着 Dragonwell 和 Oracle JDK 的对比来问数据库是不是太慢,这种属于应用托管的 JDK 与数据库实例被混为一谈。我一般会先让时间说话:同一套 SQL 在 sqlplus 里跑得飞快,在应用里慢,问题大概率不在数据库,先查连接池和网络往返,再进 AWR。
性能案例里最容易写进 PPT 的其实是函数和存储过程。比如一个普通函数没加确定性,导致每行数据都重复执行一次;一个存储过程逐行 update,百万行数据跑半小时,回滚段还差点被撑爆。这类代码级问题不解决,调大 SGA 也只是花钱买时间。顺便说一句,PPT 里常有一页“oracle 中 dual 最多存多大”,这类单行问题记下来当知识点可以,但对生产影响很小,真正要盯的是等待事件和执行计划。dual 是单行单列表,21c 之后某些版本还能自定义列,但它从来不是性能瓶颈。
2.3 安全合规层:等保命令不是临时抱佛脚
第三层是安全和合规。每年等保测评前,DBA 都要花几天改数据库基线:密码策略、登录失败处理、审计策略、最小权限。Oracle 等保命令在网上流传很广,但真正要做的是先看清基线要求再改参数。默认的 profile 允许无限次失败登录,要求改成连续 5 次失败锁定;默认audit_trail可能是 NONE,要改成 DB 或 OS;默认远程访问限制不严,要配合tcp.validnode_checking做 IP 白名单。这些改完有的动态生效,有的要重启,必须逐条记录。
等保这块最容易翻车的不是命令本身,而是“改完没有验证”。比如alter profile default limit password_life_time 90之后,只对之后改密用户生效,存量用户还是原来的过期时间,要结合dba_users里的expiry_date一起检查。审计打开之前,还要想清楚磁盘够不够放AUD$表的数据,否则审计刚开三天,SYSTEM 表空间就被写满,数据库直接挂起。案例文档里如果只写了打开审计,没写清理策略,这类内容宁可先不上线。
| 层次 | 核心问题 | 典型案例 | 常用手段 |
|---|---|---|---|
| 可用性 | 库能不能撑住、数据丢不丢 | DG 断同步、归档满、dbf 损坏 | RMAN、DG、归档策略 |
| 性能 | 业务慢、会话堆积 | AWR Top 事件、分页慢、存储过程逐行 | AWR、执行计划、索引、SQL改写 |
| 安全 | 等保测评不通过、权限失控 | 口令策略、审计未开、远程访问过宽 | profile、audit、IP 限制 |
拿到一份运维案例,先判断它属于哪一层,再决定动作。这步 30 秒能完成,能省下后面两小时的弯路。现在很多问题的表象会跨层,比如归档目录写满导致业务报错,表面是空间问题,根因可能是备库断同步,那就同时在可用性层处理,而不是光删归档。
3. Oracle 19c 单实例搭 DG:最小同步环境这样落地
3.1 DG 的最小原理与四个前提
DG 是 Oracle 自带的数据同步工具,跟外部数据库同步软件比,最大的优势是深度集成、支持角色切换、不需要额外部署中间件。物理备库的原理一句话讲清:主库的日志传输服务把 redo 传到备库,备库的 MRP 进程把 redo 应用到自己的数据文件上。同步方式分为 SYNC 和 ASYNC,保护模式分为最大保护、最大可用、最大性能。单实例对单实例是最常见的起步组合,也是后面扩展 RAC 的基础,所以我建议新手都从 19c 单实例搭 DG 练手。
动手前先确认四个前提:主备都是 19c 同版本,操作系统架构一致;主备都能通过静态监听互连;主库已开归档;系统时间基本一致,最好配了 NTP。静态监听是关键,很多 DG 搭不通都是监听里没有 SID 列表,tnsping通但服务名解析不对。备库可以先用一套全新的空环境,不需要提前装数据库软件以外的任何东西,19c 的 active duplicate 会自己把数据文件复制过去。
3.2 主库开启归档并设置 DG 参数
下面这组操作在主库执行,注意每一条的意图。
-- 1. 重启到 mount 状态开启归档 shutdown immediate; startup mount; alter database archivelog; alter database force logging; alter database open; -- 2. 设置主库 DG 相关参数 alter system set db_unique_name='orcl' scope=spfile; alter system set log_archive_config='dg_config=(orcl,orclstd)' scope=spfile; alter system set log_archive_dest_1='location=/u01/app/oracle/arch VALID_FOR=(ALL_LOGFILES,ALL_ROLES) db_unique_name=orcl' scope=spfile; alter system set log_archive_dest_2='service=orclstd LGWR ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) db_unique_name=orclstd' scope=spfile; alter system set log_archive_dest_state_2=enable scope=spfile; alter system set log_archive_format='%t_%s_%r.arc' scope=spfile; -- 3. 让 spfile 参数生效 shutdown immediate; startup;第一组命令里,shutdown immediate是干净关闭事务,startup mount后才能修改归档模式。force logging很关键,它保证即使应用里写了 nologging,所有数据块操作也会记录日志,否则备库很可能在某次操作后与主库不一致。第二组命令里,db_unique_name决定了这个库在 DG 配置里的身份;log_archive_config用dg_config列了主备两个名字;log_archive_dest_2里LGWR ASYNC表示日志写进程直接传输、备库异步接收,主库提交不等待备库确认,这是保护模式和性能的平衡点;VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE)表示只有在线日志、只有主库角色时才写往这个目标。
3.3 备库参数与 Active Duplicate
备库端先启动到 nomount,再用 RMAN 的duplicate from active database在线复制。这是 19c 最常见的做法,不需要先做全备再传原文,备库直接从主库拉原件。
# 备库执行:启动到 nomount export ORACLE_SID=orclstd sqlplus / as sysdba <<EOF startup nomount; EOF # 主库终端执行:用 RMAN 复制 rman target sys/sys_password@orcl auxiliary sys/sys_password@orclstd RMAN> duplicate target database for standby from active database nofilenamecheck;no filenamecheck的前提是主备库目录结构完全一致。如果备库的数据文件路径和主库不同,就不能带这个参数,而是要在备库 pfile 里配db_file_name_convert和log_file_name_convert,指定路径映射关系。nofilenamecheck看似省事,但生产上主备目录不一致很常见,硬用会直接报 ORA-19611,所以这里要按实际目录决定。复制完成后,备库会自动生成控制文件和数据文件,但还需要手动把备库切到 managed recovery 状态。
alter database recover managed standby database using current logfile disconnect from session;using current logfile表示备库使用传输过来的在线日志做实例恢复,这是 19c 默认的推荐方式。disconnect from session让恢复进程在后台运行,不会因为 SQL*Plus 断开而停止。执行后可以用select process,status from v$managed_standby;看 MRP0 是否变成 APPLYING_LOG。
3.4 验证同步和角色切换
同步有没有跟上,不要看感觉,要看两个数:备库应用的日志序列号,以及它落后主库多少。
-- 主库强制切一次日志,产生新的 redo alter system switch logfile; -- 备库查询 select database_role, db_unique_name, open_mode from v$database; select sequence#, applied from v$archived_log where sequence# > (select max(sequence#)-5 from v$archived_log) order by sequence# desc; select * from v$dataguard_stats;v$archived_log里applied=YES表示这条日志已经在备库应用完成。v$dataguard_stats里主要看两个值:transport lag和apply lag,正常应该都是+00 00:00:00,带+号且数字变大就说明有延迟。生产上建议把备库的编译检查也纳入巡检,比如在备库执行select count(*) from 核心表,如果备库处于 mount 状态,这一步要先建立 snapshot standby 或打开只读模式。
日常切换我建议用 DG Broker,手工 switchover 命令容易在忘记清理db_unique_name时出问题。用 broker 的思路是先建配置,再启用,再验证,不要跳步。
-- 调用 dgmgrl dgmgrl sys/sys_password@orcl DGMGRL> create configuration 'cfg' as primary database is 'orcl' connect identifier is 'orcl'; DGMGRL> add database 'orclstd' as connect identifier is 'orclstd' maintained as physical; DGMGRL> enable configuration; DGMGRL> show configuration;connect identifier必须是监听里能解析的服务名,不是任意起的别名。enable configuration之后,broker 会接管日志传输和恢复的启动,手工在 SQL*Plus 里停恢复再启动,broker 反而会误判状态。
3.5 日常备份脚本:RMAN 与归档清理
DG 再稳,RMAN 也不能省,备库不代表能恢复到任意时间点,所以日常备份脚本是案例里的标准动作。
#!/bin/bash # 每日凌晨 1 点执行,归档保留 3 天 export ORACLE_HOME=/u01/app/oracle/product/19c/dbhome_1 export ORACLE_SID=orcl export PATH=$ORACLE_HOME/bin:$PATH rman target / <<EOF crosscheck archivelog all; delete noprompt archivelog until time 'sysdate - 3'; backup database format '/u01/backup/db_%U.bkp' plus archivelog; backup current controlfile format '/u01/backup/ctl_%U.bkp'; delete noprompt obsolete; EOFcrosscheck archivelog all是为了让 RMAN 的元数据和磁盘上真实文件对齐,否则以后delete obsolete可能删不掉已经消失的文件记录。until time 'sysdate - 3'是清理三天前的归档,注意这是截止时间,不是保留三天,写反会把当天的归档全删掉。plus archivelog保证备份期间切出来的归档也包含进去,备份集才是自洽的。delete obsolete按保留策略清理过期备份,默认保留策略是一份冗余,如果配了redundancy 2会多保留一份。
脚本跑完不等于恢复没问题,我习惯再加一步验证:
rman target / RMAN> restore database validate; RMAN> validate backupset;restore database validate会把整个备份集读一遍,真实验证有没有坏块、缺文件,但不落盘。所有案例里最常被省略的就是恢复验证,备份跑了三年,真到恢复才发现缺文件,这种事故我不止见过一次。
4. 从 AWR 报表到 SQL 调优:性能类案例的定位路径
4.1 生成 AWR 报表的准确姿势
性能案例的第一步永远是拿报告,不是拍脑袋改参数。先确认快照范围,再生成 HTML 报告。
-- 列出最近 7 天的快照 select snap_id, begin_interval_time, end_interval_time from dba_hist_snapshot where begin_interval_time > sysdate - 7 order by snap_id; -- 用指定快照区间生成 HTML 报告 select dbms_workload_repository.awr_report_html( l_dbid => (select dbid from v$database), l_inst_num => 1, l_bid => 1220, l_eid => 1230, l_rpt_options => 8) report_html from dual;l_bid和l_eid是开始和结束快照 ID,一般选业务高峰时间段,不要选跨了一整天的区段,否则 Top 事件会被平均掉。l_rpt_options => 8表示包含详细的 SQL 统计信息,关键是能直接看到 SQL 的执行次数、平均耗时、CPU 和物理读。如果现场没有图形界面,也可以把awr_report_html换成awr_report_text,文本报告在终端里更好翻。
拿到报告先看两块:顶部DB Time / Elapsed的比例,以及Top 10 Foreground Wait Events。比例明显大于 1 说明数据库确实在忙,小于或接近 1 说明当前区间数据库有空闲,慢的根源在别处。Top 事件列表可以看作“数据库自己告诉你它卡在哪”。这一步不要跳过,直接往下翻 SQL 列表经常会被一两条偶发 SQL 带偏。
4.2 三个高频等待事件看一眼就知道方向
AWR 里每天出现最多的是下面这三个,每个对应一套固定排查动作。
| 等待事件 | 常见原因 | 第一步动作 |
|---|---|---|
| db file sequential read | 单块读慢,多半是索引访问、表访问路径不合理 | 到 SQL 列表找物理读高的语句,看执行计划是否走索引,索引是否失效 |
| log file sync | 提交慢,redo 写入跟不上 | 查 redo log 大小和磁盘 fsync 延迟,必要时增大日志组、换高性能盘 |
| enq: TX - row lock contention | 行锁等待,应用事务没提交 | 查 v$locked_object、v$session 关联出阻塞会话,让业务确认事务是否已经挂起 |
db file sequential read最容易误判成磁盘坏道。它本质是一种 I/O 等待类型,单块读慢可能是因为 buffer cache 过小、表和索引被频繁热切换,也可能是批量任务把 I/O 带宽占满。所以看到它,先看平均等待时间,再关联 SQL,不要急着加内存。log file sync则和磁盘直接相关,redo log 文件所在的磁盘如果和归档目录混在一起,很容易出现写放大。实践里先看v$log里日志成员大小,太小就加组加大小,太大反而会延长切换周期,需要反复观察。
4.3 分页查询带来的慢 SQL
Oracle 分页是老生常谈,但案例里十有八九是深分页翻车。深分页的意思是用户要第 19990 到 20000 页的数据,页数越大越慢。低效写法是先把前 N 万行全部取出再丢弃。
-- 低效:先取 20 万行再丢 199990 行 select t.*, rownum rn from ( select * from orders order by created_time desc ) t where rownum <= 200000 and rn > 199990;这段 SQL 的执行为什么慢?内层排序要处理全表数据,外层 rownum 限制了 20 万行,实际返回却只有 10 行,数据库把绝大多数时间浪费在拿和丢上。改法是让数据库只处理那一页前后的数据,而不是覆盖整张表。
-- 高效:先定位上一页最后一条的位置,再往后取 10 条 select * from orders where created_time < ( select created_time from ( select created_time from orders order by created_time desc ) where rownum = 199990 ) order by created_time desc fetch first 10 rows only;子查询先找到上一页那行的 created_time,外层只用大于该值的 10 行。前提是 created_time 有索引,且值足够区分,否则要用组合排序条件。19c 里fetch first 10 rows only是标准写法,12c 之前的版本还是写rownum <= 10。深分页优化后,如果页数非常深,还可以用 keyset pagination 记录上一页最后一行 id,彻底避免扫大偏移量。案例文档里应该同时记录两种写法,并标注“第几页开始切换策略”。
4.4 存储过程里的逐行处理和函数坑
存储过程性能案例,最常见的是逐行 update。业务逻辑用游标循环处理百万级数据,每行 update 一次,SQL 引擎上下文切换和 undo 生成量都爆表。反例:
-- 反例:游标循环逐行更新 declare v_count pls_integer := 0; begin for rec in (select id, status from t_order where status = 0) loop update t_order set status = 1 where id = rec.id; v_count := v_count + 1; if mod(v_count, 1000) = 0 then commit; end if; end loop; commit; end; /这段代码在数据量小的时候没感觉,到几十万行就开始慢。每条 update 都是一次上下文切换,每 1000 行一次 commit 虽然避免了回滚段爆掉,但日志同步次数并没有少。改成集合操作:
-- 正例:一条 update 解决 update t_order set status = 1 where status = 0;如果业务要求逐条做校验,推荐先批量把数据载入临时表,再一次性 update 或 merge。案例里记录这种对比,比记录存储过程语法更值钱,因为语法翻手册就有,性能规律是从故障里摸出来的。
函数坑也常见。比如查询条件里把索引列套进函数,索引直接失效。
-- 反例:trunc 包住索引列,走不了索引 select * from epay_trans where trunc(create_time) = date'2024-06-01'; -- 正例:改成范围条件 select * from epay_trans where create_time >= date'2024-06-01' and create_time < date'2024-06-02';注意这里date'2024-06-02'是当天零点,和第二天零点相差一秒,上界使用小于号,刚好覆盖 6 月 1 日全天。如果业务上 create_time 带时分秒,写成<= date'2024-06-01 23:59:59'会漏掉最后一秒的数据,所以统一用半开区间最安全。案例文档里应该把这个写法作为标准模板固定下来。
5. 运维案例里的高频故障:五条避坑与排错记录
案例看多了会发现,故障其实就那几类。下面五条是我自己踩过、也看同事踩过的记录,每条按现象到解决展开。
5.1 dbf 文件损坏:别急着找第三方工具
现象:alert 日志报 ORA-01115 / ORA-01116,说文件块读错误或文件不可读,数据库可能还在运行,但查询相关表直接报错。有人拿 SQLite 的 dbx 工具去打开 dbf 文件,方向就错了,Oracle 数据文件不是随便用外部工具解析的。
原因:磁盘坏道、掉电时数据块未完全落盘、文件被误删。先确认是数据文件还是临时文件,临时文件损坏可以重建,数据文件损坏需要备份恢复。
解决:先查文件号定位,再决定恢复路径。
select file#, name, status from v$datafile; -- 如果 datafile 7 损坏 rman target / RMAN> restore datafile 7; RMAN> recover datafile 7;如果是临时文件损坏,直接删了重建,不需要备份:
alter tablespace temp add tempfile '/u01/app/oracle/oradata/temp02.dbf' size 2g; alter database tempfile '/u01/app/oracle/oradata/temp01.dbf' drop including datafiles;数据文件损坏最怕没有备份,所以第 3 章的日常备份脚本和恢复验证是这类事故的后悔药。这里多说一句,数据库层面确定是文件坏之后,先别急着恢复,把报警磁盘的坏道情况也记录一下,否则恢复完文件又坏一次。
5.2 包状态被丢弃,调用直接报 ORA-04068
现象:生产上调用存储过程报 ORA-04068,原有包不可用,查询dba_objects发现状态变成 INVALID。这也是热词“oracle 为什么会出现包状态被丢弃”对应的场景。
原因:依赖对象被 DDL 改动,或者升级脚本只改了表结构,没有重新编译依赖它的包。包状态不是真的被“丢弃”,而是依赖链失效。
解决:先查出所有失效对象,再按需编译。
select owner, object_name, object_type, status from dba_objects where status <> 'VALID' and owner = 'APP' and object_type in ('PACKAGE','PACKAGE BODY','PROCEDURE','FUNCTION','VIEW'); -- 对失效的包逐个编译 alter package app.pkg_order compile body;也可以写匿名块循环编译,但不要无脑对整个 schema 执行dbms_utility.compile_schema。这个命令会把所有对象重新编译,生产环境里可能引发大量锁和性能抖动。我一般只筛出失效对象,编译前看一眼依赖关系,特别是包体引用了别的 schema 的包时,要先编译被引用的那层。
5.3 12c 删除不干净:重装时处处碰壁
现象:用 dbca 删除实例后想重装,dbca 列表里还显示旧实例,安装到一半提示目录已存在或监听服务被占用。热词里的“12c 删除不干净 + oracle”指的就是这类残留。
原因:deinstall 只删了数据库软件注册信息,/u01/app/oracle下的 oradata、diag 目录还在,/etc/oratab里的记录没有清理,监听配置文件里服务项也残留。
解决:按顺序清理,先停库和监听,再删目录和配置文件。
lsnrctl stop sqlplus / as sysdba <<EOF shutdown abort; EOF rm -rf /u01/app/oracle/oradata/ORCL rm -rf /u01/app/oracle/diag rm -f /etc/oratab # 如果有 dbhome 里的 old install 残留,也要清理注意这是在确认不需要任何数据恢复的前提下执行。生产环境删除实例前,先把最后一个全备和归档复制到异地,再做清理。数据库的卸载,本质上跟删除生产数据一个等级,不能图省事跳过备份。
5.4 归档目录写满,业务新事务报错
现象:应用突然报 ORA-00257,数据库能查,但新事务提交不了。查v$recovery_area_usage或v$recovery_file_dest发现空间已满。这个案例在 DG 环境里尤其常见,因为日志传输暂停时归档会在主库堆积。
原因:归档清理策略没生效,或者备库断开导致主库日志无法删除。备库断开的信号是v$archive_dest里目标状态变成 ERROR,主库的归档会越积越多。
解决:先确认备库状态有没有追上,再决定删多少。
select dest_id, status, error from v$archive_dest; -- 备库如果正常,再清理过期归档 rman target / <<EOF crosscheck archivelog all; delete noprompt archivelog until time 'sysdate - 2'; EOF顺序很重要:先确认备库已经应用完要删的归档,再在主库清理。否则主库删了,备库再申请这段日志就永久缺档,只能重建备库。生产上我给备库单独留了快照备份,就是为了在断同步太久时能快速重搭。
5.5 等保命令:基线检查到底改在哪
现象:测评报告列出口令策略、失败锁定、审计未开启等不符合项。等保命令不是网上抄几条就完事,要理解改动的位置。
原因:默认 profile 允许无限次失败登录,audit_trail默认是 NONE,远程访问也没有限制。这些都是默认配置与测评要求的差距。
解决:先按测评要求列基线,再改 profile 和审计参数。
-- 密码策略与失败锁定 alter profile default limit failed_login_attempts 5 password_lock_time 1 password_life_time 90 password_reuse_time 365; -- 打开审计,DB 级别 alter system set audit_trail=db, extended scope=spfile; -- 12c 之后常用统一审计 alter system set unified_audit_sga_queue_size=1g scope=spfile;注意audit_trail改成 DB 后要重启库,而且AUD$表会长得很快。案例文档里要同步记录清理策略:定期对AUD$做分区归档,或者开启统一审计后配置定期导出。只开审计不建清理任务的案例,基本都会在三个月后以“SYSTEM 表空间爆满”收场。
6. 把案例沉淀成巡检手册与验证脚本
案例看了再多,落地要靠巡检。我现在每接手一个库,第一周就写一个能一分钟跑完的巡检脚本。脚本不追求面面俱到,先把五件事查清楚:实例状态、备份是否成功、归档目录余量、DG 延迟、表空间使用率。
#!/bin/bash # 每日巡检脚本,输出固定格式便于比较 export ORACLE_HOME=/u01/app/oracle/product/19c/dbhome_1 export ORACLE_SID=orcl export PATH=$ORACLE_HOME/bin:$PATH sqlplus -s "/ as sysdba" <<EOF set linesize 200 pagesize 100 select instance_name, status, database_role from v\$instance, v\$database; select name, round(percent_space_used, 1) used_pct from v\$recovery_area_usage; select tablespace_name, round(used_percent, 1) used_pct from dba_tablespace_usage_metrics where used_percent > 85; EOF rman target / <<EOF list backup summary; EOF这里v\$instance里的$在 bash 的 heredoc 里必须转义,否则会被 shell 当成变量吃掉。dba_tablespace_usage_metrics是 19c 里查表空间使用率最直接的方式,不再需要手写dba_data_files和dba_free_space的 join。输出里如果出现任何一行status不是 OPEN、used_pct大于 85,就说明当天要处置。脚本跑通只是第一步,还要把输出存成带日期的文件,第二天用 diff 比较变化率,否则相当于白跑。
我自己踩过的最后一个坑:巡检脚本里塞了太多指标,导致每天的输出超过一百行,反而没人看。后来我把脚本精简成只看“异常行”,正常状态不输出,这样每天早上扫一眼日志文件有没有新内容就够了。案例 PPT 里的命令会过期,这套脚本不会,它会跟着库一起成长。希望帮到你。
本文还有配套的精品资源,点击获取