I have two identical servers (called test and production) with Linux Red Hat Enterprise Linux Server release 6.2 (Santiago), PHP version 5.4.2, Apache Apache 2.4.2, OpenSSL/0.9.8s, freeTDS 0.92-dev (not the best thing but I cannot change that for the moment), and a separate Windows server with Microsoft SQL Server.
I have a PHP script called testfs1.php that reads a string from the database, always the same, and prints the length: nothing else. Of course, the initial situation was much more complex, but I did any effort to simplify.
The database field is NVARCHAR, all the components are set to use UTF-8.
Normally everything works: the script displays the expected string length. But once every several hours or even days, on the production server only (which hosts several heavily used applications), the bug "activates": the web server starts displaying special characters extracted from database wrong. Sometimes the bug "deactivates" by itself after some minutes; last time, it lasted several hours, then I run
service httpd restart
and the bug deactivated.
In the time frame when the bug is active, it is consistent: all requests to the web server for the page testfs1.php display the wrong result; however, when I manually run
php testfs1.php
on a command line of the server, the bug never appears, even when it is active.
This is the Bash script I leave running day and night to monitor the activation of the bug:
#!/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
The PHP script I use to reproduce the issue:
<?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 ) ;
?>
Here is locales.conf used by freeTDS:
[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
Summary of the most puzzling particularities of this issue:
- Bug never happens when the script is run with PHP from the command line, only from Apache
- Bug "activates" at different moments, once every several hours or few days, and either "deactivates" by itself or with a "service httpd restart"
- When in the locales.conf used by freeTDS, the line [default]/charset was missing the bug was activating and deactivating spontaneously much more often (every few seconds)
- When another application on the same server used gettext, the bug was activating and deactivating spontaneously much more often (every few seconds)
A colleague hints that it could be a memory problem, which makes some sense considering that restarting Apache could have freed memory, and explains why it does not happen on the test server, where the traffic is minimal. I am not convinced.
Can you imagine possible causes and solutions for the situation?