You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When querying pg_locks (or using `pg_lock_status()`), approximately 75% of
backend memory allocations for resulting tuples weren't registered with
Vmtracker or Resource Group Control. This memory would also leak if the query
was cancelled or failed.
This happened because `CdbDispatchCommand()`, which is used by `pg_locks`,
internally uses libpq to obtain the results, which were allocated as PQresult
structures with bare `malloc()`, even on the server side.
This patch fixes both untracked memory issues by enforcing Vmtracker routines
for `PGresult` allocations on the server-side.
Please note that the original error from ADBDEV-7145, which is an
`AbortTransaction()` recurstion due to an OOM error while cancelling a query,
is fixed only in the next commit.
Ticket: ADBDEV-7691
-- m/ERROR: Canceling query because of high VMEM usage.*/
5
+
-- s/ERROR: Canceling query because of high VMEM usage.*/ERROR: Out of memory/
6
+
-- end_matchsubs
7
+
8
+
CREATE RESOURCE GROUP rg_oom_test WITH (cpu_rate_limit=20, memory_limit=20, memory_shared_quota=100);
9
+
CREATE
10
+
CREATE ROLE role_oom_test RESOURCE GROUP rg_oom_test;
11
+
CREATE
12
+
CREATE OR REPLACE FUNCTION gp_mock_cdbdispatchcommand(amount int) RETURNS SETOF text AS '@abs_srcdir@/../regress/regress.so', 'gp_mock_cdbdispatchcommand' LANGUAGE C;
13
+
CREATE
14
+
15
+
1: SET ROLE TO role_oom_test;
16
+
SET
17
+
18
+
-- Freeze coordinator's session after it reads results from segments.
19
+
SELECT gp_inject_fault('check_dispatch_result_end', 'suspend', dbid) FROM gp_segment_configuration WHERE role = 'p' AND content = -1;
20
+
gp_inject_fault
21
+
-----------------
22
+
Success:
23
+
(1 row)
24
+
25
+
-- Send the heavy query.
26
+
1&: SELECT count(*) FROM gp_mock_cdbdispatchcommand(1000000); <waiting ...>
27
+
28
+
-- Wait until we receive everything.
29
+
SELECT gp_wait_until_triggered_fault('check_dispatch_result_end', 1, dbid) FROM gp_segment_configuration WHERE role = 'p' AND content = -1;
30
+
gp_wait_until_triggered_fault
31
+
-------------------------------
32
+
Success:
33
+
(1 row)
34
+
35
+
-- The query should've used ~135 MB of memory. Allow 15 MB error.
36
+
WITH r AS ( SELECT (memory_usage->'-1'->'used')::text::int AS mb FROM gp_toolkit.gp_resgroup_status WHERE rsgname = 'rg_oom_test' ) SELECT r.mb < 150 AS "under 150 MB", r.mb > 120 AS "above 120 MB" FROM r;
37
+
under 150 MB | above 120 MB
38
+
--------------+--------------
39
+
t | t
40
+
(1 row)
41
+
42
+
SELECT gp_inject_fault('check_dispatch_result_end', 'reset', dbid) FROM gp_segment_configuration WHERE role = 'p' AND content = -1;
43
+
gp_inject_fault
44
+
-----------------
45
+
Success:
46
+
(1 row)
47
+
48
+
1<: <... completed>
49
+
count
50
+
---------
51
+
4000000
52
+
(1 row)
53
+
54
+
DROP FUNCTION gp_mock_cdbdispatchcommand(amount int);
0 commit comments