- 締切済み
異なるDBに存在するテーブル間のミラーリング
PHP5とMySQL5でショッピングサイトを作成しています。 サイトSとS'があり、それぞれがデータベースDBとDB'を使用しています。そして、DBとDB'にはそれぞれ顧客テーブルTとT'があります。 この状況で、Tに対して更新処理をしたときに、T'に対しても同じ更新処理を しなければなりません。逆の場合も同じです。つまり、TとT'の間でミラーリングのようなことを行いたいのです。 updateとdeleteの場合は、次のような処理の流れで問題が内容に思われます。 サイトS中のスレッドの場合 step1. DBに接続 step2. Tに対してupdate/deleteする step3. step2でupdate/deleteされた列の主キーを取得 step4. DB'に接続 step5. T'に対してstep3で取得した主キーを用いてupdate/deleteする しかし、insertの場合の処理の流れが思いつきません。一応次のような流れが思いついたのですが・・・ サイトS中のスレッドの場合 step1. DBに接続 step2. Tをロック step3. DB'に接続 step4. T'をロック step5. Tに対してinsert step6. T'に対してinsert step7. T'のロック解除 step8. Tのロック解除 しかし、これだとデッドロックが発生する可能性があると思うのですが、 どうしたらよいのでしょうか?
- みんなの回答 (3)
- 専門家の回答
みんなの回答
- MeijiK
- ベストアンサー率100% (3/3)
>>MySQLのインスタンスとは、MySQLサーバと解釈して良いのでしょうか? はい。参考URLのような方法で複数立ち上げておらず、一つだけのMySQLサーバーが立ち上げっている状態を前提にしています。 >>MySQLのレプリケーションは、マスターからスレーブへの一方向だけのようなので、今回のケースでは使えないようです。 基本的にはそうですが、マスター・マスターの構成で使っている人もいます。必要になったらググってみてください。
- ogohs
- ベストアンサー率33% (5/15)
○簡単な方法としましては、それそれのDBサーバにロックテーブルを作成して、両方のサーバのロックテーブルを取得出来た場合にのみ、insert/update/deleteの処理を行う。 ロックテーブルを取得出来ない場合は、即時解放してもう一度行う。 自サーバロック → 他サーバロック → 成功 → 各処理 | → 失敗 → ロック解放 → 最初に戻る ○こちらは推奨です。 顧客テーブルTとT'が全く同じ場合、やはり1つのサーバをマスターデータとして管理するのが良いと思います。 今回の構成から大きく変えない場合、 顧客テーブルTをマスターテーブルとして、 顧客テーブルT'のみ、顧客テーブルTからレプリケーションでテーブルを作成します。 ログイン等のselect関係の処理は今までと変わらずそのまま利用できます。 insert/update/deleteの場合のみ、接続サーバを変更する必要がありますが、顧客テーブルのみの場合は比較的簡単に実装できると思います。 検討してみてください。
- MeijiK
- ベストアンサー率100% (3/3)
単純にひとつのMySQLインスタンス内の違うDBだったら、上記のように二つにわけてミラーリングを考えるよりも、データベース一つに対して、それぞれがUPDATE/DELETE/INSERTすることで、お望みの処理が実現できると思います。 例えば、DBとDB'(DB2とします)にはそれぞれ顧客テーブルTとT'(T2とします)があるとすると、DBのTだけをつかって、DB2からは、テーブル名をDB.Tで修飾して使います。以下が、DB2からDBを操作する例です。 mysql> use db2 Database changed mysql> insert into db.t values(1, 'aaaa'); Query OK, 1 row affected (0.34 sec) mysql> insert into db.t values(2, 'bbbb'); Query OK, 1 row affected (0.02 sec) mysql> select * from db.t; +------+------+ | id | name | +------+------+ | 1 | aaaa | | 2 | bbbb | +------+------+ 2 rows in set (0.08 sec) mysql> update db.t set name = 'cccc' where id = 2; Query OK, 1 row affected (0.06 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> delete from db.t where id = 1; Query OK, 1 row affected (0.00 sec) mysql> select * from db.t; +------+------+ | id | name | +------+------+ | 2 | cccc | +------+------+ 1 row in set (0.02 sec) # DB内では通常通り、Tだけを指定して、操作します。 二つのMySQLインスタンス間で同期をとるのであれば、レプリケーション機能が使えますので、調べてみてください。
お礼
早速の回答ありがとうございます。 MeijiKさんの回答のとおりにしてみたら、うまくいきました。 ありがとうございました。 MySQLのインスタンスとは、MySQLサーバと解釈して良いのでしょうか? MySQLのレプリケーションは、マスターからスレーブへの一方向だけのようなので、今回のケースでは使えないようです。