Hatena::ブログ(Diary)

日々の記録 別館

2016-07-01

OSSカンファレンス総会に行ってみた

今日は年休だったんだけど、OSSカンファレンスの総会があるということで大崎まで足を運んでみた。

総会そのものは興味ないのでパスしたが、後半のオープンソースコンテスト発表会には興味があったので、聞いてみることに。

  • 今回はPostgreSQL/DBMS関係の発表はないけど、こういうのって、普段の仕事でもなかなか聞けないからねー。
  • あとは、どういう人種(年代や会社、職種等)がこのコンソーシアムに参加しているのかを見てみたかった、というのもある。
  • (実は大崎で私的な用事があったので、そのついでにOSSカンファレンスにも出てみたというのが真相に近い)

まあ、いろいろ分からないところも多かったが、こういう話も聞いておくのもたまにはいいかな。

なお、だからと言ってOSSコンソーシアムに入会するかと言われると・・・微妙ですなあ。
会社として参加するには、説得するのが難しそうだし、個人参加という感じの団体でもなさそうなので。


プログラミングコンテストに勝つためのOSS

  • 発表者は左野寛之さん。会津大の学生さん
  • Google Summer of Code 2016に参加。RoR改善に取り組んでいる。
  • OSS開発奨励金:プロジェクトが完遂したら$5500!
プログラミングコンテストの話
Aizu Online Judge(AOJ)
プログラミングコンテストのためのライブラリ
Social Snippet
今後にむけて
  • オンラインジャッジを利用した自動的な評価
プログラミングコンテストOSS


OSS ERP JPiereの紹介

ERP(Enterprise Resource Planing)
JPiereのデモ
JPiereの宣伝。
  • 高い人件費、高額なシステム
  • 導入工数を減らして素早く低コストで
    • iDempiereの標準機能+Jpiereの組み合わせで必要機能へのギャップ。
  • JPiere
    • 例:低減税率への対応
    • 売上の処理
    • 日本語レポートの生成。
    • 日本の商習慣だけでなく、UI改善や便利に使うためのツールも提供。
    • パラメータ設定の最適化
コミュニティ
  • 技術と収益をiDempiereのコミュニティにも還元することを考えている。
  • 2週間くらい合宿みたいなこともやった。
    • 日本とアジア圏で商習慣ってどのくらい違うのかなー。
  • フリーライダーにはなりたくない。
    • 寄付やバグレポートは毎月やっていく。


OpenFlowパッチパネルのご紹介

  • 講演者は仲間 修也 氏
  • 沖縄オープンラボラトリ所属
オープンラボラトリの紹介
OpenFlowパッチパネル(OF-Patch)とは
  • OpenFlowスイッチにてパッチパネルを実現したもの。
  • パッチパネルって?
    • 裏面にサーバルータ、スイッチを、表面の抜き差しでNW構成を変更するもの。
  • OpenFlowの説明
    • フローを入力することで制御する。
  • OF-PatchとGUIの制御画面を今回開発している。
OF-Patchの必要性
  • 従来のパッチパネルでは、物理的な配線を手動で切り替える必要があった。
  • それをソフトウェアで制御することで、現地での作業等なしにしたい。
  • 沖縄オープンラボに実際に組み込んでみた。
OSSとしての公開。
of-patchの実装
  • Leaf-Spine構成
    • 複数のOpenFlowスイッチを組み合わせてポート数を確保。
    • Spine:中間層
    • Leaf:末端層。最大48台。2000近くのポートが使えるようになる。
  • 経路選択
    • 経路に偏りが起きないように制御している。
of-Patchのデモ
  • 円周の外側が接続機器などになる。
  • デモもSpine/Leafの構成。
  • 画面上で線を繋いでフローを追加/線を切ってフローの削除などを実施。
今後の取組
  • 複数データセンタ対応
    • 沖縄オープンラボラトリが那覇近くに移転した。
    • このため拠点をまたいだ対応が必要がでてきた。
  • OAM機能
  • SINET検証


オープンソース個人番号カードドライバ

個人番号カード(マイナンバーカード)の解析
データモデル
  • 総務省が消せと言ってくるかもしれない」
  • ツリー状の構成。Unixファイルシステムに類似。
  • 緑は普通のファイル
  • 黄色はハード的に読み取り不可?になっている。チップを開けると自爆する機構が入っているかも。
