PostgreSQL+DRBD+Heartbeat(目次) +

システム構成 +

PostgreSQL+DRBD+Heartbeat.JPG

HeartbeatとDRBDを利用してPostgreSQLのHAクラスタ(Active/Stanby)を実現します。
クラスタにはHeartbeatを利用し、データベース(/data)はDRBDでネットワーク越しのデータミラーリングを行います。

プライマリ側 +

  • ホスト名(IP)
    • serv111(192.168.11.111)
  • OS
    • CentOS 5.4(kernel 2.6.18-164.6.1.el5)
  • パッケージ
    • drbd83-8.3.2-6.el5_3
    • kmod-drbd83-8.3.2-6.el5_3
    • heartbeat-2.1.3-3.el5.centos
    • postgresql-server-8.4.2-1PGDG.rhel5
    • postgresql-libs-8.4.2-1PGDG.rhel5
    • postgresql-8.4.2-1PGDG.rhel5
    • compat-postgresql-libs-4-1PGDG.rhel5

セカンダリ側 +

  • ホスト名(IP)
    • serv112(192.168.11.112)
  • OS
    • CentOS 5.4(kernel 2.6.18-164.6.1.el5)
  • パッケージ
    • drbd83-8.3.2-6.el5_3
    • kmod-drbd83-8.3.2-6.el5_3
    • heartbeat-2.1.3-3.el5.centos
    • postgresql-server-8.4.2-1PGDG.rhel5
    • postgresql-libs-8.4.2-1PGDG.rhel5
    • postgresql-8.4.2-1PGDG.rhel5
    • compat-postgresql-libs-4-1PGDG.rhel5

仮想IP +

  • ホスト名(IP)
    • serv111(192.168.11.113)

DRBDのインストール・設定 +

DRBDのインストール +

  • DRBDはyumで8.3をインストールします。
    # yum install drbd83
    # yum install kmod-drbd83

DRBDの設定 +

drbd.confの設定 +

  • DRBDの設定を行います。セカンダリ側も同じ設定をします。
    # vi /etc/drbd.conf
    global {
            usage-count no;
    }
    
    common {
            syncer { rate 10M; }
    }
    
    resource r0 {
            protocol C;
            startup {
                    wfc-timeout 120;
            }
            disk {
                    on-io-error pass_on;
            }
            on serv111 {                  # uname -n
                    device /dev/drbd0;
                    disk /dev/sdb1;
                    address 192.168.11.111:7788;
                    meta-disk internal;
            }
            on serv112 {                  # uname -n
                    device /dev/drbd0;
                    disk /dev/sdb1;
                    address 192.168.11.112:7788;
                    meta-disk internal;
            }
    }

メタファイルの作成 +

  • meta-diskに「internal」を指定した場合、ext3などのファイルシステムが作成されているとメタファイルの作成に失敗する事があるため、ddコマンドを利用してmeta-diskのデバイスをゼロで埋めます。
    詳細は公式サイトFAQ(英文)を参照
    # dd if=/dev/zero bs=1M count=1 of=/dev/sdb1; sync

  • メタファイルを作成します。
    # drbdadm create-md r0
    Writing meta data...
    initializing activity log
    NOT initialized bitmap
    New drbd meta data block successfully created.

自動起動の設定 +

  • 自動起動をonに設定します
    # chkconfig drbd on

  • chkconfigコマンドで自動起動のonを確認します。
    # chkconfig --list drbd
    drbd            0:off   1:off   2:on    3:on    4:on    5:on    6:off

DRBDの起動 +

  • 最初に起動したサーバでは以下のような警告が出るため、yesとタイプして先に進みます。 起動に成功したら、もう1台も起動します。
    # /etc/init.d/drbd start
    Starting DRBD resources: [ d(r0) ]..........
    ***************************************************************
     DRBD's startup script waits for the peer node(s) to appear.
     - In case this node was already a degraded cluster before the
       reboot the timeout is 0 seconds. [degr-wfc-timeout]
     - If the peer was available before the reboot the timeout will
       expire after 120 seconds. [wfc-timeout]
       (These values are for resource 'r0'; 0 sec -> wait forever)
     To abort waiting enter 'yes' [  13]:yes
  • 各サーバのDRBDを起動したら、以下のようにして状態を確認します。
    # cat /proc/drbd
    version: 8.3.2 (api:88/proto:86-90)
    GIT-hash: dd7985327f146f33b86d4bff5ca8c94234ce840e build 
    by mockbuild@v20z-x86-64.home.local, 2009-08-29 14:02:24
    0: cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent B r----
       ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:307200000
    「ro:Secondary/Secondary」の通り、起動時は両方ともセカンダリで接続されています。

