From 33f6bd9145c45a1090dbfaa018d7025363b35bbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E6=8C=83?= Date: Thu, 6 Aug 2020 23:38:08 +0800 Subject: [PATCH v2] delay_execution used for concurrency case simulation --- contrib/delay_execution/Makefile | 18 +++++ contrib/delay_execution/delay_execution.c | 90 +++++++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 contrib/delay_execution/Makefile create mode 100644 contrib/delay_execution/delay_execution.c diff --git a/contrib/delay_execution/Makefile b/contrib/delay_execution/Makefile new file mode 100644 index 0000000000..d31179fef6 --- /dev/null +++ b/contrib/delay_execution/Makefile @@ -0,0 +1,18 @@ +# contrib/delay_execution/Makefile + +MODULE_big = delay_execution +OBJS = \ + $(WIN32RES) \ + delay_execution.o +PGFILEDESC = "delay_execution used for concurrency case simulation" + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/delay_execution +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/delay_execution/delay_execution.c b/contrib/delay_execution/delay_execution.c new file mode 100644 index 0000000000..c0e32b6ca2 --- /dev/null +++ b/contrib/delay_execution/delay_execution.c @@ -0,0 +1,90 @@ +/*------------------------------------------------------------------------- + * + * delay_execution.c + * + * + * Copyright (c) 2008-2020, PostgreSQL Global Development Group + * + * IDENTIFICATION + * contrib/delay_execution/delay_execution.c + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include + +#include "fmgr.h" +#include "nodes/plannodes.h" +#include "optimizer/planner.h" +#include "utils/guc.h" +#include "utils/fmgrprotos.h" + + +PG_MODULE_MAGIC; + +/* + * Only the lock ID equals customized_lock_id will be used, so that + * different sessions can be blocked at different points. + */ +static int customized_lock_id = 0; + +/* Lock ID starts with 1 */ +static const int64 after_planner_lock_id = 1; + +static planner_hook_type prev_planner_hook = NULL; + +void _PG_init(void); +void _PG_fini(void); + + +static void +delay_execution_advisory_lock_unlock(int64 lock_id) +{ + if (lock_id != customized_lock_id) + return; + DirectFunctionCall1(pg_advisory_lock_int8, Int64GetDatum(lock_id)); + DirectFunctionCall1(pg_advisory_unlock_int8, Int64GetDatum(lock_id)); +} + + +static PlannedStmt * +delay_execution_planner(Query *parse, const char *query_string, int cursorOptions, + ParamListInfo boundParams) +{ + PlannedStmt *result; + if (prev_planner_hook) + result = prev_planner_hook(parse, query_string, cursorOptions, + boundParams); + else + result = standard_planner(parse, query_string, cursorOptions, + boundParams); + delay_execution_advisory_lock_unlock(after_planner_lock_id); + return result; +} + +void +_PG_init(void) +{ + DefineCustomIntVariable("delay_execution.custom_lock_id", + "Set the lock ID which will be lock/unlock during execution.", + "All locks ID starts with 1, so zero means not lock will be used.", + &customized_lock_id, + 0, + 0, INT_MAX, + PGC_SUSET, + 0, + NULL, + NULL, + NULL); + prev_planner_hook = planner_hook; + planner_hook = delay_execution_planner; +} + + +void +_PG_fini(void) +{ + planner_hook = prev_planner_hook; +} -- 2.21.0