这是我的设置:VMWare ESXi 4.0 上的两个 CentOS 5.2 机器。第一个盒子 ip 在 eth0 上是 192.168.22.52,在 eth1 上是 192.168.99.1。第二个盒子在 eth0 上运行 PostgreSQL 8.3,ip 为 192.168.99.2。这是box1的 iptables ,对于 box2 ,请参阅下面的评论。
我已经在 box1 上设置了端口 5432 转发,并且能够通过 pgAdminIII 或来自 Vista 笔记本的 psql 连接到 box2 上的 PostgreSQL(192.168.22.1,该子网中没有其他盒子,它有自己的交换机并且物理隔离)。我要连接的数据库有两个模式,一个是“较小的”(基本上只有一个表),另一个更大(大约 30 个表、100 个函数等)所以我能够使用较小的模式(浏览表等)但是当我尝试扩展更大的架构时 - 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都是开发box的克隆,原来的网络结构不同——box2不需要端口转发直接访问,访问数据库也没有问题。
现在,如果我通过 psql 在 box2 或“原始”机器上运行上述查询,或者从 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 从笔记本电脑通过没有问题。
我怀疑我遗漏了一些关于 iptables 或网络设置的信息,希望能得到您的建议。
一些事情要尝试:
首先验证您的网络是否正常运行。假设您有托管交换机,请查看速度/双工不匹配或 MTU 不匹配的接口统计信息。如果出现任何运行错误,请考虑检查/更换电缆(例如:尝试在 Cat5 上运行 GigE 而不是 Cat5e 可能会让人感到痛苦)。
运行一些测试以证明您可以在两台机器之间以及到外部机器之间进行线速传输;netcat、ftp 或 http 传输是一个好的开始(scp 可能会受到 CPU 限制,因此可能不是最好的测试)。
在 Postgres 服务器上本地测试相同的查询。如果它在适当的时间范围内完成,您就知道它不是数据库。如果它没有完成或花费“太长时间”,那么您有一个错误的查询或其他数据库问题需要调试。确保考虑事物的存储 I/O 方面;您的磁盘所能提供的功能可能已经饱和。检查 VMware 性能图表以确认/拒绝。
假设可行,禁用防火墙并从“box1”对 postgres 服务器运行相同的查询。如果可行,则 VM->VM 连接可能没问题。
假设可行,请重新启动防火墙并再次测试。如果这样可行,那么您的问题很可能是该主机外部的问题,需要对交换机或外部主机进行调试。
祝你好运。
您遇到了 MTU 问题,但我不知道为什么。我正试图在这里了解您的虚拟拓扑。
那么,您的 Windows Vista 笔记本是连接到“本地”网络,还是连接到 Internet 网络?
我假设您的 Windows Vista 笔记本已连接到 Internet,并且您正在访问“框 1”的外部 IP 地址以使用端口 5432 上的端口转发来访问“框 2”。如果是这种情况,当您尝试执行以下操作时会得到什么:
ping -l 1472 -f <框 1 IP 地址>
编辑:好的——非常好。如果愿意,请在“box 1”和“box 2”上运行“ifconfig”并检查每个以太网接口上的 MTU 值。它们都应该是 1500。(我只是想弄清楚为什么“框 1”告诉“框 2”它不能对绑定到您的笔记本的 556 字节数据报进行分段...)
编辑:佐。好吧——这太疯狂了。
如果要问的不是太多,您能否将 iptables 配置的内容(或链接)发布到问题中?(我开始在这里被难住了。你所描述的是我经常做的事情,但我不确定它是如何崩溃的。)
编辑:现在回到你身边。好的。我现在对这个感到困惑。iptables 配置看起来应该不会导致任何问题。我确实看到您将 UDP 5432 转发到“框 2”。你不需要转发——Postgres 只使用 TCP。不过,这不会伤害任何东西。
在您等待 20 分钟的过程中,您是否看到 Vista 笔记本和“box 2”之间的流量移动?你能在每次连接时重现这种情况吗?
并不是说它有很大的不同,但是在“框 1”上的 FORWARD 链上,我通常会将接受带有 RELATED、ESTABLISHED 的数据包的规则设置为链中的第一条规则(用于短路处理)。不过,我认为这不会对您产生任何重大的性能影响。
我讨厌不知道问题的答案。这会让我夜不能寐。
是否可以想象其中一台机器正试图不恰当地使用 IPv6?也就是说,您是否确保在不应该使用 IPv6 的所有地方都关闭它,并且,如果使用的话,是否正确配置?