7

私は現在、データベースをバックアップするためにMysqlスレーブでmysqldumpを実行しています。これはデータ自体のバックアップには問題なく機能しましたが、補足したいのは、mysqldumpによって生成されたデータに対応するマスターのバイナリログ位置です。

これを行うと、マスターのバイナリログ位置を取得するメインデータベースで個別のmysqldumpを実行しなくても、スレーブを復元(または新しいスレーブをセットアップ)できます。mysqldumpによって生成されたデータを取得し、それを生成したバイナリログ情報と組み合わせるだけで、出来上がり...再同期されます。

これまでのところ、私の研究により、この目標を達成できるようになりましたが、それを実現するための自動化された方法を理解できないようです。これが私が発見した「ほぼ」です:

  • メインデータベースからmysqldumpを実行している場合は、mysqldumpで「--master-data」パラメーターを使用して、ダンプデータとともにマスターのバイナリ位置をログに記録できます(これは、私たちの奴隷ですが、それは私たちが達成したいことにはやり過ぎのようです)
  • 自動化されていない方法でこれを実行したい場合は、スレーブのデータベースにログインして「STOPSLAVESQL_THREAD;」を実行できます。続いて「SHOWSLAVESTATUS;」(http://dev.mysql.com/doc/refman/5.0/en/mysqldump.html)。しかし、軟膏から何かをバックアップしたいことが事前にわかっていない限り、これは私たちに何の役にも立ちません。
  • 年間500ドルを吹き飛ばす場合は、InnoDbホットバックアッププラグインを使用して、メインDBからmysqldumpを実行するだけで済みます。しかし、私たちにはそのお金がなく、とにかくメインDBに余分なI/Oを追加したくありません。

これは、誰かが以前に理解していたはずの十分に一般的なことのように思えます。うまくいけば、誰かがStack Overflowを使用していますか?

4

5 に答える 5

9

次のシェル スクリプトは cron または定期的に実行され、必要に応じて変数を置き換えます (デフォルトは FreeBSD 用に記述されています)。

# MySQL executable location
mysql=/usr/local/bin/mysql

# MySQLDump location
mysqldump=/usr/local/bin/mysqldump

# MySQL Username and password
userpassword=" --user=<username> --password=<password>"

# MySQL dump options
dumpoptions=" --quick --add-drop-table --add-locks --extended-insert"

# Databases
databases="db1 db2 db3"

# Backup Directory
backupdir=/usr/backups

# Flush and Lock
mysql $userpassword -e 'STOP SLAVE SQL_THREAD;'

set `date +'%Y %m %d'`

# Binary Log Positions
masterlogfile=`$mysql $userpassword -e 'SHOW SLAVE STATUS \G' | grep '[^_]Master_Log_File'`
masterlogpos=`$mysql $userpassword -e 'SHOW SLAVE STATUS \G' | grep 'Read_Master_Log_Pos'`

# Write Binlog Info
echo $masterlogfile >> ${backupdir}/info-$1-$2-$3.txt
echo $masterlogpos >> ${backupdir}/info-$1-$2-$3.txt

# Dump all of our databases
echo "Dumping MySQL Databases"
for database in $databases
do
$mysqldump $userpassword $dumpoptions $database | gzip - > ${backupdir}/${database}-$1-$2-$3.sql.gz
done

# Unlock
$mysql $userpassword -e 'START SLAVE'

echo "Dump Complete!"

exit 0
于 2009-10-06T01:19:43.763 に答える
1

ロスのスクリプトは正しい方向に進んでいますが、マスターログの位置を確認する前にスレーブを停止するように言ったときは@joatisが正しいです。その理由は、READLOCKは。Read_Master_Log_Posで取得されたを保持しないためSHOW SLAVE STATUSです。

これが当てはまるかどうかを確認するには、スレーブでMySQLにログインして、次のコマンドを実行します。

FLUSH TABLES WITH READ LOCK

SHOW SLAVE STATUS \G

に注意してくださいRead_Master_Log_Pos

数秒待ってから、もう一度実行します。

SHOW SLAVE STATUS \G

が変更されたことに注意してくださいRead_Master_Log_Pos

ステータスを確認するとすぐにバックアップが開始されるため、スクリプトによって記録されたログの位置が正確である可能性があります。ただし、代わりに次の手順に従うことをお勧めします: http ://dev.mysql.com/doc/refman/5.0/en/replication-solutions-backups-mysqldump.html

そして、バックアップの期間中のSTOP SLAVE SQL_THREAD;代わりに実行します。FLUSH TABLES WITH READ LOCK

完了したら、次のコマンドでレプリケーションを再開します。START SLAVE

また、増分バックアップのために、または追加の安全対策としてbin-logsをバックアップする場合は、上記の$dumpoptions変数に--flush-logsを追加すると便利です。

于 2010-12-16T01:56:41.917 に答える
0

Read_Master_Log_Pos をマスターから継続する位置として使用すると、データが欠落する可能性があります。

Read_Master_Log_Pos 変数は、マスター バイナリ ログ ファイル内のスレーブ IO スレッドの位置です。

ここでの問題は、スレーブ SQL スレッドを停止してから Read_Master_Log_Pos を取得するまでのわずかな時間であっても、停止された SQL スレッドによって適用されていないデータを IO スレッドがマスターから受信した可能性があることです。

これにより、Read_Master_Log_Pos が mysqldump で返されたデータよりも先になり、インポートして別のスレーブで続行すると、データにギャップが残ります。

スレーブで使用する正しい値は Exec_Master_Log_Pos です。これは、スレーブ SQL スレッドが最後に実行したマスター バイナリ ログ ファイル内の位置であり、mysqldump と Exec_Master_Log_Pos の間にデータ ギャップがないことを意味します。

正しい使用法の上でロスのスクリプトを使用すると、次のようになります。

# MySQL executable location
mysql=/usr/bin/mysql

# MySQLDump executable location
mysqldump=/usr/bin/mysqldump

# MySQL Username and password
userpassword=" --user=<username> --password=<password>"

# MySQL dump options
dumpoptions=" --quick --add-drop-table --add-locks --extended-insert"

# Databases to dump
databases="db1 db2 db3"

# Backup Directory
# You need to create this dir
backupdir=~/mysqldump


# Stop slave sql thread

echo -n "Stopping slave SQL_THREAD... "
mysql $userpassword -e 'STOP SLAVE SQL_THREAD;'
echo "Done."

set `date +'%Y %m %d'`

# Get Binary Log Positions

echo "Logging master status..."
masterlogfile=`$mysql $userpassword -e 'SHOW SLAVE STATUS \G' | grep '[^_]Master_Log_File'`
masterlogpos=`$mysql $userpassword -e 'SHOW SLAVE STATUS \G' | grep 'Exec_Master_Log_Pos'`

# Write log Info

echo $masterlogfile
echo $masterlogpos
echo $masterlogfile >> ${backupdir}/$1-$2-$3_info.txt
echo $masterlogpos >> ${backupdir}/$1-$2-$3_info.txt

# Dump the databases

echo "Dumping MySQL Databases..."
for database in $databases
do
echo -n "$database... "
$mysqldump $userpassword $dumpoptions $database | gzip - > ${backupdir}/$1-$2-$3_${database}.sql.gz
echo "Done."
done

# Start slave again

echo -n "Starting slave... "
$mysql $userpassword -e 'START SLAVE'
echo "Done."

echo "All complete!"

exit 0
于 2013-02-12T18:12:30.647 に答える
0

2番目のオプションは正しいトラックのようです。

mysqldump を使用して差分バックアップを行う方法を考え出す必要がありました。最終的に、バックアップするデータベースを選択して mysqldump を実行するスクリプトを作成しました。http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html#option_mysqldump_master-dataに記載されている手順に従ってスクリプトを作成し、それを cron ジョブから呼び出すことはできませんか?

  1. mysqlに接続して「スレーブを停止」
  2. SHOW SLAVE STATUS を実行
  3. file_name、file_pos を変数に格納する
  4. スレーブをダンプして再起動します。

ちょっと考えただけですが、「CHANGE MASTER TO」行をダンプファイルに追加すると、新しいスレーブを復元/セットアップしたときに実行されると思います。

于 2009-10-06T21:23:33.923 に答える