2014年03月

pgpoolのオンラインリカバリにおけるrecovery_2nd_stage.shについて

ErogameScapはpgpoolのレプリケーションモードを使っています。
※PostgreSQLのVerが9.3なのでPostgreSQLのストリーミングレプリケーションとpgpoolのマスタースレーブモードを使うのがスマートだと思うのですが、レプリケーションモードで不自由していないのでレプリケーションモードのままです…

pgpoolのレプリケーションモードでオンラインリカバリをする場合のrecovery_2nd_stage.shの内容について、googleで「pgpool オンラインリカバリ」で検索すると2014-01-05時点以下の文書が引っかかります。

が書いてありますが、この文はいらないです。

pgpoolのオンラインリカバリの動作はざっくりと以下のような内容です。

1. リカバリ先にリカバリ元のデータを全部コピーする
2. リカバリ元へのクエリの受付を停止する
3. 1.~2.の間に更新された内容が、archive_logディレクトリ配下にあるので、リカバリ元のarchive_logの内容をリカバリ先のarchive_logにコピーする
4. リカバリ先のPostgreSQLを立ち上げる

recovery_2nd_stage.shに
rsync -az -e ssh $MASTER_BASEDIR/archive_log/ $RECOVERY_HOST:$RECOVERY_BASEDIR/archive_log/
と書いているのは、3.の動作を実現するためです。

1.の動作の中に
cp $RECOVERY_BASEDIR/archive_log/%f %pと書いたrecovery.confをリカバリ先に置く
という動作があります。

PostgreSQLはrecovery.confがあると、recovery.confに書かれた内容を実行してPostgreSQLサーバを立ち上げます。
cp $RECOVERY_BASEDIR/archive_log/%f %p

rsync -az -e ssh $MASTER_BASEDIR/archive_log/ $RECOVERY_HOST:$RECOVERY_BASEDIR/archive_log/
とやっていることが同じです。

したがって、 recovery_2nd_stage.shに
rsync -az -e ssh $MASTER_BASEDIR/archive_log/ $RECOVERY_HOST:$RECOVERY_BASEDIR/archive_log/
を書く必要はありません。

※pgpoolのオンラインリカバリの仕組みはPostgreSQLのオンラインバックアップの仕組みを理解している必要があります。pgpoolのオンラインリカバリのドキュメントだけを読むと、recovery_2nd_stage.shの中にarchive_log配下をコピーする何かを書かなくてはいけない気がしますが…というか、私もそう思っていましたが、rsyncが書いていない文書もあるし、たしかにrsyncが書いていなくても、ちゃんと動いているし、なんでかな…と思って調べて理解しました。

pgpoolのinsert_lockテーブルの作成はデータベース毎に必要

公式マニュアルにちゃんと書いてあるのですが、私が見逃していたのでメモします。

マニュアルの日本語を読まないで、コマンドだけを見てると
cd pgpool-II-x.x.x/sql
psql -f insert_lock.sql template1
と書いてあるので、上記コマンドだけ実行します。
が…上記コマンドは「データベース毎」に実行して、pgpool_catalog.insert_lockというテーブルを作成する必要があります。

「データベース毎」に実行する…というのは、どういうことでしょうか。
例えばhogehogeというユーザーがcreatedbでデータベースを作成すると、デフォルトではhogehogeという名前のデータベースが作成されます。
「データベース毎」に実行する…というのはhogehogeというデータベースがあるのなら
psql -f insert_lock.sql hogehoge
を実行する…ということです。

insert_lock.sqlには
CREATE TABLE pgpool_catalog.insert_lock(reloid OID PRIMARY KEY);
他…が書いてあります。
pgpool_catalog.insert_lockはpgpoolがINSERT文を発行するときの排他制御に使われます。

pgpool_catalog.insert_lockがないと、pgpoolはINSERT対象のテーブルにロックをかけます。

INSERTがとても多いテーブル…例えばなんらかのログを記録していくテーブルの場合、INSERTするたびにテーブルにロックをかけていく動作は致命的です。
公式マニュアルには「VACUUMと競合してINSERT処理が長時間が待たされる可能性があります」と書かれています。
最悪待ち時間が長すぎてpgpoolを利用しているアプリケーションに待ちが発生し、待ちが長すぎてサービスが停止します。
※実際にErogameScapeのサービスは停止しました。

マニュアルはちゃんと読みましょう…

※ちなみに私が「なにかおかしいな…」と気がついたのは、確かtopコマンドの出力を眺めていて、SHARE ROW EXCLUSIVEでロックがはいっているのを見たからでした。
SHARE ROW EXCLUSIVEは明示的に指定しないと使われないロックです。
なんでこんなロックが入っているのかな…と思って調べていたら、この記事の内容に気がつきました。 

PostgreSQL9.2におけるpg_stat_activityの変更点について

PostgreSQLをVerUPするときにはリリースノートをちゃんと読んで既存のシステムに影響がないかを確認しないといけないです。
PostgreSQLを9.0から9.3にあげた際に変更を把握していないではまった点について書きます。

