postgresql: из общей памяти? - PullRequest
4 голосов
/ 28 июня 2010

Я запускаю несколько запросов с использованием Python и psycopg2.Я создаю одну большую временную таблицу с примерно 2 миллионами строк, затем извлекаю из нее 1000 строк, используя cur.fetchmany(1000), и выполняю более обширные запросы с этими строками.Обширные запросы самодостаточны, хотя - как только они выполнены, мне больше не нужны их результаты, когда я перехожу к следующей 1000.

Однако, из-за 1000000 строк, я получил исключение изpsycopg2:

psycopg2.OperationalError: out of shared memory
HINT:  You might need to increase max_locks_per_transaction.

Как ни странно, это произошло, когда я выполнял запрос на удаление некоторых временных таблиц, созданных более обширными запросами.

Почему это могло произойти?Есть ли способ избежать этого?Было досадно, что это произошло на полпути, а это значит, что мне нужно все повторить.Что может max_locks_per_transaction иметь отношение к чему-либо?

ПРИМЕЧАНИЕ. Я не делаю никаких .commit() с, но я удаляю все временные таблицы, которые я создаю, и я касаюсь только одного и того жеВ любом случае, 5 таблиц для каждой «расширенной» транзакции, поэтому я не понимаю, как из-за блокировки таблиц может возникнуть проблема ...

Ответы [ 3 ]

3 голосов
/ 10 февраля 2011

при создании таблицы вы получаете на нее эксклюзивную блокировку, которая действует до конца транзакции. Даже если вы потом бросите его.

Итак, если я запустил передачу и создаю временную таблицу:

steve@steve@[local] *=# create temp table foo(foo_id int);
CREATE TABLE
steve@steve@[local] *=# select * from pg_locks where pid = pg_backend_pid();
   locktype    | database | relation  | page | tuple | virtualxid | transactionid | classid |   objid   | objsubid | virtualtransaction |  pid  |        mode         | granted 
---------------+----------+-----------+------+-------+------------+---------------+---------+-----------+----------+--------------------+-------+---------------------+---------
 virtualxid    |          |           |      |       | 2/105315   |               |         |           |          | 2/105315           | 19098 | ExclusiveLock       | t
 transactionid |          |           |      |       |            |        291788 |         |           |          | 2/105315           | 19098 | ExclusiveLock       | t
 relation      |    17631 |     10985 |      |       |            |               |         |           |          | 2/105315           | 19098 | AccessShareLock     | t
 relation      |    17631 | 214780901 |      |       |            |               |         |           |          | 2/105315           | 19098 | AccessExclusiveLock | t
 object        |    17631 |           |      |       |            |               |    2615 | 124616403 |        0 | 2/105315           | 19098 | AccessExclusiveLock | t
 object        |        0 |           |      |       |            |               |    1260 |     16384 |        0 | 2/105315           | 19098 | AccessShareLock     | t
(6 rows)

Эти блокировки отношения не сбрасываются при удалении таблицы:

steve@steve@[local] *=# drop table foo;
DROP TABLE
steve@steve@[local] *=# select * from pg_locks where pid = pg_backend_pid();
   locktype    | database | relation  | page | tuple | virtualxid | transactionid | classid |   objid   | objsubid | virtualtransaction |  pid  |        mode         | granted 
---------------+----------+-----------+------+-------+------------+---------------+---------+-----------+----------+--------------------+-------+---------------------+---------
 virtualxid    |          |           |      |       | 2/105315   |               |         |           |          | 2/105315           | 19098 | ExclusiveLock       | t
 object        |    17631 |           |      |       |            |               |    1247 | 214780902 |        0 | 2/105315           | 19098 | AccessExclusiveLock | t
 transactionid |          |           |      |       |            |        291788 |         |           |          | 2/105315           | 19098 | ExclusiveLock       | t
 relation      |    17631 |     10985 |      |       |            |               |         |           |          | 2/105315           | 19098 | AccessShareLock     | t
 relation      |    17631 | 214780901 |      |       |            |               |         |           |          | 2/105315           | 19098 | AccessExclusiveLock | t
 object        |    17631 |           |      |       |            |               |    2615 | 124616403 |        0 | 2/105315           | 19098 | AccessExclusiveLock | t
 object        |    17631 |           |      |       |            |               |    1247 | 214780903 |        0 | 2/105315           | 19098 | AccessExclusiveLock | t
 object        |        0 |           |      |       |            |               |    1260 |     16384 |        0 | 2/105315           | 19098 | AccessShareLock     | t
(8 rows)

На самом деле, он добавил еще две блокировки ... Кажется, если я постоянно создаю / удаляю эту временную таблицу, он добавляет 3 блокировки каждый раз.

Так что, я думаю, один из ответов заключается в том, что вам потребуется достаточно блокировок, чтобы справиться со всеми этими таблицами, добавляемыми / удаляемыми в течение транзакции. В качестве альтернативы, вы можете попытаться повторно использовать временные таблицы между запросами, просто обрезать их, чтобы удалить все временные данные?

3 голосов
/ 07 сентября 2012

Вы создали несколько точек сохранения с одним и тем же именем, не отпуская их?

Я следовал этим инструкциям , многократно выполняя SAVEPOINT savepoint_name, но без выполнения каких-либо соответствующих RELEASE SAVEPOINT savepoint_name инструкций.PostgreSQL просто маскировал старые точки сохранения, никогда не освобождая их.Он отслеживал каждый из них, пока не исчерпал память для блокировок.Я думаю, что мои ограничения памяти postgresql были намного ниже, мне потребовалось всего ~ 10000 точек сохранения, чтобы набрать max_locks_per_transaction .

1 голос
/ 28 июня 2010

Хорошо, вы выполняете все запросы create + внутри одной транзакции?Возможно, это объяснит проблему.То, что это произошло, когда вы отбрасывали таблицы, не обязательно будет означать что-то, может случиться так, что это будет тот момент, когда у него закончатся свободные блокировки.

Использование представления может быть альтернативой временной таблице и будетопределенно моим первым выбором, если вы создаете эту вещь, а затем сразу же удаляете ее.

...