web-dev-qa-db-ja.com

MySQLを適切に殺すには?

CPanelがインストールされたCentOS 64ビットを使用しています。

service mysql stop

それは時を刻むだけで、止まるようなことはありません。ログにはそれがたくさん投稿されます:

130303 17:42:38 [Warning] /usr/sbin/mysqld: Forcing close of thread

の中に err.logファイル、私はこれらの多くを見ます:

[Warning] /usr/sbin/mysqld: Forcing close of thread

以前はインスタントでした。それがなぜそれを行うのか、そしてどのように修正するのか?

今私はしなければなりませんkillall -9 mysqlしかし、もっと良い方法はありますか?

サーバーも非常にアクティブです。

これは構成の問題ですか?メモリの設定が高すぎますか?

[mysqld]
default-storage-engine=MyISAM
local-infile=0
symbolic-links=0
skip-networking
max_connections = 500
max_user_connections = 20
key_buffer = 512M
myisam_sort_buffer_size = 64M
join_buffer_size = 64M
read_buffer_size = 12M
sort_buffer_size = 12M
read_rnd_buffer_size = 12M
table_cache = 2048
thread_cache_size = 16K
wait_timeout = 30
connect_timeout = 15
tmp_table_size = 64M
max_heap_table_size = 64M
max_allowed_packet = 64M
max_connect_errors = 10
query_cache_limit = 1M
query_cache_size = 64M
query_cache_type = 1
low_priority_updates=1
concurrent_insert=ALWAYS
log-error=/var/log/mysql/error.log
tmpdir=/home/mysqltmp
myisam_repair_threads=4
[mysqld_safe]
open_files_limit = 8192
log-error=/var/log/mysql/error.log

[mysqldump]
quick
max_allowed_packet = 512M

[myisamchk]
key_buffer = 64M
sort_buffer = 64M
read_buffer = 16M
write_buffer = 16M
31
Tiffany Walker

Mysqlをシャットダウンする最も洗練された方法は、それを実行することです

mysqladmin -uroot -p -h127.0.0.1 --protocol=tcp shutdown

理由は次のとおりです。

Mysqlサービスファイル(/etc/init.d/mysql)は、ソケットファイルの存在に依存しています。歴史的に言えば、MySQL 4.0に戻ると、ソケットファイルが不可解に消えることがあります。これにより、標準のservice mysql stopが機能しなくなります。

言うだけでは不十分

mysqladmin -uroot -p -h127.0.0.1 shutdown

tCP/IPが明示的に有効にされていない場合、mysqldは[email protected]として着信するユーザーをroot@localhostにルーティングするためです。デフォルトでは、mysqldは抵抗の最小パスを選択し、ソケットファイルを介して[email protected]root@localhostに接続します。ただし、ソケットファイルがない場合、root@localhostは接続しません。

MySQLのmysqladmin でさえ、これはこう言っています:

Unixソケットファイルを使用してローカルサーバーに接続するときにmysqladmin shutdownを実行すると、mysqladminはサーバーのプロセスIDファイルが削除されるまで待機して、サーバーが適切に停止するようにします。

そのため、TCP/IPを有効にすることが不可欠です。

mysqladmin -uroot -p -h127.0.0.1 --protocol=tcp shutdown

2011年9月30日に戻って、mysqlserviceという名前の独自のバージョンのmysqld_multiをスクリプト化しました(私の投稿を参照してください 同じホストでの複数のインスタンスの実行 )。異なるポートからmysqldに接続するための仮想エンジンとして機能します。カスタマイズしたパラメータを使用して、独自のmy.cnfを用意する必要があります。このスクリプトでは、次のようにシャットダウンを発行します。

stop() {
  ${ECHO} -n $"Stopping ${PROGNAME}"
  ${MYSQLD_STOP}
  ATTEMPTS=0
  STOPPING_MYSQLD=1
  MINUTES_TO_TRY=10
  (( TICKS_TO_TRY = MINUTES_TO_TRY*240 ))
  while [ ${STOPPING_MYSQLD} -eq 1 ]
  do
    ${ECHO} -n "."
    ${SLEEP} 0.25
    MYSQLD_HAS_BEEN_SHUTDOWN=`${TAIL} ${MYSQL_ERROR_LOG} | ${GREP} -c "Shutdown complete$"`
    (( ATTEMPTS++ ))
    if [ ${ATTEMPTS} -eq ${TICKS_TO_TRY}   ] ; then STOPPING_MYSQLD=0 ; fi
    if [ ${MYSQLD_HAS_BEEN_SHUTDOWN} -eq 1 ] ; then STOPPING_MYSQLD=2 ; fi
  done
  ${ECHO}
  if [ ${STOPPING_MYSQLD} -eq 2 ]
  then
    ${ECHO} "Stopped ${PROGNAME}"
  else
    ${TAIL} -30 ${MYSQL_ERROR_LOG}
  fi
}

