Выполнение внешнего файла из БД Oracle с целью получения информации о дисковом пространстве

от автора

Зачастую для тех или иных нужд возникает необходимость выполнить команду OS из pl/sql или даже sql внутри Oracle Database.
Ниже описывается один из способов и его применение в задаче определения доступного дискового пространства.
Предлагаемый способ заключается в использование добавленного в 11.2 функционала «Препроцессинг данных внешних таблиц».

Таким образом нам потребуется создать объекты:

  • Directory — в ней будет располагаться наш скрипт препроцессинга и на неё будет ссылаться таблица
  • external organization table — обращение к которой будет вызывать выполнение скрипта
  • script — собственно сам файл который будет выполнять требуемое нам действие в OS

Пример создания требуемых объектов:

-- directory create or replace directory UTIL_DIR as '/u01' / -- table CREATE TABLE T_OS_COMMAND  (  v_line varchar2(4000)  )  ORGANIZATION external  ( TYPE oracle_loader  DEFAULT DIRECTORY UTIL_DIR  ACCESS PARAMETERS  ( RECORDS DELIMITED BY NEWLINE  preprocessor UTIL_DIR:'os_command.sh'  FIELDS TERMINATED BY "\n" LDRTRIM  )  location ( 'os_command.sh')  ) / 

Лучше всего иметь отдельную directory для наших целей ввиду того что нам потребуется одновременно и права на запись в ней и права на выполнение, а такую комбинацию лучше никому не выдавать.
Оптимальное использование это создание пакета (хоть и в схеме SYS) в спецификации которого описаны процедуры, которым необходимо обращение к OS, а саму реализацию оставить внутри пакета и никого к ней не подпускать.
Далее подразумевается что права на чтение, запись и выполнение к UTIL_DIR у нас имеются, также как и права на select из T_OS_COMMAND.

Для создания файла который будет выполнятся достаточно выполнить в OS (да придется хоть раз выполнить действия в OS прибегнув к более тривиальным методам — например ssh):

$touch /u01/os_command.sh $chmod ug+x /u01/os_command.sh 

Данные команды должны быть выполнены от пользователя (либо члена группы) от которых запускается экземпляр БД.

Всё готово к использованию. Для выполнения произвольной команды OS нам следует записать её в файл os_command.sh и обратиться с запросом к таблице T_OS_COMMAND.

declare   F1 UTL_FILE.FILE_TYPE; begin   F1 := UTL_FILE.FOPEN('UTIL_DIR','os_command.sh','W', 4048);    UTL_FILE.PUT_LINE (file => F1, buffer => '#!/bin/sh');   UTL_FILE.PUT_LINE (file => F1, buffer => 'export LANG=en_US.UTF-8');   UTL_FILE.PUT_LINE (file => F1, buffer => 'export PATH=$PATH:/bin');   UTL_FILE.PUT_LINE (file => F1, buffer => 'df -k | grep /');   UTL_FILE.fclose (file => F1); end; / 

Теперь для получения результата работы нашего скрипт достаточно выполнить запрос к таблице T_OS_COMMAND

При выполнении в OS команды df -k | grep / мы получим

/dev/sda2             32414672  14870956  15870548  49% / /dev/sda1               124427     18001    100002  16% /boot tmpfs                  8219820    184808   8035012   3% /dev/shm /dev/sdb2            961432104 606013444 306580660  67% /u02 

При выполнении запроса SELECT * FROM T_OS_COMMAND

V_LINE
/dev/sda2             32414672  14871076  15870428  49% /
/dev/sda1               124427     18001    100002  16% /boot
tmpfs                  8219820    184808   8035012   3% /dev/shm
/dev/sdb2            961432104 606013444 306580660  67% /u02

Далее можно приступать к реализации непосредственно методов которым необходим вызов команд OS.

Примером такой реализации может выступать пакет P_SYS_UTILITY. Пожелания по его развитию и участие в оном приветствуются.

Спецификация пакета

