public inbox for [email protected]
help / color / mirror / Atom feedFrom: Tatsuo Ishii <[email protected]>
Subject: [PATCH v1] Fix disable_load_balance_on_write and query cache.
Date: Sat, 23 May 2026 20:06:25 +0900
The disable_load_balance_on_write accepts for options:
transaction (the default)
trans_transaction
dml_adaptive
always
It appeared that except "transaction", all other options break query
cache feature. Sometimes a query result is cached even there's a write
query in a transaction, sometimes query is not cached even when it
should be.
The query cache relies on is_writing_transaction of session context to
judge whether cache can be safely used. However,
disable_load_balance_on_write overrides it to true when it should not,
and vice versa for its own purpose. To fix this new session context
variable "really_writing_transaction" is introduced. It is almost same
as existing writing_transaction, but it faithfully tracks whether a
writing query appears in an explicit transaction. The query cache uses
it instead of writing_transaction variable.
Author: Tatsuo Ishii <[email protected]>
Discussion:
Backpatch-through: v4.3
---
src/context/pool_session_context.c | 22 ++++++++++++++++++++++
src/include/context/pool_session_context.h | 19 ++++++++++++++++++-
src/protocol/CommandComplete.c | 1 +
src/protocol/pool_process_query.c | 1 +
src/protocol/pool_proto_modules.c | 17 +++++++++++++----
5 files changed, 55 insertions(+), 5 deletions(-)
diff --git a/src/context/pool_session_context.c b/src/context/pool_session_context.c
index ded41c7fc..a87cce164 100644
--- a/src/context/pool_session_context.c
+++ b/src/context/pool_session_context.c
@@ -125,6 +125,7 @@ pool_init_session_context(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backe
/* We don't have a write query in this transaction yet */
pool_unset_writing_transaction();
+ pool_unset_really_writing_transaction();
/* Error doesn't occur in this transaction yet */
pool_unset_failed_transaction();
@@ -731,6 +732,12 @@ pool_unset_writing_transaction(void)
}
}
+void
+pool_unset_really_writing_transaction(void)
+{
+ pool_get_session_context(false)->really_writing_transaction = false;
+}
+
/*
* We have a write query in this transaction.
*/
@@ -749,6 +756,12 @@ pool_set_writing_transaction(void)
}
}
+void
+pool_set_really_writing_transaction(void)
+{
+ pool_get_session_context(false)->really_writing_transaction = true;
+}
+
/*
* Do we have a write query in this transaction?
*/
@@ -758,6 +771,15 @@ pool_is_writing_transaction(void)
return pool_get_session_context(false)->writing_transaction;
}
+/*
+ * Do we really have a write query in this transaction?
+ */
+bool
+pool_is_really_writing_transaction(void)
+{
+ return pool_get_session_context(false)->really_writing_transaction;
+}
+
/*
* Error doesn't occur in this transaction yet.
*/
diff --git a/src/include/context/pool_session_context.h b/src/include/context/pool_session_context.h
index eba56982b..16e24613d 100644
--- a/src/include/context/pool_session_context.h
+++ b/src/include/context/pool_session_context.h
@@ -209,9 +209,23 @@ typedef struct
/* If true, the command in progress has finished successfully. */
bool command_success;
- /* If true, write query has been appeared in this transaction */
+ /*
+ * If true, write query has been appeared in this transaction. Note that
+ * the flag may not be turned off even if a transaction is started or
+ * committed if disable_load_balance_on_write is other than "transaction".
+ * Also if disable_load_balance_on_write is "dml_adaptive", the flag is
+ * never be turned on.
+ */
bool writing_transaction;
+ /*
+ * Unlike "writing_transaction", this flag is turned on whenever writing
+ * query is issued in an explicit transaction, and is turned off when the
+ * transaction is closed. Of course turned off when new transaction
+ * starts. This flag is referenced by query cache.
+ */
+ bool really_writing_transaction;
+
/* If true, error occurred in this transaction */
bool failed_transaction;
@@ -384,8 +398,11 @@ extern void pool_set_sent_message_state(POOL_SENT_MESSAGE *message);
extern void pool_zap_query_context_in_sent_messages(POOL_QUERY_CONTEXT *query_context);
extern POOL_SENT_MESSAGE *pool_get_sent_message_by_query_context(POOL_QUERY_CONTEXT *query_context);
extern void pool_unset_writing_transaction(void);
+extern void pool_unset_really_writing_transaction(void);
extern void pool_set_writing_transaction(void);
+extern void pool_set_really_writing_transaction(void);
extern bool pool_is_writing_transaction(void);
+extern bool pool_is_really_writing_transaction(void);
extern void pool_unset_failed_transaction(void);
extern void pool_set_failed_transaction(void);
extern bool pool_is_failed_transaction(void);
diff --git a/src/protocol/CommandComplete.c b/src/protocol/CommandComplete.c
index a3b8f0ea1..1f63a0e8d 100644
--- a/src/protocol/CommandComplete.c
+++ b/src/protocol/CommandComplete.c
@@ -370,6 +370,7 @@ handle_query_context(POOL_CONNECTION_POOL *backend)
if (pool_config->disable_load_balance_on_write != DLBOW_TRANS_TRANSACTION)
pool_unset_writing_transaction();
+ pool_unset_really_writing_transaction();
pool_unset_failed_transaction();
pool_unset_transaction_isolation();
diff --git a/src/protocol/pool_process_query.c b/src/protocol/pool_process_query.c
index dacaa9d5a..fdc8d97e0 100644
--- a/src/protocol/pool_process_query.c
+++ b/src/protocol/pool_process_query.c
@@ -4187,6 +4187,7 @@ start_internal_transaction(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *back
/* Mark that we started new transaction */
INTERNAL_TRANSACTION_STARTED(backend, i) = true;
pool_unset_writing_transaction();
+ pool_unset_really_writing_transaction();
}
}
}
diff --git a/src/protocol/pool_proto_modules.c b/src/protocol/pool_proto_modules.c
index 65ed190ef..86fb5f8a8 100644
--- a/src/protocol/pool_proto_modules.c
+++ b/src/protocol/pool_proto_modules.c
@@ -270,7 +270,7 @@ SimpleQuery(POOL_CONNECTION *frontend,
* query cache.
*/
if (pool_config->memory_cache_enabled && is_likely_select &&
- !pool_is_writing_transaction() &&
+ !pool_is_really_writing_transaction() &&
TSTATE(backend, MAIN_REPLICA ? PRIMARY_NODE_ID : REAL_MAIN_NODE_ID) != 'E' &&
!query_cache_disabled())
{
@@ -1029,7 +1029,7 @@ Execute(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend,
* message has 0 row argument, we maybe able to use cache. If
* partial_fetch is true, cannot use cache.
*/
- if (pool_config->memory_cache_enabled && !pool_is_writing_transaction() &&
+ if (pool_config->memory_cache_enabled && !pool_is_really_writing_transaction() &&
(TSTATE(backend, MAIN_REPLICA ? PRIMARY_NODE_ID : REAL_MAIN_NODE_ID) != 'E')
&& pool_is_likely_select(query) && !query_cache_disabled() &&
(query_context->atEnd || num_rows == 0) &&
@@ -1276,6 +1276,8 @@ Execute(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend,
if (!pool_is_transaction_read_only(node))
{
pool_set_writing_transaction();
+ if (TSTATE(backend, MAIN_REPLICA ? PRIMARY_NODE_ID : REAL_MAIN_NODE_ID) == 'T')
+ pool_set_really_writing_transaction();
}
}
}
@@ -4745,7 +4747,7 @@ pool_at_command_success(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend
{
if (pool_config->disable_load_balance_on_write != DLBOW_TRANS_TRANSACTION)
pool_unset_writing_transaction();
-
+ pool_unset_really_writing_transaction();
pool_unset_failed_transaction();
pool_unset_transaction_isolation();
}
@@ -4759,7 +4761,7 @@ pool_at_command_success(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend
{
if (pool_config->disable_load_balance_on_write != DLBOW_TRANS_TRANSACTION)
pool_unset_writing_transaction();
-
+ pool_unset_really_writing_transaction();
pool_unset_failed_transaction();
pool_unset_transaction_isolation();
}
@@ -4804,6 +4806,13 @@ pool_at_command_success(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend
(errmsg("not SET TRANSACTION READ ONLY")));
pool_set_writing_transaction();
+
+ /*
+ * In case in transaction, we need to
+ * really_writing_transaction so that query cache is disabled.
+ */
+ if (TSTATE(backend, MAIN_REPLICA ? PRIMARY_NODE_ID : REAL_MAIN_NODE_ID) == 'T')
+ pool_set_really_writing_transaction();
}
}
--
2.43.0
----Next_Part(Sat_May_23_20_18_16_2026_327)----
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected]
Subject: Re: [PATCH v1] Fix disable_load_balance_on_write and query cache.
In-Reply-To: <no-message-id-1122@localhost>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox