web-dev-qa-db-ja.com

MySQLレプリケーションはlog_slave_updatesで遅れています

私はこのトポロジでレプリケーションをセットアップしている最中です:

   /--B
A-
   \--C--D

これを実現するには、Cでlog_slave_updatesを有効にする必要があるため、DもAから変更を取得します。

Cはかなり頑丈なサーバーです。 Amazon EC2ベース。 32コア、250GBメモリ、20000 IOPSデータボリューム。 Aよりも強力で、メインディスクのCPUパワー、メモリ、3200 IOPSが少なくなっています。

Cでlog_slave_updatesをオンにするとすぐに、ほぼすぐにAに遅れをとります。これは、パフォーマンスが簡単に期待できるため、私には奇妙です。私の頭の中でlog_slave_updatesは、ログをディスクに書き込んでいるだけです。

これのデバッグをどこから始めればよいかわかりません。

編集フォローアップの質問をありがとう、ここにもう少し情報を追加しました:

確かにスナップショットからEBSボリュームを作成しましたが、ddを使用してすべてのバイトを読み取ることでウォームアップしましたが、これには数日かかりました。

SELECT @@INNODB_FLUSH_LOG_AT_TRX_COMMIT, @@SYNC_BINLOG\Gの出力は次のとおりです。

@@INNODB_FLUSH_LOG_AT_TRX_COMMIT: 2
@@SYNC_BINLOG: 1

これは、SHOW SLAVE STATUSを再びオンにしてから数分後のlog_slave_updatesの出力です。

               Slave_IO_State: Waiting for master to send event
                  Master_Host: anonimized
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.001253
          Read_Master_Log_Pos: 969363410
               Relay_Log_File: mysql-relay-bin.002984
                Relay_Log_Pos: 44865262
        Relay_Master_Log_File: mysql-bin.001253
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           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: 910276312
              Relay_Log_Space: 103952567
              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: 259
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: 1
                  Master_UUID: 8c7641ba-a380-11e5-a8ee-0e920570e8cb
             Master_Info_File: /mnt/mysql-data/database/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Reading event from the relay log
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 

log_slave_updatesがオンの場合のiostat -x:

Linux 4.4.0-53-generic (hostname)   01/07/2017      _x86_64_        (32 CPU)

avg-cpu:  %user   %Nice %system %iowait  %steal   %idle
           0.91    0.00    0.24    1.78    0.00   97.06

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
xvda              0.00    23.56    0.32   50.91    23.53   467.96    19.19     0.29    5.65    9.03    5.63   5.26  26.93
xvdf              0.00    61.33   93.76  163.17  9468.94  8128.52   136.98     1.14    4.44    8.68    2.00   1.89  48.48

log_slave_updatesがオフの場合のiostat -x:

Linux 4.4.0-53-generic (hostname)   01/07/2017      _x86_64_        (32 CPU)

avg-cpu:  %user   %Nice %system %iowait  %steal   %idle
           0.91    0.00    0.24    1.78    0.00   97.07

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
xvda              0.00    23.55    0.32   50.89    23.52   467.82    19.19     0.29    5.65    9.03    5.63   5.26  26.92
xvdf              0.00    61.60   93.71  163.54  9463.81  8131.70   136.79     1.14    4.43    8.68    2.00   1.88  48.48
3
Evert

最終的に、ディスクを追加する(ディスクを侵略する)ことや、Rolandoから提案されたすべての設定を変更しても役に立たないことがわかりました。

やったことの一つは:

sync_binlog=0

この設定により、mysqlはバイナリログをディスクにフラッシュせず、オペレーティングシステムにこの決定を行わせます。これはmysqlに許可するほど安全ではない可能性があるため、自己責任で使用してください。

連鎖レプリケーションを設定して移行するだけなので、これは素晴らしいソリューションです。一時的な方法です。

2
Evert

まず、SHOW SLAVE STATUS\Gに依存する必要があります