プライマリ設定とデータ同期(プライマリ側のみ) +

  • プライマリにしたいサーバで、以下のコマンドを実行するとプライマリへの昇格とデータ同期が実施されます。
    [root@serv111 ~]# drbdadm -- --overwrite-data-of-peer primary r0

  • 次にデータの同期状態を以下のコマンドで確認します。
    [root@serv111 ~]# /etc/init.d/drbd status
    drbd driver loaded OK; device status:
    version: 8.3.2 (api:88/proto:86-90)
    GIT-hash: dd7985327f146f33b86d4bff5ca8c94234ce840e build
    by mockbuild@v20z-x86-64.home.local, 2009-08-29 14:02:24
    m:res  cs          ro                 ds                     p  mounted  fstype
    0:r0   SyncTarget  Primary/Secondary  Inconsistent/UpToDate  C
    ...    sync'ed:    73.6%              (115780/431172)K

DRBDボリュームのマウント(プライマリ側のみ) +

  • DRBDボリュームにファイルシステムを作成後、マウントします。
    [root@serv111 ~]# mke2fs -j /dev/drbd0
    [root@serv111 ~]# mount -t ext3 /dev/drbd0 /data/

    これでDRBDボリュームが利用可能になります。

DRBDの動作確認 +

テストファイルを作成してDRBDの動作確認を行います。

  • プライマリ側でテストファイルを作成後、セカンダリに降格させる。
    尚、セカンダリに降格させるためには、DRBDボリュームをアンマウントさせる必要があります。
    [root@serv111 ~]# echo test > /data/test.txt
    [root@serv111 ~]# umount /data
    [root@serv111 ~]# drbdadm secondary r0
  • セカンダリ側をプライマリに昇格させて、テストファイルを確認します。
    [root@serv112 ~]# drbdadm primary r0
    [root@serv112 ~]# mount -t ext3 /dev/drbd0 /data
    [root@serv112 ~]# cat /data/test.txt
    test
    プライマリ側で作成したファイルが見れれば、DRBDの動作に問題はありません。

PostgreSQLのインストール・設定 +

PostgreSQLのインストール +

  • postgresql8.4を利用するためリポジトリを追加します。
    # rpm -ivh http://yum.pgsqlrpms.org/reporpms/8.4/pgdg-centos-8.4-1.noarch.rpm
  • postgresql-serversのインストール
    # yum install postgresql-server

データベースクラスタの初期化 +

  • /dataの所有者を変更します。
    # chown postgres:postgres /data
    # su - postgres
  • PGDATA環境変数の変更
    $ vi ~/.bash_profile
     PGDATA=/data
     export PGDATA
  • bash_profileの変更を反映します。
    $ source ~/.bash_profile
  • データベースクラスタの初期化を行います。(プライマリ側のみ)
    $ initdb --encoding=UTF-8 --no-locale -D /data
    • --no-locale
      ロケールを無効にするオプションです。
      ロケールとは、言語や文化に応じた処理をするOSの機構で、
      PostgreSQLでは主にデータのソート処理に使用します。

      英語や日本語のデータを扱う場合には特に必要ありません。
      逆に有効にするとロケール処理の分、ソート処理などが遅くなります。

    • -D
      データベースの保存場所を指定します。

  • 最後にアーカイブログ用のディレクトリを作成します。(プライマリ側のみ)
    [root@serv111 ~]$ mkdir /data/archive

PostgreSQLの設定 +

postgresql.confの編集(プライマリ側のみ) +

  • パラメータ設定ファイル「postgresql.conf」を編集します。
    [root@serv111 ~]# vi /data/postgresql.conf
    
    listen_addresses = '*'
    max_connections = 100 
    
    shared_buffers = 64MB 
    wal_buffers = 2MB                     
    work_mem = 4MB
    checkpoint_segments = 16
    
    archive_mode = on 
    archive_command = 'cp "%p" /data/archive/"%f"' 
    
    track_activities = on
    track_counts = on
    
    autovacuum = on 

pg_hba.confの編集 (プライマリ側のみ) +

  • 次にホスト認証設定ファイル「pg_hba.conf」を編集します。
    今回は、LAN(192.168.11.0/24 )からは認証により全データベースにアクセス可能にします。
    [root@serv111 ~]# vi /data/pg_hba.conf
    
    # TYPE  DATABASE    USER        CIDR-ADDRESS          METHOD
    host    all         all         192.168.11.0/24       password

