13 марта 2008 г.

Проблемы с listener ORA-12535: TNS:operation timed out в Oracle 9i

Одной из причин таких ошибок в часы пик может быть то, что листенер всего-навсего не успевает обработать поступающие запросы на подключение.
Например, когда одновременно запускаются очень много клиентских джобов, которые все в один момент обрушиваются на листенер, листенер успевает обработать только первые поступившие запросы, а остальные падают с ошибкой ORA-12535.

Для борьбы с ними можно попробовать следующие варианты:

1) Параметр INBOUND_CONNECT_TIMEOUT
Можно попробовать установить параметр в файле listener.ora: INBOUND_CONNECT_TIMEOUT_ = 600
Этот параметр задает кол-во секунд, в течение которых должна быть завершена обработка запроса клиента. Если за указанное время листенер не успевает обработать запрос клиента на подключение, он выдает ошибку ORA-12535 и обрывает соединение с клиентом.
Это аналог параметра CONNECT_TIMEOUT, который является устаревшим в версии 9i.

Еще можно попробовать в файле sqlnet.ora добавить параметр:
SQLNET.INBOUND_CONNECT_TIMEOUT = 700

2) Параметр QUEUESIZEС помощью этого параметра можно установить кол-во запросов, которые может обрабатывать листенер одновременно.

LISTENER_TESTDB =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(Host = myhost)(Port = 2483)(QUEUESIZE=200))
)
SID_LIST_LISTENER_TESTDB =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = TESTDB)
(ORACLE_HOME = /testdb/u01/app/oracle/product/9.2.0.8.0)
(SID_NAME = TESTDB)
)
)

3) Поднятие дополнительных листенеров
Установка параметров INBOUND_CONNECT_TIMEOUT и QUEUESIZE не всегда может помочь, так как листенер работает с той же скоростью, а те запросы, которые ожидают подключения к базе, всего-навсего будут дольше удерживаться, пока не рассосется очередь. Но если очередь все-таки не рассосется за указанное время, клиенты опять упадут с ошибкой ORA-12535.

Чтоб решить проблему с производительностью раз и навсегда можно поднять дополнительные листенеры и настроить tns на стороне клиента, чтоб, если не отвечает первый листенер, запрос шел на второй, третий листенеры.

И так, на сервере поднимаем 2 листенера на 2 разных портах 2483 и 2484.
В файле listener.ora прописываем:

LISTENER_TESTDB =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(Host = myhost)(Port = 2484))
)
SID_LIST_LISTENER_TESTDB =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = TESTDB)
(ORACLE_HOME = /testdb/u01/app/oracle/product/9.2.0.8.0)
(SID_NAME = TESTDB)
)
)

LISTENER_TESTDB2 =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(Host = myhost)(Port = 2483))
)
SID_LIST_LISTENER_TESTDB2 =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = TESTDB2)
(ORACLE_HOME = /testdb/u01/app/oracle/product/9.2.0.8.0)
(SID_NAME = TESTDB2)
)
)


Запускаем листенеры:
oracle@myhost $ lsnrctl
LSNRCTL> start LISTENER_TESTDB
LSNRCTL> start LISTENER_TESTDB2

Теперь нужно на стороне клиента прописать в tnsnames.ora:
TESTDB =
(DESCRIPTION =
(ADDRESS_LIST =
(FAILOVER = ON)
(LOAD_BALANCE = ON)
(ADDRESS = (PROTOCOL = TCP)(HOST = myhost)(PORT = 2483))
(ADDRESS = (PROTOCOL = TCP)(HOST = myhost)(PORT = 2484))
)
(CONNECT_DATA = (SERVICE_NAME = TESTDB))
)
Теперь можно в $ORACLE_HOME/network/log посмотреть размеры лог файлов каждого листенера. Они будут расти по мере обработки запросов на подключение.

oracle@myhost $ ls -la *.log

1 коммент.:

sh_yura комментирует...

Добрый день!
Тут (SID_NAME = TESTDB)
Должен быть одинаковый т.к у вас все в одном инстансе.


а у вас 1.(SID_NAME = TESTDB)
2.(SID_NAME = TESTDB2)