收获不止数据库

DBA,数据世界的医生(附达梦巡检代码)

本文作者: 梁敬彬、黄海明

引言

周末,达梦数据的海明老师致电L老师,不巧,L老师正在体检,未能接听。

体检结束后,L老师回拨过去,却轮到海明老师未能接听。直到海明老师再次来电,这个小小的“电话插曲”才终于有了答案——原来,海明老师竟也在体检。

这个有趣的巧合,让两人的交流从技术自然地延伸到了健康。一番畅聊之后,海明老师忽然感慨了一句:“说真的,数据库世界的DBA,和现实生活中的医生,其实是一样一样的,比如咱们的这次体检在数据库中就叫巡检。”

这句话,瞬间点亮了L老师的思路:“海明老师说得好啊。其实不止是“治未病”,”治已病“ 也是类似的。”

海明老师连连称是,两人又为此兴奋地探讨了许久,并最终决定:要把这份跨越“硅基”与“碳基”的共识写出来,并在达梦数据库环境中,让大家去感受自己作为“数据医生”的神圣使命。

0

两种生命体,一种守护者

海明老师的感慨,精准地捕捉到了DBA这个职业的核心。

当凌晨的告警铃声将你从梦中惊醒,面对“系统卡顿、业务中断”的紧急呼叫时,你是否曾感到自己像一名冲向急诊室的医生?本文将以一个新颖而深刻的视角,详细剖析数据库管理员(DBA)与医生这两个职业之间惊人的相似性,从预防医学到ICU抢救,从望闻问切到手术方案,揭示DBA作为“数据医生”的宿命、挑战与荣光。

在我们的世界里,存在两种截然不同的“生命体”。一种是碳基的,由细胞、组织和器官构成,我们称之为“人”。另一种是硅基的,由数据、逻辑和架构组成,我们称之为“信息系统”。前者由医生守护,后者则由一群被称为DBA(数据库管理员)的特殊群体守护。

这两个职业看似遥远,一个在无影灯下拯救生命,一个在命令行前保障数据。但如果你深入其工作的本质,你会发现他们遵循着几乎完全相同的哲学、方法论和职业精神。本文将带你踏上这场跨越碳基与硅基的探索之旅,看看DBA这位“数字医生”是如何工作的。

1

上医善治未病——DBA长于预防

医学的最高境界,不是治愈了多少疑难杂症,而是在于“治未病”——通过预防和保健,让疾病无从发生。这同样是衡量一位DBA价值的黄金标准。

上医善治未病——DBA长于预防

维度

医生预防

DBA保障

定期体检

安排年度体检,通过血液、影像学等指标,评估器官功能,预警潜在风险。

执行每日/每周的健康巡检 (Health Check),监控CPU、IOPS、内存命中率、空间增长等核心指标,确保系统运行在健康基线之上。

免疫接种

接种疫苗,构建抵御已知病毒的“防火墙”。

定期为数据库安装安全补丁 (Security Patch),修复已知漏洞,抵御SQL注入、数据泄露等“病毒”的侵袭。

健康处方

提出饮食、运动、作息建议,打造健康生活方式。

制定并推行《SQL开发规范》与《数据库设计最佳实践》,从源头杜绝慢查询和糟糕的表结构,这是DBA开给开发团队的“健康处方”。

相关规划

根据年龄和生活习惯,预测未来健康趋势,做好应对准备。

进行容量规划 (Capacity Planning),基于业务增长模型,精准预测未来1-3年的资源需求,提前进行扩容或架构升级,避免“器官”衰竭。

在这里插入图片描述

2

医生望闻问切——DBA条分缕析

当“病人”出现不适,一场严谨的诊断流程便开始了。“望闻问切”,在DBA的世界里,被演绎得淋漓尽致。

1. 望 (Observe) - “脸色不好...”

医生:观察病人的气色、体态、舌苔。
DBA:观察监控大盘上的曲线图就是数据库的“脸色”。CPU曲线是否陡峭?IO延迟是否飙升?连接池是否溢出?这些都是最直观的“体征”。

2. 闻 (Listen & Smell) - “咳嗽有异响...”

医生:用听诊器听心音、肺音,辨别异常杂音。
DBA:查看告警日志、慢查询日志和各种报错信息,这些就是数据库发出的“异响”和“异味”,直接指向病灶区域。

3. 问 (Question) - “哪里疼?什么时候开始的...”