APDUコマンド仕様の話。
  • 4バイトのコマンドと後続するペイロードで構成。4つのケースがある。
  • カードによって独自の命令があったりする。マイナンバーにもそういうものがある。
  • APDU通信の例
  • まさかのマイナンバーの公開w ASCIIで入っているのな。
  • 名前・住所はUTF8、生年月日はASCII。性別は0x31。
    • 女性が0x30なのか0x32なのかは不明w
ここから本題?
OpenSCスタック
PKCS#11 APIs
  • インタフェースだけ規定。
  • 全部で100個以上あるらしい。主要なものは実装されつつある。
PKCS#15
マイナンバーカードSSHの話
総務相に言いたいこと
  • 仕様を隠さないで
    • ハックする人がいるから無駄ですよ
    • 普及させたいなら公開しろと
目指していること
総務省への低減

OpenLDAP高速化の話

WiredTiger
  • BekeryDBを作った人がまたWiredTigerという新しいDBを作った。
    • 最近のマルチCPUに対応。
  • WiredTigerを使ったOpenLDAPバックエンドを開発した。




以降はわりとどうでもいい話。

役員体制の報告

  • わりとどうでもいい。


コンテスト結果発表

  • 優秀賞(2名:賞金10万円)
    • 佐野さん(IPA発表があるので、もう帰ったらしい)
    • 萩原さん
  • 最優秀賞(1名)
    • 濱野さん

2016-06-27

ハッカーズチャンプルー2016 カンファレンスに行ってきたよ

ということで、JPUGの予算を使って沖縄そばを食べに・・・じゃなくて、沖縄支部長の@zumaさんのご招待でハッカーズチャンプルー2016 カンファレンスに行きましたw

一応、きちんと発表もしましたよ。
PostgreSQL 9.6がやってくる!

PostgreSQLを使ったことがなさそうな人も多いのかな?
それでこのスライド内容で大丈夫かな?
と不安に思うところはありましたが、まずまずの感触。