起動スクリプトの修正 +

  • 起動スクリプトの環境変数PGDATAを変更します。
    # vi /etc/init.d/postgresql 
    PGDATA=/data
    PGLOG=/data/pgstartup.log
  • 変更を確認するため起動します。
    # /etc/init.d/postgresql start
    postgresql サービスを開始中:                               [  OK  ]
  • プロセスを確認します。
    # ps ax |grep post
    21481 ?        S      0:00 /usr/bin/postmaster -p 5432 -D /data
    21483 ?        Ss     0:00 postgres: logger process
    21485 ?        Ss     0:00 postgres: writer process
    21486 ?        Ss     0:00 postgres: wal writer process
    21487 ?        Ss     0:00 postgres: autovacuum launcher process
    21488 ?        Ss     0:00 postgres: archiver process
    21489 ?        Ss     0:00 postgres: stats collector process
  • Heartbeatと連携させるため、一旦停止させておきます。
    # /etc/init.d/postgresql stop
    postgresql サービスを停止中:                               [  OK  ]

自動起動の設定 +

  • PostgreSQLはHeartbeatから起動するため自動起動をOFFにします
    # chkconfig postgresql off

  • chkconfigコマンドで自動起動offを確認します。
    # chkconfig --list postgresql
    postgresql      0:off   1:off   2:off   3:off   4:off   5:off   6:off

Heartbeatとの連携 +

Heartbeatのインストール +

  • yumでインストールします。
    # yum install heartbeat

Heartbeatの設定 +

  • heartbeatの設定で利用するファイルは以下の通りです。 尚、heartbeatの設定は特に記述がない限り、プライマリとセカンダリで全く同じ設定を行います。
    ファイル名説明備考
    /etc/ha.d/ha.cfクラスタ構成を定義するメイン設定ファイル
    /etc/ha.d/haresourcesVersion1用のリソース設定ファイル
    /etc/ha.d/authkeys認証設定ファイル


  • 設定ファイルはサンプルがあるのでコピーします。
    # cp /usr/share/doc/heartbeat-2.1.3/authkeys /etc/ha.d/
    # cp /usr/share/doc/heartbeat-2.1.3/ha.cf /etc/ha.d/
    # cp /usr/share/doc/heartbeat-2.1.3/haresources /etc/ha.d/

  • PostgreSQL用のリソース起動スクリプトを用意します。
    # ln -s /etc/init.d/postgresql /etc/ha.d/resource.d/postgresql 

ha.cfの設定 +

  • ha.cfを編集します。ほとんどの設定がコメントアウトを解除しただけです。
    # vi /etc/ha.d/ha.cf
    logfile /var/log/ha-log
    logfacility local0
    keepalive 2
    deadtime 30
    warntime 10
    initdead 120
    
    udpport 694
    #baud    19200      # シリアルケーブル用の設定(今回は利用しない)
    #serial  /dev/ttyS0 # シリアルケーブル用の設定(今回は利用しない)
    bcast eth0 
    
    auto_failback off
    node    serv111  #uname -n
    node    serv112  #uname -n
    
    respawn root /usr/local/bin/check_service #サービス監視スクリプト

haresourcesの設定 +

  • リソースの設定はDRBDに関する設定を一行追加します。
    # vi /etc/ha.d/haresources
    serv111 drbddisk::r0 Filesystem::/dev/drbd0::/data::ext3 postgresql  192.168.11.113/24

authkeysの設定 +

  • 認証の設定を行います。認証は現時点で最もセキュリティレベルの高いsha1を利用します。
    # vi /etc/ha.d/authkeys
    auth 2
    2 sha1 test
  • セキュリティを確保するため、ファイルパーミッションを変更します。セカンダリ側も同様に設定します。
    # chmod 600 /etc/ha.d/authkeys 

