y_agg(name),
array_agg(value)) FROM old_prefs WHERE user_id>=160 AND user_id<240
GROUP BY user_id;
INSERT 0 55447
pg=> commit;
COMMIT
USER PID %CPU %MEMVSZ RSS TTY STAT START TIME COMMAND
postgres 19121 0.9 11.5 3277412 945560 ? Ss 15:23 0:15 postgres: pg
pg 10.0.2.71(51734) idle
Another batch:
pg=> select count(*) from old_prefs where user_id>=240 and user_id<340;
count
200614
(1 row)
Time: 83,409 ms
pg=> INSERT INTO new_preferences SELECT user_id,hstore(array_agg(name),
array_agg(value)) FROM old_prefs WHERE user_id>=240 AND user_id<340
GROUP BY user_id;
INSERT 0 87940
pg=> commit;
COMMIT
USER PID %CPU %MEMVSZ RSS TTY STAT START TIME COMMAND
postgres 19121 1.2 16.2 3736968 1331796 ? Ss 15:23 0:20 postgres: pg
pg 10.0.2.71(51734) idle
Another batch:
pg => select count(*) from old_prefs where user_id>=340 and user_id<380;
count
161390
(1 row)
pg=> INSERT INTO new_preferences SELECT user_id,hstore(array_agg(name),
array_agg(value)) FROM old_prefs WHERE user_id>=340 AND user_id<380
GROUP BY user_id;
ERROR: insert or update on table "new_preferences" violates foreign key
constraint "new_preferences_user_id_fkey"
DETAIL: Key (user_id)=(3615131) is not present in table "users".
pg=> rollback;
ROLLBACK
Ops.. have to cleanup the old_prefs, some users were deleted in the meantime:
pg=> delete from old_prefs where user_id not in (select user_id from users);
DELETE 7
pg=> commit;
COMMIT
USER PID %CPU %MEMVSZ RSS TTY STAT START TIME COMMAND
postgres 19121 1.4 26.4 4469520 2157588 ? Ss 15:23 0:29 postgres: pg
pg 10.0.2.71(51734) idle
Near 1G grow on rolled back transaction
pg=> INSERT INTO new_preferences SELECT user_id,hstore(array_agg(name),
array_agg(value)) FROM old_prefs WHERE user_id>=340 AND user_id<380
GROUP BY user_id;
INSERT 0 131803
pg=> commit;
COMMIT
USER PID %CPU %MEMVSZ RSS TTY STAT START TIME COMMAND
postgres 19121 1.7 26.6 4479944 2180536 ? Ss 15:23 0:35 postgres: pg
pg 10.0.2.71(51734) idle
Another batch, bigger this time:
pg=> select count(*) from old_prefs where user_id>=380 and user_id<420;
count
327374
(1 row)
pg=> INSERT INTO new_preferences SELECT user_id,hstore(array_agg(name),
array_agg(value)) FROM old_prefs WHERE user_id>=380 AND user_id<420
GROUP BY user_id;
INSERT 0 177044
pg=> commit;
COMMIT
USER PID %CPU %MEMVSZ RSS TTY STAT START TIME COMMAND
postgres 19121 1.9 33.1 5238968 2710756 ? Ss 15:23 0:45 postgres: pg
pg 10.0.2.71(51734) idle
Another big batch:
pg=> select count(*) from old_prefs where user_id>=420 and user_id<440;
count
375352
(1 row)
pg=> INSERT INTO new_preferences SELECT user_id,hstore(array_agg(name),
array_agg(value)) FROM old_prefs WHERE user_id>=420 AND user_id<440
GROUP BY user_id;
INSERT 0 189095
pg=> commit;
COMMIT
USER PID %CPU %MEMVSZ RSS TTY STAT START TIME COMMAND
postgres 19121 2.2 35.7 5438412 2918720 ? Ss 15:23 0:55 postgres: pg
pg 10.0.2.71(51734) idle
Now a smaller batch:
pg=> select count(*) from old_prefs where user_id>=440 and user_id<450;
count
219249
(1 row)
pg=> INSERT INTO new_preferences SELECT user_id,hstore(array_agg(name),
array_agg(value)) FROM old_prefs WHERE user_id>=440 AND user_id<450
GROUP BY user_id;
INSERT 0 99782
pg=> commit;
COMMIT
RSS keeps growing:
USER PID %CPU %MEMVSZ RSS TTY STAT START TIME COMMAND
postgres 19121 2.2 36.0 5438412 2943784 ? Ss 15:23 1:00 postgres: pg
pg 10.0.2.71(51734) idle
Lets see if a bigger batch will pass:
pg=> select count(*) from old_prefs where user_id>=450;
count
631911
(1 row)
pg=> INSERT INTO new_preferences SELECT user_id,hstore(array_agg(name),
array_agg(value)) FROM old_prefs WHERE user_id>=450 GROUP BY user_id;
INSERT 0 296541
pg=> commit;
COMMIT
Ok, this time it passed, but the backend is over 4G
USER PID %CPU %MEMVSZ RSS TTY STAT START TIME COMMAND
postgres 19121 2.2 50.0 7227968 4088928 ? Ss 15:23 1:17 postgres: pg
pg 10.0.2.71(51734) idle
Some observations:
1. Backend does not free allocated memory between transactions.
2. Rolled back transactions also leak memory.
3. Leaked memory is not linear to work done - 2 transactions with 200k keys
will leak less than 1 transaction with 400k keys
Regarding Tom's question:
The old_prefs does not fit in work_mem but is quite small regarding the total
RAM. Isn't the "work_mem" a limit of the memory each backend could allocate for
sorting, grouping and aggregation? My understanding is that bigger allocation
will overflow to disk and will not kill the server. I could be wrong though.
Thanks in advance and best regards
--
Luben Karavelov
--
Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs