我有两个相同的服务器(称为测试和生产),Linux Red Hat Enterprise Linux Server 6.2(Santiago),PHP版本5.4.2,Apache Apache 2.4.2,OpenSSL / 0.9.8s,freeTDS 0.92-dev(不是最好的事情,但我现在无法改变它,以及一个单独的Windows服务器与Microsoft SQL Server。
我有一个名为testfs1.php的PHP脚本,它从数据库中读取一个字符串,始终相同,并打印长度:没有别的。当然,最初的情况要复杂得多,但我还是努力简化。
数据库字段为NVARCHAR,所有组件都设置为使用UTF-8。
通常一切正常:脚本显示预期的字符串长度。但是每隔几个小时甚至几天,仅在生产服务器上(其中托管了几个使用频繁的应用程序),错误“激活”:Web服务器开始显示从数据库中提取的特殊字符错误。有时候,这个错误会在几分钟后自动“停用”;上次,它持续了几个小时,然后我跑了
service httpd restart
并停用了错误。
在错误处于活动状态的时间范围内,它是一致的:对页面testfs1.php的所有Web服务器请求都显示错误的结果;但是,当我手动运行时
php testfs1.php
在服务器的命令行上,即使它处于活动状态,也不会出现错误。
这是我日夜运行的Bash脚本,用于监控错误的激活:
#!/bin/bash
while : ; do
echo -n `date +%H%M%S`
wget https://www.mydomain.org/testfs1.php -o /dev/null
echo -n "("
cat testfs1.php
echo -n ") "
rm testfs1.php
sleep 2
done
我用来重现问题的PHP脚本:
<?php
$Conn = mssql_connect( 'PROD', 'user', 'password' ) ;
mssql_select_db( "DBPROD", $Conn ) ;
$Ret = mssql_query( "SELECT lname FROM people WHERE people_key=123", $Conn ) ;
list( $s ) = mssql_fetch_row( $Ret ) ;
print strlen( $s ) ;
?>
这是freeTDS使用的locales.conf:
[default]
date format = %b %e %Y %I:%M:%S:%z%p
language = us_english
charset = UTF-8
[en_US]
date format = %b %e %Y %I:%M:%S:%z%p
language = us_english
charset = UTF-8
[es_ES]
date format = %b %e %Y %I:%M:%S:%z%p
language = us_english
charset = UTF-8
[pt_BR]
date format = %b %e %Y %I:%M:%S:%z%p
language = us_english
charset = UTF-8
[it_IT]
date format = %b %e %Y %I:%M:%S:%z%p
language = us_english
charset = UTF-8
这个问题最令人费解的特点:
一位同事暗示这可能是一个内存问题,考虑到重启Apache可以释放内存,并解释为什么它不会发生在流量最小的测试服务器上。我不相信。
您能想象出可能的原因和解决方案吗?
答案 0 :(得分:1)
坦率地说,我不知道是什么造成了这种不一致的工作。但我想建议你改变FreeTDS&amp; unixODBC到稳定版本。因为FreeTDS缺乏文档和支持。我一直在使用v0.82。它工作正常。
https://gitorious.org/freetds/mars-freetds/source/52e59affc0110c5ddd379ef1e45c4554123f27b5:README#L2
查找详细问题的另一种方法是在testfs1.php中使用PDO MsSQL。通过这种方式,如果本机mssql扩展对此不一致有任何影响,您可以更好地解决问题。