サービス監視スクリプトの作成 +

  • heartbeatはサービス(PostgreSQL)が異常終了してもフェイルオーバしてくれません。
    そのため、監視スクリプトを作成して、サービス異常終了時に正しくフェイルオーバさせる必要があります。
    # vi /usr/local/bin/check_service
    
    #!/bin/sh
    
    #
    # heartbeat用 サービス監視スクリプト
    #
    
    #-----------------------------------------------------------------
    INTERVAL=3                   # 監視間隔
    VIP=192.168.11.113           # 仮想IP
    IFNAME="eth0"
    GATEWAY=192.168.11.1         # ゲートウェイ
    
    
    PG_ADMIN=postgres            # PostgreSQLの管理ユーザ
    PSQL="/usr/bin/psql"
    PGDB=template1               # サービス確認に利用するDB
    #-----------------------------------------------------------------
    
    while :
    do
            sleep $INTERVAL
    
            #
            # 仮想IPアドレスの有無を確認 
            #
            /etc/ha.d/resource.d/IPaddr $VIP status > /dev/null 2>&1
            if [ $? -ne 0 ]
            then
                    continue
            fi
    
    
            #
            # インタフェースのLinkを確認 
            #
            LINK=`/sbin/ethtool $IFNAME | awk '/Link detected: /{ print $3}'`
            if [ "$LINK" != "yes" ]
            then
                    /usr/lib/heartbeat/heartbeat -k
                    exit
            fi
    
    
            #
            # ゲートウェイとの通信確認 
            #
            ping -c 1 -w 1 $GATEWAY > /dev/null 2>&1
            if [ $? -ne 0 ]
            then
                    /usr/lib/heartbeat/heartbeat -k
                    exit
            fi
    
    
            #
            # PostgreSQLのサービス確認 
            #
            SQL="SELECT usename FROM pg_user where usename = '$PG_ADMIN'"
            CHK_COM="$PSQL -q -t -c \"$SQL\" $PGDB"
            su - $PG_ADMIN -c "$CHK_COM" > /dev/null 2>&1
            if [ $? -ne 0 ]
            then
                    /usr/lib/heartbeat/heartbeat -k
                    exit
            fi
    
    done

自動起動の設定 +

  • 自動起動をonに設定します。セカンダリ側も同様に設定します。
    # chkconfig heartbeat on

  • chkconfigコマンドで自動起動のonを確認します。
    # chkconfig --list heartbeat 
    heartbeat       0:off   1:off   2:on    3:on    4:on    5:on    6:off

Heartbeatの起動 +

  • Heartbeatを起動します。セカンダリ側も同様に起動させます。
    # /etc/init.d/heartbeat start

Heartbeatの動作確認 +

プライマリ側のPostgreSQLを停止させてフェイルオーバーの動作確認を行います。

初期状態の確認 +

  • serv111(プライマリ側)の状態を確認します。
    仮想IPが割り当てられている事を確認します。
    [root@serv111 ~]# ifconfig -a eth0:0
    eth0:0    Link encap:Ethernet  HWaddr 00:0C:29:82:38:64
              inet addr:192.168.11.113  Bcast:192.168.11.255  Mask:255.255.255.0
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              Interrupt:177 Base address:0x1400

    DRBD領域をマウントしている事を確認します。
    [root@serv111 ~]# /etc/init.d/drbd status
    drbd driver loaded OK; device status:
    version: 8.3.2 (api:88/proto:86-90)
    GIT-hash: dd7985327f146f33b86d4bff5ca8c94234ce840e build 
    by mockbuild@v20z-x86-64.home.local, 2009-08-29 14:02:24
    m:res  cs         ro                 ds                 p  mounted  fstype
    0:r0   Connected  Primary/Secondary  UpToDate/UpToDate  C  /data    ext3

    PostgreSQLが起動されている事を確認します。
    [root@serv111 ~]# ps ax |grep post
    22722 ?        S      0:00 /usr/bin/postmaster -p 5432 -D /data
    22724 ?        Ss     0:00 postgres: logger process
    22726 ?        Ss     0:00 postgres: writer process
    22727 ?        Ss     0:00 postgres: wal writer process
    22728 ?        Ss     0:00 postgres: autovacuum launcher process
    22729 ?        Ss     0:00 postgres: archiver process
    22730 ?        Ss     0:00 postgres: stats collector process


  • serv112(セカンダリ側)の状態を確認します。
    仮想IPが割り当てられていない事を確認します。
    [root@serv112 ~]# ifconfig -a eth0:0
    eth0:0    Link encap:Ethernet  HWaddr 00:0C:29:74:23:12
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              Interrupt:177 Base address:0x1400

    DRBD領域もマウントされていない事を確認します。
    [root@serv112 ~]# /etc/init.d/drbd status
    drbd driver loaded OK; device status:
    version: 8.3.2 (api:88/proto:86-90)
    GIT-hash: dd7985327f146f33b86d4bff5ca8c94234ce840e build 
    by mockbuild@v20z-x86-64.home.local, 2009-08-29 14:02:24
    m:res  cs         ro                 ds                 p  mounted  fstype
    0:r0   Connected  Secondary/Primary  UpToDate/UpToDate  C

    PostgreSQLが起動していない事を確認します。
    [root@serv112 ~]# ps ax |grep post

