-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathpgio.sql
More file actions
186 lines (146 loc) · 5.46 KB
/
pgio.sql
File metadata and controls
186 lines (146 loc) · 5.46 KB
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
-- Copyright 1999 Kevin Closson
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
-- http://www.apache.org/licenses/LICENSE-2.0
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
DROP TYPE pgio_return CASCADE;
CREATE TYPE pgio_return AS (
mypid int,
loop_iterations bigint ,
sql_selects bigint,
sql_updates bigint,
sql_select_max_tm numeric,
sql_update_max_tm numeric ,
select_blk_touch_cnt bigint,
update_blk_touch_cnt bigint
);
CREATE OR REPLACE FUNCTION mypgio(
v_mytab varchar,
v_pctupd int,
v_runtime_secs bigint,
v_scale bigint,
v_select_batch_size int,
v_update_batch_size int
) RETURNS pgio_return LANGUAGE plpgsql
AS $$
DECLARE
rec_myvar pgio_return%rowtype;
v_mytab ALIAS for $1;
v_pctupd ALIAS for $2;
v_runtime_secs ALIAS for $3;
v_scale ALIAS for $4;
v_select_batch_size ALIAS for $5;
v_update_batch_size ALIAS for $6;
v_end_time timestamp WITHOUT TIME ZONE;
v_before timestamp WITHOUT TIME ZONE;
v_after timestamp WITHOUT TIME ZONE;
v_tm timestamp WITHOUT TIME ZONE;
v_tm_delta numeric := 0.0;
v_select_max_tm numeric := 0.0;
v_update_max_tm numeric := 0.0;
v_select_batch_tm_total numeric := 0.0;
v_update_batch_tm_total numeric := 0.0;
v_tmp bigint := 0;
v_scratch bigint := 0;
v_optype int := 0;
v_master_loop_cnt bigint := 0;
v_mykey bigint := 0;
v_pid int := 0;
v_op_cnt int := 0;
v_select_cnt int := 0;
v_update_cnt int := 0;
v_select_cnt_total bigint := 0;
v_update_cnt_total bigint := 0;
v_select_blk_touch_cnt bigint := 0;
v_update_blk_touch_cnt bigint := 0;
v_update_quota boolean := FALSE;
v_select_quota boolean := FALSE;
v_select_only boolean := FALSE;
v_update_only boolean := FALSE;
BEGIN
rec_myvar.mypid := 0 ;
rec_myvar.sql_updates := 0 ;
rec_myvar.sql_selects := 0 ;
rec_myvar.loop_iterations := 0 ;
rec_myvar.sql_select_max_tm := 0.0;
rec_myvar.sql_update_max_tm := 0.0;
rec_myvar.select_blk_touch_cnt := 0;
rec_myvar.update_blk_touch_cnt := 0;
SELECT pg_backend_pid() into v_pid;
CASE
WHEN ( v_pctupd = 0 ) THEN v_select_only = TRUE ;
WHEN ( v_pctupd = 100 ) THEN v_update_only = TRUE ;
WHEN ( v_pctupd > 100 ) THEN RAISE EXCEPTION 'FATAL : UPDATE_PCT "%" IS GREATER THAN 100.', v_pctupd ;
WHEN ( v_pctupd < 0 ) THEN RAISE EXCEPTION 'FATAL : UPDATE_PCT "%" IS LESS THAN ZERO.', v_pctupd ;
WHEN v_pctupd BETWEEN 51 AND 99 THEN RAISE EXCEPTION 'FATAL : UPDATE_PCT "%" BETWEEN 51 and 99 ARE NOT SUPPORTED.', v_pctupd ;
ELSE
RAISE NOTICE 'I am PID "%" : My table is "%" : UPDATE_PCT "%" : RUN TIME SECONDS "%"', v_pid, v_mytab, v_pctupd, v_runtime_secs ;
END CASE;
v_end_time := clock_timestamp() + (v_runtime_secs || ' seconds')::interval ;
WHILE ( clock_timestamp()::timestamp < v_end_time ) LOOP
SELECT pgio_get_random_number(1, v_scale - v_select_batch_size) INTO v_mykey;
IF ( v_update_only = TRUE ) THEN
v_optype := 1;
ELSEIF ((v_update_only = FALSE AND v_select_only = FALSE AND (MOD(v_mykey , 2) = 0) AND ( v_update_quota != TRUE )) OR (v_select_quota = TRUE) ) THEN
v_optype := 1;
ELSEIF ( v_select_only = TRUE ) THEN
v_optype := 0;
ELSE
v_optype := 0;
END IF;
v_before := clock_timestamp();
IF ( v_optype = 0 ) THEN
EXECUTE 'SELECT sum(scratch) FROM ' || v_mytab || ' WHERE mykey BETWEEN ' || v_mykey || ' AND ' || v_mykey + v_select_batch_size INTO v_scratch;
v_tm_delta := cast(extract(epoch from (clock_timestamp() - v_before)) as numeric(12,8));
IF ( v_tm_delta > v_select_max_tm ) THEN
v_select_max_tm := v_tm_delta;
END IF;
v_select_cnt := v_select_cnt + 1;
v_select_cnt_total := v_select_cnt_total + 1;
v_select_blk_touch_cnt := v_select_blk_touch_cnt + v_select_batch_size;
v_select_batch_tm_total := v_select_batch_tm_total + v_tm_delta;
IF ( v_select_cnt >= ( 100 - v_pctupd) ) THEN
v_select_quota := TRUE;
END IF;
ELSE
EXECUTE 'UPDATE ' || v_mytab || ' SET scratch = scratch + 1 WHERE mykey BETWEEN ' || v_mykey || ' AND ' || v_mykey + v_update_batch_size;
v_tm_delta := cast(extract(epoch from (clock_timestamp() - v_before)) as numeric(12,8));
IF ( v_tm_delta > v_update_max_tm ) THEN
v_update_max_tm := v_tm_delta;
END IF;
v_update_cnt := v_update_cnt + 1;
v_update_cnt_total := v_update_cnt_total + 1;
v_update_blk_touch_cnt := v_update_blk_touch_cnt + v_update_batch_size;
v_update_batch_tm_total := v_update_batch_tm_total + v_tm_delta;
IF ( v_update_cnt >= v_pctupd ) THEN
v_update_quota := TRUE;
END IF;
END IF;
v_op_cnt := v_op_cnt + 1 ;
v_master_loop_cnt := v_master_loop_cnt + 1 ;
IF ( v_op_cnt >= 100 ) THEN
v_op_cnt := 0;
v_select_cnt := 0;
v_update_cnt := 0;
v_select_batch_tm_total := 0;
v_update_batch_tm_total := 0;
v_update_quota := FALSE;
v_select_quota := FALSE;
END IF;
END LOOP;
rec_myvar.mypid := v_pid;
rec_myvar.loop_iterations := v_master_loop_cnt;
rec_myvar.sql_selects := v_select_cnt_total;
rec_myvar.sql_updates := v_update_cnt_total;
rec_myvar.sql_select_max_tm := v_select_max_tm;
rec_myvar.sql_update_max_tm := v_update_max_tm;
rec_myvar.select_blk_touch_cnt := v_select_blk_touch_cnt;
rec_myvar.update_blk_touch_cnt := v_update_blk_touch_cnt;
RETURN rec_myvar;
END;
$$;