数据库的“黑匣子”--故障诊断日志基础

2020-03-26 15:22:09 浏览数 (1)

本文介绍数据库故障诊断日志基础。

01

从“黑匣子”说起

相信大家都知道,当飞机发生事故后,人们进行搜救的时候,总是会寻找一个东西---被誉为空难“见证人”的黑匣子。它可以给调查人员提供证据,帮组他们了解事故的真相。 同样,作为业界最为强大的关系型数据库,Oracle数据库也提供了无与伦比的“黑匣子”功能--数据库故障诊断基础架构。通过这个架构设计,当发生问题或者严重错误时,数据库会自动为每一个事件/错误分配一个事件号/错误号,然后输出相关的日志文件,为问题预防、发生重大问题后的追溯原因和修复缺陷等提供重要线索和证据。

02

"黑匣子"的设置

11gR1版本以后数据库的"黑匣子"是通过ADR进行管理的。ADR是自动诊断库(Automatic Diagnostic Repository)的简称,用于统一管理数据库/网络监听/客户端的警告日志,日志文件(trace)、事件日志文件(incident file)、转储文件(dump/core file)等数据库诊断信息。

ADR的结构和存放路径

这些诊断信息文件的存放路径,一般通过ADR_BASE和ADR_HOME设置。

ADR_BASE:

代码语言:javascript复制
ADR_BASE是ADR的根目录,通过初期参数DIAGNOSTIC_DEST的设定。
如果用户DIAGNOSTIC_DEST没有明确设定的话,DIAGNOSTIC_DEST会在数据库启动时默认设置如下:
・环境变量ORACLE_BASE被设置的话,设为ORACLE_BASE的路径
・环境变量ORACLE_BASE没有被设置的话,设为ORACLE_HOME/log   

ADR_HOME:

代码语言:javascript复制
ADR_HOME位于ADR_BASE的子目录中,是各产品或组件的诊断信息的根目录。
ADR_HOME的路径为:
<ADR_BASE>/diag/<product_type>/<product_id>/<instance_id>

根据产品或组件,一个ADR_BASE中可以有多个ADR_HOME;ADR_BASE中的各产品或组件的子目录结构如下:

▲Figure 9-1 Product/Component Type Subdirectories in the ADR https://docs.oracle.com/en/database/oracle/oracle-database/19/admin/diagnosing-and-resolving-problems.html#GUID-951A06EE-DDF7-4C2A-B0BB-B24418BB2E33

以数据库为例,数据库的诊断信息根目录ADR_HOME,根据ADR_BASE设定,其值为:

代码语言:javascript复制
<Oracle Database>
  <ADR_BASE>/diag/rdbms/<dbname>/<instname>
代码语言:javascript复制

▲Figure 9-2 ADR Directory Structure for a Database Instance https://docs.oracle.com/en/database/oracle/oracle-database/19/admin/diagnosing-and-resolving-problems.html#GUID-951A06EE-DDF7-4C2A-B0BB-B24418BB2E33

主要诊断信息各文件路径如下:

另外,通过V$DIAG_INFO视图可以关于ADR的信息和各种日志文件的路径。

例:

代码语言:javascript复制
SQL> col NAME format a25
SQL> col VALUE format a100
SQL> set linesize 200
SQL> select NAME,VALUE from V$DIAG_INFO;
NAME                      VALUE
------------------------- ----------------------------------------------------------------------------------------------------
Diag Enabled              TRUE
ADR Base                  /home/app/19.3.0.0/oracle
ADR Home                  /home/app/19.3.0.0/oracle/diag/rdbms/orcl19300/orcl19300
Diag Trace                /home/app/19.3.0.0/oracle/diag/rdbms/orcl19300/orcl19300/trace
Diag Alert                /home/app/19.3.0.0/oracle/diag/rdbms/orcl19300/orcl19300/alert
Diag Incident             /home/app/19.3.0.0/oracle/diag/rdbms/orcl19300/orcl19300/incident
Diag Cdump                /home/app/19.3.0.0/oracle/diag/rdbms/orcl19300/orcl19300/cdump
Health Monitor            /home/app/19.3.0.0/oracle/diag/rdbms/orcl19300/orcl19300/hm
Default Trace File        /home/app/19.3.0.0/oracle/diag/rdbms/orcl19300/orcl19300/trace/orcl19300_ora_10323.trc
Active Problem Count      0
Active Incident Count     0
ORACLE_HOME               /home/app/19.3.0.0/oracle/product/19.3.0.0/dbhome_6

