php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #43050 OCI8 persistent connections cannot recover from disconnect
Submitted: 2007-10-19 23:08 UTC Modified: 2007-11-12 10:21 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:0 (0.0%)
From: david at acz dot org Assigned:
Status: Not a bug Package: OCI8 related
PHP Version: 5.2.4 OS: SuSE Linux
Private report: No CVE-ID: None
 [2007-10-19 23:08 UTC] david at acz dot org
Description:
------------
OCI8 persistent connections cannot, by design, be closed.  The consequence is that if the connection fails then the only recourse is to restart PHP.  oci_pconnect always returns the same dead connection.  The PHP application itself cannot correct the issue.  Connections can fail due to idle timeouts, session kills, etc.

Two suggested fixes:

1) Add an oci_pclose() that always closes persistent connections.
2) Close or allow the connection to be closed after certain errors such as 28, 1012, 2396, 3114, etc.

There are at least two ways to run the test and reproduce the error:

1) After you see the "sleeping" line, kill the session with ALTER SYSTEM KILL SESSION.
2) Increase the sleep to 300 seconds and lower the idle timeout in the database to 1 minute.

The code was tested with OCI 1.3.0 Beta (Revision: 1.269.2.16.2.38.4.1).

Reproduce code:
---------------
<?
$o = oci_pconnect(DB_USER, DB_PASS, DB_NAME);
var_dump($o);
if ($o === false)
{
    $err = oci_error();
    print_r($err);
}

$sql = "ALTER SESSION SET NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS'";
query($o, $sql);

echo "sleeping\n";
sleep(60);

if (!query($o, $sql))
{
    echo "query failed, closing connection\n";
    var_dump(oci_close($o));
    $o = oci_pconnect(DB_USER, DB_PASS, DB_NAME);
    var_dump($o);
    if ($o === false)
    {
        $err = oci_error();
        print_r($err);
    }
    echo "reconnected\n";
    var_dump(query($o, $sql));
}

function query($o, $sql)
{
    $s = @oci_parse($o, $sql);
    if ($s === false)
    {
        $err = oci_error($o);
        print_r($err);
        return false;
    }
    if (!@oci_execute($s, OCI_COMMIT_ON_SUCCESS))
    {
        $err = oci_error($s);
        print_r($err);
        return false;
    }
    oci_free_statement($s);
    return true;
}
?>


Actual result:
--------------
resource(4) of type (oci8 persistent connection)
sleeping
Array
(
    [code] => 28
    [message] => ORA-00028: your session has been killed
    [offset] => 0
    [sqltext] => ALTER SESSION SET NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS'
)
query failed, closing connection
bool(true)
resource(8) of type (oci8 persistent connection)
reconnected
Array
(
    [code] => 1012
    [message] => ORA-01012: not logged on
    [offset] => 0
    [sqltext] => ALTER SESSION SET NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS'
)
bool(false)


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-10-23 22:08 UTC] david at acz dot org
I found the root cause: OCIServerVersion() succeeds even though queries fail.  You can verify this by calling oci_server_version() after the "reconnected" line in the test script.  It works but the following query returns ORA-01012.
 [2007-10-23 23:41 UTC] david at acz dot org
I wrote a patch that adds a new flag, use_ociping:

http://david.acz.org/tmp/php-5.2.4-oci8.patch

This solves the issue and seems to be the correct solution.
 [2007-11-12 10:21 UTC] tony2001@php.net
>I found the root cause: OCIServerVersion() succeeds even though
>queries fail.  You can verify this by calling oci_server_version()
>after the "reconnected" line in the test script.  It works but the
>following query returns ORA-01012.

Please report this to Oracle.
Thank you.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Apr 25 16:01:28 2024 UTC