Skip to content

Commit 1a2654b

Browse files
committed
Rework redundant code in subtrans.c
When this code was written the duplicity didn't matter, but with all the SLRU-bank stuff we just added, it has become excessive. Turn it into a simpler loop with no code duplication. Also add a test so that this code becomes covered. Discussion: https://postgr.es/m/202403041517.3a35jw53os65@alvherre.pgsql
1 parent 030e10f commit 1a2654b

File tree

2 files changed

+49
-22
lines changed

2 files changed

+49
-22
lines changed

src/backend/access/transam/subtrans.c

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ StartupSUBTRANS(TransactionId oldestActiveXID)
311311
FullTransactionId nextXid;
312312
int64 startPage;
313313
int64 endPage;
314-
LWLock *prevlock;
314+
LWLock *prevlock = NULL;
315315
LWLock *lock;
316316

317317
/*
@@ -324,42 +324,27 @@ StartupSUBTRANS(TransactionId oldestActiveXID)
324324
nextXid = TransamVariables->nextXid;
325325
endPage = TransactionIdToPage(XidFromFullTransactionId(nextXid));
326326

327-
prevlock = SimpleLruGetBankLock(SubTransCtl, startPage);
328-
LWLockAcquire(prevlock, LW_EXCLUSIVE);
329-
while (startPage != endPage)
327+
for (;;)
330328
{
331329
lock = SimpleLruGetBankLock(SubTransCtl, startPage);
332-
333-
/*
334-
* Check if we need to acquire the lock on the new bank then release
335-
* the lock on the old bank and acquire on the new bank.
336-
*/
337330
if (prevlock != lock)
338331
{
339-
LWLockRelease(prevlock);
332+
if (prevlock)
333+
LWLockRelease(prevlock);
340334
LWLockAcquire(lock, LW_EXCLUSIVE);
341335
prevlock = lock;
342336
}
343337

344338
(void) ZeroSUBTRANSPage(startPage);
339+
if (startPage == endPage)
340+
break;
341+
345342
startPage++;
346343
/* must account for wraparound */
347344
if (startPage > TransactionIdToPage(MaxTransactionId))
348345
startPage = 0;
349346
}
350347

351-
lock = SimpleLruGetBankLock(SubTransCtl, startPage);
352-
353-
/*
354-
* Check if we need to acquire the lock on the new bank then release the
355-
* lock on the old bank and acquire on the new bank.
356-
*/
357-
if (prevlock != lock)
358-
{
359-
LWLockRelease(prevlock);
360-
LWLockAcquire(lock, LW_EXCLUSIVE);
361-
}
362-
(void) ZeroSUBTRANSPage(startPage);
363348
LWLockRelease(lock);
364349
}
365350

src/test/recovery/t/009_twophase.pl

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ sub configure_and_reload
4545
my $node_paris = PostgreSQL::Test::Cluster->new('paris');
4646
$node_paris->init_from_backup($node_london, 'london_backup',
4747
has_streaming => 1);
48+
$node_paris->append_conf(
49+
'postgresql.conf', qq(
50+
subtransaction_buffers = 32
51+
));
4852
$node_paris->start;
4953

5054
# Switch to synchronous replication in both directions
@@ -481,4 +485,42 @@ sub configure_and_reload
481485
qq{27|issued to paris},
482486
"Check expected t_009_tbl2 data on standby");
483487

488+
489+
# Exercise the 2PC recovery code in StartupSUBTRANS, which is concerned with
490+
# ensuring that enough pg_subtrans pages exist on disk to cover the range of
491+
# prepared transactions at server start time. There's not much we can verify
492+
# directly, but let's at least get the code to run.
493+
$cur_standby->stop();
494+
configure_and_reload($cur_primary, "synchronous_standby_names = ''");
495+
496+
$cur_primary->safe_psql('postgres', "CHECKPOINT");
497+
498+
my $start_lsn =
499+
$cur_primary->safe_psql('postgres', 'select pg_current_wal_insert_lsn()');
500+
$cur_primary->safe_psql('postgres',
501+
"CREATE TABLE test(); BEGIN; CREATE TABLE test1(); PREPARE TRANSACTION 'foo';"
502+
);
503+
my $osubtrans = $cur_primary->safe_psql('postgres',
504+
"select 'pg_subtrans/'||f, s.size from pg_ls_dir('pg_subtrans') f, pg_stat_file('pg_subtrans/'||f) s"
505+
);
506+
$cur_primary->pgbench(
507+
'--no-vacuum --client=5 --transactions=1000',
508+
0,
509+
[],
510+
[],
511+
'pgbench run to cause pg_subtrans traffic',
512+
{
513+
'009_twophase.pgb' => 'insert into test default values'
514+
});
515+
# StartupSUBTRANS is exercised with a wide range of visible XIDs in this
516+
# stop/start sequence, because we left a prepared transaction open above.
517+
# Also, setting subtransaction_buffers to 32 above causes to switch SLRU
518+
# bank, for additional code coverage.
519+
$cur_primary->stop;
520+
$cur_primary->start;
521+
my $nsubtrans = $cur_primary->safe_psql('postgres',
522+
"select 'pg_subtrans/'||f, s.size from pg_ls_dir('pg_subtrans') f, pg_stat_file('pg_subtrans/'||f) s"
523+
);
524+
isnt($osubtrans, $nsubtrans, "contents of pg_subtrans/ have changed");
525+
484526
done_testing();

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy