From 9e27451318e4a4a2e9061e79b5139560610bd78a Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Thu, 28 Mar 2024 20:21:25 +0200 Subject: [PATCH v13-bmr 4/5] Add readbufferbench --- src/test/modules/Makefile | 1 + src/test/modules/meson.build | 1 + src/test/modules/readbufferbench/Makefile | 21 ++++ src/test/modules/readbufferbench/bench.sql | 20 ++++ src/test/modules/readbufferbench/meson.build | 28 ++++++ .../readbufferbench/readbufferbench--1.0.sql | 9 ++ .../modules/readbufferbench/readbufferbench.c | 98 +++++++++++++++++++ .../readbufferbench/readbufferbench.control | 4 + 8 files changed, 182 insertions(+) create mode 100644 src/test/modules/readbufferbench/Makefile create mode 100644 src/test/modules/readbufferbench/bench.sql create mode 100644 src/test/modules/readbufferbench/meson.build create mode 100644 src/test/modules/readbufferbench/readbufferbench--1.0.sql create mode 100644 src/test/modules/readbufferbench/readbufferbench.c create mode 100644 src/test/modules/readbufferbench/readbufferbench.control diff --git a/src/test/modules/Makefile b/src/test/modules/Makefile index 1cbd532156d..6c96a83f60e 100644 --- a/src/test/modules/Makefile +++ b/src/test/modules/Makefile @@ -12,6 +12,7 @@ SUBDIRS = \ dummy_seclabel \ libpq_pipeline \ plsample \ + readbufferbench \ spgist_name_ops \ test_bloomfilter \ test_copy_callbacks \ diff --git a/src/test/modules/meson.build b/src/test/modules/meson.build index 7c11fb97f21..8ad342bcc73 100644 --- a/src/test/modules/meson.build +++ b/src/test/modules/meson.build @@ -10,6 +10,7 @@ subdir('injection_points') subdir('ldap_password_func') subdir('libpq_pipeline') subdir('plsample') +subdir('readbufferbench') subdir('spgist_name_ops') subdir('ssl_passphrase_callback') subdir('test_bloomfilter') diff --git a/src/test/modules/readbufferbench/Makefile b/src/test/modules/readbufferbench/Makefile new file mode 100644 index 00000000000..8b421b1cb1d --- /dev/null +++ b/src/test/modules/readbufferbench/Makefile @@ -0,0 +1,21 @@ +# src/test/modules/readbufferbench/Makefile + +MODULE_big = readbufferbench +OBJS = \ + $(WIN32RES) \ + readbufferbench.o +PGFILEDESC = "readbufferbench - micro-benchmarking code ReadBuffer and friends" + +EXTENSION = readbufferbench +DATA = readbufferbench--1.0.sql + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = src/test/modules/readbufferbench +top_builddir = ../../../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/src/test/modules/readbufferbench/bench.sql b/src/test/modules/readbufferbench/bench.sql new file mode 100644 index 00000000000..76b6be5f3e1 --- /dev/null +++ b/src/test/modules/readbufferbench/bench.sql @@ -0,0 +1,20 @@ +drop table foo; +create table foo (i integer) with (fillfactor=10); +insert into foo select g from generate_series(1, 100000) g; + +do $$ +declare + begints timestamptz; + endts timestamptz; + results float[]; + i int; +begin + for i in 1..5 loop + begints = clock_timestamp(); + perform readbuffer_bench('foo', 10, 10000000); + endts = clock_timestamp(); + results[i] = extract(epoch from endts) - extract(epoch from begints); + raise notice 'run %: %', i, results[i]; + end loop; +end; +$$; diff --git a/src/test/modules/readbufferbench/meson.build b/src/test/modules/readbufferbench/meson.build new file mode 100644 index 00000000000..1b7e7863c26 --- /dev/null +++ b/src/test/modules/readbufferbench/meson.build @@ -0,0 +1,28 @@ +# Copyright (c) 2022-2024, PostgreSQL Global Development Group + +readbufferbench_sources = files( + 'readbufferbench.c', +) + +if host_system == 'windows' + readbufferbench_sources += rc_lib_gen.process(win32ver_rc, extra_args: [ + '--NAME', 'readbufferbench', + '--FILEDESC', 'readbufferbench - micro-benchmarking code ReadBuffer and friends',]) +endif + +readbufferbench = shared_module('readbufferbench', + readbufferbench_sources, + kwargs: pg_test_mod_args, +) +test_install_libs += readbufferbench + +test_install_data += files( + 'readbufferbench.control', + 'readbufferbench--1.0.sql', +) + +tests += { + 'name': 'readbufferbench', + 'sd': meson.current_source_dir(), + 'bd': meson.current_build_dir(), +} diff --git a/src/test/modules/readbufferbench/readbufferbench--1.0.sql b/src/test/modules/readbufferbench/readbufferbench--1.0.sql new file mode 100644 index 00000000000..0ab5a4015a3 --- /dev/null +++ b/src/test/modules/readbufferbench/readbufferbench--1.0.sql @@ -0,0 +1,9 @@ +/* src/test/modules/readbufferbench/readbufferbench--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION readbufferbench" to load this file. \quit + + +CREATE FUNCTION readbuffer_bench(regclass, int4, int4) +RETURNS void +AS 'MODULE_PATHNAME' LANGUAGE C STRICT PARALLEL SAFE; diff --git a/src/test/modules/readbufferbench/readbufferbench.c b/src/test/modules/readbufferbench/readbufferbench.c new file mode 100644 index 00000000000..8d4c8281c29 --- /dev/null +++ b/src/test/modules/readbufferbench/readbufferbench.c @@ -0,0 +1,98 @@ +/*-------------------------------------------------------------------------- + * + * readbufferbench.c + * Test false positive rate of Bloom filter. + * + * Copyright (c) 2018-2024, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/test/modules/readbufferbench/readbufferbench.c + * + * ------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include "access/relation.h" +#include "fmgr.h" +#include "miscadmin.h" +#include "storage/bufmgr.h" +#include "utils/rel.h" + +PG_MODULE_MAGIC; + + +PG_FUNCTION_INFO_V1(readbuffer_bench); + +Datum +readbuffer_bench(PG_FUNCTION_ARGS) +{ + Oid relid = PG_GETARG_OID(0); + int32 nblocks = PG_GETARG_INT32(1); + uint32 niters = PG_GETARG_UINT32(2); + Relation rel; + Buffer buf; + + if (PG_NARGS() != 3) + elog(ERROR, "wrong number of arguments"); + + if (!superuser()) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("must be superuser"))); + + rel = relation_open(relid, AccessShareLock); + + if (!RELKIND_HAS_STORAGE(rel->rd_rel->relkind)) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("cannot get page from relation \"%s\"", + RelationGetRelationName(rel)), + errdetail_relkind_not_supported(rel->rd_rel->relkind))); + + /* + * Reject attempts to read non-local temporary relations; we would be + * likely to get wrong data since we have no visibility into the owning + * session's local buffers. + */ + if (RELATION_IS_OTHER_TEMP(rel)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot access temporary tables of other sessions"))); + + if (nblocks < 0) + nblocks = RelationGetNumberOfBlocksInFork(rel, MAIN_FORKNUM); + else if (nblocks > RelationGetNumberOfBlocksInFork(rel, MAIN_FORKNUM)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("relation has only %d blocks", + nblocks))); + +#if 1 + { + BufferManagerRelation bmr; + + InitBMRForRel(&bmr, rel, MAIN_FORKNUM, NULL); + for (int i = 0; i < niters; i++) + { + for (BlockNumber blkno = 0; blkno < nblocks; blkno++) + { + buf = ReadBufferBMR(&bmr, blkno, RBM_NORMAL); + ReleaseBuffer(buf); + } + } + } +#else + for (int i = 0; i < niters; i++) + { + for (BlockNumber blkno = 0; blkno < nblocks; blkno++) + { + buf = ReadBuffer(rel, blkno); + ReleaseBuffer(buf); + } + } +#endif + + relation_close(rel, AccessShareLock); + + PG_RETURN_VOID(); +} diff --git a/src/test/modules/readbufferbench/readbufferbench.control b/src/test/modules/readbufferbench/readbufferbench.control new file mode 100644 index 00000000000..c7488504c86 --- /dev/null +++ b/src/test/modules/readbufferbench/readbufferbench.control @@ -0,0 +1,4 @@ +comment = 'Micro-benchmark of ReadBuffer and friends' +default_version = '1.0' +module_pathname = '$libdir/readbufferbench' +relocatable = true -- 2.39.2