2

我编写了一个脚本来使用 Django ORM 将一些对象加载到 Django 数据库中。底层数据库是 Postgres。

在愉快地运行了一段时间后,脚本失败并出现以下错误:

django.db.utils.DatabaseError: out of shared memory
HINT: You might need to increase max_locks_per_transaction.

我猜这是我的脚本效率的问题,而不是数据库设置的问题。

该脚本遍历 CSV 文件,并为 CSV 文件中的每一行创建一个数据库对象。通常有几千个对象要创建。我已经阅读了一些关于 Django 中数据库效率的背景资料。我可以排除一些错误——我不是迭代查询集,也不是使用__in查询或OFFSET.

但是我的数据库中的字段确实有很多索引,而且我猜每次创建和保存对象时,Django 都必须更新所有索引。StoreItem例如,我在字段上有六个索引。

for item in csv_rows: 
  s, created = StoreItem.objects.get_or_create(display_url=item['display_url'], \
         retailer_img_url=item['retailer_img_url'],store=store_obj)
  s.name = item['name']
  s.description = item['description']
  s.affiliate = item['affiliate']
  ... more stuff
  s.save()

两个问题:

  1. 更新数据库索引是否可能导致此错误?
  2. 如果是这种情况,我该如何调试?
4

1 回答 1

3

我有一个快速的谷歌,有几个资源可以看:

  1. postgresql:共享内存不足?
  2. http://www.databasesoup.com/2012/06/postgresqlconf-maxlockspertransaction.html

此报价取自http://www.postgresql.org/docs/9.1/static/runtime-config-locks.html

max_locks_per_transaction(整数)

共享锁表跟踪 max_locks_per_transaction * (max_connections + max_prepared_transactions) 对象(例如,表)上的锁;因此,任何时候都不能锁定这么多不同的对象。该参数控制为每个事务分配的对象锁的平均数量;只要所有事务的锁都适合锁表,单个事务就可以锁定更多对象。这不是可以锁定的行数;该值是无限的。默认值 64 已在历史上证明是足够的,但如果您的客户端在单个事务中涉及许多不同的表,则可能需要提高此值。此参数只能在服务器启动时设置。

增加此参数可能会导致 PostgreSQL 请求的 System V 共享内存超出操作系统默认配置所允许的数量。如有必要,请参阅第 17.4.1 节了解有关如何调整这些参数的信息。

运行备用服务器时,您必须将此参数设置为与主服务器上相同或更高的值。否则,备用服务器中将不允许查询。

因此,看起来您应该检查 max_locks_per_transaction 的默认值以检查其设置为合理值

同样,如果您使用的是 postgres 的默认安装,那么您可能应该检查所有其他默认值,因为在某些情况下默认值可能设置得太低。

于 2013-07-15T12:27:51.083 回答