私の古い答えからサンプル表示を取ってみましょう: MySQL Replication Lag Behavingly Erraticly Behaving 。表示では、測定の複製を感じるのに役立つ項目に注意してください

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 10.17.20.102
                  Master_User: replicant
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.002814
          Read_Master_Log_Pos: 823078734
               Relay_Log_File: relay-bin.007364
                Relay_Log_Pos: 823078879
       Relay_Master_Log_File: mysql-bin.002814
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           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: 823078734
              Relay_Log_Space: 823079071
              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:
1 row in set (0.00 sec)

こちらが商品です

  • Seconds_Behind_Master:スレーブのOSの時間からスレーブで処理された最新のクエリのTIMESTAMPを引いた値に基づいて、スレーブからの秒数はマスターからの秒数です。
  • Relay_Log_Space:まだ処理されていないマスターからスレーブで収集された合計バイト数
  • Master_Log_FileRead_Master_Log_Pos):スレーブのリレーログに記録されるマスターからの最新のbinlogエントリ。
  • Relay_Master_Log_FileExec_Master_Log_Pos):スレーブで実行されるマスターからの最新のbinlogエントリ。

ラグは、次の1つ以上を観察することによってのみ測定できます。

  • Seconds_Behind_Masterは増え続けます
  • Master_Log_FileRelay_Master_Log_Fileは同じではありません(binlogイベントはSQLスレッドが処理できるよりも速く収集されています)
  • Exec_Master_Log_Posは、Slave_SQL_Running: Yesの場合でも移動しません(これは、クエリの実行時間が長くなるか、トランザクションが非常に大きくなる可能性があります)
  • Relay_Log_Spaceは着実に増加しています
    • 収集されたbinlogイベントの量を示します
    • これは、ネットワークを介したbinlogイベントの収集が遅いことを意味する場合があります

大規模なmysqldumpを取得して数時間後(1日後でも)にロードするため、ラグが増加することがあります。初めてレプリケーションを開始するとき、数秒(または1日)経過すると、秒単位の明らかな数値の遅れが消えます。

レプリケーション用のSQLスレッドは1つしかないことに注意してください。すべてのクエリは順次処理されます。これはレプリケーションラグにどのように影響しますか?

マスターが同じ秒に300の挿入、更新、削除を実行し、各クエリの実行に1秒かかったとします。これが実際に起こっていることです:

  • マスターのバイナリログに書き込まれると、すべてのクエリがシリアル化されます
  • スレーブはマスターからbinlogイベントを読み取りますONE AT A TIME !!!
  • スレーブは記録したbinlogイベントを実行しますONE AT A TIME !!!
  • Seconds_Behind_Masterは実際には300秒(5分)増加します
  • トランザクションの結果は膨大になる可能性があり、1つのトランザクションを構成するすべてのbinlogイベントがマスターのリレーログに完全に書き込まれるまで適用できないことに注意してください(これは通常、ROWベースのレプリケーションで発生する可能性があります)。これはラグの増加にもつながります。

MySQLレプリケーションラグについては何年にもわたって何度も話しました

最も規模の大きいスレーブでも、一度に1つのSQLトランザクションしか処理しません。最終的にそのようなサーバーにフェイルオーバーしてマスターに昇格させると、ビーフィーなマスターが意味をなすようになります。

結論として、スレーブが最終的に追いつくので、これらのことに注意してください。

更新2017-01-07 17:21 EST

これは私がオンにすることについて気になるものです log_slave_updates

リレーログとバイナリログは順番に書き込まれます。 InnoDBテーブルのテーブルスペースファイル(.ibd)はランダムな書き込みを経験します。順次書き込みとランダム書き込みが同じディスクで発生する場合、ランダム書き込みが順次書き込みのボトルネックになることは非常に確実です。

おそらく、リレーログとバイナリログをデータとは別のボリュームに保存すると、これらのログへの順次書き込みの速度が向上します。

DBA StackExchangeで、MySQLセットアップのログからデータを分割するFaceBook Engineerを8回参照しました。それらに関する私の投稿を参照してください。 。リレーログへの書き込みは必須であり、 log_slave_updates は影響を受ける傾向があるため、これは必須です。

これらの投稿では、InnoDBのチューニングもお勧めします。あなたの場合、私は以下を調整します:

MySQLインスタンスに複数のデータベースがある場合は、次のように設定します。

2
RolandoMySQLDBA