我有一个Linked服务器,它使用来自11g Oracle 的OraOLEDB.Oracle提供程序,并且工作了一段时间。但是,最近建立了一个Oracle 12c异构连接。这导致11g客户端无法连接到12c实例,因为<#>路径变量使用12c TNSname而不是11g 。
路径变量已经更正,11g客户端现在可以使用TNSPing或SQLPlus连接到Oracle实例,但是当试图使用链接服务器时,server将进入抢占模式,等待类型 PREEMPTIVE _COM_COCREATEINSTANCE。链接的服务器查询不会连接到Oracle或错误退出,并导致server不允许任何新连接。他们将被困在尝试使用wait PREEMPTIVE_OS_GETPROCADDRESS登录,并等待链接服务器查询完成以便登录。
对于为什么Linked服务器会导致长时间抢占COM_COCREATEINSTANCE等待有任何想法吗?
发布于 2019-08-26 13:57:02
这些调用都是加载Oracle OleDb提供程序的一部分。不确定它们为什么会阻塞而不是失败,但这表明您的Oracle客户端设置仍然不正确。
11g OraOLEDB.Oracle提供程序不仅需要访问正确的TNSNAMES.ORA文件。它还需要加载正确的OCI.DLL,这是通过路径完成的。
OraOLEDB.Oracle和所有OleDB提供程序一样,是一个COM组件。因此,它加载了对CoCreateInstance()的调用。OleDb提供程序依次调用LoadLibrary()来查找OCI.DLL,然后(在正常的DLL加载过程中)调用GetProcAddress()来查找预期的DLL入口点函数。每当Server调用这些Win32函数之一时,它都会输入一个“PREEMPTIVE_.”等着。
因此,您需要确保LoadLibrary函数调用找到并加载正确的OCI.DLL副本,通常是通过设置系统路径来实现这一点,以便包含所需OCI.DLL的文件夹首先出现,然后重新启动。
您可以通过运行以下操作来验证正在从提升的powershell提示符加载预期的OleDB提供程序
PS C:\WINDOWS\system32> ls hklm:\SOFTWARE\Classes\OraOLEDB.Oracle若要发现OleDb提供程序的CLSID,然后查找它
PS C:\WINDOWS\system32> ls "hklm:\SOFTWARE\Classes\CLSID\{3F63C36E-51A3-11D2-BB7D-00C04FA30080}"
Hive: HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{3F63C36E-51A3-11D2-BB7D-00C04FA30080}
Name Property
---- --------
ExtendedErrors (default) : Extended Error Lookup Service
InprocServer32 (default) : c:\oracle\odac64\bin\OraOLEDB12.dll
ThreadingModel : Both
OLE DB Provider (default) : Oracle Provider for OLE DB
ProgID (default) : OraOLEDB.Oracle.1
TypeLib (default) : {0BB9AFD1-51A1-11D2-BB7D-00C04FA30080}
VersionIndependentProgID (default) : OraOLEDB.Oracle完整的进程是ProgId `OraOLEDB.Oracle‘被解析为CLSID。CLISD被解析为.dll (InProcServer32)。.DLL被加载,然后运行LoadLibrary来加载oci.dll。该链中的任何链接都可能断开,包括找到错误"bitness“的OCI.DLL副本。CoCreateInstance是比特感知的,但LoadLibrary不是。
您还可以在powershell中测试连接性。首先,确保您处于将"bitness“与Server匹配的进程中。
PS C:\WINDOWS\system32> [system.environment]::Is64BitProcess然后
PS C:\WINDOWS\system32> $con= new-object system.data.oledb.oledbconnection
PS C:\WINDOWS\system32> $con.connectionstring="provider=OraOLEDB.Oracle;data source=//server/xe;user id=xxx;password=xxx"
PS C:\WINDOWS\system32> $con.Open()https://dba.stackexchange.com/questions/246266
复制相似问题