web-dev-qa-db-ja.com

MySQLスレーブがほとんどの場合「システムロック」でスタックし、CPU使用率が高い

私たちが今直面していることを説明しましょう:

MySQLマスター-スレーブ、行ベースのレプリケーションのセットアップがあり、現時点では、スレーブは永続的なSystem Lockで動かなくなっています。マスターは、多くのupdatesおよびdeletesが実行されているアクティブなサーバーですが、スレーブは何も複製しません。ログにエラーはなく、スレーブはマスターからバイナリログを正常に読み取っていますが、スレーブでは何もしません。 Seconds_Behind_Master値は増加し続けます。スレーブショーのshow processlistは次のとおりです。

mysql> show processlist ;
+----+-------------+-----------+------+---------+-------+----------------------------------+------------------+
| Id | User        | Host      | db   | Command | Time  | State                            | Info             |
+----+-------------+-----------+------+---------+-------+----------------------------------+------------------+
| 10 | system user |           | NULL | Connect |  4985 | Waiting for master to send event | NULL             |
| 11 | system user |           | NULL | Connect | 53715 | System lock                      | NULL             |
| 14 | root        | localhost | NULL | Sleep   |  2958 |                                  | NULL             |
| 16 | root        | localhost | NULL | Query   |     0 | init                             | show processlist |
+----+-------------+-----------+------+---------+-------+----------------------------------+------------------+
4 rows in set (0.00 sec)

そしてshow slave statusは以下を示します:

SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: System lock

人生の唯一の兆候は、スレーブステータスからのRelay_Log_Posが値を変更しているが非常にゆっくりであることです。それはバイナリログからクエリを実行しているという意味ですか、それでも遅すぎるということですか?

show engine innodb statusからの情報を貼り付けています:

LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 0, not started
MySQL thread id 14, OS thread handle 0x7f7824698700, query id 216193 localhost root init
show engine innodb status
---TRANSACTION 230426904, not started
mysql tables in use 1638, locked 1638
MySQL thread id 11, OS thread handle 0x7f7824920700, query id 216192 System lock
--------
FILE I/O
--------
I/O thread 0 state: waiting for completed aio requests (insert buffer thread)
I/O thread 1 state: waiting for completed aio requests (log thread)
I/O thread 2 state: waiting for completed aio requests (read thread)
I/O thread 3 state: waiting for completed aio requests (read thread)
I/O thread 4 state: waiting for completed aio requests (read thread)

この特定のmysqlインスタンスのmysqldプロセスのCPU使用率が高いことにも注意してください。何がSlave_SQL_Running_State: System lockを引き起こし、スレーブがクエリを実行するのを妨げているのでしょうか?マシンにディスクの問題はなく、同じマスター上の別のMySQLインスタンス(myisam)のスレーブである別のMySQLインスタンスが実行されており、正常に実行されています。

MySQLバージョン:5.6.20。 OS:RHEL 6.5パーティション分割されたテーブルがあります(重要な場合)。

編集:Slave_SQL_Running_Stateが「リレーログからのイベントの読み取り」に変更される場合があることに注意してください。そのため、レプリケーションが遅すぎるようです。

6
Sree

最初に理解する必要があります。これに対する特定の解決策はありません。

したがって、質問で提供された情報によると、何が良いですか:

  1. リレーログの位置は変化し続けるとのことですが、これは「SQLスレッド」が機能していることを意味します

  2. Slave_SQL_Running_Stateも変更されているとのことですが、これはI/Oスレッドも機能していることを意味します。

    悪い点は、「リレーログスペースが増加している」ことです。これは、データが来ているが実行に時間がかかることを意味します。

ここにもっと住もう:

  1. あなたもマスターの遅さを観察していますか?マスターで遅いクエリはありますか?答えが「いいえ」の場合、2に進みます。

  2. 両方のサーバーの構成は同じですか?これでは、mysqlバッファープールの構成と分離方法を確認する必要があります。私は個人的に、分離レベルが原因である可能性があることも経験しています(MySQLではデフォルトで反復可能な読み取り)同じ場合は、3に進みます。

  3. 速度低下が観察されたときに実行されているクエリを確認しましたか?ページャーgrepクエリの後にshow processlistを実行するだけです。

これにより、何がスタックしているのかがわかります。中に入って、リレーログの位置を確認し、クエリが何であるかをリレーログで確認して、最適化してみましょう。ただし、その前に、パフォーマンスが本当に遅いかどうかを確認してください。

パフォーマンススキーマデータベースを使用し、このデータベースで、SQL、IO、レプリケーション用の計測器を有効にして、このリンクを利用することができます: https://dev.mysql.com/doc/refman/5.7/en/performance -schema-replication-tables.html

これとは別に、SYSスキーマを使用して問題の原因を診断することもできます。

ローランドが言ったことは原因の1つであり、彼は正しい。ロードファイルは一般にこの問題を引き起こす可能性があります。

私が意味をなすかどうか教えてください:)

2
Ankit Kapoor

2013年1月に、スレッドの状態「システムロック」に関する質問に回答しました。 mysqlがLOAD DATA INFILEステートメントをプロファイリングする際の「システムロック」とはどういう意味ですか?

ここで何が起こっている可能性があります、に従ってください

私の古い投稿 では、私は以下を育てました

スレッドは、テーブルの内部または外部システムロックを要求するか、または待機しています。この状態の原因が外部ロックのリクエストであり、同じMyISAMテーブルにアクセスしている複数のmysqldサーバーを使用していない場合は、-skip-external-lockingオプションを使用して外部システムロックを無効にできます。ただし、外部ロックはデフォルトで無効になっているため、このオプションは効果がない可能性があります。 SHOW PROFILEの場合、この状態は、スレッドがロックを要求している(それを待っていない)ことを意味します。

これはSQLスレッドで発生しているため、テーブルまたはテーブル内の行をロックする必要があるクエリがあることを意味します。ロックはまだ取得されていないため、SHOW PROCESSLIST;のSQLスレッドのINFOフィールドにクエリは表示されません。次の論理的な質問は、「クエリまたは少なくともロックをどのように見ることができるか」です。

SHOW ENGINE INNODB STATUS\Gを実行すると、ロックが表示されました。ただし、ロックしているテーブルは表示されません。 私の古い投稿 に基づいて、LOAD DATA INFILEがマスターで実行されてからスレーブに複製されたと思います。スレーブのテーブルをロックする必要があるのはなぜですか?

これは、MySQLがLOAD DATA INFILEを複製する方法に大きく関係しています。コマンドは、バイナリログだけでなく、データファイル全体にも複製されます。 MySQLがどのように実行するかを正確に説明した古い投稿があります。

LOAD DATA INFILEが急降下しているので、テーブルをロックし、リレーログからCSVファイルを具体化し、LOAD DATA INFILEを実行するリクエストを想定できます。全体のサイクルの間、太陽の下でターゲットテーブルにアクセスしようとしているものはありません。したがって、System Lockが発生する必要があります。

これに照らして、ログにエラーがなく、スレーブがマスターからバイナリログを読み取り、スレーブで何もせず、Seconds_Behind_Master値が増加し続けることは、世界中で理にかなっています。

UPDATE 2014-10-24 12:55 EST

分割テーブルについて言及しました。開いているファイルハンドルの数を確認する必要があります。グローバルステータス変数 open_files および Innodb_num_open_files を確認します。システムロック中にこれらが上昇している場合は、テーブルがロックされている必要があります。すべてのパーティションのファイルハンドルを開き、ロックし、場合によってはキャッシュする必要があります。

1
RolandoMySQLDBA