12 rows selected.

日志保存期间

ADR管理的日志文件的保存期间,一般通过下面两个保存策略进行设置:

代码语言:javascript复制
SHORTP_POLICY:默认720小时(30天)
LONGP_POLICY :默认8760小时(365天)

数据库的后台进程MMON会每隔24小时进行检查一次,如果日志文件超过保存策略的时间的话,会自动将其删除。 各日志的保存策略如下:

另外,文本形式的警告日志文件比较特殊,为了尽量保存有用的信息,它并不是自动管理的对象,可以根据应用情况自行删除。

ADR管理命令adrci

可以通过adrci命令来进行ADR中的设置和查看。具体用法如下: 1.在Oracle环境中输入“adrci”启动adrci命令行。

代码语言:javascript复制
    -bash-4.1$ adrci
    ADRCI: Release 19.0.0.0.0 - Production on Fri Mar 13 23:32:21 2020
    Copyright (c) 1982, 2019, Oracle and/or its affiliates.  All rights reserved.
    ADR base = "/home/app/19.3.0.0/oracle"
    adrci>

2. 可以通过在adrci命令行中输入"help",查看各命令的使用方法帮助文件。

代码语言:javascript复制
    adrci> help
     HELP [topic]
       Available Topics:
            CREATE REPORT
            ECHO
            ESTIMATE
            EXIT
            HELP
            HOST
            IPS
            PURGE
            RUN
            SELECT
            SET BASE
            SET BROWSER
            SET CONTROL
            SET ECHO
            SET EDITOR
            SET HOMES | HOME | HOMEPATH
            SET TERMOUT
            SHOW ALERT
            SHOW BASE
            SHOW CONTROL
            SHOW HM_RUN
            SHOW HOMES | HOME | HOMEPATH
            SHOW INCDIR
            SHOW INCIDENT
            SHOW LOG
            SHOW PROBLEM
            SHOW REPORT
            SHOW TRACEFILE
            SPOOL
     There are other commands intended to be used directly by Oracle, type
     "HELP EXTENDED" to see the list

3. 通过SHOW CONTROL 命令可以显示ADR相关的设置。 例:

代码语言:javascript复制
    adrci> show homepath
    ADR Homes:
    diag/rdbms/orcl19300/orcl19300
    adrci> show control

    ADR Home = /home/app/19.3.0.0/oracle/diag/rdbms/orcl19300/orcl19300:
    *************************************************************************
    ADRID                SHORTP_POLICY        LONGP_POLICY         LAST_MOD_TIME                            LAST_AUTOPRG_TIME                        LAST_MANUPRG_TIME                        ADRDIR_VERSION       ADRSCHM_VERSION      ADRSCHMV_SUMMARY     ADRALERT_VERSION     CREATE_TIME                              SIZEP_POLICY         PURGE_PERIOD         FLAGS                PURGE_THRESHOLD
    -------------------- -------------------- -------------------- ---------------------------------------- ---------------------------------------- ---------------------------------------- -------------------- -------------------- -------------------- -------------------- ---------------------------------------- -------------------- -------------------- -------------------- --------------------
    4202733928           720                  8760                 2020-03-07 10:10:10.995802  00:00        2020-03-12 07:58:51.055898  00:00                                                 1                    2                    110                  1                    2020-03-07 10:10:10.995802  00:00        18446744073709551615 0                    0                    95     
    1 row fetched

SHOW CONTROL的命令结果:

4. ADR的设置 可以通过SET命令可以进行ADR的设置。

代码语言:javascript复制
设置短期保存策略(SHORTP_POLICY)
ardci> set control (SHORTP_POLICY = <Value>)

设置长期保存策略(LONGP_POLICY)
ardci> set control (LONGP_POLICY = <Value>)

设置ADR home的大小限制(SIZEP_POLICY)
ardci> set control (SIZEP_POLICY = <Value>)

02

解密"黑匣子"

当遇到问题时候,我们就需要通过解密"黑匣子"来寻找真相了。

通常诊断信息的确认流程如下:

1.警告日志文件(alert log)

警告日志文件(alert log)会按照时间的顺序记录数据库实例启动、停止、恢复等管理操作,以及一些重要的错误、数据库重要事件的历史信息,如:

代码语言:javascript复制
实例启动/关闭处理的状态
初始化参数值的修改
各种内部和严重错误(如ORA-600、ORA-7445、ORA-60)
执行的管理命令(CREATE / ALTER / DROP DATABASE / TABLESPACE和ARCHIVE LOG输出,恢复处理等)
等等...

而且对于各种重要的错误,警告日志中还会记录关于错误的概要信息和记录详细情况的跟踪日志文件(trace file)的输出路径等信息。 所以,在日常的数据库运用中应定期监视警告日志,并且在数据库发生问题时,首先查看问题发生时间点警告日志,看看是否有有用的信息例如其他详细的跟踪日志信息等;然后向前追溯到最后一次数据库重启;通过重启的信息我们可以看到数据库的参数配置,12c以后的版本还可以看到补丁信息;通过对从重启到问题发生期间的信息确认也有可能找到对问题诊断有用的信息。 alert log输出例:

代码语言:javascript复制
Starting ORACLE instance (normal) (OS id: 976)
...
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.3.0.0.0.
ORACLE_HOME:    /home/app/19.3.0.0/oracle/product/19.3.0.0/dbhome_6
System name:    Linux
Node name:      <HOSTNAME>
Release:        2.6.32-431.el6.x86_64
Version:        #1 SMP Wed Nov 20 23:56:07 PST 2013
Machine:        x86_64
Using parameter settings in server-side spfile /home/app/19.3.0.0/oracle/product/19.3.0.0/dbhome_6/dbs/spfileorcl19300.ora
System parameters with non-default values: ★数据库启动的参数
processes                = 300
nls_language             = "AMERICAN"
nls_territory            = "AMERICA"
sga_target               = 1968M
control_files            = "/home/app/19.3.0.0/oracle/oradata/ORCL19300/control01.ctl"
control_files            = "/home/app/19.3.0.0/oracle/oradata/ORCL19300/control02.ctl"
db_block_size            = 8192
compatible               = "19.0.0"
undo_tablespace          = "UNDOTBS1"
remote_login_passwordfile= "EXCLUSIVE"
db_domain                = "<db_domain_name>"
dispatchers              = "(PROTOCOL=TCP) (SERVICE=orcl19300XDB)"
audit_file_dest          = "/home/app/19.3.0.0/oracle/admin/orcl19300/adump"
audit_trail              = "DB"
db_name                  = "orcl1930"
db_unique_name           = "orcl19300"
open_cursors             = 300
pga_aggregate_target     = 489M
diagnostic_dest          = "/home/app/19.3.0.0/oracle"
2020-03-14T04:00:39.951434 00:00
============================================================
NOTE: PatchLevel of this instance 0
============================================================
Starting background process PMON
...
2020-03-14T04:00:53.243384 00:00
===========================================================
Dumping current patch information        ★数据库的补丁信息
===========================================================
Patch Id: 29517242
Patch Description: Database Release Update : 19.3.0.0.190416 (29517242)
Patch Apply Time: 2019-04-18T07:21:17Z
Bugs Fixed: 14735102,19697993,20313356,21965541,25806201,25883179,25986062
...
Patch Id: 29585399
Patch Description: OCW RELEASE UPDATE 19.3.0.0.0 (29585399)
Patch Apply Time: 2019-04-18T07:21:33Z
Bugs Fixed: 3,27222128,27572040,27604329,27760043,27877830
...
2020-03-14T04:32:25.433991 00:00        ★错误信息
Errors in file /home/app/19.3.0.0/oracle/diag/rdbms/orcl19300/orcl19300/trace/orcl19300_ora_1561.trc  (incident=29073):★跟踪日志文件
ORA-04031: unable to allocate 40 bytes of shared memory ("shared pool","DUAL","KGLS^7e798f93","kglHeapInitialize:temp")
Incident details in: /home/app/19.3.0.0/oracle/diag/rdbms/orcl19300/orcl19300/incident/incdir_29073/orcl19300_ora_1561_i29073.trc★事件日志文件
Use ADRCI or Support Workbench to package the incident.
See Note 411.1 at My Oracle Support for error and packaging details.
...

通过上面的输出,我们可以看到如下信息:

代码语言:javascript复制
数据库启动的参数
数据库的补丁信息(12c以后的版本)
错误概要信息
跟踪日志文件名和路径
详细事件日志文件名和路径