医生:详细询问病人的主观感受、发病时间、疼痛性质。
DBA:与业务方、开发人员沟通。“哪个功能变慢了?”“具体在什么时间点开始的?”“最近有新版本上线吗?”用户的反馈是定位问题的关键线索。

4. 切 (Palpate & Analyze) - “先把个脉,一会儿再做个CT...”

医生:通过脉搏、触诊感知内部情况,并开具CT、MRI等深度检查。
DBA:这是诊断的核心。DBA的“CT机”和“核磁共振仪”包括:

  • 1). 执行计划:分析SQL执行路径,看它是否走了“弯路”(全扫描而非局部索引);

  • 2).AWR/ASH/ADDM 报告: 生成一份详尽的“体检报告”,全面分析一段时间内数据库的所有活动和等待事件;

  • 3). 性能剖析 (Profiling): 就像给代码做心电图,精准定位到消耗资源最多的函数或进程。

-- DBA的“切脉”工具之一:查看SQL的执行计划EXPLAIN  SELECT * FROM orders WHERE customer_id = 123

最终,一个合格的DBA绝不会满足于“重启一下试试”(相当于给病人吃止痛药),而是必须像医生一样,精准定位到根本原因 (Root Cause)。

在这里插入图片描述

3

医生治疗方案——DBA支撑手段

诊断明确后,便进入治疗阶段。DBA的工具箱里,也分“药物”和“手术刀”。

医生治疗方案——DBA支撑手段

方式

医生治疗

DBA支撑

药物治疗

开具处方药,调整身体机能,风险小,恢复快。

SQL优化或参数调优。 改写SQL,添加索引,或调整内核参数,这是最常用、风险最低的“药物”。

微创手术

腹腔镜手术,创口小,不影响核心功能,病人恢复期短。

在线DDL (Online DDL),如在线创建/重建索引、在线加字段。 在业务无感知或极短锁定的情况下完成结构变更。

大型手术

心脏搭桥、器官移植。 风险高、需停工、术前反复论证、术后重点监护。

数据库大版本升级、跨机房数据迁移、分库分表架构重构。 这些都是DBA的“大型手术”,需要详尽的方案、多次的演练、业务停机窗口 (Downtime),以及失败后的回滚预案 (Rollback Plan)。

在每一次“手术”前,DBA都必须像外科医生一样,向所有“家属”(业务方、管理层)清晰地阐述手术方案、潜在风险、预期收益和恢复时间,并共同决策。

在这里插入图片描述

4

ICU生死时速——DBA紧急修复

这里是DBA与医生最惊心动魄的交集——急诊室乃至重症监护室(ICU)。

ICU生死时速——DBA紧急修复

场景

医生急救

DBA修复

体征虚弱

心脏骤停,进行心肺复苏。

数据库实例宕机 (Crash),立即尝试重启实例或主备切换 (Failover)。

灾难创伤

意外导致多器官衰竭,需紧急输血、手术。

存储损坏导致数据文件丢失或损坏 (Corruption),需动用备份,执行时间点恢复 (Point-in-Time Recovery)。

黄金窗口

脑卒中有“黄金4.5小时”的溶栓窗口。

IT领域有明确的RTO (恢复时间目标) 和 RPO (恢复点目标)。RTO定义了服务中断的最长可容忍时间,RPO定义了数据丢失的最大可容忍量。

在ICU里,每一秒都关乎生死。DBA面对宕机的数据库,同样是在与时间赛跑。每一次成功的灾难恢复,都无异于一次生命的拯救。
在这里插入图片描述

5

医者仁心仁术——DBA超越技术

如果说技术是“术”,那么驱动医生和DBA前行的,则是那份“仁心”——一种根植于内心的责任感和职业道德。

  • 责任如山: 医生承载着生命的托付,DBA承载着企业核心数据资产的重量。任何一个微小的失误,都可能导致无法挽回的后果。
  • 隐私守护: 医生遵循《希波克拉底誓言》保护病人隐私,DBA则必须遵守GDPR等法规,誓死捍卫用户数据的安全与机密。
  • 终身学习: 医学在不断进步,数据库技术也在飞速迭代(从集中式到分布式,从关系型到NoSQL,再到云原生、AI数据库...)。停止学习,就意味着被淘汰。
  • 极致冷静: 手术台上的沉着,与故障排查时的冷静,是同一种稀缺品质。压力越大,越要保持逻辑清晰,避免任何情绪化的误操作。

