OSS-DB GOLD取得するぞのメモ

## 参考にした資料たち
[https://postgresqlco.nf/ja/doc/param/](https://postgresqlco.nf/ja/doc/param/) (パラメータはここで調べろ！)
[OSS-DB GOLD 公式](https://oss-db.jp/outline/gold)
[OSS-DB GOLD セミナー資料](https://oss-db.jp/measures/download)
[OSS-DB GOLD 例題](https://oss-db.jp/sample)

[[改訂新版］内部構造から学ぶPostgreSQL 設計・運用計画の鉄則](https://www.amazon.co.jp/gp/product/B07H5GCJ8J/ref=ppx_yo_dt_b_d_asin_title_o01?ie=UTF8&psc=1)


## やったこと
**ご親切なテキストなんてものは存在しない(ことにする)ので、とにかくPostgreSQLについて学ぶ**

1) PostgreSQLの公式リファレンスを読む
2）[改訂新版］内部構造から学ぶPostgreSQL 設計・運用計画の鉄則を3週
3) セミナー資料を読む
4) 例題をとく
5) 不明点を公式リファレンスとすり合わせる

## 以下メモ書き
（重複やtypo等ございましたらすみませぬ）

### 名称が変更されたもの（まだありそう）
    pg_log => log
    pg_xlog => pg_wal
    pg_clog => pg_xcal
    pg_current_xlog_location => pg_current_wal_lsn
    pg_xlogdump => pg_waldump
    pg_receivexlog => pg_receivewal


### メモリ
    kernel.shmmax
        共有メモリセグメント最大値

    kernel.shmall
        使用可能な共有メモリサイズ（ページ単位）

    共有バッファ
        shared_buffres
        ディスクから読み取ったデータをキャッシュ、その後高速に応答
        物理メモリの20%-40%
        キャッシュヒット率の確認
            キャッシュヒット率の算出
                blks_hit / (blks_hit + blks_read)
    
    WALバッファ
        wal_buffers
        WALファイルへのI/Oをシーケンシャルにするため
        自動調整の上限は16MB
        WALセグメントサイズの倍(32MB)程度が好ましい
        WALフラッシュのタイミング
            トランザクションコミット
            wal_writer_dilay時間が経過したとき 3s
            WAL_bufferが一杯になったとき
    
    work_mem
        セッションごとに確保される
        ソート・ハッシュの一時領域

    maintenance_work_mem
        メンテナンス操作
        autovacuum_work_mem(9.4~)

    maxprepared_transactions
        プリペアドトランザクションの上限
        default: 0
        
    max_locks_per_transaction
        平均取得ロック数
        default: 64


### サーバ設定
    postgresql.conf
        max_connections
            default: 100
        superuser_reserved_connections
            スーパーユーザー用予約枠
            default: 3
        deadlock_timeout
            default: 1000ms
        
        


### プロセス構造
    バックグラウンドプロセス
        logger process: サーバーログ出力
            ディフォルトは無効だが、有効化すべき
            logging_collector = on;
            log_destination = 'ディフォルトでOK'
            ログ循環設計
            ログ出力設定
        writer process: データ書き出し
        wal writer process: WAL書き出し
        wal sender / wal reciver
            max_wal_sernderでマスター側にて指定した数のスタンバイを持つ
        recovery.conf
            hot_standby = on;
            recovery.conf
        autovacuum_lancher proces: VACUUM実行
            自動VACUUMを活用
            autovacuum = on;
            autovacuum_vacuum_threshold
            autovacuum_vacuum_scalefactor
            性能影響を抑えるために、遅延VACUUMを使う
        achiver process: WALアーカイブ
            archive_mode
            archive_command: WALファイルをコピーするコマンド
            wal_level=replica / logical;
        status collector process: 統計情報収集

### データ構造
    テーブルファイル
        1ファイル最大1G,増加に伴いページ単位(8192B)に増加
        メンテナンス処理によりVisibilityMap FreeSpaceMapといったファイルも作成
        VisibilituMap: VACCUM時に不要なページをスキャンしないため
        FreeSpaceMap: 空き容量を監視し、挿入時に使用

    インデックスファイル
        1ファイル最大1G,増加に伴いページ単位(8192B)に増加
        先頭の1ページはメタページ・固定
        その他のページはルート・リフーページ・インターナルページ

    テーブル空間
        - CREATE TABLESPACE <空間名> LOCATION '<ディレクトリ>';
        OIDが割り当てられ、${pgdata}/pg_tblspc配下にシンボリックリンクとして配置
        別デバイスに配置し、I/Oを改善したい場合に有効
        オンラインバックアップではテーブル空間のバックアップも忘れずに

### テーブル構造
    ファイル構造やページ構造は理解必須
        1つのオブジェクト
            1GBごとのセグメントファイル+ VM,FSM
            セグメントファイルは8KB単位のページで構成される
            [ページヘッダ, アイテムポインタ1, アイテムポインタ2, ... ,行データ2,行データ1]

    テーブルサイズの見積もり
        ページヘッダは固定で 24byte
        1行追加されるごとにアイテムポインタ 28byte
        行データが消費するサイズ
        1) 一行のサイズ = [行ヘッダ28byte] + [行データ4+ 8+ (4+平均文字サイズ) byte]
        2) 1ページ内のデータ領域 = 8192byte -24byte * FILLFACTOR(割合に変換)
        3) ページに格納できる行数 = 1ページ内のデータ領域 / 一行のサイズ
        4) テーブル行数 / ページに格納できる行数 = 必要なページ数
        5) 必要なページ数 * 8192byte = テーブルサイズ

    インデックスサイズの見積もり
        インデックスページの固定領域は 40byte
        1エントリ消費されるごとにノードヘッダ 12byte
        1) 1ノードのサイズ = [ノードヘッダ 12byte] + [int型のエントリ 4byte]
        2) 1ページ中のデータ領域 = (8192byte -40byte) * FILLFACTOR(割合に変換)
        3) ページに格納できるノード数 = 1ページ中のデータ領域 /  1ノードのサイズ
        4) インデックスエントリ数(テーブル行数) / ページに格納できるノード数 = 必要なページ数
        5) 必要なページ数 * 8192 byte = インデックスサイズ


