pgbench 进行大量事务后数据库暂时断开连接

Posted

技术标签:

【中文标题】pgbench 进行大量事务后数据库暂时断开连接【英文标题】:Database temporarily disconnected after a lots of transactions by pgbench 【发布时间】:2012-11-28 03:22:32 【问题描述】:

我正在使用 (PostgreSQL) 9.2.1 并使用 pgbench 测试数据库。

pgbench -h 192.168.39.38 -p 5433 -t 1000 -c 40 -j 8 -C -U admin testdb

当我使用 -C 参数(为每个事务建立一个新连接)时,事务总是在第 16381 个事务之后丢失。

Connection to database "testdb" failed
could not connect to server: Can't assign requested address
    Is the server running on host "192.168.39.38" and accepting
    TCP/IP connections on port 5433?
Client 19 aborted in establishing connection.
Connection to database "testdb" failed
could not connect to server: Can't assign requested address
    Is the server running on host "192.168.39.38" and accepting
    TCP/IP connections on port 5433?
Client 19 aborted in establishing connection.
....

transaction type: TPC-B (sort of)
scaling factor: 30
query mode: simple
number of clients: 40
number of threads: 8
number of transactions per client: 1000
number of transactions actually processed: 16381/40000
tps = 1665.221801 (including connections establishing)
tps = 9487.779510 (excluding connections establishing)

并且每次测试中实际处理的交易数量始终为16381。 但是,pgbench 可以成功,并且所有事务都在以下情况下处理

-C 不使用

总交易量小于 16381

删除这些事务后,数据库可以在几秒钟内继续接受连接。 我想知道我是否遗漏了一些 PostgreSQL 的配置。

谢谢


编辑 我发现客户端被阻止连接几秒钟,但其他人仍然可以访问数据库。这是否意味着同一个客户端不能在短时间内发送太多交易?

【问题讨论】:

顺便说一句,我在 postgresql.conf 中尝试了以下参数。但是在这种情况下它们是没用的。wal_bufferscheckpoint_segmentsmax_connectionswal_writer_delayshared_buffers 可能是套接字 TIME_WAIT3 的事情。 netstat 说什么?如果通过 unix-domeain 套接字连接会发生什么? 顺便说一句:客户端和服务器之间是否有路由器/防火墙/NAT-box? 【参考方案1】:

我找到了它在大约 16000 次交易后丢失连接的原因。 TCP wait_time 为这个错误负责。以下命令将显示 TCP 连接的状态:

$ netstat -n | awk '/^tcp/ ++S[$NF] END for(a in S) print a, S[a]'

尽管如此,它并没有在 MAC OS X 中显示 TIME_WAIT。因此我错过了它。通过以下命令调整 TCP wait_time 后,pgbench 可以正常工作了。

$ sudo sysctl -w net.inet.tcp.msl=1500
net.inet.tcp.msl: 15000 -> 1500

感谢您的帮助。

【讨论】:

Hsiao - 出色的工作找出了失败的确切原因。 :)【参考方案2】:

操作系统确实存在最大连接数限制。阅读文档中的max-connections:(加粗的相关部分)

确定与数据库服务器的最大并发连接数。 默认值通常为 100 个连接,但如果您的内核设置不支持它可能会更少(在 initdb 期间确定)。该参数只能在服务器启动时设置。

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

您只能打开 16381 个连接,可以通过 2^14 (=16384) 个可能的最大连接减去默认为超级用户连接保留的 3 个连接来解释(请参阅文档)。

【讨论】:

【参考方案3】:

有趣的是,16381 如此接近 2 的幂。

这主要是猜测:

我想知道这是否是操作系统的问题。查看 TPS 数据,是否为每笔交易创建了新的连接? [编辑是的,现在我正确地阅读了你的问题。]

也许操作系统只有这么多可以使用的连接资源,并且在最近建立了 16381(加上几个额外的)后无法立即创建新连接?

可能存在用于指定可用连接资源数量的操作系统设置,这可能允许使用更多连接。您能否在问题中添加一些操作系统详细信息?


我特别怀疑您连接的端口号一直在增加,并且您正在达到限制。试试“lsof -i”,看看你是否能在发生时捕捉到一个连接,看看这个数字是否在上升。

【讨论】:

我没有调整操作系统设置,除了共享内存(kernel.shmmax=25GB)和postgresql.conf中的配置。有没有我需要注意的设置?谢谢。 我的意思是你的操作系统的设置——Linux、Windows 等。服务器和客户端机器的操作系统是什么? 我使用带有 i386 平台的 Ubuntu 12.04 作为数据库服务器。客户端机器是 Mac OS X 3.2GHz 四核 Intel Xeon。 @Hsiao,如果您想将其标记为正确答案,您需要将其添加为单独的答案并自行接受。请不要编辑其他答案和更改内容。如果您想更正此答案中的某些内容,可以随时在此处发表评论。 @ACB,我明白了。感谢您的通知。【参考方案4】:

我通过设置为 /etc/sysctl.conf 解决了问题:

net.ipv4.ip_local_port_range = 32768 65000
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 10

【讨论】:

以上是关于pgbench 进行大量事务后数据库暂时断开连接的主要内容,如果未能解决你的问题,请参考以下文章

设备断开一段时间后无法获得特征

TCP的连接与断开

TCP的连接与断开

superset连接sqlite频繁断开

移动网络状态断开连接

当 TCP 连接中的链接断开时的 send() 函数行为