Skip to content

Instantly share code, notes, and snippets.

@kwatch
Last active May 27, 2017 04:53
Show Gist options
  • Save kwatch/3503849e3a2fd588322d to your computer and use it in GitHub Desktop.
Save kwatch/3503849e3a2fd588322d to your computer and use it in GitHub Desktop.
書籍『内部構造から学ぶPostgreSQL - 設計・運用計画の鉄則』の気付いた点
# -*- coding: utf-8 -*-
- page: 55
text: "暗号化したパスワード文字列を送信する「md5」方式"
comment: MD5 はハッシュ値を計算するだけであり、暗号化するわけではないのでは?
- page: 69
item: 表4-3
text: "同時に実行されている他のトランザクションが書き込んでいるがコミットされていないデータを読み込んでしまう"
comment: "同時に実行されている他のトランザクションが、書き込んでいるがコミットされていないデータを読み込んでしまう"
または
"書き込まれたがまだコミットされていないデータを、同時に実行されている他のトランザクションが読み込んでしまう"
- page: 74
item: 図-9
text: "date"
comment: "data"では?また、トランザクションA は XID-1003 ではなく XID-1002 と思われる
- page: 95
item: 表5-6
text: "圧縮や行外への格納行わない"
comment: "圧縮や行外への格納を行わない" or "圧縮しない、また行外への格納も行わない"
- page: 102
text: "総ページの概算値 = RN / ( ( (8192 * FF) - 24) / TS )"
comment: "総ページの概算値 = (RN * TS) / ((8192 * FF) - 24)"
または
"総ページの概算値 = テーブルサイズ / ページあたり利用可能領域 = (RN * TS) / ((8192 * FF) - 24)"
- page: 120
text: "最頻値を除いた条件にを付与して"
comment: "最頻値を除いた条件を付与して"
- page: 233
text: "このため手動のANALZE実行は、"
comment: "このため手動のANALYZE実行は、"
- page: 246
text: "必要に応じてに追加する"
comment: "必要に応じて追加する"
- page: 252
text: "コストは次の次の計算式で求められます"
comment: "コストは次の計算式で求められます" or "コストは次の計算式で求まります"
- page: 254
text: "コストは次の次の計算式で求められます"
comment: "コストは次の計算式で求められます" or "コストは次の計算式で求まります"
- page: 262
text: "「アプリケーションのレスポンスが良くない」といったデータベース管理者にとっては…"
comment: "「アプリケーションのレスポンスが良くない」といった、データベース管理者にとっては…"
### 2016-06-04 追加分
- page: p.69
item: 表4-3
text: "2回目の読み込みの間に、別トランザクションで更新とコミットが行われた場合、"
fixed: "2回目の読み込みの間に別トランザクションで更新とコミットが行われた場合、"
- page: p.69
item: 表4-3
text: "検索結果が変わってしまうしまう"
fixed: "検索結果が変わってしまう"
- page: p.71
text: "テーブル/行"
fixed: "テーブルまたは行"
- page: p.72
item: 表4-6
text: "ROW SHARE"
comment: テーブルヘッダの2つ目は「FOR NO KEY UPDATE」では?
- page: p.73
item: 図4-8
text: "アポート"
fixed: "アボート" (2箇所ある)
- page: p.73
item: 図4-8
text: "デッドロック検知によりトランザクションAがアポート"
comment: この説明だと、LOCK TABLE baz を発行した瞬間にデッドロックを検知してくれるのだと誤解してしまう。
「一定時間経ってもロックを獲得できなかった場合はデッドロックと見なしてトランザクションをアボートする」という注釈があるとよい。
- page: p.79
text: "文字列長が126バイト"
comment: 厳密にいうと、文字列の*長さ*を「126バイト」と表現するのはおかしい。
「文字列のサイズが126バイト」とするのが正しい。
- page: p.79
text: "18 20 00 00"
comment: 0x000000218 を格納したら「18 02 00 00」になるのでは? (自信ない)
- page: p.84
itme: 図5-3
comment: numeric型に流れ込む矢印のうち、1本が「No」のラベルがなく、またグレーになっていない。
- page: p.86
text: 図5-5
comment: 「timestamptz」が説明なく使われている。エイリアスであることを説明すべき。
- page: p.98
text: "基本的には8,192バイトのページと呼ばれる固定長領域が..."
fixed: "ファイルは、基本的には8,192バイトの固定長領域である「ページ」と呼ばれる領域が..."
- page: p.98
text: "固定長領域は、最大約1GBまで拡張され、"
fixed: "ファイルは最大約1GBまで拡張され、"
comment: ここでは「固定長領域」=「ページ」として説明しているから、ページが1GBまで拡張されたら大変。
- page: p.100
item: 表6-1
text: "タプルの実体"
comment: 「タプル」が何か、説明されていない。
タプルを説明しないなら、表現を「行の実体」に変えたほうがよい。
- page: p.101
item: 表6-3
text: "2: HOT更新でリダイレクトされる"
comment: 「リダイレクト」とは?
- page: p.101
item: 表6-3
text: "3: 無効"
comment: p.109だと「不要領域」という説明がされているが、「3: 無効」は「不要領域」のこと?
「無効」と「不要」を同じ意味で使っているのか、それとも実は違いがあって使い分けているのか、わからなかった。
- page: p.101
item: 表6-3
text: "15 | 対応するタプルの長さ (バイト数)"
comment: これだとタプル長の最大値が 2^15-1 になるからタプルサイズは最大32KBという理解であってる?
あと、やっぱり「タプル」とは何か、事前に説明があったほうがいい。
- page: p.102
text: "テーブルフィルおよびページ内のレイアウトを理解することで、"
comment: 直前に空行を一行いれるべき。これだとこの行も「特別な領域」の説明に含まれてしまう。
- page: p.102
text: "例えば、「行の想定サイズが100バイト」..."
comment: 直前に空行を一行いれるべき。
- page: p.105
text: "まず更新のログをWALバッファに書き込みます。"
comment: 「更新のログ」とやらがどんなものか、中身がわからないのでイメージできない。
また一般的な「ログ」のイメージからすると、更新するまえにログを書き込むというのがよくわからない。
- page: p.106
text: "なお、PITRによるリカバリでは、..."
comment: 「PITR」が説明なしに使われている。
- page: p.106
text: "WAL数"
qestion: これは、WALファイル数ということ? WALはデータのことだと思うから、「WAL数」や「WAL最大数」という表現には違和感を感じる。
- page: p.106
text: "PostgreSQLの設定パラメータ「checkpoint_segements」"
comment: このパラメータの詳細な説明が p.148 にあるから、そこへのポインタがあると望ましい。
- page: p.106
text: "checkipoint_completion_targetパラメータ"
fixed: このパラメータの詳細な説明が p.148 にあるから、そこへのポインタがあると望ましい。
- page: p.108
text: "サイクリックに利用しないため、"
fixed: "循環的な再利用はしないので、"
- page: p.109
item: 図6-5
comment: 「HOT更新なしの場合」のitemsテーブルで、最下行が id=105 になっているが、これは id=102 では?
また、これがなぜHOT更新なしになるのか説明がほしい。
古い行が「不要領域」となっているが、なぜこれが再利用されないのかわからない。ぱっと見では問題なく再利用できそう。
- page: p.109
item: 図605
comment: 「HOT更新ありの場合」のitemsテーブルで、新しい行が挿入されているのにインデックスが更新されない理由がわからない。
「行へのポインタを追加」が何のことかわからない。古い行に、新しい行へのポインタを格納する領域があるのだろうか?
古い行に新しい行へのポインタを追加したとして、もしそうなら古い行を不要領域とはできないのでは?
「HOT更新なしの場合」と比較して、HOT更新ありの場合だけなぜ不要領域が再利用可能になるのかわからない。どちらの場合も再利用可能にできそうに見える。
- page: p.109
text: "HOTを効果的に活用するにはFILLFACTORによる物理設計を考慮する必要があります。"
fixed: "HOTを効果的に活用するには、次で説明するFILLFACTORによる物理設計を考慮する必要があります。"
- page: p.111
text: "2レコード分の空き領域があれば、同時にそのページ対する更新がかからないかぎり、空き領域を交互に使う可能性が高いため、更新操作により新規ページを確保する可能性が減少する。"
comment: 不要領域がすぐに回収されるなら「空き領域を交互に使う」ことはできるけど、すぐには回収されないのだから、交互に使うのは難しいのでは?
もし不要領域がすぐに回収されるなら、空き領域は1レコード分でいいはず。
- page: p.111
text: "そのページ対する更新"
fixed: "そのページに対する更新"
- page: p.114
text: "それぞれのテーブル空間にテーブルやインデックスを配置することで、並列に読み込みや書き込みを行えます。"
comment: これは、1つのテーブルを複数のディスクに分散させることで並列に読み書きするということなのか、それとも2つ以上のテーブルを別々のディスクに分散させたらそれらのテーブルを並列に読み書きできることを意味しているのか?
- page: p.120
text: "条件にを付与して"
fixed: "条件を付与して"
- page: p.124
text: "リストアはバックアップ取得時点までです。"
fixed: "リストアできるのはバックアップ取得時点までです。"
- page: p.125
text: "pg_dumpやpg_dumpallを用いて"
fixed: "pg_dumpコマンドやpg_dumpallコマンドを用いて"
comment: pg_dumpやpg_dumpallが何なのか分かってない人には、この表現のほうが親切。
- page: p.124
item: 7.2 PostgreSQLのバックアップ方式
fixed: 「論理バックアップ」と「物理バックアップ」がそもそも何なのか、説明がほしい。
例えば:
PostgreSQLのバックアップ方式は、以下の観点から分類できます。
・PostgreSQLを停止するのか (オフラインバックアップ)、それとも稼働したままなのか (オンラインバックアップ)
・データを取り出してファイルに保存するのか (論理バックアップ)、それともデータファイルを直接コピーするのか (物理バックアップ)
これらの組み合わせは2×2=4通りありますが、PostgreSQLを停止するとデータを取り出すことはできないので、オフラインバックアップと論理バックアップの組み合わせはありません。そのため、可能な組み合わせは3通りです。
- page: p.138
text: "整然と設計されたシステムでも、サーバのリソースを相応に使えなければ、可動が続くとボトルネックになってしまいます。"
fixed: "整然と設計されたシステムでも、サーバのリソースを相応に使えなければ、可動が続くとボトルネックが発生します。"
comment: 元テキストだと、システムがボトルネックとなるように読める。
システムの一部がボトルネックとなることがわかるような表現にすべき。
- page: p.138
text: "本章ではサーバのリソースを効率的に利用するために必要となるOSのパラメータ設定(CPU/メモリ/ディスクI/O)と、PostgreSQLのパラメータ設定について説明します。"
fixed: "本章では、サーバのリソース(CPUやメモリやディスクI/O)を効率的に利用するためのパラメータ設定を、OS(Linux)とPostgreSQLの両方について説明します。"
comment: ここでいう「リソース」が何のことかを具体的に示すべき。
元のテキストだと、「リソース」=「CPUやメモリやディスクI/O」であることに気付かない可能性が高い。
- page: p.138
text: "PostgreSQLではクライアントからの要求を1つのプロセスが処理するプロセスモデルのアーキテクチャを採用しています。"
fixed: データベースサーバにおけるCPUの設定では、ロックの競合を発生させないことが大事です。そしてPostgreSQLではロックの競合が発生しにくい仕組みになっているため、CPU関連でチューニングする要素は少ないです。
どういうことか説明しましょう。まずPostgreSQLでは、クライアントからの要求1つにつき、1個のサーバプロセスが対応して処理を行うようなアーキテクチャになっています(詳しくは第2章を参照してください)。
comment: ・「プロセスモデル」とは? 説明が難しいなら「1つのプロセスが処理するようなアーキテクチャ」と言い換えたほうがよい。
・「1つのプロセス」ではなく「1つのサーバプロセス」にすべき(サーバ側のプロセスであることを説明する)。
・この章のタイトルは「9.1 CPUの設定」である。なのに、いきなり「クライアントからの要求を1つのプロセスが処理します」と説明がしてあって、タイトルと内容とがあっていない。
なので、ここでは「データベースサーバにおけるCPUの設定では、ロックの競合を起こさないようにすることが大事です。」という一文を最初に入れたほうがよい。
- page: p.138
text: "PostgreSQLではデータ参照/更新において、"
fixed: "PostgreSQLではデータアクセス時に、"
comment: 三行前では「データアクセス」と書いているのに、ここでは「データ参照/更新」となっており、用語が統一されていない。
特に意図がないのであれば、統一したほうがよい。
- page: p.138
text: "PostgreSQLではデータ参照/更新において、取得するロックを十分に小さい範囲に絞ることで、ロックの競合が起こりにくいような実装になっています。PostgreSQL9.2以降では、少なくとも64コアのサーバまでCPUスケールすることが確認されています。"
fixed: 一般的には、ロックする範囲が広いとロックの競合が起きやすく、狭いと起きにくくなります。そしてロックの競合が起きると、CPUのコア数を増やしてもサーバの性能が伸びなくなります。そのため、CPUのコア数に比例した性能を出すには、ロックの競合を減らすことが大事です。
PostgreSQLの実装では、データアクセスするときにロックする範囲を小さく絞ることで、ロックの競合が起きにくいようになっています。その結果として、CPUのコア数に比例して性能が伸びます。たとえばPostgreSQL9.2以降であれば、CPUのコア数が少なくとも64個までは、コア数に (だいたい) 比例して性能が伸びることが確認されています。
comment: ・元のテキストだと、「ロックを取得する範囲が小さい→ロックの競合が起きにくくなる」という関係を知っていないと理解ができない。多くの人にとっては決して自明なことではない。
・元のテキストだと、「ロックの競合が発生する→CPUのコア数が増えても性能が伸びない」という関係を知ってないと理解ができない。多くの人にとっては決して自明なことではない。
・「CPUスケール」という言葉は、何となくはわかるけどはっきりとはわからない言葉である。できれば、より分かりやすい言葉で言い換えたほうがよい。
- page: p.138
text: "このため、PostgreSQLにおけるCPU関連のチューニングが必要になるケースは、他のリソースと比べて限定的です。"
fixed: このため、PostgreSQLにおいてCPU関連のチューニングが必要になるケースは、他のリソース(メモリとディスクI/O)に比べると、限定的です。
comment: 「他のリソース」というのが具体的に何なのか、初心者にはわからない。具体的に列挙したほうがよい。
- page: p.139
text: "スタンバイは起動できなくなります。\nスタンバイサーバ起動時に、次のようなエラーメッセージが出力されます。"
fixed: "スタンバイは起動できなくなります。その場合、スタンバイサーバ起動時に次のようなエラーメッセージが出力されます。"
comment: ここでの改行はいらないはず。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment