常駐先で、ORACLEデータベースの管理やってます。ORACLE Platinum10g、データベーススペシャリスト保有してます。データベースの話をメインにしたいです

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がどう絡むのかを理解して、どう対応するか決めるべきでした。

・負荷テストを本番想定で行っていなかった
 接続がピークとなる時間帯を想定して、負荷テストを行うべきでした。
 そうすれば、今回の設計ミスも見つけられたでしょう。
 ただ、時間、環境や人といったリソース的な制約もありました。
 そういったことを踏まえて、もう少し情シスの方と話すべきでした。
 想定負荷を掛けるツールが存在するので、そういうものを使用するとか、いくらでも代案はあったのですから。

Comment(3)

コメント

ほしゅいん

失敗事例ありがとうございました。
私の業務には含まれていませんが、
私の見えないところでは関わっていますし
何より思考の過程と振り返りが応用できそうでした。

貴重な情報ありがとうございました。

湯二

ほしゅいんさん、コメントありがとうございます。

失敗してから気付く、運用してみて気付く、、、
そうやって成長していってます。
ですが、障害のないデータベースを作るべきだと思います。

湯二

コラムを読んだ方から、共有サーバ接続にすればいいのでは、という意見をいただきました。

このコラムに登場したデータベースは、専用サーバ接続でクライアントとデータベースサーバを接続していました。

専用サーバ接続だと、1接続あたり、1サーバプロセスという対応になります。
それが、共有サーバ接続だとn接続あたり、1サーバプロセスという対応になります。
共有サーバ接続のほうが、サーバプロセスの節約になり、メモリ不足も解消できます。

そういったことから、共有サーバ接続で対応という案もありました。
ただ、共有サーバ接続だと、以下の点を考慮することが必要です。

・ディスパッチャによるオーバヘッド
・ソート処理をSGAで行うのでメモリの再設計が必要

そういったことを考慮し、今まで通り専用サーバ接続で行くことになりました。

データベースサーバをリプレースするまで、メモリ(SGA、PGA)は変更前の状態に戻し、専用サーバ接続でしばらく運用していました。

コメントを投稿する