Thread: BUG #8279: Apparent memory leak with use of INTO STRICT in plpgsql?

BUG #8279: Apparent memory leak with use of INTO STRICT in plpgsql?

From
chad.wagner@gmail.com
Date:
The following bug has been logged on the website:

Bug reference:      8279
Logged by:          Chad
Email address:      chad.wagner@gmail.com
PostgreSQL version: 9.2.4
Operating system:   Ubuntu 10.04
Description:

If I use the "SELECT ... INTO STRICT" clause with plpgsql it appears to leak
memory, until I disconnect my session and the backend dies.  If I remove the
"INTO STRICT" clause then there is no apparent memory leak.


Below is a test case to reproduce on 9.2.4, and the pmap diff of
before/after on the backend process.


Pmap on backend process (diff of before/after), about a 400MB leak:
--- x1.out    2013-07-03 21:50:02.472438435 -0400
+++ x2.out    2013-07-03 21:51:02.462435759 -0400
@@ -1,5 +1,9 @@
 11945:   postgres: wagnerch wagnerch [local] idle

 Address           Kbytes     RSS    Anon  Locked Mode   Mapping
+00007f4aae074000     148       -       -       - r-x--  plpgsql.so
+00007f4aae099000    2048       -       -       - -----  plpgsql.so
+00007f4aae299000       8       -       -       - r----  plpgsql.so
+00007f4aae29b000       4       -       -       - rw---  plpgsql.so
 00007f4aae29c000     252       -       -       - r----  LC_CTYPE
 00007f4aae2db000  560320       -       -       - rw-s-    [ shmid=0xa9c8000
]
 00007f4ad060b000      48       -       -       - r-x--
libnss_files-2.11.1.so
@@ -129,9 +133,9 @@
 00007f4ad4c36000     116       -       -       - r----  postgres
 00007f4ad4c53000      52       -       -       - rw---  postgres
 00007f4ad4c60000     364       -       -       - rw---    [ anon ]
-00007f4ad5f8b000    1192       -       -       - rw---    [ anon ]
+00007f4ad5f8b000  415820       -       -       - rw---    [ anon ]
 00007ffff3396000     144       -       -       - rw---    [ stack ]
 00007ffff33c6000       4       -       -       - r-x--    [ anon ]
 ffffffffff600000       4       -       -       - r-x--    [ anon ]
 ----------------  ------  ------  ------  ------
-total kB          632108       -       -       -
+total kB         1048944       -       -       -






Test case:


/*


CREATE TABLE head_tb AS
SELECT generate_series (1, 30) AS id;


CREATE TABLE det_tb AS
SELECT a.a header_id, b.b detail_id, rpad ('X', 1000, 'X') AS data
  FROM generate_series (1,30) AS a, generate_series (1, 50000) AS b;


CREATE INDEX det_tb_n1 ON det_tb (header_id);
CREATE UNIQUE INDEX det_tb_u1 ON det_tb (header_id, detail_id);


*/


DO LANGUAGE plpgsql
$$
DECLARE
   l_head_rec RECORD;
   l_det_rec RECORD;
   l_next_det_rec RECORD;
BEGIN
   FOR l_head_rec IN
      SELECT id,
             LEAD (id) OVER (
                ORDER BY id
                RANGE BETWEEN UNBOUNDED PRECEDING
                          AND UNBOUNDED FOLLOWING
             ) next_id
        FROM head_tb
      ORDER BY id
   LOOP
      FOR l_det_rec IN
         SELECT *
           FROM det_tb
          WHERE header_id = l_head_rec.id
      LOOP
         BEGIN
            SELECT *
              INTO STRICT l_next_det_rec
              FROM det_tb
             WHERE detail_id = l_det_rec.detail_id
               AND header_id = l_head_rec.next_id;


         EXCEPTION
            WHEN NO_DATA_FOUND
            THEN
               NULL;
         END;
      END LOOP;
   END LOOP;
END;
$$;