「ポスグレはいいぞ」と「psqlオセロ」の反応が良かったので、自分的には良し(違
まあ、PostgreSQLを最近使っていなかった人や、今まで使っていなかった人にも、PostgreSQLをちょっと見なおしてもらえる機会になれば幸いです。

ハッカーズチャンプルー、とにかく若い人(学生含む)が多く、熱い発表が多かったですね。
PostgreSQLにも、こういう若い人をなんとか呼び込んでみたいものです。

あ、もちろん沖縄そば/ラーメンもきちんと食べましたw

2016-06-21

PostgreSQL 9.6 - beta1/beta2 Release Note diff

今朝、魅蛙さんのツイートを見かけて、PostgreSQL 9.6 beta2リリースが近いことを知る。
で、pgsql-commiters MLを見てみたら、pgsql: Stamp 9.6beta2.というアナウンスーンも出ていたので、どうやら今週後半にbeta2がリリースされるみたいだ。

ということは、beta2のリリースノートもFixしたはず。
なので、この機会にbeat1とbeta2のリリースノートの差分を見てみることにした。

上記のリンクはあくまで、このエントリを書いている時点でのものなので要注意。

beta1とbeta2の機能的な差分

beta1とbeta2の機能的な差分は、リリースノートの差分から判断する限りは

  • パラレルスキャン関連のGUCの変更
    • max_parallel_workers_per_gather が max_parallel_degree の代替
  • VACUUM コマンドに DISABLE_PAGE_SKIPPING オップションが追加

だけのように見える。

一応、各セクション毎に差分をざっと列挙した。意外と少ない。

セクション差分
E.1.3.1. Server なし
E.1.3.1.1. Parallel Queriesパラレルスキャン関連のGUCの変更(max_parallel_degree 削除, max_parallel_workers_per_gather 追加, min_parallel_relation_size 追加)
E.1.3.1.3. General PerformanceVACUUMコマンドにDISABLE_PAGE_SKIPPING オップションが追加, FK性能改善の説明修正
E.1.3.1.4. Monitoringなし
E.1.3.1.5. Authenticationなし
E.1.3.1.6. Server Configurationなし
E.1.3.1.7. Reliabilityなし
E.1.3.2. Replication and Recoveryなし
E.1.3.3. Queriesなし
E.1.3.4. Utility Commandsなし
E.1.3.5. Permissions Managementなし
E.1.3.6. Data Typesなし
E.1.3.7. Functionsなし
E.1.3.8. Server-Side Languagesなし
E.1.3.9. Client Interfacesなし
E.1.3.10. Client Applicationsなし
E.1.3.10.1. psql\watch command 改善の説明修正
E.1.3.10.2. pgbenchなし
E.1.3.11. Server Applicationsなし
E.1.3.12. Source Codeなし
E.1.3.13. Additional Modulesなし

2016-06-20

PostgreSQL 9.6 - VACUUM Progress Reporting

f:id:nuko_yokohama:20160620212035j:image:w240
そういえば、9.6のVACUUM Progress Reportingをきちんと試してなかった。

VACUUM Progress Reporting

この機能は名前のとおり、VACUUMの進捗状況をレポートしてくれるというもの。
進捗状況は pg_stat_progress_vacuum ビューに書き込まれる。
なお、このビューに表示されるレコードはVACUUM処理中のみ存在する。VACUUMが完了すると消えてしまう。
なので、VACUUMがすぐに終わっちゃうと、進捗を見ようとしても見れないというもどかしさw

かといって、うちのようなpoorな環境では巨大なテーブルを作るわけにもいかない・・・。

vacuum_cost系パラメータを使う

ということで、小さいテーブルでもVACUUM Progress Reportingを見たい場合には、VACUUMの動作を遅くすればいいのですよ。
このために、Cost-based Vacuum Delay系のパラメータを調整する。
パラメータは数種類あるけど、まあ vacuum_cost_delay をちょっと調整すれば十分かと。このパラメータデフォルト値が 0 つまり遅延なく行う設定になっているけど、これを 10 (ms) とかにしていれば、pgbench_accounts (scale=10)程度のテーブルでもそれなりにVACUUM処理に時間がかかるようになる。

psql コマンドも併用する

あとはVACUUMを実行させて、別ターミナルから pg_stat_progress_vacuum ビューを定期的に検索するようにすれば良い。
たとえば、以下の様なSQLを発行する。
で、これを繰り返し実行する。そういうときに \watch コマンドを使う。

\watch 0.1

こうすると、0.1秒間隔で直前のコマンドを実行してくれる。
ヘッダ部分が邪魔なら \t コマンドで結果行だけ表示するようにすれば良い。
さらに、結果を書き込むように、 \o filename で出力ファイルを指定しておくと、後から参照するのも楽になる。

結果

テキトーにUPDATEして汚した scale factor=10 の pgbench_accounts テーブルを含む、データベース全体にVACUUMをかけて、以下のSQLでVACUUM Progress Reportingを表示させてみた。

SELECT 
 p.relname, 
 v.phase, v.heap_blks_total, v.heap_blks_scanned, v.heap_blks_vacuumed, v.index_vacuum_count 
 FROM pg_stat_progress_vacuum as v JOIN pg_class as p 
 ON (v.relid = p.oid);

第1カラムはテーブル名、第2カラムがVacuumのステータスになる。
第3カラムは総ヒープブロック数、第4カラムはスキャンしたブロック数、第5カラムがバキュームされたブロック数・・・のような感じ。

 pgbench_accounts | scanning heap |           18033 |               506 |                  0 |                  0
 pgbench_accounts | scanning heap |           18033 |              1260 |                  0 |                  0
 pgbench_accounts | scanning heap |           18033 |             17067 |                  0 |                  0
 pgbench_accounts | scanning heap |           18033 |             17157 |                  0 |                  0
 pgbench_accounts | scanning heap |           18033 |             17467 |                  0 |                  0
 pgbench_accounts | vacuuming indexes |           18033 |             18033 |                  0 |                  0
(中略)
 pgbench_accounts | vacuuming indexes |           18033 |             18033 |                  0 |                  0
 pgbench_accounts | vacuuming indexes |           18033 |             18033 |                  0 |                  0
 pgbench_accounts | vacuuming heap |           18033 |             18033 |              16767 |                  1
 pgbench_accounts | vacuuming heap |           18033 |             18033 |              17267 |                  1
 pgbench_accounts | vacuuming heap |           18033 |             18033 |              17997 |                  1
 pg_language | cleaning up indexes |               1 |                 1 |                  1 |                  0
 pg_tablespace | scanning heap |               1 |                 0 |                  0 |                  0

ステータスが、scanning heap → vacuuming indexes → vacuuming heap という具合に変更していくのが見える。

2016-06-13

postgres_fdwで異バージョン接続/外部表のカスケード

PostgreSQL 9.6/9.5のpostgres_fdwの差異を調べていて、ふと気になったことを調べてみた。

異バージョン間でFDW

PostgreSQL 9.6/9.5のpostgres_fdwの差異を調べていて、ふと気になったのだけど、異なるバージョン間をpostgres_fdwで接続ってできたっけ。
ということでやってみた。

ローカルサーバが9.6、リモートサーバが9.5の場合。
bench=# EXPLAIN ANALYZE VERBOSE 
SELECT AVG(a.data1), AVG(a.data2) 
FROM table_a a JOIN table_b b ON (a.id = b.id) 
WHERE a.data1 = 10000 ;
                                                                     QUERY PLAN                                                                      
-----------------------------------------------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=342.59..342.60 rows=1 width=64) (actual time=2.176..2.176 rows=1 loops=1)
   Output: avg(a.data1), avg(a.data2)
   ->  Foreign Scan  (cost=100.00..341.78 rows=161 width=8) (actual time=2.151..2.153 rows=11 loops=1)
         Output: a.data1, a.data2
         Relations: (public.table_a a) INNER JOIN (public.table_b b)
         Remote SQL: SELECT r1.data1, r1.data2 FROM (public.table_a r1 INNER JOIN public.table_b r2 ON (((r1.id = r2.id)) AND ((r1.data1 = 10000))))
 Planning time: 1.714 ms
 Execution time: 11.359 ms
