Skip to content

Connecting to PDO / MySQL database over unix-socket throws "a retry" error #22981

Open

Description

@wyattoday

Description

The following code:

<?php

Resulted in this output:

Error message: SQLSTATE[HY000] [2002] Resource temporarily unavailable

Error stack trace:

#0 /location-to-php.php(43): PDO->__construct()
#xx: our code

But I expected this output instead:

No crash.

This is a bug in mysqlnd in that it returns a "2002" error code (I looked into the code -- it's a "try again" code, that is a look / backoff should be taken). This happens when connecting to MySQL using a unix socket. And it happens when a high-frequency of calls are made in short succession.

Ideally a unix-socket should be opened once per process and all communication should happen on that socket (rather than opening and closing it over and over again). And "retry" "errors" (not an error) should be handled correctly.

I haven't dug into the mysqlnd extension into how to fix this yet. If someone wants to jump on this first, that would be appreciated. Otherwise I'll dig into it next week.

PHP Version

8.5.9

Operating System

Debian 12

Activity

  1. wyattoday commented on Aug 1, 2026

    @wyattoday
    Author

    Using PDO::ATTR_PERSISTENT => true does workaround this issue (but, we've been wary of using it in the past due to issues we've had in the past).

    Either way, this is a bug in mysqlnd that's worth digging into and fixing (in my opinion). And if we find subsequent issues with persistent connections we'll report them and dig into them.

  2. arshidkv12 commented on Aug 1, 2026

    @arshidkv12
    Contributor

    Please share the sample code.

  3. wyattoday commented on Aug 3, 2026

    @wyattoday
    Author

    The relevant parts of the code are just a PDO object and a test rig to make high-frequency connections to a MySQL database over a unix-socket. (So, not really a lot of code to show).

    		// this class assumes there's a global const
    		// named "DB_CONFIG" that's in the following form:
    		/*
    
    		const DB_CONFIG = [
    			'dsn' => 'mysql',
    			'unix_socket' => '/location/to/mysql/unix.sock',
    			'username'	=> 'your_user',
    			'password'	=> 'your_pass',
    			'dbname'	=> 'your_db_name'
    		];
    		*/
    
    		if (isset(DB_CONFIG['unix_socket']))
    			$connect_str = DB_CONFIG['dsn'].':unix_socket='.DB_CONFIG['unix_socket'];
    		else
    			$connect_str = DB_CONFIG['dsn'].':host='.DB_CONFIG['host'].';port='.DB_CONFIG['port'];
    
    		self::$_instance = new PDO($connect_str.';dbname='.DB_CONFIG['dbname'],
    			DB_CONFIG['username'],
    			DB_CONFIG['password'],
    			[
    				PDO::ATTR_EMULATE_PREPARES => false,
    				PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    				PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    				Pdo\Mysql::ATTR_USE_BUFFERED_QUERY => false
    			]
    		);
    

    Then just use that connection to make a query of some sort (it doesn't really matter what you do).

    As I said above "persistent connections" (PDO::ATTR_PERSISTENT => true) works-around this problem (but has it's own trade-offs such that we need to tread carefully). Also, digging into the the mysqlnd / php-poll code I see that the "2002" error code is a try-again condition that is handled incorrectly (it's handled as an error rather than a wait-try-again loop condition).

    Also, there's a chance for better resource management. That is, a step between "persistent connections" and not. Namely the unix-socket itself can be a resource that is "opened" and maintained across the lifetime of the php / php-fpm process and new database connections can be made over that shared resource. So the "state" problems / bugs of persistent connections can be avoided by treating the "tunnel" as a cached-resource and the connections are all fresh with their own state.

    But that's just a suggestion for better/faster resource management in mysqlnd. The actual bug is not handling the "2002" error code correctly in mysqlnd.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions