Mysqlレプリケーションの場合にマスターとスレーブに異なるデータベースがある場合、Mysql DBを再同期する方法は?


139

Mysql Server1MASTERとして実行されています。
Mysql Server2SLAVEとして実行されています。

現在、マスターからスレーブへのDBレプリケーションが行われています。

Server2がネットワークから削除され、1日後に再接続します。この後、マスターとスレーブのデータベースに不一致があります。

マスターからスレーブに取得したDBを復元した後も問題が解決しないので、DBを再同期する方法は?

回答:


287

これは、マスター/スレーブレプリケーションを最初から再同期するための完全なステップバイステップの手順です。

マスターで:

RESET MASTER;
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;

そして、その結果の値をコピーし、最後のコマンドのどこかの。

クライアントへの接続を閉じずに(読み取りロックを解放するため)、次のコマンドを発行してマスターのダンプを取得します。

mysqldump -u root -p --all-databases > /a/path/mysqldump.sql

これで、ダンプがまだ終了していない場合でも、ロックを解放できます。これを行うには、MySQLクライアントで次のコマンドを実行します。

UNLOCK TABLES;

次に、scpまたは任意のツールを使用して、ダンプファイルをスレーブにコピーします。

スレーブで:

mysqlへの接続を開き、次のように入力します。

STOP SLAVE;

次のコンソールコマンドを使用して、マスターのデータダンプをロードします。

mysql -uroot -p < mysqldump.sql

スレーブとマスターのログを同期します。

RESET SLAVE;
CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=98;

上記のフィールドの値は、前にコピーしたものです。

最後に、次のように入力します。

START SLAVE;

入力後、すべてが正常に機能していることを確認するには:

SHOW SLAVE STATUS;

見るべき:

Slave_IO_Running: Yes
Slave_SQL_Running: Yes

それでおしまい!


8
InnoDBはdabataseと定義されたBLOBとDATEのような他の複雑な列の型を入力すると、私は次のスイッチを使用することをお勧めします:--opt --single-transaction --comments --hex-blob --dump-date --no-autocommit --all-databases
ケンPEGA

4
であるRESET_SLAVE必要?あなたが持つものを再入力する必要がありますので、これらの命令は、レプリケーションのユーザーとパスワードをリセットすることに注意してくださいCHANGE MASTER TO...
マイク・S.

25
マスターでmysqldumpを呼び出すときに--master-dataフラグを使用すると、CHANGE MASTER TOコマンドがダンプファイルに書き込まれるため、ダンプファイルをスレーブにインポートした後、それを実行するステップが節約されます。
udog 2013

3
マスターをロックしない(Perconaは必要ありません)plusbryan.com/mysql-replication-without-downtimeこれのもう1つの利点は、SQLダンプに必要な "CHANGE MASTER"行が含まれていることです(コメントアウト)
mahemoff

2
これを自動化する方法はありますか?
メタファニエル2015年

26

MySQLのサイトにあるこのドキュメントは、時代遅れになっており、フットガン(interactive_timeoutなど)でなぞられています。マスターのエクスポートの一部としてFLASHH TABLES WITH READ LOCKを発行することは、通常、LVMやzfsなどのストレージ/ファイルシステムのスナップショットと連携している場合にのみ意味があります。

mysqldumpを使用する場合は、代わりに--master-dataオプションを使用して、人為的エラーから保護し、マスターのロックをできるだけ早く解放する必要があります。

マスターが192.168.100.50で、スレーブが192.168.100.51であり、各サーバーに個別のサーバーIDが構成され、マスターにバイナリログオンがあり、スレーブにmy.cnfの読み取り専用= 1があると仮定します。

ダンプをインポートした直後にレプリケーションを開始できるようにスレーブをステージングするには、CHANGE MASTERコマンドを発行しますが、ログファイルの名前と位置は省略します。

slaveserver> CHANGE MASTER TO MASTER_HOST='192.168.100.50', MASTER_USER='replica', MASTER_PASSWORD='asdmk3qwdq1';

スレーブが使用できるようにマスターでGRANTを発行します。

masterserver> GRANT REPLICATION SLAVE ON *.* TO 'replica'@'192.168.100.51' IDENTIFIED BY 'asdmk3qwdq1';

