Hi All,
While testing a parallel scan feature on standby server, it is found that
the parallel query fails with an error "*ERROR: failed to initialize
transaction_read_only to 0*".
Following are the steps used to reproduce the issue:
*Master :-*
edb=# create table ert(n int);
edb=# insert into ert values (generate_series(1,5000000));
edb=# analyze ert;
edb=# vacuum ert;
*Slave :-*
edb=# set max_parallel_degree =5;
SET
edb=# explain analyze verbose select * from ert where n<=1000;
ERROR: failed to initialize transaction_read_only to 0
CONTEXT: parallel worker, PID 26042
*Root cause Analysis:* After debugging the worker, it is observed that in
*RestoreGUCState()*, if a guc var can't be skipped it is Initialiazed with
a default value and
in this process when a guc variable "*transaction_read_only*" is being
Initialzed it calls a check_hook *check_transaction_read_only()* which
eventually fails due to
below check which says the guc var "*transaction_read_only*" can't be set
while recovery is in progress:
*if
(RecoveryInProgress()){GUC_check_errcode(ERRCODE_FEATURE_NOT_SUPPORTED);GUC_check_errmsg("cannot
set transaction read-write mode during recovery");return false;}*
*Solution:* Make use of a global variable "*InitializingParallelWorker"* to
protect the check for *RecoveryInProgress()* when Parallel Worker is being
Initialsed.
PFA patch to fix the issue.
With Regards,
Ashutosh Sharma
EnterpriseDB: *http://www.enterprisedb.com <http://www.enterprisedb.com>*
diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c
index 903b3a6..c7173c9 100644
--- a/src/backend/commands/variable.c
+++ b/src/backend/commands/variable.c
@@ -482,11 +482,13 @@ show_log_timezone(void)
* nothing since XactReadOnly will be reset by the next StartTransaction().
* The IsTransactionState() test protects us against trying to check
* RecoveryInProgress() in contexts where shared memory is not accessible.
+ * We can also skip the check for RecoveryInProgress while initializing the
+ * Parallel Workers by making use of the global variable InitializingParallelWorker.
*/
bool
check_transaction_read_only(bool *newval, void **extra, GucSource source)
{
- if (*newval == false && XactReadOnly && IsTransactionState())
+ if (*newval == false && XactReadOnly && IsTransactionState() && !InitializingParallelWorker)
{
/* Can't go to r/w mode inside a r/o transaction */
if (IsSubTransaction())
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers