Postgresql在防火墙之后:查询需要太长时间

这是我的设置:VMWare ESXi 4.0上的两个CentOS 5.2盒子。 第一个IP地址是eth0的192.168.22.52,eth1的IP地址是192.168.99.1。 第二个盒子在eth0上运行PostgreSQL 8.3,IP地址为192.168.99.2。 这里是box1的 iptables,box2参见下面的注释。

我已经在box1上设置了端口5432转发,并且能够通过pgAdminIII或者Vista笔记本上的psql(192.168.22.1,这个子网中没有其他的盒子,它有自己的交换机并且物理隔离)在box2上连接到PostgreSQL。 我连接的数据库有两个模式,一个是“较小”(基本上只有一个表),另一个是较大的(大约30个表,100个function等)。所以我能够使用较小的模式(浏览表等),但我试图扩大更大的模式 – pgAdminIII冻结20分钟左右。

PostgreSQL日志显示有一个查询需要太长时间:

2009-06-04 21:04:46 EEST LOG: 00000: duration: 493578.874 ms statement: SELECT pr.oid, pr.xmin, pr.*, format_type(TYP.oid, NULL) AS typname, typns.nspname AS typnsp, lanname, proargnames, proconfig, pg_get_userbyid(proowner) as funcowner, description FROM pg_proc pr JOIN pg_type typ ON typ.oid=prorettype JOIN pg_namespace typns ON typns.oid=typ.typnamespace JOIN pg_language lng ON lng.oid=prolang LEFT OUTER JOIN pg_description des ON des.objoid=pr.oid WHERE proisagg = FALSE AND pronamespace = 2200::oid AND typname <> 'trigger' ORDER BY proname 

box1和box2都是开发盒的克隆,原来的networking结构是不同的 – box2可以直接访问,不需要端口转发,访问数据库也没有问题。

现在,如果我在box2或“原始”机器上通过psql运行上述查询,或者通过box1连接到box2运行上述查询,它立即执行。

在查询运行期间,box2上的tcpdump会周期性地显示:

 12:45:39.770609 IP 192.168.99.2.postgres > 192.168.22.1.49484: . 8760:10220(1460) ack 1 win 54 12:45:39.968496 IP 192.168.22.1.49484 > 192.168.99.2.postgres: . ack 10220 win 16425 12:45:39.968541 IP 192.168.99.2.postgres > 192.168.22.1.49484: . 10220:11680(1460) ack 1 win 54 12:45:39.968574 IP 192.168.99.2.postgres > 192.168.22.1.49484: . 11680:13140(1460) ack 1 win 54 12:45:39.969250 IP 192.168.22.1.49484 > 192.168.99.2.postgres: . ack 13140 win 16425 12:45:39.969275 IP 192.168.99.2.postgres > 192.168.22.1.49484: . 13140:17520(4380) ack 1 win 54 12:45:39.969408 IP 192.168.22.52 > 192.168.99.2: ICMP 192.168.22.1 unreachable - need to frag (mtu 1500), length 556 

除此之外,我没有看到很多交通。 所有ethN接口上的MTU都是1500.笔记本ping -l 1472 -f 192.168.99.1没有问题。

我怀疑我缺less有关iptables或networking设置的东西,并会感谢您的build议。

有些事情要尝试:

  1. 首先validation您的networking是否正在运行。 假设您有pipe理交换机,请查看速度/双工不匹配的接口统计信息或不匹配的MTU。 考虑检查/更换布线,如果有任何运行错误(例如:试图运行GigE over Cat5而不是Cat5e可能会导致悲伤)。

  2. 运行一些testing来certificate你可以在两台机器和外部机器之间进行线速传输; netcat,ftp或http传输是一个很好的开始(scp可能会受CPU限制,因此可能不是最好的testing)。

  3. 在Postgres服务器上本地testing相同的查询。 如果它在适当的时间内完成,你就知道这不是数据库。 如果它没有完成或者“太长”,那么你有一个错误的查询或其他数据库问题来debugging。 确保考虑事物的存储I / O面; 你可能会饱和你的磁盘所能提供的东西。 检查VMware性能图以确认/拒绝。

  4. 假设可行,请禁用防火墙,并从“box1”对postgres服务器运行相同的查询。 如果这样的话,VM-> VM连接可能没有问题。

  5. 假设有效,请重新启动防火墙并再次testing。 如果这样的话,那么你的问题就可能在那个主机的外部,让交换机或者外部主机去debugging。

祝你好运。

你有一个MTU的问题,但我不知道为什么。 我试图让我的头在这里缠绕你的虚拟拓扑。

那么,您的Windows Vista笔记本电脑是连接到“本地”networking还是Internetnetworking?

我假设您的Windows Vista笔记本电脑已连接到Internet,并且您正在访问“方框1”的外部端IP地址以使用端口5432上的端口转发到“方框2”。 如果是这样的话,当你试图:

ping -l 1472 -f <box 1 IP address>

编辑:好的 – 非常好。 如果需要的话,在“方框1”和“方框2”上运行“ifconfig”,并检查每个以太网接口的MTU值。 他们都应该是1500.(我只是想弄清楚为什么“方框1”告诉“方框2”,它不能分割一个556字节的数据报,绑定到您的笔记本电脑…)

编辑:Zow。 好的 – 那是疯狂的

如果没有太多的问题,你可以发布你的iptablesconfiguration的内容(或链接)到问题? (我开始在这里被困住了,你所描述的是我经常做的事情,但我不确定它是如何崩溃的。)

编辑:现在回来。 好的。 我现在对此感到困惑。 iptables的configuration看起来不像是应该引起任何问题。 我确实看到你将UDP 5432转发到“方框2”。 你不需要转发 – Postgres只使用TCP。 不过,这不会伤害任何东西。

在你等待20分钟的时候,你看到Vista笔记本和“盒子2”之间的stream量在移动吗? 你每次连接都能重现吗?

不是说它有很大的不同,但是在“方框1”的FORWARD链上,我通常会规定ACCEPT包的RELATED,ESTABLISHED集是链中的第一个规则(用于短路处理)。 不过,我认为这不会对你有任何显着的性能影响。

我讨厌不知道问题的答案。 这将在晚上使我保持清醒。

可以想象这些机器之一试图不恰当地使用IPv6吗? 也就是说,是否确保IPv6在任何不应该使用的地方closures,如果正确使用,是否正确configuration?