LoginSignup
3
2

More than 5 years have passed since last update.

Python OracleアラートログのORAエラー傾向分析をしてみる

Last updated at Posted at 2018-06-26

Oracleアラートログとは

Oracleはアラートログに様々な情報を記録しています。

以下、主にアラートログに出力される情報です。

  1. DB稼動している際に発生したエラー情報 ※発生したすべての内部エラー(ORA-00600、ORA-7445)、デッドロック・エラー(ORA-00060)など
  2. DB起動情報
  3. DB停止情報
  4. 構成変更(データファイル追加など)

アラートログは以下のように記録されます。※サンプルです

Mon Jun 25 11:47:21 2018
ORA-01555 caused by SQL statement below (SQL ID: abcb02h7f6vppt, Query Duration=7498 sec, SCN: 0x08c6.000bffaa):
SELECT  "COL1", "COL2", "COL3", "COL4" FROM "TBLABC" WHERE  "TBLABC.COL1" = :B1 AND ・・・・

Mon Jun 25 12:45:35 2018
ORA-07445: exception encountered: core dump [ktiXcbDump()+220] [SIGSEGV] [Address not mapped to object] [0x000000020] [] []
ORA-00600: internal error code, arguments: [xxxx], [0], [0], [], [], [], [], []
ORA-03135: connection lost contact

上記ログの内容は、以下2つのORAエラーが発生しています。

・2018年6月25日 11時47分21秒
  ORA-01555「スナップショットが古すぎます」がエラーが発生。
   (SQL_ID(SQLを識別するID)は、[abcb02h7f6vppt] )

・2018年6月25日 12時45分35秒
  ORA-07445、ORA-00600、ORA-03135のエラーが同じ時刻に発生しています。

ORAエラーが発生したかを確認する際、アラートログでORAで検索して時間を確認することになります。

アラートログを分析することで、事前になにか対策ができないのかをできたらいいなと思い、
以下のスクリプトを作成しました。

1.DBアラートログ加工
2.月別にORA-エラー発生件数を見える化

※本投稿で使用するアラートログは投稿用に作成していますのでご了承ください

1.DBアラートログ加工

やりたいことは、アラートログの出力はORAエラー発生時刻とORAエラーが出力されている行が違うので、
エラー発生時刻とORAエラーを1行にします。

image.png

アラートログを加工してCSVにするpython スクリプト

alerttocsv.py
import datetime
import re


def alertlog_to_csv(alertlog):

    filepath = r"'"+ alertlog + "'"
    filepath = filepath.replace("'","")

    csvpath = filepath + '.csv'
    print(filepath)
    #Oracle DBアラートログを読込み
    with open(filepath,'r',errors='ignore' ,encoding='utf-8') as f:

        lines = f.readlines()

    #CSV出力
    with open(csvpath,'w') as csvf:

        #CSVヘッダー出力
        s = "STIME,ORA-ERROR,ERROR DESCRIPTION" + "\n"
        csvf.writelines(s)

        #DBアラートログは運用によっては、時間が最初にない可能性があるのでダミー日付をいれる
        t = datetime.datetime.strptime('2018-Jan-01 00:00:00', '%Y-%b-%d %H:%M:%S').strftime('%Y-%m-%d %H:%M:%S')

        #1行読込み
        for linecr  in lines:

            #改行コードを取る
            line = linecr.rstrip()

            #時間を取得
            strdate = line[len(line)-4:len(line)]  + '-' + line[4:7] + '-' + line[8:10] + ' ' + line[11:19]  

            #先頭4文字を取得
            ora = (line[0:4])

            #日付チェック
            try:
                #日付の場合、変数 t に日付をいれる
                t = datetime.datetime.strptime(strdate, '%Y-%b-%d %H:%M:%S').strftime('%Y-%m-%d %H:%M:%S')

            except:
                #こっちは日付以外の場合

                #ORA が含まれている場合、csvファイル書き込み対象
                if ora == 'ORA-':

                    #ORA-xxxxx で csvに区切りたいので 「:」 で区切る
                    oraerr= line[:line.find(":")]

                    #ORAエラーコード取得  
                    oraerr= line[:line.find(":")]

                    #時間 , ORA-エラー , エラー内容を1行にする
                    s = (t + ',' + oraerr + ','  + '"' +  line[line.find(":")+1:].replece('"','""') + '"' + "\n") 

                    #CSV出力
                    csvf.writelines(s)


if __name__ == '__main__':

    #アラートログ名を入力
    print ('====== Enter alertlog  =====')
    alertlog = input('>  ')

    alertlog_to_csv(alertlog)

pythonスクリプト実行時に、アラートログ名を入力します。
スクリプト実行すると、アラートログからcsvファイルが作成されます。
※csvファイル名は、アラートログ名に「.csv」として作成します

