php存取mssql、sybase時,如何設定query timeout

以前在整理php.ini、及freetds.conf的設定時,注意到兩者都有支援(query)timeout、及connect timeout,當時也作了設定。但最近的一些狀況,讓我好奇(query)timeout設定是否真的有發揮效果?

由於FreeTDS可以支援MS SQL、Sybase(FreeTDS is a set of libraries for Unix and Linux that allows your programs to natively talk to Microsoft SQL Server and Sybase databases.),所以就一併測試這兩種資料庫。首先,看一下相關設定的說明,php.ini 中對於MS SQL、Sybase的設定、及freetds的設定,分別如下…

測試的結果,無論是MS SQL、Sybase的timeout居然都沒效果。

難道又是文件和實際不符合嘛?找了些資料,看到Bug #34647 mssql.timeout has no affect中的討論、說明後,去挖出freetds change log,終於有點眉目。原來是因為我所使用的FreeTDS版本太舊,timeout機制在FreeTDS v8.2(freetds v0.82 change log)才開始支援。

目前,FreeTDS已經出到v0.91,以下節錄該版本主要的更新說明…詳細內容,請見freetds v0.91的說明。(感覺上,FreeTDS後續版本的變更,主要都是配合MS SQL…)
Summary of Changes in release 0.91
--------------------------------------------
1. Full Kerberos and SSPI support for passwordless login to Microsoft SQL Server from Unix and Windows clients. Includes Kerberos delegation option.
2. Full support for DB-Library under Win32/64 via NMAKE.EXE.
3. Built-in support for UTF-8.
4. Support for wide characters in ODBC.
5. Support for varchar(max) and varbinary(max).
6. Better thread-safety in ODBC.
7. Distinguish between connect and login errors.
8. Bulk-copy functions in CT-Library.

TDS versions now reflect Microsoft's nomenclature. The previous version numbers (8.0 and 9.0) are now 7.1 and 7.2. See the UG for details.

然而,以我常用的FreeBSD又有一個狀況,採一般安裝時會是 v.64。要使用FreeTDS 0.91,需要安裝/usr/ports/databases/freetds-devell 內的版本。
  • /usr/ports/databases/freetds 內的版本為0.64.x
  • /usr/ports/databases/freetds-devel 內的版本為0.91.x

更新FreeTDS版本後,重新測試兩種資料庫的query timeout,分別可看到下面訊息,表示有效果了…
  • mssql_query(): Query failed
  • sybase_query(): Sybase: Client message: Adaptive Server connection timed out (severity 78)

在後續的測試中,發現兩個有趣的狀況。兩種資料庫的設定方式、和機制,居然有所不同~
設定方式不同
  • MS SQL,需在php.ini 設定才有效果
  • Sybase,需在freetds.conf 設定才有效果

機制不同,當query timeout發生時兩種資料庫的行為不同
  • 查詢MS SQL,query timeout 發生時,查詢會中斷,傳給程式FALSE
  • 查詢Sybase,query timeout 發生時,雖然會有錯誤訊息,但…查詢不會中斷…(這一點讓人頭很大 :( )

最後,附帶一提…曾經依照FreeTDS說明 - Choosing a TDS protocol version將MS SQL 2005設定 tds version = 7.2。卻會得到錯誤,只好照freetds.conf的範例設定使用tds version = 8.0。

這次,升級到 FreeTDS 0.91後,MS SQL 2005就可以使用 tds version = 7.2 的設定了。我想,這應該是因為freetds v0.91重新定義有關(請見上面FreeTDS v0.91,節錄主要更新說明)。



參考資料

留言