【OSSでWiki構築】連載記事一覧
第1回
第2回:環境構築編
第3回:環境構築編 トラブルシューティング
第4回:Google OAuth編
第5回:Google OAuth編 トラブルシューティング
第6回:アクセス制御編
第7回:アクセス制御編 トラブルシューティング
第8回:日本語対応編
第9回:日本語対応編 トラブルシューティング
第10回:データ保全・バックアップ編
第11回:データ保全・バックアップ編 トラブルシューティング ※本記事
1. はじめに
このドキュメントは、「第10回:データ保全・バックアップ編」を進める過程で実際に遭遇したエラーや挙動、およびその解決プロセスを記録したものです。
エラーは失敗ではなく、システムへの理解を深めるための最高のヒントです。各エラーから得られた学びを共有します。
ケーススタディ1:リストア時に大量の「already exists」エラーが発生
発生した事象
バックアップデータ(dump.sql)をリストアしようとして、以下の手順を実行したところ、画面に大量の ERROR: relation ... already exists(すでに存在します)というエラーが表示された。
docker compose up -dでコンテナを起動。- リストアコマンドを実行。
原因の分析
これは「Outlineアプリの仕事が早すぎて競合した」ことが原因でした。
docker compose up -dを実行した時点で、データベース(db)だけでなく、Outlineアプリ(outline)も同時に起動しました。- Outlineアプリは起動直後、データベースが空っぽであること検知し、動作に必要なテーブル(データの棚)を自動的かつ高速に初期化(作成)しました。
- その直後に私たちがバックアップデータを流し込もうとしたため、「そのテーブルはさっきOutlineが作ったから、もうあるよ!(already exists)」と競合してしまったのです。
解決策
- 「アプリを寝かせたまま、データベースだけを起こす」ことで解決しました。
docker compose down --volumesで再度環境をリセット。docker compose up -d dbと指定し、データベースコンテナだけを先行して起動。- 邪魔が入らない状態でリストアコマンドを実行。
- 完了後、
docker compose up -dで残りのコンテナ(Outline)を起動。
学び
データベースのリストアを行う際は、接続してくるアプリケーション(Webサーバーなど)を停止させておくのが鉄則です。Docker Composeでは、サービス名を指定して個別に起動することでこれを実現できます。
ケーススタディ2:リストア成功時に出る「無視して良いエラー」
発生した事象
正しい手順(ケーススタディ1の解決策)でリストアを実行しても、最後に以下のエラーが表示された。
ERROR: cannot drop the currently open database
ERROR: current user cannot be dropped
ERROR: role "outline" already exists
原因の分析
これらはエラーというより、PostgreSQLの安全装置が正常に作動したために起きたことでした。
バックアップ作成時に -c (Clean) オプションを付けたため、リストアデータには「既存のDBやユーザーを削除して作り直す」という命令が含まれていました。
しかし、現在そのDBを開いて作業している最中(currently open)であるため、自分自身の足場を崩すような削除命令は拒否されました。
判断
テーブルデータ(中身)の上書き自体は成功しているため、これらは「無視して良いエラー」と判断しました。実際にその後の動作確認でも問題はありませんでした。
学び
エラーメッセージが出ても、すべてが「失敗」とは限りません。内容を読み、「システムを守るための正常な拒否反応」である場合は、許容して進む判断も必要です。
前の記事:第10回:データ保全・バックアップ編
次の記事:準備中
【OSSでWiki構築】連載記事一覧
第1回
第2回:環境構築編
第3回:環境構築編 トラブルシューティング
第4回:Google OAuth編
第5回:Google OAuth編 トラブルシューティング
第6回:アクセス制御編
第7回:アクセス制御編 トラブルシューティング
第8回:日本語対応編
第9回:日本語対応編 トラブルシューティング
第10回:データ保全・バックアップ編
第11回:データ保全・バックアップ編 トラブルシューティング ※本記事