(8 rows)

おお、フツーに結合SQLを9.5のリモートサーバに投げているな。

ローカルサーバが9.5、リモートサーバが9.6
bench=# EXPLAIN ANALYZE VERBOSE 
SELECT AVG(a.data1), AVG(a.data2) 
FROM table_a a JOIN table_b b ON (a.id = b.id) 
WHERE a.data1 = 10000 ;
                                                                QUERY PLAN                                                                
------------------------------------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=349.93..349.94 rows=1 width=8) (actual time=1152.246..1152.246 rows=1 loops=1)
   Output: avg(a.data1), avg(a.data2)
   ->  Hash Join  (cost=238.80..349.12 rows=161 width=8) (actual time=48.058..1152.208 rows=10 loops=1)
         Output: a.data1, a.data2
         Hash Cond: (b.id = a.id)
         ->  Foreign Scan on public.table_b b  (cost=100.00..197.75 rows=2925 width=4) (actual time=0.349..1065.369 rows=1000000 loops=1)
               Output: b.id, b.data1, b.data2
               Remote SQL: SELECT id FROM public.table_b
         ->  Hash  (cost=138.66..138.66 rows=11 width=12) (actual time=0.284..0.284 rows=10 loops=1)
               Output: a.data1, a.data2, a.id
               Buckets: 1024  Batches: 1  Memory Usage: 9kB
               ->  Foreign Scan on public.table_a a  (cost=100.00..138.66 rows=11 width=12) (actual time=0.274..0.277 rows=10 loops=1)
                     Output: a.data1, a.data2, a.id
                     Remote SQL: SELECT id, data1, data2 FROM public.table_a WHERE ((data1 = 10000))
 Planning time: 0.128 ms
 Execution time: 1152.649 ms
(16 rows)

ローカル側は9.5なので、当然ながらJoin-pushdownの実行計画が存在しない。
なので、リモートの9.6に対して、結合のないクエリを複数回発行して、その結果をローカル側で結合する。

まあ、当たり前の結果ではあるけど、一応試してみたかったので。

postgres_fdw のカスケード

ていうか、postgres_fdwのソースって実表だけなんだっけ?と疑問に思ったので、ソースとしてビュー、マテリアライズド・ビュー、そして外部表を試してみることにした。
構成はこんな感じ。
f:id:nuko_yokohama:20160613212358p:image

