php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #80546 Persistent connections appear open despite being closed
Submitted: 2020-12-22 21:17 UTC Modified: 2021-06-09 14:09 UTC
Votes:2
Avg. Score:4.0 ± 1.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: jeremys at ha dot com Assigned:
Status: Open Package: PDO DBlib
PHP Version: 7.3.25 OS: RHEL 7.8
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: jeremys at ha dot com
New email:
PHP Version: OS:

 

 [2020-12-22 21:17 UTC] jeremys at ha dot com
Description:
------------
Because PHP_DBLIB doesn't implement pdo_dbh_check_liveness_func (its value is null, which is "equivalent to returning SUCCESS"), when instantiating a new PDO object using persistent connections with dblib, if the connection dies, PHP is not aware of it and any subsequent queries using the connection fail with "DBPROCESS is dead or not enabled".

pdo_dbh_check_liveness_func definition:
https://github.com/php/php-src/blob/caa710037e663fd78f67533b29611183090068b2/ext/pdo/php_pdo_driver.h#L264

pdo_dblib's implementation:
https://github.com/php/php-src/blob/caa710037e663fd78f67533b29611183090068b2/ext/pdo_dblib/dblib_driver.c#L417

In this specific example, a Microsoft SQL Server is used to simulate a connection timeout using the WAITFOR DELAY query (which causes the connection to be considered dead by dblib). Connection is made using FreeTDS 1.1.x.

Based on the source, seems to be an issue in PHP 8 as well.

Test script:
---------------
<?php
for( $i = 0; $i <= 1; $i++ )
{
    $pdo = new PDO( 'dblib:dbname=northwinds;host=contoso', 'username', 'password', [
        PDO::ATTR_PERSISTENT => false,
        PDO::ATTR_TIMEOUT    => 5
    ] );
    try
    {
        if( $i == 0 )
        {
            $pdo->query( "WAITFOR DELAY '00:00:10'" );
        }
        var_dump( $pdo->query( "SELECT 'output' AS Output" )->fetch( PDO::FETCH_ASSOC )['Output'] );
    }
    catch( Throwable $e )
    {
        var_dump( stripos( $pdo->errorInfo()[2], 'DBPROCESS is dead or not enabled' ) === 0 );
    }
    $pdo = null;
}
?>

Expected result:
----------------
bool(true)
string(6) "output"

Actual result:
--------------
bool(true)
bool(true)

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-12-23 15:57 UTC] jeremys at ha dot com
Total copy/paste error on my part, PDO::ATTR_PERSISTENT should be set to true in the test script.
 [2021-06-09 14:09 UTC] cmb@php.net
Right, if check_liveness is (properly) implemented by the driver,
all is good.  This is basically the same issue as bug #64603
(which is about PDO_Firebird).

However, apparently PDO doesn't require drivers to implement that
method, so I wonder whether the respective code for persistent
connections[1] shouldn't be generally changed:

    if (!pdbh->methods->check_liveness || FAILURE == (pdbh->methods->check_liveness)(pdbh)) {

In words, if check_liveness is not implemented, assume the
connection to be dead.

[1] <https://github.com/php/php-src/blob/php-8.1.0alpha1/ext/pdo/pdo_dbh.c#L326>
 [2023-05-01 06:33 UTC] fariba dot shami326 at gmail dot com
If a persistent connection appears to be open despite being closed, it could be due to a variety of factors. One possible explanation is that the connection was not properly closed by the client or server, causing it to remain open even though it should have been terminated. Another possibility is that there is a delay in the release of resources associated with the connection, which can make it appear as though it is still open. Additionally, some network protocols may have built-in mechanisms to keep connections open for a certain period of time to improve performance, even after data transmission has stopped. It's important to properly manage and monitor connections to avoid these issues and ensure optimal network performance.   (https://www.benefitwallet.me/)github.com
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Mar 19 06:01:30 2024 UTC