実行時にbinlog形式を切り替える最も安全な方法は何ですか?


25

次の警告のためmysqld.log

[警告] BINLOG_FORMAT = STATEMENT以降、ステートメント形式を使用してバイナリログに書き込まれる安全でないステートメント。このステートメントは、LIMIT句を使用しているため安全ではありません。含まれる行のセットを予測できないため、これは安全ではありません。

レプリケーション形式をに切り替えたいMIXED

しかし、MySQLドキュメントによると:

テンポラリテーブルが存在する場合、実行時にレプリケーション形式を切り替えることはお勧めしません。テンポラリテーブルは文ベースのレプリケーションを使用する場合にのみ記録され、行ベースのレプリケーションでは記録されないためです。

したがって、問題は、バイナリログ形式を安全に切り替えるために一時テーブルが存在するかどうかをどのように識別できるかです。


1
クイック警告。RBR-> SBRから行って読み取りコミットを使用する場合は、これに注意してください:bugs.mysql.com/bug.php?id
Morgan

回答:


35

これを行うと、binlogには特定の形式があるので、MySQL(Oracleはまだ私の舌を転がすことはできません)がこの機能を構築したにもかかわらず、2つの形式を一緒にギャンブルしないことを決定できます。

mysqlを再起動せずに完全に安全にプレイするには、次を試してください。

FLUSH TABLES WITH READ LOCK;
FLUSH LOGS;
SET GLOBAL binlog_format = 'MIXED';
FLUSH LOGS;
UNLOCK TABLES;

これにより、最後のバイナリログは「MIXED」形式のままになります。最後の(最後の隣の)binlogが存在するのは、単に以前の形式にあった最後のbinlogをクローズするだけです。

最初のセッションより前のすべての既存のセッションは、実行されるとFLUSH LOGS;最後のbinlogに書き込みを開始しUNLOCK TABLES;ます。

試してみる !!!

警告

クレジットが支払われるべき場所にクレジットを与えると、私の答えは本当に@Jonathan の答えに便乗します。その上でbinlogを閉じて開きます。彼はこれを最初に引き出したために+1を受け取ります。

更新2011年10月12日13時58分EDT

アクティブなマスターに対してこれを行い、そのマスターから複製する1つ以上のスレーブがある場合、リレーログも新しい形式であることに注意する必要があります。できることは次のとおりです。

スレーブで、実行します STOP SLAVE;

マスターで次を実行します。

FLUSH TABLES WITH READ LOCK;
FLUSH LOGS;
SET GLOBAL binlog_format = 'MIXED';
FLUSH LOGS;
UNLOCK TABLES;

スレーブで、実行します START SLAVE;

リレーログを実行STOP SLAVE;およびSTART SLAVE;ローテーションし、新しいエントリがどの形式になっても複製されます。binlog_formatの変更をスレーブにも適用することもできます。


3
留意すべきことの1つは、mysqlのレプリケーション設定は実際にはクライアントセッションごとに設定されるということです。グローバルbinlog_formatを設定すると、NEWセッションの値が変更されるだけです。したがって、クライアントが永続的に接続されているシステムで実行している場合、ここで指定されたフラッシュとロックを行っても、設定に加えた変更はすぐには適用されません-クライアントが有効になるまで有効になりません再接続(または、独自のセッションで値を設定しますが、私の経験では前者のほうが可能性が高い)。
オースティンミルズ

好奇心those盛な人には、これを「binlog_format = 'MIXED';」と入力することもできます。あなたのmy.cnfに。
クリスチャン

2
FYI、この答えはここに答えと一致していない:dba.stackexchange.com/questions/58539/...
HTTP500

マニュアルの状態:これは、レプリケーションマスターのログ形式を変更しても、スレーブがログ形式を一致するように変更しないことを意味します。(..snip ..)レプリケーションの進行中にマスターでバイナリロギングフォーマットを変更するとまたはスレーブでも変更せずに予期しない結果を引き起こしたり、レプリケーションが完全に失敗することさえあります。
ハーフガー14

@Halfgaar先週、私はスレーブをMIXEDからSTATEMENTに3回切り替えましたが、悪影響はありませんでした。競合状態が原因でレプリケーションが中断していたため、私はそれを行っていました。クエリの実行前に、テーブルがスレーブ上に存在しなくなりました。そこで、そのような状況で安定するためにSTATEMENTに切り替えました。もちろん、私がこれを行っている間、すべての書き込みは停止されました。ところでマスターもやりました。
RolandoMySQLDBA 14

6

実行時にbinlog_formatを切り替えるには、次を実行できます。

set global binlog_format = 'MIXED';

これにより、すべての新しいセッションが混合binlog形式に設定されます。既存のセッションはすべて、終了するまで以前に設定されたものになります。

またset session binlog_format = 'MIXED';、セッションに関する問題を具体的に解決するために手動で行うこともできます。


方法を尋ねるのではなく、最も安全な方法を尋ね、一時テーブルが存在するかどうかをどのように確認できますか。
量子

3
最初にグローバル変数を設定し、残りのセッションが終了するのを待つのが最も安全な方法です。
ジョナサン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.