将DBA比作医生,并非故作高深,而是对其工作复杂性、重要性和专业性的真实写照。他们都在与“熵增”这一宇宙的基本定律作斗争,努力在一个极其复杂的系统内,维持秩序、健康与稳定。

在这里插入图片描述

下一次,当有人问起DBA是做什么的时候,你可以自豪地告诉他:“DBA是数据世界的医生,守护的是数字生命体。服务器的脉搏就是它的心跳,奔流不息的数据就是它的血液,守护着它,就是在守护这个世界的正常运转!”

附:达梦数据库巡检脚本

1.数据库授权信息查询

SELECT LIC_VERSION AS "许可证版本"       ,        SERIES_NO AS "序列号"           ,        CHECK_CODE AS "校验码"          ,        AUTHORIZED_CUSTOMER AS "最终用户",        PROJECT_NAME AS "项目名称"       ,        PRODUCT_TYPE AS "产品名称"       ,        CASE SERVER_TYPE WHEN '1' THEN '正式版' WHEN '2' THEN '测试版' WHEN '3' THEN '试用版' WHEN '4' THEN '其他' END AS "产品类型",        TO_CHAR(EXPIRED_DATE) AS "有效日期",        OS_TYPE AS "授权系统",        TO_CHAR(AUTHORIZED_USER_NUMBER) AS "授权用户数",        NVL(TO_CHAR(CONCURRENCY_USER_NUMBER),'') AS "授权并发数",        NVL(TO_CHAR(MAX_CPU_NUM),'') AS "授权CPU个数",        CLUSTER_TYPE AS "授权集群"        FROM V$LICENSE

2. 查询数据库的实例信息

SELECT '版本号',(SELECT id_code)FROM v$instanceunion allselect '数据库名',name from v$databaseunion allselect '实例名',instance_name from v$instanceunion allselect '系统状态',status$ from v$instanceunion allselect '实例模式',mode$ from v$instanceunion allselect '是否启用归档',case arch_mode when 'Y' then '是' when 'N' then '否' end from v$database union allSELECT  '页大小',cast(PAGE()/1024 as varchar)union allSELECT  '大小写敏感',cast(case SF_GET_CASE_SENSITIVE_FLAG()when '1' then '是' when '0' then '否' end as varchar)union allSELECT '字符集',CASE SF_GET_UNICODE_FLAG() WHEN '0' THEN 'GBK18030' WHEN '1' then 'UTF-8' when '2' then 'EUC-KR' endunion allSELECT  '以字符为单位',cast(case SF_GET_LENGTH_IN_CHAR()when '1' then '是' when '0' then '否' end as varchar)union allSELECT  '空白字符填充模式',cast(case (select BLANK_PAD_MODE()) when '1' then '是' when '0' then '否' end as varchar)union allselect '日志文件个数',to_char(count(*)) from v$rlogfileunion allselect '日志文件大小',cast(RLOG_SIZE/1024/1024 as varchar) from v$rlogfile where rowid =1union allselect '创建时间',to_char(create_time) from v$databaseunion allselect '启动时间',to_char(last_startup_time) from v$database;

3. 查询数据库中语句统计信息

select NAME,       STAT_VAL        from v$sysstat where name in ('select statements',                'insert statements',                'delete statements',                'update statements',                'ddl statements',                'transaction total count')

4. 数据库表空间的状态检查

SELECT NAME AS "NAME",       CASE TYPE$ WHEN '1' THEN 'DB类型' WHEN '2' THEN '临时表空间' END AS "TYPE",       CASE STATUS$ WHEN '0' THEN '联机' WHEN '1' THEN '脱机' WHEN '2' THEN '脱机' WHEN '3' THEN '损坏'END AS "STATUS",       TOTAL_SIZE*PAGE/1024/1024 AS "TOTALSIZE",       FILE_NUM AS "FILENUM"FROM V$TABLESPACE

5. 查询数据库表空间的使用情况