(´-`).oO (IMPORT FOREIGN SCHEMAがサポートされて、こういう検証が本当に楽になったよ・・・)

さて、この構成でサーバ 96_l の外部テーブルに対してクエリを投げてみる。
詳細は省略するけど、table_a, table_b, table_a_v, table_a_v, table_c, table_d 全て外部テーブル経由で検索はできた。

もちろん、更新不可能なビューや、マテリアライズド・ビューをソースとする外部表を更新しようとするとエラーになる。

bench=# UPDATE table_a_v SET data1 = 50000;
ERROR:  cannot update view "table_a_v"
DETAIL:  Views containing TABLESAMPLE are not automatically updatable.
HINT:  To enable updating the view, provide an INSTEAD OF UPDATE trigger or an unconditional ON UPDATE DO INSTEAD rule.
CONTEXT:  Remote SQL command: UPDATE public.table_a_v SET data1 = 50000
STATEMENT:  UPDATE table_a_v SET data1 = 50000;
bench=# UPDATE table_a_mv SET data1 = 50000;
ERROR:  cannot change materialized view "table_a_mv"
CONTEXT:  Remote SQL command: UPDATE public.table_a_mv SET data1 = 50000
STATEMENT:  UPDATE table_a_mv SET data1 = 50000;

で、せっかく9.6を使っているので、Join pushdownが効くのかどうか試してみた。
table_a, table_bを結合したクエリは当然結合クエリが 96_r にpushdownされてます。

bench=# EXPLAIN ANALYZE VERBOSE 
SELECT AVG(a.data1), AVG(a.data2) 
FROM table_a_v a JOIN table_b b ON (a.id = b.id) 
WHERE a.data1 = 1000 ;
                                                                      QUERY PLAN                                                                      
------------------------------------------------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=342.59..342.60 rows=1 width=64) (actual time=6.023..6.023 rows=1 loops=1)
   Output: avg(a.data1), avg(a.data2)
   ->  Foreign Scan  (cost=100.00..341.78 rows=161 width=8) (actual time=6.016..6.016 rows=0 loops=1)
         Output: a.data1, a.data2
         Relations: (public.table_a_v a) INNER JOIN (public.table_b b)
         Remote SQL: SELECT r1.data1, r1.data2 FROM (public.table_a_v r1 INNER JOIN public.table_b r2 ON (((r1.id = r2.id)) AND ((r1.data1 = 1000))))
 Planning time: 0.248 ms
 Execution time: 7.353 ms
(8 rows)

では、96_rr → 96_r → 96_l のように外部表をカスケードした場合はどうなるのか。

お、96_rr サーバまで結合クエリがきちんとpushdownされてますね。

bench=# EXPLAIN ANALYZE VERBOSE 
SELECT AVG(c.data1), AVG(c.data2) 
FROM table_c c JOIN table_d d ON (c.id = c.id) 
WHERE c.data1 = 1000;
                                                                     QUERY PLAN                                                                     
----------------------------------------------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=294.93..294.94 rows=1 width=64) (actual time=1.105..1.105 rows=1 loops=1)
   Output: avg(c.data1), avg(c.data2)
   ->  Foreign Scan  (cost=100.00..277.86 rows=3413 width=8) (actual time=1.101..1.101 rows=0 loops=1)
         Output: c.data1, c.data2
         Relations: (public.table_c c) INNER JOIN (public.table_d d)
         Remote SQL: SELECT r1.data1, r1.data2 FROM (public.table_c r1 INNER JOIN public.table_d r2 ON (((r1.id = r1.id)) AND ((r1.data1 = 1000))))
 Planning time: 0.140 ms
 Execution time: 1.787 ms
(8 rows)

96_r, 96_rr サーバデータベースに contrib/auto_explain を入れて、実際にどんなSQLが発行されてみるか確認してみる。

96_r サーバで実行されたSQL

LOG:  duration: 0.392 ms  plan:
	Query Text: DECLARE c1 CURSOR FOR
	SELECT r1.data1, r1.data2 FROM (public.table_c r1 INNER JOIN public.table_d r2 ON (((r1.id = r1.id)) AND ((r1.data1 = 1000))))
	Foreign Scan  (cost=100.00..277.86 rows=3413 width=8)
	  Relations: (public.table_c r1) INNER JOIN (public.table_d r2)

96_rr サーバで実行されたSQL

LOG:  duration: 0.018 ms  plan:
	Query Text: DECLARE c1 CURSOR FOR
	SELECT r1.data1, r1.data2 FROM (public.table_c r1 INNER JOIN public.table_d r2 ON (((r1.id = r1.id)) AND ((r1.data1 = 1000))))
	Nested Loop  (cost=0.29..2553.33 rows=100000 width=8)
	  ->  Index Scan using c_data1 on table_c r1  (cost=0.29..12.33 rows=1 width=8)
	        Index Cond: (data1 = 1000)
	        Filter: (id = id)
	  ->  Seq Scan on table_d r2  (cost=0.00..1541.00 rows=100000 width=0)

うん、きちんと結合条件がpushdownされてますね。

知ってる人には当たり前かもしれないけど、自分で確認して納得できたので良かった。