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.

Chugoku db 20th-postgresql-10-pub

732 views

Published on

PostgreSQL 10 feature(Logical Replcation, Delective Partition)

Published in: Technology
  • Be the first to comment

Chugoku db 20th-postgresql-10-pub

  1. 1. 中国地方中国地方 DBDB 勉強会勉強会 20162016 (2017-04-08)(2017-04-08) PostgreSQL 10PostgreSQL 10 がが やってくる!やってくる! ぬこ@横浜ぬこ@横浜 (@nuko_yokohama)(@nuko_yokohama)
  2. 2. 2 自己紹介 「 PostgreSQL ラーメン」 でググってください。 ねぎ中華@山富士ねぎ中華@山富士
  3. 3. 3 日本の PostgreSQL コミュニティ内で 自称ゆる枠担当やってる PostgreSQL 好きのフレンズです。
  4. 4. 4 今日は JPUG 枠として 中国ちほー DB 勉強会へ 参加することとなりました。 PostgreSQL のくだらない使い方を 日々考えています https://github.com/nuko-yokohama/pg_reversi
  5. 5. 5 今日は JPUG 枠として 中国ちほー DB 勉強会へ 参加しました。
  6. 6. 6 目次 PostgreSQL の概要と歴史 PostgreSQL 10 の新機能 Logical Replication Delective Partition Others
  7. 7. 7 PostgreSQL の 概要と歴史
  8. 8. 8 MySQL と並ぶ OSS DBMS ライセンスは BSD ライクなもの 高度なクエリにも対応 性能面でも商用 DBMS とも遜色なし 9.0 以降はレプリケーションも対応 非常に高い拡張性 活発な開発コミュニティ
  9. 9. 9 9.0 レプリケーション ストアド改良 列トリガ 排他制約 64bit Windows 対応 9.1 同期レプリケーション 外部データラッパ (FDW) WITH 句+更新文 UNLOGGED TABLE 9.2 パフォーマンス向上 カスケードレプリケーション Index Only Scan 範囲型サポート JSON 型サポート 9.3 マテリアライズドビュー 更新可能ビュー 更新 FDW JSON 型の機能拡張 エンタープライズ向け用途エンタープライズ向け用途 実験的な高度な機能実験的な高度な機能 2010 年 2011 年 2012 年 2013 年 PostgreSQL の歴史( 9.0 ~) レプリケーションが追加されてから もう 5 年以上になったのだなあ End of Life ←
  10. 10. 10 9.4 JSONB ALTER SYSTEM マテビュー改善 ロジカル・デコーディング WAL バッファ並列挿入 9.5 BRIN UPSERT Row Level Security Import foreign schema pg_rewind 9.6 パラレルクエリ 複数同期スタンバイサーバ フレーズ検索 postgres_fdw 改善 もちろん性能改善も 9.4, 9.5, 9.69.4, 9.5, 9.6 と順調に成長と順調に成長 そして・・・そして・・・ 2014 年 2015 年 2016 年 PostgreSQL の歴史( 9.4 ~) 9.6 で待望の パラレルクエリが!
  11. 11. 11 そしてそして PostgreSQL 10!PostgreSQL 10!
  12. 12. 12 すごくどうでもいいけど、 PostgreSQL 10 って 「ぽすぐれてん」なのか 「ぽすぐれじゅう」なのか。 Oracle の場合、 “ ”おらくるテン なのか、 “ ”おらくるじゅう なのか
  13. 13. 13 PostgreSQL 10( 開発中 ) 開発自体は昨年から開始 数回の commitfest で取り込む機能を議論 2016/09, 11 commit fest 2017/01, 03 commit fest 2017/05 beta release? ・・・ 2017/09 PostgreSQL 10 リリース予定?
  14. 14. 14 PostgreSQL 10 のリリース情報 https://twitter.com/sawada_masahiko/status/844933525807640576 なので、 6 月くらいに呼んでもらえると スケジュール的に 一番良かったりします。
  15. 15. 15 PostgreSQL 10 の 新機能 ( 予定 ) まだ beta 版も出ていない状況なので 細かい仕様等は今後、変更される 可能性はあります。
  16. 16. 16 Logical Replication Declarative Partitioning Others... PostgreSQL 10 主な新機能
  17. 17. 17 Logical Replication
  18. 18. 18 Physical と Logical 複製(物理)と複製(論理) 物理削除と論理削除 物理休暇と論理休暇 マジカル ( 物理 ) とロジカル ( 論理 ) Logical Replication
  19. 19. 19 Physical Replication Log Shipping Streaming Replication(9.0-) WAL の物理コピーを転送 転送された WAL を適用 データベースクラスタ全体が対象 Logical Replication
  20. 20. 20 Logical Replication 外部レプリケーション製品 pgpool-II, Slony-I Logical Decoding(9.4-) Bi-Direction Replication Logical Replication(10-) Logical Replication
  21. 21. 21 Logical Decoding のイメージ Logical Replication Replication Slot WAL テーブル 変換プラグイン ユーザ定義 論理 ログ 論理ログの 適用プログラム PostgreSQL/ その他 DBMS 更新 プラグイン開発 / インストール
  22. 22. 22 Logical Replication のイメージ Logical Replication Replication Slot WAL テーブル レプリケーション用 標準プラグイン (pgoutput) 論理 ログ サブスクライバ PostgreSQL 更新 PUBLICATION 定義 SUBSCRIPTION 定義 Logical Decoding の基盤を使って、 PostgreSQL 間のレプリケーション専用に 使いやすくした、というイメージ
  23. 23. 23 Logical Replication の基本パターン 1 あるテーブルのみを複製する Logical Replication PostgreSQL server (srv2) (port=5433) tokyo DBkanagawa DB machida table machida table SUBSCRIPTION sub_kanagawa_machida PUBLICATION pub_kanagawa_machida client PostgreSQL server (srv1) (port=5432) Replication Protocol yokohama table 接続
  24. 24. 24 大まかな手順 postgresql.conf の設定 pg_hba.conf の設定 データベース / テーブルの作成 Logical Replication の設定 Logical Replication
  25. 25. 25 postgresql.conf の設定 wal_level = logical max_wal_senders = 3 # 0 より大きい数 max_replication_slots = 3 # 0 より大きい数 PUBLICATION を設定する上流側サーバ のみ設定しておけば OK. Logical Replication
  26. 26. 26 pg_hba.conf の設定 通常の Streaming Replication 用設定と同じで OK. レプリケーション専用ユーザを使う場合には、別途レプリ ケーション権限をもつユーザを作成しておく必要がある。 Logical Replication # Allow replication connections from localhost, by a user with the # replication privilege. local replication postgres trust この例では postgres ユーザで 接続してるけど、本当は レプリケーション専用ユーザを 作る方がいいです。
  27. 27. 27 データベース / テーブルの作成 Logical Replication はデータベース単 位に設定する(重要!) 複製先に Logical Replication 対象の テーブルを持つデータベースがなけれ ば作成する。 Logical Replication
  28. 28. 28 Logical Replication の設定 複製元サーバ 複製したい対象のテーブルを選んで、 CREATE PUBLICATION を実行する。 デフォルトでは、挿入 / 更新 / 削除の全更新種別の情報 が複製される。 明示的に複製させない更新種別を指定可能。 複製先サーバ PUBLICATION が存在するデータベースへ接続し、更新 情報を受信する CREATE SUBSCRIPTION を実行する。 Logical Replication
  29. 29. 29 Logical Replication の SQL コマンド CREATE/ALTER/DROP PUBLICATION CREATE/ALTER/DROP SUBSCRIPTION Logical Replication
  30. 30. 30 CREATE PUBLICATION syntax https://www.postgresql.org/docs/devel/static/sql-createpublication.html Logical Replication CREATE PUBLICATION name [ FOR TABLE table_name [, ...] | FOR ALL TABLES ] [ WITH ( option [, ... ] ) ] where option can be: PUBLISH INSERT | NOPUBLISH INSERT | PUBLISH UPDATE | NOPUBLISH UPDATE | PUBLISH DELETE | NOPUBLISH DELETE
  31. 31. 31 CREATE SUBSCRIPTION syntax https://www.postgresql.org/docs/devel/static/sql-createsubscription.html Logical Replication CREATE SUBSCRIPTION subscription_name CONNECTION 'conninfo' PUBLICATION { publication_name [, ...] } [ WITH ( option [, ... ] ) ] where option can be: | ENABLED | DISABLED | CREATE SLOT | NOCREATE SLOT | SLOT NAME = slot_name | COPY DATA | NOCOPY DATA | NOCONNECT
  32. 32. 32 Logical Replication の設定例 テーブルの作成 Logical Replication psql -p 5432 -U postgres kanagawa -c "CREATE TABLE machida(id int primary key, pref text, data text)" psql -p 5432 -U postgres kanagawa -c "CREATE TABLE yokohama(id int primary key, pref text, data text)" psql -p 5433 -U postgres tokyo -c "CREATE TABLE machida(id int primary key, pref text, data text)" PUBLICATION を srv1 の kanagawa DB に作成 対象は machida テーブルのみ psql -p 5432 -U postgres kanagawa -c "CREATE PUBLICATION pub_kanagawa_m achida FOR TABLE machida" SUBSCRIPTION を srv2 の tokyo DB に作成 psql -p 5432 -U postgres tokyo -c "CREATE SUBSCRIPTION sub_kanagawa_ machida CONNECTION 'dbname=kanagawa port=5432 user=postgres' PUBLICATION pub_kanagawa_machida"
  33. 33. 33 Logical Replication の基本パターン 1 (再掲) Logical Replication PostgreSQL server (srv2) (port=5433) tokyo DBkanagawa DB machida table machida table SUBSCRIPTION sub_kanagawa_machida PUBLICATION pub_kanagawa_machida client PostgreSQL server (srv1) (port=5432) Replication Protocol yokohama table “ ”パブリッシャー と呼ぶ “ ”サブスクライバ と呼ぶ 接続
  34. 34. 34 設定の確認方法 srv1 の kanagawa DB に接続。 psql メタコマンド dRp で PUBLICATION を確認 Logical Replication psql -p 5432 -U postgres kanagawa -c "dRp" List of publications Name | Owner | Inserts | Updates | Deletes ----------------------+----------+---------+---------+--------- pub_kanagawa_machida | postgres | t | t | t srv2 の tokyo DB に接続 psql メタコマンド dRs で SUBSCRIPTION を確認 psql -p 5433 -U postgres tokyo -c "dRs" List of subscriptions Name | Owner | Enabled | Publication ----------------------+----------+---------+------------------------ sub_kanagawa_machida | postgres | t | {pub_kanagawa_machida}
  35. 35. 35 レプリケーションの例 ( 挿入 ) パブリッシャー (srv1) の kanagawa DB にログイン machida テーブルに挿入し、直後に検索 Logical Replication psql -p 5432 -U postgres kanagawa -c "INSERT INTO machida VALUES (1, 'kanagawa', 'Naruse'),(2, 'kanagawa', 'Machida')" INSERT 0 2 psql -p 5433 -U postgres tokyo -c "TABLE machida" id | pref | data ----+----------+--------- 1 | kanagawa | Naruse 2 | kanagawa | Machida サブスクライバ (srv2) の tokyo DB に接続 machida テーブルに挿入内容が伝播している。 psql -p 5433 -U postgres tokyo -c "TABLE machida" id | pref | data ----+----------+--------- 1 | kanagawa | Naruse 2 | kanagawa | Machida
  36. 36. 36 レプリケーションの例 ( 更新と削除 ) パブリッシャー (srv1) の kanagawa DB にログイン machida テーブルへ更新 / 削除して、直後に検索 Logical Replication psql -p 5432 -U postgres kanagawa -c "UPDATE machida SET data = 'Nyaruse' WHERE id = 1" UPDATE 1 psql -p 5432 -U postgres kanagawa -c "DELETE FROM machida WHERE id = 2" DELETE 1 psql -p 5432 -U postgres kanagawa -c "TABLE machida" id | pref | data ----+----------+--------- 1 | kanagawa | Nyaruse サブスクライバ (srv2) 側にも 更新 / 削除内容が伝播している。 psql -p 5433 -U postgres tokyo -c "TABLE machida" id | pref | data ----+----------+--------- 1 | kanagawa | Nyaruse
  37. 37. 37 レプリケーションされない例 パブリッシャー (srv1) の kanagawa DB にログイン machida テーブルを TRUNCATE し、直後に検索 Logical Replication psql -p 5432 -U postgres kanagawa -c "TRUNCATE machida" TRUNCATE TABLE psql -p 5432 -U postgres kanagawa -c "TABLE machida" id | pref | data ----+------+------ (0 rows) サブスクライバ (srv2) 側は・・・ TRUNCATE されていない! psql -p 5433 -U postgres tokyo -c "TABLE machida" id | pref | data ----+----------+--------- 1 | kanagawa | Nyaruse (1 row) 現状、 Logical Replication では TRUNCATE は未対応!
  38. 38. 38 レプリケーションされないもの TRUNCATE 文 DDL(CREATE/ALTER/DROP 等 ) VACUUM, ANALYZE などの運用系コマンド Logical Replication は DML しか対応し ていないので要注意。 なお、 Streaming Replication は TRUNCATE も DDL も対応している。 Logical Replication
  39. 39. 39 ロジカルレプリケーションの メタデータ Logical Replication
  40. 40. 40 パブリッシャー定義 pg_publication pg_publication_rel pg_publication_tables (view) サブスクライバ定義 pg_subscription pg_subscription_rel オリジン定義 pg_replication_origin Logical Replication
  41. 41. 41 レプリケーション状態の情報 pg_stat_replication (SUBSCRIPTION の状態表示) pg_stat_subscription pg_replication_origin_status Logical Replication
  42. 42. 42 Logical Replication における Conflict Logical Replication
  43. 43. 43 Logical Replication の Conflict Logical Replication PostgreSQL server (srv2) (port=5433) tokyo DBkanagawa DB machida table machida table SUBSCRIPTION sub_kanagawa_machida PUBLICATION pub_kanagawa_machida client PostgreSQL server (srv1) (port=5432) Replication Protocol yokohama table “ ”パブリッシャー と呼ぶ “ ”サブスクライバ と呼ぶ key=x のレコードを 先に挿入 key=x のレコードを 後で挿入 接続
  44. 44. 44 INSERT の Conflict 例 srv1 と srv2 の machida テーブルが同期している状態 Logical Replication psql -p 5432 -U postgres kanagawa -c "TABLE machida" id | pref | data ----+----------+--------- 1 | kanagawa | Naruse 2 | kanagawa | Machida この状態で srv2 の machida テーブルに id=3 のレコード を先に挿入しておく psql -p 5433 -U postgres tokyo -c "TABLE machida" id | pref | data ----+----------+--------- 1 | kanagawa | Naruse 2 | kanagawa | Machida psql -p 5433 -U postgres tokyo -c "INSERT INTO machida VALUES (3, 'tokyo', 'Kobuchi')" INSERT 0 1 To be continued
  45. 45. 45 INSERT の Conflict 例 srv1 に id=3 のレコードを挿入すると・・・ Logical Replication psql -p 5432 -U postgres kanagawa -c "TABLE machida" id | pref | data ----+----------+--------- 1 | kanagawa | Naruse 2 | kanagawa | Machida 3 | kanagawa | Kobuchi この状態で srv1 と srv2 の machida テーブルを参照する とこうなる。 psql -p 5433 -U postgres tokyo -c "TABLE machida" id | pref | data ----+----------+--------- 1 | kanagawa | Naruse 2 | kanagawa | Machida 3 | tokyo | Kobuchi psql -p 5432 -U postgres kanagawa -c "INSERT INTO machida VALUES (3, 'kanagawa', 'Kobuchi')" INSERT 0 1 psql -p 5432 -U postgres kanagawa -c "INSERT INTO machida VALUES (3, 'kanagawa', 'Kobuchi')" INSERT 0 1 ConfilictConfilict 発生!発生!
  46. 46. 46 INSERT の Conflict 発生時のログ パブリッシャー側のサーバログ Logical Replication 2017-04-01 15:05:25.470 JST [63830] LOG: logical decoding found consistent point at 0/172D268 2017-04-01 15:05:25.470 JST [63830] DETAIL: There are no running transactions. 2017-04-01 15:05:25.476 JST [63830] LOG: unexpected EOF on standby connection 2017-04-01 15:05:30.490 JST [63833] LOG: starting logical decoding for slot "sub_kanagawa_machida" 2017-04-01 15:05:30.490 JST [63833] DETAIL: streaming transactions committing after 0/172D2A0, reading WAL from 0/172D268 2017-04-01 15:05:25.475 JST [63829] ERROR: duplicate key value violates unique constraint "machida_pkey" 2017-04-01 15:05:25.475 JST [63829] DETAIL: Key (id)=(3) already exists. 2017-04-01 15:05:25.476 JST [1994] LOG: worker process: logical replication worker for subscription 16425 (PID 63829) exited with exit code 1 サブスクライバ側のサーバログ
  47. 47. 47 Conflict が起きたときに、どうやって解 決するのか。 Logical Replication https://www.postgresql.org/docs/devel/static/logical-replication-conflicts.html 競合によってエラーが発生し、レプリケーションが停止します。 ユーザーが手動で解決する必要があります。 競合の詳細は、サブスクライバのサーバログにあります。 マジすか・・・ ユーザーがユーザーが 手動で解決する手動で解決する 必要があります必要があります !!!!!!
  48. 48. 48 解決方法は 2 つある。 Logical Replication https://www.postgresql.org/docs/devel/static/logical-replication-conflicts.html この解決は、サブスクライバのデータを到着する変更と競合しないように修正す るか、または既存のデータと競合するトランザクションをスキップすることに よって行うことができます。
  49. 49. 49 サブスクライバ側で解決する例 srv2 側の id=3 のレコードを削除する。 Logical Replication psql -p 5433 -U postgres tokyo -c "DELETE FROM machida WHERE id=3" DELETE 1 しばらくすると、 srv1 側に挿入された id=3 レコードが 反映される。 psql -p 5433 -U postgres tokyo -c "TABLE machida" id | pref | data ----+----------+--------- 1 | kanagawa | Naruse 2 | kanagawa | Machida psql -p 5433 -U postgres tokyo -c "TABLE machida" id | pref | data ----+----------+--------- 1 | kanagawa | Naruse 2 | kanagawa | Machida 3 | kanagawa | Kobuchi 削除直後に参照すると id=3 のレコードは消えているが
  50. 50. 50 サブスクライバの更新を優先したいとき は、どうすればいいの? Logical Replication パブリッシャー側は、パブリッシャーの更新が優先されるべきと主張している。 しかしちょっと待って欲しい。パブリッシャーの更新が優先されるべきと主張す るには早計に過ぎないか。 パブリッシャーの真摯な姿勢が、今ひとつ伝わってこない。 例えばサブスクライバからはサブスクライバの更新が優先される場合もあるので はないかと主張するような声もある。 このような声にパブリッシャーは謙虚に耳を傾けるべきではないか。 (天声人語風に)
  51. 51. 51 PostgreSQL 文書にはこう書いてあるが・・・ Logical Replication https://www.postgresql.org/docs/devel/static/logical-replication-conflicts.html サブスクリプション名に対応する node_name と位置を指定して pg_replication_origin_advance() 関数を呼び出すと、トランザクションをス キップできます。 オリジンの現在の位置は、 pg_replication_origin_status シス テムビューに表示されます。 いきなり node_name とか オリジンとか言われても わかんねーよ・・・弁当かよっ!? と Slack に愚痴っていたら 救いの神、降臨!
  52. 52. 52 Logical Replication ということでアドバイスに従って試してみよう。
  53. 53. 53 サブスクライバの pg_replication_origin_status を確認 Logical Replication tokyo=# TABLE pg_replication_origin_status; local_id | external_id | remote_lsn | local_lsn ----------+-------------+------------+----------- 1 | pg_16425 | 0/172CCE8 | 0/17532D8 パブリッシャーの pg_current_wal_location() を確認 kanagawa=# SELECT pg_current_wal_location(); pg_current_wal_location ------------------------- 0/172CF28 サブスクライバ上で pg_replication_origin_advance() を実行 第 1 引数には external_id を指定 第 2 引数には pg_current_wal_location() の値を指定 tokyo=# SELECT pg_replication_origin_advance('pg_16425', '0/172CF28'); pg_replication_origin_advance ------------------------------- To be continued
  54. 54. 54 Confilict 状態からは抜け出せるが、パブリッシャー側の更新 もサブスクライブ側の更新もされたままである。 Logical Replication kanagawa=# TABLE machida; id | pref | data ----+----------+--------- 1 | kanagawa | Naruse 2 | kanagawa | Machida 3 | kanagawa | Kobuchi tokyo=# TABLE machida; id | pref | data ----+----------+--------- 1 | kanagawa | Naruse 3 | tokyo | Kobuchi 2 | kanagawa | Machida あくまでも Conflict 状態でなくなった ( 以降のレプリケー ションを受け付けるようになった)だけ! パブリッシャー側で id=3 のレコードに UPDATE かければ データ上も同期はされる。
  55. 55. 55 そもそも Conflict しているかってどう 判断するのか? Logical Replication 以下の SQL をパブリッシャーで発行する(たぶん)。 サブスクライバ側のサーバログに Conflict 原因のログが 出力されている。 ERROR: duplicate key value violates unique constraint "machida_pkey" DETAIL: Key (id)=(3) already exists. SELECT (SELECT confirmed_flush_lsn FROM pg_replication_slots) = pg_current_wal_location(); true なら Conflict していない。 false なら Conflict している。 このやり方が正しいのか 正直、まだわからぬ。
  56. 56. 56 ここまでの検証からの所感 現時点での Confilct 解消方式はイケてない。 パブリッシャーとサブスクライバを監視する別サーバが ないと自動 Conflict 解消って難しいかも? Logical Replication 監視サーバ サブスクライバパブリッシャー レプリケーション Confilict 検知 WAL 位置取得 Confilict 解消
  57. 57. 57 異なる構造間の Logical Replication Logical Replication は以下のようなテーブルの差異があっ ても複製は可能。 列定義の順番が異なっていても OK 。 複製先テーブルには、複製元にない列があっても OK ( null 可列の場合) ただし、複製テーブルには、複製元の列が全てなくてはい けない。ややこしい。 Logical Replication
  58. 58. 58 異なる構造間の Logical Replication Logical Replication 列 A 列 B 列 C AAA BBB CCC 複製元 列 C 列 B 列 A CCC BBB AAA 複製先 列 A 列 B 列 C AAA BBB CCC 複製元 列 A 列 B 列 C 列 X AAA BBB CCC (null) 複製先 列 A 列 B 列 C AAA BBB CCC 複製元 列 A 列 B AAA BBB 複製先
  59. 59. 59 異文字コード間の Logical Replication 昨日 (4/7?) に Fix されたみたい。 バグレポした篠田さん@ HPE 、そして修正した堀口さん@ NTT 、 GJ ! この手の問題は英語圏の人は積極的に対応しない・・・。 https://postgresql-jp.slack.com/archives/C0AM4GZC0/p149154729244 3787 Logical Replication Logical Replication の文字コード変換問題、修正モジュールがコミットされました。 UTF-8 から EUC_JP への変換も確認できました。堀口さん、ありがとうございました。 https://www.postgresql.org/message-id/20170407.100555.17227106.horiguchi.kyotar o@lab.ntt.co.jp
  60. 60. 60 応用編 マルチマスター構成 異バージョン間複製 異アーキテクチャ間複製 Logical Replication
  61. 61. 61 マルチマスタ構成 こういう構成なら conflict は発生しない。 同一テーブル間のマルチマスタは難しそう・・・ Logical Replication PostgreSQL server (srv2) AAA DBAAA DB XXX table XXX table PostgreSQL server (srv1) YYY table YYY table 更新 削除 更新 削除 挿入 挿入 Logical Replication Logical Replication
  62. 62. 62 異バージョン間複製 PostgreSQL 10 と PostgreSQL 11 間での複製 Logical Replication PostgreSQL 11 server (srv2) PG11 DB クラスタ PG10 DB クラスタ 全 DB 全 DB PostgreSQL 10 server (srv1) 更新 操作 Logical Replication PG10 DB クラスタ 全 DB PostgreSQL 10 server (srv2) Physical Replication pg_upgrade
  63. 63. 63 異アーキテクチャ間複製 Linux 版と Windows 版との間の複製 Logical Replication PostgreSQL 10 serve PG10 DB クラスタ PG10 DB クラスタ 全 DB 全 DB PostgreSQL 10 server 更新 操作 Logical Replication
  64. 64. 64 まとめ Logical Replication によって、一部の データの複製が可能になる。 DML による更新のみ対応。 現状は Conflict 解消方法が面倒。 マルチマスタ / 異バージョン間 / 異 アーキテクチャ間の複製も可能になる ( はず? ) 。 Logical Replication
  65. 65. 65 Physical vs Logical Logical Replication 観点 Physical Replication Logical Replication 複製範囲 データベースクラスタ全体 特定の DB/ 表も選択可能 複製対象の操作 DML(TRUNCATE 含む ), DDL DML(TRUNCATE 除く ) 同期方式 同期または非同期 非同期 用途 高可用化 部分的な複製 異バージョン / 異アーキテクチャ 間複製 用途に合わせて選定しよう。 (私見) Logical Replication は実装されたばかり。 品質面でのリスクは覚悟しておくべきか。 併存も可能だと思う(未検証)
  66. 66. 66 Declarative Partitioning
  67. 67. 67 従来の PostgreSQL パーティション構築 親テーブル定義 親テーブルを継承した子テーブル (+ CHECK 制約)を定義 トリガ関数作成 (C 言語 or PL/pgSQL) トリガ定義 職人芸 Declarative Partitioning
  68. 68. 68 Oracle, DB2 などの商用 DBMS では DDL 構文として、パーティションが サポートされていた。 PostgreSQL の従来のパーティションは いわば「なんちゃってパーティション」 Declarative Partitioning
  69. 69. 69 PostgreSQL 10 新機能 CREATE TABLE 文の拡張によりパー ティションテーブルの定義が可能に。 INSERT トリガ定義不要に! しかも INSERT が高速化! 制約矛盾もある程度チェック可能! Declarative Partitioning
  70. 70. 70 PostgreSQL 10 で 対応するパーティションの種類 レンジパーティション リストパーティション 対応しないパーティション種別 ハッシュパーティション ( 議論中 ) Declarative Partitioning
  71. 71. 71 CREATE TABLE 構文 親テーブル側 Declarative Partitioning CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name ( [ { column_name data_type [ COLLATE collation ] [ column_constraint [ ... ] ] | table_constraint | LIKE source_table [ like_option ... ] } [, ... ] ] ) [ INHERITS ( parent_table [, ... ] ) ] [ PARTITION BY { RANGE | LIST } ( { column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [, ... ] ) ] [ WITH ( storage_parameter [= value] [, ... ] ) | WITH OIDS | WITHOUT OIDS ] [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ] [ TABLESPACE tablespace_name ]
  72. 72. 72 CREATE TABLE 構文 子テーブル側 Declarative Partitioning CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name PARTITION OF parent_table [ ( { column_name [ column_constraint [ ... ] ] | table_constraint } [, ... ] ) ] FOR VALUES partition_bound_spec [ PARTITION BY { RANGE | LIST } ( { column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [, ... ] ) ] [ WITH ( storage_parameter [= value] [, ... ] ) | WITH OIDS | WITHOUT OIDS ] [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ] [ TABLESPACE tablespace_name ] 子テーブル側にも PARTITION BY が! 多段パーティション定義が可能!
  73. 73. 73 シンプルなリストパーティションの例 Declarative Partitioning japan kanagawatokyo shizuoka 親テーブル japan と同じ構造のテーブル 3 つ (tokyo, kanagawa, shizuoka) をパーテイションテーブルとする。
  74. 74. 74 従来の定義方式 親テーブルの定義。 Declarative Partitioning CREATE TABLE japan ( pref text, city text, data text ); CREATE TABLE tokyo ( CHECK (pref IN (' 東京 ')) ) INHERITS (japan); CREATE TABLE kanagawa ( CHECK (pref IN (' 神奈川 ')) ) INHERITS (japan); CREATE TABLE shizuoka ( CHECK (pref IN (' 静岡 ')) ) INHERITS (japan); 子テーブルの定義 To be continued
  75. 75. 75 従来の定義方式(つづき) トリガ関数の定義 Declarative Partitioning CREATE OR REPLACE FUNCTION pref_insert_trigger_func() RETURNS TRIGGER AS $$ BEGIN IF ( NEW.pref = ' 東京 ') THEN INSERT INTO tokyo VALUES (NEW.*); ELSIF ( NEW.pref = ' 神奈川 ') THEN INSERT INTO kanagawa VALUES (NEW.*); ELSIF ( NEW.pref = ' 静岡 ') THEN INSERT INTO shizuoka VALUES (NEW.*); ELSE RAISE EXCEPTION 'Date out of range. Fix the pref_insert_trigger() function!'; END IF; RETURN NULL; END; $$ LANGUAGE plpgsql; To be continued
  76. 76. 76 従来の定義方式(つづき) トリガの定義 Declarative Partitioning REATE TRIGGER pref_insert_trigger BEFORE INSERT ON japan FOR EACH ROW EXECUTE PROCEDURE pref_insert_trigger_func(); まとめ テーブル定義だけでなく、トリガ関数定義・トリガ定義が必 要になる。 パーティション追加によりトリガ関数の変更が入りやすい。
  77. 77. 77 面倒ですね
  78. 78. 78 PostgreSQL 10 の定義方式 親テーブルの定義。 Declarative Partitioning CREATE TABLE japan ( pref text, city text, data text ) PARTITION BY LIST (pref); CREATE TABLE tokyo PARTITION OF japan FOR VALUES IN (' 東京 '); CREATE TABLE kanagawa PARTITION OF japan FOR VALUES IN (' 神奈川 '); CREATE TABLE shizuoka PARTITION OF japan FOR VALUES IN (' 静岡 '); 子テーブルの定義 これだけで完了! ( レンジパーティションもだいたい同じ)
  79. 79. 79 多段パーティションの例 Declarative Partitioning japan kanagawatokyo shizuoka kanagawa.machidakanagawa.yokohama kanagawa.kawasaki 「町田は神奈川。いいね?」「アッハイ」
  80. 80. 80 多段パーティションの定義例 親テーブルの定義。 Declarative Partitioning CREATE TABLE japan ( pref text, city text, data text ) PARTITION BY LIST (pref); CREATE TABLE tokyo PARTITION OF japan FOR VALUES IN (' 東京 '); CREATE TABLE kanagawa PARTITION OF japan FOR VALUES IN (' 神奈川 ') PARTITION BY LIST (city); CREATE TABLE shizuoka PARTITION OF japan FOR VALUES IN (' 静岡 '); 子テーブルの定義 これだけで完了! CREATE TABLE "kanagawa.yokohama" PARTITION OF kanagawa FOR VALUES IN (' 横浜 '); CREATE TABLE "kanagawa.kawasaki" PARTITION OF kanagawa FOR VALUES IN (' 川崎 '); CREATE TABLE "kanagawa.machida" PARTITION OF kanagawa FOR VALUES IN (' 町田 ');
  81. 81. 81 パーティション状態の確認 親テーブルの確認 Declarative Partitioning CREATE TABLE japan ( pref tpartition=# d+ japan Table "public.japan" Column | Type | Collation | Nullable | Default | Storage | Stats target | Description --------+------+-----------+----------+---------+----------+-------------- +------------- pref | text | | | | extended | | city | text | | | | extended | | data | text | | | | extended | | Partition key: LIST (pref) Partitions: kanagawa FOR VALUES IN (' 神奈川 '), shizuoka FOR VALUES IN (' 静岡 '), tokyo FOR VALUES IN (' 東京 ') パーティション種別とキーを表示してくれる。 子テーブルとパーティションキー値を表示してくれる。
  82. 82. 82 パーティション状態の確認 子テーブルの確認 Declarative Partitioning partition=# d+ kanagawa Table "public.kanagawa" Column | Type | Collation | Nullable | Default | Storage | Stats target | Description --------+------+-----------+----------+---------+----------+-------------- +------------- pref | text | | | | extended | | city | text | | | | extended | | data | text | | | | extended | | Partition of: japan FOR VALUES IN (' 神奈川 ') 所属する親テーブルと、パーティションキー値を表示して くれる。
  83. 83. 83 パーティションキー重複のチェック Declarative Partitioning partition=# d+ japan Table "public.japan" Column | Type | Collation | Nullable | Default | Storage | Stats target | Description --------+------+-----------+----------+---------+----------+-------------- +------------- pref | text | | | | extended | | city | text | | | | extended | | data | text | | | | extended | | Partition key: LIST (pref) Partitions: kanagawa FOR VALUES IN (' 神奈川 '), shizuoka FOR VALUES IN (' 静岡 '), tokyo FOR VALUES IN (' 東京 ') partition=# CREATE TABLE kanagawa2 PARTITION OF japan FOR VALUES IN (' 神奈川 '); ERROR: partition "kanagawa2" would overlap partition "kanagawa" パーティションキーの重複を検知してエラーにする。
  84. 84. 84 INSERT の高速化 トリガ方式 /PostgreSQL 10 方式で構築したパーティション 親テーブルに 100 万件データを COPY Declarative Partitioning 10 倍以上の高速化! すごーい!
  85. 85. 85 プルーニング パーティションキーを条件に使った場合に 発動。 条件に一致する一部のパーティションのみ にアクセスすることで検索を効率化する。 従来のトリガベース方式でも対応してい る。 Declarative Partitioning
  86. 86. 86 多段パーティションの例 Declarative Partitioning japan kanagawatokyo shizuoka kanagawa.machidakanagawa.yokohama kanagawa.kawasaki 「町田は神奈川。いいね?」「アッハイ」 パーティションキーは 都道府県 (pref) パーティションキーは 市 (city)
  87. 87. 87 パーティションキーがない場合 Declarative Partitioning partition=# EXPLAIN SELECT * FROM japan ; QUERY PLAN ----------------------------------------------------------------------------- Append (cost=0.00..82.50 rows=3250 width=96) -> Seq Scan on tokyo (cost=0.00..16.50 rows=650 width=96) -> Seq Scan on shizuoka (cost=0.00..16.50 rows=650 width=96) -> Seq Scan on "kanagawa.yokohama" (cost=0.00..16.50 rows=650 width=96) -> Seq Scan on "kanagawa.kawasaki" (cost=0.00..16.50 rows=650 width=96) -> Seq Scan on "kanagawa.machida" (cost=0.00..16.50 rows=650 width=96) (6 rows) パーティションキーがないので、全てのパーティションを検 索する実行計画になる。 Kanagawa テーブルに対する検索は、その子テーブルを合 せた結果になる。
  88. 88. 88 都道府県を条件に指定した場合 Declarative Partitioning partition=# EXPLAIN SELECT * FROM japan WHERE pref = ' 神奈川 '; QUERY PLAN --------------------------------------------------------------------------- Append (cost=0.00..54.38 rows=9 width=96) -> Seq Scan on "kanagawa.yokohama" (cost=0.00..18.12 rows=3 width=96) Filter: (pref = ' 神奈川 '::text) -> Seq Scan on "kanagawa.kawasaki" (cost=0.00..18.12 rows=3 width=96) Filter: (pref = ' 神奈川 '::text) -> Seq Scan on "kanagawa.machida" (cost=0.00..18.12 rows=3 width=96) Filter: (pref = ' 神奈川 '::text) (7 rows) pref が神奈川のデータが格納されている子テーブル(の配 下の子テーブル)のみ検索する実行計画になる。
  89. 89. 89 市を条件に指定した場合 Declarative Partitioning partition=# EXPLAIN SELECT * FROM japan WHERE city = ' 町田 '; QUERY PLAN -------------------------------------------------------------------------- Append (cost=0.00..54.38 rows=9 width=96) -> Seq Scan on tokyo (cost=0.00..18.12 rows=3 width=96) Filter: (city = ' 町田 '::text) -> Seq Scan on shizuoka (cost=0.00..18.12 rows=3 width=96) Filter: (city = ' 町田 '::text) -> Seq Scan on "kanagawa.machida" (cost=0.00..18.12 rows=3 width=96) Filter: (city = ' 町田 '::text) (7 rows) この場合は pref への条件がないので、全ての都道府県の子 テーブルへアクセスする実行計画になる。 kanagawa テーブルに対する検索は、市が町田に対する子 テーブル“ kanagawa.machida” のみに限定される。
  90. 90. 90 都道府県と市を条件に指定した場合 Declarative Partitioning partition=# EXPLAIN SELECT * FROM japan WHERE pref = ' 神奈川 ' AND city = ' 町田 '; QUERY PLAN -------------------------------------------------------------------------- Append (cost=0.00..19.75 rows=1 width=96) -> Seq Scan on "kanagawa.machida" (cost=0.00..19.75 rows=1 width=96) Filter: ((pref = ' 神奈川 '::text) AND (city = ' 町田 '::text)) (3 rows) この場合は pref が神奈川、 city が町田の子テーブル (kanagawa.machida) のみアクセスする実行計画になる。
  91. 91. 91 現状の制約 パーティション間更新の制約 インデックス関連の制約 Declarative Partitioning
  92. 92. 92 パーティション間更新の制約 パーティションキーを変更するような UPDATE はエラー になる。 変更後の値のパーティションテーブルに挿入するわけでは なく、元のパーティションテーブルに挿入しようとして、 制約違反になる。 Declarative Partitioning To be continued partition=# SELECT * FROM japan WHERE id = 6; id | pref | city | data ----+--------+------+-------- 6 | 神奈川 | 町田 | 竹の助 (1 row) partition=# UPDATE japan SET pref = ' 東京 ' WHERE id = 6; ERROR: new row for relation "kanagawa.machida" violates partition constraint DETAIL: Failing row contains (6, 東京 , 町田 , 竹の助 ).
  93. 93. 93 パーティション間更新の制約 代替手段として、 DELETE→INSERT する必要がある。 Declarative Partitioning To be continued partition=# SELECT * FROM japan WHERE id = 6; id | pref | city | data ----+--------+------+-------- 6 | 神奈川 | 町田 | 竹の助 (1 row) partition=# BEGIN; BEGIN partition=# DELETE FROM japan WHERE id = 6; DELETE 1 partition=# INSERT INTO japan VALUES (6, ' 東京 ', ' 町田 ', ' 竹の助 '); INSERT 0 1 partition=# COMMIT; COMMIT partition=# SELECT * FROM japan WHERE id = 6; id | pref | city | data ----+------+------+-------- 6 | 東京 | 町田 | 竹の助 (1 row)
  94. 94. 94 パーティション間更新の制約 RETURNING 句を使って 1 つのクエリにすることも可能 Declarative Partitioning partition=# SELECT * FROM japan WHERE id = 6; id | pref | city | data ----+--------+------+-------- 6 | 神奈川 | 町田 | 竹の助 (1 row) partition=# WITH tmp AS (DELETE FROM japan WHERE id = 6 RETURNING id, ' 東京 ', city, data) INSERT INTO japan SELECT * FROM tmp; INSERT 0 1 partition=# SELECT * FROM japan WHERE id = 6; id | pref | city | data ----+------+------+-------- 6 | 東京 | 町田 | 竹の助 (1 row) ぐぬぬ・・・ 町田は東京に奪われました
  95. 95. 95 インデックス関連の制約 パーティションの親テーブルには Primary key が設定でき ない! Declarative Partitioning partition=# CREATE TABLE japan ( id integer primary key, pref text, city text, data text ) PARTITION BY LIST (pref); ERROR: primary key constraints are not supported on partitioned tables LINE 2: id integer primary key, ^ To be continued
  96. 96. 96 インデックス関連の制約 子テーブルを持つテーブルにはインデックスが作成できない。 Declarative Partitioning partition=# d japan Table "public.japan" Column | Type | Collation | Nullable | Default --------+---------+-----------+----------+--------- id | integer | | | pref | text | | | city | text | | | data | text | | | Partition key: LIST (pref) Number of partitions: 3 (Use d+ to list them.) partition=# CREATE INDEX japan_id ON japan USING btree (id); ERROR: cannot create index on partitioned table "japan" 親テーブルにインデックス設定したら、子テーブルに自動的に 伝播してくれればいいのになあ、とも思う・・・。
  97. 97. 97 今後期待している機能 パーティション機能+並列 FDW アクセス? Declarative Partitioning 親テーブル 子テーブル子テーブル 子テーブル子テーブル 子テーブル子テーブル 子テーブル ( FDW ) 子テーブル ( FDW ) 子テーブル ( FDW ) ここが並列動作 すれば・・・
  98. 98. 98 まとめ CREATE TABLE 定義だけで 簡単にパーティション化! INSERT も高速化された! PK, インデックスの扱いには注意 Declarative Partitioning
  99. 99. 99 Others
  100. 100. 100 Parallel Query の改善 バージョン番号体系 データベースクラスタ内の名称変更 Othres... Others
  101. 101. 101 パラレルクエリ周りの改善項目 MergeJoin IndexScan Bitmap HeapScan サブクエリを含むクエリの対応 pl/pgsql 関数を含むクエリの対応 パラレルクエリの改善 これらの改善により、どんなクエリでどのくらい性能改善効果が 出てくるのかは、 こうした団体さんや企業さんが今後、試すんじゃないかと。
  102. 102. 102 これまで (~ 9.6 ) バージョン番号体系 X. Y. Z メジャーバージョン番号 X が上がるときには、大きな機能追加があった 場合( PITR, レプリケーションなど) マイナーバージョン番号 バグ Fix, セキュリティ Fix など X. Z メジャーバージョン番号 機能追加 マイナーバージョン番号 バグ Fix, セキュリティ Fix など これから ( 10 ~)
  103. 103. 103 より実態にあった名前に変更 pg_clog → pg_xact pg_xlog が pg_wal この影響でユーティリティも名称変更があったりする。 pg_resetxlog→pg_resetwal pg_xlogdump→pg_waldump 旧名のバイナリも残ってはいる サーバログ出力先のデフォルトが変更 pg_log → log DB クラスタ内の名称変更 pg_xlog と pg_log の名称が 紛らわしいという 議論からこうなったみたい。
  104. 104. 104 今のところは、 commitfest のページを 見て commited の項目をリストアップ するしかない・・・。 5 月に PostgreSQL 10-beta がリリー スされたら、リリースノートで確認でき るはず。 Others...
  105. 105. 105 commitfest のページをチラ見して、 気になったものを挙げてみた。 Quorum commit for multiple synchronous replication 複数同期レプリケーションでの投票による昇格 pg_hba_rules view pg_hba.conf が SQL で参照可能に! if, elseif, else, endif また、 psql にいらん楽しそうな機能が! 象神様が、俺にこの機能で遊べと言っている気がする。 もちろん、この他に色々な機能改善が含まれています! Others...
  106. 106. 106 おわりに
  107. 107. 107 PostgreSQL 10 は 新世代の PostgreSQL ! 様々な可能性を秘めた Logical Replication 使いやすい Delective Partition 更に進化した Parallel Query バージョン番号体系の変更
  108. 108. 108 まだ正式リリース前なので いろいろ動かして バグレポートすると コミュニティの中の人も 喜ぶと思います。
  109. 109. 109 あなたと PostgreSQL 10, 今すぐダウンロード
  110. 110. 110 ご清聴ご清聴 ありがとうありがとう ございましたございました
  111. 111. 111 PostgreSQL 10devel Documentation https://www.postgresql.org/docs/devel/static/index.html Commitfest https://commitfest.postgresql.org/ Michael Paquier - Open source developer based in Japan http://michael.otacoo.com/ @sawada_masahiko さんの Twitter https://twitter.com/sawada_masahiko PostgreSQL Update 2017 ( 高塚さん ) https://www.slideshare.net/HarukaTakatsuka/postgre-sql-update20170310 postgresql-jp Slack https://postgresql-hackers-jp.herokuapp.com/ 篠田さん、永安さん、大山さん、澤田さんの書き込みなどなど。 ていうか、 Slack マジ有能。 参考にしたもの
  112. 112. 112 私も微力ながら PostgreSQL 10 新機能に 関する調査・検証結果を Qiita で公開してます ( 最近、怠け気味ですが・・・ ) http://qiita.com/nuko_yokohama
  113. 113. 113 Question?

×