1. 程式人生 > >資料庫日常健康檢查方式方法

資料庫日常健康檢查方式方法

巡檢內容

1.    檢查資料庫基本狀況

在本節中主要對資料庫的基本狀況進行檢查,其中包含:檢查例項狀態,檢查Oracle服務程序,檢查Oracle監聽程序,共三個部分。

SQL> select instance_name,host_name,startup_time,status,database_status from v$instance;

INSTANCE_NAME HOST_NAME STARTUP_TIME STATUS   DATABASE_STATUS

----------------     -------------------   --------------------  ----------   ------------ ----

CKDB            AS14         2009-5-7 9:3     OPEN       ACTIVE

其中“STATUS”表示Oracle當前的例項狀態,必須為“OPEN”“DATABASE_STATUS”表示Oracle當前資料庫的狀態,必須為“ACTIVE”

SQL> select name,log_mode,open_mode from v$database;

NAME     LOG_MODE    OPEN_MODE

---------     ------------       -----------------

CKDB     ARCHIVELOG  READ WRITE

其中“LOG_MODE”表示Oracle當前的歸檔方式。“ARCHIVELOG”表示資料庫執行在歸檔模式下,“NOARCHIVELOG”表示資料庫執行在非歸檔模式下。在我們的系統中資料庫必須執行在歸檔方式下。

$ps -ef|grep ora_|grep -v grep&&ps -ef|grep ora_|grep -v grep|wc –l

oracle   2960    1 0 May07 ?       00:01:02 ora_pmon_CKDB

oracle   2962    1 0 May07 ?       00:00:22 ora_psp0_CKDB

oracle   2964    1 0 May07 ?       00:00:00 ora_mman_CKDB

oracle   2966    1 0 May07 ?       00:03:20 ora_dbw0_CKDB

oracle   2968    1 0 May07 ?       00:04:29 ora_lgwr_CKDB

oracle   2970    1 0 May07 ?       00:10:31 ora_ckpt_CKDB

oracle   2972    1 0 May07 ?       00:03:45 ora_smon_CKDB

oracle   2974    1 0 May07 ?       00:00:00 ora_reco_CKDB

oracle   2976    1 0 May07 ?       00:01:24 ora_cjq0_CKDB

oracle   2978    1 0 May07 ?       00:06:17 ora_mmon_CKDB

oracle   2980    1 0 May07 ?       00:07:26 ora_mmnl_CKDB

oracle   2982    1 0 May07 ?       00:00:00 ora_d000_CKDB

oracle   2984    1 0 May07 ?       00:00:00 ora_s000_CKDB

oracle   2994    1 0 May07 ?       00:00:28 ora_arc0_CKDB

oracle   2996    1 0 May07 ?       00:00:29 ora_arc1_CKDB

oracle   3000    1 0 May07 ?       00:00:00 ora_qmnc_CKDB

oracle   3625    1 0 May07 ?       00:01:40 ora_q000_CKDB

oracle  31594    1 0 Jul20 ?       00:00:00 ora_q003_CKDB

oracle  23802    1 0 05:09 ?       00:00:33 ora_j000_CKDB

19

在檢查Oracle的程序命令輸出後,輸出顯示至少應包括以下一些程序:
. Oracle寫資料檔案的程序,輸出顯示為:“ora_dbw0_CKDB”
. Oracle
寫日誌檔案的程序,輸出顯示為:“ora_lgwr_ CKDB”
. Oracle
監聽例項狀態的程序,輸出顯示為:“ora_smon_ CKDB”
. Oracle
監聽客戶端連線程序狀態的程序,輸出顯示為:“ora_pmon_ CKDB”
. Oracle
進行歸檔的程序,輸出顯示為:“ora_arc0_ CKDB”
. Oracle
進行檢查點的程序,輸出顯示為:“ora_ckpt_ CKDB
. Oracle
進行恢復的程序,輸出顯示為:“ora_reco_ CKDB”

/home/oracle>lsnrctl status

LSNRCTL for Linux: Version 10.2.0.2.0 - Production on 23-JUL-2009 14:11:53

Copyright (c) 1991,2005, Oracle. All rights reserved.

