blob: 44fa22e1bafa369f31e8c9067c0d7f49d36018bd [file] [log] [blame]
-- Scenario for validating mirror PANIC immediately on truncate record replay
-- if file is missing.
-- start_ignore
create language plpython3u;
-- end_ignore
-- helper functions
CREATE FUNCTION rel_filepaths_on_segments(regclass) RETURNS TABLE(gp_segment_id int, filepath text)
STRICT STABLE LANGUAGE SQL AS
$fn$
SELECT gp_execution_segment(), pg_relation_filepath($1) AS filepath
$fn$
EXECUTE ON ALL SEGMENTS;
CREATE or REPLACE FUNCTION change_file_permission_readonly(path text)
RETURNS void as
$$
import os, stat
if not os.path.isfile(path):
plpy.info('skipping non-existent file %s' % (path))
else:
plpy.info('changing file permission to readonly')
os.chmod(path, stat.S_IRUSR);
$$ LANGUAGE plpython3u;
CREATE or REPLACE FUNCTION wait_for_replication_replay (retries int) RETURNS bool AS
$$
declare
i int;
result bool;
begin
i := 0;
-- Wait until the mirror (content 0) has replayed up to flush lsn
loop
SELECT flush_lsn = replay_lsn INTO result from gp_stat_replication where gp_segment_id = 0;
if result then
return true;
end if;
if i >= retries then
return false;
end if;
perform pg_sleep(0.1);
perform pg_stat_clear_snapshot();
i := i + 1;
end loop;
end;
$$ language plpgsql;
CREATE TABLE mirror_reply_test_table (a INT, b INT, c CHAR(20)) WITH (appendonly=true);
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table.
HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew.
INSERT INTO mirror_reply_test_table SELECT i AS a, 1 AS b, 'hello world' AS c FROM generate_series(1, 10) AS i;
-- need to wait till mirror creates the file on disk
SELECT wait_for_replication_replay(5000);
wait_for_replication_replay
-----------------------------
t
(1 row)
-- step to inject fault to make sure truncate xlog replay cannot open the file in write mode
SELECT change_file_permission_readonly(datadir || '/' ||
(SELECT filepath FROM rel_filepaths_on_segments('mirror_reply_test_table')
WHERE gp_segment_id = 0) || '.1')
FROM gp_segment_configuration WHERE content = 0 AND role = 'm';
INFO: changing file permission to readonly
CONTEXT: PL/Python function "change_file_permission_readonly"
change_file_permission_readonly
---------------------------------
(1 row)
-- generate truncate xlog record with non-zero EOF
VACUUM mirror_reply_test_table;
-- expecting mirror to be marked down
do $$
begin
for i in 1..120 loop
if (select status = 'd' from gp_segment_configuration where content=0 and role = 'm') then
return;
end if;
perform gp_request_fts_probe_scan();
perform pg_sleep(1);
end loop;
end;
$$;
SELECT role, preferred_role, mode, status FROM gp_segment_configuration WHERE content=0;
role | preferred_role | mode | status
------+----------------+------+--------
p | p | n | u
m | m | n | d
(2 rows)
-- post test cleanup
-- start_ignore
\! gprecoverseg -aF;
-- end_ignore
-- loop while segments come in sync
do $$
begin
for i in 1..120 loop
if (select mode = 's' from gp_segment_configuration where content=0 and role = 'p') then
return;
end if;
perform gp_request_fts_probe_scan();
perform pg_sleep(1);
end loop;
end;
$$;
SELECT role, preferred_role, mode, status FROM gp_segment_configuration WHERE content=0;
role | preferred_role | mode | status
------+----------------+------+--------
p | p | s | u
m | m | s | u
(2 rows)