从 Rails 应用程序连接到 Windows SQL Server 2008 R2
Connect to Windows SQL Server 2008 R2 from Rails app
我的 Rails 4.2.1 应用程序必须连接到 Microsoft SQL 2008 R2 数据库。我使用的是 tiny_tds
gem 版本 1.0.4。 FreeTDS v1.00.15 安装在生产服务器 运行ning Ubuntu 14.04.
我 运行 在 each 循环内查询,我无法让循环完成,进程在完成前崩溃。
我尝试使用 tiny_tds 选项但没有成功。
这是我用来获取 tiny_tds 客户端的代码(检查 tds_version
和 timeout
选项):
client = TinyTds::Client.new(username: db_conf['username'], password: db_conf['password'], host: db_conf['host'], port: db_conf['port'], database: db_conf['database'], tds_version: '7.3', timeout: 15000, appname: 'ERP')
这是发生此类错误后的 FreeTDS 日志。
packet.c:741:Sending packet 0000 12 01 00 ce 00 00 00 00-16 03 01 00
86 10 00 00 |........ ........| 0010 82 00 80 6e d9 e2 dc 97-9d 77 59
9a 5b da e3 e2 |...n.... .wY.[...| 0020 8b aa 66 ed ec 5e e2 02-e5 6c
fd db e1 ef 47 1a |..f..^.. .l....G.| 0030 9d 63 03 ed 6d 3e 28 3b-b9
64 fd 92 71 34 ff ba |.c..m>(; .d..q4..| 0040 7d 3c 8d ee 7b 34 75
e9-d5 b7 c6 83 a9 7d e6 7f |}<..{4u. .....}..| 0050 71 7e 25 11 82 b8
76 b1-c6 ba 86 b4 c3 0a 47 f0 |q~%...v. ......G.| 0060 51 96 c7 e2 5f
ca 07 b2-95 53 b9 9e bb 2c e7 cb |Q..._... .S...,..| 0070 be 0a b5 eb
b0 f3 41 1d-cd 86 fc a6 53 08 5e 56 |......A. ....S.^V| 0080 29 85 79
14 dc 2b 74 7b-b2 43 2c e8 0e 87 60 e4 |).y..+t{ .C,....| 0090 10 ef
f8 14 03 01 00 01-01 16 03 01 00 30 c7 f0 |........ .....0..| 00a0 35
f5 2c 6e 79 8d 85 b9-bd 60 b7 09 8c 7e 29 18 |5.,ny... .
...~).| 00b0
4a 56 ea c3 4e 13 bf e3-c5 8d f6 68 31 31 54 ee |JV..N... ...h11T.|
00c0 bf 2f 75 8d e9 9e c0 a9-d0 d2 9e 5b c9 92 |./u..... ...[..|
tls.c:105:in tds_pull_func_login query.c:3796:tds_disconnect()
util.c:165:Changed query state from IDLE to DEAD
util.c:322:tdserror(0x80b75e0, 0xa04ca80, 20017, 0)
dblib.c:7947:dbperror(0xae62780, 20017, 0) dblib.c:8015:dbperror:
Calling dblib_err_handler with msgno = 20017; msg->msgtext =
"Unexpected EOF from the server (192.168.32.105:1433)"
dblib.c:5777:dbgetuserdata(0xae62780) dblib.c:8037:dbperror:
dblib_err_handler for msgno = 20017; msg->msgtext = "Unexpected EOF
from the server (192.168.32.105:1433)" -- returns 2 (INT_CANCEL)
util.c:352:tdserror: client library returned TDS_INT_CANCEL(2)
util.c:375:tdserror: returning TDS_INT_CANCEL(2) util.c:375:tdserror:
returning TDS_INT_CANCEL(2) tls.c:942:handshake failed
login.c:530:login packet rejected util.c:322:tdserror(0x80b75e0,
0xa04ca80, 20002, 0) dblib.c:7947:dbperror(0xae62780, 20002, 0)
dblib.c:8015:dbperror: Calling dblib_err_handler with msgno = 20002;
msg->msgtext = "Adaptive Server connection failed"
这是 tsql -C
的输出:
~$ tsql -C
Compile-time settings (established with the "configure" script)
Version: freetds v1.00.15
freetds.conf directory: /usr/local/etc
MS db-lib source compatibility: no
Sybase binary compatibility: no
Thread safety: yes
iconv library: yes
TDS version: auto
iODBC: no
unixodbc: no
SSPI "trusted" logins: no
Kerberos: no
OpenSSL: yes
GnuTLS: no
MARS: no
知道我应该如何修复这些 Unexpected EOF from the server
错误吗?
在您的 FreeTDS 配置中(通常在 /etc/freetds/freetds.conf
中,就像在您的配置中一样),更改 text size
的值:
text size = 4294967295
这是最大值,IIRC。我相信对于 FreeTDS 0.91,您的默认值可能是 64512。
查看 SQL Profiler,我发现 Rails 应用程序在 MSSQL 服务器上打开了太多连接。达到最大打开连接数后,MSSQL 服务器拒绝打开任何新连接,导致 Unexpected EOF from the server
错误。
为了解决这个问题,我不得不在发送查询时重用打开的连接,而不是为每个查询打开一个新连接。我想这是使用 tiny_tds
连接器的正确方法。
翻译成代码:
def self.get_pmi_client
if @@pmi_client.nil? or !@@pmi_client.active?
db_conf = Rails.configuration.database_configuration["pmi_#{Rails.env}"]
@@pmi_client = TinyTds::Client.new(username: db_conf['username'], password: db_conf['password'], host: db_conf['host'], port: db_conf['port'], database: db_conf['database'])
raise MSSQLConnectionError, t('erp.errors.pmi_connection_error') unless @@pmi_client.active?
end
return @@pmi_client
end
我的 Rails 4.2.1 应用程序必须连接到 Microsoft SQL 2008 R2 数据库。我使用的是 tiny_tds
gem 版本 1.0.4。 FreeTDS v1.00.15 安装在生产服务器 运行ning Ubuntu 14.04.
我 运行 在 each 循环内查询,我无法让循环完成,进程在完成前崩溃。 我尝试使用 tiny_tds 选项但没有成功。
这是我用来获取 tiny_tds 客户端的代码(检查 tds_version
和 timeout
选项):
client = TinyTds::Client.new(username: db_conf['username'], password: db_conf['password'], host: db_conf['host'], port: db_conf['port'], database: db_conf['database'], tds_version: '7.3', timeout: 15000, appname: 'ERP')
这是发生此类错误后的 FreeTDS 日志。
packet.c:741:Sending packet 0000 12 01 00 ce 00 00 00 00-16 03 01 00 86 10 00 00 |........ ........| 0010 82 00 80 6e d9 e2 dc 97-9d 77 59 9a 5b da e3 e2 |...n.... .wY.[...| 0020 8b aa 66 ed ec 5e e2 02-e5 6c fd db e1 ef 47 1a |..f..^.. .l....G.| 0030 9d 63 03 ed 6d 3e 28 3b-b9 64 fd 92 71 34 ff ba |.c..m>(; .d..q4..| 0040 7d 3c 8d ee 7b 34 75 e9-d5 b7 c6 83 a9 7d e6 7f |}<..{4u. .....}..| 0050 71 7e 25 11 82 b8 76 b1-c6 ba 86 b4 c3 0a 47 f0 |q~%...v. ......G.| 0060 51 96 c7 e2 5f ca 07 b2-95 53 b9 9e bb 2c e7 cb |Q..._... .S...,..| 0070 be 0a b5 eb b0 f3 41 1d-cd 86 fc a6 53 08 5e 56 |......A. ....S.^V| 0080 29 85 79 14 dc 2b 74 7b-b2 43 2c e8 0e 87 60 e4 |).y..+t{ .C,...
.| 0090 10 ef f8 14 03 01 00 01-01 16 03 01 00 30 c7 f0 |........ .....0..| 00a0 35 f5 2c 6e 79 8d 85 b9-bd 60 b7 09 8c 7e 29 18 |5.,ny... .
...~).| 00b0 4a 56 ea c3 4e 13 bf e3-c5 8d f6 68 31 31 54 ee |JV..N... ...h11T.| 00c0 bf 2f 75 8d e9 9e c0 a9-d0 d2 9e 5b c9 92 |./u..... ...[..|tls.c:105:in tds_pull_func_login query.c:3796:tds_disconnect() util.c:165:Changed query state from IDLE to DEAD util.c:322:tdserror(0x80b75e0, 0xa04ca80, 20017, 0) dblib.c:7947:dbperror(0xae62780, 20017, 0) dblib.c:8015:dbperror: Calling dblib_err_handler with msgno = 20017; msg->msgtext = "Unexpected EOF from the server (192.168.32.105:1433)" dblib.c:5777:dbgetuserdata(0xae62780) dblib.c:8037:dbperror: dblib_err_handler for msgno = 20017; msg->msgtext = "Unexpected EOF from the server (192.168.32.105:1433)" -- returns 2 (INT_CANCEL) util.c:352:tdserror: client library returned TDS_INT_CANCEL(2) util.c:375:tdserror: returning TDS_INT_CANCEL(2) util.c:375:tdserror: returning TDS_INT_CANCEL(2) tls.c:942:handshake failed login.c:530:login packet rejected util.c:322:tdserror(0x80b75e0, 0xa04ca80, 20002, 0) dblib.c:7947:dbperror(0xae62780, 20002, 0) dblib.c:8015:dbperror: Calling dblib_err_handler with msgno = 20002; msg->msgtext = "Adaptive Server connection failed"
这是 tsql -C
的输出:
~$ tsql -C
Compile-time settings (established with the "configure" script)
Version: freetds v1.00.15
freetds.conf directory: /usr/local/etc
MS db-lib source compatibility: no
Sybase binary compatibility: no
Thread safety: yes
iconv library: yes
TDS version: auto
iODBC: no
unixodbc: no
SSPI "trusted" logins: no
Kerberos: no
OpenSSL: yes
GnuTLS: no
MARS: no
知道我应该如何修复这些 Unexpected EOF from the server
错误吗?
在您的 FreeTDS 配置中(通常在 /etc/freetds/freetds.conf
中,就像在您的配置中一样),更改 text size
的值:
text size = 4294967295
这是最大值,IIRC。我相信对于 FreeTDS 0.91,您的默认值可能是 64512。
查看 SQL Profiler,我发现 Rails 应用程序在 MSSQL 服务器上打开了太多连接。达到最大打开连接数后,MSSQL 服务器拒绝打开任何新连接,导致 Unexpected EOF from the server
错误。
为了解决这个问题,我不得不在发送查询时重用打开的连接,而不是为每个查询打开一个新连接。我想这是使用 tiny_tds
连接器的正确方法。
翻译成代码:
def self.get_pmi_client
if @@pmi_client.nil? or !@@pmi_client.active?
db_conf = Rails.configuration.database_configuration["pmi_#{Rails.env}"]
@@pmi_client = TinyTds::Client.new(username: db_conf['username'], password: db_conf['password'], host: db_conf['host'], port: db_conf['port'], database: db_conf['database'])
raise MSSQLConnectionError, t('erp.errors.pmi_connection_error') unless @@pmi_client.active?
end
return @@pmi_client
end