MysqlレイジーレプリケーションまたはMysqlスレーブを持つセールスマン

最近、私は次の仕事を与えられました。ラップトップを持ったセールスマンが全国を旅して誰かに何かを売っています。

なぜなら 彼らは時々、インターネットを介して中央サーバーに接続し、更新されたデータをマージする商品と価格の入手可能性に関する最新のデータを必要とします。



タスクの条件:

-営業担当者に連絡する頻度と頻度は、期間と同様に不明です。

-「営業担当者」のような営業担当者であるため、すべてが可能な限り確実に機能する必要があります。

-ソリューションは、Mysqlマスタースレーブレプリケーションに基づいている必要があります。



条件からの結論:



-信頼性のために、クライアント側(スレーブ)で最小限の設定、クラウンにスクリプトはありません。すべてがmysql内にある必要があります。

-なぜなら 営業担当者がいつどのような頻度でmasterデータベースに接続されるかはわかりませんが、すべてのスレーブがそれをダウンロードするまで、masterのbinlogを長期間保存する必要があります。



解決策:

-マスターに、どのスレーブと何人が既に「ダウンロード」したかを通知します。 むしろ、「最も怠 "な」奴隷はどの位置にいますか。

-他のすべてのbinlogは安全に削除できます。







タスクは、スレーブがすでにスレーブに追いついた場所をマスターに何らかの方法で通知する必要があるという事実に要約されました。



より正確には、タスクがあります:

1.スレーブで、現在binlogを使用している位置を確認します。

2.これをマスターに報告してください。

3.ウィザードで、不要なbinlogファイルを削除します。



なぜなら (タスクの条件に従って)外部スクリプトを実行できません。 ストアドプロシージャは残ります。

ストアドプロシージャでは「スレーブステータスの表示」のフィールドは使用できません...対処方法...



レプリケートされたデータベースのマスターにラベルを作成し、1分ごとにタイムスタンプを書き込みます。

これらの変更はbinlogに書き込まれ、binlogは遅かれ早かれスレーブになりコミットされます。 スレーブでこのテーブルから値を読み取ったので、マスターに追いついた時間を知っています:)







したがって、マスター上で作成し(複製されたテーブルで!!!)、1つのエントリを挿入します。

CREATE TABLE `master_tick` ( `id` mediumint(9) NOT NULL, `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ); INSERT INTO master_tick SET time=NOW();
      
      





イベントをハングさせます(データベース名を修正します):

 CREATE EVENT master_tick ON SCHEDULE EVERY 1 MINUTE DO UPDATE my_db.master_tick set time=NOW();
      
      





すべてが1分ごとになり、テーブルのmaster_tickフィールドが更新され、これがbinlogに書き込まれます。



はい、my.cnfに追加することを忘れないでください

 event_scheduler=1
      
      





そして、過負荷にならないように:

 SET GLOBAL event_scheduler=ON;
      
      





さて、スレーブについては、マスターにどれだけ追いついているかがわかっているので、どうにかマスターに通知する必要があります。



スレーブからマスターまで、「ローカル」テーブルENGINE = FEDERATEを介してのみ、外部スクリプトを使用せずにMYSQLツールを使用して記述できます。



イベントスレーブで最も簡単な方法は、ウィザードにあるFEDERATEテーブルを作成することです。







NOTレプリケートされたデータベースのマスターにテーブルを作成しましょう。

 CREATE TABLE `slaves` ( `server_id` int(11) NOT NULL, `master_tick_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, UNIQUE KEY `server_id` (`server_id`) )
      
      







スレーブで、それ接続します:

  CREATE TABLE `slaves` ( `slave_server_id` int(11) NOT NULL, `master_tick_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, UNIQUE KEY `server_id` (`server_id`) ) ENGINE=FEDERATED CONNECTION='mysql://user:passwd@mysql_master.mydomain.com:3306/test/slaves'
      
      





スレーブで 、master_tickテーブルからスレーブに時間をコピーするためのプロシージャを作成します。server_idを指定して、ウィザードがどのスレーブがどの位置にあるかを理解するようにしてください。

 CREATE PROCEDURE `copy_master_tick_time`() BEGIN DECLARE master_tick_time timestamp; SET @master_tick_time = (select time from my_db.master_tick); DELETE FROM test.slaves where server_id=@@server_id; INSERT INTO test.slaves set server_id=@@server_id, master_tick_time=@master_tick_time; END
      
      





スレーブで EVENTを追加します。

 CREATE EVENT `copy_master_tick` ON SCHEDULE EVERY 30 SECOND STARTS '2013-01-01 00:00:00' DO call copy_master_tick_time()
      
      







それだけです



残っているのは、不要なログを削除する最後のマスターです。

クラウンスクリプトBashを実行します。



 #!/bin/bash a=`mysql -e "select MIN(master_tick_time) from slaves;"` mysql -e "PURGE BINARY LOGS BEFORE $a"
      
      







PSたぶん、これはbinlog_format = 'ROW'の場合にのみ機能します。



All Articles