障害対応から学ぶ推論手法入門

## はじめに

みなさん、推論してますか？

普段は何気なくやっているかもしれませんが、エラーログ調査や障害対応の場面ではそのスキルが大いに試されます。
今回は、データベースの例を中心に「論理的推論手法」について記載します。

## 1. 事実 × 推論 = 仮説

目の前にある**事実**を元に、**推論**を行い、**仮説**を立てます。

**例：**
- **事実：** アプリケーションがデータベースに接続できない
- **推論：** エラーログに「too many connections」と出ているので、接続数が上限に達している可能性が高い
- **仮説：** 接続数上限に達したため、アプリケーションが接続できない

推論手法自体は、新たな情報を生み出すのではなく、既存の情報を整理・分析して結論や仮説を導くプロセスです。
情報量が増えるかどうかは、仮説を検証する過程で新たなデータ収集や観察を行うかによります。

#### 要点
1. 事実をしっかり捉え、適切な推論を行うことが大切です
2. また、**観察を通して正しい事実を定義する重要性**も忘れてはいけません
3. 誤った事実に基づくと、誤った結論に導かれてしまいます
4. エラーログやシステムの状態を正確に確認し、確かな情報を元に推論しましょう

これらの基本を押さえた上で、次に推論手法の種類について詳しく見ていきましょう。

## 2. 十分条件と必要条件

推論を行う際、**十分条件**と**必要条件**を理解しておくと、論理の精度が高まります。

### 十分条件（A ⇒ B）
Aが成り立てばBが必ず成り立つ。


**例：**
- **十分条件：** データベースサーバーが停止していると、接続は必ず失敗する

**図解**
```mermaid
flowchart LR
    A[データベースサーバーが停止している] --> B[接続は必ず失敗する]
```

### 必要条件（B ⇒ A）
Bが成り立つためにはAが必要。

**例：**
- **必要条件：** 接続が成功するためには、
    1. データベースサーバーが起動している
    2. ネットワークが正常に機能している
    3. 認証情報が正しい
    4. ファイアウォールが接続を許可している


**図解**
```mermaid
flowchart LR
    B[接続が成功する] --> A[データベースサーバーが起動している必要がある]
    B --> C[ネットワークが正常に機能している必要がある]
    B --> D[認証情報が正しい必要がある]
    B --> E[ファイアウォールが接続を許可している必要がある]
```

これらはそれぞれが**必要条件**で、一つでも欠けると接続は成功しません。この違いを意識することで、見落としを減らせます。


十分条件と必要条件の違いを理解したところで、具体的な推論手法を学んでみましょう。

## 3. 推論手法いろいろ

### 演繹法

**一般的なルールから特定の結論を導く方法**です。

三段論法とも呼ばれ、次のような形式をとります。
- **前提1：** すべてのAはBである
- **前提2：** CはAである
- **結論：** したがって、CはBである

**例：**
- **前提1：** 接続数が上限に達すると、"too many connections" エラーが発生する
- **前提2：** 現在、"too many connections" エラーが発生している
- **結論：** したがって、接続数が上限に達している

**図解**
```mermaid
flowchart TD
    A[接続数が上限に達するとエラーが発生する]
    B[too many connections エラーが発生している]
    A --> C[接続数が上限に達している]
    B --> C
```

#### 要点

1. 前提が真であれば結論も必ず真になります
2. **既知の一般的なルールや法則を具体的なケースに適用する際は特に有効です。**
3. システムの仕様やドキュメントに基づいて問題の原因を特定するときに役立ちます
4. 既存の前提から論理的に結論を導いており、新しい情報は生まれません

#### 注意点
前提が正しければ結論も正しいですが、前提に誤りがあると結論も誤ります。
前提の偏りや飛躍がないか、慎重に確認しましょう。

**注意点の例：**

前提の解像度が低いまま推論を進めてしまうことがあります。

**例：**
- **前提1：** サーバーに問題があるとアプリケーションが動かない
- **前提2：** アプリケーションが動かない
- **結論：** したがって、サーバーに問題がある

この推論では、アプリケーションサーバーとデータベースサーバーの区別がついておらず、他にも「アプリケーションが動かない理由」が存在する可能性を無視しています。

