2017年1月21日土曜日

ORACLEの32ビット版はメモリサイズに制限がある!

ORACLEの知識だけが先行して、失敗したことがあります。
受発注管理システムに携わっていたころの話です。
コールセンターで、お客さんからの電話を受けて、商品の注文を入力するシステムです。
データベースのパフォーマンスが悪く、電話を受けてからの受発注業務に支障が出ているとのこと。
その会社の情報システム部と話した結果、全体的に遅いので個々のSQLをチューニングするよりは、データベースの構成を
見直したほうが良いということになりました。
■現状調査
データベースを構築した方は既にいませんでした。
取りあえず私は現状の環境調査から始めました。
環境は、
 ・サーバメモリは4GByte
 ・OS:windows server 32bit
 ・ORACLE:10g 32bit
調査の結果、ORACLEで必要なメモリが足りず、パフォーマンスが悪いようです。
ここで、ざっくりと専門用語の説明を。
ORACLEのメモリはSGAとPGAで構成されています。
SGAにはSQL解析結果をもとにした実行計画や、よく使用されるデータをキャッシュしています。
PGAは、大量のソート処理を行うために確保されています。
SGA、PGA合わせて、500MByte確保されていて、処理量とデータ量に対して足りていませんでした。
メモリ不足からディスクへのアクセスを行っていることが、パフォーマンス遅延の原因のようでした。
■環境変更
そこで、以下のようにORACLEで確保しているメモリを変更しました。
M0
32bitOSなので、ORACLE.exeという一つのプロセスに対してメモリを2GByteまでしか使えません。
本番環境にて、ORACLEが使用できるメモリサイズを500MByteから1900MByteまで拡張しました。(SGA、PGA合わせて)
残り100MByteは、ORACLEのバックグラウンドプロセスなどの予備用に取っておきました。
作業自体は問題なく完了しました。
■負荷テスト
負荷テストをどうするか話し合いました。
テスト環境はありません。本番環境でテストすることになりました。
テストするとなると、システムを停止する必要があります。
日中にシステム停止することは、コールセンターなので無理です。
夜間にテストすることになりました。
そのテストも、夜間バッチが動かない間に行う必要があるとのことで、1時間くらいで出来る内容となりました。
情シスの方が5人くらいで同時に使って、パフォーマンスと動作に問題ないことを確認しました。
実際は、コールセンターの方は40人位いるので、それ位の人数でテストするべきですが、、、
■運用
テレビCMを打った後、コールセンターの電話が一斉に鳴りだします。
そのタイミングで、受発注システムを介したデータベース接続が行われます。
CMを打った直後が、データベースに一番負荷がかかる時間帯ということになります。
■問題発生
画面に接続できないです~
04
データベース接続が出来ず、受発注システムの画面を表示出来ない、との連絡が。
慌ててコールセンターに駆けつけると、コールセンターの方が電話片手に、注文を受け付けることが出来ず混乱状態です。
データベースに接続できない端末は一つだけではなく、沢山ありました。
まずは、ネットワークの問題かと思い、データベースサーバにpingしてみました。
応答がありました。
ORACLEのリスナーも起動しています。
端末からtnspingも通ります。
何より、接続できている端末がいます。
原因が分かりません。
こうしている間にも、CMを観たお客さんからの電話は鳴り続け、商品の注文が取れないよう状態が、、、
そうこうしているうちに、情シスの方から
どうにかしてください!!
08
■復旧
そこで、我に返りました。
こういうときは、原因追求より復旧優先です。
メモリ設定を変更前の状態に戻せば、正常な状態に戻るはずです。
データベース停止の許可を貰い、復旧作業を行いました。
元の状態に戻ったデータベースは、システムからの接続を受け付けるようになりました。
■原因調査
その後、データベースサーバのリスナーログを確認すると、
「ORA-12518: TNS: リスナーはクライアント接続をハンドオフできませんでした」
というエラーが出力されていました。
メモリ不足で、新規接続用のメモリが確保できない状態だったのです。
調査の結果、以下のことが分かりました。
windowsのORACLEはORACLE.exeプロセスに、以下のメモリを保持しています。
・SGA
・PGA
・サーバプロセスのメモリ
・バックグラウンドプロセスのメモリ
サーバプロセスは、端末からデータベースサーバにセッションが確立されると生成されます。
つまり、サーバプロセスはコールセンターの人がシステムにどんどん接続すると、どんどん増えていきます。
32bitOSは、1プロセス当たり2GByteまでという制限があります。
つまり、ORACLE.exeプロセスは2GByteより大きくなれないのです。
<<障害発生までの流れ>>
CMが流れた。

注文が来た。

コールセンターの方が、受発注管理システムを起動し、データベースへの接続が徐々に増えた。
※サーバプロセスが使用するメモリがどんどん増えた。

ORACLE.exeプロセスが2GByteの限界にぶつかり、それで新規接続が出来なくなった。
つまり
・windows版ORACLEの特徴である接続セッションが増加するとORACLE.exeのメモリサイズが肥大することを考慮してなかった。。
・通常業務開始後、接続数の増加と共に限界の2GByteを超え、ORA-12518エラーが発生。
・一定人数までしかシステムに接続できなかった。
激狭の人気ラーメン店に客が押し寄せて、早々に店じまいした感じでしょうか。
後ろで2時間並んでた客は激怒です。
10
変更前の500MByteだったときは、サーバプロセス用のメモリに余裕があり、コールセンターの方が全員接続できたのでしょう。
遅いながらも。
パフォーマンスが悪い問題も残りましたが、今後コールセンターの人が増えた時に、メモリ不足でシステムに接続できなくなる
ことが起こる可能性が出てきました。
対策として、64bitOSに刷新し、メモリを10GByte確保しました。
■振り返り
勉強不足が引き起こした障害です。
・ORACLEの知識だけで対応しようとしたのが問題でした。
 ORACLEだって所詮はOSの上に乗っかているものの一つです。
 ORACLEとOSがどう絡むのかを理解して、どう対応するか決めるべきでした。
・負荷テストを本番想定で行っていなかった
 接続がピークとなる時間帯を想定して、負荷テストを行うべきでした。
 そうすれば、今回の設計ミスも見つけられたでしょう。
 ただ、時間、環境や人といったリソース的な制約もありました。
 そういったことを踏まえて、もう少し情シスの方と話すべきでした。
 想定負荷を掛けるツールが存在するので、そういうものを使用するとか、いくらでも代案はあったのですから。

0 件のコメント:

コメントを投稿