File: pg_rewrite_concurrent.spec

package info (click to toggle)
pg-rewrite 2.0.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 348 kB
  • sloc: ansic: 3,132; sql: 199; makefile: 17; sh: 2
file content (135 lines) | stat: -rw-r--r-- 3,247 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
setup
{
    CREATE EXTENSION injection_points;
    CREATE EXTENSION pg_rewrite;

    CREATE TABLE tbl_src(i int primary key, j int,
			 k int generated always as (-j) virtual,
			 l int generated always as (-j) stored);
    INSERT INTO tbl_src(i, j) VALUES (1, 10), (4, 40), (7, 70);

    -- Change of data type and column order.
    CREATE TABLE tbl_dst(j int, i bigint primary key, k int, l int);
}

teardown
{
    DROP EXTENSION injection_points;
    DROP EXTENSION pg_rewrite;
    DROP TABLE tbl_src;
    DROP TABLE tbl_src_old;
}

session s1
setup
{
    SELECT injection_points_attach('pg_rewrite-before-lock', 'wait');
    SELECT injection_points_attach('pg_rewrite-after-commit', 'wait');
}
# Perform the initial load and wait for s2 to do some data changes.
#
# Since pg_rewrite uses background worker, the isolation tester does not
# recognize that the session waits on an injection point (because the worker
# is who waits). Therefore use rewrite_table_nowait(), which only launches the
# worker and goes on. The 'wait_for_s1_sleep' step below then checks until the
# waiting started.
step do_rewrite
{
    SELECT rewrite_table_nowait('tbl_src', 'tbl_dst', 'tbl_src_old');
}
# Check the data.
step do_check
{
    TABLE pg_rewrite_progress;

    SELECT i, j, k, l FROM tbl_src ORDER BY i, j;
}

session s2
# Since s1 uses background worker, the backend executing 'wait_before_lock'
# does not appear to be waiting on the injection point. Instead we need to
# check explicitly if the waiting on the injection point is in progress, and
# wait if it's not.
step wait_for_before_lock_ip
{
DO $$
BEGIN
        LOOP
		PERFORM pg_stat_clear_snapshot();

	        PERFORM
		FROM pg_stat_activity
		WHERE (wait_event_type, wait_event)=('InjectionPoint', 'pg_rewrite-before-lock');

		IF FOUND THEN
			EXIT;
		END IF;

		PERFORM pg_sleep(.1);
	END LOOP;
END;
$$;
}
step do_changes
{
	INSERT INTO tbl_src VALUES (2, 20), (3, 30), (5, 50);

	-- Update with no identity change.
	UPDATE tbl_src SET j=0 WHERE i=1;

	-- Update with identity change.
	UPDATE tbl_src SET i=6 WHERE i=4;

	-- Update a row we inserted, to check that the insertion is visible.
	UPDATE tbl_src SET j=7 WHERE i=2;
	-- ... and update it again, to check that the update is visible.
	UPDATE tbl_src SET j=8 WHERE j=7;

	-- Delete.
	DELETE FROM tbl_src WHERE i=7;
}
step wakeup_before_lock_ip
{
    SELECT injection_points_wakeup('pg_rewrite-before-lock');
}
# Wait until the concurrent changes have been committed by the pg_rewrite
# worker.
step wait_for_after_commit_ip
{
DO $$
BEGIN
        LOOP
		PERFORM pg_stat_clear_snapshot();

	        PERFORM
		FROM pg_stat_activity
		WHERE (wait_event_type, wait_event)=('InjectionPoint', 'pg_rewrite-after-commit');

		IF FOUND THEN
			EXIT;
		END IF;

		PERFORM pg_sleep(.1);
	END LOOP;
END;
$$;
}
# Like wakeup_before_lock_ip above.
step wakeup_after_commit_ip
{
    SELECT injection_points_wakeup('pg_rewrite-after-commit');
}
teardown
{
    SELECT injection_points_detach('pg_rewrite-before-lock');
    SELECT injection_points_detach('pg_rewrite-after-commit');
}

permutation
    do_rewrite
    wait_for_before_lock_ip
    do_changes
    wakeup_before_lock_ip
    wait_for_after_commit_ip
    do_check
    wakeup_after_commit_ip