データベースバックアップ · 1 min read · Dec 10, 2025

MySQLの増分バックアップ - InnoDBおよびMyIsamデータベースの時点バックアップと復元

増分バックアップを行うことは、大規模な本番データベースにとって重要な要件です。安全な増分バックアップがなければ、信頼できる本番データベースを持っているとは言えません。なぜなら、緊急時にデータベースを復元するためには十分なデータが必要だからです。インターネットでいくつか検索した結果、MyISAMとInnoDBの完全な増分バックアップを行うツールを見つけることができませんでした(もしかしたら、私はGoogleやインターネットでの検索の専門家ではないのかもしれません)。そこで、私はこのツールを書くことに決めましたが、時間を無駄にせず、他のオープンソースソリューションから利益を得るために、最もシンプルで広く使用されている完全バックアップ用のスクリプトである-automysqlbackup-にこの機能を追加することを選びました。

メカニズム

増分バックアップを行うために、automysqlbackupのPostおよびPre機能を使用します。完全バックアップを開始する前に、mysql-backup-preがバックアッププロセス中にデータベース全体をロックするためのクエリを実行します。バックアップが実行されている間に変更を避けるために、binlogをフリーズする必要があります。バックアップ中にbinlogの名前と位置は変更されてはなりません。バイナリログの位置は、次の増分バックアッププロセスで非常に重要であり、次の増分バックアップを開始するための出発点として使用されます。完全バックアップが終了した後、mysql-backup-postがデータベースロックを解除します。

ロッククエリ: FLUSH TABLES WITH READ LOCK; SELECT SLEEP(86400)

ロッククエリを見つける: mysql -u[username] -p[pass] -e “show processlist” | grep “SELECT SLEEP(86400)” | awk ‘{print $1}’

要件

  • パッケージをインストールし、mysql.confを更新するためのroot権限
  • mysql-community-clientパッケージ
  • automysqlbackupおよびmysql-incrementalのインストール

インストール

ディストリビューション用のmysql-community-clientパッケージをインストールします。

注意: MySQLをインストールした後、’mysqlshow’コマンドが必要です。

automysqlbackupをインストールします:

download the package from https://sourceforge.net/projects/automysqlbackup/
tar -xzf [PathYouSavedTarFile] -C /tmp/
cd /tmp/
./install.sh

automysqlbackupのインストール中に、automysqlbackup.confとそのバイナリのパスについて尋ねられますが、デフォルトのままで変更せずに進めることができます。

rm /etc/automysqlbackup/myserver.conf

mysql-incrementalをインストールします: https://sourceforge.net/projects/mysqlincrementalbackup/からパッケージをダウンロードします。

cd /tmp  
wget http://downloads.sourceforge.net/project/mysqlincrementalbackup/mysql-incremental.tar.gz  
tar xfz mysql-incremental.tar.gz
cp mysql-incremental /etc/automysqlbackup/
chmod 755 /etc/automysqlbackup/mysql-incremental
cp mysql-backup-post /etc/automysqlbackup/
chmod 755 /etc/automysqlbackup/mysql-backup-post
cp mysql-backup-pre /etc/automysqlbackup/
chmod 755 /etc/automysqlbackup/mysql-backup-pre

automysqlbackup.confを更新します:

以下のパラメータを見つけて、コメントを外し、変更します:

        CONFIG_mysql_dump_username='Mysqlユーザー名。ロックを取得する権限が必要です'
    CONFIG_mysql_dump_password='パスワード'
    CONFIG_backup_dir='フルバックアップと増分バックアップを保存するバックアップディレクトリ'
    CONFIG_db_names=('databaseName1' 'databaseName2' )
    CONFIG_db_month_names=('databaseName1' 'databaseName2' )
    CONFIG_mysql_dump_master_data=2
    CONFIG_prebackup="/etc/automysqlbackup/mysql-backup-pre"
    CONFIG_postbackup="/etc/automysqlbackup/mysql-backup-post"

my.cnfの更新:

MySQL設定ファイルを編集します:

nano /etc/mysql/my.cnf

1- BinLogフォーマット

STATEMENTフォーマットにいくつかの制限があるため、私の推奨はROWベースのフォーマットを設定することです。詳細については、このハウツーの「トラブルシューティング」セクションを参照してください。バイナリログフォーマットの種類を確認するには、” select @@binlog_format; “クエリを実行します。logbinフォーマットを変更するには、mysql.confまたはmy.cnfにbinlog_format = ROWを追加する必要があります。

2- binlog_do_db