しかし、${MYSQLD_STOP}とは何ですか?

MYSQL_CONN="-uroot -p<rootpassword> -P${MYSQLD_PORT} -h127.0.0.1 --protocol=tcp"
MYSQLD_STOP="${MYSQLADMIN} ${MYSQL_CONN} shutdown"

私が127.0.0.1と明示的なポートを使用していることに注意してください。そうすれば、ソケットファイルに依存しません。

私は常にmysqladmin --protocol=tcp shtudownがハングした場合のmysqlのシャットダウンの適切な代替手段としてservice mysql stopを使用してきました。 mysqldおよびkill -9mysqld_safeを実行すると、最後の手段の最後の手段になります。 (はい、私は最後の3回言った)。

多くの場合、mysqldは警告なしにmysql.sockを削除しました。他の人々も長年にわたってこの問題を抱えています:

エピローグ

秘密は私が述べたとおりです: mysqladmin を使用してTCP/IP経由でmysqlに接続します(--protocol=tcp)およびshutdownを発行します。 shutdown privilege が認証されたシャットダウン専用のmysql.userにあるため、これは機能する必要があります。これにより、Linuxサーバーでmysqldをシャットダウンするときに、Windowsマシンからリモートシャットダウンを発行できるようになったときに、勤務時間が節約されました。

2013-03-06 22:48 EST更新

シャットダウン中に何が起こっているのか心配な場合は、シャットダウン時間を操作する方法と、特にバッファープールに大量のInnoDBデータがある場合に、データをディスクにフラッシュする方法があります。

提案#1

ダーティページが多い場合は、 innodb_max_dirty_pages_pct を0に下げることができます。

SET GLOBAL innodb_max_dirty_pages_pct = 0;

これをシャットダウンの約15〜30分前に設定します。これにより、mysqldにディスクに書き込むダーティページの最小量が与えられます。

提案#2

デフォルトでは、 innodb_fast_shutdown は1です。このオプションには3つの値があります

  • 0:InnoDBは、シャットダウンする前に、遅いシャットダウン、完全なパージ、および挿入バッファーのマージを行います。
  • 1:InnoDBは、高速シャットダウンと呼ばれるプロセスであるシャットダウン時にこれらの操作をスキップします。
  • 2:MySQLがクラッシュしたかのように、InnoDBがログをフラッシュし、コールドシャットダウンします。コミットされたトランザクションは失われませんが、クラッシュリカバリ操作により、次の起動に時間がかかります。

ドキュメントはさらにこれを言います:

シャットダウンが遅いと、かなりの量のデータがまだバッファリングされている極端なケースでは数分、場合によっては数時間かかることがあります。 MySQLメジャーリリース間でアップグレードまたはダウングレードする前にスローシャットダウン手法を使用して、アップグレードプロセスでファイル形式が更新された場合に備えて、すべてのデータファイルが完全に準備されるようにします。

緊急事態またはトラブルシューティングの状況でinnodb_fast_shutdown = 2を使用して、データが破損するリスクがある場合に、最速のシャットダウンを実現します。

ほとんどの場合、innodb_max_dirty_pages_pctとinnodb_fast_shutdownのデフォルトで十分です。

38
RolandoMySQLDBA

MySQLを「どのように」シャットダウンするかについての質問ではなく、なぜシャットダウンが遅いのかについての質問のようです。

同様の質問に対する私の答え で、スムーズな再起動のためのいくつかの提案を提供しました。これは、MySQLの開始を要求した後に発生する必要があるアクティビティの量を減らすのに役立ちます シャットダウンプロセス

SHOW FULL PROCESSLIST;を頻繁に使用していない場合、これは項目1です。これは、シャットダウンが非常に遅くなっているサーバーで何が起こっているのかを把握する必要があるためです。中断しても安全な実行時間の長いクエリがある場合は、KILL <thread-id>を使用してそれらを強制終了できます。

他の提案の要約:

グローバル変数innodb_fast_shutdown = 1(デフォルト)を設定すると、シャットダウンのInnoDBの部分が高速化されます。ただし、これはonly安全ですが、アップグレードの実行とは無関係の理由でサーバーをシャットダウンする場合は安全です。アップグレードのためにシャットダウンする場合は、これを0に設定する必要があります

