mita2 database life

主にMySQLに関するメモです

PHP mysqli ドライバの max_persistent 設定の使い所がよくわからなかった件

TL;DR

  • PHPmysqli.max_persistent で指定できるのは、HTTPワーカ プロセスあたり のコネクション数だった
    • 「全部で何個まで」っていう制限値じゃなかった

PHP mysqli.max_persistent 設定

Persistent Connections まわりのエントリーを先日書きました。

mita2db.hateblo.jp

@do_aki さんに、PHPmysqli ドライバには以下のようなコネクション数をコントロールする設定があると教えてもらいました。

mysqli.max_persistent integer Maximum of persistent connections that can be made. Set to 0 for unlimited.

https://www.php.net/manual/en/mysqli.configuration.php#ini.mysqli.max-persistent

これを使えば、PHPからDBサーバへ貼るコネクション数をコントロールできるのかしら?

試します

mysqli.max_persistent=1 に設定して、簡単なプログラムを実行します。 ちなみに、mysqli ドライバで持続的接続(Persistent Connections) を使うには、ホスト名 に p:プレフィックスを付ける必要があります。

$ cat /etc/php.d/30-mysqli.ini
mysqli.max_persistent=1
<?php

if (($mysqli = mysqli_connect("p:db01", "appuser", "password", ""))) {
  $res = mysqli_query($mysqli, "SELECT CONNECTION_ID() as msg");
  $row = mysqli_fetch_assoc($res);
  echo $row['msg']."\n";
}

?>

実行したあとに、DBサーバ側でコネクション数を数えます。

mysql> SHOW PROCESSLIST;
+--------+-------------+---------------------+------+---------+-<snip>
| Id     | User        | Host                | db   | Command | <snip>
+--------+-------------+---------------------+------+---------+-<snip>
| 554589 | appuser     | 192.168.X.X:36642   | NULL | Sleep   | <snip>
| 554590 | appuser     | 192.168.X.X:36664   | NULL | Sleep   | <snip>
| 554591 | appuser     | 192.168.X.X:36668   | NULL | Sleep   | <snip>
| 554592 | appuser     | 192.168.X.X:36670   | NULL | Sleep   | <snip>
| 554593 | appuser     | 192.168.X.X:36704   | NULL | Sleep   | <snip>

・・・接続数が絞れてない? httpd のプロセス数と同じ数のコネクションが出来てしまっています。

プロセス毎の制限値らしい

mysqli ドライバではなく、mysql ドライバ (i のつかない方) のマニュアルには、「プロセス毎の最大値」と記載があります。 mysqli も同じ挙動だろうという推測ができますね・・・

mysql.max_persistent integer The maximum number of persistent MySQL connections per process.

<?php
$a = mysqli_connect("p:db01", "appuser", "password", "");
$b = mysqli_connect("p:db02", "appuser", "password", "");
?>

2つ接続を貼ってみると、2個目の mysqli_connect がエラーになりました。 やはり、プロセス毎でした。そして、最大数に達さないように、あふれたコネクションを閉じてくれるのではなく、エラーになるんですね。。。

$ sudo tail /var/log/httpd/error_log
[Sun Aug 09 16:08:30.949737 2020] [php7:warn] [pid 19100] [client X.X.X.X:55350] 
PHP Warning:  mysqli_connect(): Too many open persistent links (1) in /var/www/html/index.php on line 10

意図せず大量にコネクションを貼ってしまうのを防ぐためのパラメータなんですかねー・・・いまいち使い所がわからん。