rm /blog

IT系技術職のおっさんがIT技術とかライブとか日常とか雑多に語るブログです。* 本ブログに書かれている内容は個人の意見・感想であり、特定の組織に属するものではありません。/All opinions are my own.*

【障害記録】No.9:副問い合わせが一意にならずにシステムエラー

自分が体験したシステム障害を紹介してトラウマを抉り返す自虐コーナー
※特定避けるため一部脚色・変更しているが、大体ほぼ実体験。

障害No障害分類No
(自分用)発生分類
アプリ/データ/ミドル/ハード案件名個人的ヤバイ度
(5段階評価)

9 A アプリ 副問い合わせが一意にならずにシステムエラー ★★☆☆☆

 


 

 

発生日時 2017/01某日 解決日時 2017/01某日 発見者 お客さん 対応者 原因者 俺ではない!(笑)
障害の詳細内容 まぁありがちな話(本来あってはならないのだが)である。
この記事に似た事例を載せたので参考にしていただきたい。
ただこ上の記事に書いた内容の発端は本件ではない。

とあるテーブルAとBがあり、ざっくり、Aが「親」Bが「子」のテーブルだとする。
で、以下のようにデータが入っているとする。
(★がついているのはKEY項目)

■テーブルA(TABLE_A)
★NoMemo
1 メモです。
2 メモ2です。
3 メモ3です。

■テーブルB(TABLE_B)
★No★SubNoMemo
1 1 メモ1の1です。
2 1 メモ2の1です。
2 2 メモ2の2です。

このとき、以下のようなSQLを投げるとする。
select
  TABLE_B.No
 ,TABLE_B.SubNo
 ,TABLE_B.Memo
from TABLE_B
where TABLE_B.No = :TEST_NO -- ←画面で指定する条件だとする
order by
  TABLE_B.No
 ,(select length(TABLE_A.Memo)
   from TABLE_A
   where TABLE_A.No = TABLE_B.No
  )

赤太字部分はソートの項目指定になっているが、
B自身の項目ではなく、
Bから見たときの親テーブルであるAに依存しており、
要するに副問い合わせになっている。
ただこのSQLは全体として、
青太字の部分までしか条件が入らないので、Bのレコードを一意に特定できない。
(No=1なら偶然Bは1レコードになるが、No=2だとBは2レコードになる)
で、その前提で赤太字部分を見ると、
確かにAを見る分には一意になる(AのKEYはNoだけだから)が、
SELECTの主テーブルであるB自体が一意に特定できてないので、
青太字の条件によっては赤太字の結果が複数レコードひっかかり、
結果的にソート順指定として成立しないことがある。

実際見つけられたときも
「検索したときシステムエラーになるのとならないのがある」
という内容だった。
↑の例でいっても、
No=1は問題なく動作するが
No=2は動作しない⇒実行すると「ORA-01427: 単一行副問合せにより2つ以上の行が戻されます」が発生する。
で、No=2のデータを検索されて落ちた、と。
対応内容・経緯等 単純なPGバグ(テーブルの主キーを捉えられていない)なので、修正してリリースして終了。
他に特にいうことない。
実は本番稼働後に発生した課題ではなく、
稼働前のテスト中にお客さんがテストして発生した案件だったので、
あくまでテスト中の課題として片づけた。
(まあ、「なんで今更こんなの出るの?(^^;」とは言われたが)
反省点・あとがき 最近出会う協力会社さんの人は、なんかどうもこの辺の意識が緩いというか、
テーブルを見るときに、仕様に基づかず、なぜか自分なりの考えで参照しようとするというか、
そういうことする人が多い。
テーブルにきちんとキー項目が設定されてるんだからそれちゃんと見ればいいだけの話なんだが。
アプリ仕様上どうしてもキーまで指定できないんだったら(仕様の検討は必要だが)MAXにするとかCOUNTとるとか
もしくは発生してもアプリ側で例外措置をちゃんととるとか(まあ例外起きるの知ってるくらいなら仕様検討するだろうが)
少なくともアプリが困らない(今回のようにシステムエラーを起こさない)範囲で考慮をしておけばいい。
「テーブルのキーを見ない」という大前提がある中で、それにより起こりうる弊害が意識できていない。
自分で死ぬ隙を作っておいて「死ぬべくして死にました!」って笑い話にもならんぞ。。
この件は、「落ちてくれた」から異常が起きていることが非常にわかりやすかったけども、
キーの指定が足らないがゆえに明細が重複して表示される等のケースも経験しており、
そういうのも含めてなんでこういう実装をしてしまうのか正直個人的には理解できないのである。

まあ、自身が担当したり設計したりした機能でないと、
「普通この項目で一意になるから内部的な条件はこれでいいよ」
ってお客さんに相談もせず勝手な判断で作り込んでしまう人は確かにいる(俺の周りにもいる…俺ではないぞ!w)
また、業務的なキーと論理的なキーが一致しないケースも中にはある(「将来的な拡張性を加味して…」とかね)
これはそれとは違くて、設計当初から決まっていたキーをちゃんと指定してないことにより起きた問題だから
本当にただのPGバグなだけなのだが。
「ちゃんとキー項目を見る」というのは当たり前だが非常に大切なことである。
俺は一応普段から気を付けているつもりだが、
こういう件を踏まえてぜひとも今後に生かしていかねばなるまいと改めて感じたのである。