blob: 30f03315d7e58c66f54566e3447644513701cfb6 [file] [log] [blame]
CREATE OR REPLACE FUNCTION gp_workfile_mgr_test_on_master(testname text, numfiles int)
RETURNS setof bool
LANGUAGE C VOLATILE EXECUTE ON COORDINATOR AS '@abs_builddir@/isolation2_regress@DLSUFFIX@', 'gp_workfile_mgr_test_harness';
CREATE OR REPLACE FUNCTION gp_workfile_mgr_test_on_segments(testname text, numfiles int)
RETURNS setof bool
LANGUAGE C VOLATILE EXECUTE ON ALL SEGMENTS AS '@abs_builddir@/isolation2_regress@DLSUFFIX@', 'gp_workfile_mgr_test_harness';
CREATE FUNCTION gp_workfile_mgr_test(testname text, numfiles int)
RETURNS SETOF BOOL
AS
$$
SELECT C.* FROM gp_workfile_mgr_test_on_master($1, $2) as C
UNION ALL
SELECT C.* FROM gp_workfile_mgr_test_on_segments($1, $2) as C
$$
LANGUAGE SQL;
CREATE OR REPLACE FUNCTION gp_workfile_mgr_create_workset(worksetname text, interXact bool, holdPin bool, closeFile bool)
RETURNS setof void
LANGUAGE C VOLATILE EXECUTE ON ALL SEGMENTS AS '@abs_builddir@/isolation2_regress@DLSUFFIX@', 'gp_workfile_mgr_create_workset';
CREATE OR REPLACE FUNCTION gp_workfile_mgr_create_empty_workset(worksetname text)
RETURNS setof void
LANGUAGE C VOLATILE EXECUTE ON ALL SEGMENTS AS '@abs_builddir@/isolation2_regress@DLSUFFIX@', 'gp_workfile_mgr_create_workset';
CREATE FUNCTION gp_workfile_mgr_cache_entries()
RETURNS TABLE(segid int4, prefix text, size int8, operation text, slice int4, sessionid int4, commandid int4, numfiles int4)
AS '$libdir/gp_workfile_mgr', 'gp_workfile_mgr_cache_entries'
LANGUAGE C VOLATILE EXECUTE ON ALL SEGMENTS;
-- Wait for at the most 1 min for backends to remove transient
-- workfile sets as part of exit processing and then report long lived
-- workfile sets.
create or replace function report_workfile_entries()
returns table(segid int4, prefix text, size int8, operation text, slice int4, numfiles int4) as $$
declare
iterations int; /* in func */
cnt int; /* in func */
begin
iterations := 120; /* wait at the most 1 min */
select count(*) into cnt from gp_workfile_mgr_cache_entries() w
where w.prefix not like 'long_live_workset%'; /* in func */
while (iterations > 0) and (cnt > 0)
loop
select count(*) into cnt from gp_workfile_mgr_cache_entries() w
where w.prefix not like 'long_live_workset%'; /* in func */
perform pg_sleep(0.5); /* sleep for half a second */
iterations := iterations - 1; /* in func */
end loop; /* in func */
return query select w.segid, w.prefix, w.size, w.operation, w.slice, w.numfiles
from gp_workfile_mgr_cache_entries() w; /* in func */
end; /* in func */
$$
language plpgsql volatile execute on all segments;
-- start_ignore
!\retcode gpconfig -c gp_workfile_max_entries -v 32 --skipvalidation;
!\retcode gpstop -ari;
-- end_ignore
-- setup for workfile made in temp tablespace test
! mkdir -p '@testtablespace@/workfile_mgr';
1: DROP TABLESPACE IF EXISTS work_file_test_ts;
1: CREATE TABLESPACE work_file_test_ts LOCATION '@testtablespace@/workfile_mgr';
1: select gp_workfile_mgr_test('atomic_test', 0);
-- test will fail when the workset exceeds gp_workfile_max_entries, the workset will be released at the end of transaction.
1: select gp_workfile_mgr_test('workfile_fill_sharedcache', 0);
1: select segid, count(*) from gp_workfile_mgr_cache_entries() group by segid order by segid;
1: select gp_workfile_mgr_test('workfile_create_and_set_cleanup', 2000);
1: select gp_workfile_mgr_test('workfile_create_and_individual_cleanup', 2000);
1: select gp_workfile_mgr_test('workfile_made_in_temp_tablespace', 2000);
1: select gp_workfile_mgr_test('workfile_create_and_individual_cleanup_with_pinned_workfile_set', 2000);
1: DROP TABLESPACE work_file_test_ts;
-- start_ignore
!\retcode gpconfig -r gp_workfile_max_entries --skipvalidation;
!\retcode gpstop -ari;
-- end_ignore
-- test workset cleanup
2: begin;
2: select gp_workfile_mgr_create_workset('short_live_workset', false, false, false);
2: select gp_workfile_mgr_create_empty_workset('long_live_workset');
2: select segid, count(*) from gp_workfile_mgr_cache_entries() group by segid order by segid;
3: select gp_workfile_mgr_create_workset('inter_xact_workset', true, false, false);
-- transaction commit will cleanup the pinned workfile_set.
4: begin;
4: select gp_workfile_mgr_create_workset('commit_tnx_workset', false, true, false);
4: select gp_workfile_mgr_create_workset('commit_tnx_workset_empty', false, true, true);
4: select segid, prefix, size, operation, slice, numfiles from gp_workfile_mgr_cache_entries() order by (segid, prefix);
4: end;
4: select segid, prefix, size, operation, slice, numfiles from gp_workfile_mgr_cache_entries() order by (segid, prefix);
-- transaction abort will cleanup the workset.
4: begin;
4: select gp_workfile_mgr_create_workset('abort_tnx_workset', false, false, false);
4: select gp_workfile_mgr_create_workset('abort_tnx_workset_pinned', false, true, false);
4: select segid, prefix, size, operation, slice, numfiles from gp_workfile_mgr_cache_entries() order by (segid, prefix);
4: abort;
4: select segid, prefix, size, operation, slice, numfiles from gp_workfile_mgr_cache_entries() order by (segid, prefix);
-- for workset lives across transaction, e.g. with hold cursor, proc exit will cleanup the workset
3q:
-- The "q:" step does not wait for the backend process to exit. So
-- wait at the most 1 min so that only the long lived sessions are
-- reported. If we don't wait thte test sometimes fails because
-- "inter_xact_workset" entries show up in the output of
-- gp_workfile_mgr_cache_entries().
4: select * from report_workfile_entries();