### I/O分散、故障リスク分散
    データディレクトリ
        指定: initdb -D
        ディフォルト位置: $PGDATA

    WALファイル出力先
        指定: initdb -X
        ディフォルト位置: $PGDATA/pg_xlog

    ユーザデータ格納先
        TABLESPACE機能
        ディフォルト位置: $PGDATA/base

    ログファイル出力先
        パラメータ
        $PGDATA/pg_log

    アーカイブ退避先
        パラメータ

    考慮するポイント
        データとWALは別のディスクとする
        WALファイルは出力先を指定する
        WALファイルは二重化できないので、RAIDによる保護を検討する
        テーブル・INDXはTABLESPACE機能を利用し、配置先を分散する

### レプリケーションの構成
    データ同期モード
        synchronous_commit
            remote_apply: 完全同期
            on / remote_write: 準同期
            指定なし: 非同期
        synchronous_standby_names
            remote_apply: 同期対象スタンバイリスト
            on / remote_write: 同期対象スタンバイリスト

    マルチスタンバイ
        同期対象スタンバイリストは通常は先頭1台が同期
        その他のスタンバイは非同期スタンバイ
        synchronous_standby_names = N(slave1, slave2, slave3)
            上記の書式でN台の同期設定が可能(9.6～)


### 監視
    サーバー監視
        sar, iostat, vmstat, top, netstat (上げれば切りがない)

    データベース領域
        pg_database_size('db');
        pg_relation_size('table');
        pg_total_relation_size('table') インデックスのサイズも含む


    WAL領域
        1セグメント 16MB　循環利用する
        チェックポイントが住めば不要
        max_wal_size: 超えるとチェックポイント処理
        min_wal_size: 再利用可能な状態で維持
        リカバリ時はベースバックアップ以降のWALが必要となる
        WALファイルの領域が枯渇するとDB停止
            アーカイブモード
                WAL消失を防ぐため
                アーカイブ先の空き容量がななら巡回されるWALファイルを残しておく
            レプリケーション
                スタンバイに転送予定だが、まだ転送が完了してないWAL
        checkpoint_segments (before 9.4)
        checkpoint_timeout
        checkpoint_completion_target
            次のチェックポイント発生までの目標時間の割合
        必要領域 = 16MB * checkpoint_segments * ( 3 + 1 )
        df / du

    アーカイブWAL領域
        PITRで利用
        df / du

    テーブル・インデックス容量見積もり
        列の型 indexの列の型 その型がどの程度のデータサイズなのか
    
    各データ型のデータサイズ
        smallint: 2byte
        integer: 4byte
        bigint: 8byte
        real: 4byte
        Timestamp: 8byte
        date: 4byte
        interval; 16byte
        varchar(n),char(n),text: N<126の場合(1+N)byte N>=126の場合 (4+N)byte

    VACUUM
        VACUUM
            更新/削除された行の再利用
        VACUUM FULL
            表の再作成を行う
        VACUUM FREEZE
            トランザクションID周回問題への対処
        更新/削除された行の切り詰め


    遅延VACUUM
        vacuum_cost_delay
        vacuum_cost_page_hit
        vacuum_cost_page_miss
        vacuum_cost_page_dirty
        vacuum_cost_limit

    自動VACUUM
        autovacuum
        log_autovacuum_min_duration
        autovacuum_max_worker
        autovacuum_naptime
        autovacuum_vacuum_threshold
        autovacuum_vacuum_scale_factor

    vacuumdb
        vacuumdb [接続オプション][オプション][db名]
            -f | --full
            -z | --analyze

    pg_stat_user_table
        n_live_tup: 有効行数
        n_dead_tup: 無効行数
        n_tup_hot_upd: HOTに更新された行数
        last_vacuum: 最後にVACUUM ANALYZEが実行された日時
        last_autovacuum
        vacuum_count: 最後にリセットしてからの実行回数

    pg_stat_user_indexed
        idx_scan: インデックスキャンが実行された回数

    プロセス監視・クエリ実行
        ps -ef など
        SELECT 1; など
        pg_isreadyコマンド
            1: 接続拒否
            2: 無応答
            3: 実行に失敗
        pg_stat_archiverビュー
        pg_stat_acrtivityビュー
        pg_stat_progress_vacuumビュー
        psql

    HOTによる更新とFILFACTOR
        HOTは行データが更新されてもインデックスを更新しない仕組み
        変更前データの領域はVACUUM不要で再利用可能となる
        有効になる条件
            同一ページ内に更新後のデータが格納できる場合
            インデックスに格納されたキーの値自体が変更されない
            ロングトランザクションが古いデータを見ていないこと

    ログ
        pstgresql.confパラメータ
            client_min_message
                default: notice
            log_min_message
                default: warning
            log_min_error_statement
                default: error
            log_checkpoints
                チェックポイントの出力有無
            log_connections
                接続切断の情報有無
            log_lock_waits
                一定以上待たされたDB、テーブル、connなど
            log_autovacuum_min\duration
                自動バキュームの秒数をこえた場合に出力
            log_line_prefix
                先頭に出力する情報（silverででた）
            log_rotation_age
            log_rotation_size
            log_truncate_on_rotation
                名前が同じログファイルに対し、上書き(on)か追記か(off)

