linux – 为什么PostgreSQL在长时间运行INSERT时没有保存到磁盘… SELECT …?

linux – 为什么PostgreSQL在长时间运行INSERT时没有保存到磁盘… SELECT …?,第1张

概述我正在使用外部数据包装器将大量数据(在一列上进行非常简单的日期转换)移动到本地数据库.使用Django游标(因为我懒得拔出凭据来创建原始的psycopg2游标)我做了这种查询(匿名并删除了几个连接,但与原始连接相同): cursor.executemany( sql.SQL( """ INSERT INTO local_table ( 我正在使用外部数据包装器将大量数据(在一列上进行非常简单的日期转换)移动到本地数据库.使用Django游标(因为我懒得拔出凭据来创建原始的psycopg2游标)我做了这种查询(匿名并删除了几个连接,但与原始连接相同):

cursor.executemany(    sql.sql(        """        INSERT INTO local_table (            foreign_key_ID,other_foreign_key_ID,datetime,comment        )        SELECT other_local_table.ID,%s,(object_date + to_timestamp(object_time,'HH24:MI')::time) at time zone '…',comment          FROM imported_schema.remote_table          JOIN other_local_table ON other_local_table.code = remote_table.code        """    ),[(dummy_ID,)],)

但是,一段时间后,本地Postgres服务器总是会被OOM杀死.我期待Postgres将新行刷新到磁盘以避免内存不足,但据我所知,这只是没有发生 – / var / lib / docker / volumes / vagrant_postgres_data只增加几MB而驻留内存使用成长为GB.本地服务器没有足够的RAM来将整个结果集保存在内存中,因此我需要一个不涉及更昂贵的硬件设置的解决方案.

我是否需要设置类似wal_sync_method或work_mem的东西才能生效?

根据文档,executemany应该是工作的正确工具:

The function is mostly useful for commands that update the database: any result set returned by the query is discarded.

在linux上在两台服务器上运行Postgres 10.6 containers,在本地运行Django 2.1.我没有使用FDW以外的任何扩展.

解释计划:

Insert on local_table  (cost=817872.44..818779.47 rows=25915 wIDth=56)  ->  Subquery Scan on "*SELECT*"  (cost=817872.44..818779.47 rows=25915 wIDth=56)        ->  HashAggregate  (cost=817872.44..818390.74 rows=25915 wIDth=48)              Group Key: other_local_table.ID,1,timezone('…'::text,(remote_table.object_date + (to_timestamp((remote_table.object_time)::text,'HH24:MI'::text))::time without time zone)),remote_table.comment              ->  nested Loop  (cost=101.15..807974.88 rows=989756 wIDth=48)                    ->  nested Loop  (cost=0.57..60.30 rows=73 wIDth=12)                          ->  nested Loop  (cost=0.29..42.35 rows=38 wIDth=4)                                ->  Seq Scan on fourth_local_table  (cost=0.00..7.45 rows=1 wIDth=4)                                      Filter: ((code)::text = '…'::text)                                ->  Index Scan using … on third_local_table  (cost=0.29..34.49 rows=41 wIDth=8)                                      Index Cond: (ID = fourth_local_table.ID)                          ->  Index Scan using … on other_local_table  (cost=0.29..0.45 rows=2 wIDth=16)                                Index Cond: (ID = third_local_table.ID)                    ->  Foreign Scan on remote_table  (cost=100.58..9421.44 rows=151030 wIDth=20)

postgresqltuner建议我

set vm.overcommit_memory=2 in /etc/sysctl.conf … This will disable memory overcommitment and avoID postgresql killed by OOM killer.

这是解决方案吗?

解决方法 除了可能消耗任何内存量的HashAggregate之外,我在执行计划中没有看到任何内容,这应该受到work_mem的限制.

要诊断这一点,您应该首先配置系统,以便获得常规的OOM错误,而不是调用OOM杀手.这意味着使用sysctl设置vm.overcommit_memory = 2并将vm_overcommit_ratio调整为100 *(RAM – swap)/ RAM.

当服务器收到OOM错误时,它会将当前内存上下文及其大小转储到Postgresql日志中.这应该指示内存的去向.如有疑问,请将其添加到问题中.

您使用的是第三方扩展吗?

总结

以上是内存溢出为你收集整理的linux – 为什么PostgreSQL在长时间运行INSERT时没有保存到磁盘… SELECT …?全部内容,希望文章能够帮你解决linux – 为什么PostgreSQL在长时间运行INSERT时没有保存到磁盘… SELECT …?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/1017382.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-23
下一篇 2022-05-23

发表评论

登录后才能评论

评论列表(0条)

保存