diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c index 6ebe75a..d74e9a5 100644 --- a/src/backend/catalog/storage.c +++ b/src/backend/catalog/storage.c @@ -405,6 +405,21 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst, smgrimmedsync(dst, forkNum); } +bool +hasPendingSync(Relation rel) +{ + PendingRelOps *pending; + + for (pending = pendingDeletes; pending != NULL; pending = pending->next) + { + if (RelFileNodeEquals(pending->relnode, rel->rd_node) && + pending->backend == rel->rd_backend && + pending->dosync) + return true; + } + return false; +} + /* * smgrDoPendingOperations() -- Take care of relation deletes and syncs at * end of xact. diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h index cd51df4..66fb8dc 100644 --- a/src/include/utils/rel.h +++ b/src/include/utils/rel.h @@ -513,6 +513,20 @@ typedef struct ViewOptions (relation)->rd_smgr->smgr_targblock = (targblock); \ } while (0) +static inline bool +subids_need_wal(Relation relation) +{ + extern bool hasPendingSync(Relation rel); + bool relcache_verdict = + (relation->rd_createSubid == InvalidSubTransactionId && + relation->rd_firstRelfilenodeSubid == InvalidSubTransactionId); + bool storage_verdict = !hasPendingSync(relation); + + Assert(relcache_verdict == storage_verdict); + + return relcache_verdict; +} + /* * RelationNeedsWAL * True if relation needs WAL. @@ -521,10 +535,8 @@ typedef struct ViewOptions * truncated in the current transaction. */ #define RelationNeedsWAL(relation) \ - ((relation)->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT && \ - (XLogIsNeeded() || \ - (relation->rd_createSubid == InvalidSubTransactionId && \ - relation->rd_firstRelfilenodeSubid == InvalidSubTransactionId))) + ((relation)->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT && \ + (XLogIsNeeded() || subids_need_wal(relation))) /* * RelationUsesLocalBuffers diff --git a/src/test/recovery/t/018_wal_optimize.pl b/src/test/recovery/t/018_wal_optimize.pl index b26cd8e..56b92b4 100644 --- a/src/test/recovery/t/018_wal_optimize.pl +++ b/src/test/recovery/t/018_wal_optimize.pl @@ -157,6 +157,16 @@ wal_level = $wal_level is($result, qq(3), "wal_level = $wal_level, SET TABLESPACE in subtransaction"); + $node->safe_psql('postgres', " + CREATE TABLE test2a (id int); + BEGIN; + TRUNCATE test2a; + SAVEPOINT s; + TRUNCATE test2a; + ROLLBACK TO s; + INSERT INTO test2a DEFAULT VALUES; + COMMIT;"); + # UPDATE touches two buffers; one is BufferNeedsWAL(); the other is not. $node->safe_psql('postgres', " BEGIN;