【问题标题】:Sporadic semaphore timeout using SQL Server 2014 and pyodbc使用 SQL Server 2014 和 pyodbc 的零星信号量超时
【发布时间】:2019-05-16 07:22:07
【问题描述】:

我在插入 SQL Server 时遇到了这个奇怪的信号量超时问题。下面是可以重现问题的简短 sn-p 代码。

运行相同代码库的同事都没有数据库存在问题。我们还有一个应用服务器,可以在几个小时内保持与数据库的连接而不会出现问题。在我的笔记本电脑上运行的不同之处在于:1)我有最新的戴尔 Precision 5530,这与我的同事不同; 2) 我使用的是 Anaconda/Python 3.7/pyodbc 4.0.26/Windows 10 的最新版本,而我的同事使用的是 python 3.5/3.6/Windows 7&Linux。谷歌搜索建议我尝试更新我尝试过的网络适配器驱动程序并且使用最新的驱动程序。

有人遇到过类似的问题吗?

[编辑 1] 感谢以下建议,我已更新到更新的驱动程序,但出现了不同的错误。

import time
import pyodbc

cxn = pyodbc.connect('DSN=db;DATABASE=db;Uid=user;Pwd=password', autocommit=True)

def insert(cxn):
    ids = [(i, ) for i in range(100000)]
    cur = cxn.cursor()
    cur.fast_executemany = True
    cur.execute('create table #tmp (unique_id int)')
    # cur.commit()
    print(1)
    cur.executemany('insert into #tmp values (?)', ids)
    # cur.commit()
    print(2)
    cur.execute('create unique index tmp_pk on #tmp (unique_id)')
    # cur.commit()
    print(3)
    cur.execute('select * from #tmp')
    print(4)
    cur.execute('drop table #tmp')

for i in range(1000):
    print('loop {} {}'.format(i, time.time()))
    insert(cxn)
    time.sleep(60)

在 ipython 中多次迭代后:

loop 6 1557992375.617378
1
---------------------------------------------------------------------------
OperationalError                          Traceback (most recent call last)
<ipython-input-1-8ceea4a06017> in <module>
     23 for i in range(1000):
     24         print('loop {} {}'.format(i, time.time()))
---> 25         insert(cxn)
     26         time.sleep(60)

<ipython-input-1-8ceea4a06017> in insert(cxn)
     11         # cur.commit()
     12         print(1)
---> 13         cur.executemany('insert into #tmp values (?)', ids)
     14         # cur.commit()
     15         print(2)

OperationalError: ('08S01', '[08S01] [Microsoft][ODBC Driver 17 for SQL Server]TCP Provider: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.\r\n (10060) (SQLExecute); [08S01] [Microsoft][ODBC Driver 17 for SQL Server]Communication link failure (10060)')

错误是:

[08S01] [Microsoft][ODBC Driver 17 for SQL Server] TCP 提供程序:

连接尝试失败,因为连接的一方在一段时间后没有正确响应,或者连接的主机没有响应,建立连接失败。

(10060) (SQL 执行); [08S01] [Microsoft][ODBC Driver 17 for SQL Server]通信链路故障 (10060)')

【问题讨论】:

  • 您也使用了错误的驱动程序。您使用的是deprecated native client 而不是the ODBC driverPython examples in the docs 使用 ODBC 驱动程序
  • 您可以在[这里]找到最新版本的 ODBC 驱动程序(当前为at v 17。当前版本为 17。连接字符串应如下所示:'DRIVER={ODBC Driver 17 for SQL Server};SERVER=server;DATABASE=database;UID=username;PWD=password
  • facepalm 我没有意识到这一点。刚刚安装了v17。会让你知道它是怎么回事。谢谢!

标签: sql-server pyodbc


【解决方案1】:

这看起来像一个客户端错误,但不要指望修复。原生客户端is deprecated

重要

SQL Server Native Client (SQLNCLI) 仍然被弃用,不建议将其用于新的开发工作。

Microsoft 推荐 ODBC 已经有相当长的一段时间了,并将大部分精力放在了那里。这是可以理解的,因为这是唯一可以在 Linux 上运行的东西。

SQL Server 文档站点包含有关Python 的完整部分,其中包含pyodbcpymssql 的示例。正如他们解释的那样:

但是,Microsoft 将其测试工作和信心放在了 pyodbc 驱动程序上。

您可以找到适用于 Windows、MacOS 和各种 Linux 发行版的 ODBC 驱动程序here

pyodbc 的示例很简单,不需要 DSN:

import pyodbc 
# Some other example server values are
# server = 'localhost\sqlexpress' # for a named instance
# server = 'myserver,port' # to specify an alternate port
server = 'tcp:myserver.database.windows.net' 
database = 'mydb' 
username = 'myusername' 
password = 'mypassword' 
cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER='+server+';DATABASE='+database+';UID='+username+';PWD='+ password)
cursor = cnxn.cursor()

【讨论】:

  • 好的,ODBC v17 驱动程序没有修复它。我已经用新错误更新了上述问题。
  • 在我的代码库中,它似乎总是在插入到类似于上面的 tmp 表时失败,所以我怀疑它是否真的是一个连接问题。我还有一个活动的 SQL Server Management Studio 正在运行而不会退出
  • @swmfg 这完全是一个不同的错误。它抱怨连接失败。但是,当您调用 connect 时,应该会出现此错误,而不是过一会儿。顺便说一句,你在哪里关闭光标?您的测试在同一连接上创建了 100 个 Million 游标而不关闭它们。 SQL Server 的活动监视器和日志显示什么?
  • 我的印象是游标超出范围时会自行关闭,但在我的代码中,我将游标包装在 with 上下文中,我遇到了这个问题。让我试试上面我明确关闭光标的地方。
  • @swmfg 当我尝试连接到没有 DSN 的远程数据库时,我无法重现任何问题。我也注意到了time.sleep(),这意味着连接尝试不是在一个紧密的循环中进行的。您是否尝试过使用 SERVER 而不是 DSN 进行连接?数据源可能包含影响连接的设置
猜你喜欢
  • 2017-04-12
  • 1970-01-01
  • 1970-01-01
  • 2021-10-08
  • 1970-01-01
  • 2020-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多