警告日志就像是索引,帮助我们明确调查方向和如何进一步确认问题的详细状况。 ※注:

代码语言:javascript复制
对于警告日志文件,在11g以后的版本同时输出文本(Text)和xml 两种形式的相同内容文件。
xml形式的警告日志文件(log.xml)主要是供Enterprise Maneger和ADR操作使用;
对于一般调查我们可以使用文本(Text)形式的警告日志文件。
文本(Text)形式的警告日志文件为:<ADR_HOME>/trace/alert_<ORACLE_SID>.log
xml形式的警告日志文件为:<ADR_HOME>/trace/log.xml

2.日志文件

常见的日志文件包括跟踪日志文件(trace file)、事件日志文件(incident file)以及转储文件等。 跟踪日志文件是每个服务器和后台进程都可以写入的关联跟踪文件。跟踪文件中可能包含有关进程环境,状态,活动和错误的信息,并在进程的生命周期中定期更新。此外,当进程检测到严重错误时,数据库还会将有关错误的信息写入其跟踪文件。 事件日志文件是当数据库发生事件时,数据库将分配事件编号并将一个或多个详细跟踪文件和诊断数据输出到为该事件创建的事件目录中的日志里。 如果是RAC实例环境的话,Oracle数据库还提供了Hang Manager(HM)功能,通过Hang Manager能够及时地检测和解决挂起问题,维持资源可用性,而且能够输出关于挂起等相关的dia0/diag日志,所以在RAC环境中遇到问题的话,去检查dia0/diag相关日志是否非常有必要的。

日志路径

・跟踪日志文件(trace file)会输出到以下目录:

代码语言:javascript复制
<diagnostic_dest>/diag/rdbms/<dbname>/<instancename>/trace/
(其中dbname和instancename为数据库名和实例名)

--可以通过以下SQL查看默认的路径
SQL> select * from v$diag_info where NAME in ('Default Trace File', 'Diag Trace');

・对于事件日志文件(incident file),一般会在incident的文件夹中生成。

代码语言:javascript复制
<diagnostic_dest>/diag/rdbms/<dbname>/<instancename>/incident/incdir_<incident_number>
(其中dbname和instancename为数据库名和实例名)

・12c以后的多租户环境(CDB)

在12c以后的多租户环境(CDB)和Non-CDB 的环境一样会以进程为单位生成跟踪日志和事件日志文件。

虽然生成的日志文件名中并不会包含容器(Container相关的信息),但是在跟踪日志/事件日志文件的头文件中会输出一些关于容器的内容。

代码语言:javascript复制
*** CONTAINER ID:(<CONTAINER ID>) <时间戳>
例如:
*** CONTAINER ID:(3) 2016-07-27 10:33:40.269
其中,CONTAINER ID代表的意义如下:
・CONTAINER ID=1    : ROOT
・CONTAINER ID=2    : SEED
・CONTAINER ID=3 以上 : PDB

3.健康监控检查(Health Monitor)

Oracle 11g开始提供了健康监控检查(Health Monitor)功能,可以进行DB结构完整性、物理和逻辑数据块完整性、UNDO和REDO完整性、数据字典、事务等完整性检测,并根据检测解雇生成相关报告和提供解决问题建议。

当发生重大问题时,数据库故障诊断机制会自动调用健康监控检查功能进行检测,用户也可以调用DBMS_HM 程序包进行手动健康监控检查。 手动健康监控检查的方法如下: 1.通过v$hm_check视图获取健康监控检查的类别名。 例:

代码语言:javascript复制
SQL> SELECT name FROM v$hm_check WHERE internal_check='N';
NAME
----------------------------------------------------------------
DB Structure Integrity Check
CF Block Integrity Check
Data Block Integrity Check
Redo Integrity Check
Transaction Integrity Check
Undo Segment Integrity Check
Dictionary Integrity Check
ASM Allocation Check
8 rows selected.

2. 通过DBMS_HM.RUN_CHECK程序包运行健康监控检查。 例:

代码语言:javascript复制
BEGIN
  DBMS_HM.RUN_CHECK('Dictionary Integrity Check', 'MY_RUNNAME');
END;
/

3. 通过DBMS_HM.GET_RUN_REPORT获取运行报告。