マスターを(画面で)圧縮してエクスポートし、正しいバイナリログ座標を自動的にキャプチャします。

mysqldump --master-data --all-databases --flush-privileges | gzip -1 > replication.sql.gz

replication.sql.gzファイルをスレーブにコピーしてから、zcatを使用してスレーブで実行されているMySQLのインスタンスにインポートします。

zcat replication.sql.gz | mysql

スレーブにコマンドを発行してレプリケーションを開始します。

slaveserver> START SLAVE;

必要に応じて、スレーブの/root/.my.cnfを更新して、マスターと同じルートパスワードを保存します。

5.1以降を使用している場合は、最初にマスターのbinlog_formatをMIXEDまたはROWに設定することをお勧めします。主キーが不足しているテーブルでは、ログに記録された行のイベントが遅いことに注意してください。これは通常、スレーブで間違ったデータを生成する可能性が低いため、binlog_format = statement(マスター上)の代替(およびデフォルト)構成よりも優れています。

レプリケーションをフィルタリングする必要がある(ただし、そうすべきではない)場合は、スレーブオプションのreplicate-wild-do-table = dbname。%またはreplicate-wild-ignore-table = badDB。%を使用して、binlog_format = rowのみを使用してください。

このプロセスは、mysqldumpコマンドの期間中、マスターのグローバルロックを保持しますが、それ以外の場合はマスターに影響を与えません。

mysqldump --master-data --all-databases --single-transaction(InnoDBテーブルのみを使用しているため)を使用したい場合は、MySQL Enterprise Backupまたはxtrabackupと呼ばれるオープンソース実装(提供:ペルコナ)


3
あなたは、単に既存のスレーブを再構築したい場合は、手順のカップルをスキップし、上記のプロセスをたどることができます:GRANTと手動のCHANGE MASTERコマンド
時代遅れ

質問1:Windowsでは、に相当するものは何ですかzcat。質問2:mysqldumpパフォーマンスの点で、これは大規模データベースでどのように機能しますか?使用する方法SELECT INTO OUTFILELOAD DATA、あなたの提案プロセスにスムーズに?(一般的にパフォーマンスが
高い

STOP SLAVEプロセスのどこかにする必要はありませんか?
デビッドV.

16

スレーブ(Server2)に直接書き込む場合を除いて、唯一の問題は、Server2が切断された後に発生した更新がないことです。「START SLAVE;」でスレーブを再起動するだけです。すべてを高速に戻す必要があります。


2
ビンのログをチェックして、システムが同期していなかった期間をカバーしているかどうかを確認できます。欠落している日がある場合、これはさらに大きな問題になる可能性があり、欠落しているデータを復元するためにフルダンプを実行する必要があります。
nelaaro

7

Maatkit utilitsが役立つと思います。mk-table-syncを使用できます。このリンクを参照してください:http : //www.maatkit.org/doc/mk-table-sync.html


スクリプトの実行中は、書き込みを一時的に停止する必要があると思います。
Ztyx 2014年

これはまだうまくいきます。ただし、ツールの名前は変更され、現在はpt-table-syncと呼ばれています。しかし実際には、pt-slave-restartツールが魔法のように機能することがわかりました。
mlerley

7

私はこの質問に非常に遅れていますが、私はこの問題に遭遇しました。多くの検索の結果、Bryan Kennedyからこの情報を見つけました:http : //plusbryan.com/mysql-replication-without-downtime

マスターで、次のようなバックアップを
作成します。mysqldump --skip-lock-tables --single-transaction --flush-logs --hex-blob --master-data = 2 -A>〜/ dump.sql

次に、ファイルの先頭を調べて、MASTER_LOG_FILEとMASTER_LOG_POSの値を書き留めます。後で必要になります 。headdump.sql -n80 | grep "MASTER_LOG"

「dump.sql」ファイルをスレーブにコピーして復元します 。mysql -u mysql-user -p <〜/ dump.sql

スレーブmysqlに接続し、次のようなコマンドを実行します: CHANGE MASTER TO MASTER_HOST = 'master-server-ip'、MASTER_USER = 'replication-user'、MASTER_PASSWORD = 'slave-server-password'、MASTER_LOG_FILE = 'value from above'、 MASTER_LOG_POS =上記の値。スレーブを開始します。

スレーブの進行状況を確認するには: SHOW SLAVE STATUS;

すべてが順調な場合、Last_Errorは空白になり、Slave_IO_Stateは「マスターがイベントを送信するのを待っています」を報告します。Seconds_Behind_Masterを探します。これは、それがどれだけ遅れているかを示します。YMMV。:)