### ストリーミング・レプリケーション
    マスター側
        pstgresql.conf
            liste_address
            wal_level = archive / host_standby
            archive_mode = on
            archive_command
            max_wal_senders = 1
        pg_hba.conf
            2列めにreplication
            host replication postgres 192.168.1.2/32 trust
        
    スレーブ側
        revovery.conf
            standby_mode = on
            primary_conninfo
            trigger_file
            restore_command
        primary_conninf = 'host=192.168.1.1 port=5432 user=postgres'

    手順
        マスタ側の設定
        マスタのベースバックアップ取得
        ベースバックアップをスレーブで展開
        スレーブの設定
        スレーブの起動
        LOG: streaming replication successfully connected to primary

    フェイルオーバー
        postgreSQLには無い

    recovery.conf
        trigger_fileで設定したトリガファイルを作成することでフェイルオーバー
        touch /tmp/trigger.file

    状態管理関数
        pg_current_xlog_location() WAL書き出し位置を返却
        pg_last_xlog_receive_location() WAL受信位置を返却
        上記2つを比較

### バックアップ・リカバリ
    コールドバックアップ
        オフラインバックアップ
        データベースを停止した状態で取得する
            rsyncやtarを使用する
            storageスナップショット機能も利用可能
        バックアップした時点にのみリカバリ可能
        設定ファイルも含む
        リストア時間が相対的に短い
        類似構成の別マシンにコピーも可能
        pg_tblspc内のシンボリックリンクに注意
        データ実体もバックアップすること
        pg_walの位置に注意
        メジャーバージョンが一致していること★

    ホットバックアップ
        オンラインバックアップ
        データベースを稼働させた状態で取得する
        倫理バックアップを取得
        バックアップ開始時点のもので一貫性有り
        dp_dump / dp_dumpallコマンドで実施
            pg_dump: データベース単位 バイナリ
                テーブル空間も対応
                以下のことを行わないこと
                    DDL操作
                    ラージオブジェクトのデータ書き換え
            pd_dumpall: ユーザ情報含むデータベースクラスタ全体
                テーブル空間も対応
        設定ファイルはベットバックアップする必要あり
        メジャーバージョンが異なっていてもリストア可能★

        pg_basebuckup
            レプリケーションできる状態であること前提
            pg_archivecleanup (9.5~)

    リカバリ
        PITR ( POINT IN TIME RECOVERY)
            WALをアーカイブしておき、定期的にデータベースクラスタ全体をコピー
            インスタンにバックアップ開始・終了を通知する必要あり
            任意の時点の状態にリカバリ可能
            複雑だが、最も自由度が高い
            事前準備(postgresql.conf)
                wal_level=archive | hot_standby
                archive_mode=on
                archive_command='cp -i %p /path/to/archie%f'
    
    バックアップ方法
        低レベルAPI
            1) SELECT pg_start_backup('label');
            2) クラスタ全体をコピー
            3) SElECT pg_stop_backup();
                ベースバックアップが取れたらそれ以前のWALは破棄可
        pg_basebackup
            開始・終了の通知関数不要
            リモートでも取得可能
            superuserまたはreplication権限のあるユーザーで実行
            GUCパラメータ max_wal_senderを 1～2増やす

    リストア方法
        1) インスタンスが稼働している場合は停止
        2) $PGDATA/pg_xlogを任意の場所に退避
        3) クラスタを削除
        4) バックアップを&PGDATA/に再配置
        5) $PGDATA/pg_xlogの中を全削除し2をコピー
        6) recovery.confを作成し、&PGDATA配下に配置

    リカバリ方法
        1) pg_hba.confを編集、一般の接続をrefuse
        2) インスタンスを起動、自動リカバリを開始
            recovery.conf => recovery.done
            LOG: archive recovery complete
        3) DB内容を確認
        4) pg_hba.confをもとに戻してreload