SELECT       F.TABLESPACE_NAME ,       ROUND((T.TOTAL_SPACE - F.FREE_SPACE) / 1024, 2) "USED" ,       CASE WHEN H.TOTAL_MAX_SPACE == 0 THEN ROUND(F.FREE_SPACE / 1024, 2) ELSE ROUND((H.TOTAL_MAX_SPACE -(T.TOTAL_SPACE - F.FREE_SPACE)) / 1024, 2) END "FREE_MAX" ,       CASE WHEN H.TOTAL_MAX_SPACE == 0 THEN ROUND(T.TOTAL_SPACE / 1024, 2) ELSE ROUND(H.TOTAL_MAX_SPACE / 1024, 2) END "TOTAL_MAX" ,       CASE WHEN H.TOTAL_MAX_SPACE == 0 THEN ROUND((F.FREE_SPACE/1024)/(T.TOTAL_SPACE / 1024), 4)*100||'%' ELSE ROUND(((H.TOTAL_MAX_SPACE-(T.TOTAL_SPACE - F.FREE_SPACE))/1024)/(H.TOTAL_MAX_SPACE / 1024), 4)*100||'%' END PER_FREE_MAX,       CASE WHEN H.TOTAL_MAX_SPACE == 0 THEN ROUND((((T.TOTAL_SPACE - F.FREE_SPACE))/1024)/(T.TOTAL_SPACE / 1024), 4)*100||'%' ELSE ROUND((((T.TOTAL_SPACE - F.FREE_SPACE))/1024)/(H.TOTAL_MAX_SPACE / 1024), 4)*100||'%' END PER_USED_MAX ,       ROUND(F.FREE_SPACE / 1024, 2) "FREE" ,       ROUND(T.TOTAL_SPACE / 1024, 2) "TOTAL",       CASE WHEN T.TOTAL_SPACE == 0 THEN '' ELSE (ROUND((F.FREE_SPACE / T.TOTAL_SPACE), 4)* 100) || '% ' END PER_FREE,       CASE WHEN T.TOTAL_SPACE == 0 THEN '' ELSE (ROUND((T.TOTAL_SPACE - F.FREE_SPACE) / T.TOTAL_SPACE, 4) * 100)||'%' END PER_USED  FROM ( SELECT TABLESPACE_NAME,                ROUND(SUM(BLOCKS * ( SELECT PARA_VALUE / 1024                   FROM V$DM_INI                  WHERE PARA_NAME = 'GLOBAL_PAGE_SIZE' ) / 1024)) FREE_SPACE           FROM DBA_FREE_SPACE       GROUP BY TABLESPACE_NAME ) F, ( SELECT TABLESPACE_NAME,                ROUND(SUM(BYTES / 1048576)) TOTAL_SPACE           FROM DBA_DATA_FILES       GROUP BY TABLESPACE_NAME ) T, ( SELECT TABLESPACE_NAME,                ROUND(SUM(MAXBYTES / 1048576)) TOTAL_MAX_SPACE           FROM DBA_DATA_FILES       GROUP BY TABLESPACE_NAME ) H WHERE F.TABLESPACE_NAME = T.TABLESPACE_NAME AND F.TABLESPACE_NAME =H.TABLESPACE_NAME

6. 查询表空间的数据文件使用情况

SELECT  PATH,       TO_CHAR(TOTAL_SIZE*PAGE/1024/1024) AS TOTAL_SIZE,       TO_CHAR(FREE_SIZE*PAGE/1024/1024) AS FREE_SIZE,       (TO_CHAR(100-FREE_SIZE*100/TOTAL_SIZE)) AS REM_PER,       CASE AUTO_EXTEND WHEN '0' THEN '未开启' WHEN '1' THEN '已开启' END AS AUTO_EXTEND,       NEXT_SIZE,       MAX_SIZE,       b.TABLESPACE_NAME  FROM V$DATAFILE a,dba_data_files b where b.file_name = a.PATH  order by GROUP_ID

7. 查询数据库中的用户信息

SELECT A.USERNAME ,       CASE B.RN_FLAG WHEN '0' THEN '否' WHEN '1' THEN '是' END AS READ_ONLY,       CASE A.ACCOUNT_STATUS WHEN 'LOCKED' THEN '锁定' WHEN 'OPEN' THEN '正常' END AS "状态",       TO_CHAR(A.LOCK_DATE,'YYYY-MM-DD HH24:MI:SS') AS "锁定起始时间",       TO_CHAR(A.EXPIRY_DATE,'YYYY-MM-DD HH24:MI:SS') AS "密码截止使用时间",       TO_CHAR(round(datediff(DAY,TO_CHAR(sysdate,'YYYY-MM-DD HH24:MI:SS'),TO_CHAR(A.EXPIRY_DATE,'YYYY-MM-DD HH24:MI:SS')),2)) AS EXPIRY_DATE_DAY,       TO_CHAR(round(datediff(DAY,TO_CHAR(sysdate,'YYYY-MM-DD HH24:MI:SS'),TO_CHAR(A.LOCK_DATE,'YYYY-MM-DD HH24:MI:SS')),2)) AS LOCK_DATE_DAY,       A.DEFAULT_TABLESPACE,       A.PROFILE,       TO_CHAR(A.CREATED,'YYYY-MM-DD HH24:MI:SS') AS CREATE_TIME  FROM DBA_USERS A,        SYSUSERS B  WHERE A.USER_ID=B.ID