3
これは機能し、スレーブがすでに設定されていて同期が外れているだけの場合は、CHANGE MASTERを実行する必要はありません。指定するだけ--master-data=1(またはだけ--master-data)。
LSerni 2016年

5

これは、mysqlスレーブが同期しなくなったときに私が通常行うことです。私はmk-table-syncを見てきましたが、リスクセクションは恐ろしいと思っていました。

マスター:

SHOW MASTER STATUS

出力された列(File、Position)は少し役に立ちます。

スレーブ:

STOP SLAVE

次に、マスターデータベースをダンプし、スレーブデータベースにインポートします。

次に、以下を実行します。

CHANGE MASTER TO
  MASTER_LOG_FILE='[File]',
  MASTER_LOG_POS=[Position];
START SLAVE;

ここで、[File]と[Position]は、上記で実行した「SHOW MASTER STATUS」から出力された値です。

お役に立てれば!


5
どうやらあなたはFLUSH TABLES WITH READ LOCK;SHOW MASTER STATUSにマスターデータベースをダンプしていないので、これは壊れているようです。マスターステータスをダンプが取得される前の時点に効果的に設定し、すでにダンプに含まれている履歴を再生するため、スレーブで重複キーエラーが発生する可能性があると思います。(説明した順序で作業を行う場合)
KajMagnus 14


3

時にはあなたも奴隷にキックを与える必要があるだけです

試す

stop slave;    
reset slave;    
start slave;    
show slave status;

かなり頻繁に、奴隷、彼らは立ち往生している:)


...を使用Positionしてマスターで監視し、スレーブshow master status;で監視します。スレーブはマスターに追いつく必要があります。短いネットワーク停止の直後にmysql 5.6を使用して私のために働いた。Exec_Master_Log_Pos:show slave status \G
Mike S

10
これは誤解を招く恐れがあります。いったんスレーブをリセットすると、マスターはどこにいるかについての情報が完全に失われます。
Qian Chen

2

うまくいけば他の人を助ける完全な答えはここにあります...


マスターとスレーブを使用してmysqlレプリケーションをセットアップしたいのですが、同期するためにログファイルを使用することがわかっていたため、スレーブがオフラインになり同期が外れた場合、理論的には接続するだけで十分です。ユーザーmalonsoが述べたように、マスターに送信し、中断したところからログファイルを読み続けます。

したがって、マスターとスレーブを構成した後のテスト結果は次のとおりです。http//dev.mysql.com/doc/refman/5.0/en/replication-howto.html ...

推奨されるマスター/スレーブ構成を使用し、スレーブに書き込みを行わない場合、彼と私は正しい場所にいます(mysql-server 5.xに関する限り)。「START SLAVE;」を使う必要すらありませんでした。マスターに追いついただけです。しかし、デフォルトの88000があり、60秒ごとに何かが再試行するので、スレーブを起動または再起動する必要がある可能性があることを使い果たしたと思います。とにかく、スレーブをオフラインにして再度バックアップする必要があるかどうかを知りたいと思っていた私のような人にとっては、手動による介入が必要です。いいえ、それは必要ありません。

たぶん、元の投稿者のログファイルが破損していましたか?しかし、おそらくサーバーが1日オフラインになるだけではありません。


/usr/share/doc/mysql-server-5.1/README.Debian.gzからプルされます。これはおそらく非debianサーバーにも意味があります:

*複製に関するその他の注意事項
===============================
MySQLサーバーがレプリケーションスレーブとして機能している場合、
--tmpdirをメモリベースのファイルシステム上のディレクトリを指すように、または
サーバーホストの再起動時にクリアされるディレクトリ。複製
スレーブは、マシンの再起動後も一時ファイルの一部が必要なので、
一時テーブルまたはLOAD DATA INFILE操作を複製できること。もし
一時ファイルディレクトリ内のファイルは、サーバーの再起動時に失われます。
複製は失敗します。

次のようなSQLを使用できます。「tmpdir」のような変数を表示します。見つけるために。