### ホットスタンバイ
        マスタ側
        postgresql.conf
            wal_level=hot_standby
        スレーブ側
        postgresql.conf
            hot_standby=on

### アクセス統計情報
        pg_locks
            実行中トランザクションにより獲得されたロックに関する情報
            locktype
                relation
                page
                tuple
                transactionid
                virtualxid
            mode: ロックモード
            granted: ロックを保持しているか
        pg_stat_database
            キャッシュヒット率=blks_hit / (blks_hit + blks_read)
            tup_returned: シーケンシャルスキャンにより取得された行数
            tup_fetched: インデックスキャン・ビットマップスキャンで取得した行数
        pg_stat_clear_snapshot
            最新情報に更新可能

    標準統計情報ビュー
    pg_stat_bgwriter
        buffers_backendがbuffers_allocより大きい場合、shared_bufferの値が不足
        buffers_checkpoint: チェックポイントで書き出されたdrityバッファ数
        buffers_clean: バックエンドライタで書き出されたdirtyバッファ数
        buffers_backend: バックエンドプロセスより書き出されたdirtyバッファ数

    pg_stat_all_tables
        seq_tup_read / seq_scan
        n_dead_tup: バキュームの対象
        pg_relation_size: バキュームの対象量
        N_tup_hot_upd / n_tup_upd
    
    pg_statio_all_tables
        テーブルあたりのI/Oに関する統計情報

    pg_stat_all_indexed
        インデックスごとのアクセスに関する統計情報を表示
        使われていないインデックスの特定
        idx_scan: 実行回数
        idx_tup_read: ノード数
        idx_tup_fetch: レコード数
    
    pg_statio_all_indexed
        インデックスごとのI/Oに関する統計情報を表示
        idx_blks_read: 共有バッファ以外からブロックを読み込んだ回数
        idx_blks_hit: 共有バッファからブロックを読み込んだ回数

    pg_stat_activity
        バックエンドプロセス単位で表示
        長時間経過してる・ロック待ち状態のSQLを調査可能
            pid: プロセスID
            query: 実行中のクエリ
            waiting: ロックマチの状態か
            backend_start: プロセス開始日時
            xact_start: トランザクション開始日時
            query_start: SQL実行の開始日時
            client_addr: クライアントのIPアドレス
            pg_cancel_backend(pid): クエリを取り消す
            pg_terminate_backend(pid): 強制切断

    pg_stat_statement
        実行されたSQLを記録・分析
            所要時間が長い/実行回数が多いSQLはチューニング効果大
            contribツール
                rmpやソースコード参照
                CREATE EXTENSION, share_preload_libraries