**図解**
```mermaid
flowchart TD
    A[サーバーに問題があるとアプリケーションが動かない]
    B[アプリケーションが動かない]
    A --> C[サーバーに問題があると結論づける]
    B --> C
```

このように、前提が不十分または曖昧だと、誤った結論に至るリスクがあります。

### 帰納法

**個々の事例から一般的なルールを導く方法**です。

**例：**
- **観察1：** バッチジョブでモデルAのメソッドBにエラーが発生
- **観察2：** オンライン処理でモデルAのメソッドBが不正確な結果を返す
- **観察3：** ピーク時間帯にモデルAのメソッドBがレスポンス遅延を引き起こす
- **結論：** モデルAのメソッドBに問題を含む可能性が高い

**図解**
```mermaid
flowchart TD
    A[事例1: バッチジョブでメソッドBにエラー]
    B[事例2: オンライン処理でメソッドBが不正確]
    C[事例3: ピーク時にメソッドBで遅延]
    D[モデルAのメソッドBに問題がある]
    A --> D
    B --> D
    C --> D
```

#### 要点

1. **複数の事象やデータからパターンを見つけ出し、全体の傾向や原因を推測する際に有効です**
2. ログ解析やユーザーからの報告をもとに問題の共通点を探るときに役立ちます
2. 観察対象を増やす事で新たなデータが蓄積され、その結果として情報量が増える事があります

#### 注意点
観察事例が限定的だと、一般化による誤りが生じる可能性があります。
前提が偏っていたり、過程や結果に飛躍がある場合も問題です。
多角的な視点でデータを集め、慎重に結論を導きましょう。

**注意点の例：**

少ない観察事例から過度な一般化をしてしまうことがあります。

**例：**
- **観察1：** 朝にサーバーエラーが発生した
- **観察2：** 次の日の朝もサーバーエラーが発生した
- **結論：** 毎朝サーバーエラーが発生する

**図解**
```mermaid
flowchart TD
    A[観察1: 朝にサーバーエラー]
    B[観察2: 次の日の朝もサーバーエラー]
    C[毎朝サーバーエラーが発生すると結論づける]
    A --> C
    B --> C
```

このように、観察事例が限られているのに一般化すると、誤った結論に至る可能性があります。

### アブダクション

**観察された事実を最も適切に説明する仮説を導く方法**です。
この手法を用いるには、物事を**構造化**したり、関連する**法則を知る**必要があります。

**例：**
- **事実：** エラーログに「connection timeout」が多い
- **仮説：** ネットワークの問題が原因ではないか

**図解**
```mermaid
flowchart TD
    A[エラーログに「connection timeout」が多い]
    B[ネットワークの問題が原因ではないか]
    A --> B
```


#### 要点

1. **障害対応の初期段階で限られた情報から迅速に仮説を立てる際に有効です**
2. 問題の原因が明確でないときに、最も可能性の高い原因を推測するために使われます
2. 仮説を検証するためにネットワークのモニタリングやテストを行うことで、新しい情報が得られる事があります

#### 注意点
**他の可能性を見落とすリスクがあります。**
誤った推論を避けるために、システム全体の構造や関連する法則を理解し、仮説を検証することが重要です。

### ヒューリスティクス

**経験や直感に基づく問題解決の方法**です。過去の経験を活かして迅速に対処できます。
問題解決の際の思考の補助として使われます。

**例：**
- **経験：** 「以前、キャッシュ設定の不備でレスポンスが遅くなったことがあった。」
- **推論：** 「今回のレスポンス遅延もキャッシュ設定が原因かもしれない。」

**図解**
```mermaid
flowchart TD
    A[過去の経験: キャッシュ設定の不備で遅延]
    B[現在の問題: レスポンス遅延が発生]
    C[キャッシュ設定が原因かも]
    A --> C
    B --> C
```
推論手法（演繹法、帰納法、アブダクション）と性質が異なり、厳密な論理推論というよりは問題解決のための経験則や指針です。

#### 要点
1. **時間的制約がある中で経験を活かして素早く対処する必要があるときに役立ちます**
2. 過去の経験や直感をもとに、即座に問題解決策を見つける際に有効です
2. 情報量は増えません。ただし、問題解決のために追加の調査やデータ収集を行う場合、その過程で情報量が増えることがあります

