[Sqlrelay-discussion] Bug report, open client connections not freed, with code to reproduce problem
Brought to you by:
mused
|
From: Ingmar B. <sw...@gm...> - 2007-10-15 10:32:08
|
Hi David,
I am using:
sqlrelay 0.39.4
Oracle 10g
php 4.3.11
I've discovered a bug that will cause sqlrelay to think that client
connections are still open while they are not. This is quite troublesome, as
once all client connections are taken, sqlrelay will have to be restarted.
I've been able to isolate the bug in a piece of code. In the code, I've
denoted two sqlrcur_free statements as #A and #B respectively. Trouble will
occur in the situation in which #A has not been commented out while #B has
been commented out. When both have been commented out, there is no problem.
To run the example, first a simple table has to be created:
CREATE TABLE t1
(
c1 varchar(20),
c2 varchar(20),
c3 varchar(20),
c4 varchar(20),
c5 varchar(20),
c6 varchar(20),
c7 varchar(20),
c8 varchar(20),
c9 varchar(20),
c10 varchar(20),
c11 varchar(20),
c12 varchar(20),
c13 varchar(20),
c14 varchar(20),
c15 varchar(20),
c16 varchar(20),
c17 varchar(20)
);
It is actually also possible to reveil the bug using only DUAL, but I needed
a lot of duals to do so. Hence, I think this example is better. Below is the
example code:
//Funtion to connect to a db_schema, initializes the variable $conn
//connect_to_user_db($DB_SCHEMA);
$query = "DECLARE TYPE curtype IS REF CURSOR; ref_cur curtype; BEGIN OPEN
ref_cur FOR
SELECT
t1.c1, t1.c2, t1.c3, t2.c1, t2.c2, t2.c3, t3.c1, t3.c2,
t3.c3
FROM t1
, t1 t2
, t1 t3
WHERE 1 <> 1;
:query_handle := ref_cur ; END;
";
$cur = sqlrcur_alloc($conn);
sqlrcur_prepareQuery($cur, $query);
sqlrcur_defineOutputBindCursor($cur, "query_handle");
sqlrcur_executeQuery($cur);
$query_cursor = sqlrcur_getOutputBindCursor($cur, "query_handle");
sqlrcur_fetchFromBindCursor($query_cursor);
sqlrcur_free($query_cursor); //#A
sqlrcur_free($cur);
$cur = sqlrcur_alloc($conn);
$query = "DECLARE TYPE curtype IS REF CURSOR; ref_cur curtype; BEGIN
OPEN ref_cur FOR SELECT * FROM DUAL; :query_handle := ref_cur ; END;";
sqlrcur_prepareQuery($cur, $query);
sqlrcur_defineOutputBindCursor($cur, "query_handle");
sqlrcur_executeQuery($cur);
$query_cursor = sqlrcur_getOutputBindCursor($cur, "query_handle");
sqlrcur_fetchFromBindCursor($query_cursor);
//sqlrcur_free($query_cursor); //#B
sqlrcur_free($cur);
sqlrcon_free($conn);
Just hit the refresh button a couple of times, and with sqlr-status you will
see the open client connections increase, these are never released again.
Now the strange thing is that if you look in the directory
/usr/local/firstworks/var/sqlrelay/tmp/pids/, then there is a file for each
connection related to the schema. However, if you grep on the process list
for these pids, then you will find that these processes do not exist. This
is why I think that sqlrelay thinks that the connection is still there while
it is not. When you stop sqlrelay using sqlr-stop, then these pid files are
not deleted and sqlr-stop will complain that these processes do not exist.
Please let me know whether the code has helped reproducing the problem. If
you have any questions, let me know.
Regards,
Ingmar
|