Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
PostgreSQL運用管理
入門
Yoshiyuki Asaba
内容
• initdbなど基本的なところ
• process構成
• walなどの物理ファイル
• LOCK
• VACUUM/ANALYZE/REINDEX
• EXPLAINの見方
• backup/replication
• source...
基本
バージョン番号
• PostgreSQL x.y.zというバージョン番号が付く
• x.yがメジャーバージョン(9.4がベータ版)
• 基本的にデータベースの物理ファイルに互換性がない
• zがマイナーバージョン(9.3.4)
• bugfixが...
データベースの初期化
• initdbコマンド
• 指定したディレクトリに必要なファイルを一式作成
• 設定ファイルも生成される
• initdb実行したユーザ=PostgreSQLのスーパーユーザ
• 注意:localeはCにしておくと余計な...
設定ファイル
• postgresql.conf
• PostgreSQL本体の設定
• pg_hba.conf
• 認証の設定
• recovery.conf
• あとで説明
• pg_ident.conf
• ほとんど使わないので省略
postgresql.conf
• memoryやloggingなど様々な設定が可能
• デフォルトの設定は使いものにならないので、変更
が必要
• 設定変更はreloadで済むものや、restartが必要な
物があるので注意
pg_hba.conf
• どこからの接続を許可するなどを記述
• type, database, user, address, method
• methodはtrust, reject, md5, clearなど
# "local" is ...
kernelの設定
• 共有メモリを確保するので、上限を変更する必要あ
り
• kernel.shmmax
• kernel.shmall
/etc/sysctl.conf
kernel.shmmax=21474836480
kernel.sh...
起動・停止
• pg_ctlコマンドを使う
• pg_ctl -D <initdbした場所> {start¦stop¦reload¦
restart¦promote}
• ubuntuであればsudo service postgresql
re...
process構成
プロセス
• マルチプロセスアーキテクチャ
• プロセス間通信はpipe,shmem,signal,socket
• 親プロセスはpostmasterと呼ばれる
• 基本的には停止やreloadはpostmasterにsignalを投げる
• ...
プロセス一覧
postmaster 接続受け付ける親プロセス
backend SQLを処理するプロセス
wal writer WALを定期的に書きだすプロセス
background writer
共有バッファを定期的に書きだすプロセス
(昔はC...
シグナル
• postmaster
SIGTERM 全クライアントが終了するまで待つ(smart shutdown)
SIGINT
接続中のクライアントのトランザクションをabortして
shutdown(fast shutdown)
SIGQ...
メモリ
• 共有メモリ
• 共有バッファ、WALバッファ、複数プロセスで共有さ
れる内部データ
• ヒープメモリ
• sort等のクエリ実行時に使われるプロセス固有の作業
空間
共有メモリ
• 起動時にまとめてガツンと確保
• shared buffer
• WAL buffer
• LOCK領域
• 9.4から挙動が変わるかも?
[vagrant@precise64] /head/data % ipcs -a
-----...
共有バッファ
• すべてのデータ操作は必ず共有バッファを通る
• 操作はブロック(8KB)単位
共有バッファ
物理ファ
イル
物理ファ
イル
物理ファ
イル
postgres
postgres
WAL/
CLOG
write
read/write
monitoring
統計情報収集プロセス
• PostgreSQL自身で、どんな処理をどれだけしたか
などを記録している
• autovacuumはこのデータを見ている
• stats collector processがそのプロセス
• http://www.p...
monitoring例
• 接続中のユーザ数を調べる
• SELECT * FROM pg_stat_activity;
• キャッシュヒット率を調べる
• test DBの情報を見る
test=# select heap_blks_hit::...
LOCK
ロックの粒度
• spin lock
• LWLOCK(lightweight lock)
• 行ロック
• テーブルロック
spin lock
• 一番泥臭い所
• CPUアーキテクチャごとにアセンブリ言語で書か
れている
• s_lock.h
• とても短い期間だけ取りたいロック
• SpinLockAcquire/SpinLockRelease
LWLock
• spin lockよりは重い、内部的なロック
• spin lockとsemaphoreを使って実装
行ロック
• 行に対してかかるロック
• ユーザが意識することができるロック
• 行ロックは共有ロックと排他ロックの2種類
• 共有ロックはreadは同時にできるが、排他ロッ
クが入るとブロックされる
明示的な行ロック
• 排他ロック
• SELECT … FOR UPDATE
• 共有ロック
• SELECT … FOR SHARE
テーブルロック
ロック名 競合
ACCESS SHARE ACCESS EXCLUSIVE
ROW SHARE EXCLUSIVEおよびACCESS EXCLUSIVE
ROW EXCLUSIVE
SHARE、SHARE ROW EXCLUSI...
pg_locks
• テーブルロックを誰が取っているかを見ることがで
きるビュー
test=# begin;
BEGIN
test=# lock table store;
LOCK TABLE
test=# select * from pg_l...
デッドロック検出
• postgresql.confのdeadlock_timeoutの間隔でデッドロックを検出
• ロックグラフをtopological sort
• 重いので10秒に設定してある(default 1秒)
test=# beg...
ロック周りのトラブル
• サーバが綺麗にダウンしなかった場合
• バッチサーバがOOMで落ちてしまった
• → keepaliveの設定を短くする
#tcp_keepalives_idle = 0 # TCP_KEEPIDLE, in seco...
VACUUM/
ANALYZE/REINDEX
VACUUMの必要性
• MVCC使ってトランザクションを実装しているため
• 現在のtransaction idと、行に埋まっているxminやpg_clogなどから、その行が見えても良いか
を判断(multi xactとかよくわからない概念が...
XID周回問題
• トランザクションIDは2^32(unsigned int)
• なのでオーバーフローする可能性ある
• ちゃんと対策してある
• autovacuumが勝手にXID周回問題を回避するVACUUMを流す
test=# vacu...
HOT UPDATE
• 特定の条件を満たすとHOT UPDATEという処理が走り、VACUUMを
せずに不要領域を回収する
• 詳しくはこちら
• http://lets.postgresql.jp/documents/tutorial/ho...
VACUUMチューニング
• maintenance_work_mem
• めったに使わないので、多めに設定しておいてよい
• vacuum_cost_*
• ちんたらVACUUMを動かす設定
• I/Oのピークを避けたい場合に設定
ANALYZE
• 各テーブルのカラムごとにどういうデータがあるか、
という統計情報を持っている
• pg_statsというビューで確認できる
pg_stats例1
• most common_vals
• よく出てくる値を持っている
• よく出てくる値であれば、plannerはseqscanのほうが速いと判断することもある
test=# select * from pg_stats ...
pg_stats例2
• histogram_bounds
• コスト見積もりのときに、=やbetweenでどれくらい行があるかを推定する
test=# select * from pg_stats where tablename = 't1'...
pg_stats例3
• correlation
• 物理的にどういう順番で並んでいるか
• 昇順で並んでいればいるほど1に近づく
• 降順で並んでいればいるほど-1に近づく
• ランダムだと0に近づく
REINDEX
• まれにインデックス壊れたり、インデックスが肥大
化することがあるので、作りなおすコマンド
• テーブルロックとるので、場合によってはDROP
INDEXしてからCREATE INDEX CONCURRENTLY
で作るほうが...
autovacuum
• デーモンプロセスで、更新頻度によって自動的に
VACUUMを動かす
• thresholdはテーブル単位で設定可能
#autovacuum = on # Enable autovacuum subprocess? 'o...
クエリチューニング
基本的な戦略
• 絶対的なクエリ実行時間だけを見て、チューニング
対象のクエリを探さない
• 10秒かかっているクエリが一日一回しかない場
合は、相手にしなくて良い
• 全体のうちに上位何%か占めているクエリを潰す
べき
• newrelic便利
EXPLAIN
• チューニング対象となるクエリがどうやって実行さ
れるかを確認する
• EXPLAINとEXPLAIN ANALYZE
• ANALYZEをつけると、実際にクエリを実行し
て、どこにどれだけ時間かかったかを表示
• EXPLA...
例
test=# explain select * from t1 where a < 100;
QUERY PLAN
--------------------------------------------------------------...
table scan
• seq scan
• テーブルを上から下まで全てスキャンする
• index scan
• インデックス経由でデータをフェッチ
• インデックスはbtreeやGINなど色々ある
• bitmapscanというインデック...
table join
• nested loop
• 総当りで組み合わせを作る
• merge join
• お互いをソートしておいて、

上から順番に組み合わせていく
• sortのコストがかかる
• hash join
• hash tab...
その他のプラン
• 集合演算
• Append
• Setop
• ソートやLIMIT
• Sort(TOP-N sort, quick sort, file sort)
• LIMIT
• CTE
• workscanとか
よくあるトラブル
• ANALYZEが不足していて、間違ったプランが使われる
• analyzeすること
• set enable_seqscan to offとかできるが非推奨
• インデックスがない
• 貼るしかない
• where func...
書き込みチューニング
何をチューニングするか?
• 書き込みのチューニングは結構むずい
• どこかで必ず書かないといけないので
• ただ、書き込みを分散させることで、負荷を減ら
すことは可能
• 時間を分散
• 場所を分散
いらないインデックス削除
• 使わないインデックスは書き込みに対するペナルティ
を追加しているだけ
• 使っていないものかどうかは統計情報収集プロセス
から取り出す
• pg_stat_user_indexesなどを見る
test=# sele...
CHECKPOINTを減らす
• CHECKPOINTとは、メモリにだけ書かれた変更を確実にディス
クに書き込むプロセス
• 決められた時間 or 消費したWALファイル数でCHECKPOINT
が起動
• デフォルトだとCHECKPOINTが...
sync_method
• fsync, fdata_sync, open_syncなど、syncするメ
ソッドを変更できる
• どれがいいかは実機で試さないといけない
• filesystemとか色々な条件で変わる?
やっちゃだめ
• fsync=off
• データ消える
• full_page_writes=off
• データ消える
backup/restore
backup
• コールドバックアップ
• PostgreSQLを停止して、データをバックアップ
• ホットバックアップ
• 稼働中にバックアップを取得
• 論理バックアップ
• pg_dump, pg_dumpall
• 使い方はマニュアル見...
PITR
• ある時点の物理バックアップと差分(WAL)を使って任意の時間まで戻
る
• といっても、物理バックアップより過去には戻れない
• WAL-Eという、S3にバックアップを保管するツールを使っている
• pg_basebackupとい...
戻し方
1. ベースバックアップを展開
2. recovery.confというファイルを作成し、物理ファ
イルのあるtop directoryに置く
• http://www.postgresql.jp/document/9.1/
html/r...
replication
replication設定
• マニュアルみて頑張ってください
• http://www.postgresql.jp/document/9.3/html/
warm-standby.html#STREAMING-
REPLICATION
ソースコードツアー
ディレクトリ構成
• Cで書かれています
• src/include/
• header file
• src/backend
• .cファイル
.
¦-- access transaction系
¦-- bootstrap bootstrap
¦-- catalog system catalog
¦-- commands SQLのコマンドのエントリポイント(CREATE TABLEなど...
デバッグビルド
• make, gcc, libzlib, その他パッケージが必要
• configureでこけるので、都度入れる
• gdbも入れておく(さらにいうとemacsも)
• 最適化するとデバッグめんどくさいのでoffにする
CFLAG...
test=# select pg_backend_pid();
pg_backend_pid
----------------
9574
(1 row)
% gdb -p 9574
…
(gdb) bt
#0 0x00007fe6c4d1121...
気合で頑張りましょう
Upcoming SlideShare
Loading in …5
×

PostgreSQL運用管理入門

3,993 views

Published on

ちょっと古い内容かもしれませんが、いつぞやに書いたPostgreSQL運用管理入門

Published in: Engineering
  • Be the first to comment

PostgreSQL運用管理入門

  1. 1. PostgreSQL運用管理 入門 Yoshiyuki Asaba
  2. 2. 内容 • initdbなど基本的なところ • process構成 • walなどの物理ファイル • LOCK • VACUUM/ANALYZE/REINDEX • EXPLAINの見方 • backup/replication • source code reading
  3. 3. 基本
  4. 4. バージョン番号 • PostgreSQL x.y.zというバージョン番号が付く • x.yがメジャーバージョン(9.4がベータ版) • 基本的にデータベースの物理ファイルに互換性がない • zがマイナーバージョン(9.3.4) • bugfixが中心 • たまにセキュリティ問題とかで、system catalogを書 き換えないといけないこともある
  5. 5. データベースの初期化 • initdbコマンド • 指定したディレクトリに必要なファイルを一式作成 • 設定ファイルも生成される • initdb実行したユーザ=PostgreSQLのスーパーユーザ • 注意:localeはCにしておくと余計なトラブルを回避 できる(createdbでもlocaleを設定することは可能)
  6. 6. 設定ファイル • postgresql.conf • PostgreSQL本体の設定 • pg_hba.conf • 認証の設定 • recovery.conf • あとで説明 • pg_ident.conf • ほとんど使わないので省略
  7. 7. postgresql.conf • memoryやloggingなど様々な設定が可能 • デフォルトの設定は使いものにならないので、変更 が必要 • 設定変更はreloadで済むものや、restartが必要な 物があるので注意
  8. 8. pg_hba.conf • どこからの接続を許可するなどを記述 • type, database, user, address, method • methodはtrust, reject, md5, clearなど # "local" is for Unix domain socket connections only local all all trust # IPv4 local connections: host all all 127.0.0.1/32 trust # IPv6 local connections: host all all ::1/128 trust host test test 192.168.1.0/24 md5 unix domain socket TCP
  9. 9. kernelの設定 • 共有メモリを確保するので、上限を変更する必要あ り • kernel.shmmax • kernel.shmall /etc/sysctl.conf kernel.shmmax=21474836480 kernel.shmall=5242880 sudo sysctl -p
  10. 10. 起動・停止 • pg_ctlコマンドを使う • pg_ctl -D <initdbした場所> {start¦stop¦reload¦ restart¦promote} • ubuntuであればsudo service postgresql reload {start¦stop¦reload¦restart}
  11. 11. process構成
  12. 12. プロセス • マルチプロセスアーキテクチャ • プロセス間通信はpipe,shmem,signal,socket • 親プロセスはpostmasterと呼ばれる • 基本的には停止やreloadはpostmasterにsignalを投げる • 全ての子プロセスはpostmasterからfork()される /usr/lib/postgresql/9.3/bin/postgres -D /var/lib/postgresql/9.3/main -c config_file=/etc/postgresql/9.3/main/postgresql.conf _ postgres: checkpointer process _ postgres: writer process _ postgres: wal writer process _ postgres: autovacuum launcher process _ postgres: stats collector process _ postgres: postgres test [local] idle
  13. 13. プロセス一覧 postmaster 接続受け付ける親プロセス backend SQLを処理するプロセス wal writer WALを定期的に書きだすプロセス background writer 共有バッファを定期的に書きだすプロセス (昔はCHECKPOINTも実行していた) stats collector 統計情報をUDPで受けるプロセス autovacuum vacuumやanalyzeをある閾値超えたら実行するプロセス archiver walをどこかにコピーするためのプロセス wal sender streaming replicationの送る側 wal receiver streaming replicationを受ける側 checkpointer CHECKPOINTを実行するプロセス
  14. 14. シグナル • postmaster SIGTERM 全クライアントが終了するまで待つ(smart shutdown) SIGINT 接続中のクライアントのトランザクションをabortして shutdown(fast shutdown) SIGQUIT 強制終了(immediate shutdown) 次回の起動時にリカバリが走る • postgres(backend process) SIGTERM クエリをキャンセルし、プロセスを終了する SIGINT クエリをキャンセルするだけ SIGQUIT 強制終了(postmaster以外のプロセスが再起動かかる)
  15. 15. メモリ • 共有メモリ • 共有バッファ、WALバッファ、複数プロセスで共有さ れる内部データ • ヒープメモリ • sort等のクエリ実行時に使われるプロセス固有の作業 空間
  16. 16. 共有メモリ • 起動時にまとめてガツンと確保 • shared buffer • WAL buffer • LOCK領域 • 9.4から挙動が変わるかも? [vagrant@precise64] /head/data % ipcs -a ------ Shared Memory Segments -------- key shmid owner perms bytes nattch status 0x0052fe19 655361 vagrant 600 56 5 ------ Semaphore Arrays -------- key semid owner perms nsems 0x0052fe19 5242887 vagrant 600 17 0x0052fe1a 5275656 vagrant 600 17 0x0052fe1b 5308425 vagrant 600 17 0x0052fe1c 5341194 vagrant 600 17 0x0052fe1d 5373963 vagrant 600 17 0x0052fe1e 5406732 vagrant 600 17 0x0052fe1f 5439501 vagrant 600 17 0x0052fe20 5472270 vagrant 600 17
  17. 17. 共有バッファ • すべてのデータ操作は必ず共有バッファを通る • 操作はブロック(8KB)単位 共有バッファ 物理ファ イル 物理ファ イル 物理ファ イル postgres postgres WAL/ CLOG write read/write
  18. 18. monitoring
  19. 19. 統計情報収集プロセス • PostgreSQL自身で、どんな処理をどれだけしたか などを記録している • autovacuumはこのデータを見ている • stats collector processがそのプロセス • http://www.postgresql.jp/document/9.3/html/ monitoring-stats.html
  20. 20. monitoring例 • 接続中のユーザ数を調べる • SELECT * FROM pg_stat_activity; • キャッシュヒット率を調べる • test DBの情報を見る test=# select heap_blks_hit::numeric / (heap_blks_read + heap_blks_hit)::numeric from pg_statio_user_tables where heap_blks_read <> 0; test=# select * from pg_stat_database where datname = 'test';
  21. 21. LOCK
  22. 22. ロックの粒度 • spin lock • LWLOCK(lightweight lock) • 行ロック • テーブルロック
  23. 23. spin lock • 一番泥臭い所 • CPUアーキテクチャごとにアセンブリ言語で書か れている • s_lock.h • とても短い期間だけ取りたいロック • SpinLockAcquire/SpinLockRelease
  24. 24. LWLock • spin lockよりは重い、内部的なロック • spin lockとsemaphoreを使って実装
  25. 25. 行ロック • 行に対してかかるロック • ユーザが意識することができるロック • 行ロックは共有ロックと排他ロックの2種類 • 共有ロックはreadは同時にできるが、排他ロッ クが入るとブロックされる
  26. 26. 明示的な行ロック • 排他ロック • SELECT … FOR UPDATE • 共有ロック • SELECT … FOR SHARE
  27. 27. テーブルロック ロック名 競合 ACCESS SHARE ACCESS EXCLUSIVE ROW SHARE EXCLUSIVEおよびACCESS EXCLUSIVE ROW EXCLUSIVE SHARE、SHARE ROW EXCLUSIVE、EXCLUSIVE、お よびACCESS EXCLUSIVEロ SHARE UPDATE EXCLUSIVE SHARE UPDATE EXCLUSIVE、SHARE、SHARE ROW EXCLUSIVE、EXCLUSIVE、およびACCESS SHARE ROW EXCLUSIVE、SHARE UPDATE EXCLUSIVE、 SHARE ROW EXCLUSIVE、EXCLUSIVE、および SHARE ROW EXCLUSIVE ROW EXCLUSIVE、SHARE UPDATE EXCLUSIVE、 SHARE、SHARE ROW EXCLUSIVE、EXCLUSIVE、お EXCLUSIVE ACCESS EXCLUSIVE http://www.postgresql.jp/document/9.3/html/explicit-locking.html
  28. 28. pg_locks • テーブルロックを誰が取っているかを見ることがで きるビュー test=# begin; BEGIN test=# lock table store; LOCK TABLE test=# select * from pg_locks; locktype ¦ database ¦ relation ¦ page ¦ tuple ¦ virtualxid ¦ transactionid ¦ classid ¦ objid ¦ objsubid ¦ virtualtransaction ¦ pid ¦ mode ¦ granted ¦ fastpath ------------+----------+----------+------+-------+------------+---------------+---------+-------+----------+--------------------+------ +---------------------+---------+---------- relation ¦ 96179 ¦ 11090 ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ 2/9246 ¦ 4362 ¦ AccessShareLock ¦ t ¦ t virtualxid ¦ ¦ ¦ ¦ ¦ 2/9246 ¦ ¦ ¦ ¦ ¦ 2/9246 ¦ 4362 ¦ ExclusiveLock ¦ t ¦ t relation ¦ 96179 ¦ 98466 ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ 2/9246 ¦ 4362 ¦ AccessExclusiveLock ¦ t ¦ f (3 rows)
  29. 29. デッドロック検出 • postgresql.confのdeadlock_timeoutの間隔でデッドロックを検出 • ロックグラフをtopological sort • 重いので10秒に設定してある(default 1秒) test=# begin; BEGIN test=# lock table t2; LOCK TABLE test=# lock table t1; LOCK TABLE test=# test=# begin; BEGIN test=# lock table t1; LOCK TABLE test=# lock table t2; ERROR: deadlock detected DETAIL: Process 4405 waits for AccessExclusiveLock on relation 370301 of database 96179; blocked by process 4397. Process 4397 waits for AccessExclusiveLock on relation 370298 of database 96179; blocked by process 4405. HINT: See server log for query details.
  30. 30. ロック周りのトラブル • サーバが綺麗にダウンしなかった場合 • バッチサーバがOOMで落ちてしまった • → keepaliveの設定を短くする #tcp_keepalives_idle = 0 # TCP_KEEPIDLE, in seconds; # 0 selects the system default #tcp_keepalives_interval = 0 # TCP_KEEPINTVL, in seconds; # 0 selects the system default #tcp_keepalives_count = 0 # TCP_KEEPCNT; # 0 selects the system default
  31. 31. VACUUM/ ANALYZE/REINDEX
  32. 32. VACUUMの必要性 • MVCC使ってトランザクションを実装しているため • 現在のtransaction idと、行に埋まっているxminやpg_clogなどから、その行が見えても良いか を判断(multi xactとかよくわからない概念が入ってきて、もっと複雑) • 不要領域の回収をVACUUMが行う test=# begin; BEGIN test=# insert into t1 values (1); INSERT 0 1 test=# insert into t1 values (2); INSERT 0 1 test=# commit; COMMIT test=# select xmin, cmin, xmax, cmax, a from t1; xmin ¦ cmin ¦ xmax ¦ cmax ¦ a --------+------+------+------+--- 182983 ¦ 0 ¦ 0 ¦ 0 ¦ 1 182983 ¦ 1 ¦ 0 ¦ 1 ¦ 2 (2 rows) test=# select xmin, cmin, xmax, cmax, a from t1; xmin ¦ cmin ¦ xmax ¦ cmax ¦ a --------+------+--------+------+--- 182983 ¦ 0 ¦ 182984 ¦ 0 ¦ 1 182983 ¦ 0 ¦ 182984 ¦ 0 ¦ 2 (2 rows) INSERT DELETE (実際には削除されずに残る)
  33. 33. XID周回問題 • トランザクションIDは2^32(unsigned int) • なのでオーバーフローする可能性ある • ちゃんと対策してある • autovacuumが勝手にXID周回問題を回避するVACUUMを流す test=# vacuum freeze t1;; VACUUM test=# select xmin, cmin, xmax, cmax, a from t1; xmin ¦ cmin ¦ xmax ¦ cmax ¦ a ------+------+------+------+--- 2 ¦ 0 ¦ 0 ¦ 0 ¦ 1 2 ¦ 0 ¦ 0 ¦ 0 ¦ 2 (2 rows)
  34. 34. HOT UPDATE • 特定の条件を満たすとHOT UPDATEという処理が走り、VACUUMを せずに不要領域を回収する • 詳しくはこちら • http://lets.postgresql.jp/documents/tutorial/hot_1/ • ざっくりいうと • 各ページを更新用に少しスペースを開けておく(fillfactorを設定する) • インデックス貼っていない行を更新すること • トランザクションを開きっぱなしにしない
  35. 35. VACUUMチューニング • maintenance_work_mem • めったに使わないので、多めに設定しておいてよい • vacuum_cost_* • ちんたらVACUUMを動かす設定 • I/Oのピークを避けたい場合に設定
  36. 36. ANALYZE • 各テーブルのカラムごとにどういうデータがあるか、 という統計情報を持っている • pg_statsというビューで確認できる
  37. 37. pg_stats例1 • most common_vals • よく出てくる値を持っている • よく出てくる値であれば、plannerはseqscanのほうが速いと判断することもある test=# select * from pg_stats where tablename = 't1'; -[ RECORD 1 ]----------+-------------------------- schemaname ¦ public tablename ¦ t1 attname ¦ a inherited ¦ f null_frac ¦ 0 avg_width ¦ 4 n_distinct ¦ 3 most_common_vals ¦ {0,2,1} most_common_freqs ¦ {0.337,0.331633,0.331367} histogram_bounds ¦ correlation ¦ 0.330139 most_common_elems ¦ most_common_elem_freqs ¦ elem_count_histogram ¦ 最頻値 割合 test=# insert into t1 select i % 3 from generate_series(1, 100000) as i; INSERT 0 100000 test=# analyze;
  38. 38. pg_stats例2 • histogram_bounds • コスト見積もりのときに、=やbetweenでどれくらい行があるかを推定する test=# select * from pg_stats where tablename = 't1'; -[ RECORD 1 ]---------- +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------- schemaname ¦ public tablename ¦ t1 attname ¦ a inherited ¦ f null_frac ¦ 0 avg_width ¦ 4 n_distinct ¦ -1 most_common_vals ¦ most_common_freqs ¦ histogram_bounds ¦ {62,10654,21336,31180,41045,51219,60253,69810,80088,89617,99667,109195,119385,128797,139121,148759,158234,168133,1 77878,188918,199286,208736,218954,229307,… correlation ¦ 1 most_common_elems ¦ most_common_elem_freqs ¦ elem_count_histogram ¦
  39. 39. pg_stats例3 • correlation • 物理的にどういう順番で並んでいるか • 昇順で並んでいればいるほど1に近づく • 降順で並んでいればいるほど-1に近づく • ランダムだと0に近づく
  40. 40. REINDEX • まれにインデックス壊れたり、インデックスが肥大 化することがあるので、作りなおすコマンド • テーブルロックとるので、場合によってはDROP INDEXしてからCREATE INDEX CONCURRENTLY で作るほうが停止時間が少ないかも
  41. 41. autovacuum • デーモンプロセスで、更新頻度によって自動的に VACUUMを動かす • thresholdはテーブル単位で設定可能 #autovacuum = on # Enable autovacuum subprocess? 'on' # requires track_counts to also be on. #log_autovacuum_min_duration = -1 # -1 disables, 0 logs all actions and # their durations, > 0 logs only # actions running at least this number # of milliseconds. #autovacuum_max_workers = 3 # max number of autovacuum subprocesses # (change requires restart) #autovacuum_naptime = 1min # time between autovacuum runs #autovacuum_vacuum_threshold = 50 # min number of row updates before # vacuum #autovacuum_analyze_threshold = 50 # min number of row updates before # analyze #autovacuum_vacuum_scale_factor = 0.2 # fraction of table size before vacuum #autovacuum_analyze_scale_factor = 0.1 # fraction of table size before analyze #autovacuum_freeze_max_age = 200000000 # maximum XID age before forced vacuum # (change requires restart) #autovacuum_vacuum_cost_delay = 20ms # default vacuum cost delay for # autovacuum, in milliseconds; # -1 means use vacuum_cost_delay #autovacuum_vacuum_cost_limit = -1 # default vacuum cost limit for # autovacuum, -1 means use # vacuum_cost_limit
  42. 42. クエリチューニング
  43. 43. 基本的な戦略 • 絶対的なクエリ実行時間だけを見て、チューニング 対象のクエリを探さない • 10秒かかっているクエリが一日一回しかない場 合は、相手にしなくて良い • 全体のうちに上位何%か占めているクエリを潰す べき • newrelic便利
  44. 44. EXPLAIN • チューニング対象となるクエリがどうやって実行さ れるかを確認する • EXPLAINとEXPLAIN ANALYZE • ANALYZEをつけると、実際にクエリを実行し て、どこにどれだけ時間かかったかを表示 • EXPLAINはコストを出すのみ
  45. 45. 例 test=# explain select * from t1 where a < 100; QUERY PLAN ---------------------------------------------------------------------- Index Only Scan using t1_a on t1 (cost=0.42..10.16 rows=99 width=4) Index Cond: (a < 100) (2 rows) test=# explain analyze select * from t1 where a < 100; QUERY PLAN ----------------------------------------------------------------------------------------------------------------- Index Only Scan using t1_a on t1 (cost=0.42..10.16 rows=99 width=4) (actual time=0.017..0.513 rows=99 loops=1) Index Cond: (a < 100) Heap Fetches: 99 Total runtime: 1.502 ms (4 rows)
  46. 46. table scan • seq scan • テーブルを上から下まで全てスキャンする • index scan • インデックス経由でデータをフェッチ • インデックスはbtreeやGINなど色々ある • bitmapscanというインデックスを組み合わせる
 プランもある • index only scan • インデックスだけを見てデータをフェッチ テーブルデータ インデックスデータ テーブルデータ インデックスデータ
  47. 47. table join • nested loop • 総当りで組み合わせを作る • merge join • お互いをソートしておいて、
 上から順番に組み合わせていく • sortのコストがかかる • hash join • hash tableを使う • メモリ食う 1 4 2 4 8 1 1 2 4 1 4 8 sort済み 1 2 4 1 4 8 hash table
  48. 48. その他のプラン • 集合演算 • Append • Setop • ソートやLIMIT • Sort(TOP-N sort, quick sort, file sort) • LIMIT • CTE • workscanとか
  49. 49. よくあるトラブル • ANALYZEが不足していて、間違ったプランが使われる • analyzeすること • set enable_seqscan to offとかできるが非推奨 • インデックスがない • 貼るしかない • where func(hoge) = 3みたいなのは、関数インデックスが必要 • table joinが遅い • 先に絞り込んでからtable joinすると速くなるケースが結構ある • work_memを増やす • テーブルスキーマ変更はコスト大なので、よく考えてから実施すること
  50. 50. 書き込みチューニング
  51. 51. 何をチューニングするか? • 書き込みのチューニングは結構むずい • どこかで必ず書かないといけないので • ただ、書き込みを分散させることで、負荷を減ら すことは可能 • 時間を分散 • 場所を分散
  52. 52. いらないインデックス削除 • 使わないインデックスは書き込みに対するペナルティ を追加しているだけ • 使っていないものかどうかは統計情報収集プロセス から取り出す • pg_stat_user_indexesなどを見る test=# select * from pg_stat_user_indexes where idx_scan = 0;
  53. 53. CHECKPOINTを減らす • CHECKPOINTとは、メモリにだけ書かれた変更を確実にディス クに書き込むプロセス • 決められた時間 or 消費したWALファイル数でCHECKPOINT が起動 • デフォルトだとCHECKPOINTが頻発するので、60min, 64 ファイルで設定している • CHECKPOINT中は全力でディスクに書き込んでいくので、ち んたら動かすようにする (checkpoint_completion_target=0.9)
  54. 54. sync_method • fsync, fdata_sync, open_syncなど、syncするメ ソッドを変更できる • どれがいいかは実機で試さないといけない • filesystemとか色々な条件で変わる?
  55. 55. やっちゃだめ • fsync=off • データ消える • full_page_writes=off • データ消える
  56. 56. backup/restore
  57. 57. backup • コールドバックアップ • PostgreSQLを停止して、データをバックアップ • ホットバックアップ • 稼働中にバックアップを取得 • 論理バックアップ • pg_dump, pg_dumpall • 使い方はマニュアル見て • 物理バックアップ • Point In Time Recovery • 慣れないとめんどくさい
  58. 58. PITR • ある時点の物理バックアップと差分(WAL)を使って任意の時間まで戻 る • といっても、物理バックアップより過去には戻れない • WAL-Eという、S3にバックアップを保管するツールを使っている • pg_basebackupというツールもある wal_level=archive or hot standby archive_mode=on archive_command= walをコピーするコマンド postgresql.conf test=# select pg_start_backup('hoge'); pg_start_backup ----------------- 6/28000028 (1 row) (ここでtarとか使って物理バックアップ) test=# select pg_stop_backup(); pg_stop_backup ---------------- 6/280000B8 (1 row)
  59. 59. 戻し方 1. ベースバックアップを展開 2. recovery.confというファイルを作成し、物理ファ イルのあるtop directoryに置く • http://www.postgresql.jp/document/9.1/ html/recovery-target-settings.html 3. postmasterを起動
  60. 60. replication
  61. 61. replication設定 • マニュアルみて頑張ってください • http://www.postgresql.jp/document/9.3/html/ warm-standby.html#STREAMING- REPLICATION
  62. 62. ソースコードツアー
  63. 63. ディレクトリ構成 • Cで書かれています • src/include/ • header file • src/backend • .cファイル
  64. 64. . ¦-- access transaction系 ¦-- bootstrap bootstrap ¦-- catalog system catalog ¦-- commands SQLのコマンドのエントリポイント(CREATE TABLEなど) ¦-- executor SQL実行エンジン ¦-- foreign foreign data wrapper ¦-- lib library ¦-- libpq libpqというクライアントライブラリ ¦-- main main ¦-- nodes parseしたnodeを操作する関数群 ¦-- optimizer コストの計算やplanを組み立てたりするplanner ¦-- parser parser ¦-- port portingに必要なコード ¦-- postmaster postmaster(サーバプロセス)のコード。autovacuumなども ¦-- regex 正規表現 ¦-- replication replication ¦-- rewrite viewやruleでクエリを書き換えるrule engine ¦-- storage storage周り。ロックも。 ¦-- tcop postgresプロセスのmain ¦-- tsearch 全文検索 `-- utils 多言語や色々な型、ソートなどを定義
  65. 65. デバッグビルド • make, gcc, libzlib, その他パッケージが必要 • configureでこけるので、都度入れる • gdbも入れておく(さらにいうとemacsも) • 最適化するとデバッグめんどくさいのでoffにする CFLAGS=-O0 ./configure ̶prefix=$HOME/debug make install initdb -D $HOME/debug/data pg_ctl -D $HOME/debug/data start
  66. 66. test=# select pg_backend_pid(); pg_backend_pid ---------------- 9574 (1 row) % gdb -p 9574 … (gdb) bt #0 0x00007fe6c4d1121d in __libc_recv (fd=10, buf=0xcc09e0 <PqRecvBuffer>, n=8192, flags=-1) at ../sysdeps/unix/sysv/linux/x86_64/recv.c:29 #1 0x000000000064a848 in secure_read (port=0x16dbf10, ptr=0xcc09e0 <PqRecvBuffer>, len=8192) at be-secure.c:317 #2 0x00000000006561a5 in pq_recvbuf () at pqcomm.c:854 #3 0x000000000065623f in pq_getbyte () at pqcomm.c:895 #4 0x000000000075c002 in SocketBackend (inBuf=0x7fffe4adbdb0) at postgres.c:335 #5 0x000000000075c3dc in ReadCommand (inBuf=0x7fffe4adbdb0) at postgres.c:483 #6 0x0000000000760d93 in PostgresMain (argc=1, argv=0x16bc438, dbname=0x16bc2e8 "postgres", username=0x16bc2d0 "y-asaba") at postgres.c:3965 #7 0x00000000006f313a in BackendRun (port=0x16dbf10) at postmaster.c:4117 #8 0x00000000006f283f in BackendStartup (port=0x16dbf10) at postmaster.c:3791 #9 0x00000000006ef259 in ServerLoop () at postmaster.c:1570 #10 0x00000000006ee90f in PostmasterMain (argc=3, argv=0x16bb530) at postmaster.c:1223 #11 0x000000000065849c in main (argc=3, argv=0x16bb530) at main.c:225
  67. 67. 気合で頑張りましょう

×