пятница, 28 декабря 2012 г.

Настройка Oracle Linked server и параметр «Allow in process»


В этой стать не будет описан сам процесс настройки связанного сервера к СУБД Oracle  будет немного описана проблема, которая может возникнуть с данным связанным сервером и с параметром "Allow in Process".


После установки провайдера, многие разработчики\ администраторы включают параметр «Allow in process»



О параметре, данный параметр определяет, как работает провайдер Oracle: внутри процесса SQL server или вне его. Если снаружи, то это значит, что провайдер работает не влияя на работу sql server, если произошла какая-то ошибка, то она не затронет процесс ms sql server. А вот если внутри, то это  значит, если произошла ошибка в провайдере, то это ошибка будет принадлежать и процессу sql server-у.

После этого создают запросы, с использованием данного параметра, ссылаясь на то, что без данного параметра запросы не работают, и не понимая в суть проблемы, почему они не работают.

К примеру, когда показывал данную проблему, сделал несколько запроса:
---1 запрос

SELECT *

  FROM OPENQUERY

      (ORALink,

            'SELECT * FROM DWH.DEALCLASS');

go

--2 запрос

SELECT *

  FROM OPENQUERY

      (ORALink,

            'SELECT UK

            ,SRC_CCODE,classtype_ccode,

            class_ccode,name,

            validfrom,validto,

         FROM DWH.DEALCLASS');

go

--3 запрос

SELECT *

  FROM OPENQUERY

      (ORALink,

            'SELECT TO_CHAR(UK)

            ,to_char(SRC_CCODE),to_char(classtype_ccode),

            to_char(class_ccode),to_char(name),

            to_char(validfrom),to_char(validto),

          FROM DWH.DEALCLASS')

Изначально, в системе, был запрос  №1, который у них работал с включенным параметром «Allow in process», разработчики были рады, т.к не надо в запросе в Oracle-у указывать все поля, думать над типами полей. Кстати, 2-й и 3-й запрос так-же будет работать с данным параметром. Но в итоге у них несколько раз подряд упал сервер в разгар рабочего дня, а это был боевой нагруженный сервер. Начали анализировать, нашли проблему и запрос, проблема была в настройках провайдера Oracle. Убрали галочку, т.е вывели процесс провайдера за процесс sql server-а. Запустили запрос №1 . запрос не отрабатывает, а выдает ошибку:

Msg 7399, Level 16, State 1, Line 1

The OLE DB provider "OraOLEDB.Oracle" for linked server " OraLink" reported an error. Access denied.

Msg 7350, Level 16, State 2, Line 1

Cannot get the column information from OLE DB provider "OraOLEDB.Oracle" for linked server " OraLink ".

Ошибка  не может получить информацию о полях от провайдера, кстати сами поля могут отобразится в том же гриде Management Studio, но без данных.

Выполняем запрос №2, ошибка та же.

И только запрос №3 выполнится без проблем, в чем причина – причина в различных типах данных ms sql server и oracle. Поэтому, еще раз, не надо в запросах использовать символ «*»  и не забываем о совместимости типов данных.

Как это выглядит на практике если параметр включен, а выглядит это не очень хорошо, выливается это в падение процесса ms sql server-а, его полнейшей остановки или зависания, при котором даже не помогает  выделенное административное подключение(DAC).

Что мы увидим в данном случае в дампе sql server-а? А там будет примерно такая картина:

SqlDumpExceptionHandler: Process 127 generated fatal exception c0000005 EXCEPTION_ACCESS_VIOLATION. SQL Server is

terminating this process.

* *******************************************************************************

*

* BEGIN STACK DUMP:

* 12/12/12 12:12:21 spid 112

*

*

* Exception Address = 0000000077EED0E5 Module(UNKNOWN+0000000000000000)

* Exception Code = c0000005 EXCEPTION_ACCESS_VIOLATION

* Access Violation occurred reading address FFFFFFFFFFFFFFFF

* Input Buffer 484 bytes -

* select * from openquery(ORALink,' select * from DB.TABLE

* …………)

PROCESS_NAME: sqlservr.exe

 

ERROR_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%08lx referenced memory at 0x%08lx. The memory could not be %s.

 

EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%08lx referenced memory at 0x%08lx. The memory could not be %s.

 

EXCEPTION_PARAMETER1: 0000000000000000

 

EXCEPTION_PARAMETER2: ffffffffffffffff

 

READ_ADDRESS: ffffffffffffffff

 

FAULTING_THREAD: 0000000000006a00

 

DEFAULT_BUCKET_ID: HEAP_CORRUPTION

 

PRIMARY_PROBLEM_CLASS: HEAP_CORRUPTION

=============================

 

Ниже привожу рекомендации Майкрософт по решению данной проблемы:

1) Нужно отключить свойство «Allow inprocess» для этого провайдера (сделать «out of process»)

2) Включить конфигурацию DCOM:
1. Open Regedit as administrator.
2. Find key
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID\{2206CDB0-19C1-11D1-89E0-00C04FD7A829}.
3. Right click Permissions.
4. click Advanced.
5. click tab Owner.
6. change owner to Administrators.
7. click OK.
8. click Full Control to Administrators.
9. click OK.
10. Start DCOMCNFG.

3) Учетную запись от которой стартует SQL Server добавить в группу “Distributed COM Users” и добавить следующие права rights:
1. Start --> Run --> Dcomcnfg
2. Component services --> My computer --> DCOM config --> MSDAINITIALIZE
3. Right click on MSDAINITIALIZE --> properties -->security
4. Add SQL startup account under "launch and activation permission", "Access permission" and "Configuration permission".
5. Give full rights

В наглядном виде пункты 2-3 приведены в этой статье:
Troubleshooting “Cannot create an instance of OLE DB provider”
http://blogs.msdn.com/b/dataaccesstechnologies/archive/2011/09/28/troubleshooting-cannot-create-an-instance-of-ole-db-provider.aspx

4) Перезагрузить SQL Server (полностью весь сервер)

5) Проверить работу линкованного сервера для Oracle.

Эта инструкция предоставлена на основе следующей статьи:
http://blogs.msdn.com/b/dataaccesstechnologies/archive/2010/08/19/permissions-needed-to-set-up-linked-server-with-out-of-process-provider.aspx

Главное после настройки протестировать, что для линкованного сервера все работает нормально, при ошибках необходимо проанализировать запросы.

Так что вот так. Удачного линкования!

Комментариев нет :

Отправить комментарий