1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

PDOで「Packets out of order. Expected 1 received 0」のワーニングが出る

Last updated at Posted at 2022-06-21
../

CentOS Stream 8でPHP7.4からPDOでMySQL8.0に接続する際に「Packets out of order. Expected 1 received 0」のワーニングが出る時がある。毎回確実に出る訳でもなく、どのような状況の時に出るのかは判明できていない。心当たりのある原因を後述しておく。

PHP message: @@ enter getUsers('admin',false)
PHP message: @@ new UserManager()
PHP message: @@ new UserDataAccessor()
PHP message: @@ PersistenceBase::__construct()
PHP message: @@ PersistenceBase::pdo = null
PHP message: 
PHP Warning:  Packets out of order. Expected 1 received 0. Packet size=145 
              in common/integration/PersistenceBase.php on line 46
              
PHP message: @@@ connected mysql:dbname=test;host=localhost;port=3306;charset=utf8
PHP message: @@@ select * from user order by user_id --> 6

数日前は何度か起きていたが、最近はまったく起きていない。

上記の場合、PDOに接続でき、ユーザー情報の検索はできている。PDOに接続に行く際に「Packets out of order. Expected 1 received 0」のWarningが出たと言っている。「パケットの順序がおかしい。1でないといけないのに0になっている」と言っている。Warningだから無視していいのか、解決すべきなのかも分からず。

  private function pdo(): PDO {
  
    error_log('@@ PersistenceBase::pdo = ' . (is_null($this->pdo)? 'null' : 'available'));
    
    if (empty($this->pdo)){
    
      $dsn = $this->props['db.dsn'];
      $user = $this->props['db.user'];
      $password = $this->props['db.password'];
      $options = [
          PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
          PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
          // PDO::ATTR_EMULATE_PREPARES, false,
          PDO::ATTR_PERSISTENT => true
      ];
      try {
        
        $this->pdo = new PDO($dsn, $user, $password, $options);
        error_log("@@@ connected " . $dsn);
        
      } catch (PDOException $e) {
        
        error_log("@@@ dsn = " . $dsn);
        error_log("@@@ user = " . $user);
        error_log("@@@ password = " . $password);
        error_log("@@@ connect failed: " . $e->getMessage());
        error_log($e->getTraceAsString());
      }
    }
    return $this->pdo;
  }

ネット情報を見てもよく分からず。再現するようになったら、そのとき再度、調べたい。関連しそうなログは、以下のもの。

$ tail -200 /var/log/php_errors.log
$ tail -200 /var/log/httpd/error_log
$ tail -200 /var/log/mysql/mysqld.log
$ tail -200 /var/log/nginx/error.log
$ tail -200 /var/log/php-fpm/error.log

原因は、MySQLの wait_timeout が8時間の問題だったかも

確認はしていないのだけど、原因は、MySQLの wait_timeout の設定だったかもしれない。MySQLは、デフォルトでは8時間アクセスがないとタイムアウトする。例えば、前日にはうまく行っていても、翌朝にはMySQLを再起動しないといけないときが、Javaでもあった。今回の環境でも、wait_timeoutを設定しないまま使っていたためかもしれない。

以下のように、wait_timeout に31536000をセットしたから起きなくなったのかな。31536000 = 365 * 24 * 3600 である。

$ vi /etc/my.cnf.d/mysql-server.cnf

[mysqld]
character-set-server=utf8
lower_case_table_names=1

interactive_timeout=31536000
wait_timeout=31536000

PHPのシステムロガー error_log() の使い方

ついでなので、PHPのシステムロガーの使い方を整理しておく。呼び出しには、汎用のerror_log()を使う。

error_log(string $message, int $message_type = 0, ?string $destination = null): bool

message_type=0のとき、message がPHPのシステムロガーに送られ、error_log の値に応じて、OSのシステムログ機構を使って保存されるか、ファイルに保存されるかが決まる。デフォルトのオプション。
message_type=3のとき、message は destination で指定されたファイルに追加される。messageの末尾に改行文字を付与した方がよい。

PHPのシステムロガーの設定は、php.ini で行う。

$ vi /etc/php.ini

; 出力するエラーのレベル 
;error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
error_reporting = E_ALL

; エラーを表示するか。どこに表示するか。{ On,Off,stderr,stdout }
display_errors = On

; 起動時のエラーを表示するか。
display_startup_errors = On

; ログを出力するか。stderrやerror_logで指定される場所に出力される。
log_errors = On

; ログの出力先ファイル
error_log = /var/log/php_errors.log

; ログの出力先をsyslogに委ねる場合
;error_log = syslog
;syslog.ident = php
;syslog.facility = user

$ systemctl restart httpd
$ systemctl restart nginx

以前は、error_reporting = E_ALL | E_STRICT と書いていたらしい。PHP7.4では error_reporting = E_ALL でいい。E_STRICTなど細かいものを除外するときは、error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT と書くそうだ。

../
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?