両方のデータベースが互いに自動的に同期しますか?たとえば、マスターに書き込み、スレーブは自動的に更新されますか?
TransformBinary

2

このエラーを含めるために一般的な回答に追加します。

"ERROR 1200 (HY000): The server is not configured as slave; fix in config file or with CHANGE MASTER TO",

スレーブからのワンショットでの複製:

1つのターミナルウィンドウで:

mysql -h <Master_IP_Address> -uroot -p

接続後、

RESET MASTER;
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;

ステータスは次のように表示されます。位置番号は異なることに注意してください。

+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 |      98  | your_DB      |                  |
+------------------+----------+--------------+------------------+

彼が「別の端末を使用する」と同じようにダンプをエクスポートします!

終了して、自分のDB(スレーブ)に接続します。

mysql -u root -p

以下のコマンドを入力します。

STOP SLAVE;

上記のようにダンプをインポートし(もちろん別の端末で!)、以下のコマンドを入力します。

RESET SLAVE;
CHANGE MASTER TO 
  MASTER_HOST = 'Master_IP_Address', 
  MASTER_USER = 'your_Master_user', // usually the "root" user
  MASTER_PASSWORD = 'Your_MasterDB_Password', 
  MASTER_PORT = 3306, 
  MASTER_LOG_FILE = 'mysql-bin.000001', 
  MASTER_LOG_POS = 98; // In this case

ログが記録されたら、server_idパラメータを設定します(通常、新しい/複製されていないDBの場合、これはデフォルトでは設定されていません)。

set global server_id=4000;

次に、スレーブを起動します。

START SLAVE;
SHOW SLAVE STATUS\G;

出力は彼が説明したものと同じでなければなりません。

  Slave_IO_Running: Yes
  Slave_SQL_Running: Yes

注:複製されると、マスターとスレーブは同じパスワードを共有します!


両方のデータベースが互いに自動的に同期しますか?たとえば、マスターに書き込み、スレーブは自動的に更新されますか?
TransformBinary

1

LVMを使用したスレーブの再構築

Linux LVMを使用してMySQLスレーブを再構築するために使用する方法は次のとおりです。これにより、マスターでのダウンタイムを最小限に抑えながら、一貫したスナップショットが保証されます。

マスターMySQLサーバーでinnodb max dirty pages percentをゼロに設定します。これにより、MySQLはすべてのページをディスクに書き込むように強制され、再起動が大幅に高速化されます。

set global innodb_max_dirty_pages_pct = 0;

ダーティページの数を監視するには、次のコマンドを実行します

mysqladmin ext -i10 | grep dirty

数が減少しなくなったら、続行するポイントに到達しました。次にマスターをリセットして、古いbinログ/リレーログをクリアします。

RESET MASTER;

lvdisplayを実行してLVパスを取得します

lvdisplay

出力は次のようになります

--- Logical volume ---
LV Path                /dev/vg_mysql/lv_data
LV Name                lv_data
VG Name                vg_mysql

コマンドでマスターデータベースをシャットダウンする

service mysql stop

次にスナップショットを取ると、mysql_snapshotが新しい論理ボリューム名になります。binlogがOSドライブに配置されている場合、それらもスナップショットである必要があります。

lvcreate --size 10G --snapshot --name mysql_snapshot /dev/vg_mysql/lv_data

コマンドでマスターを再起動

service mysql start

ダーティページの設定をデフォルトに戻す

set global innodb_max_dirty_pages_pct = 75;

lvdisplayを再度実行して、スナップショットが存在し、表示されていることを確認します

lvdisplay

出力:

--- Logical volume ---
LV Path                /dev/vg_mysql/mysql_snapshot
LV Name                mysql_snapshot
VG Name                vg_mysql

スナップショットをマウントする

mkdir /mnt/mysql_snapshot
mount /dev/vg_mysql/mysql_snapshot /mnt/mysql_snapshot

既存のMySQLスレーブを実行している場合は、停止する必要があります

service mysql stop

次に、MySQLデータフォルダーをクリアする必要があります

cd /var/lib/mysql
rm -fr *

マスターに戻ります。スナップショットをMySQLスレーブにrsyncします

rsync --progress -harz /mnt/mysql_snapshot/ targethostname:/var/lib/mysql/

rsyncが完了したら、スナップショットをアンマウントして削除できます

