diff --git a/doc/src/sgml/indexam.sgml b/doc/src/sgml/indexam.sgml index d4163c96e9f..cf359fa9ffd 100644 --- a/doc/src/sgml/indexam.sgml +++ b/doc/src/sgml/indexam.sgml @@ -126,8 +126,6 @@ typedef struct IndexAmRoutine bool amcaninclude; /* does AM use maintenance_work_mem? */ bool amusemaintenanceworkmem; - /* does AM block HOT update? */ - bool amhotblocking; /* OR of parallel vacuum flags */ uint8 amparallelvacuumoptions; /* type of data stored in index, or InvalidOid if variable */ @@ -248,15 +246,6 @@ typedef struct IndexAmRoutine null, independently of amoptionalkey. - - The amhotblocking flag indicates whether the - access method blocks HOT when an indexed attribute is - updated. Access methods without pointers to individual tuples (like - BRIN) may allow HOT even in this - case. This does not apply to attributes referenced in index predicates; - an update of such attribute always disables HOT. - - diff --git a/src/backend/access/brin/brin.c b/src/backend/access/brin/brin.c index 0de1441dc6d..e88f7efa7e4 100644 --- a/src/backend/access/brin/brin.c +++ b/src/backend/access/brin/brin.c @@ -108,7 +108,6 @@ brinhandler(PG_FUNCTION_ARGS) amroutine->amcanparallel = false; amroutine->amcaninclude = false; amroutine->amusemaintenanceworkmem = false; - amroutine->amhotblocking = false; amroutine->amparallelvacuumoptions = VACUUM_OPTION_PARALLEL_CLEANUP; amroutine->amkeytype = InvalidOid; diff --git a/src/backend/access/gin/ginutil.c b/src/backend/access/gin/ginutil.c index 3d15701a01e..20f470648be 100644 --- a/src/backend/access/gin/ginutil.c +++ b/src/backend/access/gin/ginutil.c @@ -56,7 +56,6 @@ ginhandler(PG_FUNCTION_ARGS) amroutine->amcanparallel = false; amroutine->amcaninclude = false; amroutine->amusemaintenanceworkmem = true; - amroutine->amhotblocking = true; amroutine->amparallelvacuumoptions = VACUUM_OPTION_PARALLEL_BULKDEL | VACUUM_OPTION_PARALLEL_CLEANUP; amroutine->amkeytype = InvalidOid; diff --git a/src/backend/access/gist/gist.c b/src/backend/access/gist/gist.c index 8c6c744ab74..5866c6aaaf7 100644 --- a/src/backend/access/gist/gist.c +++ b/src/backend/access/gist/gist.c @@ -78,7 +78,6 @@ gisthandler(PG_FUNCTION_ARGS) amroutine->amcanparallel = false; amroutine->amcaninclude = true; amroutine->amusemaintenanceworkmem = false; - amroutine->amhotblocking = true; amroutine->amparallelvacuumoptions = VACUUM_OPTION_PARALLEL_BULKDEL | VACUUM_OPTION_PARALLEL_COND_CLEANUP; amroutine->amkeytype = InvalidOid; diff --git a/src/backend/access/hash/hash.c b/src/backend/access/hash/hash.c index fd1a7119b6c..c361509d68d 100644 --- a/src/backend/access/hash/hash.c +++ b/src/backend/access/hash/hash.c @@ -75,7 +75,6 @@ hashhandler(PG_FUNCTION_ARGS) amroutine->amcanparallel = false; amroutine->amcaninclude = false; amroutine->amusemaintenanceworkmem = false; - amroutine->amhotblocking = true; amroutine->amparallelvacuumoptions = VACUUM_OPTION_PARALLEL_BULKDEL; amroutine->amkeytype = INT4OID; diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index 74218510276..637de1116c9 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -3190,7 +3190,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, * Note that we get copies of each bitmap, so we need not worry about * relcache flush happening midway through. */ - hot_attrs = RelationGetIndexAttrBitmap(relation, INDEX_ATTR_BITMAP_HOT_BLOCKING); + hot_attrs = RelationGetIndexAttrBitmap(relation, INDEX_ATTR_BITMAP_ALL); key_attrs = RelationGetIndexAttrBitmap(relation, INDEX_ATTR_BITMAP_KEY); id_attrs = RelationGetIndexAttrBitmap(relation, INDEX_ATTR_BITMAP_IDENTITY_KEY); diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c index 06131f23d4b..9b730f303fb 100644 --- a/src/backend/access/nbtree/nbtree.c +++ b/src/backend/access/nbtree/nbtree.c @@ -114,7 +114,6 @@ bthandler(PG_FUNCTION_ARGS) amroutine->amcanparallel = true; amroutine->amcaninclude = true; amroutine->amusemaintenanceworkmem = false; - amroutine->amhotblocking = true; amroutine->amparallelvacuumoptions = VACUUM_OPTION_PARALLEL_BULKDEL | VACUUM_OPTION_PARALLEL_COND_CLEANUP; amroutine->amkeytype = InvalidOid; diff --git a/src/backend/access/spgist/spgutils.c b/src/backend/access/spgist/spgutils.c index a171ca8a08a..2c661fcf96f 100644 --- a/src/backend/access/spgist/spgutils.c +++ b/src/backend/access/spgist/spgutils.c @@ -62,7 +62,6 @@ spghandler(PG_FUNCTION_ARGS) amroutine->amcanparallel = false; amroutine->amcaninclude = true; amroutine->amusemaintenanceworkmem = false; - amroutine->amhotblocking = true; amroutine->amparallelvacuumoptions = VACUUM_OPTION_PARALLEL_BULKDEL | VACUUM_OPTION_PARALLEL_COND_CLEANUP; amroutine->amkeytype = InvalidOid; diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index 60e72f9e8bf..0e8fda97f86 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -2439,10 +2439,10 @@ RelationDestroyRelation(Relation relation, bool remember_tupdesc) list_free_deep(relation->rd_fkeylist); list_free(relation->rd_indexlist); list_free(relation->rd_statlist); + bms_free(relation->rd_indexattr); bms_free(relation->rd_keyattr); bms_free(relation->rd_pkattr); bms_free(relation->rd_idattr); - bms_free(relation->rd_hotblockingattr); if (relation->rd_pubdesc) pfree(relation->rd_pubdesc); if (relation->rd_options) @@ -5104,10 +5104,10 @@ RelationGetIndexPredicate(Relation relation) Bitmapset * RelationGetIndexAttrBitmap(Relation relation, IndexAttrBitmapKind attrKind) { + Bitmapset *indexattrs; /* indexed columns */ Bitmapset *uindexattrs; /* columns in unique indexes */ Bitmapset *pkindexattrs; /* columns in the primary index */ Bitmapset *idindexattrs; /* columns in the replica identity */ - Bitmapset *hotblockingattrs; /* columns with HOT blocking indexes */ List *indexoidlist; List *newindexoidlist; Oid relpkindex; @@ -5116,18 +5116,18 @@ RelationGetIndexAttrBitmap(Relation relation, IndexAttrBitmapKind attrKind) MemoryContext oldcxt; /* Quick exit if we already computed the result. */ - if (relation->rd_attrsvalid) + if (relation->rd_indexattr != NULL) { switch (attrKind) { + case INDEX_ATTR_BITMAP_ALL: + return bms_copy(relation->rd_indexattr); case INDEX_ATTR_BITMAP_KEY: return bms_copy(relation->rd_keyattr); case INDEX_ATTR_BITMAP_PRIMARY_KEY: return bms_copy(relation->rd_pkattr); case INDEX_ATTR_BITMAP_IDENTITY_KEY: return bms_copy(relation->rd_idattr); - case INDEX_ATTR_BITMAP_HOT_BLOCKING: - return bms_copy(relation->rd_hotblockingattr); default: elog(ERROR, "unknown attrKind %u", attrKind); } @@ -5158,7 +5158,7 @@ restart: relreplindex = relation->rd_replidindex; /* - * For each index, add referenced attributes to appropriate bitmaps. + * For each index, add referenced attributes to indexattrs. * * Note: we consider all indexes returned by RelationGetIndexList, even if * they are not indisready or indisvalid. This is important because an @@ -5167,10 +5167,10 @@ restart: * CONCURRENTLY is far enough along that we should ignore the index, it * won't be returned at all by RelationGetIndexList. */ + indexattrs = NULL; uindexattrs = NULL; pkindexattrs = NULL; idindexattrs = NULL; - hotblockingattrs = NULL; foreach(l, indexoidlist) { Oid indexOid = lfirst_oid(l); @@ -5235,9 +5235,8 @@ restart: */ if (attrnum != 0) { - if (indexDesc->rd_indam->amhotblocking) - hotblockingattrs = bms_add_member(hotblockingattrs, - attrnum - FirstLowInvalidHeapAttributeNumber); + indexattrs = bms_add_member(indexattrs, + attrnum - FirstLowInvalidHeapAttributeNumber); if (isKey && i < indexDesc->rd_index->indnkeyatts) uindexattrs = bms_add_member(uindexattrs, @@ -5254,15 +5253,10 @@ restart: } /* Collect all attributes used in expressions, too */ - if (indexDesc->rd_indam->amhotblocking) - pull_varattnos(indexExpressions, 1, &hotblockingattrs); + pull_varattnos(indexExpressions, 1, &indexattrs); - /* - * Collect all attributes in the index predicate, too. We have to - * ignore amhotblocking flag, because the row might become indexable, - * in which case we have to add it to the index. - */ - pull_varattnos(indexPredicate, 1, &hotblockingattrs); + /* Collect all attributes in the index predicate, too */ + pull_varattnos(indexPredicate, 1, &indexattrs); index_close(indexDesc, AccessShareLock); } @@ -5290,46 +5284,46 @@ restart: bms_free(uindexattrs); bms_free(pkindexattrs); bms_free(idindexattrs); - bms_free(hotblockingattrs); + bms_free(indexattrs); goto restart; } /* Don't leak the old values of these bitmaps, if any */ + bms_free(relation->rd_indexattr); + relation->rd_indexattr = NULL; bms_free(relation->rd_keyattr); relation->rd_keyattr = NULL; bms_free(relation->rd_pkattr); relation->rd_pkattr = NULL; bms_free(relation->rd_idattr); relation->rd_idattr = NULL; - bms_free(relation->rd_hotblockingattr); - relation->rd_hotblockingattr = NULL; /* * Now save copies of the bitmaps in the relcache entry. We intentionally - * set rd_attrsvalid last, because that's what signals validity of the - * values; if we run out of memory before making that copy, we won't leave - * the relcache entry looking like the other ones are valid but empty. + * set rd_indexattr last, because that's the one that signals validity of + * the values; if we run out of memory before making that copy, we won't + * leave the relcache entry looking like the other ones are valid but + * empty. */ oldcxt = MemoryContextSwitchTo(CacheMemoryContext); relation->rd_keyattr = bms_copy(uindexattrs); relation->rd_pkattr = bms_copy(pkindexattrs); relation->rd_idattr = bms_copy(idindexattrs); - relation->rd_hotblockingattr = bms_copy(hotblockingattrs); - relation->rd_attrsvalid = true; + relation->rd_indexattr = bms_copy(indexattrs); MemoryContextSwitchTo(oldcxt); /* We return our original working copy for caller to play with */ switch (attrKind) { + case INDEX_ATTR_BITMAP_ALL: + return indexattrs; case INDEX_ATTR_BITMAP_KEY: return uindexattrs; case INDEX_ATTR_BITMAP_PRIMARY_KEY: return pkindexattrs; case INDEX_ATTR_BITMAP_IDENTITY_KEY: return idindexattrs; - case INDEX_ATTR_BITMAP_HOT_BLOCKING: - return hotblockingattrs; default: elog(ERROR, "unknown attrKind %u", attrKind); return NULL; @@ -6250,11 +6244,10 @@ load_relcache_init_file(bool shared) rel->rd_indexlist = NIL; rel->rd_pkindex = InvalidOid; rel->rd_replidindex = InvalidOid; - rel->rd_attrsvalid = false; + rel->rd_indexattr = NULL; rel->rd_keyattr = NULL; rel->rd_pkattr = NULL; rel->rd_idattr = NULL; - rel->rd_hotblockingattr = NULL; rel->rd_pubdesc = NULL; rel->rd_statvalid = false; rel->rd_statlist = NIL; diff --git a/src/include/access/amapi.h b/src/include/access/amapi.h index 0b89f399f08..1dc674d2305 100644 --- a/src/include/access/amapi.h +++ b/src/include/access/amapi.h @@ -244,8 +244,6 @@ typedef struct IndexAmRoutine bool amcaninclude; /* does AM use maintenance_work_mem? */ bool amusemaintenanceworkmem; - /* does AM block HOT update? */ - bool amhotblocking; /* OR of parallel vacuum flags. See vacuum.h for flags. */ uint8 amparallelvacuumoptions; /* type of data stored in index, or InvalidOid if variable */ diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h index 90b3c49bc12..1896a9a06d1 100644 --- a/src/include/utils/rel.h +++ b/src/include/utils/rel.h @@ -155,11 +155,10 @@ typedef struct RelationData List *rd_statlist; /* list of OIDs of extended stats */ /* data managed by RelationGetIndexAttrBitmap: */ - bool rd_attrsvalid; /* are bitmaps of attrs valid? */ + Bitmapset *rd_indexattr; /* identifies columns used in indexes */ Bitmapset *rd_keyattr; /* cols that can be ref'd by foreign keys */ Bitmapset *rd_pkattr; /* cols included in primary key */ Bitmapset *rd_idattr; /* included in replica identity index */ - Bitmapset *rd_hotblockingattr; /* cols blocking HOT update */ PublicationDesc *rd_pubdesc; /* publication descriptor, or NULL */ diff --git a/src/include/utils/relcache.h b/src/include/utils/relcache.h index 86dddbd975d..c93d8654bb9 100644 --- a/src/include/utils/relcache.h +++ b/src/include/utils/relcache.h @@ -55,10 +55,10 @@ extern bytea **RelationGetIndexAttOptions(Relation relation, bool copy); typedef enum IndexAttrBitmapKind { + INDEX_ATTR_BITMAP_ALL, INDEX_ATTR_BITMAP_KEY, INDEX_ATTR_BITMAP_PRIMARY_KEY, - INDEX_ATTR_BITMAP_IDENTITY_KEY, - INDEX_ATTR_BITMAP_HOT_BLOCKING + INDEX_ATTR_BITMAP_IDENTITY_KEY } IndexAttrBitmapKind; extern Bitmapset *RelationGetIndexAttrBitmap(Relation relation, diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c index 22578b6246e..a0894ff9860 100644 --- a/src/test/modules/dummy_index_am/dummy_index_am.c +++ b/src/test/modules/dummy_index_am/dummy_index_am.c @@ -298,7 +298,6 @@ dihandler(PG_FUNCTION_ARGS) amroutine->amcanparallel = false; amroutine->amcaninclude = false; amroutine->amusemaintenanceworkmem = false; - amroutine->amhotblocking = true; amroutine->amparallelvacuumoptions = VACUUM_OPTION_NO_PARALLEL; amroutine->amkeytype = InvalidOid; diff --git a/src/test/regress/expected/brin.out b/src/test/regress/expected/brin.out index 96cbb5de4ef..ae4c424e79f 100644 --- a/src/test/regress/expected/brin.out +++ b/src/test/regress/expected/brin.out @@ -567,61 +567,3 @@ SELECT * FROM brintest_3 WHERE b < '0'; DROP TABLE brintest_3; RESET enable_seqscan; --- Test handling of index predicates - updating attributes in predicates --- should block HOT even for BRIN. We update a row that was not indexed --- due to the index predicate, and becomes indexable. -CREATE TABLE brin_hot_2 (a int, b int); -INSERT INTO brin_hot_2 VALUES (1, 100); -CREATE INDEX ON brin_hot_2 USING brin (b) WHERE a = 2; -UPDATE brin_hot_2 SET a = 2; -EXPLAIN (COSTS OFF) SELECT * FROM brin_hot_2 WHERE a = 2 AND b = 100; - QUERY PLAN ------------------------------------ - Seq Scan on brin_hot_2 - Filter: ((a = 2) AND (b = 100)) -(2 rows) - -SELECT COUNT(*) FROM brin_hot_2 WHERE a = 2 AND b = 100; - count -------- - 1 -(1 row) - -SET enable_seqscan = off; -EXPLAIN (COSTS OFF) SELECT * FROM brin_hot_2 WHERE a = 2 AND b = 100; - QUERY PLAN ---------------------------------------------- - Bitmap Heap Scan on brin_hot_2 - Recheck Cond: ((b = 100) AND (a = 2)) - -> Bitmap Index Scan on brin_hot_2_b_idx - Index Cond: (b = 100) -(4 rows) - -SELECT COUNT(*) FROM brin_hot_2 WHERE a = 2 AND b = 100; - count -------- - 1 -(1 row) - --- test BRIN index doesn't block HOT update -CREATE TABLE brin_hot ( - id integer PRIMARY KEY, - val integer NOT NULL -) WITH (autovacuum_enabled = off, fillfactor = 70); -INSERT INTO brin_hot SELECT *, 0 FROM generate_series(1, 235); -CREATE INDEX val_brin ON brin_hot using brin(val); -UPDATE brin_hot SET val = -3 WHERE id = 42; --- ensure pending stats are flushed -SELECT pg_stat_force_next_flush(); - pg_stat_force_next_flush --------------------------- - -(1 row) - -SELECT pg_stat_get_tuples_hot_updated('brin_hot'::regclass::oid); - pg_stat_get_tuples_hot_updated --------------------------------- - 1 -(1 row) - -DROP TABLE brin_hot; diff --git a/src/test/regress/expected/stats.out b/src/test/regress/expected/stats.out index 6b233ff4c05..5b0ebf090f4 100644 --- a/src/test/regress/expected/stats.out +++ b/src/test/regress/expected/stats.out @@ -554,246 +554,4 @@ SELECT pg_stat_get_live_tuples(:drop_stats_test_subxact_oid); DROP TABLE trunc_stats_test, trunc_stats_test1, trunc_stats_test2, trunc_stats_test3, trunc_stats_test4; DROP TABLE prevstats; ------ --- Test that various stats views are being properly populated ------ --- Test that sessions is incremented when a new session is started in pg_stat_database -SELECT sessions AS db_stat_sessions FROM pg_stat_database WHERE datname = (SELECT current_database()) \gset -\c -SELECT sessions > :db_stat_sessions FROM pg_stat_database WHERE datname = (SELECT current_database()); - ?column? ----------- - t -(1 row) - --- Test pg_stat_bgwriter checkpointer-related stats, together with pg_stat_wal -SELECT checkpoints_req AS rqst_ckpts_before FROM pg_stat_bgwriter \gset --- Test pg_stat_wal -SELECT wal_bytes AS wal_bytes_before FROM pg_stat_wal \gset -CREATE TABLE test_stats_temp AS SELECT 17; -DROP TABLE test_stats_temp; --- Checkpoint twice: The checkpointer reports stats after reporting completion --- of the checkpoint. But after a second checkpoint we'll see at least the --- results of the first. -CHECKPOINT; -CHECKPOINT; -SELECT checkpoints_req > :rqst_ckpts_before FROM pg_stat_bgwriter; - ?column? ----------- - t -(1 row) - -SELECT wal_bytes > :wal_bytes_before FROM pg_stat_wal; - ?column? ----------- - t -(1 row) - ------ --- Test that resetting stats works for reset timestamp ------ --- Test that reset_slru with a specified SLRU works. -SELECT stats_reset AS slru_commit_ts_reset_ts FROM pg_stat_slru WHERE name = 'CommitTs' \gset -SELECT stats_reset AS slru_notify_reset_ts FROM pg_stat_slru WHERE name = 'Notify' \gset -SELECT pg_stat_reset_slru('CommitTs'); - pg_stat_reset_slru --------------------- - -(1 row) - -SELECT stats_reset > :'slru_commit_ts_reset_ts'::timestamptz FROM pg_stat_slru WHERE name = 'CommitTs'; - ?column? ----------- - t -(1 row) - -SELECT stats_reset AS slru_commit_ts_reset_ts FROM pg_stat_slru WHERE name = 'CommitTs' \gset --- Test that multiple SLRUs are reset when no specific SLRU provided to reset function -SELECT pg_stat_reset_slru(NULL); - pg_stat_reset_slru --------------------- - -(1 row) - -SELECT stats_reset > :'slru_commit_ts_reset_ts'::timestamptz FROM pg_stat_slru WHERE name = 'CommitTs'; - ?column? ----------- - t -(1 row) - -SELECT stats_reset > :'slru_notify_reset_ts'::timestamptz FROM pg_stat_slru WHERE name = 'Notify'; - ?column? ----------- - t -(1 row) - --- Test that reset_shared with archiver specified as the stats type works -SELECT stats_reset AS archiver_reset_ts FROM pg_stat_archiver \gset -SELECT pg_stat_reset_shared('archiver'); - pg_stat_reset_shared ----------------------- - -(1 row) - -SELECT stats_reset > :'archiver_reset_ts'::timestamptz FROM pg_stat_archiver; - ?column? ----------- - t -(1 row) - -SELECT stats_reset AS archiver_reset_ts FROM pg_stat_archiver \gset --- Test that reset_shared with bgwriter specified as the stats type works -SELECT stats_reset AS bgwriter_reset_ts FROM pg_stat_bgwriter \gset -SELECT pg_stat_reset_shared('bgwriter'); - pg_stat_reset_shared ----------------------- - -(1 row) - -SELECT stats_reset > :'bgwriter_reset_ts'::timestamptz FROM pg_stat_bgwriter; - ?column? ----------- - t -(1 row) - -SELECT stats_reset AS bgwriter_reset_ts FROM pg_stat_bgwriter \gset --- Test that reset_shared with wal specified as the stats type works -SELECT stats_reset AS wal_reset_ts FROM pg_stat_wal \gset -SELECT pg_stat_reset_shared('wal'); - pg_stat_reset_shared ----------------------- - -(1 row) - -SELECT stats_reset > :'wal_reset_ts'::timestamptz FROM pg_stat_wal; - ?column? ----------- - t -(1 row) - -SELECT stats_reset AS wal_reset_ts FROM pg_stat_wal \gset --- Test that reset_shared with no specified stats type doesn't reset anything -SELECT pg_stat_reset_shared(NULL); - pg_stat_reset_shared ----------------------- - -(1 row) - -SELECT stats_reset = :'archiver_reset_ts'::timestamptz FROM pg_stat_archiver; - ?column? ----------- - t -(1 row) - -SELECT stats_reset = :'bgwriter_reset_ts'::timestamptz FROM pg_stat_bgwriter; - ?column? ----------- - t -(1 row) - -SELECT stats_reset = :'wal_reset_ts'::timestamptz FROM pg_stat_wal; - ?column? ----------- - t -(1 row) - --- Test that reset works for pg_stat_database --- Since pg_stat_database stats_reset starts out as NULL, reset it once first so we have something to compare it to -SELECT pg_stat_reset(); - pg_stat_reset ---------------- - -(1 row) - -SELECT stats_reset AS db_reset_ts FROM pg_stat_database WHERE datname = (SELECT current_database()) \gset -SELECT pg_stat_reset(); - pg_stat_reset ---------------- - -(1 row) - -SELECT stats_reset > :'db_reset_ts'::timestamptz FROM pg_stat_database WHERE datname = (SELECT current_database()); - ?column? ----------- - t -(1 row) - ----- --- pg_stat_get_snapshot_timestamp behavior ----- -BEGIN; -SET LOCAL stats_fetch_consistency = snapshot; --- no snapshot yet, return NULL -SELECT pg_stat_get_snapshot_timestamp(); - pg_stat_get_snapshot_timestamp --------------------------------- - -(1 row) - --- any attempt at accessing stats will build snapshot -SELECT pg_stat_get_function_calls(0); - pg_stat_get_function_calls ----------------------------- - -(1 row) - -SELECT pg_stat_get_snapshot_timestamp() >= NOW(); - ?column? ----------- - t -(1 row) - --- shows NULL again after clearing -SELECT pg_stat_clear_snapshot(); - pg_stat_clear_snapshot ------------------------- - -(1 row) - -SELECT pg_stat_get_snapshot_timestamp(); - pg_stat_get_snapshot_timestamp --------------------------------- - -(1 row) - -COMMIT; ----- --- pg_stat_have_stats behavior ----- --- fixed-numbered stats exist -SELECT pg_stat_have_stats('bgwriter', 0, 0); - pg_stat_have_stats --------------------- - t -(1 row) - --- unknown stats kinds error out -SELECT pg_stat_have_stats('zaphod', 0, 0); -ERROR: invalid statistics kind: "zaphod" --- db stats have objoid 0 -SELECT pg_stat_have_stats('database', (SELECT oid FROM pg_database WHERE datname = current_database()), 1); - pg_stat_have_stats --------------------- - f -(1 row) - -SELECT pg_stat_have_stats('database', (SELECT oid FROM pg_database WHERE datname = current_database()), 0); - pg_stat_have_stats --------------------- - t -(1 row) - --- ensure that stats accessors handle NULL input correctly -SELECT pg_stat_get_replication_slot(NULL); - pg_stat_get_replication_slot ------------------------------- - -(1 row) - -SELECT pg_stat_get_subscription_stats(NULL); - pg_stat_get_subscription_stats --------------------------------- - -(1 row) - -- End of Stats Test diff --git a/src/test/regress/sql/brin.sql b/src/test/regress/sql/brin.sql index eec73b7fbe2..33a30fcf777 100644 --- a/src/test/regress/sql/brin.sql +++ b/src/test/regress/sql/brin.sql @@ -509,39 +509,3 @@ SELECT * FROM brintest_3 WHERE b < '0'; DROP TABLE brintest_3; RESET enable_seqscan; - --- Test handling of index predicates - updating attributes in predicates --- should block HOT even for BRIN. We update a row that was not indexed --- due to the index predicate, and becomes indexable. -CREATE TABLE brin_hot_2 (a int, b int); -INSERT INTO brin_hot_2 VALUES (1, 100); -CREATE INDEX ON brin_hot_2 USING brin (b) WHERE a = 2; - -UPDATE brin_hot_2 SET a = 2; - -EXPLAIN (COSTS OFF) SELECT * FROM brin_hot_2 WHERE a = 2 AND b = 100; -SELECT COUNT(*) FROM brin_hot_2 WHERE a = 2 AND b = 100; - -SET enable_seqscan = off; - -EXPLAIN (COSTS OFF) SELECT * FROM brin_hot_2 WHERE a = 2 AND b = 100; -SELECT COUNT(*) FROM brin_hot_2 WHERE a = 2 AND b = 100; - - --- test BRIN index doesn't block HOT update -CREATE TABLE brin_hot ( - id integer PRIMARY KEY, - val integer NOT NULL -) WITH (autovacuum_enabled = off, fillfactor = 70); - -INSERT INTO brin_hot SELECT *, 0 FROM generate_series(1, 235); -CREATE INDEX val_brin ON brin_hot using brin(val); - -UPDATE brin_hot SET val = -3 WHERE id = 42; - --- ensure pending stats are flushed -SELECT pg_stat_force_next_flush(); - -SELECT pg_stat_get_tuples_hot_updated('brin_hot'::regclass::oid); - -DROP TABLE brin_hot; diff --git a/src/test/regress/sql/stats.sql b/src/test/regress/sql/stats.sql index 096f00ce8be..3f3cf8fb56b 100644 --- a/src/test/regress/sql/stats.sql +++ b/src/test/regress/sql/stats.sql @@ -285,115 +285,4 @@ SELECT pg_stat_get_live_tuples(:drop_stats_test_subxact_oid); DROP TABLE trunc_stats_test, trunc_stats_test1, trunc_stats_test2, trunc_stats_test3, trunc_stats_test4; DROP TABLE prevstats; - - ------ --- Test that various stats views are being properly populated ------ - --- Test that sessions is incremented when a new session is started in pg_stat_database -SELECT sessions AS db_stat_sessions FROM pg_stat_database WHERE datname = (SELECT current_database()) \gset -\c -SELECT sessions > :db_stat_sessions FROM pg_stat_database WHERE datname = (SELECT current_database()); - --- Test pg_stat_bgwriter checkpointer-related stats, together with pg_stat_wal -SELECT checkpoints_req AS rqst_ckpts_before FROM pg_stat_bgwriter \gset - --- Test pg_stat_wal -SELECT wal_bytes AS wal_bytes_before FROM pg_stat_wal \gset - -CREATE TABLE test_stats_temp AS SELECT 17; -DROP TABLE test_stats_temp; - --- Checkpoint twice: The checkpointer reports stats after reporting completion --- of the checkpoint. But after a second checkpoint we'll see at least the --- results of the first. -CHECKPOINT; -CHECKPOINT; - -SELECT checkpoints_req > :rqst_ckpts_before FROM pg_stat_bgwriter; -SELECT wal_bytes > :wal_bytes_before FROM pg_stat_wal; - - ------ --- Test that resetting stats works for reset timestamp ------ - --- Test that reset_slru with a specified SLRU works. -SELECT stats_reset AS slru_commit_ts_reset_ts FROM pg_stat_slru WHERE name = 'CommitTs' \gset -SELECT stats_reset AS slru_notify_reset_ts FROM pg_stat_slru WHERE name = 'Notify' \gset -SELECT pg_stat_reset_slru('CommitTs'); -SELECT stats_reset > :'slru_commit_ts_reset_ts'::timestamptz FROM pg_stat_slru WHERE name = 'CommitTs'; -SELECT stats_reset AS slru_commit_ts_reset_ts FROM pg_stat_slru WHERE name = 'CommitTs' \gset - --- Test that multiple SLRUs are reset when no specific SLRU provided to reset function -SELECT pg_stat_reset_slru(NULL); -SELECT stats_reset > :'slru_commit_ts_reset_ts'::timestamptz FROM pg_stat_slru WHERE name = 'CommitTs'; -SELECT stats_reset > :'slru_notify_reset_ts'::timestamptz FROM pg_stat_slru WHERE name = 'Notify'; - --- Test that reset_shared with archiver specified as the stats type works -SELECT stats_reset AS archiver_reset_ts FROM pg_stat_archiver \gset -SELECT pg_stat_reset_shared('archiver'); -SELECT stats_reset > :'archiver_reset_ts'::timestamptz FROM pg_stat_archiver; -SELECT stats_reset AS archiver_reset_ts FROM pg_stat_archiver \gset - --- Test that reset_shared with bgwriter specified as the stats type works -SELECT stats_reset AS bgwriter_reset_ts FROM pg_stat_bgwriter \gset -SELECT pg_stat_reset_shared('bgwriter'); -SELECT stats_reset > :'bgwriter_reset_ts'::timestamptz FROM pg_stat_bgwriter; -SELECT stats_reset AS bgwriter_reset_ts FROM pg_stat_bgwriter \gset - --- Test that reset_shared with wal specified as the stats type works -SELECT stats_reset AS wal_reset_ts FROM pg_stat_wal \gset -SELECT pg_stat_reset_shared('wal'); -SELECT stats_reset > :'wal_reset_ts'::timestamptz FROM pg_stat_wal; -SELECT stats_reset AS wal_reset_ts FROM pg_stat_wal \gset - --- Test that reset_shared with no specified stats type doesn't reset anything -SELECT pg_stat_reset_shared(NULL); -SELECT stats_reset = :'archiver_reset_ts'::timestamptz FROM pg_stat_archiver; -SELECT stats_reset = :'bgwriter_reset_ts'::timestamptz FROM pg_stat_bgwriter; -SELECT stats_reset = :'wal_reset_ts'::timestamptz FROM pg_stat_wal; - --- Test that reset works for pg_stat_database - --- Since pg_stat_database stats_reset starts out as NULL, reset it once first so we have something to compare it to -SELECT pg_stat_reset(); -SELECT stats_reset AS db_reset_ts FROM pg_stat_database WHERE datname = (SELECT current_database()) \gset -SELECT pg_stat_reset(); -SELECT stats_reset > :'db_reset_ts'::timestamptz FROM pg_stat_database WHERE datname = (SELECT current_database()); - - ----- --- pg_stat_get_snapshot_timestamp behavior ----- -BEGIN; -SET LOCAL stats_fetch_consistency = snapshot; --- no snapshot yet, return NULL -SELECT pg_stat_get_snapshot_timestamp(); --- any attempt at accessing stats will build snapshot -SELECT pg_stat_get_function_calls(0); -SELECT pg_stat_get_snapshot_timestamp() >= NOW(); --- shows NULL again after clearing -SELECT pg_stat_clear_snapshot(); -SELECT pg_stat_get_snapshot_timestamp(); -COMMIT; - ----- --- pg_stat_have_stats behavior ----- --- fixed-numbered stats exist -SELECT pg_stat_have_stats('bgwriter', 0, 0); --- unknown stats kinds error out -SELECT pg_stat_have_stats('zaphod', 0, 0); --- db stats have objoid 0 -SELECT pg_stat_have_stats('database', (SELECT oid FROM pg_database WHERE datname = current_database()), 1); -SELECT pg_stat_have_stats('database', (SELECT oid FROM pg_database WHERE datname = current_database()), 0); - - --- ensure that stats accessors handle NULL input correctly -SELECT pg_stat_get_replication_slot(NULL); -SELECT pg_stat_get_subscription_stats(NULL); - - -- End of Stats Test