PostgreSQL 9.6→10アップグレードのダウンタイムをpglogicalで最小化(翻訳)

概要 原著者の許諾を得て翻訳・公開いたします。 英語記事: Upgrading PostgreSQL from 9.6 to 10 with minimal downtime using pglogical 原文公開日: 2017/11/10 著者: Rodrigo Rosenfeld Rosas PostgreSQL 9.6->10アップグレードのダウンタイムをpglogicalで最小化(翻訳) PostgreSQL 10がリリースされ、9.6クラスタを最新バージョンにアップグレードしてみたくなりました。しかし、以前アップグレードしたときのようにメンテナンス画面を開いてマイグレーションを実行するのに膨大な段取りが必要になるのでしょうか。そのときは、アプリをメンテナンスモードに切り替え、新しいダンプを取って新しいクラスタでリストアし、メンテナンスモードをオフにしました。 この方法だと、アプリは1時間ほど、もしかするともっと長い時間使えなくなるかもしれません。pglogicalを再読した後、9.6から10への切り替えをわずか数秒で完了できるpglogicalを試す決心を固めました。 概要 pglogicalは論理レプリケーションを実装していて、バージョンの異なるデータベース同士でもレプリケーションを行えます。これはPostgreSQL自身が提供するバイナリレプリケーションでは不可能です。PostgreSQL 10では論理レプリケーション機能のサポートがいくつか追加されましたが、9.6からのレプリケーションを行いたいので、いくつかの外部拡張に頼る必要があります。 pglogicalの必要条件のひとつは、レプリケーションされるすべてのテーブルに主キーが設定されていることです。主キーは単独カラムでなくても構いませんが、主キーの存在は必須です。また、レプリケーションエージェントが動作するために、両方のデータベースにsuperuserでアクセスできる必要もあります。DDLレプリケーションはサポートされず、TRUNCATE CASCADEはレプリケーションされません。特殊な条件ではないので、ほとんどのデータベースについてレプリケーションできるはずです。 ただし、主キーの必須要件には特別な注意が必要です。特に移行前のデータベースで、ActiveRecord gemでデータベースマイグレーションを管理していた場合、以前はschema_migrationsテーブルに主キーがありませんでした。その場合は次を実行します。 alter table schema_migrations add primary key (version); アップグレードの方針は、PostgreSQLパッケージをpglogical拡張のサポート付きでインストールしてから、新しいPostgreSQL 10クラスタを作成して、新しいクラスタだけにスキーマをリストアするというものです。現在のクラスタの停止/再起動は、pglogicalを有効にしてインストールしたPostgreSQLを使って行うべきです。このクラスタはTCP/IP経由で他方に接続可能になっている必要があります。プロバイダ側(アップグレード前の9.6データベースを指す)とサブスクライバ側(新しいPostgreSQL 10データベースを指す)には、接続先のIPアドレスとポートをそれぞれ指定する必要があります。pglogical拡張を両方のデータベースで作成し、postgresql.confとpg_hba.confで論理レプリケーションを有効にし、両方のデータベースを再起動します。最後に、プロバイダ、サブスクライバ、そしてサブスクリプションを作成するいくつかのpglogical文が発行されてレプリケーションが開始されます。レプリケーションが完了したら、新しいクラスタのポートを古いクラスタに合わせて変更して古いクラスタを停止し、新しいクラスタを再起動できます。最後にアプリも再起動するとよいでしょう。特にrow型などのカスタム型がある場合、OIDが変わる可能性が高く、そうしたrow型が登録されているとアプリを再起動するまで期待どおりに動作しないためです。たとえばSequel gemを用いたDB.register_row_typeが使われている場合、これに該当する可能性があります。 最後の切り替えは可能な限り数秒以内に行われるので、ダウンタイムを最小限にできます。 手順のハンズオン 私たちのサーバーではアプリの他にDockerでPostgreSQLを実行しているので、本記事では手順の説明にもDockerを使いますが、他のセットアップでの手順にも簡単に応用できるはずです。Dockerでデモを行う利点は、(Dockerコンテナを)そのまま簡単に複製できることと、データベースの作成や実行にも対応できる点です。 本記事では、PostgreSQLクライアントがホストにもインストールされていることが前提です。 Dockerイメージと起動スクリプトの準備 以下のDockerfileをpg96/とpg10/サブディレクトリにそれぞれ作成します(Dockerコンテナ内でPostgreSQLを実行していない場合、自分の環境で複製するにはDockerfile内の手順をご覧ください)。 # pg96/Dockerfile FROM postgres:9.6 RUN apt-get update && apt-get install -y wget gnupg RUN echo “deb [arch=amd64] http://packages.2ndquadrant.com/pglogical/apt/ jessie-2ndquadrant main” > /etc/apt/sources.list.d/2ndquadrant.list\ && wget –quiet -O – http://packages.2ndquadrant.com/pglogical/apt/AA7A6805.asc | apt-key add -\ && apt-get update\ && apt-get install -y postgresql-9.6-pglogical RUN echo “host replication postgres 172.18.0.0/16 trust” >> /usr/share/postgresql/9.6/pg_hba.conf.sample RUN echo “host replication postgres ::1/128 trust” >> /usr/share/postgresql/9.6/pg_hba.conf.sample RUN echo “shared_preload_libraries = ‘pglogical'” >> /usr/share/postgresql/postgresql.conf.sample RUN echo “wal_level = ‘logical'” >> /usr/share/postgresql/postgresql.conf.sample RUN echo “max_wal_senders = 20” >> /usr/share/postgresql/postgresql.conf.sample RUN echo “max_replication_slots = 20” >> /usr/share/postgresql/postgresql.conf.sample # pg10/Dockerfile FROM postgres:10 RUN rm /etc/apt/trusted.gpg && apt-get update && apt-get install -y wget RUN echo “deb [arch=amd64] http://packages.2ndquadrant.com/pglogical/apt/ stretch-2ndquadrant main” > /etc/apt/sources.list.d/2ndquadrant.list\ && wget –quiet -O – http://packages.2ndquadrant.com/pglogical/apt/AA7A6805.asc | apt-key add -\ && apt-get update\ && apt-get install -y postgresql-10-pglogical RUN echo “host … Continue reading PostgreSQL 9.6→10アップグレードのダウンタイムをpglogicalで最小化(翻訳)