8. 查询数据库中用户权限

SELECT USERNAME AS "用户名", WM_CONCAT(PRIVILEGE) AS "默认权限"FROM(SELECT  A.USERNAME ,     C.PRIVILEGE FROM DBA_USERS A,SYSUSERS B, (SELECT A.* FROM (SELECT GRANTEE,GRANTED_ROLE PRIVILEGE,'ROLE_PRIVS' PRIVILEGE_TYPE,CASE ADMIN_OPTION WHEN 'Y' THEN 'YES' ELSE 'NO' END ADMIN_OPTION FROM DBA_ROLE_PRIVS UNION SELECT GRANTEE,PRIVILEGE,'SYS_PRIVS' PRIVILEGE_TYPE,ADMIN_OPTION FROM DBA_SYS_PRIVSUNION SELECT GRANTEE,PRIVILEGE||' ON '||OWNER||'.'||TABLE_NAME PRIVILEGE,'TABLE_PRIVS' PRIVILEGE_TYPE,GRANTABLE FROM DBA_TAB_PRIVS) AWHERE GRANTEE IN (SELECT USERNAME FROM ALL_USERS WHERE USERNAME NOT IN ('SYS','SYSDBA','SYSSSO','SYSAUDITOR') ) ) C WHERE A.USER_ID=B.ID AND A.USERNAME = C.GRANTEE)GROUP BY USERNAME

9. 查询数据库中的对象是否无效(函数、存储过程、包等对象)

SELECT  OWNER,       OBJECT_NAME,       OBJECT_TYPE,       TO_CHAR(CREATED,'YYYY-MM-DD HH24:MI:SS'),       TO_CHAR(LAST_DDL_TIME,'YYYY-MM-DD HH24:MI:SS')  FROM DBA_OBJECTS WHERE OWNER NOT IN('SYS',                    'SYSJOB',                    'SYSAUDITOR',                    'CTISYS',                    'SYSSSO')   and STATUS = 'INVALID'

10. 查询数据库中的大表信息

SELECT A.TABLE_NAME,A.TABLESPACE_NAME,B.OWNER ,B.BYTES                   FROM (SELECT TABLE_NAME,TABLESPACE_NAME FROM ALL_TABLES  GROUP BY TABLE_NAME,TABLESPACE_NAME) AS A                   LEFT JOIN (SELECT OWNER,SEGMENT_NAME,SUM(BYTES) BYTES FROM DBA_SEGMENTS WHERE SEGMENT_TYPE='TABLE'GROUP BY OWNER,SEGMENT_NAME) AS B                   ON A.TABLE_NAME=B.SEGMENT_NAME                   WHERE B.OWNER NOT IN ('SYS','SYSDBA','SYSAUDITOR','SYSSSO','CTISYS') ORDER BY BYTES DESC LIMIT 10

11. 查询数据库中的分区大表信息

SELECT A.OWNER,       A.TABLE_NAME,       A.PARTITIONING_TYPE,       TO_CHAR(ROUND(TABLE_USED_SPACE(A.OWNER, A.TABLE_NAME) * PAGE / 1024.0 / 1024, 2))    SIZEMB,       A.PARTITION_COUNT                                                                 as partition_num,       table_rowcount(a.owner, a.table_name)                                             as row_num  FROM DBA_PART_TABLES a;

12. 查询数据库中会话的使用情况

