Minecraftサーバーをバックアップする
MODのバグによるデータの破損やアイテム全損時のリカバリーのために、Minecraftサーバーのデータを何らかの方法でバックアップしておきたいと思ったので、gitで管理することとしました。プラグインとかを使っても良いのですが、gitの方が何かと応用が効くと思ったので。 以下、その手順です(Minecraftサーバーの導入までは完了しているものとします)。
gitのインストール
ご存知ない方のために説明しておきますと、gitはバージョン管理システムの一つで、ファイルの変更履歴を管理することができます。 ファイルのバックアップを取るためにファイル名に日時をつけたり1, 2といったバージョンをつけたコピーを何個も作ったことはないでしょうか? gitを使えば、そのような作業を行う必要はなくなります。また、後述するようにGitHubやGitLabといったホスティングサービスも使えば、複数のPC間でデータを同期することもできますし、PC自体が壊れてもデータを取り戻すことができます。
gitは以下のサイトからダウンロードできます。
以下ではgitの使用経験がない方でも理解できるように説明していきますので、ご安心ください。
gitの初期設定
最初にユーザー名とメールアドレスを設定しておくと良いです。 以下のコマンドをコマンドプロンプト等を起動して実行してください1。
git config --global user.name "Your Name"
git config --global user.email "Your Email"
リポジトリの作成
サーバーの置いてあるディレクトリで以下のコマンドを実行して、リポジトリ2を作成します。
git init
.git
という隠しディレクトリが作成されます。このディレクトリには、ファイルの変更履歴等が保存されます。
除外設定
.gitignore
というファイルを作成し、バックアップしないファイルやディレクトリを指定します。
# バックアップしないディレクトリは末尾に/をつけて記述します
world/data/raids.dat
world/DIM1/data/raids_end.dat
world/DIM-1/data/raids.dat
world/level.dat
world/level.dat_old
world/session.lock
上のファイル類はサーバーに誰もいない(=セーブデータが更新されない)時も常に更新されるので、いちいち定期的にバックアップしていたらキリがありません。なくても自動生成されるようだったので、除外しておきます。
他にも、バックアップを取りたくないファイルやディレクトリがあれば、.gitignore
に追記してください。ただし既にリポジトリに追加されているファイルは.gitignore
に追記しても無視されません。一旦リポジトリから削除する必要があります。
その場合は、以下のコマンドを実行してください。
git rm --cached <ファイル名>
バックアップスクリプト
自動更新を行うスクリプトを作成します。backup.bat
などという名前で保存してください。これはWindows向けのスクリプトです。
@echo off
setlocal enabledelayedexpansion
set REMOTE_REPO_URL=<YOUR_REMOTE_REPO_URL>
if not exist ".git" (
git init
git remote add origin %REMOTE_REPO_URL%
)
REM リモートリポジトリからpullする前にローカルの変更をスタッシュ
git fetch origin
git diff-index --quiet HEAD -- || (
echo Stashing local changes...
git stash save
)
echo Pulling changes from remote...
git pull origin main
git stash pop || echo ''
git add .
REM 変更があるか確認
git diff-index --quiet HEAD || (
git commit -m "Auto-commit: %date% %time%"
git push origin main
)
REM 1時間待機して再実行
timeout /t 3600
call %0
<YOUR_REMOTE_REPO_URL>
にはリモートリポジトリのURLを指定してください。この場合、リモートリポジトリはGitHubやGitLabなどのホスティングサービスを使うことを想定しています。
リモートリポジトリなしでも運用はできます。なしでいく場合はset REMOTE_REPO_URL=<YOUR_REMOTE_REPO_URL>
とgit remote add origin %REMOTE_REPO_URL%
という行を削除してください。
リモートリポジトリを使う場合は、ホスティングサービスにユーザー登録し、リポジトリを作成して、ローカルにクローンしておいてください(リポジトリの作成方法やクローンの方法は各ホスティングサービスが解説していると思いますので、割愛します)。そのリポジトリにサーバーを移して管理することになります。
スクリプトが作成できたら、サーバーのディレクトリ上で実行しっぱなしにしておいてください。
デフォルトでは、1時間ごとに変更があれば自動でバックアップを行います。更新を試行する間隔を変更したい場合はtimeout /t 3600
の3600
(3600秒=1時間)の部分を変更し再起動してください。
ロールバックの実行
これで、過去のバックアップを使ってデータを復元(ロールバック)することができるようになりました。
ロールバックを行う場合、まずはサーバーを一旦停止します。git log
でコミット3の一覧を表示し、復元したい時刻のコミットハッシュを確認します。commitの右にある長い文字列がコミットハッシュです。
復元したいコミットハッシュをコピーし、q
を押して終了します。
コミットハッシュを<COMMIT_HASH>
とすると、git checkout <COMMIT_HASH>
で指定したコミットの状態に戻すことができます。
といってもこの状態は正確には復元ではなく、一時的なものです。復元を記録して恒久的なものにするには、revertを行う必要があります。
git revert HEAD^...<COMMIT_HASH>
で指定したコミットまでの全ての変更を取り消すことができます。
しかしこの操作はおそらく失敗すると思います。コンフリクト(競合)が発生するからです。
具体的には、stats
内のjsonファイルがコンフリクトするはずです。
この場合は<<<<<<<HEAD
と=======
に囲われた行を丸ごと削除してください。あと>>>>>> parent of ...
という行も削除してください。
これでコンフリクトが解消されたはずなので、git add .
を実行して全ての変更を確定し、git revert --continue
を実行します。するとロールバックの詳細を記述したエディタ画面が開くと思うので、何かコメントを残したければ書いて、エディタを閉じます。
これでロールバックが完了しました。git push origin main
でリモートリポジトリにも反映させてください。
以上はコマンドラインでの操作です。これが難しいと感じる方は、SourcetreeやGitHub DesktopなどのGUIツールを使うと良いでしょう。
revertを実行しても復元前の状態も残る(正確には、ロールバックを行った記録が残る)ので、ロールバックを取り消すこともできます。操作に失敗してもやり直せるのがgitの強みですね。
また、gitを導入したことによって、バックアップ以外にも色々なことができるようになります。ある地点からブランチ(分岐)を作成して並行世界を作ったり統合したりすることもできるのですが、まあその辺りをやりたい場合はgitについて調べてみてください。