### 実行計画
    EXPLAIN 実行計画の表示のみ
    EXPLAIN ANALYZE 実際にSQLが走り、実行結果に基づく情報も合わせて表示される

    プランノード
        スキャン
            Seq Scan: 先頭ブロックから順にヒープ全体をスキャン
            Index Scan: インデックスに基づいてヒープをスキャン
            Index Only Scan: インデックのみを用いてスキャン
            Bitmap Index Scan:
                複数のインデックスから作成したビットマップに基づいてスキャン
        
        結合
            Nest Loop: Outer一行につきInner全体をスキャンし結合
            Merge Join: 結合キーでソートされた結果同士を結合
            Hash Join: Innerの結合キーでハッシュテーブルを作成しそれに基づきスキャン
        
        そのた
            Sort: 結果の並び替え
            Limit: 結果の行方向の部分集合を取得
            Materialize: 結果セットを一時領域に保存
        
        オプション
            ANALYZE(bool)
                言わずもがな
            VERBOSE(bool)
                trueであれば各種追加情報出力
            BUFFERS(bool)
                trueであれば共有バッファの使用状況を出力
            FORMAT(text,xml, json, yaml)
                出力フォーマット指定

    INDEXチューニング
        インデックスを追加する
        SELECTで取得する列がすべてインデックスに含まれるならIndexOnlyScan
        WHERE以外でもインデックスは使われる
        結合条件 / ソート条件
    
    ANALYZE
        EXPLAIN ANALYZEを実行し、乖離がないか調べる
        手動でのANALYZEは基本的に不要
        一時テーブルに対しては手動でのANALYZEが必要
    
    work_mem
        ソート・ハッシュ表作成時に利用できるメモリ量を指定する
        shared_buffersとは個別に確保
        大きすぎる値を設定するのは危険
        log_temp_filesパラメータで調査が可能

    effective_cache_size
        カーネルのバッファキャッシュを含めた、利用可能なディスクキャッシュの推定値を設定
        
    プランコスト定数の変更
        データベースの大半がディスクキャッシュに乗る場合
            seq_page_cost / random_page_cost を減らす
        インデックススキャンを選択させる
            random_page_cost / effective_cache_size を増やす
        
    プランなメソッド設定の変更
        postgresql.confで設定するとすべてのSQLに影響が出る
        SETでセッションまたはトランザクションごとに設定すべき

    テーブル結合最適化処理
        パラメータに小さな値を設定することで、最適化処理時間を短縮化できる
        実行計画の制度が低下する可能性がある
        from_collapse_limit
        join_collapse_limit

