python - postgresql:共享内存不足?

标签 python database postgresql psycopg2

我正在使用 Python 和 psycopg2 运行大量查询。我创建了一个包含大约 200 万行的大型临时表,然后使用 cur.fetchmany(1000) 一次从中获取 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 个表“extensive”事务,所以我看不出表锁用完是怎么回事...

最佳答案

当您创建一个表时,您会在它上面获得一个排它锁,该锁一直持续到事务结束。即使您随后继续并放弃它。

因此,如果我启动一个交易并创建一个临时表:

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 个锁。

所以我猜一个答案是您将需要足够的锁来处理在整个事务中添加/删除的所有这些表。或者,您可以尝试在查询之间重用临时表,简单地截断它们以删除所有临时数据?

关于python - postgresql:共享内存不足?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3132533/

相关文章:

php - MySql数据库设计——哪种表结构更好?

java - Hibernate:如果字段存在某个值,则无法更新为新值

python - 在 Python Tkinter 窗口中显示 Google Map API

python - random.randint 非整数? [Python]

database - 如何在 Informix 中创建影子表

sql - SUM 3 个不同的 "CASE"列,具有三个不同的总数

带有 Postgresql 适配器的 Ruby activerecord 无法选择 OID

python - 函数是 python 中的一流对象吗?

python - 导出 sklearn 模型以在 R 中运行

mysql - 从三个字段中识别一个字段,其中字段的值等于 `MySQL`中的特定数字