例) alert_orcl.log の場合、 alert_orcl.log.csv として作成されます

- 作成されたサンプル

 「2.月別にORA-エラー発生件数を見える化」で動作確認される場合のサンプルです。
  また、本投稿ではこのcsvを使用しております。

alert_orcl.log.csv
STIME,ORA-ERROR,ERROR DESCRIPTION
2018-02-19 13:01:01,ORA-00600,"internal error code"
2018-02-25 09:33:10,ORA-01555,"abc02h7f6vppt, Query Duration=4263 sec, SCN: 0x08c7.b8bcc363):"
2018-02-25 22:20:11,ORA-01653,"unable to extend table scott.TBLA by 8192 in tablespace TS"
2018-02-25 23:43:32,ORA-01654,"unable to extend index scott.IDX_A_1 by 16 in tablespace TSI"
2018-02-25 21:20:11,ORA-01653,"unable to extend table scott.TBLB by 8192 in tablespace TS"
2018-02-25 22:43:32,ORA-01654,"unable to extend index scott.IDX_B_1 by 16 in tablespace TSI"
2018-02-26 02:26:32,ORA-00060,"Deadlock detected"
2018-02-26 02:27:32,ORA-00060,"Deadlock detected"
2018-02-28 12:33:10,ORA-01555,"abc02h7f6vppt, Query Duration=3600 sec, SCN: 0x08bf.b8bcc823):"
2018-02-28 13:11:10,ORA-01555,"abc02h7f6vppt, Query Duration=4101 sec, SCN: 0x08bf.dra3f8dd):"
2018-02-28 13:22:10,ORA-01555,"abc02h7f6vppt, Query Duration=3703 sec, SCN: 0x08bf.9ui3b834):"
2018-02-28 13:34:10,ORA-01555,"abc02h7f6vppt, Query Duration=4767 sec, SCN: 0x08bf.84a3b823):"
2018-03-26 01:12:12,ORA-00060,"Deadlock detected"
2018-03-26 02:01:34,ORA-00060,"Deadlock detected"
2018-04-20 11:01:01,ORA-00600,"internal error code"
2018-04-26 01:12:12,ORA-00060,"Deadlock detected"
2018-04-26 02:01:34,ORA-00060,"Deadlock detected"
2018-05-19 13:01:01,ORA-00600,"internal error code"
2018-05-25 09:33:10,ORA-01555,"7zaxmbuwgvgsn, Query Duration=3121 sec, SCN: 0x08bf.b8bcc732):"
2018-05-25 21:19:11,ORA-01653,"unable to extend table scott.TBLA by 8192 in tablespace TS"
2018-05-25 22:20:11,ORA-01653,"unable to extend table scott.TBLB by 8192 in tablespace TS"
2018-05-25 23:43:32,ORA-01654,"unable to extend index scott.IDX_A_1 by 16 in tablespace TSI"
2018-05-25 23:52:32,ORA-01654,"unable to extend index scott.IDX_B_1 by 16 in tablespace TSI"
2018-05-25 23:55:32,ORA-01654,"unable to extend index scott.IDX_A_2 by 16 in tablespace TSI"
2018-05-26 02:26:32,ORA-00060,"detected"
2018-05-26 02:27:32,ORA-00060,"Deadlock detected"
2018-05-28 12:33:10,ORA-01555,"abc02h7f6vppt, Query Duration=10909 sec, SCN: 0x08bd.379e854a):"
2018-05-31 13:11:10,ORA-01555,"abc02h7f6vppt, Query Duration=10845 sec, SCN: 0x08bd.3973d944):"
2018-05-31 13:22:10,ORA-01555,"abc02h7f6vppt, Query Duration=5034 sec, SCN: 0x08bd.3fb8eaf1):"
2018-05-31 14:11:10,ORA-01555,"abc02h7f6vppt, Query Duration=9187 sec, SCN: 0x08bc.59b143ad):"
2018-05-31 15:34:10,ORA-01555,"abc02h7f6vppt, Query Duration=3940 sec, SCN: 0x08bc.5c97c1b0):"
2018-06-26 02:26:32,ORA-00060,"Deadlock detected"
2018-06-26 02:27:32,ORA-00060,"Deadlock detected"

2.月別にORA-エラー発生件数を見える化

1.で作成されたCSVファイルを読込み、月別にORAエラーの傾向を確認します

実行するとcsvファイル名をきかれるので、ファイル名を入力して処理を実行。

alertmonth.py
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import datetime
import numpy as np
from matplotlib.ticker import *

