Oracle数据库日常运维指南:实例检查、空间监控、备份恢复与SQL优化

发布时间:2026/10/12 1:15:18
Oracle数据库日常运维指南:实例检查、空间监控、备份恢复与SQL优化 简介一份面向Oracle数据库运维人员的系统化维护教程覆盖实例启停、日常巡检、RAC操作与紧急故障处理等内容。资源以1个PPT文件呈现整体大小仅1.83MB便于快速下载与翻阅。已有98人浏览学习适合作为数据库入门与日常维护的参考。内容从实例启动的Nomount、Mount、Open三阶段与NORMAL、TRANSACTIONAL、IMMEDIATE、ABORT四种关闭模式讲起详细说明各阶段检查要点与操作差异随后展开数据库日志、性能、存储、安全等常规检查项介绍企业管理器的管理功能并针对RAC环境给出日常操作维护思路。此外还涵盖数据库紧急故障恢复及alertSID.log、后台/用户跟踪文件等诊断文件的管理方法有助于运维人员建立系统的维护框架并快速定位常见问题。1. Oracle日常管理与维护别等告警响了才想起来数据库还要人管很多单位装完Oracle数据库后一年都不动它直到某天凌晨磁盘告警、业务反馈连不上库DBA才连夜爬起来处理。我见过太多所谓“日常管理”最后都变成了“故障应急”。Oracle日常管理与维护的核心是把实例和监听状态、表空间水位、备份可恢复性、SQL性能变化这四类东西变成每天能验证的例行动作而不是让数据库像黑匣子一样跑着。这篇笔记写给要自己扛库的运维、DBA和半路接手的开发按实例、备份、性能、避坑这条线往下走每一段都能直接抄到命令行。2. 实例与监听用三条命令判断数据库今天是否健康数据库能不能对外服务第一道关口是实例和监听。实例代表Oracle内存和后台进程加起来的那套运行体系监听则是客户端接入的入口。日常维护不需要把几百个视图全查一遍先确认三件事实例状态、告警日志里有没有ORA-、监听能不能连。2.1 检查实例状态与告警日志sqlplus 加 tail 就够了以root切到oracle用户用操作系统认证进数据库sqlplus / as sysdba进去以后先看实例和数据库状态SELECT instance_name, status, database_status, startup_time FROM v$instance; SELECT name, open_mode FROM v$database;正常情况status是OPENdatabase_status是ACTIVEopen_mode是READ WRITE。startup_time能告诉你数据库是不是被人悄悄重启过。如果status是STARTED或MOUNTED说明实例还没完全打开通常是崩溃恢复过程中的状态。接着直接看告警日志tail -200 $ORACLE_BASE/diag/rdbms/dbname/SID/trace/alert_SID.logdbname是数据库名SID是实例名路径在12c之后都走ADR统一管理不用再满世界找udump/bdump。想看准确路径查v$diag_info视图里DIAG_TRACE的值。告警日志里重点搜ORA-、ORA-600、ORA-07445以及“space”相关字样这类通常是内部错误或者表空间写满了。数据库如果跑在Linux上还要顺手确认开机自启动配置改/etc/oratab把最后一项从N改成Y再配置dbstart和dbstop对应脚本。很多人忘了这个机房断电重启后应用全连不上才回来翻这个文件。如果数据库用的是ASM存储日常还要看一眼磁盘组剩余空间进入ASM实例可以执行sqlplus / as sysasm或者直接asmcmd lsdg查看使用率。记住ASM实例里没有业务数据它只负责管理磁盘不能当普通实例来连。2.2 监听服务无法启动从 tnsping 到 listener.log 的排查顺序监听是单独的一套进程跟实例不绑定。实例挂了监听可能还在反过来监听挂了实例照跑但客户端连不进来。很多同事一遇到连不上就重启数据库其实监听才是元凶。排查顺序我一般固定为tnsping、lsnrctl、listener日志、端口这四步tnsping orcl lsnrctl status lsnrctl start tail -100 $ORACLE_BASE/diag/tnslsnr/$(hostname)/listener/trace/log.xml netstat -an | grep 1521tnsping通说明本机的tnsnames.ora解析没问题但不代表监听能干活必须lsnrctl status看实际状态。监听启动报错最常见的是TNS-12541和TNS-01189一般是有残留进程占着端口或者上一次异常退出留下的pid文件没清掉。这时候先lsnrctl stop再检查有没有LISTENER进程残留kill掉后重新lsnrctl start。不要一上来就改listener.ora90%的情况是进程残留不是配置错。日志路径也分版本10g在ORACLE_HOME/network/log11g之后进了ADR路径里会带主机名用$(hostname)拼接更稳。另外Windows上监听服务起不来先去服务管理器看“OracleOraDb...TNSListener”这个服务的登录身份和依赖关系常见坑是服务密码过期或者Oracle主目录环境变量指向了旧路径。2.3 listener.log 疯长10g 到 19c 的监听日志清理办法监听日志是另一个日常维护重点。默认情况下listener.log把所有连接尝试都写进去日志增长快高峰期几分钟就能写上几百MB磁盘被它占满的案例非常多。注意对Oracle 10g、11g和12c之后的处理姿势不一样。10g里监听日志在$ORACLE_HOME/network/log12c以后在ADR的listener/trace目录而且日志格式变成XML。清理不能直接rm因为监听进程持有文件句柄直接删了空间不释放还会导致后续写日志报错。我常用的轮转方式是保留最近一份日志清空原文件再让监听重新打开文件LOG_DIR$ORACLE_BASE/diag/tnslsnr/$(hostname)/listener/trace DT$(date %Y%m%d) mv $LOG_DIR/listener.log $LOG_DIR/listener_$DT.log $LOG_DIR/listener.log lsnrctl reloadreload会通知监听重新打开日志文件比stop/start平滑正在跑的连接不会断。配合crontab每天凌晨执行一次日志就按天归档了。12c以后也可以直接改参数降低连接日志的详细程度比如设置日志级别为OFF来彻底不写但生产环境不建议关否则排查问题没有依据。这类日志里也容易混入恶意扫描的连接记录定期归档既保磁盘也保留排查依据是日常管理里性价比很高的一件事。3. 表空间与备份恢复空间管理和后悔药都不能缺磁盘满了是数据库最常见的“慢性死亡”方式所以空间管理排第二。备份恢复则是最后一道后悔药很多团队只备份不恢复演练出了事才发现备份根本不能用。这一章把两条线一起讲清楚。3.1 表空间使用率一条 SQL 把所有数据文件看明白日常巡检里我至少每天看一次表空间水位。最顺手的是这条SELECT d.tablespace_name, ROUND(SUM(d.bytes)/1024/1024/1024, 2) total_gb, ROUND(NVL(SUM(f.bytes),0)/1024/1024/1024, 2) free_gb, ROUND((SUM(d.bytes) - NVL(SUM(f.bytes),0)) / SUM(d.bytes) * 100, 2) used_pct FROM dba_data_files d LEFT JOIN dba_free_space f ON d.file_id f.file_id GROUP BY d.tablespace_name ORDER BY used_pct DESC;dba_data_files统计的是分配给数据文件的总大小dba_free_space按文件ID关联出剩余空间。used_pct超过85%就要关注超过90%建议立即扩容或清理。注意自动扩展这个参数别迷信很多表空间虽然autoextend on但maxsize设了上限照样会满。查maxsize也简单把dba_data_files里的maxbytes字段带出来就行。另外删除大表数据后表空间使用率可能一点没降因为DELETE只是打标记段的空间不还给文件系统。要彻底释放要么TRUNCATE要么用ALTER TABLE ... SHRINK SPACE后者要注意在业务低峰执行。临时表空间暴涨也不要忽略查v$temp_space_header能看到临时文件水位排序和临时段写入了太多数据时它也会爆。3.2 RMAN 备份策略保留策略和归档日志怎么配合RMAN是Oracle默认的备份恢复工具日常维护里最难的不是敲命令是定策略。核心就是回答两个问题备份留几天归档日志怎么配。rman target / CONFIGURE RETENTION POLICY TO RECOVERY WINDOW OF 7 DAYS; CONFIGURE CONTROLFILE AUTOBACKUP ON; BACKUP DATABASE PLUS ARCHIVELOG DELETE INPUT;恢复窗口7天意思是可以把数据库恢复到7天内的任意时间点。PLUS ARCHIVELOG表示备份数据库的同时备份归档日志并且DELETE INPUT会在备份完成后删掉已备份的归档这样归档目录不容易爆。只备份数据库不备份归档恢复到故障点会缺日志这是最常见的血泪教训。库比较大的时候全备放周日晚周一到周六做增量BACKUP INCREMENTAL LEVEL 0 DATABASE; BACKUP INCREMENTAL LEVEL 1 CUMULATIVE DATABASE;Level 0相当于全备基线Level 1累积备份只包含自上次Level 0以来的变化恢复时需要先还原Level 0再叠Level 1。备份不是跑完就完还要定期用CROSSCHECK核对备份集因为磁盘上的备份文件可能被手动清理或迁移RMAN里的元数据早就对不上了。我一般加一条定时任务每周做一次CROSSCHECK和DELETE OBSOLETE避免备份集变成一堆僵尸记录。3.3 恢复演练全库恢复、表空间恢复、单表恢复备份做得再勤不演练等于没有。日常维护里最值钱的时间就是用来做恢复演练的时间。按风险从低到高通常练三种恢复。全库恢复适合彻底崩溃场景# 第一阶段启动到 mount sqlplus / as sysdba EOF STARTUP MOUNT; EOF # 第二阶段在 RMAN 中还原并恢复 rman target / EOF RESTORE DATABASE; RECOVER DATABASE; EOF # 第三阶段打开数据库 sqlplus / as sysdba EOF ALTER DATABASE OPEN; EOF表空间恢复适用某个数据文件损坏比如磁盘坏道导致单个表空间文件损坏# 1. 表空间置为离线 sqlplus / as sysdba EOF ALTER TABLESPACE users OFFLINE IMMEDIATE; EOF # 2. 在 RMAN 中还原并恢复 rman target / EOF RESTORE TABLESPACE users; RECOVER TABLESPACE users; EOF # 3. 表空间重新上线 sqlplus / as sysdba EOF ALTER TABLESPACE users ONLINE; EOF单表恢复最常用的是闪回比如业务误删了一张表的数据FLASHBACK TABLE t TO TIMESTAMP TO_TIMESTAMP(2024-01-01 10:00:00,YYYY-MM-DD HH24:MI:SS);闪回依赖undo空间undo_retention太短或者表结构在误删后有DDL变更闪回会失败。这时只能做表空间时间点恢复或者从备份里挖出这张表再导入。还有一种场景是误TRUNCATE闪回表救不了只能靠闪回数据库或者RMAN恢复所以TRUNCATE前一定仔细确认。恢复演练不能只在一个库里玩要拿测试环境定期练把关键步骤写成操作卡真出事时照着卡来不靠临场回忆。4. 性能巡检与 SQL 优化日常维护里翻车最多的一环日常维护做完健康检查剩下的时间基本都在跟SQL性能较劲。Oracle SQL性能优化的难点不是看执行计划而是判断性能是“今天突然差”还是“一直就那样”。4.1 AWR/ADDM 报告先看结论再看图AWR报告相当于Oracle自带的体检报告ADDM则是直接给你诊断建议。很多人拿到几十页报告从头翻到尾最后什么都没记住。我一般只盯几个区域Top 10 Foreground Events、SQL ordered by Elapsed Time、Segment Statistics。生成报告用脚本就行-- 在 SQL*Plus 中执行 ?/rdbms/admin/awrrpt.sql ?/rdbms/admin/addmrpt.sql执行后它会要你选快照起始和结束ID一般选最近一天业务高峰前后两个快照。如果想主动打个快照EXEC DBMS_WORKLOAD_REPOSITORY.CREATE_SNAPSHOT();AWR快照默认每小时生成一个保留8天这两个参数在DBMS_WORKLOAD_REPOSITORY里都能调整。AWR里“Top 10 Foreground Events”如果看到db file sequential read或者log file sync排在前面说明等待事件主要集中在IO或提交频率上从这两条线继续往下查准没错。ADDM则会给一句人话比如“等待SQL的缓冲池命中率偏低”直接按它的建议调即可别把AWR当黑匣子逐页啃。4.2 执行计划为什么变统计信息、绑定变量与分页查询日常维护里最尴尬的是代码没动SQL突然慢了。十有八九是执行计划变了触发原因就那么几个统计信息过期、绑定变量窥探、数据分布偏移。先看执行计划EXPLAIN PLAN FOR SELECT * FROM users WHERE create_date SYSDATE - 7; SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);执行计划里如果看到全表扫描或索引跳跃扫描而表数据量很大第一反应是统计信息太旧。补一下EXEC DBMS_STATS.GATHER_TABLE_STATS(SCOTT,USERS);DBMS_STATS会重新收集表和列的基数、直方图让CBO重新算代价。注意生产环境收集统计信息也要错峰I/O密集时跑会拖慢业务。还有一类是绑定变量在第一次调用时被“窥视”到特定值后面所有值都按那个值的执行计划走这叫绑定变量窥探解决思路是把直方图做好或者用自适应游标。说到分页查询Oracle经典的写法是ROWNUM嵌套SELECT * FROM ( SELECT t.*, ROWNUM rn FROM (SELECT * FROM users ORDER BY user_id) t WHERE ROWNUM 40 ) WHERE rn 20;深分页时这条会越来越慢因为内层排序要建完整结果集。12c以后可以用OFFSET FETCH但要谨慎它内部实现更快的做法是把分页改成基于上一页最后一个值的游标分页。还有个容易被问到的问题视图上能不能加索引不能。视图本身不存数据要加速视图查询只能优化视图内部SQL或者把视图改成物化视图。连着看执行计划、统计信息、分页写法这套下来才算把SQL性能巡检闭环了。4.3 存储过程用于巡检一个表空间监控脚本的演进巡检如果每次敲一遍SQL早晚有人漏查。更稳的做法是把规则固化成一个存储过程定时调用。比如把上面表空间使用率做成一个PL/SQL存储过程CREATE OR REPLACE PROCEDURE p_check_tablespace AS v_used_pct NUMBER; BEGIN FOR r IN (SELECT tablespace_name, SUM(bytes) total_bytes FROM dba_data_files GROUP BY tablespace_name) LOOP SELECT NVL(SUM(bytes),0) INTO v_used_pct FROM dba_free_space WHERE tablespace_name r.tablespace_name; v_used_pct : (1 - v_used_pct / r.total_bytes) * 100; IF v_used_pct 90 THEN DBMS_OUTPUT.PUT_LINE(r.tablespace_name || usage || v_used_pct || %); -- 生产环境这里换成 UTL_MAIL 发邮件或写入巡检日志表 END IF; END LOOP; END p_check_tablespace;存储过程的好处是检查逻辑统一权限好管控后续接Python连接Oracle做可视化时直接查存储过程写入的巡检日志表就行。PL/SQL里如果需要变长数组可以用VARRAY或ASSOCIATIVE ARRAY但巡检这类轻量逻辑别用太重。调用方式用DBMS_SCHEDULER比老式DBMS_JOB更灵活BEGIN DBMS_SCHEDULER.CREATE_JOB( job_name JOB_CHECK_TBS, job_type PLSQL_BLOCK, job_action BEGIN p_check_tablespace; END;, start_date SYSTIMESTAMP, repeat_interval FREQDAILY; BYHOUR8, enabled TRUE ); END;repeat_interval里的FREQ和BYHOUR定义频率这里表示每天早上8点跑一次。改频率就改这个字符串不用重新建job。所有巡检逻辑都按这个套路往DBMS_SCHEDULER里塞Oracle实例状态、监听状态、备份状态都能自动化。Python连接Oracle主要是后面做展示层真正让巡检少出人命的是这一层调度。5. 常见问题避坑监听日志、ORA-01428 与删除不干净日常维护里有一批问题不是不会处理是每次都踩同一个坑。我按现象、原因、解决三步把高频问题列出来方便你直接对照。5.1 监听服务启动失败的两类现象与处理顺序现象一lsnrctl start执行后报TNS-12541/TNS-01189监听起不来。原因上一次Oracle异常退出Listener进程还残留在内存或者pid文件没清理。解决先lsnrctl stop忽略报错然后ps -ef | grep tnslsnr看残留进程kill掉再lsnrctl start。如果端口被其他程序占用netstat -an | grep 1521能看到是谁占的。现象二tnsping能通但应用还是报无法连接。原因监听起来了但实例没有注册到监听数据库启动后动态注册需要几秒钟如果SERVICE_NAME配置不对就一直不注册。解决在监听里执行lsnrctl services看看有没有对应服务再回数据库执行ALTER SYSTEM REGISTER强制注册。别急着重启监听很多时候service配置里的全局数据库名和实例名不一致重启也白搭。5.2 ORA-01428参数越界不只在日期函数里现象某天跑一条SQL突然报ORA-01428: argument x is out of range常见于TRUNC(SYSDATE)这类日期函数传入了一个超出范围的数字比如月份传了13或者天数传了32。原因Oracle函数对参数有严格定义域参数越界就抛这个错。还有不少人写WHERE时直接用两个日期相减再拿结果跟一个天数比较天数写大了也会触发。解决先定位是哪条SQL、哪个参数越界。日期处理不要拼裸数字用TO_DATE加格式掩码例如TO_DATE(2024-02-30,YYYY-MM-DD)这种一看就是无效日期。TRUNC(SYSDATE)本身没问题问题常在它周围的表达式。顺便提醒dual表只有一行一列做SELECT NVL(MAX(...),0)之类没问题别把大结果集往dual上堆误用的人不在少数。5.3 12c 删除不干净重装失败时的清理思路现象Oracle 12c卸载后重装要么配置助手中途报错要么监听服务起不来要么安装界面提示“实例已存在”。原因卸载时只删了ORACLE_HOME目录服务、注册表、环境变量和启动项没清干净。Windows下尤其明显服务里还能看到OracleOraDB12Home1_...的服务名。解决以管理员身份逐项清理。先停掉所有Oracle服务在命令行里用sc delete逐个删服务再打开注册表删除HKEY_LOCAL_MACHINE\SOFTWARE\Oracle键还有HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services下Oracle开头和ORA开头的服务键也要清。最后把oracle用户的环境变量ORACLE_HOME、ORACLE_SID、PATH里的Oracle路径全部删掉检查启动项和计划任务里有没有残留。重装前再确认一下端口1521没被占用这一步做完基本就能干干净净装上了。另一个跟删除相关的坑业务让“删掉一张表的部分数据”你用DELETE删完结果表空间磁盘空间没降下来。原因是高水位线还在段空间没有收缩。解决方式是如果确认数据不需要用TRUNCATE如果需要保留部分行就用ALTER TABLE ... SHRINK SPACE前提是表没有禁用行移动。这类误用DELETE导致空间不释放的翻车现场几乎每个月都能见到。6. 进阶把巡检攒成一个可复用的 shell 检查清单前面的内容分开看都是点最后把它们串成一条线一个每天早上自动跑一遍的shell巡检脚本。这个脚本不需要复杂框架能输出结果、能定位问题就行。6.1 脚本骨架一次巡检该查哪些东西#!/bin/bash export ORACLE_SIDorcl export ORACLE_HOME/u01/app/oracle/product/19.0.0/dbhome_1 export PATH$ORACLE_HOME/bin:$PATH LOG/var/log/oracle_daily_$(date %F).log sqlplus -s / as sysdba EOF $LOG SET PAGESIZE 100 SELECT instance_name, status FROM v\$instance; SELECT tablespace_name, ROUND((SUM(bytes) - NVL(SUM(free),0)) / SUM(bytes) * 100, 2) used_pct FROM (SELECT tablespace_name, bytes, 0 free FROM dba_data_files UNION ALL SELECT tablespace_name, 0 bytes, bytes free FROM dba_free_space) t GROUP BY tablespace_name HAVING used_pct 90; EOF if grep -E ORA-|TNS- $LOG; then echo 【异常】巡检中发现ORA或TNS错误 else echo 【正常】巡检完成 fi脚本里v$instance必须写成v$instance否则会被shell当成变量吞掉。used_pct那段用UNION ALL把已使用和空闲空间按表空间合并再算使用率比单独JOIN更不容易漏。grep那行会打印异常行这是最简的告警方式。生产环境可以再用mailx把LOG发到值班邮箱或者把告警行写入业务监控平台。如果是等保要求比较严的环境建议在脚本里加AUDIT或者记录操作日志历史输出保留半年这些都有对应的等保命令和审计配置别等到检查时才补。6.2 定时执行与结果验证crontab、日志与告警# crontab -e每天上午8点执行 0 8 * * * /home/oracle/bin/ora_daily_check.sh /var/log/oracle_cron.log 21执行完别直接走人要看三样东西一是cron执行记录确认脚本真的跑了二是当天的ora_daily_日期.log看看内容里有没有HAVING筛选出的超阈值表空间三是手动跑一遍脚本确认sqlplus没因为环境变量问题静默失败。我自己的习惯是每周一早上一来就看上周的巡检日志统计而不是只看当天。现在回顾一下这几年的维护经验最深的教训是巡检脚本能发现90%的问题但剩下10%要靠恢复演练兜底。以前我光写脚本不看结果直到一次真实恢复时发现归档日志少了一段才知道自动化的前提是结果可验证。后来给自己定了死规矩脚本跑完必须人工扫一眼关键输出每月最后一个周五做一次RMAN恢复演练。这套流程坚持下来数据库出大问题的次数确实少了。希望帮到你。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询