過去4日間、毎晩の更新で大きな問題がありましたが、これらの4日間の間にすべてがうまくいった場合を除いて、.
これらの更新中に、いくつかのフルテキストインデックスを更新します。私はこのようにしています。
- フルテキストインデックスを削除する
- フルテキストテーブルを更新する
- フルテキストインデックスを追加する
これは2年以上完璧に機能しています。通常の更新時間は約3〜4時間で、毎晩更新されるデータ量としては正常でした。しかし、金曜日以降、実際の更新時間は9-12時間でした!
昨夜、サーバーがエンジンによって意図的にクラッシュしました。これはエラーログにありました
InnoDB:警告:長いセマフォ待機:-スレッド8676がdict0boot.ic行36で241.00秒間待機しましたセマフォ:0000000053B0C1E8のミューテックスがファイルdict0dict.cc行887を作成し、var 1待機者フラグ1 InnoDBをロックします:#### ## InnoDBモニターを30秒間起動して診断情報を出力します:InnoDB:保留中のプレアド0、pwrites 0
InnoDB:######診断情報が標準エラーストリームに出力されるInnoDB:エラー:セマフォの待機が600秒を超えたInnoDB:サーバーがハングしているように見えるため、意図的にサーバーをクラッシュさせます。 2014-07-21 05:20:54 1384 InnoDB:ファイルsrv0srv.cc行1748のスレッド4996でのアサーションエラー
InnoDB:意図的にメモリトラップを生成します。 InnoDB:詳細なバグレポートを http://bugs.mysql.com に送信してください。 InnoDB:mysqldの起動直後に、アサーションエラーまたはクラッシュが繰り返し発生する場合、InnoDB:でも、InnoDB:InnoDBテーブルスペースが破損している可能性があります。 InnoDBを参照してください: http://dev.mysql.com/doc/refman/5.6/en/forcing-innodb-recovery.html InnoDB:強制的なリカバリについて。
私はサーバーを再起動したところ、うまくいきました。今のところ、bugs.mysql.comに完全なバグレポートを投稿するのを待っています。
私はこれで何かを発見しました ページ 、そしてそれは同じ種類の問題のようですが、それ以上のメッセージはありません。
ここからどこへ行くべきかわからない、なぜこれが突然の出来事なのかわからない。
ここからどのような詳細を提供する必要がありますか?
[〜#〜]編集[〜#〜]
this を読んだ後、
「MySQL 5.6以降のアーキテクチャの変更により、アダプティブハッシュインデックスを無効にするのに適したワークロードが以前のリリースよりも多くなりますが、デフォルトでは有効になっています。」
SET GLOBAL innodb_adaptive_hash_index=0
を使用してアダプティブハッシュインデックスを無効にし、問題が修正されたかどうかを確認する最初の試行を試みています。状況は夜のようです。
夜間更新:
アップデートはうまくいきました。 6時間未満。フルテキストインデックスの更新に問題はありませんでしたが、JOIN
を使用した単純な更新クエリが遅いことがわかりました。 (8
秒で40000レコード。これは通常1
未満で実行されました)。
今日も継続してそれを微調整します。
そのような問題も抱えていました。データベースは1日に数回、理由もなく壊れました。これが役に立ったかどうかはわかりませんが、私の解決策はすべてのテーブルを最適化することです。これまでの3日間、この問題は発生しなくなりました。
すべてのテーブルを最適化するには多くの方法がありますが、PHPを使用してLinuxコンソールからこれを行う方法の例を紹介します
#!/bin/php -n
<?php
// /bin/php -n /sysmyx/mysql/hand_optimize_all_tables.php
dl('mysqlnd.so');
dl('mysqli.so');
$timestart = time();
$n=0;
$con=mysqli_connect("localhost","roootmysql","passss");
if (mysqli_connect_errno()) { echo "mysql error".PHP_EOL;
exit;
}
mysqli_query($con,"SET GLOBAL innodb_buffer_pool_dump_now = 1");
$res = mysqli_query($con,"SHOW DATABASES");
while ($row = mysqli_fetch_assoc($res)) {
$db_name=$row['Database'];
if ($db_name!="mysql" && $db_name!="information_schema" && $db_name!="performance_schema" && $db_name!="" && $db_name!="sys") {
echo '*'.$db_name.'*'.PHP_EOL;
//!!!!!!!!!!!!!!!!!!!!!!!// $query="SHOW TABLE STATUS FROM $db_name where Data_free>0;";
$query="SHOW TABLE STATUS FROM $db_name";
$tabbll=mysqli_query($con,$query);
while ($row2 = mysqli_fetch_assoc($tabbll)) {
$n++;
$opt_table='`'.$db_name.'`.`'.$row2['Name'].'`';
$query2="OPTIMIZE TABLE $opt_table";
$time1 = time();
mysqli_query($con,$query2);
$time2 = time();
$time3 = $time2-$time1;
echo $n.' '.$time3.' '.$row2['Data_free'].' '.$opt_table.PHP_EOL;
}}}
mysqli_query($con,"SET GLOBAL innodb_buffer_pool_load_now = 1");
mysqli_close($con);
$timeend = time();
$time = $timeend-$timestart;
?>
また、設定my.cnfの一部
innodb_thread_concurrency=0
flush_time=0
innodb_adaptive_hash_index=0
innodb_adaptive_hash_index_parts=1
innodb_purge_threads=1
innodb_fatal_semaphore_wait_threshold=60
2019年7月7日更新
このエラーの原因となった問題を見つけました。
問題は、4,000行のテーブルがあることでした。このテーブルは、毎秒約1000回の更新を受信しました。また、同時にこの表から、毎秒約500の選択があります。通常、選択時間は0.006秒ですが、数日後に選択時間は5秒になります。その後、数千の選択がキューに集められ、「長いセマフォ待機」というエラーが発生した瞬間。
可能な解決策:
1)別のテーブル構造を作成し、インディクスをチェックして、テーブルをいくつかのテーブルに分割します。
2)数時間ごとにテーブルを最適化します。
3)このテーブルのキャッシュシステムを用意する
考えられる検索の問題:
Mysqlのクラッシュ時に収集されたクエリを確認するのに役立つ便利なスクリプト。 cronを通じて毎分スクリプトを実行します。
#!/bin/bash
USER=$(</sys_snting/mysql_user)
PASSWORD=$(</sys_snting/mysql_pass)
num=$(mysql --user=$USER --password=$PASSWORD -s -N -e "SELECT count(*) FROM information_schema.processlist ;")
if [ $num -ge 500 ] ; then
mysql --user=$USER --password=$PASSWORD -e "show full processlist" > /media/bug/$(date +%Y%m%d%H%M%S)_$num.txt
echo $num
# Kill selections that can lead to "A long semaphore wait"
# mysql --user=$USER --password=$PASSWORD -N -e "SELECT Id FROM information_schema.processlist where INFO like '%SELECT \`d_narfe\` FROM \`maitableep_com\`.\`5000_active\` WHERE%';" | while IFS= read -r loop
# do
# echo "$loop"
# mysqladmin --user=$USER --password=$PASSWORD kill $loop
# done
fi