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


12

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

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

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

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

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

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


回答:


20

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

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

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

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

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

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

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

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

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

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

スローログに関しては、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

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


MySQLはv5.7から、マルチスレッド方式でスレーブに変更を適用できるようになりました。関連ドキュメントはここにあります:dev.mysql.com/doc/refman/5.7/en/replication-options-slave.html
edigu

2

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

ROWをbinlog形式として使用している場合は、すべてのテーブルに主キーまたは一意キーがあることを確認してください。
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つのdeleteステートメントを実行して、PKまたは一意のキーなしでテーブルの100万レコードを削除すると、マスター側で1つのフルテーブルスキャンのみが実行されますが、スレーブではそうではありません。
ROW binlog_formatが使用されている場合、MySQLは行の変更を(STATEMENT binlog_formatのようなステートメントとしてではなく)バイナリログに書き込み、その変更はスレーブの行ごとに適用されます。つまり、100万の全テーブルスキャンが行われます。スレーブでは、マスターで削除ステートメントを1つだけ反映する必要があり、それがスレーブラグの問題を引き起こしています。


0

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

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


MySQL 5.5以前では、レプリケーションイベントの実行はスレーブ側でシングルスレッド化されています。「システムユーザー」として実行されている「SHOW FULL PROCESSLIST」には2つのスレッドがあります。1つはマスターからイベントを受信し、もう1つはクエリを実行しています。スレーブが遅れている場合、そのスレッドは、現在実行されているクエリを表示する必要があります。それを見て、リソース不足のディスク/メモリ/ CPU統計も調べてください。
マイケル-sqlbot 2012
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.