pgpool2.git / summary / log / commit / refs
commit c0f6942a8952cf7f9dc9be2d410c6cd61ccaff70
Author: Tatsuo Ishii <ishii at sraoss.co.jp>
Date: Sat Dec 13 08:20:11 2008 +0000
Fix Execute() to avoid kind mismatch error caused by
"SET TRANSACTION ISOLATION LEVEL must be called before any query".
pool_process_query.c | 30 ++++++++++++++++++++++++------
1 file changed, 24 insertions(+), 6 deletions(-)
diff --git a/pool_process_query.c b/pool_process_query.c
index 1247c4074..b704932ec 100644
--- a/pool_process_query.c
+++ b/pool_process_query.c
@@ -1458,6 +1458,7 @@ static POOL_STATUS Execute(POOL_CONNECTION *frontend,
PrepareStmt *p_stmt;
int deadlock_detected = 0;
int serialization_error_detected = 0;
+ int active_sql_transaction_error = 0;
POOL_STATUS ret;
/* read Execute packet */
@@ -1566,10 +1567,8 @@ static POOL_STATUS Execute(POOL_CONNECTION *frontend,
return POOL_END;
/*
- * We must check deadlock error because a aborted transaction
- * by detecting deadlock isn't same on all nodes.
- * If a transaction is aborted on master node, pgpool send a
- * error query to another nodes.
+ * Check dead lock error on the master node and abort
+ * transactions on all nodes if so.
*/
deadlock_detected = detect_deadlock_error(MASTER(backend), MAJOR(backend));
if (deadlock_detected < 0)
@@ -1584,6 +1583,22 @@ static POOL_STATUS Execute(POOL_CONNECTION *frontend,
if (serialization_error_detected < 0)
return POOL_END;
+ /*
+ * check "SET TRANSACTION ISOLATION LEVEL must be called before any query" error.
+ * This happens in following scenario:
+ *
+ * M:S1:BEGIN;
+ * S:S1:BEGIN;
+ * M:S1:SELECT 1; <-- only sent to MASTER
+ * M:S1:SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
+ * S:S1:SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
+ * M: <-- error
+ * S: <-- ok since no previous SELECT is sent. kind mismatch error occurs!
+ */
+ active_sql_transaction_error = detect_active_sql_transaction_error(MASTER(backend), MAJOR(backend));
+ if (active_sql_transaction_error < 0)
+ return POOL_END;
+
}
/* send query to other nodes */
@@ -1591,15 +1606,18 @@ static POOL_STATUS Execute(POOL_CONNECTION *frontend,
{
if (!VALID_BACKEND(i) || IS_MASTER_NODE_ID(i))
continue;
- if (deadlock_detected == SPECIFIED_ERROR || serialization_error_detected == SPECIFIED_ERROR)
+ if (deadlock_detected == SPECIFIED_ERROR || serialization_error_detected == SPECIFIED_ERROR ||
+ active_sql_transaction_error == SPECIFIED_ERROR)
{
char msg[1024] = "pgpoool_error_portal"; /* large enough */
int len = strlen(msg);
if (deadlock_detected == SPECIFIED_ERROR)
pool_log("Execute: received deadlock error message from master node. query: %s", string);
+ else if (serialization_error_detected == SPECIFIED_ERROR)
+ pool_log("SimpleQuery: received serialization failure error message from master node. query: %s", string);
else
- pool_log("Execute: received serialization failure error message from master node. query: %s", string);
+ pool_log("SimpleQuery: received SET TRANSACTION ISOLATION LEVEL must be called before any query error. query: %s", string);
memset(msg + len, 0, sizeof(int));
if (send_execute_message(backend, i, len + 5, msg))
[parent: aaec285ed8b9]