尽管有足够的可用内存,但 Postgres 仍然出现内存不足错误
Postgres gets out of memory errors despite having plenty of free memory
我有一个服务器 运行ning Postgres 9.1.15。服务器有 2GB RAM,没有交换空间。间歇性地,Postgres 将开始在某些 SELECT 上出现 "out of memory" 错误,并且会继续这样做,直到我重新启动 Postgres 或 一些连接到它的客户端。奇怪的是,发生这种情况时,free
仍然报告超过 500MB 的可用内存。
select version();
:
PostgreSQL 9.1.15 on x86_64-unknown-linux-gnu, compiled by gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3, 64-bit
uname -a
:
Linux db 3.2.0-23-virtual #36-Ubuntu SMP Tue Apr 10 22:29:03 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
Postgresql.conf(其他都注释掉out/default):
max_connections = 100
shared_buffers = 500MB
work_mem = 2000kB
maintenance_work_mem = 128MB
wal_buffers = 16MB
checkpoint_segments = 32
checkpoint_completion_target = 0.9
random_page_cost = 2.0
effective_cache_size = 1000MB
default_statistics_target = 100
log_temp_files = 0
我从pgtune(我选择了"mixed type of applications")那里得到了这些值,并根据我所读的内容一直在摆弄它们,但没有取得太大的实际进展。目前有 68 个连接,这是一个典型的数字(我还没有使用 pgbouncer 或任何其他连接池)。
/etc/sysctl.conf
:
kernel.shmmax=1050451968
kernel.shmall=256458
vm.overcommit_ratio=100
vm.overcommit_memory=2
大约两周前,在 OOM 杀手杀死了 Postgres 服务器后,我第一次将 overcommit_memory
更改为 2。在此之前,服务器已经 运行 正常运行了很长时间。我现在得到的错误没有那么严重,但更烦人,因为它们更频繁。
我没有多少运气来确定导致 postgres 运行 "out of memory" 的第一个事件 - 似乎每次都不一样。最近一次崩溃时,记录的前三行是:
2015-04-07 05:32:39 UTC ERROR: out of memory
2015-04-07 05:32:39 UTC DETAIL: Failed on request of size 125.
2015-04-07 05:32:39 UTC CONTEXT: automatic analyze of table "xxx.public.delayed_jobs"
TopMemoryContext: 68688 total in 10 blocks; 4560 free (4 chunks); 64128 used
[... snipped heaps of lines which I can provide if they are useful ...]
---
2015-04-07 05:33:58 UTC ERROR: out of memory
2015-04-07 05:33:58 UTC DETAIL: Failed on request of size 16.
2015-04-07 05:33:58 UTC STATEMENT: SELECT oid, typname, typelem, typdelim, typinput FROM pg_type
2015-04-07 05:33:59 UTC LOG: could not fork new process for connection: Cannot allocate memory
2015-04-07 05:33:59 UTC LOG: could not fork new process for connection: Cannot allocate memory
2015-04-07 05:33:59 UTC LOG: could not fork new process for connection: Cannot allocate memory
TopMemoryContext: 396368 total in 50 blocks; 10160 free (28 chunks); 386208 used
[... snipped heaps of lines which I can provide if they are useful ...]
---
2015-04-07 05:33:59 UTC ERROR: out of memory
2015-04-07 05:33:59 UTC DETAIL: Failed on request of size 1840.
2015-04-07 05:33:59 UTC STATEMENT: SELECT... [nested select with 4 joins, 19 ands, and 2 order bys]
TopMemoryContext: 388176 total in 49 blocks; 17264 free (55 chunks); 370912 used
在那之前的崩溃,几个小时前,只有最后一个查询的三个实例作为崩溃的前三行。该查询经常 运行 非常 ,所以我不确定问题是 因为 这个查询,还是只是出现在错误日志中,因为它相当复杂 SELECT 一直 运行。也就是说,这里有一个解释分析:http://explain.depesz.com/s/r00
这就是 postgres 用户 ulimit -a
的样子:
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 15956
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 15956
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
下次发生崩溃时,我会尝试从 free
中获取确切的数字,与此同时,这是我所有信息的脑力转储。
关于从这里到哪里去的任何想法?
我只是 运行 遇到了同样的问题,我试图恢复一个 ~2.5 GB 的纯文本 SQL 文件。我将我的 Digital Ocean 服务器扩展到 64 GB RAM,创建了一个 10 GB 的交换文件,然后再次尝试。我遇到了 50 GB 可用内存不足的错误,并且没有使用交换空间。
我将我的服务器缩减到我正在使用的 1 GB 小型实例(需要重新启动)并且我想我会再试一次,除了我感到沮丧之外没有其他原因。我开始导入并意识到我忘记再次创建我的临时交换文件。
我在导入过程中创建了它。 psql 在崩溃之前使它更进一步 lot。它通过了另外 5 个表格。
我认为 psql 中一定存在分配内存的错误。
能不能在出现错误时检查一下是否有可用的交换内存?
我已经完全删除了 Linux 桌面中的交换内存(只是为了测试其他东西...),我得到了完全相同的错误!我很确定你也是这样。
您报告的可用内存大小与 shared_buffers 大小相同,这有点可疑。您确定您正在查找正确的值吗?
崩溃时 free
命令的输出和 /proc/meminfo
的内容一样有用
请注意,如果您看到 overcommit_ratio
为 100,则将 overcommit_memory
设置为 2 并不是那么有效。它基本上会将内存分配限制为大小交换(在本例中为 0)+ 100物理 RAM 的百分比,不考虑共享内存和磁盘缓存的任何 space。
您可能应该将 overcommit_ratio
设置为 50。
我有一个服务器 运行ning Postgres 9.1.15。服务器有 2GB RAM,没有交换空间。间歇性地,Postgres 将开始在某些 SELECT 上出现 "out of memory" 错误,并且会继续这样做,直到我重新启动 Postgres 或 一些连接到它的客户端。奇怪的是,发生这种情况时,free
仍然报告超过 500MB 的可用内存。
select version();
:
PostgreSQL 9.1.15 on x86_64-unknown-linux-gnu, compiled by gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3, 64-bit
uname -a
:
Linux db 3.2.0-23-virtual #36-Ubuntu SMP Tue Apr 10 22:29:03 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
Postgresql.conf(其他都注释掉out/default):
max_connections = 100
shared_buffers = 500MB
work_mem = 2000kB
maintenance_work_mem = 128MB
wal_buffers = 16MB
checkpoint_segments = 32
checkpoint_completion_target = 0.9
random_page_cost = 2.0
effective_cache_size = 1000MB
default_statistics_target = 100
log_temp_files = 0
我从pgtune(我选择了"mixed type of applications")那里得到了这些值,并根据我所读的内容一直在摆弄它们,但没有取得太大的实际进展。目前有 68 个连接,这是一个典型的数字(我还没有使用 pgbouncer 或任何其他连接池)。
/etc/sysctl.conf
:
kernel.shmmax=1050451968
kernel.shmall=256458
vm.overcommit_ratio=100
vm.overcommit_memory=2
大约两周前,在 OOM 杀手杀死了 Postgres 服务器后,我第一次将 overcommit_memory
更改为 2。在此之前,服务器已经 运行 正常运行了很长时间。我现在得到的错误没有那么严重,但更烦人,因为它们更频繁。
我没有多少运气来确定导致 postgres 运行 "out of memory" 的第一个事件 - 似乎每次都不一样。最近一次崩溃时,记录的前三行是:
2015-04-07 05:32:39 UTC ERROR: out of memory
2015-04-07 05:32:39 UTC DETAIL: Failed on request of size 125.
2015-04-07 05:32:39 UTC CONTEXT: automatic analyze of table "xxx.public.delayed_jobs"
TopMemoryContext: 68688 total in 10 blocks; 4560 free (4 chunks); 64128 used
[... snipped heaps of lines which I can provide if they are useful ...]
---
2015-04-07 05:33:58 UTC ERROR: out of memory
2015-04-07 05:33:58 UTC DETAIL: Failed on request of size 16.
2015-04-07 05:33:58 UTC STATEMENT: SELECT oid, typname, typelem, typdelim, typinput FROM pg_type
2015-04-07 05:33:59 UTC LOG: could not fork new process for connection: Cannot allocate memory
2015-04-07 05:33:59 UTC LOG: could not fork new process for connection: Cannot allocate memory
2015-04-07 05:33:59 UTC LOG: could not fork new process for connection: Cannot allocate memory
TopMemoryContext: 396368 total in 50 blocks; 10160 free (28 chunks); 386208 used
[... snipped heaps of lines which I can provide if they are useful ...]
---
2015-04-07 05:33:59 UTC ERROR: out of memory
2015-04-07 05:33:59 UTC DETAIL: Failed on request of size 1840.
2015-04-07 05:33:59 UTC STATEMENT: SELECT... [nested select with 4 joins, 19 ands, and 2 order bys]
TopMemoryContext: 388176 total in 49 blocks; 17264 free (55 chunks); 370912 used
在那之前的崩溃,几个小时前,只有最后一个查询的三个实例作为崩溃的前三行。该查询经常 运行 非常 ,所以我不确定问题是 因为 这个查询,还是只是出现在错误日志中,因为它相当复杂 SELECT 一直 运行。也就是说,这里有一个解释分析:http://explain.depesz.com/s/r00
这就是 postgres 用户 ulimit -a
的样子:
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 15956
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 15956
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
下次发生崩溃时,我会尝试从 free
中获取确切的数字,与此同时,这是我所有信息的脑力转储。
关于从这里到哪里去的任何想法?
我只是 运行 遇到了同样的问题,我试图恢复一个 ~2.5 GB 的纯文本 SQL 文件。我将我的 Digital Ocean 服务器扩展到 64 GB RAM,创建了一个 10 GB 的交换文件,然后再次尝试。我遇到了 50 GB 可用内存不足的错误,并且没有使用交换空间。
我将我的服务器缩减到我正在使用的 1 GB 小型实例(需要重新启动)并且我想我会再试一次,除了我感到沮丧之外没有其他原因。我开始导入并意识到我忘记再次创建我的临时交换文件。
我在导入过程中创建了它。 psql 在崩溃之前使它更进一步 lot。它通过了另外 5 个表格。
我认为 psql 中一定存在分配内存的错误。
能不能在出现错误时检查一下是否有可用的交换内存?
我已经完全删除了 Linux 桌面中的交换内存(只是为了测试其他东西...),我得到了完全相同的错误!我很确定你也是这样。
您报告的可用内存大小与 shared_buffers 大小相同,这有点可疑。您确定您正在查找正确的值吗?
崩溃时 free
命令的输出和 /proc/meminfo
请注意,如果您看到 overcommit_ratio
为 100,则将 overcommit_memory
设置为 2 并不是那么有效。它基本上会将内存分配限制为大小交换(在本例中为 0)+ 100物理 RAM 的百分比,不考虑共享内存和磁盘缓存的任何 space。
您可能应该将 overcommit_ratio
设置为 50。