web-dev-qa-db-ja.com

MySQLレプリケーション-スレーブは継続的にマスターに遅れています

MySQL-5.1.50をマスター/スレーブレプリケーション設定で使用しています。

ほとんどの場合、スレーブはマスターより遅れています。

show processlist;を実行しても、時間がかかっているクエリはありません。 slow_logも有効にしました。ただし、実行速度の遅いクエリは検出されません。

スレーブはレプリケーションがマスターより数秒遅れていることを警告し続けています。時々、遅延時間が増加します。

問題の原因を診断するにはどうすればよいですか?

この問題が過去20日間続いているため、緊急のサポートが必要です。

12
adeela sahar

Seconds_Behind_Masterは、タイムトラベルを介して過去を表示するようなものです。

次のように考えてください。

  • 太陽は地球から93,000,000マイル離れています
  • 光速は186,000マイル/秒です
  • 単純な除算は、太陽の光が地球に到達するまでに約500秒(8分20秒)かかることを示しています
  • 太陽を見ると、実際には太陽は見えません。 8分20秒前の場所がわかります。

同様に、マスターは多くのクエリを同時に処理しているようです。

スレーブを振り返ってSHOW SLAVE STATUS\Gを実行すると、Seconds_Behind_Masterに対して200と表示されます。その数はどのように計算されますか? スレーブのクロック時間(UNIX_TIMESTAMP(NOW())-クエリが完了し、マスターのバイナリログに記録されたときのクエリのタイムスタンプ

Seconds_Behind_Master以外に、確認するべき別のメトリックがあります。そのメトリックはRelay_Log_Spaceと呼ばれます。これは、スレーブ上のすべてのリレーファイルのすべてのバイトの合計を表します。デフォルトでは、最大の単一リレーログは1GBに制限されています。 Relay_Log_Spaceが1GB未満の場合は、長時間実行されている多くのクエリがマスターで並列に実行されていることを示しています。残念ながら、シングルスレッドの性質を持つReplicationのSQLスレッドにより、クエリは順番に実行されます。

たとえば、マスターに次のシナリオがあるとします。

  • スロークエリログが有効になっています
  • マスターで並列に実行される20のクエリ
  • 各クエリに3秒かかりました
  • 各クエリは、同じタイムスタンプでマスターバイナリログに記録されます。

スレーブがそれらのクエリをリレーログから読み取り、それらを1つずつ処理するとき

  • 奴隷の時計が動きます
  • 20個のクエリのそれぞれのタイムスタンプは同じになります
  • 差は3秒増加し、クエリが完了します
  • この結果、Seconds_Behind_Masterは60秒になります

スローログに関しては、 long_query_time のデフォルトは10秒です。リレーログ内のすべてのクエリが10秒未満の場合、スロークエリログでは何もキャッチされません。

マスターサーバーとスレーブサーバーの両方に次の推奨事項があります

さらにトラブルシューティング

レプリケーションラグの原因となっているクエリを確認するには、次の操作を行います。

  • SHOW SLAVE STATUS\G
  • リレーログの名前をRelay_Log_Fileから取得します
  • STOP SLAVE;
  • START SLAVE;
  • OSでは、cd /var/lib/mysqlまたはリレーログが書き込まれる場所
  • リレーログをテキストファイルにダンプする

たとえば、SHOW SLAVE STATUS\Gをやってみましょう

               Slave_IO_State: Waiting for master to send event
                  Master_Host: 10.64.51.149
                  Master_User: replicant
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000009
          Read_Master_Log_Pos: 1024035856
               Relay_Log_File: relay-bin.000030
                Relay_Log_Pos: 794732078
        Relay_Master_Log_File: mysql-bin.000009
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB: search_cache
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 1024035856
              Relay_Log_Space: 794732271
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 106451149

STOP SLAVE; START SLAVE;を実行すると、リレーログが閉じ、新しいログが開きます。それでも、relay-bin.000030が必要です。

次のように内容をダンプします。

cd /var/lib/mysql
mysqlbinlog relay-bin.000030 > /root/RelayLogQueries.txt
less /root/RelayLogQueries.txt

これで、スレーブが現在処理しようとしているクエリを確認できます。これらのクエリをチューニングの開始点として使用できます。

20
RolandoMySQLDBA

どのバイナリログ形式を使用していますか? ROWまたはSTATEMENTを使用していますか?
"_SHOW GLOBAL VARIABLES LIKE 'binlog_format';_"

ROWをバイナリログ形式として使用している場合は、すべてのテーブルに主キーまたは一意キーがあることを確認してください。
SELECT t.table_schema,t.table_name,engine FROM information_schema.tables t INNER JOIN information_schema .columns c on t.table_schema=c.table_schema and t.table_name=c.table_name and t.table_schema not in ('performance_schema','information_schema','mysql') GROUP BY t.table_schema,t.table_name HAVING sum(if(column_key in ('PRI','UNI'), 1,0)) =0;

あなたが実行した場合マスターで1つの削除ステートメントを使用して、PKまたは一意のキーなしでテーブルの100万レコードを削除すると、マスター側で1回の全テーブルスキャンのみが実行されますが、スレーブではそうではありません。
ROW binlog_formatが使用されている場合、MySQLは行の変更をバイナリログに(STATEMENT binlog_formatのようなステートメントとしてではなく)書き込み、その変更はスレーブの行ごとに適用されます。テーブルスキャンはスレーブ上で行われ、マスター上の1つの削除ステートメントのみを反映するため、スレーブラグの問題が発生しています。

2
Moll

SHOW SLAVE STATUSのseconds_behind_master値は、イベントが最初に実行されてバイナリログに記録されたときに保存されたマスターのシステム時間と、イベントがそこで実行されたときのスレーブのシステム時間の差です。

2つのシステムのクロックが同期していない場合、マスターの2秒後に誤った値が表示されます。

0