pgpool2.git / summary / log / commit / refs
commit 67bc07abd14720ee60b31adccdb4a626095016f7
Author: Tatsuo Ishii <ishii at sraoss.co.jp>
Date: Sat Sep 26 07:51:38 2009 +0000
Fix reset_backend to deal with DEALLOCATE error. In this case prepared
objects are not removed and reset_backend is infinitely called.
Fix do_command to guard against the case that after execution of an
SQL command, the backend does not return either N, E or C. This should
not happen but there was a report that it actually happend in certain
cases(maybe caused by asynchronized backend data?)
See:
Subject: Re: [Pgpool-general] pgpool 2.2.4: DEALLOCATED children
From: Xavier Noguer
Date: Fri, 25 Sep 2009 03:35:57 -0400
For more details.
Patches by Xavier Noguer with minor tweak by Tatsuo Ishii.
pool_process_query.c | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/pool_process_query.c b/pool_process_query.c
index 65096699f..97d322655 100644
--- a/pool_process_query.c
+++ b/pool_process_query.c
@@ -2161,10 +2161,20 @@ static int reset_backend(POOL_CONNECTION_POOL *backend, int qcnt)
qn = pool_config->num_reset_queries;
+ /*
+ * After execution of all SQL commands in the reset_query_list, we
+ * remove all prepared objects in the prepared_list.
+ */
if (qcnt >= qn)
{
if (prepared_list.cnt == 0)
{
+ /*
+ * Either no prepared objects were created or DISCARD ALL
+ * or DEALLOCATE ALL is on the reset_query_list and they
+ * were executed. The latter causes call to
+ * reset_prepared_list which removes all prepared objects.
+ */
reset_prepared_list(&prepared_list);
return 2;
}
@@ -2178,6 +2188,15 @@ static int reset_backend(POOL_CONNECTION_POOL *backend, int qcnt)
reset_prepared_list(&prepared_list);
return -1;
}
+ /*
+ * If DEALLOCATE returns ERROR response, instead of
+ * CommandComplete, del_prepared_list is not called and the
+ * prepared object keeps on sitting on the prepared list. This
+ * will cause infinite call to reset_backend. So we call
+ * del_prepared_list() again. This is harmless since trying to
+ * remove same prepared object will be ignored.
+ */
+ del_prepared_list(&prepared_list, prepared_list.portal_list[0]);
return 1;
}
@@ -2619,6 +2638,12 @@ static POOL_STATUS do_command(POOL_CONNECTION *frontend, POOL_CONNECTION *backen
return POOL_END;
}
len = ntohl(len) - 4;
+
+ if (kind != 'N' && kind != 'E' && kind != 'C')
+ {
+ pool_error("do_command: error, kind is not N, E or C(%02x)", kind);
+ return POOL_END;
+ }
string = pool_read2(backend, len);
if (string == NULL)
{
[parent: eb4d5638db24]