PostgreSQL9.0のpg_stat_activityテーブルの定義は以下の通りです。
         ビュー "pg_catalog.pg_stat_activity"
        列        |            型            | 修飾語
------------------+--------------------------+--------
 datid            | oid                      |
 datname          | name                     |
 procpid          | integer                  |
 usesysid         | oid                      |
 usename          | name                     |
 application_name | text                     |
 client_addr      | inet                     |
 client_port      | integer                  |
 backend_start    | timestamp with time zone |
 xact_start       | timestamp with time zone |
 query_start      | timestamp with time zone |
 waiting          | boolean                  |
 current_query    | text                     |


PostgreSQL9.3のpg_stat_activityテーブルの定義は以下の通りです。
         ビュー "pg_catalog.pg_stat_activity"
        列        |            型            | 修飾語
------------------+--------------------------+--------
 datid            | oid                      |
 datname          | name                     |
 pid              | integer                  |
 usesysid         | oid                      |
 usename          | name                     |
 application_name | text                     |
 client_addr      | inet                     |
 client_hostname  | text                     |
 client_port      | integer                  |
 backend_start    | timestamp with time zone |
 xact_start       | timestamp with time zone |
 query_start      | timestamp with time zone |
 state_change     | timestamp with time zone |
 waiting          | boolean                  |
 state            | text                     |
 query            | text                     |

列が追加、列名が変更されています。

ErogameScapeでは、2013年9月に起きた障害の対策としてテーブルに長時間ロックをかけているクエリとそのロック解除を待っているクエリを強制的に終了させるスクリプトを動かしています。
そのスクリプトはpg_stat_activityの内容を使っています。
pg_stat_activityのprocpidがpidにかわっていたのでスクリプトの中のSQLの修正が必要でした。


ErogameScapeは実質サーバー1台で動かしているので、パソコンの前に座っている時はtopを眺めています。CPUを食っているPostgreSQLのプロセスを見つけたら、
SELECT * FROM pg_stat_activity WHERE pid = プロセスID ;
して、 実行されているクエリを特定してEXPLAINしてみます。

こんなことをしなくてもスロークエリをログに保存して後で見ればいいのですが、今起こっている事象を見る方に興味がわいてしまいます…

さくらのレンタルサーバはsshでログインできる

はじめに

さくらインターネットのさくらのレンタルサーバはスタンダード以上のプランであればsshでログインできます。
※さくらのレンタルサーバを使い始めて相当経ちますが、今さら知りました…


さくらインターネットのさくらのレンタルサーバにsshでログインする

さくらインターネットのレンタルサーバーを使ってみる事にした - e_p_i's blog の文書がいいかなと思います。

CentOS同士ですと(ErogameScapeはCentOSを使っています)
$ ssh-keygen -t dsa

Enter file in which to save the key (/home/hogehoge/.ssh/id_dsa): そのままEnter
Enter passphrase (empty for no passphrase): そのままEnter
Enter same passphrase again: そのままEnter

$ ssh-copy-id -i .ssh/id_dsa.pub [ユーザー名]@[].sakura.ne.jp

ap2@192.168.0.14's password: パスワード入力

$ ssh [ユーザー名]@[ドメイン名の一部].sakura.ne.jp
でいけるのですが、
$ ssh-copy-id -i .ssh/id_dsa.pub ap2.sakura.ne.jp
Ambiguous output redirect.
となってしまうので、上記リンク先の文書の通りにやるか、authorized_keysを直接編集するかになるかなあ…と思います。


経緯

ErogameScapeでキャラクター紹介のための画像データを持つことにしました。
画像のデータは転送量が多いので、画像データ用のサーバーを用意することにしました。
画像データ用のサーバーは自宅サーバーにはおかず、契約していたさくらのVPSに置くことにしました。

ある日、さくらのVPSにデータを転送しようとしたら、転送NGでした。
NGの内容は容量超過でした…
さくらのVPSは1G HDDプランで100GBのディスク容量を持つ(2013/12/28現在)のですが、私が契約した時点では20GBでした。

今のさくらのVPSに移行すれば同じ値段でディスク容量が100Gに増えるのですが「また1から設定するのがめんどくさい…」ということで、別に使っていたさくらのレンタルサーバーに画像データを移すことにしました。
※ちなみに、さくらのレンタルサーバーのスタンダードプランも、私が契約した当時はディスク容量が30Gだったのですが、100Gになっていました…今の設定を引き継いで以降できるのかな…

データの移行にはrsyncを使うのが一番早いと思うのですが、 「レンタルサーバーってftpしか使えないよね」という思い込みがありました。

が…OHPを見ると「シェルログイン」と書いてあることを知りました。
無事rsyncでデータを移行することができました。 

私、VPSじゃないと出来ないことが結構あるんじゃなかろうか?と思っていたのですが、シェルログインが使えるのであれば、レンタルサーバーで一通りのことが出来るんじゃないかなあ…思いました。
多くの方々にとってはVPSを運用するってかなり高いスキルが求められて厳しいと思っています。   
記事検索