バイナリログに関連する変更を持つデータベースを指定する必要があります。データベースを指定しない場合、任意のデータベースの変更がバイナリログに記録されます。この場合、STATEMENTフォーマットを選択すると、増分バックアップとbinlogファイルから復元する際に問題が発生する可能性があります。このオプションにデータベースを追加できます:

binlog_do_db = DATABASENAME1
binlog_do_db = DATABASENAME2

3- expire_logs_days

バイナリログファイルを長期間保持するには、このパラメータを高い値に増やすことができます。私の推奨は60日です。したがって、” expire_logs_days = 60 “を追加または変更する必要があります。

4- log-bin

バイナリログが保存されるディレクトリ。古いMySQLバージョンでは、mysql-incrementalが正しいパスを見つけられない場合があります。したがって、mysql-incrementalを実行した後にこのエラーが発生した場合は、mysql-incrementalスクリプトを更新し、バイナリログパスを設定する必要があります。

5- log_slave_updates

スレーブサーバーでmysql-incrementalバックアップを設定している場合は、このオプションを有効にする必要があります。通常、スレーブはマスターサーバーから受信した更新を自分のバイナリログに記録しません。このオプションは、スレーブが自分のSQLスレッドによって実行された更新を自分のバイナリログに記録するように指示します。http://dev.mysql.com/doc/refman/5.1/en/replication-options-slave.html#option_mysqld_log-slave-updates

automysqlbackupを実行する

指定したデータベースから少なくとも1つの完全バックアップを取得するために、automysqlbackupを手動で実行します。

automysqlbackup

コマンドを正常に実行した後、/ [BackupDirInAutomysqlbackup] /status/backup_infoファイルで新しく追加された日次バックアップに関する情報を確認します。エラーの詳細については、/var/log/Backup_Post_Pre_logを確認してください。バックアップファイルは、/[BackupDirInAutomysqlbackup]/daily/[DatabaseName]/ディレクトリに保存されます。

mysql-incrementalを実行する

少なくとも1つの時間ごとのバックアップを取得するために、mysql-incrementalを手動で実行します。

mysql-incremental

エラーが発生した場合、詳細は” /var/log/Backup_Incremental_Log “ファイルに記録されます。増分バックアップファイルは、/[BackupDirInAutomysqlbackup]/IncrementalBackup/ディレクトリに保存されます。

root crontabを編集する

mysql-incrementalを1時間以上スケジュールできます。backup_statusから完全バックアップの総時間を見つけ、その値に基づいて正確なスケジュール時間を設定します。もちろん、mysql-incrementalバックアップには、開始前に実行中の完全バックアップを見つけるメカニズムがあるため、増分バックアップと完全バックアップの間での競合について心配する必要はありません。

crontab -e
5 00 * * * root /usr/local/bin/automysqlbackup
25 *  * * * root  /etc/automysqlbackup/mysql-incremental

データベースの復元

特定の時点まで復元するためには(時点復元)、まず1つの完全な日次バックアップを復元し、その後、関連する増分バックアップファイルを順次復元する必要があります。より明確にするために、testDBデータベースを復元する手順は以下の通りです。サンプルシナリオでは、2015年5月1日午前2時までデータを復元することを意図しています。バックアップディレクトリを/backup、ターゲットデータベースをtestDBとして設定しています:

1- mysql -u root -p DatabaseName < /backup/daily/testDB/daily_DatabaseName_2015-05-16_00h05m_Saturday.sql.gz
2- mysql -u root -p DatabaseNAme < /backup/IncrementalBackup/2015-5-01_Incremental/testDB/testDB_IncrementalBackup_2015-5-01_00h25m.1
3- mysql -u root -p DatabaseNAme < /backup/IncrementalBackup/2015-5-01_Incremental/testDB/testDB_IncrementalBackup_2015-5-01_01h25m.2
4- mysql -u root -p DatabaseNAme < /backup/IncrementalBackup/2015-5-01_Incremental/testDB/testDB_IncrementalBackup_2015-5-01_02h25m.3

重要な注意事項とトラブルシューティング

MySQLはバイナリログの異なるフォーマットをサポートしています。一部のMySQLバージョンは、binlogフォーマットとして’statement-based’を使用しており、このタイプのbinlogにはいくつかの制限があるため、増分バックアップ手順で使用する際には注意が必要です。MySQLがstatement-baseフォーマットに設定されている場合、データベースに基づいて正しくフィルタリングできません。データベースを変更するために’USE’または’\u’を設定し、その後、binlog-do-dbに含まれていない別のデータベースを更新すると、そのステートメントはbinlogファイルに記録されますが、これは望ましくない状態です!特定のデータベースに基づいて復元する際に問題が発生します。また、binlog-do-dbに含まれていない別のデータベースに変更を加え、binlog-do-dbに含まれているデータベースを更新すると、そのステートメントはbinlogファイルに記録されません。binlog-do-dbにデータベースを追加する目的は、データベースに基づいてフィルタリングすることですが、期待通りには機能しません。’USE’または’\u’がクエリを実行する前に実行されない場合、mysqlbinlogは特定のデータベースに関連する’update queries’を抽出できません。この問題については、以下のシナリオでさらに説明します:

データベース: 
 - binlog
     - person (テーブル) 
  - binlog2
     - person (テーブル)

 binlog-do-db=binlog2 (このデータベースの変更のみがbinlogファイルに記録されることになっています)
--------シナリオ 1---------
\u binlog2
insert into person (data) values ('17') ---> binlogに記録される  *望ましい状態*
insert into binlog.person (data) values ('25'); ---> binlogに記録される (ターゲットデータベースは'binlog') *望ましくない状態*
--------シナリオ 2---------
\u binlog
insert into person (data) values ('17') ---> binlogに記録されない  *望ましい状態*
insert into binlog2.person (data) values ('25'); ---> binlogに記録されない (ターゲットデータベースは'binlog2') *望ましくない状態* これはbinlog2データベースが変更されているため、この変更を記録したいが、logbinファイルには記録されません。
--------シナリオ 3---------
データベースに接続するだけで、'USE'または'\u'ステートメントなしで、任意のデータベースのすべての更新が記録されますが、mysqlbinlogは特定のデータベースに基づいてフィルタリングできません。したがって、これは増分バックアップの目的には望ましくない状態です。更新クエリを実行する前に'USE'または'\u'を使用することは非常に重要です。なぜなら、mysqlbinlogはbinlogファイル内の'USE'ステートメントに基づいて更新クエリを見つけるからです。

上記の問題に対する回避策

  1. 各ユーザーが更新するデータベースにのみアクセスできるようにデータベース上にユーザーを定義し、データベースに接続する際にはデータベース名を指定する必要があります。もちろん、ほとんどのアプリケーションには、資格情報とデータベース名が設定された設定ファイルがありますので、その場合、データベース間でのクロスアクセスはなく、”\USE”または”\u”を使用することに関する懸念はありません。

  2. 行ベースのbinlogフォーマットを使用する場合、上記の問題はすべて解消されます。言い換えれば、行ベースのフォーマットはbinlogにとってはるかに適切な方法です。https://dev.mysql.com/doc/refman/5.1/en/replication-options-binary-log.html

ログファイル

すべての情報をログファイルに記録しようとしましたので、ログ内に十分な情報を見つけることができます:

/var/log/Backup_Post_Pre_log
/var/log/Backup_Incremental_Log
/[SpecifiedBackupDirInAutomysqlbackup.conf]/status/backup_info

“backup_info”ファイルには、バックアップの詳細情報とバックアップが終了した時間が含まれています(時間はUnix時間形式です)。バックアップが開始された時点のbinlog名と位置、バックアップの種類、前回の完全バックアップからのバックアップの数、およびバックアップの期間が含まれています。

サンプルbackup_info:

1431043501,mysql-bin.000026,120,Daily,2015-05-08,0,24
1431044701,mysql-bin.000026,120,Hourly,2015-05-08,1,1

異なる値の説明は以下の通りです:

 1th) 1431043501 : バックアップが終了した時間を示します。バックアップが実行されたサーバーでdate --date @1431043501コマンドを実行すると、人間が読みやすい形式で表示できます。
 2th) Mysql-bin.000026 : このファイルまでバックアップが行われたバイナリログ名を示します。
 3th) 120 : バイナリログ内でバックアップが行われた位置を示します。
 4th) Daily/Hourly: バックアップの種類を示します。Dailyはautomysqlbackupスクリプトによる完全バックアップを意味し、Hourlyはmysql-incrementalスクリプトによって行われます。
 5th) 2015-05-08: バックアップが行われた日付。この日付は、増分バックアップのディレクトリを作成する際に使用され、また、時間ごとのバックアップを復元する際の基準としても使用されます。復元手順では、最初に完全バックアップを復元し、その後、他の増分バックアップが順次復元されます。
 6th) 0 : 前回の完全バックアップからのバックアップの数を示します。0はバックアップが完全であり、他は時間ごとのバックアップを意味します。この数値は復元手順で非常に重要です。
 7th) 24: バックアップの期間(秒単位)。

バグ報告

バグを報告したり、提案やレビューを行うことができます: https://sourceforge.net/projects/mysqlincrementalbackup.

Share: X/Twitter LinkedIn

新しい投稿を受信箱で受け取る

スパムはありません。いつでも購読を解除できます。