代码语言:javascript复制
SET LONG 100000
SET LONGCHUNKSIZE 1000
SET PAGESIZE 1000
SET LINESIZE 512
SELECT DBMS_HM.GET_RUN_REPORT('<运行时指定的名>') FROM DUAL;

运行报告例:

代码语言:javascript复制
SQL> SELECT DBMS_HM.GET_RUN_REPORT('MY_RUNNAME') FROM DUAL;
DBMS_HM.GET_RUN_REPORT('MY_RUNNAME')
------------------------------------------------------------------------
Basic Run Information
 Run Name                     : my_runname
 Run Id                       : 1
 Check Name                   : Dictionary Integrity Check
 Mode                         : MANUAL
 Status                       : COMPLETED
 Start Time                   : 2020-03-14 03:05:57.792376  00:00
 End Time                     : 2020-03-14 03:05:59.557245  00:00
 Error Encountered            : 0
 Source Incident Id           : 0
 Number of Incidents Created  : 0

Input Parameters for the Run
 TABLE_NAME=ALL_CORE_TABLES
 CHECK_MASK=ALL

Run Findings And Recommendations
 Finding
 Finding Name  : Dictionary Inconsistency
 Finding ID    : 2
 Type          : FAILURE
 Status        : OPEN
 Priority      : CRITICAL
 Message       : SQL dictionary health check: obj$.namespace 46 on object OBJ$
               failed
 Message       : Damaged rowid is AAAAASAABAAAEDaAAc - description: Object
               Name PRIVATE_DBAAS is referenced
 Finding
 Finding Name  : Dictionary Inconsistency
 Finding ID    : 5
 Type          : FAILURE
 Status        : OPEN
 Priority      : CRITICAL
 Message       : SQL dictionary health check: obj$.namespace 46 on object OBJ$
               failed
 Message       : Damaged rowid is AAAAASAABAAAEDaAAe - description: Object
               Name PUBLIC_DBAAS is referenced

4. 收集额外诊断信息

DDL 日志 数据定义语言(DDL)日志是与警报日志具有相同格式和基本行为的文件,但它仅包含数据库发出的DDL语句。

如果要启用 DDL 日志的话,需要将ENABLE_DDL_LOGGING初始化参数设置为TRUE。

代码语言:javascript复制
例:
--启用
SQL> alter system set ENABLE_DDL_LOGGING=true;
--禁用
SQL> alter system set ENABLE_DDL_LOGGING=false;

在11g版本中,XML格式的DDL Logging信息记录在ADR HOME/alert目录中,而文本格式信息将记录在警告日志alert_<SID>.log文件中。 在12c以后的版本中,XML格式的DDL Logging信息记录在ADR HOME/log/ddl/log.xml目录中,而文本格式信息将记录在警告日志ADR HOME/log/ddl_<SID>.log文件中。

诊断事件/Trace

ORACLE数据库不仅能够自动输出一些非常重要的警告、错误和跟踪文件,而且如果发生问题时,数据库默认输出的信息不充分的话,为了解决问题收集更加详细的信息,还提供了诊断事件(event)功能,用于缩小问题范围和定位问题。 比较常见的是在发生ORA-XXX错误时,通过指定errorstack 来输出ORACLE运行函数的堆栈情况或者系统状态信息(systemstate)等。 例如,可以通过如下设置,当ORA-8103错误发生时同时输出errorstack和systemstate。

代码语言:javascript复制
例:
SQL> alter system set event ='8103 trace name errorstack level 3; name systemstate level 10' scope=spfile;
SQL> alter system set events '8103 trace name errorstack level 3; name systemstate level 10';

还有,最为常见的为了在进程执行过程中输出更多的诊断信息,如:SQL Trace (10046 Event)和Optimizer Trace(10053 Event)等。

代码语言:javascript复制
例:
--SQL Trace (10046 Event):跟踪SQL语句和的执行过程,收集语句的执行过程和各种相关信息
SQL>alter session set events '10046 trace name context forever, level 12';
      
--Optimizer Trace(10053 Event):跟踪优化器(CBO)的动作内容,了解CBO是如何选择最优执行计划的。 
SQL>alter session set events '10053 trace name context forever, level 1'; 

以上便是数据库故障诊断过程中使用的自动诊断库(Automatic Diagnostic Repository)和相关日志的介绍,希望对你有所帮助。

专注于技术不限于技术!

用碎片化的时间,一点一滴地提高数据库技术和个人能力。

0 人点赞