SELECT  *FROM        (                SELECT                        STATE    ,                         CASE     WHEN  INSTR(CLNT_IP, ':',8)  > 0      THEN SUBSTR(CLNT_IP, 1, INSTR(CLNT_IP, ':',8) - 1)     ELSE CLNT_IP     END AS CLNT_IP  ,                        CLNT_TYPE,                        CURR_SCH ,                        USER_NAME,                        COUNT(*) COUNTS                FROM                        V$SESSIONS                GROUP BY                        STATE    ,                         CASE     WHEN  INSTR(CLNT_IP, ':',8)  > 0      THEN SUBSTR(CLNT_IP, 1, INSTR(CLNT_IP, ':',8) - 1)     ELSE CLNT_IP     END   ,                        CLNT_TYPE,                        CURR_SCH ,                        USER_NAME                ORDER BY                        STATE        )

13. 长时间空闲会话检查

SELECT SESS_ID,       SESS_SEQ,       USER_NAME,       CREATE_TIME,       CLNT_TYPE,       CLNT_HOST,       CLNT_IP,       OSNAME,       CONN_TYPE,       CLNT_VER  FROM SYS.V$SESSIONS WHERE STATE = 'IDLE'   AND DATEDIFF(HH, LAST_SEND_TIME, SYSDATE) > 48   AND DATEDIFF(HH, CREATE_TIME, SYSDATE) > 48;

14. 查询数据库的redo日志大小

SELECT FILE_ID,PATH,CLIENT_PATH,RLOG_SIZE FROM V$RLOGFILE

15. 查询数据库的定时任务信息

SELECT  SYSJOB."NAME"           ,        SCHE."NAME" SCHENAME    ,        SCHE."JOBID"            ,        SCHE."TYPE"             ,        SCHE."FREQ_INTERVAL"    ,        SCHE."FREQ_SUB_INTERVAL",        SCHE."STARTTIME"        ,        STEPS."NAME" STEPSNAME  ,        STEPS."SEQNO" STEPSSEQNO,        STEPS."TYPE" STEPSTYPE  ,        STEPS.COMMAND WHAT      ,        STEPS.SUCC_ACTION       ,        STEPS.FAIL_ACTIONFROM        SYSJOB.SYSJOBSCHEDULES SCHELEFT JOIN SYSJOB.SYSJOBSTEPS STEPSON        SCHE.JOBID = STEPS.JOBIDLEFT JOIN SYSJOB.SYSJOBS SYSJOBON        SCHE.JOBID = SYSJOB.IDWHERE        SCHE.VALID == 'Y'ORDER BY        STEPS.JOBID,        STEPS.SEQNO ASC

16. 查询定时任务是否有错误 

select           NAME ,         '' STEPNAME ,         MAX(START_TIME) START_TIME,         ERRINFO    from ( SELECT NAME ,                  MAX(START_TIME) START_TIME,                  ERRINFO             FROM SYSJOB.SYSSTEPHISTORIES2            WHERE ERRCODE !=0         GROUP BY NAME,                  ERRINFO         union all           select NAME ,                  MAX(START_TIME) START_TIME,                  ERRINFO             from SYSJOB.SYSJOBHISTORIES2            where ERRCODE !=0         GROUP BY NAME,                  ERRINFO )   WHERE TO_CHAR(START_TIME,'YYYY-MM-DD HH24:MI:SS') >= TO_CHAR(TRUNC(ADD_DAYS(SYSDATE, -7)),'YYYY-MM-DD HH24:MI:SS')GROUP BY NAME,         ERRINFOORDER BY START_TIME DESC LIMIT 10

17. 数据字典的淘汰情况

SELECT ROUND(TOTAL_SIZE/1024.0/1024, 2) TOTALSIZE         ,                          ROUND(USED_SIZE /1024.0/1024, 2) USEDSIZE         ,                          DICT_NUM DICTNUM                                ,                          ROUND(SIZE_LRU_DISCARD/1024.0/1024, 2)  SIZELRUDISCARD,                          LRU_DISCARD LRUDISCARD,ROUND((USED_SIZE/1024.0/1024)/(TOTAL_SIZE/1024.0/1024)*100, 2) CACHE_HIT                   FROM                          V$DB_CACHE

18. 查询数据库中的无效索引

select owner, index_name,table_name,index_type,status from dba_indexeswhere status != 'VALID' and owner notin ('SYS', 'SYSAUDITOR', 'SYSSSO', 'SYSDBA', 'DEM', 'SYSJOB', 'SYSDBO')order by 1,2,3;

19. 查询数据库分区表中的无效索引