def alertcsv_to_year(csvfile):

    csvpath = r"'"+ csvfile + "'"
    csvpath = csvpath.replace("'","")

    #1.Oracle DBアラートCSVファイルを読込む
    dfcsv = pd.read_csv(csvpath)

    #2.インデックス列をSTIMEに設定
    dfcsv.set_index('STIME',inplace=True)

    #3.日付データ(文字型)を yyyy-mm 形式にして格納
    dfcsv.index = dfcsv.index.map(lambda x: datetime.datetime.strptime(x[0:7],"%Y-%m"))

    #4.get_dummies を使用して ダミー変数を作成
    dfdummy = pd.get_dummies(dfcsv["ORA-ERROR"])

    #5.yyyy-mm形式にした集計キーで、Oraエラーの数を数える
    df=dfdummy.groupby(['STIME']).sum()

    #6.棒グラフと日付は相性が悪いので、数字に変換
    df.index = df.index.map(lambda x: x.month)

    #表示設定
    fig = plt.figure(figsize=(8, 6))
    plt.style.use('ggplot')
    ax1 = fig.add_subplot(1,1,1)

    #棒グラフで表示
    df.plot(kind='bar',ax =ax1)

    #書式設定
    plt.title("ORA ERROR COUNT (month)", fontsize=12)   
    plt.xlabel("month", fontsize=12)
    plt.ylabel("count", fontsize=12)
    plt.tick_params(labelsize=12)

    plt.show()

if __name__ == '__main__':

    #csvファイル名を入力 (絶対パス or 相対パス)
    print ('====== Enter csv file  =====')
    csvfile = input('>  ')

    alertcsv_to_year(csvfile)

pythonスクリプトを実行するとcsvファイル名をきかれるので、ファイル名を入力して処理を実行。

※pythonスクリプトの実行方法詳細は、以下を参照ください
 ・Windows環境でPythonスクリプト(.py)の実行方法

image.png

月別のORAエラー件数のグラフができた!
image.png

グラフからは、2月、5月がORAエラーが多い傾向にあります。
※この傾向分析(日別、時間別分析)については次回、投稿します。

月別にORA-エラー発生件数を見える化のコードの説明

csvから取込んだデータは、ORAエラー発生時間、ORAエラー番号になります。
このままではグラフ化できないので、月別にORAエラー別に発生件数を集計します。
(集計方法はDataFrameのgroupbyを使用)

1.Oracle DBアラートCSVファイルを読込む
   csvから取込んだデータは、ORAエラー発生時間、ORAエラー番号が並んでいます。
   このデータを加工して、月別のORAエラー件数を集計します。

   以下、csvがDataFrameに格納されているイメージです

      import pandas as pd
      df=pd.DataFrame([
              ['2018-05-29 10:00:00','ORA-00001'],
              ['2018-05-29 11:00:00','ORA-00020'],
              ['2018-06-25 12:00:00','ORA-00060'],
              ['2018-06-26 18:00:00','ORA-00001'],
              ['2018-06-27 19:00:00','ORA-00020']
              ]
              ,columns=['STIME','ORAERROR'])

   image.png

2.インデックス列をSTIMEに設定
   STIMEをインデックスにする理由として3.で日付変換をかけるから実施

    df.set_index('STIME',inplace=True)

  image.png

3.日付データ(文字型)を yyyy-mm 形式にして格納
   インデックスを日付形式に変換します。ここでは、yyyy-mm と変換します。
   ⇒月単位で集計するための前準備

      import datetime
      df.index = df.index.map(lambda x: datetime.datetime.strptime(x[0:7],"%Y-%m"))

   image.png

4.get_dummies を使用して ダミー変数を作成
   ダミー変数を作成して、ORAエラーを展開します。

    dfdummy = pd.get_dummies(df["ORAERROR"])

   image.png

5.yyyy-mm形式にした集計キーで、Oraエラーの数を数える
   インデックス[STIME]はyyyy-mm形式に変換しているので、
   STIMEで集計すれば、月別のORAエラー件数が算出できます。

      df=dfdummy.groupby(['STIME']).sum()

   image.png

6.棒グラフと日付は相性が悪いので、数字に変換
   pandasの棒グラフでx軸が日付型のデータだと、思うように表示されないので数字に変換してます。

      df.index = df.index.map(lambda x: x.month)

   image.png

  ※7.で加工したDataFrameを棒グラフで表示してます

OracleアラートログのORAエラー傾向分析した分析と考えられる対策案

本投稿では月別の分析を実施しました。次回投稿では日別、月別でORAエラー分析を行って対策も考えてみました。

以下投稿を参照ください

(続き)OracleアラートログのORAエラー傾向分析

補足.アラートログの日付書式が変更

Oracle12R2 からはアラートログの日付の表示形式が変更されておりますので
本ツールは、12R1以前のアラートログで動作するものとなります。

http://otndnld.oracle.co.jp/ondemand/od12c-oct2016/03_DB12201_coretech_InstallUpgradeCompati_forOTN_v2.4.pdf

※P41 「ログ、トレース出力の時間表記の変更」参照ください
3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2