MySQLのInnoDB全文検索(MeCabパーサ)を使ってたら急に重くなってサーバが落ちた件

スポンサーリンク
Linux
スポンサーリンク
↑管理人が個人でUnity+Live2Dで作成しているスマホゲームです

先日、自前のサーバ(さくらのVPS)が何らかの高負荷で落ちてしまいました。
管理画面でリソースを見るとこんな感じです。

端末エミュレータからログインできないので管理画面のVNCコンソールからログインすると、killedプロセスメッセージがずらずらと流れています。何かの原因でメモリが食い尽くされてしまったようです。
入力出来ないので管理画面から強制再起動して原因を探ります。

スポンサーリンク

原因はMySQL

topするとMySQLが高負荷状態である事がわかり、mysqlモニタを立ち上げてスロークエリをチェックします。

mysql> show variables like 'slow%';
+---------------------+-----------------------------------+
| Variable_name       | Value                             |
+---------------------+-----------------------------------+
| slow_launch_time    | 2                                 |
| slow_query_log      | OFF                               |
| slow_query_log_file | /var/lib/mysql/www9107uj-slow.log |
+---------------------+-----------------------------------+
mysql> SET GLOBAL  slow_query_log = ON;

スロークエリログを確認します。

# Query_time: 206.152644  Lock_time: 0.000140 Rows_sent: 30  Rows_examined: 155
SET timestamp=1616995433;
SELECT SQL_CALC_FOUND_ROWS * FROM info WHERE  MATCH(title,description) AGAINST('\'***\'' in BOOLEAN mode)   LIMIT 30 OFFSET 0;

InnoDBの全文検索のクエリのようです。EXPLAINしてみます。

mysql> explain SELECT SQL_CALC_FOUND_ROWS * FROM info WHERE  MATCH(title,description) AGAINST('***' in BOOLEAN mode)   LIMIT 100 OFFSET 0;
+----+-------------+-------+------------+----------+---------------+-----------+---------+-------+------+----------+-----------------------------------+
| id | select_type | table | partitions | type     | possible_keys | key       | key_len | ref   | rows | filtered | Extra                             |
+----+-------------+-------+------------+----------+---------------+-----------+---------+-------+------+----------+-----------------------------------+
|  1 | SIMPLE      | info   | NULL       | fulltext | search_key     | search_key | 0       | const |    1 |   100.00 | Using where; Ft_hints: no_ranking |
+----+-------------+-------+------------+----------+---------------+-----------+---------+-------+------+----------+-----------------------------------+
1 row in set, 1 warning (1 min 18.50 sec)

異常に時間がかかっている以外は特に問題ないようです。検索文字列は3文字の日本語です。検索文字列前後の\’を消しても変化なし。
試しにIN BOOLEAN MODEを削除してみました。

mysql> explain SELECT SQL_CALC_FOUND_ROWS * FROM info WHERE  MATCH(title,description) AGAINST('***')   LIMIT 100 OFFSET 0;
+----+-------------+-------+------------+----------+---------------+-----------+---------+-------+------+----------+-------------------------------+
| id | select_type | table | partitions | type     | possible_keys | key       | key_len | ref   | rows | filtered | Extra                         |
+----+-------------+-------+------------+----------+---------------+-----------+---------+-------+------+----------+-------------------------------+
|  1 | SIMPLE      | info   | NULL       | fulltext | search_key     | search_key | 0       | const |    1 |   100.00 | Using where; Ft_hints: sorted |
+----+-------------+-------+------------+----------+---------------+-----------+---------+-------+------+----------+-------------------------------+
1 row in set, 1 warning (0.64 sec)

なんだか急に爆速になってしまいました。
boolean modeの何が原因だったんでしょう??

1 Star2 Stars3 Stars4 Stars5 Stars (まだ投票されていません)
読み込み中...

コメント

広告ブロッカーを無効にしてください。

タイトルとURLをコピーしました