トップページ

Linux 日記
  Linux日記08~
  Linux日記2006
  Linux日記2005
  Linux日記2004
  Linux日記2003
  Linux日記2002
  Linuxカーネル
  + メモ ... (3p)
  + 勉強会 ... (6p)

アートでいこう(笑)!
  イラスト日記08〜
  イラスト日記2005
  イラスト日記2004
  イラスト日記2003
  アイコン描こうぜ

UCC(梅丘自転車部)
  活動ログ2003
  活動ログ2001
  活動ログ2000
  その他
  ワシの愛車

自動車関連
  FD3S日記05~
  S202日記2004
  S202日記2003
  S202日記2002
  S202給油等記録
  S202掲示板

自宅前カメラ
EZweb/PCSV用
プロフィール
社会科ノート 2004
社会科ノート 2003
全角半角変換
自家用リンク
視聴予定表
メモ

W/O index
Linux 日記 2008~

pg_standby (Mon Jun 22 2009)

ドキュメント(PostgreSQL: Documentation: Manuals: PostgreSQL 8.3: pg_standby, 同和訳)を読んでもいまいち挙動がわからなかったので、ソースをあたってみた。以下、PostgreSQL のコードからの抜粋の擬似コード化。

postgresql-8.3.7/src/backend/access/transam/xlog.c:
  >>> StartupXLOG () {
    readRecoveryCommandFile();
    >>> readRecoveryCommandFile () {
      if (strcmp(tok1, "restore_command") == 0) {
        recoveryRestoreCommand = pstrdup(tok2);
      }
    }
    if (read_backup_label(&checkPointLoc, &minRecoveryLoc)) {
      record = ReadCheckpointRecord(checkPointLoc, 0);
      if (record != NULL) {
        InRecovery = true;
      }
    } else {
      checkPointLoc = ControlFile->checkPoint;
      record = ReadCheckpointRecord(checkPointLoc, 1);
      if (record == NULL) {
        checkPointLoc = ControlFile->prevCheckPoint;
        record = ReadCheckpointRecord(checkPointLoc, 2);
        if (record != NULL) {
          InRecovery = true;
        }
      }
    }
    if (InRecovery) {
      if (XLByteLT(checkPoint.redo, RecPtr)) {
        record = ReadRecord(&(checkPoint.redo), PANIC);
      } else {
        record = ReadRecord(NULL, LOG);
      }
      if (record != NULL) {
        // main redo apply loop
        do {
          RestoreBkpBlocks(record, EndRecPtr);
          >>> RestoreBkpBlocks () {
            // いまいちわからんが、こいつが書き出しているようだ
          }
          record = ReadRecord(NULL, LOG);
          >>> ReadRecord () {
            readFile = XLogFileRead(readId, readSeg, emode);
            >>> XLogFileRead () {
              foreach(cell, expectedTLIs) {
                if (InArchiveRecovery) {
                  restoredFromArchive = RestoreArchivedFile(path,
                   xlogfname, "RECOVERYXLOG", XLogSegSize );
                  >>> RestoreArchivedFile () {
                    rc = system(xlogRestoreCmd);
                  }
                }
              }
            }
          }
        } while (record != NULL && recoveryContinue);
        errmsg("redo done at ~");
      }
    }
  }

なるほどね。てっきり postgres プロセスは、起動の際、restore_command を用いて、一気に全ての WAL ログ セグメント ファイルをコピーしてから適用するものだと思っていたからワケ分からなくなっていたのだが、実際には、一つ処理しては適用している。pg_standby が単なるコピーコマンドと異なる点は、「次」が見つからなかったとき、postgres プロセスに処理を返さず、次のログ ファイルが届くか、あるいは主系が死ぬまで待機するところ。postgres に「スタンバイモード」といったようなものがあるわけではなく、単に pg_standby が処理を戻さないだけのこと。なので、まさに warm standby。主系が死んだら、速攻でサービスが始められるようになっている。

逆に言うと、warm standby な DB cluster では、古いスナップショットは無くなっちゃっているので、人為的ミスからの PITR リカバリには使えないってことですね。それはそれでどこか別に保持しておかないと。


