接手一套Oracle生产库,最怕的就是“书到用时方恨少”。平时看过不少命令大全,真到故障或者巡检的时候,脑子一片空白,只能现场翻文档。今天这篇东西,不打算写成教科书式的命令罗列,而是按DBA日常工作的实际场景来梳理——从实例巡检、用户权限、备份恢复,到性能诊断、SQL调优,再到那些让人头疼的迁移和补丁操作。我把这些年实际用下来、频率最高、最容易踩坑的Oracle常用命令整理成一套可以直接照着用的操作清单,每个命令都带上了我自己的用法习惯和注意事项,希望能帮你少走点弯路。
1. 实例与数据库状态巡检:每天上班第一件事
很多DBA的习惯是一上班先看邮件、看监控告警,但我建议你先把下面的命令过一遍,尤其是数据库刚接手或者近期有过变更的时候。这套巡检命令基本覆盖了“数据库活着吗、跑得动吗、会不会马上满”这几个核心问题。
1.1 登录与基本信息确认
不要小看登录这一步,生产环境里登录方式错了,后面全是坑。我一般用操作系统认证登录,避免密码问题:
bash复制sqlplus / as sysdba
登录后第一件事,确认实例状态和版本:
sql复制SELECT STATUS, INSTANCE_NAME, VERSION, STARTUP_TIME, HOST_NAME
FROM V$INSTANCE;
这里重点看STATUS是否是OPEN,STARTUP_TIME是否和你预期的重启时间一致。如果状态是MOUNTED或者STARTED,说明数据库没有完全打开,需要进一步检查。版本信息很重要,很多命令在不同版本下行为有差异,后面讲到的很多特性在11g、12c、19c里表现都不太一样。
还有一个我几乎每天都要查的:
sql复制SELECT NAME, OPEN_MODE, DATABASE_ROLE, LOG_MODE, FORCE_LOGGING
FROM V$DATABASE;
OPEN_MODE显示READ WRITE还是READ ONLY,DATABASE_ROLE是PRIMARY还是PHYSICAL STANDBY,这决定了你到底是主库还是备库,千万别在备库上执行写操作。LOG_MODE如果是NOARCHIVELOG,那就要敲响警钟了——这种模式下基本只能做冷备,出了故障恢复窗口会非常难看。
1.2 会话与等待事件:数据库“卡”在哪
当业务反馈“系统很慢”的时候,不要急着重启,先看会话。我常用的三板斧:
sql复制-- 查看当前所有活跃会话
SELECT SID, SERIAL#, USERNAME, STATUS, MACHINE,
SQL_ID, EVENT, BLOCKING_SESSION, LOGON_TIME
FROM V$SESSION
WHERE STATUS = 'ACTIVE'
AND USERNAME IS NOT NULL
ORDER BY LOGON_TIME;
EVENT字段是重点。如果大量会话卡在enq: TX - row lock contention,说明有人在锁表;如果卡在db file sequential read,大概率是SQL执行计划有问题或者IO慢。BLOCKING_SESSION字段可以直接告诉我们是谁在挡路。
定位到阻塞源之后,确认无误再杀掉会话:
sql复制ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE;
注意,IMMEDIATE表示立即中断,否则Oracle会等当前事务结束才断。杀会话一定要确认是哪个业务的会话,我见过有人把应用连接池的会话全杀了,结果应用集体重连,瞬间把库打爆。
如果只看等待事件分布,可以直接查视图:
sql复制SELECT EVENT, TOTAL_WAITS, TIME_WAITED_MICRO
FROM V$SYSTEM_EVENT
WHERE WAIT_CLASS != 'Idle'
ORDER BY TIME_WAITED_MICRO DESC
FETCH FIRST 10 ROWS ONLY;
这里排除Idle类事件(比如空等待),剩下的才是真正消耗时间的等待。这一条命令能快速判断瓶颈在CPU、IO还是锁竞争。
1.3 表空间与数据文件使用率
表空间满导致数据库hang住,这种事故在运维中太常见了。我建议每周至少检查一次,而且要按数据文件级别去看:
sql复制SELECT TABLESPACE_NAME, ROUND(SUM(BYTES)/1024/1024/1024, 2) AS SIZE_GB,
ROUND(SUM(MAXBYTES)/1024/1024/1024, 2) AS MAXSIZE_GB,
ROUND((SUM(BYTES) - SUM(FREE_SPACE))/SUM(BYTES)*100, 2) AS USED_PERCENT
FROM (
SELECT TABLESPACE_NAME, BYTES, MAXBYTES,
DECODE(AUTOEXTENSIBLE, 'YES', 0, BYTES) AS FREE_SPACE
FROM DBA_DATA_FILES
)
GROUP BY TABLESPACE_NAME
ORDER BY USED_PERCENT DESC;
简单版的话也可以直接查DBA_TABLESPACE_USAGE_METRICS:
sql复制SELECT TABLESPACE_NAME, USED_PERCENT, USED_SPACE, TABLESPACE_SIZE
FROM DBA_TABLESPACE_USAGE_METRICS
WHERE USED_PERCENT > 80
ORDER BY USED_PERCENT DESC;
习惯上我会把80%作为预警线,达到85%就开始准备扩容或者清理回收。如果表空间开启了自动扩展,数据文件一般不会满,但要注意MAXSIZE的限制,以及文件系统本身的剩余空间。很多人只看表空间使用率,忽略了磁盘满,这是另一个隐藏雷区。
1.4 归档日志与告警日志:故障的“前兆”
归档日志满是非常经典的问题,一旦归档目录写满,数据库会直接hang住。日常检查归档空间:
sql复制SELECT DEST_ID, ROUND(SPACE_USED/1024/1024/1024, 2) AS USED_GB
FROM V$RECOVERY_AREA_USAGE;
-- 或者直接看归档日志数量和最近切换时间
SELECT THREAD#, SEQUENCE#, FIRST_TIME, NEXT_TIME
FROM V$ARCHIVED_LOG
WHERE FIRST_TIME > SYSDATE - 1
ORDER BY SEQUENCE#;
如果发现归档切得很频繁,说明数据库日志量很大,这时候要看是不是有批量任务在跑,或者是否有应用在频繁提交小事务。另外,每天看一眼告警日志是必须的:
bash复制tail -200 $ORACLE_BASE/diag/rdbms/$ORACLE_SID/$ORACLE_SID/trace/alert_$OR
