【问题标题】:Connect to Windows SQL Server 2008 R2 from Rails app从 Rails 应用程序连接到 Windows SQL Server 2008 R2
【发布时间】:2017-01-27 07:00:52
【问题描述】:

我的 Rails 4.2.1 应用程序必须连接到 Microsoft SQL 2008 R2 数据库。我正在使用tiny_tds gem 版本 1.0.4。 FreeTDS v1.00.15 安装在运行 Ubuntu 14.04 的生产服务器上。

我在每个循环中运行查询,但无法完成循环,进程在完成前崩溃。 我尝试使用 tiny_tds 选项但没有成功。

这是我用来获取 tiny_tds 客户端的代码(检查 tds_versiontimeout 选项):

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:发送数据包 0000 12 01 00 ce 00 00 00 00-16 03 01 00 86 10 00 00 |........ ........| 0010 82 00 80 6e d9 e2 直流 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 |}<.. ..... b8 b1-c6 ba b4 c3 f0 ......g. c7 e2 ca b2-95 b9 bb e7 cb .s... b5 eb b0 f3 fc a6 ....s. dc e8 e4 .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:将查询状态从 IDLE 更改为 DEAD util.c:322:tdserror(0x80b75e0, 0xa04ca80, 20017, 0) dblib.c:7947:dbperror(0xae62780, 20017, 0) dblib.c:8015:dbperror: 使用 msgno = 20017 调用 dblib_err_handler;味精->味精文本= “来自服务器的意外 EOF (192.168.32.105:1433)” dblib.c:5777:dbgetuserdata(0xae62780) dblib.c:8037:dbperror: dblib_err_handler for msgno = 20017; msg->msgtext = "意外的 EOF 从服务器 (192.168.32.105:1433)" -- 返回 2 (INT_CANCEL) util.c:352:tdserror: 客户端库返回 TDS_INT_CANCEL(2) util.c:375:tdserror: 返回 TDS_INT_CANCEL(2) util.c:375:tdserror: 返回 TDS_INT_CANCEL(2) tls.c:942:handshake failed login.c:530:登录数据包被拒绝 util.c:322:tdserror(0x80b75e0, 0xa04ca80, 20002, 0) dblib.c:7947:dbperror(0xae62780, 20002, 0) dblib.c:8015:dbperror:使用 msgno = 20002 调用 dblib_err_handler; msg->msgtext = "自适应服务器连接失败"

这是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?你应该可以运行tsql -C 来查看。如果您使用的是 0.91,则需要使用 tds_version: '7.2'; 7.3 要求 0.95 或更高。
  • @FlipperPA 看来我正在使用 FreeTDS 0.91(从 Ubuntu 数据包管理器安装)。使用tds_version: '7.2',我得到相同的Unexpected EOF from server 错误。
  • 如果您使用的是 0.91,则使用 tds_version: '7.2' 可以省去您的麻烦(尤其是在处理 Unicode 时)。但回到手头的问题:你能联系tsql吗?例如,TDSVER=7.2 tsql -H 192.168.32.105 -p 1433 -U your_username?如果这不起作用,您可以telnet 192.168.32.105 1433 并连接吗?此外,如果您的密码中包含非字母字符,您可能需要尝试使用少于 20 个字符的短(ish)字母数字密码。旧版本的 FreeTDS 的用户名和密码最大长度为 25 个字符(但我认为它们增加了 0.91)。
  • @FlipperPA 连接正常,我可以发送查询并获得结果。问题是 FreeTDS 在一些大的 SELECT 查询上崩溃并出现 Unexpected EOF from the server 错误。我正在寻找如何解决这个问题的解决方案。

标签: ruby-on-rails sql-server ruby-on-rails-4 freetds tiny-tds


【解决方案1】:

在您的 FreeTDS 配置中(通常在您的配置中的 /etc/freetds/freetds.conf 中),更改 text size 的值:

text size = 4294967295

这是最大值,IIRC。我相信对于 FreeTDS 0.91,您的默认值可能是 64512。

【讨论】:

    【解决方案2】:

    查看 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-27
      • 1970-01-01
      • 2015-03-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多