Connecting to (ADDRESS=(PROTOCOL=tcp)(HOST=)(PORT=1521))

STATUS of the LISTENER

------------------------

Alias                    LISTENER

Version                  TNSLSNR for Linux: Version 10.2.0.2.0 - Production

Start Date               07-MAY-2009 09:35:52

Uptime                   77 days 4 hr. 36 min. 0 sec

Trace Level              off

Security                 ON: Local OS Authentication

SNMP                     OFF

Listener Parameter File  /data/oracle/product/10.2.0/network/admin/listener.ora

Listener Log File        /data/oracle/product/10.2.0/network/log/listener.log

Listening Endpoints Summary...

 (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=AS14)(PORT=1521)))

Services Summary...

Service "CKDB" has 1 instance(s).

 Instance "CKDB", status READY, has 1 handler(s) for this service...

Service "CKDBXDB" has 1 instance(s).

 Instance "CKDB", status READY, has 1 handler(s) for this service...

Service "CKDB_XPT" has 1 instance(s).

 Instance "CKDB", status READY, has 1 handler(s) for this service...

The command completed successfully

“Services Summary”項表示Oracle的監聽程序正在監聽哪些資料庫例項,輸出顯示中至少應該有“CKDB”這一項。

檢查監聽程序是否存在:

[oracle@AS14 ~]$ ps -ef|grep lsn|grep -v grep

oracle   2954    1 0 May07 ?       00:01:17 /data/oracle/product/10.2.0/bin/tnslsnr LISTENER –inherit

在本節主要檢查相關的日誌檔案,包含:檢查作業系統的日誌檔案,檢查Oracle日誌檔案,檢查Oracle核心轉儲目錄,檢查Root使用者和Oracle使用者的email,總共四個部分。

# cat /var/log/messages |grep failed

檢視是否有與Oracle使用者相關的出錯資訊。

[oracle@AS14 ~]$ cat /data/oracle/admin/CKDB/bdump/alert_CKDB.log |grep ora-

[oracle@AS14 ~]$ cat /data/oracle/admin/CKDB/bdump/alert_CKDB.log |grep err

[oracle@AS14 ~]$ cat /data/oracle/admin/CKDB/bdump/alert_CKDB.log |grep fail

Oracle在執行過程中,會在警告日誌檔案(alert_SID.log)中記錄資料庫的一些執行情況:資料庫的啟動、關閉,啟動時的非預設引數;資料庫的重做日誌切換情況,記錄每次切換的時間,及如果因為檢查點(checkpoint)操作沒有執行完成造成不能切換,會記錄不能切換的原因;對資料庫進行的某些操作,如建立或刪除表空間、增加資料檔案;資料庫發生的錯誤,如表空間不夠、出現壞塊、資料庫內部錯誤(ORA600)等。定期檢查日誌檔案,根據日誌中發現的問題及時進行處理:

問題

處理

啟動引數不對

檢查初始化引數檔案

因為檢查點操作或歸檔操作沒有完成造成重做日誌不能切換

如果經常發生這樣的情況,可以考慮增加重做日誌檔案組;想辦法提高檢查點或歸檔操作的效率;

有人未經授權刪除了表空間

檢查資料庫的安全問題,是否密碼太簡單;如有必要,撤消某些使用者的系統許可權

出現壞塊

檢查是否是硬體問題(如磁碟本生有壞塊),如果不是,檢查是那個資料庫物件出現了壞塊,對這個物件進行重建

表空間不夠

增加資料檔案到相應的表空間

出現ORA-600

根據日誌檔案的內容檢視相應的TRC檔案,如果是Oraclebug,要及時打上相應的補丁

Listener日誌:$ORACLE_HOME/network/log

