![]() ![]() ![]() ![]() |
![]() |
|
![]() |
||
![]() |
この記事はPostgreSQL Advent Calendar 2012の9日目だと思います。
PL/v8のことはもうご存知でしょうか。JavaScript実行エンジンのV8を組み込んだプロシージャ言語で、JavaScriptでPostgreSQLを拡張することができます。PostgreSQL9.2ではJSON型がビルトインとしてサポートされたこともあり、PostgreSQL本体のリリース文の中に言及があるなど、こちらの知らないところで宣伝されていたりしてこっちがびっくりするときもしばしば。先日日本で開催されたHeroku Meetup #7に来ていたはずのWillもあっちこっちでPL/v8の宣伝してますね。
さて、つい先ほどPGXNにて1.3.0と1.2.1をリリースしました。1.2.1は1.2.0からのバグフィックス、1.3.0は新機能を盛り込んだバージョンになります。あまり日本語で機能全体を紹介したことがないので概要を公式ドキュメントからの抜粋で紹介します。
いわゆる普通のユーザ定義関数をサポートします。SELECT foo() FROM bar;といった使い方ですね。下記のような感じです。
CREATE FUNCTION plv8_test(keys text[], vals text[]) RETURNS text AS $$ var o = {}; for(var i=0; i<keys.length; i++){ o[keys[i]] = vals[i]; } return JSON.stringify(o); $$ LANGUAGE plv8 IMMUTABLE STRICT; SELECT plv8_test(ARRAY['name', 'age'], ARRAY['Tom', '29']); SELECT plv8_test(ARRAY['name', 'age'], ARRAY['Tom', '29']); plv8_test --------------------------- {"name":"Tom","age":"29"} (1 row)
Set Returning Functionというやつです。generate_series()の類いですね。この場合はplv8.return_next()によって行を返します。
CREATE TYPE rec AS (i integer, t text); CREATE FUNCTION set_of_records() RETURNS SETOF rec AS $$ // plv8.return_next() stores records in an internal tuplestore, // and return all of them at the end of function. plv8.return_next( { "i": 1, "t": "a" } ); plv8.return_next( { "i": 2, "t": "b" } ); // You can also return records with an array of JSON. return [ { "i": 3, "t": "c" }, { "i": 4, "t": "d" } ]; $$ LANGUAGE plv8; SELECT * FROM set_of_records(); i | t ---+--- 1 | a 2 | b 3 | c 4 | d (4 rows)
トリガもかけます。PL/pgSQLと同様の変数を利用することができます。
CREATE FUNCTION test_trigger() RETURNS trigger AS $$ plv8.elog(NOTICE, "NEW = ", JSON.stringify(NEW)); plv8.elog(NOTICE, "OLD = ", JSON.stringify(OLD)); plv8.elog(NOTICE, "TG_OP = ", TG_OP); plv8.elog(NOTICE, "TG_ARGV = ", TG_ARGV); if (TG_OP == "UPDATE") { NEW.i = 102; return NEW; } $$ LANGUAGE "plv8"; CREATE TRIGGER test_trigger BEFORE INSERT OR UPDATE OR DELETE ON test_tbl FOR EACH ROW EXECUTE PROCEDURE test_trigger('foo', 'bar');
9.0以降でDO文で呼び出す関数をサポートしています。
DO $$ plv8.elog(NOTICE, 'this', 'is', 'inline', 'code') $$ LANGUAGE plv8;
引数と戻り値のデータ型に応じて適当なJSのデータ型に変換します。
timestamptzまでは想像に難くないと思います。1.3.0ではbyteaとJSONを追加し、byteaは後ほど紹介するTypedArrayによって符号なし1バイト整数配列に変換されます。9.2以降のJSON型についてはJSON.parse()/stringify()を呼び出してJavaScriptのオブジェクトに変換されます。
PL/pythonやPL/perlと同様にSPIによるデータベースアクセスが利用できます。基本的にはplv8.execute()によりSQLが発行できるのと、plv8.prepare()によってPlanオブジェクトを取得、fetch()やcursor()を呼び出す方法があります。
var json_result = plv8.execute( 'SELECT * FROM tbl' ); var num_affected = plv8.execute( 'DELETE FROM tbl WHERE price > $1', [ 1000 ] );
var plan = plv8.prepare( 'SELECT * FROM tbl WHERE col = $1', ['int'] ); var rows = plan.execute( [1] ); var sum = 0; for (var i = 0; i < rows.length; i++) { sum += rows[i].num; } plan.free(); return sum;
SPI関連でサブトランザクションが自動的に発行されます。関数の途中でplv8.execute()が失敗しても、try/catchで復帰してそれまでのデータベースへの変更をロールバックした後に処理を継続することができます。
try{ plv8.subtransaction(function(){ plv8.execute("INSERT INTO tbl VALUES(1)"); -- should be rolled back! plv8.execute("INSERT INTO tbl VALUES(1/0)");-- occurs an exception }); } catch(e) { ... do fall back plan ... }
plv8オブジェクト経由で各種ユーティリティ関数が提供されています。
こちらはほぼ標準てきな内容です。さらに、plv8.find_functionを利用して別のユーザ定義関数をJS関数としてロードすることができます。
CREATE FUNCTION callee(a int) RETURNS int AS $$ return a * a $$ LANGUAGE plv8; CREATE FUNCTION caller(a int, t int) RETURNS int AS $$ var func = plv8.find_function("callee"); return func(a); $$ LANGUAGE plv8;
PL/v8はtrusted languageであるため、データベース外のリソース(ファイルシステム、ネットワーク)へのアクセスは制限されていますので、こうしたコードの再利用はfind_functionを利用すると便利です。
1.3.0よりウィンドウ関数APIを利用できるのでユーザ定義ウィンドウ関数をPL/v8で作成することができます。ウィンドウ関数内ではplv8.get_window_object()を呼び出してウィンドウオブジェクトを取得し、APIを呼び出すことができます。
var winobj = plv8.get_window_object(); return winobj.get_current_position() + 1;
V8には変態的な機能があって、メモリの内容を直に配列化することができます。これはもともとブラウザのCanvasのサポートでピクセルメモリを高速に処理するために用意されているのですが、PL/v8ではこれを利用してbytea及び一部の配列をJSの配列に変換します。byteaの列に任意のバイナリデータを保存して、面倒なCユーザ定義関数を書く変わりにJSで処理してしまうことも可能です。また、int2/int4/float4/float8についてはドメイン型plv8_int2array/plv8_int4array/plv8_float4array/plv8_float8arrayが用意されており、これらを引数として与えると一次元でNULLを含まない配列に対して高速なメモリアクセスが可能です。
create table foo(i, ary) as select i, ary from(select array_agg(a) ary from generate_series(1, 100000)a)a, generate_series(1, 100)i; create or replace function int4sum(ary plv8_int4array) returns int8 as $$ var sum = 0; for (var i = 0; i < ary.length; i++) { sum += i; } return sum; $$ language plv8 immutable strict; select int4sum(ary) from foo; Time: 48.882 ms -- plv8_int4arrayのかわりにint4[]を使った場合 Time: 820.785 ms
もうC言語関数いらないかもしれませんね。
1.3.0からはd8を利用したデバッガを利用することができます。make時にENABLE_DEBUGGER_SUPPORTを定義するとデバッガ用のポートを開きます。デフォルトは35432番で待っています。
$ d8 --remote-debugger --debugger-port=35432
Node.jsなどではお馴染みのようです。
その他のPLでも同様の問題があるように、V8についてもユーザを切り替えた際に実行環境が混じらないように、それぞれのユーザごとにV8実行環境が作成されます。SET ROLEコマンドを使って同一接続中にユーザを切り替えた場合はグローバル変数などが別に定義されます。
plv8.start_procに定義済みのJS関数名を記述することにより、毎回のJSエンジン初期化時にその関数が呼び出されます。これはグローバル変数/関数の準備などをするために有用です。
SET plv8.start_proc = 'plv8_init'; SELECT plv8_test(10);
現在のところ、CoffeeScriptとLiveScriptが利用可能です。それぞれ別のExtensionになっていますので、利用したい場合はCREATE EXTENSIONを呼び出してください。特にLiveScriptについては、かのPugsを開発者Audrey Tangからパッチをもらっています。
----
さていかがでしょうか。PostgreSQLに標準でついてくるPL/pythonなどに比べても機能的に足りないところはなく、ウィンドウ関数やデバッガの機能などは寧ろ勝っていると言えるでしょう。またPL/v8の重要な特性の一つとしてtrusted languageがあり、セキュリティ上の理由からPL/pgSQLしか利用できなかった場面でもPL/v8が利用できます。特にPaaSなどではここが重要になるかもしれません。しかしPL/pgSQLに対して処理速度は圧倒的でありますので、よほどの理由(Oracleポーティングとか?)でないかぎりPL/pgSQLでないとだめという理由は見当たりません。強いて言えばJSには標準ライブラリ的なものはないので特有の問題を既存のライブラリで解決するなどのときはPL/pythonの方がいいとは思います。
というわけで、外様PLながらPL/v8は最もリッチなプロシージャ言語になってしまいました。本当はFDWとかも書けるようにしたいのですが、いかんせんネットワーク処理はできないのであまり有用ではないと思われます。その他、他に不足する部分があればどしどしIssueListにご応募ください。
Enjoy!
お気づきの方も多いと思いますが、no titleにてAdvent Calendarを追跡中です。・・・が、どうもYahoo PipseとGAEの組み合わせが悪いようでPipseの更新を自動で反映できず、たまに私がデータの更新日付を1年前に戻して再取得させている・・・という涙ぐましいお話。
ちなみにYahoo Pipseは下記の要領で動いています。
ATNDのコメントRSSを取得
↓
各リンクURLを収集
↓
↓
タイトルまたは本文にPostgreSQL Advent Calendarの文字列が含まれるエントリを抽出
↓
新しいRSSとして再構成
という流れになっています。初めてPipse触ったんですが、見た目のファンシーさの割にできることがわかりにくく・・・結局3時間ぐらいかかったので自前でプログラム書いた方が早かったんじゃというツッコミもありつつ、まあできたので良しと。上記の通り文字列抽出をしているのでAdvent Calendar本体の記事から程なく別目的で同様の文字列を含むエントリをアップした場合誤認識する可能性があります。なんでURLマッチしないんだと言われそうですが、いろいろあって結論からいうとPipseではUNIONできてもJOINできないんですねこれが。
というわけで各エントリをアップ頂いている皆々様には感謝の言葉に尽きますが、Yahoo Pipseからのアクセスがトップになっているからといって私に後ろ指ささないように・・・
PostgreSQL Advent Calendar 12/2。もちろん日本時間で進行してます。
さてあまりディープな話しても仕方ないかなと思い、今話題絶頂渋谷女子高生の間でも噂になっていると言われるHeroku Postgresを早速使ってみた感想。ご存じない方のために念のため説明しておくと、HerokuがクラウドサービスとしてPostgreSQL単品で使えるサービスをこの間から提供しています。Database As A Serviceというやつか。
まずはログイン。Webサービスの方は無料から始められるけど、Postgresは最低月200ドルの有料サービスなのでクレジットカードを登録。Postgresの方とWebとでシングルサインオンです。
ログインしてデータベース作成。マジで2クリックぐらいです。できあがるとこんな感じ。
フルAjaxでさくさく動きます。データベース名やユーザ名、パスワードはランダム文字列が勝ってに割り振られますが、右上のConnection Settingの矢印からpsqlを選ぶとコピペでそのままシェルキックできる文字列を作ってくれます。ついでにJDBCやActiveRecord用文字列も作ってくれます。
SSL必須なのでソースインストールでpsql使っているようなマニアックな方はぜひ--with-opensslでビルドしなおしてください。っていうかこのオプション指定したことなかったアルよ。あ、おしゃれな六本木のお兄さんはもちろんpgAdminとかで接続してね。
psqlでログインすると何のからくりもないバニラPostgresです。\cでtemplate1にもつながります。おもむろにCREATE DATABASEすると権限がないとおこられます。\lはこんな感じ。
dv2jnpm7g28edxm=> \l List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges -----------------+-----------------+----------+-------------+-------------+------------------------------------- dv2jnpm7g28edxm | uv25d4bx5cii4b0 | UTF8 | en_US.UTF-8 | en_US.UTF-8 | uv25d4bx5cii4b0=CTc/uv25d4bx5cii4b0+ | | | | | collectd=c/uv25d4bx5cii4b0 postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | postgres=CTc/postgres template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres + | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres + | | | | | postgres=CTc/postgres (4 rows)
9.0でDO構文使えますので
dv2jnpm7g28edxm=> do $$ declare begin raise 'hoge'; end; $$; ERROR: hoge
とかも動きました。
システムカタログもpg_authidとか以外は普通に見えるので、pg_pltemplateをのぞいてみました。
dv2jnpm7g28edxm=> select * from pg_pltemplate; tmplname | tmpltrusted | tmpldbacreate | tmplhandler | tmplinline | tmplvalidator | tmpllibrary | tmplacl ------------+-------------+---------------+------------------------+--------------------------+-------------------+-------------------+--------- plpgsql | t | t | plpgsql_call_handler | plpgsql_inline_handler | plpgsql_validator | $libdir/plpgsql | pltcl | t | t | pltcl_call_handler | | | $libdir/pltcl | pltclu | f | f | pltclu_call_handler | | | $libdir/pltcl | plperl | t | t | plperl_call_handler | plperl_inline_handler | plperl_validator | $libdir/plperl | plperlu | f | f | plperl_call_handler | plperl_inline_handler | plperl_validator | $libdir/plperl | plpythonu | f | f | plpython_call_handler | plpython_inline_handler | | $libdir/plpython | plpython2u | f | f | plpython_call_handler | plpython_inline_handler | | $libdir/plpython2 | plpython3u | f | f | plpython3_call_handler | plpython3_inline_handler | | $libdir/plpython3 | (8 rows)
ん?先日の話だと「安全じゃない(untrusted)言語なんて導入できない」とか言ってたような。
dv2jnpm7g28edxm=> create language plperl; ERROR: could not access file "$libdir/plperl": No such file or directory
なるほど。共有オブジェクト置いてないんですね。っていうかそれならpg_pltemplateからはずしとけよって気もしますが。パッケージインストールなのかな?
そのうちここにplv8jsが並ぶわけですね。わかります。
dv2jnpm7g28edxm=> create table t(a, b, c) as select i, i % 100, repeat('x', 100 + i % 100) from generate_series(1, 1000000)i; SELECT 1000000 Time: 23165.819 ms dv2jnpm7g28edxm=> select pg_size_pretty(pg_database_size('dv2jnpm7g28edxm')); pg_size_pretty ---------------- 189 MB (1 row) Time: 107.376 ms dv2jnpm7g28edxm=> select count(*) from t; count --------- 1000000 (1 row) Time: 937.279 ms
手元のMacBookでやったらCTASは4秒ぐらいで終わったのでやっぱり書き込みはちょっと遅いですね。もちろんWAL設定が手元はデフォルトなんですが。ただ参照は手元と同じぐらいかちょっと早いぐらい。キャッシュが1.7Gでテーブル作成は自由にできて参照もこのぐらい出るのならば、なんかもうこれでいいかって気がします。ていうかこれで最低ランクなんですが、最高ランクのMechaって誰が月6400ドルも払って数十ギガのキャッシュのせるのか。面白いから用意してみたって匂いがぷんぷんするw。
さてさて目玉はレプリケーション。ポチットな。
一回失敗しましたが、二回目で完成。ログもAjaxかWebSocketか知らないけどWeb画面開いたまま更新されていきます。もちろんこのFollowerも一台につき200ドル/月。
バックアップもワンクリック。リストアは新しいDBインスタンスになる模様。金稼ぐなー。バックアップのダウンロードもリンクのクリックでダウンロード始まります。形式は-Fcですね。
あ、ちなみに料金は月極の時間単位なので、11月31日の夜にDB作って早速2ドル請求が来ました。逆に言うとこうして実験してインスタンス破棄すれば200ドルもいらないわけです。ていうかこのぐらいの性能でレプリケーション、バックアップ、リストア、ログ管理等等を全く気にしなくていいとすれば、月200でサーバ+DBAなんか雇えないわけで、十分ペイする気がします。
そんなわけで長くなりましたが、Heroku Postgres使ってみました。
明日はitagaki.takahiroさんです。よろしう。
P.S.
pg_settingsをコピペしときます。興味のある人はご覧あれ。
dv2jnpm7g28edxm=> select name, setting from pg_settings; name | setting ---------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------- allow_system_table_mods | off application_name | psql archive_command | test -f /etc/postgresql/9.0/main/wal-e.d/ARCHIVING_OFF || envdir /etc/postgresql/9.0/resource6279_heroku_com/wal-e.d/env wal-e wal-push %p archive_mode | on archive_timeout | 60 array_nulls | on authentication_timeout | 60 autovacuum | on autovacuum_analyze_scale_factor | 0.1 autovacuum_analyze_threshold | 50 autovacuum_freeze_max_age | 200000000 autovacuum_max_workers | 3 autovacuum_naptime | 60 autovacuum_vacuum_cost_delay | 20 autovacuum_vacuum_cost_limit | -1 autovacuum_vacuum_scale_factor | 0.2 autovacuum_vacuum_threshold | 50 backslash_quote | safe_encoding bgwriter_delay | 200 bgwriter_lru_maxpages | 100 bgwriter_lru_multiplier | 2 block_size | 8192 bonjour | off bonjour_name | bytea_output | hex check_function_bodies | on checkpoint_completion_target | 0.7 checkpoint_segments | 40 checkpoint_timeout | 300 checkpoint_warning | 30 client_encoding | UTF8 client_min_messages | notice commit_delay | 0 commit_siblings | 5 constraint_exclusion | partition cpu_index_tuple_cost | 0.001 cpu_operator_cost | 0.0005 cpu_tuple_cost | 0.003 cursor_tuple_fraction | 0.1 custom_variable_classes | DateStyle | ISO, MDY db_user_namespace | off deadlock_timeout | 1000 debug_assertions | off debug_pretty_print | on debug_print_parse | off debug_print_plan | off debug_print_rewritten | off default_statistics_target | 100 default_tablespace | default_text_search_config | pg_catalog.english default_transaction_isolation | read committed default_transaction_read_only | off default_with_oids | off effective_cache_size | 191250 effective_io_concurrency | 1 enable_bitmapscan | on enable_hashagg | on enable_hashjoin | on enable_indexscan | on enable_material | on enable_mergejoin | on enable_nestloop | on enable_seqscan | on enable_sort | on enable_tidscan | on escape_string_warning | on extra_float_digits | 0 from_collapse_limit | 8 fsync | on full_page_writes | on geqo | on geqo_effort | 5 geqo_generations | 0 geqo_pool_size | 0 geqo_seed | 0 geqo_selection_bias | 2 geqo_threshold | 12 gin_fuzzy_search_limit | 0 hot_standby | on ignore_system_indexes | off integer_datetimes | on IntervalStyle | postgres join_collapse_limit | 8 krb_caseins_users | off krb_srvname | postgres lc_collate | en_US.UTF-8 lc_ctype | en_US.UTF-8 lc_messages | en_US.UTF-8 lc_monetary | en_US.UTF-8 lc_numeric | en_US.UTF-8 lc_time | en_US.UTF-8 listen_addresses | * lo_compat_privileges | off local_preload_libraries | log_autovacuum_min_duration | -1 log_checkpoints | on log_connections | off log_destination | syslog log_disconnections | off log_duration | off log_error_verbosity | default log_executor_stats | off log_hostname | off log_line_prefix | %u [ONYX] log_lock_waits | off log_min_duration_statement | 50 log_min_error_statement | error log_min_messages | notice log_parser_stats | off log_planner_stats | off log_rotation_age | 1440 log_rotation_size | 10240 log_statement | none log_statement_stats | off log_temp_files | -1 log_timezone | UTC log_truncate_on_rotation | off logging_collector | on maintenance_work_mem | 65536 max_connections | 500 max_files_per_process | 1000 max_function_args | 100 max_identifier_length | 63 max_index_keys | 32 max_locks_per_transaction | 64 max_prepared_transactions | 500 max_stack_depth | 2048 max_standby_archive_delay | -1 max_standby_streaming_delay | -1 max_wal_senders | 10 password_encryption | on plpgsql.variable_conflict | error port | 5432 post_auth_delay | 0 pre_auth_delay | 0 random_page_cost | 4 search_path | "$user",public segment_size | 131072 seq_page_cost | 1 server_encoding | UTF8 server_version | 9.0.5 server_version_num | 90005 session_replication_role | origin shared_buffers | 53120 silent_mode | off sql_inheritance | on ssl | on ssl_renegotiation_limit | 524288 standard_conforming_strings | off statement_timeout | 0 superuser_reserved_connections | 3 synchronize_seqscans | on synchronous_commit | on syslog_facility | local0 syslog_ident | resource6279_heroku_com tcp_keepalives_count | 9 tcp_keepalives_idle | 7200 tcp_keepalives_interval | 75 temp_buffers | 1024 temp_tablespaces | TimeZone | UTC timezone_abbreviations | Default trace_notify | off trace_recovery_messages | log trace_sort | off track_activities | on track_activity_query_size | 1024 track_counts | on track_functions | none transaction_isolation | read committed transaction_read_only | off transform_null_equals | off unix_socket_group | unix_socket_permissions | 511 update_process_title | on vacuum_cost_delay | 0 vacuum_cost_limit | 200 vacuum_cost_page_dirty | 20 vacuum_cost_page_hit | 1 vacuum_cost_page_miss | 10 vacuum_defer_cleanup_age | 0 vacuum_freeze_min_age | 50000000 vacuum_freeze_table_age | 150000000 wal_block_size | 8192 wal_buffers | 1024 wal_keep_segments | 127 wal_level | hot_standby wal_segment_size | 2048 wal_sender_delay | 200 wal_sync_method | fdatasync wal_writer_delay | 200 work_mem | 102400 xmlbinary | base64 xmloption | content zero_damaged_pages | off (196 rows)
うーん。shared_buffers=53120ってことは8KBかけて400MBですね。キャッシュって何のことなんだろう。。。
まあ今に始まったことではないかもしれませんが。。。
SQL Server 2012の全貌が見えてきた!新ライセンス体系、高可用性、見える化、インメモリ、そしてビッグデータ (2/3):EnterpriseZine(エンタープライズジン)
Enterpriseエディションならではの機能としてカラムベースのインデックス処理技術である「カラムストアインデックス」がある。Excel/SharePointのアドインである多次元インメモリ機能「PowerPivot」のカラムベースエンジン(VertiPack)をベースに、列(カラム)単位のインデックス格納を実現、データの圧縮率を大幅に高め、パフォーマンスを劇的に向上させる機能だ。斎藤氏によれば「件数にもよるが、フルテーブルスキャンに比べて100倍以上は高速になる」とのこと。日次集計など参照処理を行うデータウェアハウジングにおいて大幅な処理性能向上が期待できる。
カラム単位のインデックスって普通じゃね?インデックスって普通カラムに対して貼るものだよね??五味さんって以前もPostgreSQLかなんかの記事で意味不明なことを書いていた記憶があるからまあ記者なんてそんなもんだよねと思っていたら、Microsoftのページにも「Columnstore Index」って書いてあったなんだかなと思ったり。
でよく読んでみると列圧縮(カラムコンプレッション)のことなんだと思う。ただしGreenplumのそれと違って元のテーブルはそのまま保存して列圧縮したデータを別に作るんだろうと思われる。なので「インデックス」と呼んでいるんだと思うんだけど、それって本質的にインデックスじゃないよね?? どっちかっていうとVerticaのマテリアライズドビューに近い気がする。だいたいあれですよ、Clustered Indexって奴だって、それ意味あるの??みたいな話でしょ。
ちなみに列圧縮はBIデータベースでは割とホットでして、元々列指向のVerticaやSybaseはともかく、Netizza、Teradata、Greenplumもサポート(予定)しており、ないと列強に加われないという明治時代の軍艦みたいなものです。あ、Oracle(Exadata)もサポートするとかしたとか。
Teradata Columnar and Teradata 14 compression | DBMS?2 : DataBase Management System Services
Jim Gray亡き今というか彼がいたからSQL ServerがBIっぽくなっちゃっただけで、MySQLみたいに「そういうのは関係ないですから」っていう方向を進めばよかったのに。
閑話休題。
AlwaysOnでは、最大4台のセカンダリサーバに複製可能で、自動/手動によるフェールオーバーが可能だ。セカンダリは同期モードと非同期モードに設定することができ、同期モードに設定すると「アクティブセカンダリ」として稼働させることができる。いつでもプライマリに取って代われるセカンダリ、という位置づけだ。これにより処理を負荷分散させながらコンピューティングリソースを使うことが可能で、高い可用性を維持できるという。デモでは東京⇔大阪間でのフェールオーバーが行われた場合、ダウンタイム15秒程度でセカンダリがプライマリのロールを引き継いで稼働するデモが実演された。ほぼリアルタイムの同期といっていいだろう。
15秒!?15秒でリアルタイムって呼んでいいの??何千件というトランザクションが消える(失敗する)と思うんですけど、いいんですね。それでいいんですね。WALをディスクに書くか、メモリに書くかですったもんだ議論しているPostgreSQLのレプリケーションはがんばりすぎですかね。もちろんフェイルオーバーが透過的にできるのは大事なことだと思いますけど、15秒ってひどくないですか。しかも最大4台とか。「カスケードしてもいい?」とかおちゃめなことを言ってるFujiiさんが泣きます。
まー総じてSQL Serverのテクノロジっていつの時代もこんなかんじで「えっ?」って話が多いような気がするけど、実際自分がその業界に行ってみてわかった、SQL ServerをBIで使ってるところはないに等しい(笑)もちろん小規模でOLTPと並行でBIツールと使ってるところはあるけれども、大規模でいうと Teradata、Oracle、Netizza、Greenplum、たまにSybaseとかAsterとかVerticaとかいう話はあっても、SQL Serverはないね。それでも大企業のバックエンドでWindowsサーバーと抱き合わせで使ってる人たち、かわいそうになあ、っていつも思うけど。Jとか。レプリケーションの怠慢っぷりに何度となく泣かされておりましたもので。まったくMSの誇大広告には目に余るものがある・・・
SFPUG二回目。今日はHerokuオフィスで直々にPostgreSQLの話を聞いてきましたよ。
彼らはpure PostgreSQLを使っていて、ソースには全く手を入れていない。が、デモを見る限りAmazonにPostgreSQLインスタンスをワンクリックで立ち上げてWALもばっちり保存(自作のWAL-Eとやらを使ってるらしい)。ストリーミングレプリケーションとホットスタンバイもWebの管理画面からワンクリックで追加。DBのスナップショットもワンクリック。まさにこれぞ象の群れと呼ぶべきかもしれない。
写真貼りますけどオフィスはサンフランシスコ市中にあっておしゃれなレンガ作りの建物を3フロアゆったり使ってオサレな感じ。雰囲気的にはCookPadが近いと思うけど、Ruby使いはいつもオサレだね。そんなオサレな連中がPostgreSQLに注目しているというのがまたホット。MySQLには全く興味がないってさ。
そんな彼らが今最も注目しているのがpl/v8。今俺触ってないって何回も言ってるのに「よくするにはどうしたらいいか」「このプロジェクトこそが今我々に最も必要だ」などとアツく語られてしまいました。やっぱHerokuのターゲットが小〜中規模のWebアプリをさくさく作ることにあるため、JavaScriptこそが最も使い勝手がいいらしい。おまけに速い(と彼らは思ってる)。メンバーの一人が作ったプレゼン↓
http://pgeu-plv8.herokuapp.com/
そんなわけでシャレで始めたplv8ですがHerokuだけでなく随分いろんな人が興味持ってるらしいしplv8開発者は絶賛期待されております。9.2か9.3にはJSONデータ型も入れてHerokuのデファクトにしたいってさ。そうなるとpl/perlやpl/pythonどころじゃなくなるかもねー
んだば