第2回:実践・初めてのエラー対応

DBAへの道

皆さんこんにちは。株式会社システムエグゼ データベースソリューション本部の藤林です。
すっかり秋になり、過ごしやすい日々が続いておりますが、皆様いかがお過ごしでしょうか。食欲の秋ということで、体重増加が懸念されますので、皆様もご注意下さい。
前回に引き続き「DBAへの道」というタイトルで、今まで私がORACLE DBAになるために歩んできた過去の経験を、お話していきたいと思います。

ORA-600エラー発生!

ORACLEを経験されている方ならよくご存知のORA-600エラー。マニュアルで確認すると「内部エラー。 サポートへ連絡をして下さい」(Oracle8時点)となります。要は不慮のエラーが発生したということ。
似たようなエラーでORA-7445というのもあり、この2つのエラーが発生すると非常にやっかいで、長期戦に突入といった状況になります。
ORA-600をユーザプロセスで受けたのであれば、インスタンス自身には問題は生じません。ですが、バックグラウンドプロセスがこのエラーを受けると、 インスタンスダウンとなり、大変な問題となってしまいます。

この時はユーザプロセスがORA-600を受けたらしく、インスタンスには特に問題がありませんでした。
解決のため、まずはサポートに問い合わせるための資料採取を行います。
errorstack、systemstatedump....様々な資料を採取する必要があります。
ORA-600の場合、エラーに引数がありますので、過去のエラー発生状況を使用して、同じ問題が無いか確認を行います。その後サポートに問い合わせを行うのですが、当然内部エラーなので、なかなか回答を得られない状況です。
しかしながらお客様への説明が必要となりますので、何とか途中経過だけでもサポートより回答をもらい、第1次報告としてお客様へ報告を行います。

(この時はインスタンスに影響がなかったので、それほど大事にはなりませんでしたが、インスタンスダウンとなった際には、昼夜を問わず2時間置きに報告会を実施するとの事です。後に経験しますが、非常に大変でした)

新米の私は、指示された事をこなすだけで「いっぱいいっぱい」でしたが、何とか対応する事ができたと思います。

エラー分析と対策!そして新たな問題が…

前述の通り、ORA-600の場合エラーに引数があります。実はこの引数は、単純に数字の場合もありますが、C言語のコマンドだったりする場合もあります。
C言語がわかる人なら、トレースに出力されているCallStackを見れば何となく、何をやっている箇所でエラーが発生しているかわかるそうです。
何の仕事でもそうですが、専門職といっても幅広い知識が必要だと言うことが実感できました。やはり1にも2にも勉強ですね。

勉強といえば、自宅にLinux環境を構築した事と、毎日UNIX機をさわっている事で、UNIXに対しての作業は不安がなくなってきました。
こういう毎日の積み重ねがスキルとして蓄積されていくんだなあと実感しました。ORACLEデータベースの知識とUNIXの知識を少しずつ蓄積していく中で、 またしても大きな問題となる黒い影が潜んでいることを、このときは知る由もなかったのです。

現在担当しているサーバで一番大きなサーバはクラスタ構成という冗長化構成となっています。
ORACLEはOracle Parallel Server(OPS)というデータベース構造となっています。これは共有ディスクに配置した一つのデータベースに対して、複数のインスタンスからデータアクセスができる物です。
片方のインスタンスがダウンしても、もう片方のインスタンスが稼動するので、対障害性に強い構成となっています。Oracle9i以降はReal Application Clusters(RAC)という名前に変わり、更に進化し続けています。

監視チームより連絡が入りました。ORACLEのパフォーマンスが低下し、タイムアウトが続出しているという内容でした。
問題のサーバに接続し、セッションの状況、待機イベントの確認を行うと、多量の待機イベントが発生しCPUも90%を超える高負荷な状況となっています。
しかし、ひとつのセッションが止まっている状況ではなく、少しずつではありますが、処理は動いている状況でした。
お客様の判断により片方のインスタンスを停止すると、大量に発生していた待機イベントは減少し、縮退運転ながら普通に稼動するようになりました。
大量の資料を採取したので、日本ORACLEへの問い合わせを行いました。すぐに回答がでる事象ではありませんので、自分でも資料を元に調べる事にしました。
幸いORACLEのインターナルの資料が手元にありましたので調べ始めると、非常に難しい内容となってきました。