$ls $ORACLE_BASE/admin/CKDB/cdump/*.trc|wc -l

$ls $ORACLE_BASE/admin/CKDB/udump/*.trc|wc –l

如果上面命令的結果每天都在增長,則說明Oracle程序經常發生核心轉儲。這說明某些使用者程序或者資料庫後臺程序由於無法處理的原因而異常退出。頻繁的核心轉儲特別是資料庫後臺程序的核心轉儲會導致資料庫異常終止。

2.4.   檢查Root使用者和Oracle使用者的email

#tail –n 200 /var/mail/root

#tail –n 200 /var/mail/oracle

檢視有無與Oracle使用者相關的出錯資訊。

在本節主要檢查相關Oracle物件的狀態,包含:檢查Oracle控制檔案狀態,檢查Oracle線上日誌狀態,檢查Oracle表空間的狀態,檢查Oracle所有資料檔案狀態,檢查Oracle所有表、索引、儲存過程、觸發器、包等物件的狀態,檢查Oracle所有回滾段的狀態,總共六個部分。

SQL> select status,name from v$controlfile;

STATUS NAME

------- --------------------------------------------------------------------------------

       /data/oradata/CKDB/control01.ctl

       /data/oradata/CKDB/control02.ctl

       /data/oradata/CKDB/control03.ctl

輸出結果應該有3條以上(包含3條)的記錄,“STATUS”應該為空。狀態為空表示控制檔案狀態正常。

SQL> select group#,status,type,member from v$logfile;

   GROUP# STATUS TYPE   MEMBER

---------- ------- ------- -----------

        3        ONLINE /data/oradata/CKDB/redo03.log

        2        ONLINE /data/oradata/CKDB/redo02.log

        1        ONLINE /data/oradata/CKDB/redo01.log

        4        ONLINE /data/oradata/CKDB/redo04.log

        5        ONLINE /data/oradata/CKDB/redo05.log

        6        ONLINE /data/oradata/CKDB/redo06.log

6 rows selected

輸出結果應該有3條以上(包含3條)記錄,“STATUS”應該為非“INVALID”,非“DELETED”。注:“STATUS”顯示為空表示正常。

SQL> select tablespace_name,status from dba_tablespaces;

TABLESPACE_NAME               STATUS

------------------------------ ---------

SYSTEM                        ONLINE

UNDOTBS1                      ONLINE

SYSAUX                        ONLINE

TEMP                          ONLINE

USERS                         ONLINE

SJ1                           ONLINE

ADM_INDEX                     ONLINE

HOME_DATA                     ONLINE

HOME_INDEX                    ONLINE

PHOTO_DATA                    ONLINE

PHOTO_INDEX                   ONLINE

。。。。。。。

輸出結果中STATUS應該都為ONLINE

SQL> select name,status from v$datafile;

NAME                                              STATUS

-------------------------------------------------- -------

/data/oradata/CKDB/system01.dbf                   SYSTEM

/data/oradata/CKDB/undotbs01.dbf                  ONLINE

/data/oradata/CKDB/sysaux01.dbf                   ONLINE

/data/oradata/CKDB/users01.dbf                    ONLINE

/data/oradata/CKDB/sj.dbf                         ONLINE

/data/oradata/CKDB/HOME_DATA1.dbf                 ONLINE

/data/oradata/CKDB/HOME_INDEX1.dbf                ONLINE

/data/oradata/CKDB/PHOTO_DATA1.dbf                ONLINE

/data/oradata/CKDB/PHOTO_INDEX1.dbf               ONLINE

/data/oradata/CKDB/BLOG_DATA1.dbf                 ONLINE

/data/oradata/CKDB/BLOG_INDEX1.dbf                ONLINE

/data/oradata/CKDB/AUDIO_DATA1.dbf                ONLINE

/data/oradata/CKDB/AUDIO_INDEX1.dbf               ONLINE

/data/oradata/CKDB/VIDEO_DATA1.dbf                ONLINE

/data/oradata/CKDB/VIDEO_INDEX1.dbf               ONLINE

/data/oradata/CKDB/SYS_DATA1.dbf                  ONLINE

/data/oradata/CKDB/SYS_INDEX1.dbf                 ONLINE

/data/oradata/CKDB/ADM_DATA1.dbf                  ONLINE

/data/oradata/CKDB/ADM_INDEX1.dbf                 ONLINE

/data/oradata/CKDB/perfstat.dbf                   ONLINE

輸出結果中“STATUS”應該都為“ONLINE”。或者:

SQL> select file_name,status from dba_data_files;

FILE_NAME                                    STATUS

--------------------------------------------- ---------

/data/oradata/CKDB/users01.dbf               AVAILABLE

/data/oradata/CKDB/sysaux01.dbf              AVAILABLE

/data/oradata/CKDB/undotbs01.dbf             AVAILABLE

/data/oradata/CKDB/system01.dbf              AVAILABLE

/data/oradata/CKDB/sj.dbf                    AVAILABLE

/data/oradata/CKDB/perfstat.dbf              AVAILABLE

/data/oradata/CKDB/HOME_DATA1.dbf            AVAILABLE

/data/oradata/CKDB/HOME_INDEX1.dbf           AVAILABLE

/data/oradata/CKDB/PHOTO_DATA1.dbf           AVAILABLE

輸出結果中“STATUS”應該都為“AVAILABLE”

sql>select owner,object_name,object_type from dba_objects where status!='VALID' and owner!='SYS' and owner!='SYSTEM';

no rows selected

如果有記錄返回,則說明存在無效物件。若這些物件與應用相關,那麼需要重新編譯生成這個物件,或者:

SELECT owner, object_name, object_type FROM dba_objects WHERE status= 'INVALID';

SQL> select segment_name,status from dba_rollback_segs;

SEGMENT_NAME                  STATUS

------------------------------ ----------------

SYSTEM                        ONLINE

_SYSSMU1$                     ONLINE

_SYSSMU2$                     ONLINE

_SYSSMU3$                     ONLINE

_SYSSMU4$                     ONLINE

_SYSSMU5$                     ONLINE

_SYSSMU6$                     ONLINE

_SYSSMU7$                     ONLINE

_SYSSMU8$                     ONLINE

_SYSSMU9$                     ONLINE

_SYSSMU10$                    ONLINE

11 rows selected

輸出結果中所有回滾段的“STATUS”應該為“ONLINE”

在本節主要檢查Oracle相關資源的使用情況,包含:檢查Oracle初始化檔案中相關的引數值,檢查資料庫連線情況,檢查系統磁碟空間,檢查Oracle各個表空間使用情況,檢查一些擴充套件異常的物件,檢查system表空間內的內容,檢查物件的下一擴充套件與表空間的最大擴充套件值,總共七個部分。

SQL> select resource_name,max_utilization,initial_allocation,

 limit_value from v$resource_limit;

RESOURCE_NAME       MAX_UTILIZATION INITIAL_ALLOCAT LIMIT_VALUE

-------------------- --------------- --------------- ---------------

processes                       162       500            500

sessions                        168       555            555

enqueue_locks                   136      6930           6930

enqueue_resources               111      2660      UNLIMITED

ges_procs                         0         0              0

ges_ress                          0         0      UNLIMITED

ges_locks                         0         0      UNLIMITED

ges_cache_ress                    0         0      UNLIMITED

ges_reg_msgs                      0         0      UNLIMITED

ges_big_msgs                      0         0      UNLIMITED

ges_rsv_msgs                      0         0              0

gcs_resources                     0         0              0

gcs_shadows                       0         0              0

dml_locks                        76      2440      UNLIMITED

temporary_table_locks             26 UNLIMITED      UNLIMITED                                                 

transactions                     13       610      UNLIMITED

branches                          0       610      UNLIMITED

cmtcallbk                         3       610      UNLIMITED

sort_segment_locks                5 UNLIMITED      UNLIMITED

max_rollback_segments             11       610          65535

RESOURCE_NAME       MAX_UTILIZATION INITIAL_ALLOCAT LIMIT_VALUE

-------------------- --------------- --------------- ---------------

max_shared_servers                1 UNLIMITED      UNLIMITED

parallel_max_servers             16        80           3600

22 rows selected

LIMIT_VALU-MAX_UTILIZATION<=5,則表明與RESOURCE_NAME相關的Oracle初始化引數需要調整。可以通過修改Oracle初始化引數檔案$ORACLE_BASE/admin/CKDB/pfile/initORCL.ora來修改。

檢視當前會話連線數,是否屬於正常範圍。

SQL> select count(*) from v$session;

 COUNT(*)

----------

       29

select sid,serial#,username,program,machine,status from v$session;

SID   SERIAL#    USERNAME      PROGRAM       MACHINE     STATUS

---- ---------- ------------ ---------------------------- ------------ --------

  1  3                      oracle@xz15saledb (PMON)    xz15saledb  ACTIVE

  2  3                      oracle@xz15saledb (DBW0)    xz15saledb  ACTIVE

  3  3                      oracle@xz15saledb (DBW1)    xz15saledb  ACTIVE

  4  3                      oracle@xz15saledb (LGWR)    xz15saledb  ACTIVE

  5  3                      oracle@xz15saledb (CKPT)    xz15saledb  ACTIVE

  6  3                      oracle@xz15saledb (SMON)    xz15saledb  ACTIVE

  7  3                      oracle@xz15saledb (RECO)    xz15saledb  ACTIVE

  8   1                      oracle@xz15saledb (CJQ0)   xz15saledb  ACTIVE

  9   3                      oracle@xz15saledb (ARC0)   xz15saledb  ACTIVE

 10   3                      oracle@xz15saledb (ARC1)   xz15saledb  ACTIVE

 11 11319   ZK  AccPrtInv_svr@xz15tuxedo2 (TNS V1-V3)  xz15tuxedo2 INACTIVE

 13 48876   ZG          upload@xz15saleap (TNS V1-V3)  xz15saleap  INACTIVE

 17 20405   ZK   AccCreateRpt@xz15tuxedo1 (TNS V1-V3)  xz15tuxedo1 INACTIVE

 20 12895   ZK      OweScanSvr@xz15billdb (TNS V1-V3)  xz15billdb  INACTIVE

其中:SID 會話(session)ID號;

SERIAL# 會話的序列號,和SID一起用來唯一標識一個會話;

USERNAME 建立該會話的使用者名稱;

PROGRAM 這個會話是用什麼工具連線到資料庫的;

STATUS 當前這個會話的狀態,ACTIVE表示會話正在執行某些任務,INACTIVE表示當前會話沒有執行任何操作;

如果建立了過多的連線,會消耗資料庫的資源,同時,對一些“掛死”的連線可能需要手工進行清理。如果DBA要手工斷開某個會話,則執行:(一般不建議使用這種方式去殺掉資料庫的連線,這樣有時候session不會斷開。容易引起死連線。建議通過sid查到作業系統的spid,使用ps –ef|grep spidno的方式確認spid不是ORACLE的後臺程序。使用作業系統的kill -9命令殺掉連線)

alter system kill session 'SID,SERIAL#';

注意:上例中SID110(USERNAME列為空)的會話,是Oracle的後臺程序,不要對這些會話進行任何操作。

如果檔案系統的剩餘空間過小或增長較快,需對其進行確認並刪除不用的檔案以釋放空間。

[oracle@AS14 ~]$ df -h

Filesystem           Size Used Avail Use% Mounted on

/dev/sda5            9.7G 3.9G 5.4G 42% /

/dev/sda1            479M  16M 438M  4% /boot

/dev/sda2             49G  19G  28G 41% /data

none                1014M    0 1014M  0% /dev/shm

SQL> select f.tablespace_name,a.total,f.free,round((f.free/a.total)*100) "% Free"

 from

 (select tablespace_name, sum(bytes/(1024*1024)) total from dba_data_files group by tablespace_name) a,

(select tablespace_name, round(sum(bytes/(1024*1024))) free from dba_free_space group by tablespace_name) f

WHERE a.tablespace_name = f.tablespace_name(+)

order by "% Free";

TABLESPACE_NAME                    TOTAL      FREE    % Free

------------------------------ ---------- ---------- ----------

OPERATION_DATA                      1800       547        30

WAPWEB_DATA                          100        36        36

OPERATION_INDEX                      500       186        37

SYSTEM                              1024       515        50

SYSAUX                              1024       534        52

SALE8_TEMP                           100        62        62

SJ1                                  500       348        70

PERFSTAT                             500       356        71

……….

HOME_DATA                            100        77        77

SYS_INDEX                            100       100       100

VIDEO_INDEX                          100       100       100

VIDEO_DATA                           100       100       100

BLOG_DATA                            100       100       100

39 rows selected

如果空閒率%Free小於10%以上(包含10%),則注意要增加資料檔案來擴充套件表空間而不要是用資料檔案的自動擴充套件功能。請不要對錶空間增加過多的資料檔案,增加資料檔案的原則是每個資料檔案大小為2G或者4G,自動擴充套件的最大限制在8G

sql>select Segment_Name, Segment_Type, TableSpace_Name,

(Extents/Max_extents)*100 Percent

From sys.DBA_Segments

Where Max_Extents != 0 and (Extents/Max_extents)*100>=95

order By Percent;

no rows selected

如果有記錄返回,則這些物件的擴充套件已經快達到它定義時的最大擴充套件值。對於這些物件要修改它的儲存結構引數。

select distinct(owner) from dba_tables

where tablespace_name='SYSTEM' and

owner!='SYS' and owner!='SYSTEM'

union

select distinct(owner) from dba_indexes

where tablespace_name='SYSTEM' and

owner!='SYS' and owner!='SYSTEM';

no rows selected

如果記錄返回,則表明system表空間記憶體在一些非systemsys使用者的物件。應該進一步檢查這些物件是否與我們應用相關。如果相關請把這些物件移到非System表空間,同時應該檢查這些物件屬主的預設表空間值。

sql>select a.table_name, a.next_extent, a.tablespace_name

from all_tables a,

(select tablespace_name, max(bytes) as big_chunk

from dba_free_space

group by tablespace_name ) f

where f.tablespace_name = a.tablespace_name

and a.next_extent > f.big_chunk

union

select a.index_name, a.next_extent, a.tablespace_name

from all_indexes a,

(select tablespace_name, max(bytes) as big_chunk

from dba_free_space

group by tablespace_name ) f

where f.tablespace_name = a.tablespace_name

and a.next_extent > f.big_chunk;

no rows selected

如果有記錄返回,則表明這些物件的下一個擴充套件大於該物件所屬表空間的最大擴充套件值,需調整相應表空間的儲存引數。

在本節主要檢查Oracle資料庫備份結果,包含:檢查資料庫備份日誌資訊,檢查backup卷中檔案產生的時間,檢查oracle使用者的email,總共三個部分。

假設:備份的臨時目錄為/backup/hotbakup,我們需要檢查2009722日的備份結果,則用下面的命令來檢查:

#cat /backup/hotbackup/hotbackup-09-7-22.log|grep –i error

備份指令碼的日誌檔案為hotbackup-月份-日期-年份.log,在備份的臨時目錄下面。如果檔案中存在“ERROR:”,則表明備份沒有成功,存在問題需要檢查。

#ls –lt /backup/hotbackup

backup卷是備份的臨時目錄,檢視輸出結果中檔案的日期,都應當是在當天凌晨由熱備份指令碼產生的。如果時間不對則表明熱備份指令碼沒執行成功。

#tail –n 300 /var/mail/oracle

熱備份指令碼是通過Oracle使用者的cron去執行的。cron執行完後作業系統就會發一條Email通知Oracle使用者任務已經完成。檢視Oracle email中今天凌晨部分有無ORA-ErrorFailed等出錯資訊,如果有則表明備份不正常。

在本節主要檢查Oracle資料庫效能情況,包含:檢查資料庫的等待事件,檢查死鎖及處理,檢查cpuI/O、記憶體效能,檢視是否有僵死程序,檢查行連結/遷移,定期做統計分析,檢查緩衝區命中率,檢查共享池命中率,檢查排序區,檢查日誌緩衝區,總共十個部分。

set pages 80

set lines 120

col event for a40

select sid,event,p1,p2,p3,WAIT_TIME,SECONDS_IN_WAIT from v$session_wait where event not like 'SQL%' and event not like 'rdbms%';

如果資料庫長時間持續出現大量像latch freeenqueuebuffer busy waitsdb file sequential readdb file scattered read等等待事件時,需要對其進行分析,可能存在問題的語句。

SQL>SELECT SQL_TEXT FROM (SELECT * FROM V$SQLAREA ORDER BY DISK_READS)

WHERE ROWNUM<=5 desc;