FLUSH TABLES;を使用すると、開いているすべてのテーブルが適切に閉じられます。後続のクエリで参照された場合は再開されますが、シャットダウンを要求してからシャットダウンが完了するまでの経過時間は最終的に短縮されます。これは、初期のハウスキーピングを実行し、さらに重要なことにステージを設定するためです。最後のステップのために...

FLUSH TABLES WITH READ LOCK;は、開いているすべてのテーブルを閉じ、現在のクライアント接続が所有する排他ロックを取得します。これにより、他の接続がサーバー全体のテーブルに書き込むことができなくなります。このロックを所有するまでmysql>プロンプトは表示されません。この時点でシャットダウンリクエストを発行できますが、このセッションから切断しないでください。

ビジー状態のサーバーでは、これらの手順によりサーバーでのアクティビティのレベルが低下し、物事がより静かになり、シャットダウンまたは再起動がよりスムーズに行われるようになります。

5

MySQLは純粋にロックアップされていない可能性がありますが、シャットダウン時にクリーンアップアクティビティ(ロールバックなど)を実行しています。シャットダウン時にそれをすべて行わせない場合、起動時に待たなければならないことがよくあります。

次の点に注意してください。あるターミナルウィンドウでmysqlをシャットダウンし、別のターミナルウィンドウでエラーログ(tail -f [yourerror.log])を監視します。エラーログには、MySQLの動作が表示されます。

私はあなたの経験を聞いて申し訳ありません。これと同様の愚かなMySQLシナリオでの私の経験があなたを助けることができることを願っています。

MySQLサービスをサーバーから終了する方法を理解する代わりに、場合によっては、次の方法でシステムの状態をチェックして、サービスの悪用があるかどうかを判断する必要があります(仮定はCentOS/RHEL環境の概念に基づいています):

 /usr/bin/iostat
 /usr/bin/uptime
 top -c

以下を使用して、平均システム負荷とシステム内で最も消費されているリソースを特定します。

システムで処理されているSQLステートメントの全体像を取得するには、mytopもインストールする必要があります。

mytopをインストールするには、次の手順を実行するだけです。

 cd /root
 wget http://jeremy.zawodny.com/mysql/mytop/mytop-1.6.tar.gz
 tar -zxvf /root/mytop-1.6.tar.gz
 cd /root/mytop-1.6
 Perl Makefile.pl
 make
 make install
 chmod 644 /usr/local/bin/mytop
 vi /usr/local/bin/mytop 

(お好みのテキストエディタを使用してください)

"long|!" => \$config{long_nums}を検索

#"long|!" => \$config{long_nums}としてコメント化します。

chmod 555 /usr/local/bin/mytop

そして、あなたはmytopで行くのが良いです。これを使用して、MySQLサービスを占有しているMySQLステートメントをチェックして停止します。

上記の手順を実行すると、次の機能が提供されます。

  • サーバーのステータス/正常性の診断
  • ボトルネックの原因の診断

ボトルネックの原因を取り除いた後は、MySQLサービスを再起動しようとすると、より簡単な日がくるはずです。上記の情報がお役に立てば幸いです。

注:mytopは古く、メンテナンスされていません。最近のシステムでは、おそらくinnotopを使用する必要があります。

1
Michael Feng

MySQLのinit-scriptの標準実装は、SIGTERMを使用してMySQLに信号を送り、MySQLがシャットダウンするまで一定の時間待機します。

MySQLは、SIGTERMを受け取った後、最初に新しい接続の受け取りを停止し、保留中のクエリの実行を完了します(これは、ワークロードと同時クライアントの数によっては時間がかかる場合があります)。次に、ディスクへのデータのフラッシュを開始します(これには時間がかかる場合があります)ワークロード、構成、使用可能なメモリ、およびストレージエンジンの選択に応じて、長時間かかります。データのフラッシュがすべて完了すると、MySQLは初期化段階で割り当てたメモリの割り当てを解除し(MySQLによって割り当てられたメモリの量によっては、これにも時間がかかる場合があります)、開いているすべてのファイルハンドルを閉じてから呼び出します「exit(0)」。

シャットダウンのリクエスト後、MySQLのシャットダウンに時間がかかる場合、このステージの1つ以上が完了するまでに長い時間がかかる可能性があります。時間がある場合は、プロセスが完了するのを待つことを強くお勧めします(これにより、データベースインスタンスを再び起動したときのデータ損失や長時間の回復プロセスを回避できます)。

残念ながら、質問に十分な情報がないため、問題の適切な解決策を提案できません。これが問題の理解に役立つことを願っています。

0
LMC