我有一个 Java 抓取工具,它会产生大约 1,500-2,100 个线程,每个线程都通过 jdbc 连接到同一个数据库并进行插入。这些线程插入非常频繁。
连接过多时数据库似乎会崩溃。当所有线程都失去连接时,我总是会生成 210 个线程或连接。以下是在服务器端生成的日志消息。
2015-07-15 20:18:37 UTC [10825-21] LOG: checkpointer process (PID 13435) was terminated by signal 9: Killed
2015-07-15 20:18:37 UTC [10825-22] LOG: terminating any other active server processes
2015-07-15 20:18:37 UTC [16836-1] user@db WARNING: terminating connection because of crash of another server process
2015-07-15 20:18:37 UTC [16836-2] user@db DETAIL: The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory.
2015-07-15 20:18:37 UTC [16836-3] user@db HINT: In a moment you should be able to reconnect to the database and repeat your command.
以下是客户端(抓取工具)显示的错误信息。
SEVERE: An I/O error occurred while sending to the backend.
org.postgresql.util.PSQLException: An I/O error occurred while sending to the backend.
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:283)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:570)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:420)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:366)
at SocketBot.run(SocketBot.java:167)
Caused by: java.io.EOFException
at org.postgresql.core.PGStream.ReceiveChar(PGStream.java:284)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1803)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:255)
... 4 more
在 postgresql.conf 文件中,我设置了 max connections = 2500。但我想这里还有更多需要调整的地方。如果有人想知道的话,我的服务器有 512MB RAM。
答案1
Linux 的内存不足杀手可能正在终止进程。这意味着您的服务器配置错误。强烈建议您不是让 Linux 过度使用内存,这样它就会向应用程序发出适当的内存不足错误响应,而不是几乎随机地终止进程。PostgreSQL 旨在处理内存不足的情况,但如果 Linux 终止进程而不是报告内存不足,PostgreSQL 就无法处理内存不足的情况。
要确认这里发生的情况,请使用命令检查内核消息日志dmesg
。
看http://www.postgresql.org/docs/current/static/kernel-resources.html#LINUX-MEMORY-OVERCOMMIT