diff options
author | Heikki Linnakangas | 2016-08-22 16:23:34 +0000 |
---|---|---|
committer | Heikki Linnakangas | 2016-08-22 18:21:58 +0000 |
commit | d6176e87030f39de91182c05ecab2b37b1bd688c (patch) | |
tree | e06b1eeb680102ef39fc5d212edde3a7f71159e1 | |
parent | 295dee2321acea93f4f1e189b3c84e4fec7cdbb1 (diff) |
Add a test modulecsn5
-rw-r--r-- | src/test/modules/mvcctorture/Makefile | 18 | ||||
-rw-r--r-- | src/test/modules/mvcctorture/README | 25 | ||||
-rw-r--r-- | src/test/modules/mvcctorture/mvcctorture--1.0.sql | 9 | ||||
-rw-r--r-- | src/test/modules/mvcctorture/mvcctorture.c | 129 | ||||
-rw-r--r-- | src/test/modules/mvcctorture/mvcctorture.control | 5 |
5 files changed, 186 insertions, 0 deletions
diff --git a/src/test/modules/mvcctorture/Makefile b/src/test/modules/mvcctorture/Makefile new file mode 100644 index 0000000000..cc4ebc838a --- /dev/null +++ b/src/test/modules/mvcctorture/Makefile @@ -0,0 +1,18 @@ +# src/test/modules/mvcctorture/Makefile + +MODULE_big = mvcctorture +OBJS = mvcctorture.o + +EXTENSION = mvcctorture +DATA = mvcctorture--1.0.sql + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = src/test/modules/mvcctorture +top_builddir = ../../../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/src/test/modules/mvcctorture/README b/src/test/modules/mvcctorture/README new file mode 100644 index 0000000000..915b00129a --- /dev/null +++ b/src/test/modules/mvcctorture/README @@ -0,0 +1,25 @@ +A litte helper module for testing MVCC performance. + +The populate_mvcc_test_table function can be used to create a test table, +with given number of rows. Each row in the table is stamped with a different +xmin, and XMIN_COMMITTED hint bit can be set or not. Furthermore, the +xmins values are shuffled, to defeat caching in transam.c and clog.c as badly +as possible. + +The test table is always called "mvcc_test_table". You'll have to drop it +yourself between tests. + +For example: + +-- Create a test table with 10 million rows, without setting hint bits +select populate_mvcc_test_table(10000000, false); + +-- See how long it takes to scan it +\timing +select count(*) from mvcc_test_table; + + + +If you do the above, but have another psql session open, in a transaction +that's done some updates, i.e. is holding backthe xmin horizon, you will +see the worst-case performance of the CSN patch. diff --git a/src/test/modules/mvcctorture/mvcctorture--1.0.sql b/src/test/modules/mvcctorture/mvcctorture--1.0.sql new file mode 100644 index 0000000000..652a6a3f39 --- /dev/null +++ b/src/test/modules/mvcctorture/mvcctorture--1.0.sql @@ -0,0 +1,9 @@ +/* src/test/modules/mvcctorture/mvcctorture--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION mvcctorture" to load this file. \quit + +CREATE FUNCTION populate_mvcc_test_table(int4, bool) +RETURNS void +AS 'MODULE_PATHNAME', 'populate_mvcc_test_table' +LANGUAGE C STRICT; diff --git a/src/test/modules/mvcctorture/mvcctorture.c b/src/test/modules/mvcctorture/mvcctorture.c new file mode 100644 index 0000000000..a89a2e6e96 --- /dev/null +++ b/src/test/modules/mvcctorture/mvcctorture.c @@ -0,0 +1,129 @@ +/*------------------------------------------------------------------------- + * + * mvctorture.c + * + * Copyright (c) 2012, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/test/modules/mvcctorture.c + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include "access/heapam.h" +#include "access/hio.h" +#include "access/htup_details.h" +#include "access/transam.h" +#include "access/xact.h" +#include "access/visibilitymap.h" +#include "catalog/pg_am.h" +#include "executor/spi.h" +#include "funcapi.h" +#include "nodes/makefuncs.h" +#include "storage/bufmgr.h" +#include "utils/rel.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(populate_mvcc_test_table); + +Datum +populate_mvcc_test_table(PG_FUNCTION_ARGS) +{ + uint32 nrows = PG_GETARG_UINT32(0); + bool set_xmin_committed = PG_GETARG_BOOL(1); + RangeVar *rv; + Relation rel; + Datum values[1]; + bool isnull[1]; + HeapTuple tup; + TransactionId *xids; + int ret; + int i; + Buffer buffer; + Buffer vmbuffer = InvalidBuffer; + + /* Connect to SPI manager */ + if ((ret = SPI_connect()) < 0) + /* internal error */ + elog(ERROR, "populate_mvcc_test_table: SPI_connect returned %d", ret); + + SPI_execute("CREATE TABLE mvcc_test_table(i int4)", false, 0); + + SPI_finish(); + + /* Generate a different XID for each tuple */ + xids = (TransactionId *) palloc0(nrows * sizeof(TransactionId)); + for (i = 0; i < nrows; i++) + { + BeginInternalSubTransaction(NULL); + xids[i] = GetCurrentTransactionId(); + ReleaseCurrentSubTransaction(); + } + + rv = makeRangeVar(NULL, "mvcc_test_table", -1); + + rel = heap_openrv(rv, RowExclusiveLock); + + /* shuffle */ + for (i = 0; i < nrows - 1; i++) + { + int x = i + (random() % (nrows - i)); + TransactionId tmp; + + tmp = xids[i]; + xids[i] = xids[x]; + xids[x] = tmp; + } + + for (i = 0; i < nrows; i++) + { + values[0] = Int32GetDatum(i); + isnull[0] = false; + + tup = heap_form_tuple(RelationGetDescr(rel), values, isnull); + + /* Fill the header fields, like heap_prepare_insert does */ + tup->t_data->t_infomask &= ~(HEAP_XACT_MASK); + tup->t_data->t_infomask2 &= ~(HEAP2_XACT_MASK); + tup->t_data->t_infomask |= HEAP_XMAX_INVALID; + if (set_xmin_committed) + tup->t_data->t_infomask |= HEAP_XMIN_COMMITTED; + HeapTupleHeaderSetXmin(tup->t_data, xids[i]); + HeapTupleHeaderSetCmin(tup->t_data, 1); + HeapTupleHeaderSetXmax(tup->t_data, 0); /* for cleanliness */ + tup->t_tableOid = RelationGetRelid(rel); + + heap_freetuple(tup); + + /* + * Find buffer to insert this tuple into. If the page is all visible, + * this will also pin the requisite visibility map page. + */ + buffer = RelationGetBufferForTuple(rel, tup->t_len, + InvalidBuffer, + 0, NULL, + &vmbuffer, NULL); + RelationPutHeapTuple(rel, buffer, tup, false); + + if (PageIsAllVisible(BufferGetPage(buffer))) + { + PageClearAllVisible(BufferGetPage(buffer)); + visibilitymap_clear(rel, + ItemPointerGetBlockNumber(&(tup->t_self)), + vmbuffer, VISIBILITYMAP_VALID_BITS); + } + + MarkBufferDirty(buffer); + UnlockReleaseBuffer(buffer); + } + + if (vmbuffer != InvalidBuffer) + ReleaseBuffer(vmbuffer); + + heap_close(rel, NoLock); + + PG_RETURN_VOID(); +} diff --git a/src/test/modules/mvcctorture/mvcctorture.control b/src/test/modules/mvcctorture/mvcctorture.control new file mode 100644 index 0000000000..1b5feb95a7 --- /dev/null +++ b/src/test/modules/mvcctorture/mvcctorture.control @@ -0,0 +1,5 @@ +# mvcctorture extension +comment = 'populate a table with a mix of different XIDs' +default_version = '1.0' +module_pathname = '$libdir/mvcctorture' +relocatable = true |