From 68db56a95032518bf527376e152540cc11ddbb31 Mon Sep 17 00:00:00 2001 From: Daniil Davidov Date: Sun, 23 Nov 2025 01:08:14 +0700 Subject: [PATCH v22 4/5] Tests for parallel autovacuum --- src/backend/access/heap/vacuumlazy.c | 9 + src/backend/commands/vacuumparallel.c | 49 +++ src/backend/postmaster/autovacuum.c | 28 ++ src/include/postmaster/autovacuum.h | 1 + src/test/modules/Makefile | 1 + src/test/modules/meson.build | 1 + src/test/modules/test_autovacuum/.gitignore | 2 + src/test/modules/test_autovacuum/Makefile | 28 ++ src/test/modules/test_autovacuum/meson.build | 36 ++ .../t/001_parallel_autovacuum.pl | 319 ++++++++++++++++++ .../test_autovacuum/test_autovacuum--1.0.sql | 12 + .../modules/test_autovacuum/test_autovacuum.c | 41 +++ .../test_autovacuum/test_autovacuum.control | 3 + 13 files changed, 530 insertions(+) create mode 100644 src/test/modules/test_autovacuum/.gitignore create mode 100644 src/test/modules/test_autovacuum/Makefile create mode 100644 src/test/modules/test_autovacuum/meson.build create mode 100644 src/test/modules/test_autovacuum/t/001_parallel_autovacuum.pl create mode 100644 src/test/modules/test_autovacuum/test_autovacuum--1.0.sql create mode 100644 src/test/modules/test_autovacuum/test_autovacuum.c create mode 100644 src/test/modules/test_autovacuum/test_autovacuum.control diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c index 91be2502c09..6407c10524b 100644 --- a/src/backend/access/heap/vacuumlazy.c +++ b/src/backend/access/heap/vacuumlazy.c @@ -151,6 +151,7 @@ #include "storage/freespace.h" #include "storage/lmgr.h" #include "storage/read_stream.h" +#include "utils/injection_point.h" #include "utils/lsyscache.h" #include "utils/pg_rusage.h" #include "utils/timestamp.h" @@ -869,6 +870,14 @@ heap_vacuum_rel(Relation rel, const VacuumParams params, lazy_check_wraparound_failsafe(vacrel); dead_items_alloc(vacrel, params.nworkers); +#ifdef USE_INJECTION_POINTS + /* + * Trigger injection point, if parallel autovacuum is about to be started. + */ + if (AmAutoVacuumWorkerProcess() && ParallelVacuumIsActive(vacrel)) + INJECTION_POINT("autovacuum-start-parallel-vacuum", NULL); +#endif + /* * Call lazy_scan_heap to perform all required heap pruning, index * vacuuming, and heap vacuuming (plus related processing) diff --git a/src/backend/commands/vacuumparallel.c b/src/backend/commands/vacuumparallel.c index 27a6120b0e3..78ccfede031 100644 --- a/src/backend/commands/vacuumparallel.c +++ b/src/backend/commands/vacuumparallel.c @@ -39,6 +39,7 @@ #include "postmaster/autovacuum.h" #include "storage/bufmgr.h" #include "tcop/tcopprot.h" +#include "utils/injection_point.h" #include "utils/lsyscache.h" #include "utils/rel.h" @@ -306,6 +307,10 @@ static bool parallel_vacuum_index_is_parallel_safe(Relation indrel, int num_inde bool vacuum); static void parallel_vacuum_error_callback(void *arg); +#ifdef USE_INJECTION_POINTS +static inline void parallel_vacuum_report_cost_based_params(void); +#endif + /* * Try to enter parallel mode and create a parallel context. Then initialize * shared memory state. @@ -918,6 +923,19 @@ parallel_vacuum_process_all_indexes(ParallelVacuumState *pvs, int num_index_scan pvs->pcxt->nworkers_launched, nworkers))); } +#ifdef USE_INJECTION_POINTS + /* + * To be able to exercise whether all reserved parallel workers are being + * released anyway, allow injection points to trigger a failure at this + * point. + * + * This injection point is also used to wait until parallel workers + * finishes their part of index processing. + */ + if (nworkers > 0) + INJECTION_POINT("autovacuum-leader-before-indexes-processing", NULL); +#endif + /* Vacuum the indexes that can be processed by only leader process */ parallel_vacuum_process_unsafe_indexes(pvs); @@ -1295,6 +1313,16 @@ parallel_vacuum_main(dsm_segment *seg, shm_toc *toc) /* Process indexes to perform vacuum/cleanup */ parallel_vacuum_process_safe_indexes(&pvs); +#ifdef USE_INJECTION_POINTS + /* + * If we are parallel autovacuum worker, we can consume delay parameters + * during index processing (via vacuum_delay_point call). This logging + * allows tests to ensure this. + */ + if (shared->is_autovacuum) + parallel_vacuum_report_cost_based_params(); +#endif + /* Report buffer/WAL usage during parallel execution */ buffer_usage = shm_toc_lookup(toc, PARALLEL_VACUUM_KEY_BUFFER_USAGE, false); wal_usage = shm_toc_lookup(toc, PARALLEL_VACUUM_KEY_WAL_USAGE, false); @@ -1347,3 +1375,24 @@ parallel_vacuum_error_callback(void *arg) return; } } + +#ifdef USE_INJECTION_POINTS +/* + * Log values related to cost-based vacuum delay parameters. It is used for + * testing purpose. + */ +static inline void +parallel_vacuum_report_cost_based_params(void) +{ + const char *msg_format = + _("Parallel autovacuum worker cost params: cost_limit=%d, cost_delay=%g, cost_page_miss=%d, cost_page_dirty=%d, cost_page_hit=%d"); + + elog(DEBUG2, + msg_format, + vacuum_cost_limit, + vacuum_cost_delay, + VacuumCostPageMiss, + VacuumCostPageDirty, + VacuumCostPageHit); +} +#endif diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index 0d78d02bd09..7b24a5d6e67 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2495,12 +2495,20 @@ do_autovacuum(void) } PG_CATCH(); { + int nreserved_workers = av_nworkers_reserved; + /* * Parallel autovacuum can reserve parallel workers. Make sure * that all reserved workers are released. */ AutoVacuumReleaseAllParallelWorkers(); + if (nreserved_workers > 0) + ereport(DEBUG2, + (errmsg("%d parallel autovacuum workers has been released after occured error", + nreserved_workers), + errhidecontext(true))); + /* * Abort the transaction, start a new one, and proceed with the * next table in our list. @@ -3465,6 +3473,21 @@ AutoVacuumReleaseAllParallelWorkers(void) Assert(av_nworkers_reserved == 0); } +/* + * Get number of free autovacuum parallel workers. + */ +uint32 +AutoVacuumGetFreeParallelWorkers(void) +{ + uint32 nfree_workers; + + LWLockAcquire(AutovacuumLock, LW_SHARED); + nfree_workers = AutoVacuumShmem->av_freeParallelWorkers; + LWLockRelease(AutovacuumLock); + + return nfree_workers; +} + /* * autovac_init * This is called at postmaster initialization. @@ -3633,5 +3656,10 @@ adjust_free_parallel_workers(int prev_max_parallel_workers) AutoVacuumShmem->av_freeParallelWorkers = Max(nfree_workers, 0); AutoVacuumShmem->av_maxParallelWorkers = autovacuum_max_parallel_workers; + ereport(DEBUG2, + (errmsg("number of free parallel autovacuum workers is set to %u due to config reload", + AutoVacuumShmem->av_freeParallelWorkers), + errhidecontext(true))); + LWLockRelease(AutovacuumLock); } diff --git a/src/include/postmaster/autovacuum.h b/src/include/postmaster/autovacuum.h index f3783afb51b..52be260e15f 100644 --- a/src/include/postmaster/autovacuum.h +++ b/src/include/postmaster/autovacuum.h @@ -66,6 +66,7 @@ extern bool AutoVacuumRequestWork(AutoVacuumWorkItemType type, extern void AutoVacuumReserveParallelWorkers(int *nworkers); extern void AutoVacuumReleaseParallelWorkers(int nworkers); extern void AutoVacuumReleaseAllParallelWorkers(void); +extern uint32 AutoVacuumGetFreeParallelWorkers(void); /* shared memory stuff */ extern Size AutoVacuumShmemSize(void); diff --git a/src/test/modules/Makefile b/src/test/modules/Makefile index 44c7163c1cd..937dbb64fd2 100644 --- a/src/test/modules/Makefile +++ b/src/test/modules/Makefile @@ -16,6 +16,7 @@ SUBDIRS = \ plsample \ spgist_name_ops \ test_aio \ + test_autovacuum \ test_binaryheap \ test_bitmapset \ test_bloomfilter \ diff --git a/src/test/modules/meson.build b/src/test/modules/meson.build index 2634a519935..5ac8d87702d 100644 --- a/src/test/modules/meson.build +++ b/src/test/modules/meson.build @@ -16,6 +16,7 @@ subdir('plsample') subdir('spgist_name_ops') subdir('ssl_passphrase_callback') subdir('test_aio') +subdir('test_autovacuum') subdir('test_binaryheap') subdir('test_bitmapset') subdir('test_bloomfilter') diff --git a/src/test/modules/test_autovacuum/.gitignore b/src/test/modules/test_autovacuum/.gitignore new file mode 100644 index 00000000000..716e17f5a2a --- /dev/null +++ b/src/test/modules/test_autovacuum/.gitignore @@ -0,0 +1,2 @@ +# Generated subdirectories +/tmp_check/ diff --git a/src/test/modules/test_autovacuum/Makefile b/src/test/modules/test_autovacuum/Makefile new file mode 100644 index 00000000000..32254c53a5d --- /dev/null +++ b/src/test/modules/test_autovacuum/Makefile @@ -0,0 +1,28 @@ +# src/test/modules/test_autovacuum/Makefile + +PGFILEDESC = "test_autovacuum - test code for parallel autovacuum" + +MODULE_big = test_autovacuum +OBJS = \ + $(WIN32RES) \ + test_autovacuum.o + +EXTENSION = test_autovacuum +DATA = test_autovacuum--1.0.sql + +TAP_TESTS = 1 + +EXTRA_INSTALL = src/test/modules/injection_points + +export enable_injection_points + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = src/test/modules/test_autovacuum +top_builddir = ../../../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/src/test/modules/test_autovacuum/meson.build b/src/test/modules/test_autovacuum/meson.build new file mode 100644 index 00000000000..3441e5e49cf --- /dev/null +++ b/src/test/modules/test_autovacuum/meson.build @@ -0,0 +1,36 @@ +# Copyright (c) 2024-2025, PostgreSQL Global Development Group + +test_autovacuum_sources = files( + 'test_autovacuum.c', +) + +if host_system == 'windows' + test_autovacuum_sources += rc_lib_gen.process(win32ver_rc, extra_args: [ + '--NAME', 'test_autovacuum', + '--FILEDESC', 'test_autovacuum - test code for parallel autovacuum',]) +endif + +test_autovacuum = shared_module('test_autovacuum', + test_autovacuum_sources, + kwargs: pg_test_mod_args, +) +test_install_libs += test_autovacuum + +test_install_data += files( + 'test_autovacuum.control', + 'test_autovacuum--1.0.sql', +) + +tests += { + 'name': 'test_autovacuum', + 'sd': meson.current_source_dir(), + 'bd': meson.current_build_dir(), + 'tap': { + 'env': { + 'enable_injection_points': get_option('injection_points') ? 'yes' : 'no', + }, + 'tests': [ + 't/001_basic.pl', + ], + }, +} diff --git a/src/test/modules/test_autovacuum/t/001_parallel_autovacuum.pl b/src/test/modules/test_autovacuum/t/001_parallel_autovacuum.pl new file mode 100644 index 00000000000..9b80d371f5c --- /dev/null +++ b/src/test/modules/test_autovacuum/t/001_parallel_autovacuum.pl @@ -0,0 +1,319 @@ +# Test parallel autovacuum behavior + +use warnings FATAL => 'all'; +use PostgreSQL::Test::Cluster; +use PostgreSQL::Test::Utils; +use Test::More; + +if ($ENV{enable_injection_points} ne 'yes') +{ + plan skip_all => 'Injection points not supported by this build'; +} + +# Before each test we should disable autovacuum for 'test_autovac' table and +# generate some dead tuples in it. + +sub prepare_for_next_test +{ + my ($node, $test_number) = @_; + + $node->safe_psql('postgres', qq{ + ALTER TABLE test_autovac SET (autovacuum_enabled = false); + }); + + $node->safe_psql('postgres', qq{ + UPDATE test_autovac SET col_1 = $test_number; + }); +} + + +my $psql_out; + +my $node = PostgreSQL::Test::Cluster->new('node1'); +$node->init; + +# Configure postgres, so it can launch parallel autovacuum workers, log all +# information we are interested in and autovacuum works frequently +$node->append_conf('postgresql.conf', qq{ + max_worker_processes = 20 + max_parallel_workers = 20 + max_parallel_maintenance_workers = 20 + autovacuum_max_parallel_workers = 20 + log_min_messages = debug2 + log_autovacuum_min_duration = 0 + autovacuum_naptime = '1s' + min_parallel_index_scan_size = 0 + shared_preload_libraries=test_autovacuum +}); +$node->start; + +# Check if the extension injection_points is available, as it may be +# possible that this script is run with installcheck, where the module +# would not be installed by default. +if (!$node->check_extension('injection_points')) +{ + plan skip_all => 'Extension injection_points not installed'; +} + +# Create all functions needed for testing +$node->safe_psql('postgres', qq{ + CREATE EXTENSION test_autovacuum; + CREATE EXTENSION injection_points; +}); + +my $indexes_num = 4; +my $initial_rows_num = 10_000; +my $autovacuum_parallel_workers = 2; + +# Create table and fill it with some data +$node->safe_psql('postgres', qq{ + CREATE TABLE test_autovac ( + id SERIAL PRIMARY KEY, + col_1 INTEGER, col_2 INTEGER, col_3 INTEGER, col_4 INTEGER + ) WITH (autovacuum_parallel_workers = $autovacuum_parallel_workers); + + INSERT INTO test_autovac + SELECT + g AS col1, + g + 1 AS col2, + g + 2 AS col3, + g + 3 AS col4 + FROM generate_series(1, $initial_rows_num) AS g; +}); + +# Create specified number of b-tree indexes on the table +$node->safe_psql('postgres', qq{ + DO \$\$ + DECLARE + i INTEGER; + BEGIN + FOR i IN 1..$indexes_num LOOP + EXECUTE format('CREATE INDEX idx_col_\%s ON test_autovac (col_\%s);', i, i); + END LOOP; + END \$\$; +}); + +# Test 1 : +# Our table has enough indexes and appropriate reloptions, so autovacuum must +# be able to process it in parallel mode. Just check if it can. +# Also check whether all requested workers: +# 1) launched +# 2) correctly released + +prepare_for_next_test($node, 1); + +$node->safe_psql('postgres', qq{ + ALTER TABLE test_autovac SET (autovacuum_enabled = true); +}); + +# Wait until the parallel autovacuum on table is completed. At the same time, +# we check that the required number of parallel workers has been started. +$log_start = $node->wait_for_log( + qr/parallel workers: index vacuum: 2 planned, 2 reserved, 2 launched/, + $log_start +); + +$psql_out = $node->safe_psql('postgres', qq{ + SELECT get_parallel_autovacuum_free_workers(); +}); +is($psql_out, 20, 'All parallel workers has been released by the leader'); + +# Test 2: +# Check whether parallel autovacuum leader can propagate cost-based parameters +# to parallel workers. + +prepare_for_next_test($node, 2); + +$node->safe_psql('postgres', qq{ + SELECT injection_points_attach('autovacuum-start-parallel-vacuum', 'wait'); + SELECT injection_points_attach('autovacuum-leader-before-indexes-processing', 'wait'); + + ALTER TABLE test_autovac SET (autovacuum_parallel_workers = 1, autovacuum_enabled = true); +}); + +# Wait until parallel autovacuum is inited +$node->wait_for_event( + 'autovacuum worker', + 'autovacuum-start-parallel-vacuum' +); + +# Reload config - leader worker must update its own parameters during indexes +# processing +$node->safe_psql('postgres', qq{ + ALTER SYSTEM SET vacuum_cost_limit = 500; + ALTER SYSTEM SET vacuum_cost_page_miss = 10; + ALTER SYSTEM SET vacuum_cost_page_dirty = 10; + ALTER SYSTEM SET vacuum_cost_page_hit = 10; + SELECT pg_reload_conf(); +}); + +$node->safe_psql('postgres', qq{ + SELECT injection_points_wakeup('autovacuum-start-parallel-vacuum'); +}); + +# Now wait until parallel autovacuum leader completes processing table (i.e. +# guaranteed to call vacuum_delay_point) and launches parallel worker. +$node->wait_for_event( + 'autovacuum worker', + 'autovacuum-leader-before-indexes-processing' +); + +# Check whether parallel worker successfully updated all parameters during +# index processing +$log_start = $node->wait_for_log( + qr/Parallel autovacuum worker cost params: cost_limit=500, cost_delay=2, / . + qr/cost_page_miss=10, cost_page_dirty=10, cost_page_hit=10/, + $log_start +); + +# Cleanup +$node->safe_psql('postgres', qq{ + SELECT injection_points_wakeup('autovacuum-leader-before-indexes-processing'); + + SELECT injection_points_detach('autovacuum-start-parallel-vacuum'); + SELECT injection_points_detach('autovacuum-leader-before-indexes-processing'); + + ALTER TABLE test_autovac SET (autovacuum_parallel_workers = $autovacuum_parallel_workers); +}); + +# Test 3: +# Test adjustment of free parallel workers number when changing +# autovacuum_max_parallel_workers parameter + +prepare_for_next_test($node, 4); + +$node->safe_psql('postgres', qq{ + SELECT injection_points_attach('autovacuum-leader-before-indexes-processing', 'wait'); + ALTER TABLE test_autovac SET (autovacuum_enabled = true); +}); + +$node->wait_for_event( + 'autovacuum worker', + 'autovacuum-leader-before-indexes-processing' +); + +$node->safe_psql('postgres', qq{ + ALTER SYSTEM SET autovacuum_max_parallel_workers = 1; + SELECT pg_reload_conf(); +}); + +# Since 2 parallel workers already launched and will be released in the future, +# we are expecting that : +# 1) number of free workers will be '0' after config reload +# 2) number of free workers will be '1' after releasing workers + +# Check statement (1) +$log_start = $node->wait_for_log( + qr/number of free parallel autovacuum workers is set to 0 due to config reload/, + $log_start +); + +$node->safe_psql('postgres', qq{ + SELECT injection_points_wakeup('autovacuum-leader-before-indexes-processing'); +}); + +# Wait until the end of parallel processing +$log_start = $node->wait_for_log( + qr/parallel workers: index vacuum: 2 planned, 2 reserved, 2 launched/, + $log_start +); + +# Check statement (2) +$psql_out = $node->safe_psql('postgres', qq{ + SELECT get_parallel_autovacuum_free_workers(); +}); +is($psql_out, 1, 'Number of free parallel workers is consistent'); + +# Cleanup +$node->safe_psql('postgres', qq{ + SELECT injection_points_detach('autovacuum-leader-before-indexes-processing'); + ALTER SYSTEM SET autovacuum_max_parallel_workers = 10; + SELECT pg_reload_conf(); +}); + +# Test 4: +# We want parallel autovacuum workers to be released even if leader gets an +# error. At first, simulate situation, when leader exits due to an ERROR. + +prepare_for_next_test($node, 4); + +$node->safe_psql('postgres', qq{ + SELECT injection_points_attach('autovacuum-leader-before-indexes-processing', 'error'); + ALTER TABLE test_autovac SET (autovacuum_enabled = true); +}); + +$log_start = $node->wait_for_log( + qr/error triggered for injection point / . + qr/autovacuum-leader-before-indexes-processing/, + $log_start +); + +$log_start = $node->wait_for_log( + qr/2 parallel autovacuum workers has been released after occured error/, + $log_start +); + +# Cleanup +$node->safe_psql('postgres', qq{ + SELECT injection_points_detach('autovacuum-leader-before-indexes-processing'); +}); + +# Test 5: +# Same as above test, but simulate situation, when leader exits due to FATAL. + +prepare_for_next_test($node, 5); + +$node->safe_psql('postgres', qq{ + SELECT injection_points_attach('autovacuum-start-parallel-vacuum', 'wait'); + SELECT injection_points_attach('autovacuum-leader-before-indexes-processing', 'wait'); + ALTER TABLE test_autovac SET (autovacuum_enabled = true); +}); + +# Wait until parallel autovacuum is inited and wake up the leader +$node->wait_for_event( + 'autovacuum worker', + 'autovacuum-start-parallel-vacuum' +); +$node->safe_psql('postgres', qq{ + SELECT injection_points_wakeup('autovacuum-start-parallel-vacuum'); +}); + +$node->wait_for_event( + 'autovacuum worker', + 'autovacuum-leader-before-indexes-processing' +); + +my $av_pid = $node->safe_psql('postgres', qq{ + SELECT pid FROM pg_stat_activity + WHERE backend_type = 'autovacuum worker' + AND wait_event = 'autovacuum-leader-before-indexes-processing' + LIMIT 1; +}); + +$node->safe_psql('postgres', qq{ + SELECT pg_terminate_backend('$av_pid'); +}); + +$log_start = $node->wait_for_log( + qr/terminating autovacuum process due to administrator command/, + $log_start +); + +# Now it is safe to check the number of free parallel workers, because even if +# autovacuum is trying to vacuum table in parallel mode again, the leader +# worker cannot go any further than "autovacuum-start-parallel-vacuum" point. +# I.e. no one can interfere and change the number of free parallel workers. + +$psql_out = $node->safe_psql('postgres', qq{ + SELECT get_parallel_autovacuum_free_workers(); +}); +is($psql_out, 10, 'All parallel workers has been released by the leader after FATAL'); + +# Cleanup +$node->safe_psql('postgres', qq{ + SELECT injection_points_detach('autovacuum-start-parallel-vacuum'); + SELECT injection_points_detach('autovacuum-leader-before-indexes-processing'); +}); + +$node->stop; +done_testing(); diff --git a/src/test/modules/test_autovacuum/test_autovacuum--1.0.sql b/src/test/modules/test_autovacuum/test_autovacuum--1.0.sql new file mode 100644 index 00000000000..e5646e0def5 --- /dev/null +++ b/src/test/modules/test_autovacuum/test_autovacuum--1.0.sql @@ -0,0 +1,12 @@ +/* src/test/modules/test_autovacuum/test_autovacuum--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION test_autovacuum" to load this file. \quit + +/* + * Functions for expecting shared autovacuum state + */ + +CREATE FUNCTION get_parallel_autovacuum_free_workers() +RETURNS INTEGER STRICT +AS 'MODULE_PATHNAME' LANGUAGE C; diff --git a/src/test/modules/test_autovacuum/test_autovacuum.c b/src/test/modules/test_autovacuum/test_autovacuum.c new file mode 100644 index 00000000000..959629c7685 --- /dev/null +++ b/src/test/modules/test_autovacuum/test_autovacuum.c @@ -0,0 +1,41 @@ +/*------------------------------------------------------------------------- + * + * test_autovacuum.c + * Helpers to write tests for parallel autovacuum + * + * Copyright (c) 2020-2025, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/test/modules/test_autovacuum/test_autovacuum.c + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include "commands/vacuum.h" +#include "fmgr.h" +#include "miscadmin.h" +#include "postmaster/autovacuum.h" +#include "storage/shmem.h" +#include "storage/ipc.h" +#include "storage/lwlock.h" +#include "utils/builtins.h" +#include "utils/injection_point.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(get_parallel_autovacuum_free_workers); +Datum +get_parallel_autovacuum_free_workers(PG_FUNCTION_ARGS) +{ + uint32 nfree_workers; + +#ifndef USE_INJECTION_POINTS + ereport(ERROR, errmsg("injection points not supported")); +#endif + + nfree_workers = AutoVacuumGetFreeParallelWorkers(); + + PG_RETURN_UINT32(nfree_workers); +} diff --git a/src/test/modules/test_autovacuum/test_autovacuum.control b/src/test/modules/test_autovacuum/test_autovacuum.control new file mode 100644 index 00000000000..1b7fad258f0 --- /dev/null +++ b/src/test/modules/test_autovacuum/test_autovacuum.control @@ -0,0 +1,3 @@ +comment = 'Test code for parallel autovacuum' +default_version = '1.0' +module_pathname = '$libdir/test_autovacuum' -- 2.43.0