EatSmartシステム部ブログ

ウェブサイトの開発や運営に関する情報です。

PostgreSQLのバックアップ処理で使用するディスク容量を減らす工夫

イートスマートが提供するサービスでは、データベースにPostgreSQLを利用しています。 レプリケーションを行うことで冗長性を確保することに加え、毎日バックアップを作成しています。 このバックアップを作成する処理が使用するディスク容量が増えてきたので、減らす工夫を行ってみました。

以前のバックアップ処理

以下の流れでバックアップを行っていました。 バックアップの対象はすべてのテーブルではありません。

1.psqlコマンドで、COPYで指定したテーブルをTOで指定したファイルへ出力 2. gzipコマンドで、1で出力したファイルを圧縮 3. tarコマンドで、2で圧縮したファイルをアーカイブにする 4. 2で圧縮したファイルを削除する

バックアップの対象は数十のテーブルです。 これらのテーブルに対して1と2の処理を実行すると、圧縮されたファイルが大量に作成されます。 3でtarにアーカイブするタイミングで、2の圧縮ファイルと合わせて大量のディスク容量が消費されてしまいます。

新たなバックアップの処理

改善を試みたのは以下の2つです。

  1. 大量のディスク容量が消費される
  2. バックアップから完全なリストアができない

1に関しては、テーブルの内容を都度tarへアーカイブすることで解消を行いました。 psql/COPYの後にgzipで圧縮していたものを、pg_dumpgzipを組み合わせています。

- psql -d <データベース名> -c "COPY <テーブル名> TO '<バックアップファイル>'" > /dev/null
- gzip <バックアップファイル>
+ pg_dump --data-only --table=<テーブル名> <データベース名> | gzip > <バックアップファイル>.gz

アーカイブを作成する処理を、すべてのテーブルのバックアップを作成してからまとめて行うのではなく、バックアップファイルを都度行うようにしています。

- tar cfP <アーカイブファイル> *.gz
+ tar rfP <バックアップファイル> <バックアップファイル>.gz

2に関しては、データのバックアップはあるものの、スキーマやシーケンスのバックアップが無いため、完全なリストアができない状態でした。 このため、まずスキーマをバックアップする処理を追加しました。

+ pg_dump -h 127.0.0.1 -U postgres --schema-only <データベース名> > <スキーマのバックアップファイル>.sql

シーケンスはpg_classから取得して、テーブルと同様にバックアップの対象に追加しました。

SELECT c.relname FROM pg_class c LEFT join pg_user u ON c.relowner = u.usesysid WHERE c.relkind = 'S';

リストアは、アーカイブファイルを展開したものをpsqlコマンドで実行することで行うことができます。

+ psql -d <データベース名> -f "<スキーマのバックアップファイル>.sql"
+ zcat "<バックアップファイル>.gz" | psql -U postgres -d <データベース名>

まとめ

以上の工夫で、バックアップ処理で使用するディスクを最大2割程度減らすことができました。