Skip to content

Commit

Permalink
[db_oracle] Do not change asynch mode when connection lost.
Browse files Browse the repository at this point in the history
The sessions may be ended due to a network error,
and change OCI_ATTR_NONBLOCKING_MODE attribute with no session
will cause "ORA-03126: network driver does not support non-blocking
operations" error.

In the case, the function done_timelimit will failed with ORA-03126 error.
The error is not considered as a connection loss,
and subsequent operations will always throw this error,
and the lost connection never reconnect.

(cherry picked from commit a565783)
  • Loading branch information
GangZhuo authored and liviuchircu committed Nov 16, 2022
1 parent 87eee76 commit 861e8dd
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 11 deletions.
14 changes: 9 additions & 5 deletions modules/db_oracle/asynch.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,9 @@ sword begin_timelimit(ora_con_t* con, int connect)
}


static sword remap_status(ora_con_t* con, sword status)
static sword remap_status(ora_con_t* con, sword status, sword *errcode)
{
sword code;
sword code = 0;

if ( status == OCI_ERROR
&& OCIErrorGet(con->errhp, 1, NULL, &code,
Expand All @@ -200,6 +200,7 @@ static sword remap_status(ora_con_t* con, sword status)
{
status = OCI_STILL_EXECUTING;
}
if (errcode) *errcode = code;
return status;
}

Expand All @@ -214,7 +215,7 @@ int wait_timelimit(ora_con_t* con, sword status)
if (!cur_asynch_mode)
return 0;

if (remap_status(con, status) != OCI_STILL_EXECUTING)
if (remap_status(con, status, NULL) != OCI_STILL_EXECUTING)
return 0;

gettimeofday(&cur, NULL);
Expand All @@ -230,12 +231,12 @@ int wait_timelimit(ora_con_t* con, sword status)
int done_timelimit(ora_con_t* con, sword status)
{
int ret = 0;
sword code;

if (!cur_asynch_mode)
return 0;

if (remap_status(con, status) == OCI_STILL_EXECUTING) {
sword code;
if (remap_status(con, status, &code) == OCI_STILL_EXECUTING) {

status = OCIBreak(con->svchp, con->errhp);
if (status != OCI_SUCCESS)
Expand All @@ -255,6 +256,9 @@ int done_timelimit(ora_con_t* con, sword status)
db_oracle_error(con, status));
db_oracle_disconnect(con);
++ret;
} else if (db_oracle_connection_lost(code)) {
db_oracle_disconnect(con);
cur_asynch_mode = 0;
} else {
status = change_mode(con);
if (status != OCI_SUCCESS) {
Expand Down
19 changes: 13 additions & 6 deletions modules/db_oracle/dbase.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,17 @@ static const char* db_oracle_errorinfo(ora_con_t* con)
if (OCIErrorGet(con->errhp, 1, NULL, &errcd,
(OraText*)errbuf, sizeof(errbuf),
OCI_HTYPE_ERROR) != OCI_SUCCESS) errbuf[0] = '\0';
else switch (errcd) {
else if (db_oracle_connection_lost(errcd)) {
LM_ERR("connection dropped\n");
db_oracle_disconnect(con);
}

return errbuf;
}

int db_oracle_connection_lost(sword errcode)
{
switch (errcode) {
case 28: /* your session has been killed */
case 30: /* session ID does not exists */
case 31: /* session marked for kill */
Expand Down Expand Up @@ -113,13 +123,10 @@ static const char* db_oracle_errorinfo(ora_con_t* con)
case 12561: /* tns unknown error */
case 12608: /* tns send timeount */
case 12609: /* tns receive timeount */
LM_ERR("conneciom dropped\n");
db_oracle_disconnect(con);
default:
break;
return 1;
}

return errbuf;
return 0;
}

const char* db_oracle_error(ora_con_t* con, sword status)
Expand Down
5 changes: 5 additions & 0 deletions modules/db_oracle/ora_con.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,9 @@ sword db_oracle_reconnect(ora_con_t* con);
*/
const char* db_oracle_error(ora_con_t* con, sword status);

/*
* Does the error code indicate that the connection has been lost
*/
int db_oracle_connection_lost(sword errcode);

#endif /* ORA_CON_H */

0 comments on commit 861e8dd

Please sign in to comment.