ビジー状態のレプリケートされたシステムで単一のデータベースを特定の時点にリカバリするための戦略またはツールを探します。
マスタースレーブ複製構成の2つのMySQL 5.0.77サーバーで実行されている12のデータベースがあります。読み取り専用スレーブのフルダンプが毎日取得され、これらのバックアップがオフサイトにある、使用可能な増分SQLダンプがあり、レプリケーションステータスが監視されます。
編集:テーブルはInnoDBとmyISAMの混合であるため、エンジン固有のソリューションは利用できません。
したがって、マスターサーバーに完全な障害が発生した場合、レプリケーションを中断してスレーブサーバーを昇格させることができます。また、新しいサーバーを再構築してオフサイドのフルバックアップから構成し、スレーブから1時間ごとに取得した差分を適用することもできます。
ただし、部分的な障害、または単一のデータベースの障害に対処する方法を心配しています。かなりありそうな2つのシナリオが考えられます。
現時点では、FULL- $ DATE-all-databases.sql.gzファイルとして多数のフルダンプがあり、DIFF- $ DATE-all-databases.sql.gzとしてフルダンプに適用できる差分があります
データベース7を特定の時点に復元するには、FULLファイルとDIFFファイルを使用したgrepと、そのSQLを手動で適用する必要があります。
マスターデータベースへの以前のDIFFダンプの1つに回復できるようにするには、どうすればよいですか?
個々のデータベースファイルにバックアップする必要がありますか?
mysqldump --databases "database1" | gzip > database1.sql.gz
mysqldump --databases "database2" | gzip > database2.sql.gz
mysqldump --databases "database3" | gzip > database3.sql.gz
のではなく..
mysqldump --master-data --lock--all-databases --all-databases | gzip > all-databases.sql.gz
個別のmysqldumpファイルを使用する場合、マスターデータのバイナリログはどうなりますか?マスターサーバーのリカバリダンプに--master-dataを設定する必要がありますか?
すべてのデータベースがInnoDBのみを使用している場合、良いニュースがあります。
すべてのデータベースをスレーブから並行してダンプする必要があります。
実際、すべてのデータベースを同じ時点に強制することができます。
スレーブについて最初に覚えておくべきことは、スレーブが他のスレーブのマスターでない場合は、バイナリログを有効にする必要がないことです。
各ダンプは、各ダンプファイルの22行目に異なる位置に書き込まれるため、並列ダンプに--master-data
オプションを使用することはできません。マスターの最後のログファイルを記録し、SHOW SLAVE STATUS\G
を使用して実行されたスレーブを配置することをお勧めします。このように、すべてのデータベースは同じ時点の位置を持っています。
すべてのデータベースを収集し、すべてのデータベースの並列ダンプをスクリプト化できます。
DBLIST=/tmp/ListOfDatabasesToParallelDump.txt
BACKUP_BASE=/backups
BACKUP_DATE=`date +"%Y%m%d_%H%M%S"`
BACKUP_HOME=${BACKUP_BASE}/${BACKUP_DATE}
mkdir ${BACKUP_HOME}
cd ${BACKUP_HOME}
mysql -h... -u... -p... -e"STOP SLAVE;"
mysql -h... -u... -p... -e"SHOW SLAVE STATUS\G" > ${SSS}
LOGFIL=`cat ${SSS} | grep "Relay_Master_Log_File" | awk '{print $2}'`
LOGPOS=`cat ${SSS} | grep "Exec_Master_Log_Pos" | awk '{print $2}'`
echo "Master was at ${LOGFIL} Position ${LOGPOS} for this Backup" > Master_Log_FilePos.txt
mysql -h... -u... -p... -AN -e"SELECT schema_name FROM information_schema.schemata WHERE schema_name NOT IN ('information_schema','mysql','performance_schema')" > ${DBLIST}
for DB in `cat ${DBLIST}`
do
mysqldump -h... -u... -p... --hex-blob --routines --triggers ${DB} | gzip > ${DB}.sql.gz &
done
wait
mysql -h... -u... -p... -e"START SLAVE;"
データベースが多すぎる場合は、次のように一度に10個または20個ずつダンプします。
DBLIST=/tmp/ListOfDatabasesToParallelDump.txt
SSS=/tmp/ShowSlaveStatusDisplay.txt
BACKUP_BASE=/backups
BACKUP_DATE=`date +"%Y%m%d_%H%M%S"`
BACKUP_HOME=${BACKUP_BASE}/${BACKUP_DATE}
mkdir ${BACKUP_HOME}
cd ${BACKUP_HOME}
mysql -h... -u... -p... -e"STOP SLAVE;"
mysql -h... -u... -p... -e"SHOW SLAVE STATUS\G" > ${SSS}
LOGFIL=`cat ${SSS} | grep "Relay_Master_Log_File" | awk '{print $2}'`
LOGPOS=`cat ${SSS} | grep "Exec_Master_Log_Pos" | awk '{print $2}'`
echo "Master was at ${LOGFIL} Position ${LOGPOS} for this Backup" > Master_Log_FilePos.txt
mysql -h... -u... -p... -AN -e"SELECT schema_name FROM information_schema.schemata WHERE schema_name NOT IN ('information_schema','mysql','performance_schema')" > ${DBLIST}
COMMIT_LIMIT=20
COMMIT_COUNT=0
for DB in `cat ${DBLIST}`
do
mysqldump -h... -u... -p... --hex-blob --routines --triggers ${DB} | gzip > ${DB}.sql.gz &
(( COMMIT_COUNT++ ))
if [ ${COMMIT_COUNT} -eq ${COMMIT_LIMIT} ]
then
COMMIT_COUNT=0
wait
fi
done
wait
if [ ${COMMIT_COUNT} -gt 0 ]
then
wait
fi
mysql -h... -u... -p... -e"START SLAVE;"
単一のテーブルを回復する必要がある場合は、サイズ順で一度にtables 20を並列ダンプできます。
これを試して:
TBLIST=/tmp/ListOfTablesToParallelDump.txt
SSS=/tmp/ShowSlaveStatusDisplay.txt
BACKUP_BASE=/backups
BACKUP_DATE=`date +"%Y%m%d_%H%M%S"`
BACKUP_HOME=${BACKUP_BASE}/${BACKUP_DATE}
mkdir ${BACKUP_HOME}
cd ${BACKUP_HOME}
mysql -h... -u... -p... -e"STOP SLAVE;"
mysql -h... -u... -p... -e"SHOW SLAVE STATUS\G" > ${SSS}
LOGFIL=`cat ${SSS} | grep "Relay_Master_Log_File" | awk '{print $2}'`
LOGPOS=`cat ${SSS} | grep "Exec_Master_Log_Pos" | awk '{print $2}'`
echo "Master was at ${LOGFIL} Position ${LOGPOS} for this Backup" > Master_Log_FilePos.txt
mysql -h... -u... -p... -AN -e"SELECT CONCAT(table_schema,'.',table_name) FROM information_schema.tables WHERE table_schema NOT IN ('information_schema','mysql','performance_schema') ORDER BY data_length" > ${DBLIST}
COMMIT_LIMIT=20
COMMIT_COUNT=0
for DBTB in `cat ${TBLIST}`
do
DB=`echo "${DBTB}" | sed 's/\./ /g' | awk '{print $1}'`
TB=`echo "${DBTB}" | sed 's/\./ /g' | awk '{print $2}'`
DUMPFILE=$DB-{DB}-TBL-${TB}.sql.gz
mysqldump -h... -u... -p... --hex-blob --routines --triggers ${DB} ${TB} | gzip > ${DUMPFILE} &
(( COMMIT_COUNT++ ))
if [ ${COMMIT_COUNT} -eq ${COMMIT_LIMIT} ]
then
COMMIT_COUNT=0
wait
fi
done
wait
if [ ${COMMIT_COUNT} -gt 0 ]
then
wait
fi
mysql -h... -u... -p... -e"START SLAVE;"
データベースまたは個々のテーブルをダンプするスクリプトを作成したので、そのデータを自由にロードできます。マスターのバイナリログからSQLを実行する必要がある場合は、mysqlbinlog
を使用して日時の位置を指定し、SQLを他のテキストファイルに出力できます。バイナリログのタイムスタンプから必要なデータ量を見つけるために、十分な注意を払う必要があります。 OS内のすべてのバイナリログのタイムスタンプは、最後に書き込まれた時刻を表していることに注意してください。