首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Postgresql大事务OOM杀手

Postgresql大事务OOM杀手
EN

Database Administration用户
提问于 2018-05-11 06:52:29
回答 2查看 4.2K关注 0票数 3

我们有一个运行在Postgresql 9.5上的CentOS release 6.5 (Final)服务器有16 of的内存。我们正在运行一个长事务,它在多个表中添加和更新数百万行中的10s行。除了这个事务,在这个阶段没有查询在DB上运行,但是它可以在其他查询期间运行,所以必须进行事务处理。

它可以正常工作,直到OOM杀手决定它已经足够并杀死postmaster进程为止:

代码语言:javascript
复制
Out of memory: Kill process 1766 (postmaster) score 890 or sacrifice child
Killed process 1766, UID 26, (postmaster) total-vm:24384508kB, anon-rss:14376288kB, file-rss:138616kB

以下是相关的postgres配置:

代码语言:javascript
复制
#-------------------------------------------------------------------------
# RESOURCE USAGE (except WAL)
#-------------------------------------------------------------------------

# - Memory -

shared_buffers = 128MB                  # min 128kB
                                        # (change requires restart)
#huge_pages = try                       # on, off, or try
                                        # (change requires restart)
#temp_buffers = 8MB                     # min 800kB
#max_prepared_transactions = 0          # zero disables the feature
                                        # (change requires restart)
# Caution: it is not advisable to set max_prepared_transactions nonzero unless
# you actively intend to use prepared transactions.
#work_mem = 4MB                         # min 64kB
#maintenance_work_mem = 64MB            # min 1MB
#autovacuum_work_mem = -1               # min 1MB, or -1 to use maintenance_work_mem
#max_stack_depth = 2MB                  # min 100kB
dynamic_shared_memory_type = posix      # the default is the first option
                                        # supported by the operating system:
                                        #   posix
                                        #   sysv
                                        #   windows
                                        #   mmap
                                        # use none to disable dynamic shared memory

# - Disk -

#temp_file_limit = -1                   # limits per-session temp file space
                                        # in kB, or -1 for no limit

# - Kernel Resource Usage -

#max_files_per_process = 1000           # min 25
                                        # (change requires restart)
#shared_preload_libraries = ''          # (change requires restart)

# - Cost-Based Vacuum Delay -

#vacuum_cost_delay = 0                  # 0-100 milliseconds
#vacuum_cost_page_hit = 1               # 0-10000 credits
#vacuum_cost_page_miss = 10             # 0-10000 credits
#vacuum_cost_page_dirty = 20            # 0-10000 credits
#vacuum_cost_limit = 200                # 1-10000 credits

# - Background Writer -

#bgwriter_delay = 200ms                 # 10-10000ms between rounds
#bgwriter_lru_maxpages = 100            # 0-1000 max buffers written/round
#bgwriter_lru_multiplier = 2.0          # 0-10.0 multipler on buffers scanned/round

# - Asynchronous Behavior -

#effective_io_concurrency = 1           # 1-1000; 0 disables prefetching
#max_worker_processes = 8

另外,vm.overcommit_memory被设置为2

我发现的一个解决方案是禁用OOM杀手的特定过程,我试图避免,因为它让我觉得不是正确的解决方案。我没有找到任何方法来强迫postgres将内存刷新到磁盘,或者限制使用的内存总量。

有什么建议吗?

EN

回答 2

Database Administration用户

回答已采纳

发布于 2018-05-13 06:24:59

好的,在尝试了很多事情之后,我找到了解决办法。

这个问题隐藏在我们对JDBC库的使用中。

我们与设置为false的自动提交有很长的连接:

代码语言:javascript
复制
connection.setAutoCommit(false)

在此期间,我们使用游标执行了许多小查询和几个查询:

代码语言:javascript
复制
statement.setFetchSize(SOME_FETCH_SIZE)

在JDBC中,您可以创建一个connection对象,并通过这个连接创建statements。当您执行状态时,您将得到一个result set

现在,这些对象中的每一个都需要关闭,但是如果关闭语句,则条目集将关闭,如果关闭连接,则关闭所有语句及其结果集。

我们习惯于用自己的连接来缩短活的查询,因此我们从不关闭语句,假设连接一旦关闭就会处理这些事情。

现在的问题是,这个长事务(大约24小时)从未关闭连接。这些陈述从未结束。显然,语句对象包含运行代码的服务器和PostgreSQL数据库上的资源。

对于DB中剩下的资源,我最好的猜测是与游标相关的内容。使用游标的语句从未关闭,因此它们返回的结果集也从未关闭。这意味着数据库没有释放DB中的相关游标资源,而且由于它位于一个巨大的表上,因此占用了大量的RAM。

我唯一不明白的是,当PostgreSQL未能分配内存时,它为什么没有保存磁盘上的一些资源(而不是交换)。

希望它能帮助将来有类似问题的人。

票数 2
EN

Database Administration用户

发布于 2018-05-11 07:19:56

确保您有足够的交换空间空闲,并禁用OOM杀手。它是为一个用例设计的,而不是你正在做的事情。除非有什么地方可以交换,否则Linux不能安全地过度提交。还要检查内核参数vm.swappiness,它设置为什么?

票数 0
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/206448

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档