web-dev-qa-db-ja.com

停電テスト後にInnoDBマスター-マスターレプリケーションが不整合になる

午後の紳士、

私は現在、データベースエンジンとしてInnoDBを使用したマスター-マスターレプリケーション設定のストレステストを行っています。

このシンプルなスクリプトを使用して、リモートサーバーからLinux CLIで実行するテストを行っています。

<?php

while(true) {
    try {
        $conn = mysql_connect('10.0.10.210', 'test', 'test');
        if ($conn) {
            mysql_select_db('testdb');
            $random = Rand(0, 1000);
            $res = mysql_query("INSERT INTO test VALUES(0, 'test',    $random)");
            if ($res) {
                echo "\n inserted " . microtime();
            } else {
                echo "\n not inserted " . microtime();
            }
            mysql_close($conn);
        } else {
            echo "\n can not connect";
        }
    } catch (Exception $ex) {
        echo "\n can not insert"  . microtime();
    }
}

var_dump($res);
echo "ok";

私たちが直面している問題は、電源を抜くことだけでホストの1つを遮断しようとしていることです。

フェイルオーバーの目的でMySQL-MMMも使用していますが、これは現在直面している問題とは関係ありませんが、ここで使用している手順について説明します。

1)Master-Masterは完全に機能し、server1は仮想IP 10.0.10.210を持ち、書き込みと読み取りを提供しています

2)ケーブルを抜くことでserver1をシャットダウンし、仮想IPがserver2に移動します。すべてが機能し、約20秒のダウンタイム後に挿入が続行されます。

3)server1を再度起動すると、server1が起動して仮想IPアドレスを取得し、1〜2秒のダウンタイム後に挿入が続行されます。

これの問題は、server1のダウンタイム中に発生したall挿入がすべて失われ、「STOP SLAVE; START SLAVE;」と入力した場合です。私はこれらのエラーを受け取ります:

[ERROR] Slave I/O: Got fatal error 1236 from master when reading data from binary log: 'Client requested master to start replication from impossible position', Error_code: 1236

また、mysqld.logファイルの内容に対応するオフセットを使用してバイナリログを手動で確認すると、次のようになります。

[root@db1 mysql]# mysqlbinlog --offset=623435 db1-mysql-bin.000001
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#121030 12:55:16 server id 1  end_log_pos 106   Start: binlog v 4,   server v 5.1.61-log created 121030 12:55:16 at startup
# Warning: this binlog is either in use or was not closed properly.
ROLLBACK/*!*/;
BINLOG '
VOqPUA8BAAAAZgAAAGoAAAABAAQANS4xLjYxLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAABU6o9QEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC
'/*!*/;
ERROR: Error in Log_event::read_log_event(): 'read error', data_len: 112,     event_type: 2
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;

バイナリログファイルが適切に閉じられていないことを理解していますが、InnoDBがこれを処理するはずではありませんか?確かに、ハードな電源オフは、少なくとも私の心にはありませんが、珍しいことではありません。私はEXT4ファイルシステムを実行しています。

これは、これまでのところラボのセットアップに過ぎません。実際には、必要な予防策をすべて備えた最先端の(水中ではない...)データセンターでこれを実行しています。

問題に当てはまるどんな光でも大いに感謝されます、ありがとう。

[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
symbolic-links=0
sync_binlog=1

# REPLICATION SETTINGS
server_id = 2
replicate-same-server-id = 0
auto-increment-increment = 2
auto-increment-offset = 2
replicate-do-db = test
binlog-ignore-db = mysql

log-bin=db2-mysql-bin
relay-log=db2-relay-log
relay-log-index=relay-log-index

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

[〜#〜] update [〜#〜]

私はファイルシステムをEXT4からXFSに切り替えましたが、実際にデータの損失を処理しましたが、今では別の問題がまだ非常に小さく、簡単に解決できるはずです。

Server1をシャットダウンする手順を実行した後、server2にフェールオーバーし、server1を起動して、server1にロールバックします。すべてが見事に機能し続け、server1はserver2が中断したところを正確にピックアップします。唯一の問題は、server2がserver1の同期を停止するため、その逆です。

STOP SLAVEを実行すると、スレーブを開始します。同期が始まり、数秒後にserver1と同じになりますが、なぜこれが自動的に行われないのですか?

6
Lars

エラーが発生しない限り、スレーブはサイレント(アイドル)マスターとクラッシュしたマスターの違いを区別できないので、スレーブがデフォルトになるまでTCP接続はオンラインのままですTCPタイムアウトに達しました。

私の箱では、これがデフォルトでした

[root@db1 ~]# sysctl -e net.ipv4.tcp_keepalive_time
net.ipv4.tcp_keepalive_time = 7200

だから私はそれを整理しました

echo 30 > /proc/sys/net/ipv4/tcp_keepalive_time
echo 2 > /proc/sys/net/ipv4/tcp_keepalive_probes
echo 1 > /proc/sys/net/ipv4/tcp_keepalive_intvl

これにより、30秒ごとにSYNパッケージが送信され、接続がまだ応答しているかどうかが確認され、同期が早く開始されます。 MySQLプロセスを再起動してソケットを再度開くことを忘れないでください。再起動後も設定が保持されるように、それをrcスクリプトに追加してください。

このためにTweakにはたくさんのつまみがあるので、この件に関する詳細情報が記載されたURLを次に示します。 http://dom.as/2006/09/12/mysql-tcp-network-tuning/

これを設定する方法に興味がある場合は、こちらをお読みください。 http://mute.nu/2012/how-to-set-up-a-2-node-Apache-and-mysql-fail-over-environment/

つまり、全体として、MySQLデータディレクトリをXFSに配置し、TCPキープアライブ設定を微調整すれば、すべて完了です。

3
Lars

レプリケーションとバイナリロギングはinnodbとは独立して行われるため、残念ながら問題が発生する可能性があります。

チェックアウト: http://dev.mysql.com/doc/refman/5.5/en/replication-options-binary-log.html#sysvar_sync_binlog

あなたの説明から、サーバーのsync_binlogが0に設定されていると思います。 0のままにしておくと、mysqlがファイルシステムに依存してディスクへのフラッシュを処理します。これは事実上、binlogデータがファイルシステムのキャッシュにあることが多いことを意味します。これは、一定の間隔でカーネルによってディスクにフラッシュされますが、停電の場合、そこにあるものはすべて失われます。

Sync_binlogを1に設定すると、mysqlはコミットのたびにfdatasyncを使用してbinlogイベントをファイルシステムにフラッシュします。これは安全です(停電の場合、最大で1つのトランザクションが失われるため)が、より多くのディスクアクティビティが作成されます。ベンチマークを行い、ワークロードへの影響を確認します。両方のシナリオのトレードオフを知ることで、情報に基づいた決定を下すことができます。

お役に立てば幸いです。

3
drogart

これを実行し、STOP/START SLAVEの必要性を排除する変更を確認します。

'slave%'のような変数を表示します。

0
Rick James