create or replace package P_SYS_UTILITY is    -- Author  : ALEXEY   -- Created : 23.08.2013   -- Purpose : Get system info (*nix versions)  /* Get on file or folder name its device or ASM group and used/free space on it   * raw devices not supported */ procedure Get_Disk_Usage ( p_file_name  in varchar2, -- file name (also accept only path)                            o_mount_dev  out nocopy varchar2, -- device or ASM group                            o_used_space out number, -- used space                            o_free_space out number); -- free space   -- Collect space USAGE in BD -- Recomended evry day schedule run procedure Collect_Usage;  -- Get Forecast on space usage -- Recomended base from 10 collects function Get_Forecast ( pDT         in date, -- date for forecast                         pBASE       in integer default 188, -- base days in calculate forecast                         pTYPE_F     in varchar2 default 'SLOPE', -- type forecast: SLOPE | AVG                         pTABLESPACE in varchar2 default null, -- tablespace ( null = all )                         pOWNER      in varchar2 default null, -- user ( null = all )                         pTYPE       in varchar2 default null )  -- segment type ( null = all ), allow like          return number; -- size in bytes on date pDT  -- Get score of space usage and availability -- Can be used in external monitoring tool : Nagios, etc function Get_Space_Status ( pFOREDAYS   in number default 60,  -- days after that                             pFREE_PRCNT in number default 25 ) -- free cpace greater than          return number; -- 0 - Space free enough .. 100 - not enough free space  end P_SYS_UTILITY; 

Метод Get_Disk_Usage

p_file_name — имя файла или папки для месторасположения которого(-ой) будет произведен расчет. Позволяет передавать имена относящиеся к ASM disk groups.
o_mount_dev — имя устройства в системе на которое смонтировано указанное месторасположение, определяется из вывода команды df. Для ASM будет возвращено имя disk group.
o_used_space — количество байт занятых на устройстве/diskgroup
o_free_space — количество байт доступных на устройстве/diskgroup
Осуществляет вызов df с передачей в качестве параметра имени файла, или обращение к v$asm_diskgroup в случае если имя файла начинается на "+".

Метод Collect_Usage

Осуществляет сбор информации об использовании пространства внутри БД. Группирует по табличным пространствам, владельцам и типам сегментов. Не берет в учет сегменты типа undo и temp. Сохраняет полученную информацию в таблицу T_SPACE_USAGE. Рекомендуется к ежедневному выполнению.

Структура T_SPACE_USAGE

create table T_SPACE_USAGE (   dt$ date,   owner$ varchar2(30),   tablespace$ varchar2(30),   type$ varchar2(18),   bytes$ number,   blocks$ number); create index INDX_T_SPACE_USAGE_DT on T_SPACE_USAGE (dt$); comment on table T_SPACE_USAGE is 'Store archive data of usage space in RDBMS'; comment on column T_SPACE_USAGE.DT$ is 'Date collect space usage'; comment on column T_SPACE_USAGE.OWNER$ is 'Segment owner - user in BD'; comment on column T_SPACE_USAGE.TABLESPACE$ is 'Name of tablespace in BD'; comment on column T_SPACE_USAGE.TYPE$ is 'Segment type'; comment on column T_SPACE_USAGE.BYTES$ is 'Size in bytes'; comment on column T_SPACE_USAGE.BLOCKS$ is 'Size in blocks'; 

Метод Get_Forecast

pDT — дата на которую надо спрогнозировать размер
pBASE — количество дней, данные за которые войдут в базу по которой будет строиться прогноз
pTYPE_F — способ прогнозирования — либо на основе ковариация (генеральной) совокупности, либо на основе среднего изменения
pTABLESPACE — табличное пространство по которому производится прогнозирование, если не передавать то по всем
pOWNER — владелец схемы по которому производится прогнозирование, если не передавать то по всем
pTYPE — тип сегментов данных по которому производится прогнозирование, если не передавать то по всем
Выполняет расчет прогнозируемого занимаемого места сегментов согласно указанным критериям. Результат в байтах.

Метод Get_Space_Status

pFOREDAYS — количество дней для прогноза
pFREE_PRCNT — процент доступного пространства (считается от прогнозируемого занятого)
Производит оценку по шкале от 0 до 100 доступного для роста БД пространства.

Также учитывает ограничения на рост файлов внутри БД.

Простой результат позволяет интегрировать вызов функции в системы мониторинга с настройкой порогов критичности.

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

ссылка на оригинал статьи http://habrahabr.ru/post/191870/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *