company_banner
15 февраля в 15:19

Zabbix-мониторинг данных в БД Oracle без unixODBC

Была поставлена задача: реализовать мониторинг БД Oracle средствами Zabbix, а именно — отслеживать параметры табличных пространств на определенном инстансе. Раз задача поставлена, значит делаем. Как известно, Zabbix предоставляет возможность через предопределенный тип данных осуществлять запросы к базам данным и получать результат запроса. На официальном сайте разработчиков Zabbix есть очень хорошая документация по настройке ODBC-мониторинга.

image

У нас сервер Zabbix 3.0.4 под управлением Centos 7. Ранее ODBC мониторинг не был настроен, а следовательно, нужно открывать инструкции и начинать установку и настройку.

Согласно инструкции с официального сайта Zabbix был установлен пакет unixODBC. Так как UnixODBC-драйвер для Oracle триальный, а бюджет под эту задачу не выделяли, было принято решение — искать другой способ. Перелопатив кучу сайтов с инструкциями установки клиента Oracle, были скачаны с сайта oracle.com пакеты:      

oracle-instantclient11.2-basic-11.2.0.3.0-1.x86_64.rpm
oracle-instantclient11.2-sqlplus-11.2.0.3.0-1.x86_64.rpm
oracle-instantclient11.2-devel-11.2.0.3.0-1.x86_64.rpm
oracle-instantclient11.2-odbc-11.2.0.3.0-1.x86_64.rpm

После того, как все эти пакеты были установлены, осталось только произвести настройки клиента и unixODBC. В результате все настройки были произведены и осталось только протестировать, что все работает.

Перелогиниваемся под пользователем zabbix и выполняем команду isql, согласно инструкции.

[user@serverZabbix]$ isql -v CMSAHI username/password


Все ок. Пробуем получить тот же результат из веб Zabbix. После настройки элемента данных «Мониторинг БД» ждем результата. Но не тут-то было. Элемент данных перешел в статус «Не поддерживается». Получаем ошибку: Cannot connect to ODBC DSN:[SQL_ERROR]:[01000][0][[unixODBC][Driver Manager]Can't open lib '/usr/lib/oracle/11.2/client64/lib/libsqora.so.11.1': file not found]|.

Странная ошибка, тем более, что указанный файл по указанному пути есть.


Начался процесс поиска причины и попытки исправить ошибку. После нескольких дней поиска, перепробовав кучу советов, найденных в интернете, набрёл на тикет в баг-трекере Zabbix. По описанию проблемы – это как раз наша проблема. Что же делать? Тикет открыт, баг найден и в последующих версиях Zabbix, а следовательно, если причина нашей ошибки именно этот баг, настроить мониторинг не получится. Ну не ставить же свежевышедшую версию Zabbix ради решения одной задачи.

В голову пришла мысль: а что, если для подключения к БД использовать не unixODBC а SqlPlus, который был установлен вместе с пакетом oracle-instantclient11.2-sqlplus-11.2.0.3.0-1.x86_64.rpm. Исходя из этой идеи, необходимо настроить клиент oracle для подключения.

Клиент Oracle был установлен в /usr/lib/oracle/11.2/client64. Первое, что нужно сделать – это создать файл tnsnames.ora и заполнить его данными для подключения к БД oracle. Для этого нужно создать папку для хранения этого файла:

sudo mkdir /usr/lib/oracle/11.2/client64/network/admin –p

В созданной директории нужно создать файл с именем tnsnames.ora и заполнить его. Обязательно нужно проверить, чтобы у всех созданных директорий и самого файла были права доступа на чтение для пользователя zabbix.

Далее, нужно создать скрипт для подключения к БД и выполнения запросов. Ниже пример скрипта для выполнения простых селектов:

#!/bin/sh
## Для корректной работы нужно задать переменные окружения ниже
export ORACLE_HOME=/usr/lib/oracle/11.2/client64
export PATH=$PATH:$ORACLE_HOME/bin
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:/usr/lib64:/usr/lib:$ORACLE_HOME/bin
export TNS_ADMIN=$ORACLE_HOME/network/admin
## Директория для хранения sql – файлов. Созданная предварительно.
## Обязательно убедиться, что пользователю zabbix выданы права доступа на запись и чтение
scriptLocation=/etc/zabbix/SqlScripts
## Тут задается абсолютный путь и название создаваемого файла с выполняемым запросом
## в качестве первого параметра скрипта предполагается передавать какую-то уникальную ## строку, для идентификации файла с запросом
sqlFile=$scriptLocation/sqlScript_"$1".sql
## Записываем выполняемый запрос в файл
echo "$2" > sqlFile;
## Собственно, ниже подключаемся к БД и выполняем запрос из ранее сохраненного файла.
## Логин и пароль открытые, не хорошо. 
username="$3"
password="$4"
tnsname="$5"
var=$($ORACLE_HOME/bin/sqlplus -s $username/$password@$tnsname < $sqlFile)
## Получаем результат запроса из полученной выше строки и возвращаем результат.
echo $var | cut -f3 -d " "

Скрипт необходимо поместить в папку /etc/zabbix/externalscripts – папка для хранения скриптов внешних проверок (см настройки zabbix_server.conf строка ExternalScripts=/etc/zabbix/externalscripts). Также скрипту необходимо выдать права доступа на чтение и выполнение пользователю zabbix. Скрипт готов. Настраиваем элемент данных «Внешняя проверка» в веб-интерфейсе Zabbix как на скрине ниже.


Созданный ранее скрипт принимает сл. параметры:

  1. Идентификатор файла с запросом (строка)
  2. Простой запрос (строка)
  3. логин для подключения к БД (строка)
  4. Пароль, для подключения к БД (строка)
  5. TNS БД, к которой хотим подключиться (строка)

На скрине выше поле «Ключ» заполнено следующим образом:

getOracleSelect.sh["TestSelect","select count(*) from testTable;","username","password","CMSAHI"]

где «TestSelect» – строковый идентификатор, для формирования sql-файла;
      «select count(*) from testTable;» – сам запрос.
      «username» и «password» – данные подключения к базе
      «tnsname» – название базы (см tnsnames.ora)


! ВАЖНО! Запрос должен возвращать значение только одной колонки результирующей таблицы, если ожидается получить численное или текстовое значение результата выборки.

После того, как элемент создан, если все настроено верно, веб-интерфейс Zabbix отобразит результат выполнения запроса.

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

Для получения параметров занятого табличного пространства использован скрипт ниже:

SELECT round((totalspace — freespace) * 100 / decode(maxspace, 0, totalspace, maxspace), 2) "%USED" 
  FROM (SELECT tablespace_name, SUM (bytes) / (1024*1024*1024) totalspace, Sum(maxbytes)/ 1024/1024/1024 maxspace
           FROM dba_data_files
         GROUP BY tablespace_name) a, 
       (SELECT tablespace_name, SUM (Bytes) / (1024*1024*1024) freespace
          FROM dba_free_space
         GROUP BY tablespace_name) b
 WHERE A.TABLESPACE_NAME = B.TABLESPACE_NAME (+)
   AND A.TABLESPACE_NAME = 'TAB_SPACE1';

Так как требуется мониторить всего несколько табличных пространств, под каждое был создан свой sql-файл. Для решения поставленной задачи, скрипт получения данных из бд был изменен. Ниже сам скрипт:

#!/bin/sh
export ORACLE_HOME=/usr/lib/oracle/11.2/client64
export PATH=$PATH:$ORACLE_HOME/bin
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:/usr/lib64:/usr/lib:$ORACLE_HOME/bin
export TNS_ADMIN=$ORACLE_HOME/network/admin
scriptLocation=/etc/zabbix/SqlScripts
sqlFile=$scriptLocation/getPUsedTableSpace_"$1".sql
username="$2"
password="$3"
tnsname="$4"
var=$($ORACLE_HOME/bin/sqlplus -s $username/$password@$tnsname < $sqlFile)
echo $var | cut -f3 -d " "

Ключ для элемента данных, соответственно, выглядит так:

getOracleSelect.sh["TAB_SPACE1","username","password","CMSAHI"]

где 'TAB_SPACE1' — наименование табличного пространства.


Как видно из скрина выше, веб-интерфейс Zabbix получает результаты выполнения запроса и отображает процентное значение использованного табличного пространства.

Остается только настроить триггеры и действия оповещений.

Если кому-то поможет данный способ, буду рад. Если у кого-то будут идеи по модернизации скриптов и самого подхода, минуя unixODBC, пишите.
Автор: @Talik0507
Похожие публикации

Комментарии (23)

  • 0
    Получаем ошибку: Cannot connect to ODBC DSN:[SQL_ERROR]:[01000][0][[unixODBC][Driver Manager]Can't open lib '/usr/lib/oracle/11.2/client64/lib/libsqora.so.11.1': file not found]|.

    Что самое интересное, дальше по тексту есть и решение:
    export ORACLE_HOME=/usr/lib/oracle/11.2/client64
    export LD_LIBRARY_PATH=$ORACLE_HOME/lib:/usr/lib64:/usr/lib:$ORACLE_HOME/bin
    

    Только применить его нужно не в скрипте, а перед стартом Заббикса. Например, в systemd-шном service файле:
    [Unit]
     Description=Zabbix Server Daemon
     After=syslog.target network.target
    
    [Service]
     Type=forking
    
     Environment=ORACLE_HOME=...
     Environment=LD_LIBRARY_PATH=...
     Environment=TNS_ADMIN=/opt/oracle
    
     ExecStart=/usr/sbin/zabbix_server
     ExecReload=/usr/sbin/zabbix_server -R config_cache_reload
     PIDFile=/tmp/zabbix_server.pid
    
     User=zabbix
     Group=zabbix
    
    [Install]
     WantedBy=multi-user.target
    
    
    (пример из «живого» конфига)
    • 0
      Пробовали этот способ, Ошибка оставалась.
      • 0
        Возможно поможет
        # echo /usr/lib/oracle/12.1/client64/lib >> /etc/ld.so.conf.d/Oracle12.conf
        после чего настраиваем привязку динамических ссылок при помощи ldconfig
        # ldconfig

        Это правда для клиента, но думаю ход мысли понятен
        • 0
          Спасибо, попробую на клоне сервака. Надеюсь, что-то сработает.
          • 0
            Не мое
            недавно просто статья попадалась
            не сочтите за рекламу
            но оставлю здесь ссылку
            https://www.opennet.ru/tips/2996_php_oracle_centos.shtml
            • 0
              спасибо, поэксперементирую.
          • 0
            https://habrahabr.ru/post/226365/
            Поймите суть проблемы, тестите через isql -v и из под пользователя zabbix
            • 0

              Если вы внимательно читали статью, то, наверняка заметили, что так и тратили и все работало. Проблемы начинались при запросах сервера.

              • 0
                Вопрос так Вам удалось настроить zabbix + unixODBC? И давно unixODBC для Oracle платный?
                • 0

                  Если честно, то пока забил на это. Работает по указанной схеме. Не часто приходится мониторить бд. А текущей реализации хватает.

                • 0

                  Но настроен мониторинг через unixODBC postgres и mysql.

                  • 0
                    Ну в комментариях решение указали, нужно просто при старте заббикса сервера передать ему переменные окружения как у Вас в скрипте:
                    export ORACLE_HOME=/usr/lib/oracle/11.2/client64
                    export PATH=$PATH:$ORACLE_HOME/bin
                    export LD_LIBRARY_PATH=$ORACLE_HOME/lib:/usr/lib64:/usr/lib:$ORACLE_HOME/bin
                    export TNS_ADMIN=$ORACLE_HOME/network/admin 
                    


                    mcleod095 дал совет.
                    Просто на продакшене проверенно, правда с zabbix 2.8 — облегчает жизнь в разы, так как можно нормальные запросы по длине передавать и макросы и так далее, гораздо удобнее чем через скриптом.
                    • 0
                      Недавно как раз переносил мониторинг на новые сервера и вообщем немного из проверенного.
                      Можно переменные для оракла прописать и в systemd файл а можно и в /etc/sysconfig/zabbix-server (хотя это больше для редхат подобных систем). Если прописывать /etc/sysconfig/zabbix-server то надо прописывать вот так
                      ORACLE_HOME=/usr/lib/oracle/11.2/client64/
                      TNS_ADMIN=/etc
                      NLS_LANG=American_America.AL32UTF8
                      export ORACLE_HOME
                      export TNS_ADMIN
                      export NLS_LANG

                      если прописать
                      export ORACLE_HOME=/usr/lib/oracle/11.2/client64/
                      то не видит их zabbix_server
    • +1
      Лучше конечно так не делать.
      создаете каталог /etc/systemd/system/zabbix-server.service.d
      и там уже файл env.conf
      в который включаете
      [Service]
      Environment=ORACLE_HOME=…
      Environment=LD_LIBRARY_PATH=…
      Environment=TNS_ADMIN=/opt/oracle

      Так при обновлении файла запуска не потеряются изменения
  • 0

    Orabbix http://www.smartmarmot.com/wiki/index.php?title=Orabbix не пробовали использовать для мониторинга?

    • 0
      Нет, не пробовали. Читал как-то описание, но, видимо упустил момент, где orabix позволял выполнять произвольные скрипты. На сколько я понял, плагин призван мониторить характеристики самого инстанса. Надо будет перечитать инструкцию, спасибо.
      • 0
        Я когда-то тоже задался вопросом мониторинга БД в Zabbix. Пробовал Orabbix — не понравилось.
        Решил написать свой велосипед. Цели написания собственного плагина: удобство конфигурации, мониторинг любых видов БД.
        Если Вам интересно, то можете посмотреть мой репозиторий на GitHub. Если будут предложения по улучшению — буду рад включить их в будущие версии.
        • 0
          Спасибо, обязательно ознакомлюсь.
  • 0

    Спасибо, обязательно ознакомлюсь.

  • 0
    Я использовал для мониторинга Pyora.
    На питоне, с использованием библиотеки cx_Oracle.
    Скрипт легко дорабатывается под свои нужды.
    Для коннекта используется стандартный клиент Oracle.
    • 0

      Спасибо, буду знать о еще одной возможности решить вопросы мониторинга баз.

      • 0
        Способ то хороший, но шибко умный — создаётся множество проверок и на каждую итерацию отдельный коннект к базе.
        Вот думаю, как его красиво переделать на zabbix trapper.
  • 0
    Таки допилил проверку параметров базы через zabbix trapper.
    GitHub
    Может кому сгодится.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Самое читаемое Администрирование