*.la について (Mon Oct 20 2008)

        
On Thu, Apr 24, 2008 at 02:49:27PM +0900, Kiichiro NAKA wrote:
> この記事(↓)が、とてもよくまとまっていて参考になりました。Gentoo の
> コアメンテナらしい。
>
>   What about those .la files?
>   http://blog.flameeyes.eu/articles/2008/04/14/what-about-those-la-files
>
> 最終理想形は、libltdl 用を除く *.la は取り除き、静的ライブラリは
> "pkg-config --static" で依存先を取得できるようにする、であるが、なかな
> かうまくはいかないね、ということのようです。

DBus (Thu Oct 02 2008)

DBus が、システムのための IPC とセッションごとの IPC を提供しているのは分かるのですが、実装や設定方法がからきし分かりません。調べてみます。

81        3324  0.0  0.1   2432   932 ?        Ss   Sep30   0:03 \
 dbus-daemon --system
knaka     3792  0.0  0.1   3200   700 ?        S    Sep30   0:00 \
 /usr/bin/dbus-launch --exit-with-session --sh-syntax
knaka     3793  0.0  0.1   2300   788 ?        Ss   Sep30   0:00 \
 /usr/bin/dbus-daemon --fork --print-pid 5 --print-address 7 --session
knaka    22602  0.0  0.1   2868   856 pts/4    S+   07:53   0:00 \
 grep -i dbus

/etc/init.d/messagebus がサービスとしてシステムバスを用意。

