diff --git a/.github/workflows/build-gpdb.yml b/.github/workflows/build-gpdb.yml index 90e9e7bb37b..977d8c0bad6 100644 --- a/.github/workflows/build-gpdb.yml +++ b/.github/workflows/build-gpdb.yml @@ -166,6 +166,9 @@ jobs: {"test":"ic-parallel-retrieve-cursor", "make_configs":["src/test/isolation2:installcheck-parallel-retrieve-cursor"] }, + {"test":"ic-temp_tables_stat", + "make_configs":["src/test/isolation2:installcheck-tts"] + }, {"test":"ic-mirrorless", "make_configs":["src/test/isolation2:installcheck-mirrorless"] }, diff --git a/gpcontrib/Makefile b/gpcontrib/Makefile index 9665ceed10c..4754040669d 100644 --- a/gpcontrib/Makefile +++ b/gpcontrib/Makefile @@ -27,7 +27,8 @@ ifeq "$(enable_debug_extensions)" "yes" gp_subtransaction_overflow \ gp_check_functions \ gp_aux_catalog \ - gp_interconnect_stats + gp_interconnect_stats \ + temp_tables_stat else recurse_targets = gp_sparse_vector \ gp_distribution_policy \ @@ -43,7 +44,8 @@ else gp_subtransaction_overflow \ gp_check_functions \ gp_aux_catalog \ - gp_interconnect_stats + gp_interconnect_stats \ + temp_tables_stat endif ifeq "$(with_zstd)" "yes" diff --git a/gpcontrib/temp_tables_stat/Makefile b/gpcontrib/temp_tables_stat/Makefile new file mode 100644 index 00000000000..2b198777c95 --- /dev/null +++ b/gpcontrib/temp_tables_stat/Makefile @@ -0,0 +1,20 @@ +# gpcontrib/temp_tables_stat/Makefile + +MODULE_big = temp_tables_stat +OBJS = $(MODULE_big).o $(WIN32RES) + +EXTENSION = $(MODULE_big) +PGFILEDESC = "Collect and show statistics on temporary tables" + +DATA = $(MODULE_big)--0.1.sql + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = gpcontrib/temp_tables_stat +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/gpcontrib/temp_tables_stat/temp_tables_stat--0.1.sql b/gpcontrib/temp_tables_stat/temp_tables_stat--0.1.sql new file mode 100644 index 00000000000..00b9a2b7eac --- /dev/null +++ b/gpcontrib/temp_tables_stat/temp_tables_stat--0.1.sql @@ -0,0 +1,8 @@ +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION temp_tables_stat" to load this file. \quit + +CREATE FUNCTION tts_get_seg_files(OUT user_id oid, OUT sess_id int4, OUT path text, OUT content int2, OUT size int8) +RETURNS SETOF RECORD +AS 'MODULE_PATHNAME', 'tts_get_seg_files' +LANGUAGE C +EXECUTE ON ALL SEGMENTS; diff --git a/gpcontrib/temp_tables_stat/temp_tables_stat.c b/gpcontrib/temp_tables_stat/temp_tables_stat.c new file mode 100644 index 00000000000..b17f397657a --- /dev/null +++ b/gpcontrib/temp_tables_stat/temp_tables_stat.c @@ -0,0 +1,376 @@ +#include "postgres.h" + +#include + +#include "cdb/cdbvars.h" +#include "funcapi.h" +#include "pgstat.h" +#include "storage/dsm.h" +#include "storage/ipc.h" +#include "utils/builtins.h" + +PG_MODULE_MAGIC; + +void _PG_init(void); +void _PG_fini(void); + +static file_create_hook_type prev_file_create_hook = NULL; +static file_unlink_hook_type prev_file_unlink_hook = NULL; +static shmem_startup_hook_type prev_shmem_startup_hook = NULL; + +/* + * RelFileNodeBackend-s for each temp table are stored in the list of arrays. + * The list is located in shared memory. The head node of the list (TTSHeadNode) + * is allocated using ShmemInitStruct. Next nodes (TTSNode) are allocated using + * DSM. The next node is created when array of RelFileNodeBackend-s in + * the previous one is full. It is assumed that array in the head node is large + * enough to contain all RelFileNodeBackend-s in normal case and DSM is used + * very rarely. + */ + +typedef struct TTSNode +{ + dsm_handle next; /* Handle of DSM segment with the next node */ + int num; /* Number of elements in files */ + RelFileNodeBackend files[1000000]; +} TTSNode; + +typedef struct TTSHeadNode +{ + LWLock lock; + TTSNode node; +} TTSHeadNode; + +static TTSHeadNode *head = NULL; /* Head of the list */ + +/* Get next node by current one */ +static TTSNode * +next_node(const TTSNode *node) +{ + dsm_segment *dsm_seg; + + if (node->next == DSM_HANDLE_INVALID) + return NULL; + + dsm_seg = dsm_find_mapping(node->next); + if (dsm_seg == NULL) + { + dsm_seg = dsm_attach(node->next); + dsm_pin_mapping(dsm_seg); + } + + return dsm_segment_address(dsm_seg); +} + +/* + * This function is called with the same argument when each fork is created. + * Add file info to the list if it is not there. + */ +static void +tts_file_create_hook(RelFileNodeBackend rnode) +{ + TTSNode *node; + + if (prev_file_create_hook) + (*prev_file_create_hook)(rnode); + + if (!RelFileNodeBackendIsTemp(rnode) || head == NULL) + return; + + rnode.backend = MyBackendId; + + LWLockAcquire(&head->lock, LW_EXCLUSIVE); + + /* Don't add rnode when it exists in the list of arrays */ + for (node = &head->node;; node = next_node(node)) + { + for (int i = 0; i < node->num; i++) + if (RelFileNodeBackendEquals(rnode, node->files[i])) + goto lExit; + + if (node->next == DSM_HANDLE_INVALID) + break; + } + + /* Create a new node if the last node is full */ + if (node->num == ARRAY_SIZE(node->files)) + { + dsm_segment *next_seg = dsm_create(sizeof(TTSNode)); + dsm_pin_mapping(next_seg); + node->next = dsm_segment_handle(next_seg); + node = dsm_segment_address(next_seg); + node->next = DSM_HANDLE_INVALID; + node->num = 0; + } + + node->files[node->num++] = rnode; + +lExit: + LWLockRelease(&head->lock); +} + +static void +delete_from_ttsnode(TTSNode *node, int index, TTSNode *prev_node) +{ + /* Find the last node */ + TTSNode *last_node = node; + TTSNode *last_prev_node = prev_node; + + while (last_node->next != DSM_HANDLE_INVALID) + { + last_prev_node = last_node; + last_node = next_node(last_node); + } + + /* replace the deleted element with the last one */ + node->files[index] = last_node->files[last_node->num - 1]; + + if (last_node->num > 1) + last_node->num--; + else if (last_node == &head->node) + head->node.num = 0; + else + { + /* + * last_prev_node != NULL because last_node is not head. + * next_node() has been called, so the mapping exists. + */ + dsm_detach(dsm_find_mapping(last_prev_node->next)); + last_prev_node->next = DSM_HANDLE_INVALID; + } +} + +/* This function is called once for all forks. Delete file info from the list */ +static void +tts_file_unlink_hook(RelFileNodeBackend rnode) +{ + if (prev_file_unlink_hook) + (*prev_file_unlink_hook)(rnode); + + if (!RelFileNodeBackendIsTemp(rnode) || head == NULL) + return; + + rnode.backend = MyBackendId; + LWLockAcquire(&head->lock, LW_EXCLUSIVE); + + /* Find rnode in the list of arrays and delete it from the list node */ + for (TTSNode *node = &head->node, *prev_node = NULL; + node != NULL; + prev_node = node, node = next_node(node)) + { + for (int i = 0; i < node->num; i++) + if (RelFileNodeBackendEquals(rnode, node->files[i])) + { + delete_from_ttsnode(node, i, prev_node); + goto lExit; + } + } + +lExit: + LWLockRelease(&head->lock); +} + +/* Postmaster creates a new shared memory space for the head node of the list */ +static void +tts_shmem_startup(void) +{ + bool found; + + if (prev_shmem_startup_hook) + (*prev_shmem_startup_hook)(); + + head = ShmemInitStruct("temp_tables_stat", sizeof(TTSHeadNode), &found); + if (found) + return; + + LWLockInitialize(&head->lock, 0); + head->node.next = DSM_HANDLE_INVALID; + head->node.num = 0; +} + +/* + * Get size of all files from the dirname directory, which names start + * with fn_start + */ +static int64 +tts_get_file_size(const char *dirname, const char *fn_start) +{ + struct dirent *direntry; + int64 dirsize = 0; + const size_t fn_start_len = strlen(fn_start); + DIR *dirdesc = AllocateDir(dirname); + + if (!dirdesc) + return 0; + + while ((direntry = ReadDir(dirdesc, dirname)) != NULL) + { + struct stat fst; + char fn[MAXPGPATH * 2]; + + CHECK_FOR_INTERRUPTS(); + + if (strcmp(direntry->d_name, ".") == 0 || + strcmp(direntry->d_name, "..") == 0 || + strncmp(direntry->d_name, fn_start, fn_start_len) != 0) + continue; + + snprintf(fn, sizeof(fn), "%s/%s", dirname, direntry->d_name); + + if (stat(fn, &fst) < 0) + { + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not stat file \"%s\": %m", fn))); + } + dirsize += fst.st_size; + } + + FreeDir(dirdesc); + return dirsize; +} + +/* Copy the files info from the list to local memory */ +static RelFileNodeBackend * +get_files(uint32 *files_num) +{ + RelFileNodeBackend *files; + + *files_num = 0; + + LWLockAcquire(&head->lock, LW_SHARED); + + /* Count files of temp tables */ + for (const TTSNode *node = &head->node; node != NULL; node = next_node(node)) + *files_num += node->num; + + /* Allocate local memory for array of the files data */ + files = palloc(sizeof(*files) * (*files_num)); + + /* Combine arrays from the list nodes into one array */ + *files_num = 0; + for (const TTSNode *node = &head->node; node != NULL; node = next_node(node)) + { + RelFileNodeBackend *dst = files + (*files_num); + memcpy(dst, node->files, sizeof(*files) * node->num); + *files_num += node->num; + } + + LWLockRelease(&head->lock); + + return files; +} + +/* Get temp tables files list on segments */ +PG_FUNCTION_INFO_V1(tts_get_seg_files); +Datum +tts_get_seg_files(PG_FUNCTION_ARGS) +{ + enum { NATTR = 5 }; + + FuncCallContext *funcctx; + const PgBackendStatus *beStatus; + const RelFileNodeBackend *file; + char *sep; + char *path; + HeapTuple tuple; + Datum values[NATTR] = {0}; + bool nulls [NATTR] = {0}; + static const PgBackendStatus *beStatuses = NULL; + + if (SRF_IS_FIRSTCALL()) + { + MemoryContext oldcontext; + TupleDesc tupdesc; + + funcctx = SRF_FIRSTCALL_INIT(); + + oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); + + tupdesc = CreateTemplateTupleDesc(NATTR, false); + TupleDescInitEntry(tupdesc, 1, "user_id", OIDOID, -1, 0); + TupleDescInitEntry(tupdesc, 2, "sess_id", INT4OID, -1, 0); + TupleDescInitEntry(tupdesc, 3, "path", TEXTOID, -1, 0); + TupleDescInitEntry(tupdesc, 4, "content", INT2OID, -1, 0); + TupleDescInitEntry(tupdesc, 5, "size", INT8OID, -1, 0); + + funcctx->tuple_desc = BlessTupleDesc(tupdesc); + + if (head->node.num == 0) + { + MemoryContextSwitchTo(oldcontext); + SRF_RETURN_DONE(funcctx); + } + + funcctx->user_fctx = get_files(&funcctx->max_calls); + MemoryContextSwitchTo(oldcontext); + } + + funcctx = SRF_PERCALL_SETUP(); + + if (funcctx->call_cntr >= funcctx->max_calls) + SRF_RETURN_DONE(funcctx); + + if (beStatuses == NULL) + { + bool found; + Size size = mul_size(sizeof(PgBackendStatus), MaxBackends); + beStatuses = ShmemInitStruct("Backend Status Array", size, &found); + if (!found) + ereport(ERROR, (errmsg("Backend Status Array is not found"))); + } + + file = ((RelFileNodeBackend *) funcctx->user_fctx) + funcctx->call_cntr; + + beStatus = &beStatuses[file->backend - 1]; + values[0] = ObjectIdGetDatum(beStatus->st_userid); + values[1] = Int32GetDatum(beStatus->st_session_id); + path = relpathbackend(file->node, TempRelBackendId, MAIN_FORKNUM); + values[2] = CStringGetTextDatum(path); + values[3] = Int16GetDatum(GpIdentity.segindex); + sep = strrchr(path, '/'); + Assert(sep != NULL); + *sep = '\0'; + values[4] = Int64GetDatum(tts_get_file_size(path, sep + 1)); + pfree(path); + + tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls); + + SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple)); +} + +void +_PG_init(void) +{ + if (!process_shared_preload_libraries_in_progress) + { + ereport(ERROR, + (errmsg("temp_tables_stat is not in shared_preload_libraries"))); + } + + if (IS_QUERY_DISPATCHER()) + return; + + RequestAddinShmemSpace(sizeof(TTSHeadNode)); + RequestAddinLWLocks(1); + + prev_file_create_hook = file_create_hook; + file_create_hook = tts_file_create_hook; + + prev_file_unlink_hook = file_unlink_hook; + file_unlink_hook = tts_file_unlink_hook; + + prev_shmem_startup_hook = shmem_startup_hook; + shmem_startup_hook = tts_shmem_startup; +} + +void +_PG_fini(void) +{ + if (IS_QUERY_DISPATCHER()) + return; + + file_create_hook = prev_file_create_hook; + file_unlink_hook = prev_file_unlink_hook; + shmem_startup_hook = prev_shmem_startup_hook; +} diff --git a/gpcontrib/temp_tables_stat/temp_tables_stat.control b/gpcontrib/temp_tables_stat/temp_tables_stat.control new file mode 100644 index 00000000000..b08ce3480f1 --- /dev/null +++ b/gpcontrib/temp_tables_stat/temp_tables_stat.control @@ -0,0 +1,5 @@ +# temp_tables_stat extension +comment = 'Collect and show statistics on temporary tables' +default_version = '0.1' +module_pathname = '$libdir/temp_tables_stat' +relocatable = true diff --git a/src/test/isolation2/Makefile b/src/test/isolation2/Makefile index 87c54fd4307..9a2d40b4b0e 100644 --- a/src/test/isolation2/Makefile +++ b/src/test/isolation2/Makefile @@ -76,6 +76,8 @@ installcheck: install installcheck-parallel-retrieve-cursor installcheck-ic-tcp installcheck-mdb: install ./pg_isolation2_regress $(EXTRA_REGRESS_OPTS) --init-file=$(top_builddir)/src/test/regress/init_file --init-file=./init_file_isolation2 --psqldir='$(PSQLDIR)' --inputdir=$(srcdir) --schedule=$(srcdir)/isolation2_schedule_mdb +installcheck-tts: install + ./pg_isolation2_regress $(EXTRA_REGRESS_OPTS) --init-file=$(top_builddir)/src/test/regress/init_file --init-file=./init_file_isolation2 --psqldir='$(PSQLDIR)' --inputdir=$(srcdir) temp_tables_stat installcheck-resgroup: install ./pg_isolation2_regress $(EXTRA_REGRESS_OPTS) --init-file=$(top_builddir)/src/test/regress/init_file --init-file=./init_file_resgroup --psqldir='$(PSQLDIR)' --inputdir=$(srcdir) --dbname=isolation2resgrouptest --schedule=$(srcdir)/isolation2_resgroup_schedule diff --git a/src/test/isolation2/expected/temp_tables_stat.out b/src/test/isolation2/expected/temp_tables_stat.out new file mode 100644 index 00000000000..9113b5b03d6 --- /dev/null +++ b/src/test/isolation2/expected/temp_tables_stat.out @@ -0,0 +1,1399 @@ +-- start_ignore +0: ! gpconfig -c shared_preload_libraries -v 'temp_tables_stat'; +20251123:12:36:14:039354 gpconfig:sokolov43a-yu-lin:sokolov43a-yu-[INFO]:-completed successfully with parameters '-c shared_preload_libraries -v temp_tables_stat' + +0: ! gpstop -raiq; + + +1: CREATE EXTENSION IF NOT EXISTS temp_tables_stat; +CREATE +-- end_ignore + +1: CREATE OR REPLACE FUNCTION get_files (OUT user_id_ok bool, OUT cur_sess_id bool, OUT content int2, OUT size int8) RETURNS SETOF record AS $$ SELECT (SELECT a.oid = f.user_id FROM pg_authid a WHERE a.rolname = current_user) user_id_ok, (SELECT s.setting::int = f.sess_id FROM pg_settings s WHERE name = 'gp_session_id') cur_sess_id, content, size FROM tts_get_seg_files() f; -- $$ LANGUAGE SQL; +CREATE + +-- No tables, the files list is empty +1: SELECT * FROM tts_get_seg_files(); + user_id | sess_id | path | content | size +---------+---------+------+---------+------ +(0 rows) + +-- +-- Ordinary heap tables + +-- We can see tables created in the current session +1: CREATE TEMP TABLE t1(i INT) DISTRIBUTED BY (i); +CREATE +1: SELECT * FROM get_files(); + user_id_ok | cur_sess_id | content | size +------------+-------------+---------+------ + t | t | 0 | 0 + t | t | 1 | 0 + t | t | 2 | 0 +(3 rows) +1: CREATE TEMP TABLE t2(i INT) DISTRIBUTED BY (i); +CREATE +1: CREATE TEMP TABLE t3(i INT) DISTRIBUTED BY (i); +CREATE +1: SELECT * FROM get_files(); + user_id_ok | cur_sess_id | content | size +------------+-------------+---------+------ + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 0 +(9 rows) + +-- We can see tables created in other sessions +2: CREATE TEMP TABLE t1(i INT) DISTRIBUTED BY (i); +CREATE +1: SELECT * FROM get_files(); + user_id_ok | cur_sess_id | content | size +------------+-------------+---------+------ + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 0 + t | f | 1 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | f | 2 | 0 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 0 + t | f | 0 | 0 +(12 rows) +2: SELECT * FROM get_files(); + user_id_ok | cur_sess_id | content | size +------------+-------------+---------+------ + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | t | 0 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | t | 1 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | t | 2 | 0 +(12 rows) +3: SELECT * FROM get_files(); + user_id_ok | cur_sess_id | content | size +------------+-------------+---------+------ + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 0 +(12 rows) + +-- Dropped tables are removed from the list in all sessions +1: DROP TABLE t2; +DROP +1: SELECT COUNT(*) FROM tts_get_seg_files(); + count +------- + 9 +(1 row) +2: SELECT COUNT(*) FROM tts_get_seg_files(); + count +------- + 9 +(1 row) +3: SELECT COUNT(*) FROM tts_get_seg_files(); + count +------- + 9 +(1 row) +2: DROP TABLE t1; +DROP +1: SELECT COUNT(*) FROM tts_get_seg_files(); + count +------- + 6 +(1 row) +2: SELECT COUNT(*) FROM tts_get_seg_files(); + count +------- + 6 +(1 row) +3: SELECT COUNT(*) FROM tts_get_seg_files(); + count +------- + 6 +(1 row) +1q: ... +2q: ... +3q: ... + +-- +-- Heap tables, on commit drop + +-- We can see tables created in the current session +1: BEGIN; +BEGIN +1: CREATE TEMP TABLE t1(i INT) ON COMMIT DROP DISTRIBUTED BY (i); +CREATE +1: SELECT * FROM get_files(); + user_id_ok | cur_sess_id | content | size +------------+-------------+---------+------ + t | t | 1 | 0 + t | t | 2 | 0 + t | t | 0 | 0 +(3 rows) +1: CREATE TEMP TABLE t2(i INT) ON COMMIT DROP DISTRIBUTED BY (i); +CREATE +1: CREATE TEMP TABLE t3(i INT) ON COMMIT DROP DISTRIBUTED BY (i); +CREATE +1: SELECT * FROM get_files(); + user_id_ok | cur_sess_id | content | size +------------+-------------+---------+------ + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 0 +(9 rows) + +-- We can see tables created in other sessions +2: BEGIN; +BEGIN +2: CREATE TEMP TABLE t1(i INT) ON COMMIT DROP DISTRIBUTED BY (i); +CREATE +1: SELECT * FROM get_files(); + user_id_ok | cur_sess_id | content | size +------------+-------------+---------+------ + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | f | 2 | 0 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 0 + t | f | 1 | 0 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 0 + t | f | 0 | 0 +(12 rows) +2: SELECT * FROM get_files(); + user_id_ok | cur_sess_id | content | size +------------+-------------+---------+------ + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | t | 2 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | t | 0 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | t | 1 | 0 +(12 rows) +3: SELECT * FROM get_files(); + user_id_ok | cur_sess_id | content | size +------------+-------------+---------+------ + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 0 +(12 rows) + +-- Dropped tables are removed from the list in all sessions +1: ROLLBACK; +ROLLBACK +1: SELECT COUNT(*) FROM tts_get_seg_files(); + count +------- + 3 +(1 row) +2: SELECT COUNT(*) FROM tts_get_seg_files(); + count +------- + 3 +(1 row) +3: SELECT COUNT(*) FROM tts_get_seg_files(); + count +------- + 3 +(1 row) +2: COMMIT; +COMMIT +1: SELECT COUNT(*) FROM tts_get_seg_files(); + count +------- + 0 +(1 row) +2: SELECT COUNT(*) FROM tts_get_seg_files(); + count +------- + 0 +(1 row) +3: SELECT COUNT(*) FROM tts_get_seg_files(); + count +------- + 0 +(1 row) +1q: ... +2q: ... +3q: ... + +-- +-- Ordinary AO tables +-- 4 files per AO table: data file, pg_aoseg, pg_aovisimap, pg_aovisimap_index + +-- We can see tables created in the current session +1: CREATE TEMP TABLE t1(i INT) WITH (APPENDOPTIMIZED = TRUE) DISTRIBUTED BY (i); +CREATE +1: SELECT * FROM get_files(); + user_id_ok | cur_sess_id | content | size +------------+-------------+---------+------- + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 32768 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 32768 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 32768 +(12 rows) +1: CREATE TEMP TABLE t2(i INT) WITH (APPENDOPTIMIZED = TRUE) DISTRIBUTED BY (i); +CREATE +1: CREATE TEMP TABLE t3(i INT) WITH (APPENDOPTIMIZED = TRUE) DISTRIBUTED BY (i); +CREATE +1: SELECT * FROM get_files(); + user_id_ok | cur_sess_id | content | size +------------+-------------+---------+------- + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 32768 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 32768 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 32768 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 32768 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 32768 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 32768 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 32768 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 32768 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 32768 +(36 rows) + +-- We can see tables created in other sessions +2: CREATE TEMP TABLE t1(i INT) WITH (APPENDOPTIMIZED = TRUE) DISTRIBUTED BY (i); +CREATE +1: SELECT * FROM get_files(); + user_id_ok | cur_sess_id | content | size +------------+-------------+---------+------- + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 32768 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 32768 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 32768 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 32768 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 32768 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 32768 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 32768 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 32768 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 32768 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 32768 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 32768 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 32768 +(48 rows) +2: SELECT * FROM get_files(); + user_id_ok | cur_sess_id | content | size +------------+-------------+---------+------- + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 32768 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 32768 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 32768 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 32768 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 32768 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 32768 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 32768 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 32768 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 32768 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 32768 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 32768 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 32768 +(48 rows) +3: SELECT * FROM get_files(); + user_id_ok | cur_sess_id | content | size +------------+-------------+---------+------- + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 32768 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 32768 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 32768 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 32768 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 32768 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 32768 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 32768 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 32768 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 32768 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 32768 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 32768 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 32768 +(48 rows) + +-- Dropped tables are removed from the list in all sessions +1: DROP TABLE t2; +DROP +1: SELECT COUNT(*) FROM tts_get_seg_files(); + count +------- + 36 +(1 row) +2: SELECT COUNT(*) FROM tts_get_seg_files(); + count +------- + 36 +(1 row) +3: SELECT COUNT(*) FROM tts_get_seg_files(); + count +------- + 36 +(1 row) +2: DROP TABLE t1; +DROP +1: SELECT COUNT(*) FROM tts_get_seg_files(); + count +------- + 24 +(1 row) +2: SELECT COUNT(*) FROM tts_get_seg_files(); + count +------- + 24 +(1 row) +3: SELECT COUNT(*) FROM tts_get_seg_files(); + count +------- + 24 +(1 row) +1q: ... +2q: ... +3q: ... + +-- +-- AO tables, on commit drop + +-- We can see tables created in the current session +1: BEGIN; +BEGIN +1: CREATE TEMP TABLE t1(i INT) WITH (APPENDOPTIMIZED = TRUE) ON COMMIT DROP DISTRIBUTED BY (i); +CREATE +1: SELECT * FROM get_files(); + user_id_ok | cur_sess_id | content | size +------------+-------------+---------+------- + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 32768 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 32768 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 32768 +(12 rows) +1: CREATE TEMP TABLE t2(i INT) WITH (APPENDOPTIMIZED = TRUE) ON COMMIT DROP DISTRIBUTED BY (i); +CREATE +1: CREATE TEMP TABLE t3(i INT) WITH (APPENDOPTIMIZED = TRUE) ON COMMIT DROP DISTRIBUTED BY (i); +CREATE +1: SELECT * FROM get_files(); + user_id_ok | cur_sess_id | content | size +------------+-------------+---------+------- + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 32768 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 32768 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 32768 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 32768 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 32768 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 32768 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 32768 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 32768 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 32768 +(36 rows) + +-- We can see tables created in other sessions +2: BEGIN; +BEGIN +2: CREATE TEMP TABLE t1(i INT) WITH (APPENDOPTIMIZED = TRUE) ON COMMIT DROP DISTRIBUTED BY (i); +CREATE +1: SELECT * FROM get_files(); + user_id_ok | cur_sess_id | content | size +------------+-------------+---------+------- + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 32768 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 32768 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 32768 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 32768 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 32768 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 32768 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 32768 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 32768 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 32768 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 32768 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 32768 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 32768 +(48 rows) +2: SELECT * FROM get_files(); + user_id_ok | cur_sess_id | content | size +------------+-------------+---------+------- + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 32768 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 32768 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 32768 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 32768 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 32768 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 32768 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 32768 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 32768 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 32768 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 32768 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 32768 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 32768 +(48 rows) +3: SELECT * FROM get_files(); + user_id_ok | cur_sess_id | content | size +------------+-------------+---------+------- + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 32768 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 32768 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 32768 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 32768 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 32768 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 32768 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 32768 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 32768 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 32768 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 32768 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 32768 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 32768 +(48 rows) + +-- Dropped tables are removed from the list in all sessions +1: ROLLBACK; +ROLLBACK +1: SELECT COUNT(*) FROM tts_get_seg_files(); + count +------- + 12 +(1 row) +2: SELECT COUNT(*) FROM tts_get_seg_files(); + count +------- + 12 +(1 row) +3: SELECT COUNT(*) FROM tts_get_seg_files(); + count +------- + 12 +(1 row) +2: COMMIT; +COMMIT +1: SELECT COUNT(*) FROM tts_get_seg_files(); + count +------- + 0 +(1 row) +2: SELECT COUNT(*) FROM tts_get_seg_files(); + count +------- + 0 +(1 row) +3: SELECT COUNT(*) FROM tts_get_seg_files(); + count +------- + 0 +(1 row) +1q: ... +2q: ... +3q: ... + +-- +-- Ordinary AOCO tables +-- 4 files per AOCO table: data file, pg_aocsseg, pg_aovisimap, pg_aovisimap_index + +-- We can see tables created in the current session +1: CREATE TEMP TABLE t1(i INT, j INT) WITH (APPENDOPTIMIZED = TRUE, ORIENTATION = COLUMN) DISTRIBUTED BY (i); +CREATE +1: SELECT * FROM get_files(); + user_id_ok | cur_sess_id | content | size +------------+-------------+---------+------- + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 32768 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 32768 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 32768 +(12 rows) +1: CREATE TEMP TABLE t2(i INT, j INT) WITH (APPENDOPTIMIZED = TRUE, ORIENTATION = COLUMN) DISTRIBUTED BY (i); +CREATE +1: CREATE TEMP TABLE t3(i INT, j INT) WITH (APPENDOPTIMIZED = TRUE, ORIENTATION = COLUMN) DISTRIBUTED BY (i); +CREATE +1: SELECT * FROM get_files(); + user_id_ok | cur_sess_id | content | size +------------+-------------+---------+------- + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 32768 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 32768 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 32768 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 32768 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 32768 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 32768 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 32768 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 32768 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 32768 +(36 rows) + +-- We can see tables created in other sessions +2: CREATE TEMP TABLE t1(i INT, j INT) WITH (APPENDOPTIMIZED = TRUE, ORIENTATION = COLUMN) DISTRIBUTED BY (i); +CREATE +1: SELECT * FROM get_files(); + user_id_ok | cur_sess_id | content | size +------------+-------------+---------+------- + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 32768 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 32768 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 32768 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 32768 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 32768 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 32768 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 32768 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 32768 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 32768 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 32768 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 32768 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 32768 +(48 rows) +2: SELECT * FROM get_files(); + user_id_ok | cur_sess_id | content | size +------------+-------------+---------+------- + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 32768 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 32768 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 32768 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 32768 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 32768 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 32768 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 32768 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 32768 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 32768 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 32768 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 32768 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 32768 +(48 rows) +3: SELECT * FROM get_files(); + user_id_ok | cur_sess_id | content | size +------------+-------------+---------+------- + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 32768 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 32768 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 32768 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 32768 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 32768 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 32768 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 32768 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 32768 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 32768 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 32768 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 32768 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 32768 +(48 rows) + +-- Dropped tables are removed from the list in all sessions +1: DROP TABLE t2; +DROP +1: SELECT COUNT(*) FROM tts_get_seg_files(); + count +------- + 36 +(1 row) +2: SELECT COUNT(*) FROM tts_get_seg_files(); + count +------- + 36 +(1 row) +3: SELECT COUNT(*) FROM tts_get_seg_files(); + count +------- + 36 +(1 row) +2: DROP TABLE t1; +DROP +1: SELECT COUNT(*) FROM tts_get_seg_files(); + count +------- + 24 +(1 row) +2: SELECT COUNT(*) FROM tts_get_seg_files(); + count +------- + 24 +(1 row) +3: SELECT COUNT(*) FROM tts_get_seg_files(); + count +------- + 24 +(1 row) +1q: ... +2q: ... +3q: ... + + +-- +-- AO tables, on commit drop + +-- We can see tables created in the current session +1: BEGIN; +BEGIN +1: CREATE TEMP TABLE t1(i INT, j INT) WITH (APPENDOPTIMIZED = TRUE, ORIENTATION = COLUMN) ON COMMIT DROP DISTRIBUTED BY (i); +CREATE +1: SELECT * FROM get_files(); + user_id_ok | cur_sess_id | content | size +------------+-------------+---------+------- + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 32768 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 32768 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 32768 +(12 rows) +1: CREATE TEMP TABLE t2(i INT, j INT) WITH (APPENDOPTIMIZED = TRUE, ORIENTATION = COLUMN) ON COMMIT DROP DISTRIBUTED BY (i); +CREATE +1: CREATE TEMP TABLE t3(i INT, j INT) WITH (APPENDOPTIMIZED = TRUE, ORIENTATION = COLUMN) ON COMMIT DROP DISTRIBUTED BY (i); +CREATE +1: SELECT * FROM get_files(); + user_id_ok | cur_sess_id | content | size +------------+-------------+---------+------- + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 32768 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 32768 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 32768 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 32768 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 32768 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 32768 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 32768 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 32768 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 32768 +(36 rows) + +-- We can see tables created in other sessions +2: BEGIN; +BEGIN +2: CREATE TEMP TABLE t1(i INT, j INT) WITH (APPENDOPTIMIZED = TRUE, ORIENTATION = COLUMN) ON COMMIT DROP DISTRIBUTED BY (i); +CREATE +1: SELECT * FROM get_files(); + user_id_ok | cur_sess_id | content | size +------------+-------------+---------+------- + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 32768 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 32768 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 32768 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 32768 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 32768 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 32768 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 32768 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 32768 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 32768 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 32768 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 32768 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 32768 +(48 rows) +2: SELECT * FROM get_files(); + user_id_ok | cur_sess_id | content | size +------------+-------------+---------+------- + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 32768 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 32768 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 32768 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 0 + t | t | 1 | 32768 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 32768 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 32768 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 32768 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 0 + t | t | 0 | 32768 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 32768 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 32768 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 32768 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 0 + t | t | 2 | 32768 +(48 rows) +3: SELECT * FROM get_files(); + user_id_ok | cur_sess_id | content | size +------------+-------------+---------+------- + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 32768 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 32768 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 32768 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 0 + t | f | 2 | 32768 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 32768 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 32768 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 32768 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 0 + t | f | 0 | 32768 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 32768 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 32768 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 32768 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 0 + t | f | 1 | 32768 +(48 rows) + +-- Dropped tables are removed from the list in all sessions +1: ROLLBACK; +ROLLBACK +1: SELECT COUNT(*) FROM tts_get_seg_files(); + count +------- + 12 +(1 row) +2: SELECT COUNT(*) FROM tts_get_seg_files(); + count +------- + 12 +(1 row) +3: SELECT COUNT(*) FROM tts_get_seg_files(); + count +------- + 12 +(1 row) +2: COMMIT; +COMMIT +1: SELECT COUNT(*) FROM tts_get_seg_files(); + count +------- + 0 +(1 row) +2: SELECT COUNT(*) FROM tts_get_seg_files(); + count +------- + 0 +(1 row) +3: SELECT COUNT(*) FROM tts_get_seg_files(); + count +------- + 0 +(1 row) +1q: ... +2q: ... +3q: ... + +-- +-- Check that files size calculation takes into account all the forks +CREATE TEMP TABLE t1 WITH (APPENDOPTIMIZED = TRUE, ORIENTATION = COLUMN) AS SELECT i, i j FROM generate_series(1, 100) i DISTRIBUTED BY (i); +CREATE 100 +-- t1 consists of two colums. Both column files are taken into account +SELECT content, size FROM tts_get_seg_files(); + content | size +---------+------- + 2 | 288 + 2 | 32768 + 2 | 0 + 2 | 32768 + 0 | 384 + 0 | 32768 + 0 | 0 + 0 | 32768 + 1 | 384 + 1 | 32768 + 1 | 0 + 1 | 32768 +(12 rows) +-- Vaccum adds FSM and VM +VACUUM t1; +VACUUM +SELECT content, size FROM tts_get_seg_files(); + content | size +---------+-------- + 1 | 384 + 1 | 163840 + 1 | 0 + 1 | 32768 + 2 | 288 + 2 | 163840 + 2 | 0 + 2 | 32768 + 0 | 384 + 0 | 163840 + 0 | 0 + 0 | 32768 +(12 rows) + +-- +-- Cleanup +DROP FUNCTION get_files (OUT user_id_ok bool, OUT cur_sess_id bool, OUT content int2, OUT size int8); +DROP + +DROP EXTENSION temp_tables_stat; +DROP + +-- start_ignore +! gpconfig -r shared_preload_libraries; +20251123:12:36:27:042380 gpconfig:sokolov43a-yu-lin:sokolov43a-yu-[INFO]:-completed successfully with parameters '-r shared_preload_libraries' + +! gpstop -raiq; + +-- end_ignore diff --git a/src/test/isolation2/sql/temp_tables_stat.sql b/src/test/isolation2/sql/temp_tables_stat.sql new file mode 100644 index 00000000000..dbdfd3d177c --- /dev/null +++ b/src/test/isolation2/sql/temp_tables_stat.sql @@ -0,0 +1,251 @@ +-- start_ignore +0: ! gpconfig -c shared_preload_libraries -v 'temp_tables_stat'; +0: ! gpstop -raiq; + +1: CREATE EXTENSION IF NOT EXISTS temp_tables_stat; +-- end_ignore + +1: CREATE OR REPLACE FUNCTION get_files +(OUT user_id_ok bool, OUT cur_sess_id bool, OUT content int2, OUT size int8) +RETURNS SETOF record +AS $$ + SELECT (SELECT a.oid = f.user_id + FROM pg_authid a + WHERE a.rolname = current_user) user_id_ok, + (SELECT s.setting::int = f.sess_id + FROM pg_settings s + WHERE name = 'gp_session_id') cur_sess_id, + content, + size + FROM tts_get_seg_files() f; -- +$$ LANGUAGE SQL; + +-- No tables, the files list is empty +1: SELECT * FROM tts_get_seg_files(); + +-- +-- Ordinary heap tables + +-- We can see tables created in the current session +1: CREATE TEMP TABLE t1(i INT) DISTRIBUTED BY (i); +1: SELECT * FROM get_files(); +1: CREATE TEMP TABLE t2(i INT) DISTRIBUTED BY (i); +1: CREATE TEMP TABLE t3(i INT) DISTRIBUTED BY (i); +1: SELECT * FROM get_files(); + +-- We can see tables created in other sessions +2: CREATE TEMP TABLE t1(i INT) DISTRIBUTED BY (i); +1: SELECT * FROM get_files(); +2: SELECT * FROM get_files(); +3: SELECT * FROM get_files(); + +-- Dropped tables are removed from the list in all sessions +1: DROP TABLE t2; +1: SELECT COUNT(*) FROM tts_get_seg_files(); +2: SELECT COUNT(*) FROM tts_get_seg_files(); +3: SELECT COUNT(*) FROM tts_get_seg_files(); +2: DROP TABLE t1; +1: SELECT COUNT(*) FROM tts_get_seg_files(); +2: SELECT COUNT(*) FROM tts_get_seg_files(); +3: SELECT COUNT(*) FROM tts_get_seg_files(); +1q: +2q: +3q: + +-- +-- Heap tables, on commit drop + +-- We can see tables created in the current session +1: BEGIN; +1: CREATE TEMP TABLE t1(i INT) ON COMMIT DROP DISTRIBUTED BY (i); +1: SELECT * FROM get_files(); +1: CREATE TEMP TABLE t2(i INT) ON COMMIT DROP DISTRIBUTED BY (i); +1: CREATE TEMP TABLE t3(i INT) ON COMMIT DROP DISTRIBUTED BY (i); +1: SELECT * FROM get_files(); + +-- We can see tables created in other sessions +2: BEGIN; +2: CREATE TEMP TABLE t1(i INT) ON COMMIT DROP DISTRIBUTED BY (i); +1: SELECT * FROM get_files(); +2: SELECT * FROM get_files(); +3: SELECT * FROM get_files(); + +-- Dropped tables are removed from the list in all sessions +1: ROLLBACK; +1: SELECT COUNT(*) FROM tts_get_seg_files(); +2: SELECT COUNT(*) FROM tts_get_seg_files(); +3: SELECT COUNT(*) FROM tts_get_seg_files(); +2: COMMIT; +1: SELECT COUNT(*) FROM tts_get_seg_files(); +2: SELECT COUNT(*) FROM tts_get_seg_files(); +3: SELECT COUNT(*) FROM tts_get_seg_files(); +1q: +2q: +3q: + +-- +-- Ordinary AO tables +-- 4 files per AO table: data file, pg_aoseg, pg_aovisimap, pg_aovisimap_index + +-- We can see tables created in the current session +1: CREATE TEMP TABLE t1(i INT) WITH (APPENDOPTIMIZED = TRUE) DISTRIBUTED BY (i); +1: SELECT * FROM get_files(); +1: CREATE TEMP TABLE t2(i INT) WITH (APPENDOPTIMIZED = TRUE) DISTRIBUTED BY (i); +1: CREATE TEMP TABLE t3(i INT) WITH (APPENDOPTIMIZED = TRUE) DISTRIBUTED BY (i); +1: SELECT * FROM get_files(); + +-- We can see tables created in other sessions +2: CREATE TEMP TABLE t1(i INT) WITH (APPENDOPTIMIZED = TRUE) DISTRIBUTED BY (i); +1: SELECT * FROM get_files(); +2: SELECT * FROM get_files(); +3: SELECT * FROM get_files(); + +-- Dropped tables are removed from the list in all sessions +1: DROP TABLE t2; +1: SELECT COUNT(*) FROM tts_get_seg_files(); +2: SELECT COUNT(*) FROM tts_get_seg_files(); +3: SELECT COUNT(*) FROM tts_get_seg_files(); +2: DROP TABLE t1; +1: SELECT COUNT(*) FROM tts_get_seg_files(); +2: SELECT COUNT(*) FROM tts_get_seg_files(); +3: SELECT COUNT(*) FROM tts_get_seg_files(); +1q: +2q: +3q: + +-- +-- AO tables, on commit drop + +-- We can see tables created in the current session +1: BEGIN; +1: CREATE TEMP TABLE t1(i INT) WITH (APPENDOPTIMIZED = TRUE) ON COMMIT DROP DISTRIBUTED BY (i); +1: SELECT * FROM get_files(); +1: CREATE TEMP TABLE t2(i INT) WITH (APPENDOPTIMIZED = TRUE) ON COMMIT DROP DISTRIBUTED BY (i); +1: CREATE TEMP TABLE t3(i INT) WITH (APPENDOPTIMIZED = TRUE) ON COMMIT DROP DISTRIBUTED BY (i); +1: SELECT * FROM get_files(); + +-- We can see tables created in other sessions +2: BEGIN; +2: CREATE TEMP TABLE t1(i INT) WITH (APPENDOPTIMIZED = TRUE) ON COMMIT DROP DISTRIBUTED BY (i); +1: SELECT * FROM get_files(); +2: SELECT * FROM get_files(); +3: SELECT * FROM get_files(); + +-- Dropped tables are removed from the list in all sessions +1: ROLLBACK; +1: SELECT COUNT(*) FROM tts_get_seg_files(); +2: SELECT COUNT(*) FROM tts_get_seg_files(); +3: SELECT COUNT(*) FROM tts_get_seg_files(); +2: COMMIT; +1: SELECT COUNT(*) FROM tts_get_seg_files(); +2: SELECT COUNT(*) FROM tts_get_seg_files(); +3: SELECT COUNT(*) FROM tts_get_seg_files(); +1q: +2q: +3q: + +-- +-- Ordinary AOCO tables +-- 4 files per AOCO table: data file, pg_aocsseg, pg_aovisimap, pg_aovisimap_index + +-- We can see tables created in the current session +1: CREATE TEMP TABLE t1(i INT, j INT) + WITH (APPENDOPTIMIZED = TRUE, ORIENTATION = COLUMN) + DISTRIBUTED BY (i); +1: SELECT * FROM get_files(); +1: CREATE TEMP TABLE t2(i INT, j INT) + WITH (APPENDOPTIMIZED = TRUE, ORIENTATION = COLUMN) + DISTRIBUTED BY (i); +1: CREATE TEMP TABLE t3(i INT, j INT) + WITH (APPENDOPTIMIZED = TRUE, ORIENTATION = COLUMN) + DISTRIBUTED BY (i); +1: SELECT * FROM get_files(); + +-- We can see tables created in other sessions +2: CREATE TEMP TABLE t1(i INT, j INT) + WITH (APPENDOPTIMIZED = TRUE, ORIENTATION = COLUMN) + DISTRIBUTED BY (i); +1: SELECT * FROM get_files(); +2: SELECT * FROM get_files(); +3: SELECT * FROM get_files(); + +-- Dropped tables are removed from the list in all sessions +1: DROP TABLE t2; +1: SELECT COUNT(*) FROM tts_get_seg_files(); +2: SELECT COUNT(*) FROM tts_get_seg_files(); +3: SELECT COUNT(*) FROM tts_get_seg_files(); +2: DROP TABLE t1; +1: SELECT COUNT(*) FROM tts_get_seg_files(); +2: SELECT COUNT(*) FROM tts_get_seg_files(); +3: SELECT COUNT(*) FROM tts_get_seg_files(); +1q: +2q: +3q: + + +-- +-- AO tables, on commit drop + +-- We can see tables created in the current session +1: BEGIN; +1: CREATE TEMP TABLE t1(i INT, j INT) + WITH (APPENDOPTIMIZED = TRUE, ORIENTATION = COLUMN) + ON COMMIT DROP + DISTRIBUTED BY (i); +1: SELECT * FROM get_files(); +1: CREATE TEMP TABLE t2(i INT, j INT) + WITH (APPENDOPTIMIZED = TRUE, ORIENTATION = COLUMN) + ON COMMIT DROP + DISTRIBUTED BY (i); +1: CREATE TEMP TABLE t3(i INT, j INT) + WITH (APPENDOPTIMIZED = TRUE, ORIENTATION = COLUMN) + ON COMMIT DROP + DISTRIBUTED BY (i); +1: SELECT * FROM get_files(); + +-- We can see tables created in other sessions +2: BEGIN; +2: CREATE TEMP TABLE t1(i INT, j INT) + WITH (APPENDOPTIMIZED = TRUE, ORIENTATION = COLUMN) + ON COMMIT DROP + DISTRIBUTED BY (i); +1: SELECT * FROM get_files(); +2: SELECT * FROM get_files(); +3: SELECT * FROM get_files(); + +-- Dropped tables are removed from the list in all sessions +1: ROLLBACK; +1: SELECT COUNT(*) FROM tts_get_seg_files(); +2: SELECT COUNT(*) FROM tts_get_seg_files(); +3: SELECT COUNT(*) FROM tts_get_seg_files(); +2: COMMIT; +1: SELECT COUNT(*) FROM tts_get_seg_files(); +2: SELECT COUNT(*) FROM tts_get_seg_files(); +3: SELECT COUNT(*) FROM tts_get_seg_files(); +1q: +2q: +3q: + +-- +-- Check that files size calculation takes into account all the forks +CREATE TEMP TABLE t1 + WITH (APPENDOPTIMIZED = TRUE, ORIENTATION = COLUMN) + AS SELECT i, i j FROM generate_series(1, 100) i + DISTRIBUTED BY (i); +-- t1 consists of two colums. Both column files are taken into account +SELECT content, size FROM tts_get_seg_files(); +-- Vaccum adds FSM and VM +VACUUM t1; +SELECT content, size FROM tts_get_seg_files(); + +-- +-- Cleanup +DROP FUNCTION get_files +(OUT user_id_ok bool, OUT cur_sess_id bool, OUT content int2, OUT size int8); + +DROP EXTENSION temp_tables_stat; + +-- start_ignore +! gpconfig -r shared_preload_libraries; +! gpstop -raiq; +-- end_ignore