Out of memory - Mailing list pgsql-novice

From Tom Wilcox
Subject Out of memory
Date
Msg-id 2C6372A5-92DB-43C5-8273-E8D4F60B4E3C@gmail.com
Whole thread Raw
Responses Re: Out of memory
List pgsql-novice
Hi,

I am new to Postgres and I do not know much about databases in general.

I have been trying to execute a plpgsql function that creates several tables, joins and unions them before applying a
fewfunctions (which also create and join tables) before inserting a few rows into a permanent table and exiting. This
functionis called for every row of a table which is not small (>50000 rows). 

I am getting this error consistently after running for around 400s:

ERROR: out of shared memory
SQL state: 53200
Hint: You might need to increase max_locks_per_transaction.
Context: SQL statement "CREATE TABLE tmp_cands AS SELECT d.premise_id AS uid, d.* FROM tmp_cands_1 AS c INNER JOIN
nlpg.match_dataAS d ON c.pid = d.premise_id" 
PL/pgSQL function "get_match" line 61 at SQL statement

I have increased the max_locks_per_transaction to 10000 to no avail.

Please can anyone tell me how I can find out more about this error and/or what I might do to solve it. I was thinking
thatit might be related to the creation of tables that may not be getting dropped until the query exited. In which case
Iwas thinking of trying to use EXECUTE ''DROP/CREATE/ ....'' at the cost of no query planning benefits, but this is
mostlya guess.. 

Any help/suggestions much appreciated. I have pasted the offending portions of the code below for luck.

Cheers,
Tom

------------------------------

-- Inserts matches for input address into match table and returns number of matches found
DROP  FUNCTION IF EXISTS nlpg.get_match(ipt struct_address) ;
CREATE OR REPLACE FUNCTION nlpg.get_match(ipt struct_address) RETURNS INTEGER AS '
DECLARE
    ipt ALIAS FOR $1;
    num_matches integer;
    rc integer;
BEGIN
    -- Get candidate sets
    DROP TABLE IF EXISTS tmp_cands_n;
    CREATE TABLE tmp_cands_n AS SELECT nlpg.get_namenum_cands(($1).name) AS pid;
    DROP TABLE IF EXISTS tmp_cands_s;
    CREATE TABLE tmp_cands_s AS SELECT nlpg.get_street_100_cands(($1).street) AS pid;
    DROP TABLE IF EXISTS tmp_cands_p;
    CREATE TABLE tmp_cands_p AS SELECT nlpg.get_pc_cands(($1).pc) AS pid;

    -- Get full intersection...
    DROP TABLE IF EXISTS tmp_cands_pn;
    DROP TABLE IF EXISTS tmp_cands_1;
    CREATE TABLE tmp_cands_pn AS SELECT DISTINCT n.*
        FROM tmp_cands_n AS n INNER JOIN tmp_cands_p AS p ON p.pid = n.pid;
    CREATE TABLE tmp_cands_1 AS SELECT DISTINCT c.*
        FROM tmp_cands_pn AS c INNER JOIN tmp_cands_s AS s ON c.pid = s.pid;

    -- TODO: Other intersections, use more complex lookup tables, etc.
    GET DIAGNOSTICS rc = ROW_COUNT;
    --RAISE NOTICE ''1st level intersection - rc = %'',rc;

        IF rc = 0 THEN
        DROP TABLE IF EXISTS tmp_cands_ps;
        CREATE TABLE tmp_cands_ps AS
            SELECT s.* FROM tmp_cands_s AS s INNER JOIN tmp_cands_p AS p ON s.pid = p.pid;
        DROP TABLE IF EXISTS tmp_cands_ns;
        CREATE TABLE tmp_cands_ns AS
            SELECT n.* FROM tmp_cands_n AS n INNER JOIN tmp_cands_s AS s ON n.pid = s.pid;
        DROP TABLE IF EXISTS tmp_cands_1;
        CREATE TABLE tmp_cands_1 AS
            SELECT * FROM tmp_cands_pn
            UNION
            SELECT * FROM tmp_cands_ps
            UNION
            SELECT * FROM tmp_cands_ns;

        -- 2nd Level Intersection of candidates

        GET DIAGNOSTICS rc = ROW_COUNT;
        --RAISE NOTICE ''2nd level intersection - rc = %'',rc;
    END IF;

        IF rc = 0 THEN
        -- 3rd Level Intersection of candidates
        DROP TABLE IF EXISTS tmp_cands_1;
        CREATE TABLE tmp_cands_1 AS
            SELECT * FROM tmp_cands_n
            UNION
            SELECT * FROM tmp_cands_s
            UNION
            SELECT * FROM tmp_cands_p;
        --RAISE NOTICE ''3rd level intersection - rc = %'',rc;
    END IF;

    -- Expand candidates to include match data for distance metric evaluation
    DROP TABLE IF EXISTS tmp_cands;
    CREATE TABLE tmp_cands AS SELECT d.premise_id AS uid, d.*
        FROM tmp_cands_1 AS c INNER JOIN nlpg.match_data AS d ON c.pid = d.premise_id;

    -- Evaluate distances
    DROP TABLE IF EXISTS ranked_cands;
    CREATE TABLE ranked_cands AS
        SELECT
            dist(ipt,(c.uid, c.name, c.street, c.town, c.pc)::struct_address) AS dist,
            pc_dist(ipt.pc,c.pc) AS pc_dist,
            town_dist(ipt.town,c.town) AS town_dist,
            street_dist(ipt.street,c.street) AS street_dist,
            name_dist(ipt.name,c.name) AS name_dist,
            num_dist(ipt.name,c.name) AS num_dist,
            *
    FROM tmp_cands AS c ORDER BY dist ASC;

    -- Select best cands
    IF NOT tableExists(''matches'',''nlpg_matches'') THEN
        CREATE TABLE matches.nlpg_matches AS SELECT ipt AS input, r.* FROM ranked_cands AS r WHERE r.dist = (SELECT
min(dist)FROM ranked_cands); 
    ELSE
        INSERT INTO matches.nlpg_matches SELECT ipt AS input, r.* FROM ranked_cands AS r WHERE r.dist = (SELECT
min(dist)FROM ranked_cands); 
    END IF;

    GET DIAGNOSTICS num_matches = ROW_COUNT;
    RETURN num_matches;
END;
' LANGUAGE 'plpgsql';

-- Get test input
DROP TABLE IF EXISTS tmp_pft_input;
CREATE TABLE tmp_pft_input AS
    SELECT (i.uid,i.name,i.street,i.town,i.pc)::struct_address AS inp  FROM
    attr.non_resi_all_match_data AS i
    ORDER BY RANDOM()
    LIMIT 10000;

SELECT nlpg.get_match(j.inp), j.inp AS input FROM tmp_pft_input AS j;

-- 12,781ms for 10 input
-- 127,937ms for 100 input
-- 431, 193ms for 10000 input but it to fail due to
--     ERROR: out of shared memory
--     SQL state: 53200
--     Hint: You might need to increase max_locks_per_transaction.
--     Context: SQL statement "CREATE TABLE tmp_cands AS SELECT d.premise_id AS uid, d.* FROM tmp_cands_1 AS c INNER
JOINnlpg.match_data AS d ON c.pid = d.premise_id" 
--     PL/pgSQL function "get_match" line 61 at SQL statement


pgsql-novice by date:

Previous
From: Mladen Gogala
Date:
Subject: Re: Encoding issue with pgAdmin
Next
From: Hernan Danielan
Date:
Subject: LargeObject