### セキュリティ関連設定
    データ暗号化
        個人情報を含む列のみを暗号化するなどAP側で実装
    通信経路暗号化
        実行されるSQL文の盗聴を防ぐ
    監査情報の取得
        バックアップの持ち出しなどから保護
    
    PostgreSQL
        データ格納時にpgcrypto関数を使用し、列単位で暗号化
        Open SSLライブラリをロードし通信経路暗号化
        データファイル暗号化はできない

    SSL通信設定を理解する
        PostgreSQLのインストール時
            configure実行時に --with openssl
            RPMでは有効化済み
        データベースクラスタ
            ssl=on
            サーバー証明書の設定、秘密鍵を含む設定ファイルを用意し指定
        認証設定
            クライアントごとにSSL通信を矯正するかどうかを指定可
            pg_hba.conf type=hotsslを指定

### 監査情報の取得
    log_statementの指定によるSQL文を記録
        log_statementの設定
            none: 出力なし
            ddl: 実行されたDDL文のみ
            mod: 実行されたDDLとDML文を記録
            all: 実行されたすべて
        ユーザー単位で指定可能
        テーブル単位やSELECTのみは不可
    log_connection
        ログイン・ログアウトの記録

### パフォーマンス監視
    システムカタログの監視
        pg_stat_bgwriter: チェックポイント感覚の適正値把握
        pg_stat_all_tables: キャッシュヒット率HOT更新IndexScan割合VACUUM設定の適正値
        pg_statio_all_tables: I/O
        pg_stat_activity: ユーザセッションごとに実行されてるSQL
        pg_locks: pg_stat_activityとjoinし、他セッションをブロックしているSQLを特定

    スロークエリの検出
        ログ監視設定
            log_min_duration_statement
            エラーレベル
                PANIC: サーバーが停止している
                FATAL: セッションが切断されている
                ERROR: 処理が失敗し、セッションは残っている
            loc_checkpoints
                適切な間隔で動いているか
                所領時間は意図した通りか
                pg_stat_bgwriterビューでチェック
            log_min_error_statement
                指定のエラーレベルに対してSQLを記録
            log_min_duration_statement
                実行に長時間要したSQLのトクエイ
            log_loc_waits / deadlock_timeout
                ロック取得に要した時間がtimeoutを超過
            log_line_prefix
                %t: timestump
                %u: username
                %d: database
                %p: PID
                %c: sessionID
                %x: transactionID
                %e: SQLSTATE Error code
                %a: Application name
                %%: %そのもの
            log_destination
                サーバー側のログ出力先を指定
                stderr: plain textで標準エラー出力
                csvlog: csvで標準エラー出力
                syslog: plain textでsyslogに出力
                eentlog: windowsのイベントログへ
            logging_collecotr
                stderr, csvlogの内容を保存するか
            log_directory
            log_filename
                %使用可能

### オブジェクトのメンテナンス
    インデックスの劣化
        インデックスは表の更新に合わせて自動で書き換えられる
            ソートされたデータ構造を保つため、ブロック内に空きがないと劣化する
            インデックスを指定したVACUUMはできない

    メンテナンス手段
        以下を比較しページ数が非常に大きい場合には再作成を検討
            pg_class
                reltuples: インデックスエントリ
                relages: インデックスのページ数
            pgstatindex()
                idx_j: 昇順
                idx_i: 降順
            pg_stats
                correlation
                    テーブルのクラスタ性
            
        CLUSTER
            クラスタ性の復活
            

        再作成
            ロック強度と所要時間とのトレードオフ
                REINDEX
                DROP INDEX / CREATE INDEX
                CREATE INDEX CONCURRENTRY