#### 注意点
経験に頼りすぎると、**新たな問題を見落とす**可能性があります。
他の推論手法と組み合わせて検証しましょう。

これらの推論手法を理解したところで、次にそれらを組み合わせて実際の問題を解決する例を見てみましょう。

## 4. 推論の組み合わせを用いた問題解決例

### シナリオ：新機能追加後のデータベース障害

新機能をリリースしてから1週間後、徐々にアプリケーション負荷が上昇し遂にダウン。
エラーログには「too many connections」のメッセージが多数表示されています。

### ステップ1：演繹法で即チェック

- **推論：** 接続数が上限に達するとエラーが発生する。"too many connections" エラーが出ているので、接続数が上限に達している可能性が高い
- **行動：** データベースの接続数を確認
- **結果：** 確認すると、接続数が上限である1024に達していた

### ステップ2：アブダクションで仮説を立てる

前のステップで接続数が上限に達していることが確認できましたが、原因を特定するために仮説を立てます。

- **事実：** 新機能リリース後に問題が発生し、スロークエリの発生量が多い
- **仮説：** 「新機能にN+1問題があるのではないか？」
- **行動：** コードを調査し、N+1問題を発見し修正する
- **結果：** しかし、状況は改善せず

### ステップ3：帰納法で原因を探る

前の仮説で問題が解決しなかったため、他の可能性を探ります。

- **観察：** CPU使用率が平均の20%から95%に急上昇している。スロークエリが依然として多発している
- **過去のパターン：** スロークエリが発生するとサーバー負荷が高まり、接続数が増加することが多い
- **推論：** 「スロークエリが原因で接続数が増えているのではないか？」
- **行動：** クエリの最適化を試みる
- **結果：** しかし、効果なし

### ステップ4：ヒューリスティクスに頼る

他の手法で解決できなかったため、過去の経験に基づいて推論します。

- **経験：** 「以前、インデックス追加漏れで同様の問題があった。」
- **推論：** 「インデックス不足が原因かもしれない。」

### ステップ5：演繹法で原因を特定し修正

ヒューリスティクスに基づき、論理的に原因を特定します。

- **前提1：** 新機能リリース後、一週間の運用によりデータ量が増加した
- **前提2：** インデックスが不足していると、データ量の増加に伴い特定のクエリがスロークエリになる
- **前提3：** スロークエリがアプリケーションの待ち時間を増加させ、結果として接続数の増加を引き起こす
- **仮説：** インデックス不足が原因で接続数上限に達している
- **結論：** インデックスを追加すれば問題が解決するはず
- **行動：** インデックスを追加する

### ステップ6：帰納法でシステムの安定性を確認

最後に、システム全体を観察して問題が解決したか確認します。

- **観察1：** インデックス追加後、CPU使用率が20%に戻った
- **観察2：** スロークエリが発生していない
- **観察3：** 接続数が安定している（上限の1024を下回っている）
- **結論：** システムは安定しており、問題は解決されたと推測される

**このように、さまざまな推論手法を組み合わせることで、効果的に問題の根本原因を特定し、解決策を見つけることができます。**

### 最終的な状況整理

```mermaid
flowchart TD
    A[新機能の追加]
    B[1週間後に障害発生]
    A --> B
    B --> C["too many connections" エラー]
    C -- 演繹法 --> D[接続数上限に達している可能性]
    D -- アブダクション --> E[N+1問題を疑う]
    E --> F[N+1問題を修正]
    F --> G[問題解決せず]
    G -- 帰納法 --> H[スロークエリを発見]
    H --> I[クエリの最適化を試みるが効果なし]
    I -- ヒューリスティクス --> J[インデックス不足を疑う]
    J -- 演繹法 --> K[インデックスを追加]
    K -- 帰納法 --> L[サービス復旧]
```

## さいごに

推論は間違えることもあります。しかし、さまざまな手法を組み合わせ、論理的に検証することで、最終的に問題解決にたどり着けます。

ヒューリスティクスは経験に基づく有用な手段ですが、過信は禁物です。他の推論法と組み合わせ、常に新たな視点で状況を見直すことが重要です。

論理的かつ柔軟に考え、継続的な仮説の設定と検証を続けていきましょう。

---

「インデックスさえ付ければ、もう障害は二度と起こらない！」

（ッターン！）

「ん？データベースに接続できない？！？」