私は Cron sync mysqlテーブル を見てきました。しかし、レプリケーションは使用できません。以前は percona-toolkit を使用していましたが、完全に機能しました。 syncコマンドはオンデマンドで実行することも、cron経由で実行することもできます。 2つのテーブルのチェックサムを比較し、挿入、更新、削除などを行います。ただし、Perl(DBD :: mysql)とMySQLには、これを実行する新しいサーバーとの互換性がないため、pt-table-を使用できません。同期。 Perl/DBD以外のものを使用する同様のソリューションはありますか?
編集:(詳細、明快さ)
mysqldump --opt <database> <tablename>
を使用してテーブルのダンプを作成し、新しいサーバーにフィードします。 TCP/IPを介してリモートデータベースにアクセスできるように見えるので、次のように使用できます。
mysqldump --opt --user=<youruser> --password=<yourpassword> -Host <yourhost> \
<yourDB> <yourtable> | mysql -u <newserveruser> -p<password>
リモートデータベースに接続し、それをダンプして、出力を新しいサーバーにフィードします。
リモートデータベースへの直接TCP/IPアクセスがなかった場合でも、 公開キー認証 を設定した後、SSHを介してデータをトンネリングすることで、ほとんど同じことができます。
ssh -C -l <remoteuser> <remoteserver> \
'mysqldump --opt --user=<youruser> --password=<yourpassword> <yourDB> <yourtable>' \
| mysql -u <newserveruser> -p<password>
詳細は mysqldump
のドキュメント および SSHのマニュアルページ を参照してください。
さらに帯域幅の効率が必要な場合は、mysqldump
を使用してダンプを作成し、それをソースサーバーに保存し、インポートする前にrsync
を使用して宛先サーバーで対応するものをコピー/更新することを検討してください。 rsync
はソースファイルと宛先ファイルに ローリングチェックサム を作成するため、以降の実行でダンプの内容のほとんどを転送する必要はない可能性があります。
行を挿入するときに一時テーブルを使用し、後でテーブルを元のテーブル名に変更してロック時間を短縮することを目的としたmysqldumpパッチがありましたが、未解決の問題があり、メインブランチに入れなかったので、実験的なものと見なします。 。パッチコードと詳細については この説明 を参照してください。
何らかの理由で宛先にテーブルを単にドロップできない場合は、ダンプされたデータを新しいテーブルに挿入する可能性があります(迅速でダーティですが、いくらか安全ではないアプローチでは、mysqldump
出力をsed -e 's/mytable/newtable/g'
にパイプしてから、さらにパイプしますto mysql
)次に、このようないくつかのJOINを使用してUPDATE/DELETE/INSERTサイクルを実行します(untested、サニティチェックを実行します) ):
/* set write lock on the table so it cannot be read while updating */
LOCK TABLES mytable WRITE;
/* update all rows which are present in mytable and newtable */
UPDATE mytable AS M LEFT JOIN newtable AS N ON M.primarykey = N.primarykey
SET M.column1=N.column1, M.column2=N.column2 [...]
WHERE N.primarykey Is Not NULL;
/* delete all rows from mytable which are no longer present in newtable */
DELETE M FROM mytable AS M LEFT JOIN newtable AS N on M.primarykey = N.primarykey
WHERE N.primarykey Is NULL;
/* insert new rows from newtable */
INSERT INTO mytable (primarykey, column1, column2, [...])
SELECT (N.primarykey, N.column1, N.column2, [...]) FROM mytable AS M
RIGHT JOIN newtable AS N ON M.primarykey=N.primarykey WHERE M.primarykey Is NULL
/* release lock */
UNLOCK TABLES;
注:もちろん、データベースのデータは、データを挿入/更新している間は一貫性がありませんが、トランザクションを使用していない限り(利用できません) MyISAMテーブルの場合)、これはどのような場合でも当てはまります。テーブルを削除して再作成すると、更新、削除、挿入のサイクルと同じように一時的な不整合が生じます。これは、MyISAMの非アトミックトランザクションレスデザインの性質によるものです。
rubyrep のようにしたいようですが、これは左または右に同期でき、どちらの方法で同期させたいかを設定できます。しかし、それはデータベースレベルであり、テーブルレベルではないと思います。これは、テーブルベースの同期に変更するための良い出発点になるかもしれません。
ログにアクセスできない可能性があるようです。または、バイナリログからコマンドを取得することをお勧めします。
トリガーを使用してみましたか?
DELIMITER $$
CREATE TRIGGER sync_table1_insert
AFTER INSERT ON `table1` FOR EACH ROW
BEGIN
INSERT INTO table2 (id, value) VALUES (NEW.id, NEW.value);
END;
$$
DELIMITER ;
DELIMITER $$
CREATE TRIGGER sync_table1_update
AFTER UPDATE ON `table1` FOR EACH ROW
BEGIN
UPDATE table2 SET value = NEW.value WHERE id = NEW.id;
END;
$$
DELIMITER ;
DELIMITER $$
CREATE TRIGGER sync_table1_delete
AFTER DELETE ON `table1` FOR EACH ROW
BEGIN
DELETE FROM table2 WHERE id = OLD.id;
END;
$$
DELIMITER ;