### チューニング
    ベンチマークの取得
        pgbench: contribツール・TPSを計測

    観点
        自動VACCUMの遅延設定・ダーティバッファ書き出し
        チェックポイント
        pg_stat_xxxビューのどの列を見ればいいか、ログ出力を見れば良いか
        パラメータ(リスクと効果を期待できるか理解する)
            fsync
            full_page_writes
            synchronous_commit
            commit_delay
            wal_sync_method

### 性能改善
    インデックスが聞かない原因例
        統計情報が正しく取得されていない
            自動バキュームが有効であったとしてもテーブル内容に大きな変更がされた場合
                手動でVACUUM ANALYZEを実行
            データが最初にロードされた時
                手動でVACUUM ANALYZEを実行
        検索条件に式・関数が利用されている
            式・関数インデックスの作成で解決することもある
                CREATE INDEX ON test (lower(mail_address));
                他の方法で解決可能なら積極的には利用するべきではない
        インデックスを利用しても効果がない
            カーディナリティ度が低い場合はインデックスは利用されない
            検索条件等に誤りがないか確認する必要がある
        統計情報の精度が足りない
            精度が足りない場合はインデックスが利用されない非効率な実行計画になる
            https://www.postgresql.jp/document/11/html/row-estimation-examples.html

    実行時間とネットワーク転送コスト
    https://fo-pro.s3.ap-northeast-1.amazonaws.com/files/5c24dddf5b3a437d0e0059f3/20160806-gold-01.pdf
        実行時間
            以下の実行時間はすべて算出方法が異なる
                log_min_duration_statement
                    duration
                EXPLAIN ANALYZE
                    Execution time
                psql > \timing
                    Time
                アプリケーションログに出力される実行時間
            ネットワーク転送コストが実行時間に含まれているかを意識すべき
        ネットワーク転送コスト
            クラウドでは帯域幅だけではなく、レイテンシもボトルネックとなる
            PostgreSQLでは通信プロトコルはTCP/IPを用いるので、影響をもろに受ける
            log_min_duration_statement
                durationにはネットワーク転送コストは含まれていない
            削減方法
                コネクションプーリングを利用する
                クエリの発行回数を抑える
                    ストアドプロシージャ
                通信の圧縮を有効にする
                    sslcompression
                TCPのチューニングを実行
                    tcp_slow_start_after_idle=off など
                ネットワーク転送コストが問題となるような構成にしない

### 障害の種類
    電源障害・プロセス障害
        メモリ城のデータは消失するが、起動時にリカバリされる

    ファイル破損
        正常なバックアップがあれば復旧可能
        限定的な障害の場合、少ない影響で復旧させることを検討
            WALの破損 pg_xlog 
                pg_resetxlogの検討
            データの破損 
                baseやテーブルスペース
            システムデータの破損 global
                シングルユーザーモードで接続・REINDEX
            インデックス base テーブルスペース
                インデックス再作成
    
    データ・WALの物理ディスク障害
        インデックスデータの場合
            インデックス再作成を検討
            システムテーブルのインデックスの場合は注意が必要
            システムに与える影響を考慮して検討
        
        WALファイル
            起動時に読み込まれるため、破損していると起動できない
            pg_restxlogを使用してWALのリセット
            正常なトランザクション位置を指定してPITRを実行
                pg_resetxlog -f -x XID $PGDATA

    容量不足時
        容量不足により各ファイルへの書き込みが失敗するとどうなるか
            データファイル
                データ破壊を引き起こす可能性がある
                WALファイル
                    容量が不足すると、データベースクラスタが停止する

            対処
                LVMなどで容量追加
                テーブルスペース機能で別領域に移動 データファイル
                シンボリックリンクで別領域に移動 WALファイル