umount /mnt/mysql_snapshot
lvremove -f /dev/vg_mysql/mysql_snapshot

古いレプリケーションユーザーが存在しないか、パスワードが不明な場合は、マスターにレプリケーションユーザーを作成します

GRANT REPLICATION SLAVE on *.* to 'replication'@'[SLAVE IP]' identified by 'YourPass';

/ var / lib / mysqlデータファイルがmysqlユーザーによって所有されていることを確認します。所有している場合は、次のコマンドを省略できます。

chown -R mysql:mysql /var/lib/mysql

次に、binlogの位置を記録します。

ls -laF | grep mysql-bin

次のようなものが表示されます

..
-rw-rw----     1 mysql mysql  1073750329 Aug 28 03:33 mysql-bin.000017
-rw-rw----     1 mysql mysql  1073741932 Aug 28 08:32 mysql-bin.000018
-rw-rw----     1 mysql mysql   963333441 Aug 28 15:37 mysql-bin.000019
-rw-rw----     1 mysql mysql    65657162 Aug 28 16:44 mysql-bin.000020

ここで、マスターログファイルは順番に最も大きいファイル番号であり、ビンログの位置はファイルサイズです。これらの値を記録します。

master_log_file=mysql-bin.000020
master_log_post=65657162

次にスレーブMySQLを起動します

service mysql start

次のコマンドを実行して、スレーブでマスター変更コマンドを実行します。

CHANGE MASTER TO 
master_host="10.0.0.12", 
master_user="replication", 
master_password="YourPass", 
master_log_file="mysql-bin.000020", 
master_log_pos=65657162; 

最後にスレーブを起動します

SLAVE START;

スレーブのステータスを確認します。

SHOW SLAVE STATUS;

スレーブIOが実行中であり、接続エラーがないことを確認してください。幸運を!

BR、Juha Vehnia

私は最近、ここにある私のブログにこれを書きました...詳細はほとんどありませんが、ストーリーは同じです。

http://www.juhavehnia.com/2015/05/rebuilding-mysql-slave-using-linux-lvm.html


0

この問題をすばやく解決するためのスクリプトを含むGitHubリポジトリを作成しました。いくつかの変数を変更して実行するだけです(最初に、スクリプトはデータベースのバックアップを作成します)。

私はこれがあなた(そして他の人々も)を助けることを願っています。

MySQLマスター/スレーブレプリケーションをリセット(再同期)する方法


スクリプトは常にマスターログの位置を1に設定し、マスターログファイルの名前を設定します。私はこれが気になるべきかどうか確信が持てません。説明してもらえますか?私は現在1,000,000以上のポジションを持っています。これは、速度を上げる前に1milのクエリを再生しようとすることを意味しますか?既存のデータに対してこれらのクエリを実行する際に破損の可能性はありませんか?mysqlダンプを実行するときにスクリプトで--master-data = 2オプションを使用し、ファイルからファイルとposをプルしてそれらを設定するのはなぜでしょうか。
ジョサイア

0

私たちはMySQLのマスターマスターレプリケーションテクニックを使用しており、1つのMySQLサーバーがネットワークから1を削除すると言った場合、接続が復元された後、サーバーに再接続し、ネットワーク内にあったサーバー2でコミットされたすべてのレコードが転送されます。復元後に接続を失ったサーバー1に。MySQLのスレーブスレッドは、デフォルトで60秒ごとにそのマスターへの接続を再試行します。このプロパティは、MySQLとしてフラグ "master_connect_retry = 5"として変更できます。5は秒単位です。つまり、5秒ごとに再試行する必要があります。

ただし、接続を失ったサーバーがデータベースでコミットを行わないことを確認する必要があります。重複したキーエラーエラーコード:1062


0

マスター

mysqldump -u root -p --all-databases --master-data | gzip > /tmp/dump.sql.gz  

scp master:/tmp/dump.sql.gz slave:/tmp/ ダンプファイルをスレーブサーバーに移動する

スレーブ:

STOP SLAVE;

zcat /tmp/dump.sql.gz | mysql -u root -p

START SLAVE;
SHOW SLAVE STATUS;  


マスターSET GLOBAL expire_logs_days = 3では、スレーブの問題が発生した場合に実行して、binlogを3日間保持できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.