2

MySQL5.1 でマスター/スレーブ レプリケーションを実行しており、mysql プロキシ 0.8.x で r/w 分割を行っています。

一時テーブルを除いて正常に動作します。MySQL は、一時テーブルが存在しないというエラーをスローします。

これは、マスター サーバーのクエリ ログです。

        CREATE TEMPORARY TABLE IF NOT EXISTS sh ( ad_id MEDIUMINT( 8 ) UNSIGNED NOT NULL, score float , INDEX ( `ad_id` ), INDEX ( `score` )) ENGINE = MEMORY

INSERT INTO sh
                            SELECT  cl.ID, 1
                            FROM    classifieds cl
                            WHERE   cl.advertiser_id = '40179'

これは、スレーブのクエリ ログです。

CREATE TEMPORARY TABLE IF NOT EXISTS sh ( ad_id MEDIUMINT( 8 ) UNSIGNED NOT NULL, score float , INDEX ( `ad_id` ), INDEX ( `score` )) ENGINE = MEMORY

これは mysql エラー メッセージです。

Occured during executing INSERT INTO sh SELECT cl.ID, 1 FROM classifieds cl WHERE cl.advertiser_id = '40179' statement
Error: 1146 Table 'dbname.sh' doesn't exist

マスターに直接クエリを実行すると (php db 接続を mysql-proxy ではなくマスターに変更する)、問題なく動作します。

私はこのmysqlプロキシ設定を使用しています:

[mysql-proxy]
daemon = true
pid-file = /home/mysqladm/mysql-proxy.pid
log-file = /home/mysqladm/mysql-proxy.log
log-level = debug
proxy-address = 192.168.0.109:3307
proxy-backend-addresses = 192.168.0.108:3306
proxy-read-only-backend-addresses = 192.168.0.109
proxy-lua-script = /usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua

それを修正する方法について誰か考えがありますか?助けてくれてありがとう!

// 翌日編集

これが機能しない理由を知っていると思います:

MySQL Proxy は create tmp および insert select ステートメントをマスターに送信し、マスターはコマンドを正しくスレーブにレプリケートし、次のステップで select がスレーブに送信されます。残念ながら、MySQL では、tmp テーブルはそれを発行した接続に対してのみ有効です。したがって、レプリケーションによって作成された tmp テーブルは、スレーブ上の mysql プロキシによって発行された 2 番目の接続に対しては有効ではありません。

私は現在、アプリケーションを変更し、マスターに直接 tmp テーブルを使用して接続を発行することで、これを解決しようとしています。

より良い解決策があると思われる場合はお知らせください。

4

1 に答える 1

0

はい、まさにそれが問題です。これは、アプリケーション層がそれ自体で判断するのではなく、MySQL Proxy を使用して読み取りクエリを分割することの落とし穴の 1 つです。

あなたがやっていることは、その決定をアプリケーション層に戻すことのようですが、これらのテーブルのみです。それは良い回避策です。dbh を直接データベースに向ける必要がある例外をさらに作成している場合は、そのコードを抽象化し、特定の機能に対して dbh を要求する方法をアプリケーションに与えることを検討してください。この場合、コードでライブラリに「TEMPORARY TABLE クエリを実行できる dbh をください」と要求する必要があります。

もう 1 つの方法は、すべての TEMPORARY TABLE に認識可能な名前を付けることです (おそらく、すべて "tmp_" で始まるようにします)。これにより、Proxy はそれらの SELECT を適切な場所に送信するための戦いの機会を得ることができます。

于 2011-08-08T12:54:14.740 に答える