web-dev-qa-db-ja.com

mysqldumpを安全に停止する方法

私(まあ、私のcronスクリプト)はkillall mysqldumpを試してみましたが、うまくいきませんでした-mysqlサーバーがしばらくして接続の受け入れを停止しました。

mysql 5.5.55-0+deb8u1を備えたDebian Jessieマシンでした。

使用シナリオは次のとおりです。

  • 長時間(数時間)SELECTクエリがありましたが、これは本当に遅いか、それを送信したクライアントに問題がありました(クエリの状態はSending data)。他のすべてのクエリは問題なく来ていました。と行く(おそらく負荷が少しだけ高かった)。

  • 夜にmysqldump --max_allowed_packet=2147483648 --hex-blob --single-transaction --master-data --routines --order-by-primary --databases db1 db2 db3... | pigz -p8 > backup.sql.gzでバックアップが実行されていました。おそらく、上記のSELECTが最初に終了するのを待っていたため、終了しませんでした(ここで推測すると、通常とは異なる外観で、何ヶ月も同じ設定で問題なく動作しました)。

  • 午前中にcronジョブが実行され、killall -q mysqldumpが設定された時間までにバックアップが終了しなかった場合にバックアップを安全に終了するはずでした(後で問題を調査して修正するよう管理者に通知します)。 mysqlサーバーは通常。

  • ただし、結果は完全な接続テーブルであり、ユーザーはmysqlサーバーにログインできませんでした。 FLUSH /*!40101 LOCAL */ TABLESクエリがWaiting for table flushでスタックし、何百ものSELECTクエリが同じWaiting for table flush状態でスタックしました。

  • さらに、他のSELECTクエリがLOCK TABLESに残っているため、Waiting for table flush mysqlクエリを管理者が強制終了しても役に立たなかった(これは 意図された動作? のようです)

Mysqlサーバーを再起動すると、最終的に問題が「修正」されました。ただし、この状況(および緊急の管理者介入)の繰り返しを回避したいので、安全にDebian Jessie mysql-5.5.55のmysqldumpバックアップを終了します(または今後のDebian Stretch mariadb-10.1.23-8)。方法はありますか?

そうでない場合、mysqlバックアップを実行し、午前中にサーバーの負荷を回避するためのその他のオプションは何ですか(これは-この場合-サーバーが完全にハングしているのとほぼ同じくらい悪い)。

(可能な限り、Debian Stableパッケージを使い続けたいです)

1
Matija Nalis

@Mannojが示唆しているように、私は単純な「killall -q mysqldump」を問題を解決するよりスマートなバージョンに置き換えました。状態が「テーブルフラッシュを待機しています」で4時間以上前のすべてのクエリを探し、それらを強制終了します(そして、問題を翌日にデバッグできるようにプロセスリストを生成します)。

私はそれをcron(8)から2回呼び出します:

  • 午後11時-バックアップを開始する直前(そのため、長時間実行中のSELECTがまだ実行されていても、バックアップは実際に開始されます)
  • 午前7時、「ハード」引数-人々が仕事に取り掛かる直前(誰も接続できない場合に備えてmysqlサーバーを再起動するため)
#!/ bin/sh 
 killall -q mysqldump 
 sleep 3 
 mysql -BNe 'show processlist' |\
 Perl -nE '($ id、$ u、$ h、$ db、$ cmd、$ time、$ state、$ info)= split/\ t /; 
 if(($ time> 4 * 3600)and($ cmd =〜/ Query /)){
 $ found ++; 「プロセスリストを表示」と言います。 
 if($ found == 1); 「$ idを殺す」と言う
}; ' | mysql -v 
 
 if ["$ 1" = "hard"] 
 then 
 sleep 30 
 mysql -BNe 'show processlist' | grep -q 'Query。* show processlist' || /etc/init.d/mysql restart 
 fi 
 
0
Matija Nalis

--master_dataを使用して、マスターステータスの一貫した値を取得しているため。

Mysqldumpの内部は、以下のコマンドをmysqlサーバーに発行します。

2017-05-31T04:39:05.843130Z    48 Query /*!40100 SET @@SQL_MODE='' */
2017-05-31T04:39:05.843273Z    48 Query /*!40103 SET TIME_ZONE='+00:00' */
2017-05-31T04:39:05.843411Z    48 Query FLUSH /*!40101 LOCAL */ TABLES
2017-05-31T04:39:05.846031Z    48 Query FLUSH TABLES WITH READ LOCK
2017-05-31T04:39:05.846166Z    48 Query SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ
2017-05-31T04:39:05.846279Z    48 Query START TRANSACTION /*!40100 WITH CONSISTENT SNAPSHOT */
2017-05-31T04:39:05.846413Z    48 Query SHOW MASTER STATUS
2017-05-31T04:39:05.846539Z    48 Query UNLOCK TABLES
..
..... Here it continues to take backup of data and structures .

何が起こったのですか?:

バックアップが開始されたばかりで、特定のテーブルで実行されていたクエリがFLUSH TABLESコマンドでさえ実行される前に長時間実行され、テーブルのロックが解除されなかったため、FLUSH TABLESそのスレッドが完了するのを待つか、そのテーブルのrevision_versionがすべてのテーブルと同じになるまでフラッシュを続けます。

したがって、他のスレッドも他のテーブルに対してブロックされます。これは、テーブルのフラッシュが行われている間、DB * .Tables *レベルのロック全体であるためです。最後に、すべての新しい接続がプロセスリストに蓄積され、max_connectionsまで蓄積され、誰もログインできないようにします。

ターミナルにログインしてフラッシュテーブルを強制終了しようとした場合、フラッシュされたテーブルをプルバックまたはロールバックして、独自のスレッド接続を解放する方法はないと思います。そのため、より長い時間KILLED STATEになる可能性があります。したがって、サーバーを再起動するという最後のオプションに達している可能性があります。

修正方法::

問題の時点​​で、管理者がmysqlプロンプトにログインできたとき。

FLUSH TABLESスレッドでkillコマンドを発行する代わりに、長いSELECTを実行しているスレッドにkillが指定された場合。新しいクエリのロック。そしてバックアップは継続されたでしょう。長い時間実行されているクエリの結果を待っている相手側で回答を期待している人はいないと思います。

長期的な解決策は何ですか?:

  • バックアップ時にそのような長時間のクエリが実行されないようにする必要があります。

  • これは新しい展開の可能性があるか、誰かが不正なクエリをトリガーしてセッションを閉じようとしませんでした。

  • クエリがXsecsより多く実行されている場合は、クエリを強制終了してみてください(要件によって異なります)。または

  • チームと調整して、クエリを調整するか、管理者に送信して結果データを提供するか、個別のスレーブをまとめて提供します。
1
Mannoj

コメントのレピュテーション制限のため、テストするには2つのオプションがあると思います。mysqldumpを安全に停止することは、この問題を解決する良い方法ではないと思います。

max_allowed_packet

最近、データベースが突然大きくなっていますか?

許可されている2Gを示しています。

2Gを超えるデータの場合、プロセスがハングします。

ロックなしのテーブルヒントなし

あなたが試すことができます --lock-tables=falseまたはskip-add-locks in my.cnfロックされたテーブルを無効にします。

0
Su Jun-Ming