start() {
  ...
  daemon --check $servicename $processname --system

X 起動時に、セッションバスを用意。

$ cat /etc/X11/xinit/xinitrc.d/30dbus
# to be sourced
eval `/usr/bin/dbus-launch --exit-with-session --sh-syntax`

参照: D-BUS によるメッセージの受け渡し

/var/run/messagebus.pid

/etc/dbus-1/system.conf の に、UNIX domain socket のパスがある。dbus-1.2.1/dbus/dbus-sysdeps-unix.c:_dbus_listen_unix_socket() で bind(2) してそのパスを指定している。UNIX ドメインソケットについては unix(7) を見てください。セクション 7 は "その他"。セクションについては man(1) で。

[root@localhost proc]# netstat --listen --programs  | grep system_bus_socket
unix  2      [ ACC ]     STREAM     LISTENING     6608   \
 3324/dbus-daemon    /var/run/dbus/system_bus_socket
[root@localhost proc]# netstat --programs  | grep system_bus_socket
unix  3      [ ]         STREAM     CONNECTED     103628 \
 3324/dbus-daemon    /var/run/dbus/system_bus_socket
unix  3      [ ]         STREAM     CONNECTED     18705  \
 3324/dbus-daemon    /var/run/dbus/system_bus_socket
unix  3      [ ]         STREAM     CONNECTED     8944   \
 3324/dbus-daemon    /var/run/dbus/system_bus_socket
unix  3      [ ]         STREAM     CONNECTED     8725   \
 3324/dbus-daemon    /var/run/dbus/system_bus_socket
unix  3      [ ]         STREAM     CONNECTED     8302   \
 3324/dbus-daemon    /var/run/dbus/system_bus_socket
unix  3      [ ]         STREAM     CONNECTED     7908   \
 3324/dbus-daemon    /var/run/dbus/system_bus_socket
unix  3      [ ]         STREAM     CONNECTED     7109   \
 3324/dbus-daemon    /var/run/dbus/system_bus_socket
unix  3      [ ]         STREAM     CONNECTED     6683   \
 3324/dbus-daemon    /var/run/dbus/system_bus_socket
unix  3      [ ]         STREAM     CONNECTED     6655   \
 3324/dbus-daemon    /var/run/dbus/system_bus_socket
[root@localhost proc]# LANG=C ls -l /proc/3324/fd/
total 0
lrwx------ 1 root root 64 Oct  3 07:58 0 -> /dev/null
lrwx------ 1 root root 64 Oct  3 07:58 1 -> /dev/null
lrwx------ 1 root root 64 Oct  3 07:58 10 -> socket:[6683]
lrwx------ 1 root root 64 Oct  3 07:58 11 -> socket:[7908]
lrwx------ 1 root root 64 Oct  3 07:58 12 -> socket:[8302]
lrwx------ 1 root root 64 Oct  3 07:58 13 -> socket:[8725]
lrwx------ 1 root root 64 Oct  3 07:58 14 -> socket:[103628]
lrwx------ 1 root root 64 Oct  3 07:58 15 -> socket:[18705]
lrwx------ 1 root root 64 Oct  3 07:58 16 -> socket:[8944]
lrwx------ 1 root root 64 Oct  3 07:58 2 -> /dev/null
lrwx------ 1 root root 64 Oct  3 07:58 3 -> socket:[6608]
lrwx------ 1 root root 64 Oct  3 07:58 4 -> /dev/null
lr-x------ 1 root root 64 Oct  3 07:58 5 -> /inotify
lrwx------ 1 root root 64 Oct  3 07:58 6 -> socket:[6610]
lrwx------ 1 root root 64 Oct  3 07:58 7 -> socket:[6611]
lrwx------ 1 root root 64 Oct  3 07:58 8 -> socket:[6655]
lrwx------ 1 root root 64 Oct  3 07:58 9 -> socket:[7109]

d-feet で見られるのだが、コマンドラインのツールはないか?

[root@localhost ~]# ps aux | grep sr0
root      3453  0.0  0.2   3340  1104 ?        S    Sep30   \
 1:10 hald-addon-storage: polling /dev/sr0 (every 2 sec)
[root@localhost ~]# LANG=C ls -l /proc/3453/fd/
total 0
lr-x------ 1 root root 64 Oct  3 10:06 0 -> /dev/null
lrwx------ 1 root root 64 Oct  3 10:06 1 -> /dev/null
lrwx------ 1 root root 64 Oct  3 10:06 2 -> /dev/null
lrwx------ 1 root root 64 Oct  3 10:06 3 -> socket:[7108]
lrwx------ 1 root root 64 Oct  3 10:06 4 -> socket:[7110]
[root@localhost ~]# netstat --program | grep -e 7108 -e 7110
unix  3      [ ]         STREAM     CONNECTED     7110   3453/sr0 (every 2 s
unix  3      [ ]         STREAM     CONNECTED     7108   3453/sr0 (every 2 s

以下、FAQ の "Bus Names" の項参照。

listen port みたいなものとして、Well-known Names というのがバスに付与されます。"org.freedesktop.ConsoleKit" みたいなの。

private connection 用バスには、UCN - Unique Connection Name が付与されます。

残念ながら Linux には、クライアントがオープンしている UNIX ドメインソケットが、どのサーバプロセスのどのソケットと通信しているか知る方法がありません。せいぜい、/proc/net/unix で、ノード番号がとなりあっているどうしはほぼ同時に作られたから相互に通信しているだろうな、と推測するくらいしかできません。

|-hald---hald-runner-+-hald-addon-acpi
|                    |-hald-addon-input
|                    `-hald-addon-storage

hal-0.5.11rc2/hald/linux/addons/Makefile.am:
  libexec_PROGRAMS = \
    ... \
    hald-addon-storage

  hald_addon_storage_SOURCES = \
   addon-storage.c ../../logger.c ../../util_helper.c

hal-0.5.11rc2/hald/linux/addons/addon-storage.c:update_proc_title()
  hal_set_proc_title("hald-addon-storage: polling %s (every %d sec)",
   device_file, interval_in_seconds );

hal-0.5.11rc2/hald/util_helper.c:
  static char **argv_buffer = NULL;
  hal_set_proc_title_init(int argc, char *argv[]):
    argv_buffer = argv;
  hal_set_proc_title():
    vsnprintf(argv_buffer[0], argv_size, format, ap);
dbus-1.2.1/bus/dispatch.c:check_get_connection_unix_process_id()
  dbus_message_new_method_call(DBUS_SERVICE_DBUS,
   DBUS_PATH_DBUS,
   DBUS_INTERFACE_DBUS,
   "GetConnectionUnixProcessID" );

dbus-1.2.1/dbus/dbus-shared.h:
  #define DBUS_SERVICE_DBUS "org.freedesktop.DBus"

これ何だ? d-feet では出ないんだが。

d-feet は出さないようにしている。dbus_introspector.py:BusWatch.add_name() で落としている。

- ご意見・ご要望は、サイト管理者(那賀樹一郎 (Kiichiro NAKA) <knaka@ayutaya.com>)までお願いします。
- このサイトは、Turbolinux 上の Mozilla w3m でテストされています。Internet Explorer では未確認です
- 言うまでもありませんが、当サイトはリンクフリーです
- W3C の HTML チェックをかけたところ、ズタボロでした。頑張ったけど、ダメだこりゃ……