SELECT *  FROM (SELECT SCH_NAME, INDEX_NAME, PARTITION_NAME, SUBPARTITION_NAME,STATUS          FROM DBA_IND_SUBPARTITIONS        UNION        SELECT SCH_NAME, INDEX_NAME, PARTITION_NAME, NULL,STATUS          FROM DBA_IND_PARTITIONS        UNION        SELECT OWNER, INDEX_NAME, NULL, NULL,STATUS FROM DBA_INDEXES) S WHERE S.STATUS = 'UNUSABLE'   AND S.SCH_NAME NOT IN       ('SYS', 'SYSAUDITOR', 'SYSSSO', 'SYSDBA', 'DEM', 'SYSJOB', 'SYSDBO') ORDER BY 1, 2

20. 查询数据库中的大索引信息

SELECT objname AS "对象名",objtype as "对象类型",TABLESPACE_NAME AS "表空间",to_char(round(TOT_BLOCKS/1024.0/1024.0*page(),2)) AS "大小(MB)"from (SELECT objname,objtype,TABLESPACE_NAME,SUM(page_used) TOT_BLOCKS FROM (select * from/*(select owner||'.'||table_name objname, 'TABLE/TABLE PART' objtype, TABLESPACE_NAME, TABLE_USED_PAGES(owner,table_name) page_used from dba_tables  where tablespace_name not in ('TEMP','ROLL','SYSTEM') and owner not in ('SYS','SYSAUDITOR','SYSSSO','SCHEDULER')and temporary='N'and TABLE_USED_PAGES(owner,table_name)> (select sum(TOTAL_SIZE)*0.0001 from v$datafile)order by table_used_space(owner,table_name) desclimit 10)union all*/(select owner||'.'||index_name objname, 'INDEX/INDEX PART' objtype, TABLESPACE_NAME, INDEX_USED_PAGES(owner,index_name) page_used from dba_indexes  where tablespace_name not in ('TEMP','ROLL','SYSTEM') and owner not in ('SYS','SYSAUDITOR','SYSSSO','SCHEDULER')and temporary='N'and INDEX_TYPE != 'CLUSTER'and INDEX_USED_PAGES(owner,index_name)> (select sum(TOTAL_SIZE)* 0 from v$datafile)order by index_used_space(owner,table_name) desc)order by page_used desclimit 10)GROUP BY objname,objtype,TABLESPACE_NAMEorder by TOT_BLOCKS DESC limit 10)

21. 查询监视器信息

selectTO_CHAR(DW_CONN_TIME, 'YYYY-MM-DD HH24:MI:SS') CONN_TIME,MON_CONFIRM,MON_IP,MON_ID,MON_TERM from v$dmmonitor

22. 查询实例运行错误的日志

select * from V$INSTANCE_LOG_HISTORY where LEVEL$ not in ('INFO','WARN')

23. 查询数据库中是否存在死锁

SELECT TO_CHAR(HAPPEN_TIME,'YYYY-MM-DD HH24:MI:SS') HAPPEN_TIME,SQL_TEXT  FROM V$DEADLOCK_HISTORY WHERE HAPPEN_TIME >DATEADD(DAY,-30,SYSDATE)

24. 查询数据库中的已经运行后的慢SQL

SELECT SQL_TEXT,EXEC_TIME,FINISH_TIME FROM V$SYSTEM_LONG_EXEC_SQLS ORDER BY EXEC_TIME DESC

25. 查询数据库中运行报错的SQL语句

SELECT SQL_TEXT,ECPT_DESC,max(ERR_TIME)ERR_TIME FROM V$RUNTIME_ERR_HISTORY  group by SQL_TEXT,ECPT_DESC LIMIT 10

26. 查询数据库中正在运行的慢SQL

select *  from ( SELECT DATEDIFF(MS,LAST_RECV_TIME,SYSDATE) EXEC_TIME,                            DBMS_LOB.SUBSTR(SF_GET_SESSION_SQL(SESS_ID)) SLOW_SQL,                            SESS_ID,                            CURR_SCH,                            THRD_ID,                            LAST_RECV_TIME,                            SUBSTR(CLNT_IP,8,13) CONN_IP                       FROM V$SESSIONS                      WHERE  1=1                    and STATE='ACTIVE'                   ORDER BY 1 DESC)              where EXEC_TIME >= ? and LAST_RECV_TIME > TO_TIMESTAMP('2000-01-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS') LIMIT ?
更多精彩原创内容见公众号
    点关注   Image  不迷路
往期回顾
大白话人工智能系列
数据库拍案惊奇系列
世事洞明皆学问系列