フェイルオーバーの確認 +

  • フェイルオーバーの確認をするため、serv111(プライマリ側)のPostgreSQLを停止させます。
    [root@serv111 ~]# /etc/init.d/postgresql stop
    postgresql サービスを停止中:                               [  OK  ]


  • serv111の状態を確認します。
    PostgreSQLを終了させたため、仮想IPが割り当てられていません。
    [root@serv111 ~]# ifconfig -a eth0:0
    eth0:0    Link encap:Ethernet  HWaddr 00:0C:29:82:38:64
             UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
             Interrupt:177 Base address:0x1400
    
    DRBD領域もマウントされていません。
    [root@serv111 ~]# /etc/init.d/drbd status
    drbd driver loaded OK; device status:
    version: 8.3.2 (api:88/proto:86-90)
    GIT-hash: dd7985327f146f33b86d4bff5ca8c94234ce840e build 
    by mockbuild@v20z-x86-64.home.local, 2009-08-29 14:02:24
    m:res  cs         ro                 ds                 p  mounted  fstype
    0:r0   Connected  Secondary/Primary  UpToDate/UpToDate  C

    PostgreSQLも起動していません。
    [root@serv111 ~]# ps ax |grep post


  • serv112の状態を確認します。
    serv111側でPostgreSQLを終了させたため、仮想IPが割り当てられています。
    [root@serv112 ~]# ifconfig -a eth0:0
    eth0:0    Link encap:Ethernet  HWaddr 00:0C:29:74:23:12
              inet addr:192.168.11.113  Bcast:192.168.11.255  Mask:255.255.255.0
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              Interrupt:177 Base address:0x1400

    DRBD領域もマウントされています。

    [root@serv112 ~]# /etc/init.d/drbd status
    drbd driver loaded OK; device status:
    version: 8.3.2 (api:88/proto:86-90)
    GIT-hash: dd7985327f146f33b86d4bff5ca8c94234ce840e build 
    by mockbuild@v20z-x86-64.home.local, 2009-08-29 14:02:24
    m:res  cs         ro                 ds                 p  mounted  fstype
    0:r0   Connected  Primary/Secondary  UpToDate/UpToDate  C  /data    ext3

    PostgreSQLも起動しています。
    [root@serv112 ~]#  ps ax |grep post
    31910 ?        S      0:00 /usr/bin/postmaster -p 5432 -D /data
    31949 ?        Ss     0:00 postgres: logger process
    31951 ?        Ss     0:00 postgres: writer process
    31952 ?        Ss     0:00 postgres: wal writer process
    31953 ?        Ss     0:00 postgres: autovacuum launcher process
    31954 ?        Ss     0:00 postgres: archiver process
    31955 ?        Ss     0:00 postgres: stats collector process

これでフェイルオーバの確認は終了です。

FAQ +

メタファイル作成時にエラーが表示される +

  • Q.
    メタファイル作成時に下記のようなエラーが表示されてメタファイルが作成できない。
    # drbdadm create-md r0
    md_offset 2146758656
    al_offset 2146725888
    bm_offset 2146660352
    
    Found ext3 filesystem which uses 2096448 kB
    current configuration leaves usable 2096348 kB
    
    Device size would be truncated, which
    would corrupt data and result in
    'access beyond end of device' errors.
    You need to either
       * use external meta data (recommended)
       * shrink that filesystem first
       * zero out the device (destroy the filesystem)
    Operation refused.
    
    Command 'drbdmeta 0 v08 /dev/sdb1 internal create-md' terminated with exit code 40
    drbdadm create-md r0: exited with code 40

  • A.
    ext3などのファイルシステムが作成されているとmetaファイルの作成に失敗する事があります。
    その場合はddコマンドを利用してmeta-diskのデバイスをゼロで埋めた後でメタファイルを作成して下さい。
    # dd if=/dev/zero bs=1M count=1 of=/dev/sdb1; sync
    # drbdadm create-md r0

DRBDが起動しない +

  • Q.
    DRBDを起動すると下記エラーが出て起動できない。
    # /etc/init.d/drbd start
    Starting DRBD resources: Can not load the drbd module.
  • A.
    DRBDのモジュールがインストールされていない可能性があります。
    下記の通りインストールしてください。
    # yum install kmod-drbd83

リンク +

このエントリーをはてなブックマークに追加
Last-modified: 2010-06-05 (土) 12:30:45 (627d)   最終更新のRSS