私はubuntuサーバー12、mysql innodb_version 5.5.49でLAMPをWordpressプラットフォーム(仮想化された3つのWebサイト)で実行しています。約2年間問題なく実行されていますが、エラー「データベース接続の確立エラー」エラー。他の仮想化サイトにも「最大接続超過」エラーが時々発生します。新しいプラグインやデータベースの変更はありません。
Rootとしてmysqlにログインしてshow full processlist;
を実行すると、サイトのプライマリログインの1つだけによって生成された150のスリーププロセスのリストが表示されます。もちろん、150は私のmax_connections制限なので、これらのプロセスはサーバー全体を下にドラッグしています。それぞれが稼働している時間を考えると、約6が生成されているようです毎秒。
私の問題は、トラブルシューティングのアイデアが不足していることです。私は確かにDBA初心者です。これが私がこれまでに試したことです:
とりあえず、1つのサイトで実行できる最大プロセスをmax_connectionsの50%に制限したので、他のサイトは実際に実行されています。この時点でほぼ何でも試してみてください。洞察をデバッグしてください。
これは、私が簡単に有効にしたMySQLログファイルの出力です。
7990364 Query SELECT COUNT(*) FROM wp_postmeta WHERE meta_key = '_loved' AND post_id = 669
7990364 Query SELECT COUNT(*) FROM wp_postmeta WHERE meta_key = '_loved' AND post_id = 667
7990364 Query SELECT COUNT(*) FROM wp_postmeta WHERE meta_key = '_loved' AND post_id = 591
7990364 Query SELECT COUNT(*) FROM wp_postmeta WHERE meta_key = '_loved' AND post_id = 568
7990364 Query SELECT COUNT(*) FROM wp_postmeta WHERE meta_key = '_loved' AND post_id = 561
7990364 Query SELECT COUNT(*) FROM wp_postmeta WHERE meta_key = '_loved' AND post_id = 553
7990364 Query SELECT COUNT(*) FROM wp_postmeta WHERE meta_key = '_loved' AND post_id = 541
7990364 Query SELECT COUNT(*) FROM wp_postmeta WHERE meta_key = '_loved' AND post_id = 461
7990364 Query SELECT COUNT(*) FROM wp_postmeta WHERE meta_key = '_loved' AND post_id = 439
7990364 Query SELECT COUNT(*) FROM wp_postmeta WHERE meta_key = '_loved' AND post_id = 393
7990364 Query SELECT COUNT(*) FROM wp_postmeta WHERE meta_key = '_loved' AND post_id = 359
7990364 Query SELECT COUNT(*) FROM wp_postmeta WHERE meta_key = '_loved' AND post_id = 301
7990364 Query SELECT COUNT(*) FROM wp_postmeta WHERE meta_key = '_loved' AND post_id = 299
7990364 Query SELECT COUNT(*) FROM wp_postmeta WHERE meta_key = '_loved' AND post_id = 297
7990364 Query SELECT COUNT(*) FROM wp_postmeta WHERE meta_key = '_loved' AND post_id = 13
7990364 Query SELECT COUNT(*) FROM wp_postmeta WHERE meta_key = '_loved' AND post_id = 1
以下はその結果です。
EXPLAIN SELECT COUNT(*) FROM wp_postmeta WHERE meta_key = '_loved' AND post_id = 669;
1 | SIMPLE | wp_postmeta | ref | post_id,meta_key | post_id | 8 | const | 5 | Using where
show create table wp_postmeta;
からの結果
| wp_postmeta | CREATE TABLE `wp_postmeta` (
`meta_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`post_id` bigint(20) unsigned NOT NULL DEFAULT '0',
`meta_key` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`meta_value` longtext COLLATE utf8mb4_unicode_ci,
PRIMARY KEY (`meta_id`),
KEY `post_id` (`post_id`),
KEY `meta_key` (`meta_key`(191))
) ENGINE=InnoDB AUTO_INCREMENT=3360 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci |
また:
innodb_buffer_pool_size: 134217728
*************************** 1. row ***************************
Name: wp_postmeta
Engine: InnoDB
Version: 10
Row_format: Compact
Rows: 1388
Avg_row_length: 247
Data_length: 344064
Max_data_length: 0
Index_length: 131072
Data_free: 72351744
Auto_increment: 3360
Create_time: 2016-04-22 13:46:34
Update_time: NULL
Check_time: NULL
Collation: utf8mb4_unicode_ci
Checksum: NULL
Create_options:
Comment:
1 row in set (0.00 sec)
データベースのサイズは約5MBです。
これは小さなDBですが、正直なところ、これはWPコードの問題である可能性があると思います。個々のクエリに長時間かかることではありませんが、max_connections
が満たされることはチェックするたびに、max_connections
は常に最大になります。
(表示されているクエリのみの部分的な回答です。これが修正されれば、他の違反者を特定できる可能性があります。)
_SELECT COUNT(*)
FROM wp_postmeta
WHERE meta_key = '_loved' AND post_id = 669
_
このクエリの場合、最適なインデックスは_(post_id, meta_key)
_ですが、_meta_key
_は_utf8mb4
_文字セットでvarchar(255)
として定義されているため、標準の設定ではそのようなインデックスは大きすぎます。
代わりに使用できます
_ALTER TABLE wp_postmeta ADD INDEX(`post_id`, `meta_key`(100));
_
最適ではありませんが、テーブルからアクセスする行を少なくすることで、パフォーマンスが少し向上するインデックスを作成します。
_innodb_large_prefix
_ の設定を確認して変更すると、最適なインデックスを作成しようとする場合があります(ただし、マニュアルに記載されているように、行の形式についていくつかの追加要件があります)。これは、index-only ref accessにつながり、インデックスを使用してクエリを最適化できるのと同じくらい高速です。
本当にmeta_key
に191文字を超える値がありますか?そうでない場合は、次の変更を行います。
CREATE TABLE `wp_postmeta` (
`meta_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`post_id` bigint(20) unsigned NOT NULL DEFAULT '0',
`meta_key` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL, -- note length
`meta_value` longtext COLLATE utf8mb4_unicode_ci,
PRIMARY KEY (`meta_id`),
KEY `meta_key` (post_id, `meta_key`) -- note compound, no "prefixing"
) ENGINE=InnoDB AUTO_INCREMENT=3360 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
これにより、特定のクエリを完全にインデックスで実行できるため、クエリの実行が速くなります。
(WP ought変更するものは他にもありますが、安全に変更することはできません。)
また、max_connections
を20に下げます。150のクライアントが互いにつまずき、全員が終了するまでに時間がかかるのは意味がありません。
また、Webサーバーに許可されるクライアントの数を減らします。この場合も、20が妥当な場合があります。