ORACLEと言えば読み取り一貫性(Consistent Read:CR)ですが、シングルインスタンスの時でも難しいのに、いきなりOPSではさらに訳がわからない状況ですので、 まずはシングルインスタンスではどうなっているかを確認する事から始めました。
読み取り一貫性を調べ始めると、ORACLE全体のロック機構にたどりつきました。ORACLEのロック機構は大きく分けると「ラッチ・ロック・エンキュー」の3つに分かれます。
これらの差は処理の重要度によりコストが違い、読み取り一貫性を確立するためには、これらのロックを駆使しているようです。OPSの場合は更にインスタンス間のロックが必要となってきます。
シングルインスタンスでも大変なのに、インスタンス間でもロックを管理しているなんて、ORACLEを開発した人ってどういう頭の構造をしているのか感心しました。

このロック機構を図にして、お客様へ定例会で説明をしました。
はっきり言って難しい内容なので、中々理解してくれませんでした。しかもまだお客様との信頼関係も出来ていないので、残念ながらあまり信用してくれていない感がありました。
しかしロックの機構を説明するだけでは、パフォーマンス低下の原因はわかりませんし、解決策も出せません。お客様としては早く原因究明をしたいとの事でしたので、これから現象再現のためのテストの日々が続く事となりました。

パフォーマンス低下の原因を探れ!

パフォーマンス低下の原因を探るべく、再現テストを実施する事となりました。
かなり大規模なシステムのため、たくさんの要員が必要となります。再現テストの環境の、他の試験などで利用されているため、マシンの確保も難しい状況です。
今回のパフォーマンス劣化は、重要課題という事で、優先順位をあげてもらい、夜間ではありますが、何とかマシンの確保ができました。
シミュレータを実行し、本番と近いトランザクションを再現させます。投入のスピードを速める事により負荷をあげ、事象を再現させるべく試みます。

負荷はあがってきて、CPU使用率も90%近くになってきました。 レスポンスも悪くなってきましたが、本番環境で発生した事象が再現できません。
次のシミュレータを準備し、再度チャレンジです。
・・・これらの作業を繰り返しましたが、残念ながら再現には至りませんでした。時間は既に午前0時をまわっています。

後日この結果をお客様へ報告しました。当然再現ができなかったので、再度スケジューリングをして再チャレンジとなりました。
しかし他の作業もスケジュールがありますので、すぐにマシン確保とはいきませんでした。本番環境で発生した事象および再現テストを行った際の資料を基に、日本オラクルのサポートへ依頼を行いました。藁をも掴む思いです。
しかし残念ながら、有用となる情報を得ることはできませんでした。数日が経過しても、再現テストを実施するテスト環境の確保は難しかったため、本件は一旦、次回再現時に採取する資料を決め、再現待ちのステータスとなりました。
解決はしていないものの、とりあえずひと段落の心境です。

話は変わって、ORACLEには全ての変更作業が記録されるREDOログファイルがあります。
今こそLogMiner(確か8iから実装)というREDOログファイルの変更記録を確認するツールがありますが、 Oracle8時代ではこのような便利なツールがなく、ORACLEさんより入手したopコード(オペコードと読む)を使用して、REDOログの変更記録を手動で確認しました。
何のために使用するかですが、例えばORA-600、ORA-7445などが発生した際に、直前にどのような変更作業を行っていたかを確認し、対策を立てるためです。最新の11gでは、DBA作業がかなり簡単になった感があります。
昔は(おじさんぽい口調で恐縮ですが)色々手動で行う事によって、自分の知識の肥やしになったかなと思いますが、 やはり便利なツールを駆使して、障害対応の時間を短縮する事が、お客様にとっても有益だと思います。
しかし、行き過ぎはよくない結果を生むことにもなるので、時間短縮も節度ある考えのもと、実行したいと思います。