середа, 27 квітня 2016 р.

Работаем с Diagnostic Pack (AWR, ADDM) в Oracle Standard Editions

По умолчанию функция AWR в Oracle SE отключена, потому включим её,=

alter system set control_management_pack_access="DIAGNOSTIC+TUNING" scope=both;

вот и всё, сбор статистики начался автоматически.

просмотреть статистику можем через ASH viewer, такой себе аналог GRID controla? скачать можем здесь,-
https://habrahabr.ru/company/jetinfosystems/blog/245507/

когда нужда отпадёт, отключаем

alter system set control_management_pack_access="NONE" scope=both;


https://iusoltsev.wordpress.com/profile/oracle_tools/


-- Теперь будем собирать snapshot каждые 120 минут и хранить 14400 минут (10 дней)
BEGIN
  DBMS_WORKLOAD_REPOSITORY.modify_snapshot_settings(
    retention => 14400,
    INTERVAL  => 120);
END;
/
-- Соберём snapshot на текущий момент вручную
EXEC DBMS_WORKLOAD_REPOSITORY.create_snapshot;
 
-- Удалим снимки состояния с 20 по 30 включительно
BEGIN
  DBMS_WORKLOAD_REPOSITORY.drop_snapshot_range (
    low_snap_id  => 20,
    high_snap_id => 30);
END;
/

Как разврапить package Oracle (unwpap)

архив в по ссылке

https://sourceforge.net/projects/plsqlunwrapper/

середа, 6 квітня 2016 р.

читаем трасировку (наброски)


=====================
PARSING IN CURSOR #64 len=172 dep=0 uid=33 oct=6 lid=33 tim=4690635760240 hv=4249995639 ad='3f944cd8'
UPDATE EMP SET USER_NAME=:b1,USER_PERM=:b2,USER_PWD=:b3,USER_PWDD=:b4,USER_LANG=:b5,E_TYP=NVL(:b6,1),USER_PWD1=:b7,USER_PWDD1=:b4 WHERE UP = :b9  AND :b10 BETWEEN FD AND TD
END OF STMT

/*Здесь запомнили, что курсор 64 - это update emp*/

PARSE #64:c=0,e=812,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=0,tim=4690635760231
/*Это был хардпарс*/
WAIT #64: nam='SQL*Net message to client' ela= 2 p1=675562835 p2=1 p3=0
WAIT #64: nam='SQL*Net message from client' ela= 685 p1=675562835 p2=1 p3=0
/*отчитались перед приладой и подождали следующей команды*/
/*следующая команда - бинд*/
BINDS #64:
 bind 0: dty=1 mxl=128(60) mal=00 scl=00 pre=00 oacflg=03 oacfl2=10 size=512 offset=0
   bfp=02df9570 bln=128 avl=06 flg=05
   value="pankov"
/*:b1='pankov', и т.д.*/
 bind 1: dty=1 mxl=128(60) mal=00 scl=00 pre=00 oacflg=03 oacfl2=10 size=0 offset=128
   bfp=02df95f0 bln=128 avl=00 flg=01
 bind 2: dty=1 mxl=128(88) mal=00 scl=00 pre=00 oacflg=21 oacfl2=10 size=0 offset=256
   bfp=02df9670 bln=128 avl=88 flg=01 value="JILEBNDJKOFBOKLFCNCINGOKGDKDKJEOMDNGHGNDHOFGDOAJJCNNLAOKMLEILOGOJGKKELAEPLPNBMJANOLKLONN"
 bind 3: dty=12 mxl=07(07) mal=00 scl=00 pre=00 oacflg=01 oacfl2=0 size=0 offset=384
   bfp=02df96f0 bln=07 avl=07 flg=01
   value="9/14/2004 10:59:13"
 bind 4: dty=2 mxl=23(22) mal=00 scl=00 pre=00 oacflg=03 oacfl2=0 size=0 offset=392
   bfp=02df96f8 bln=23 avl=02 flg=01
   value=2
 bind 5: dty=2 mxl=23(22) mal=00 scl=00 pre=00 oacflg=03 oacfl2=0 size=0 offset=416
   bfp=02df9710 bln=23 avl=02 flg=01
   value=1
 bind 6: dty=1 mxl=32(00) mal=00 scl=00 pre=00 oacflg=21 oacfl2=0 size=0 offset=440
   bfp=02df9728 bln=32 avl=00 flg=01
 bind 7: dty=12 mxl=07(07) mal=00 scl=00 pre=00 oacflg=01 oacfl2=0 size=0 offset=472
   bfp=02df9748 bln=07 avl=07 flg=01
   value="9/14/2004 10:59:13"
 bind 8: dty=2 mxl=23(22) mal=00 scl=00 pre=00 oacflg=03 oacfl2=0 size=0 offset=480
   bfp=02df9750 bln=23 avl=03 flg=01
   value=1627
 bind 9: dty=12 mxl=07(07) mal=00 scl=00 pre=00 oacflg=01 oacfl2=0 size=0 offset=504
   bfp=02df9768 bln=07 avl=07 flg=01
   value="9/14/2005 10:59:13"
/*Уфф, отбиндились.*/
/*Раз-два-три-четыре-пять, начинаем исполнять (все время обращаем внимание на номер курсора!):*/
EXEC #64:c=10000,e=1640,p=0,cr=2,cu=1,mis=0,r=1,dep=0,og=3,tim=4690635762805
/*               ^^^^elapsed                ^^обновлена одна строка*/
/* Что касается размерности elapsed и прочих таймов: в 8i - это сотые секунды, 9i - миллисекунды. 10g - не знаю, вероятно, то же что 9i */
WAIT #64: nam='SQL*Net message to client' ela= 2 p1=675562835 p2=1 p3=0
WAIT #64: nam='SQL*Net message from client' ela= 577 p1=675562835 p2=1 p3=0
WAIT #64: nam='SQL*Net message to client' ela= 1 p1=675562835 p2=1 p3=0
WAIT #64: nam='SQL*Net message from client' ela= 1642 p1=675562835 p2=1 p3=0
/*Еще немного пообщались с клиентом, всего на 2+577+1+1642=2222*/
RPC CALL:PROCEDURE APEKS.KK_EMP.SET_CLR(I_USERID IN NUMBER, I_DT IN DATE);
RPC BINDS:
 bind 0: dty=6 bfp=02d2a128 flg=00 avl=03 mxl=22 val=1627
 bind 1: dty=12 bfp=02d2a150 flg=00 avl=08 mxl=00 val="06/09/2005 20:11:10"
===================== 




Находим sid и serial# сессии:

select  s.username
,   s.sid
,   s.serial#
,   s.osuser
,   s.machine
,   s.terminal
,   p.spid
,   last_call_et
,   status
from    V$SESSION s
,   V$PROCESS p
where   s.PADDR = p.ADDR
and s.sid='123';


Включить трассировку:

BEGIN
SYS.DBMS_System.Set_Ev(156, 13, 10046, 12, '');
END;
/

Отключить трассировку сессии:

BEGIN
SYS.DBMS_System.Set_Ev(156, 13, 10046, 0, '');
END;
/

Файлы трассировок находятся:

show parameter dump_dest

или так:


select name, value
 from v$parameter
 where name like '%dump_dest%';

set serveroutput on
exec dbms_output.put_line( scott.get_param( 'user_dump_dest' ) )


В 11g так:

with home
 as
 (select value home
    from v$diag_info
  where name = 'ADR Home'
 )
 select name,
        case when value <> home.home
                 then replace(value,home.home,'$home$')
                        else value
        end value
from v$diag_info, home
/



 select c.value || '/' || d.instance_name || '_ora_' ||
 a.spid || '.trc' ||
 case when e.value is not null then '_'||e.value end trace
 from v$process a, v$session b, v$parameter c, v$instance d, v$parameter e
 where a.addr = b.paddr
 and b.audsid = userenv('sessionid')
 and c.name = 'user_dump_dest'
 and e.name = 'tracefile_identifier'
/


Обработка файлов трассировки:

Обработка файла трассировки выполняется при помощи утилиты tkprof, поставляемой 
в комплекте Oracle Server. Формат вызова команды: 

$tkprof trace_file processed_trace_file explain=username/password sort=exeela fchela 

где

- trace_file - исходный необработанный файл трассировки; 
- processed_trace_file - имя результирующего обработанного файла трассировки; 
- username - имя пользователя, под которым работала трассируемая сессия; 
- password - пароль пользователя. 

Анализ файлов трассировки. 
Анализ статистики работы сессии. 
Выявление проблемных SQL предложений.

Обработанный файл трассировки состоит из последовательно расположенных 
блоков SQL-предложений, выполняемых данной сессией. В конце файла приводится 
суммарная статистика по всем SQL-предложениям, выполнявшимся данной сессией. 
SQL-предложения в файле располагаются в порядке, зависящем от параметра 
sort команды tkprof. Наиболее полезным параметром сортировки является 
elapsed time (общее затраченное время). Наибольшее время обычно занимает 
процедура выполнения (execute) или выборки (fetch) SQL-предложений, 
поэтому используются параметры sort = exeela или sort = fchela соответственно. 


tkprof test1_j000_10411.trc test1_j000_10411.prf explain=user/passw@test1 table=user.tun_plan_table sort=(exeela,fchela)





Трассировка сессии 

Включение/выключение трассировки. Получение и обработка файлов 
Для того чтобы получить файл трассировки заданной сессии необходимо включить 
для нее режим трассировки, подождать необходимое для накопления информации 
время, выключить режим трассировки и обработать полученный файл. 
Иногда может возникнуть необходимость исследования необработанного 
файла трассировки. В этом случае для получения более детальной информации 
о трассируемом процессе рекомендуется включать трассировку через 
Server Manager, используя 12-ый уровень отладки.

Процедура включения / выключения трассировки при помощи SQLPlus

Включение 

Для включения трассировки сессии с параметрами SID и SERIAL# необходимо 
выполнить из SQLPlus следующую последовательность команд: 

SQL>alter system set timed_statistics = true; 
SQL>alter system set max_dump_file_size = unlimited; 
SQL>exec dbms_system.set_sql_trace_in_session( , TRUE); 

Выключение 

Для выключения трассировки сессии с параметрами SID и SERIAL# необходимо 
выполнить из SQLPlus следующую последовательность команд: 


SQL>exec dbms_system.set_sql_trace_in_session( , FALSE); 

Скрипт: ode.sql 




Процедура включения / выключения трассировки при помощи Server Manager

Включение 

Для включения трассировки сессии необходимо определить SPID 
соответствующего ей процесса и выполнить следующую последовательность 
команд: 

SVRMGRL> oradebug setospid 
SVRMGRL> oradebug unlimit 
SVRMGRL> oradebug event 10046 trace name context forever, level 8 

или для более детальной информации в необработанном файле трассировки 
(в том числе вывода bind переменных и oracle events) 

SVRMGRL> oradebug event 10046 trace name context forever, level 12 


Выключение 

Для выключения трассировки сессии необходимо определить SPID 
соответствующего ей процесса и выполнить следующую последовательность 
команд: 

SVRMGRL> oradebug event 10046 trace name context off 

Следует помнить, что остановка трассировки не закрывает созданный файл 
в операционной системе, поэтому, если вы начнете трассировку заново, 
то информация будет добавляться в уже существующий файл. 
При удалении файла трассировки, он не исчезнет до тех пор, пока не будет 
принудительно закрыт или не завершится трассируемая сессия. 
Для принудительного закрытия файла трассировки следует использовать 
следующую команду Server Manager: 

SVRMGRL> oradebug setospid 
SVRMGRL> oradebug close_trace

Файл трассировки создается в каталоге, указанном в параметре базы данных 
background_dump_dest для фоновых процессов или в параметре user_dump_dest 
для пользовательскиx процессов. 

Имя файла формируется по маске _*_.trc, где 

- DBNAME - имя базы данных; 
- SPID - идентификатор процесса в UNIX. 

Имя файла трассировки также можно узнать, выполнив в Server Manager следующую 
последовательность команд: 

SVRMGRL> oradebug setospid 
SVRMGRL> oradebug tracefile_name 

Обработка файла трассировки выполняется при помощи утилиты tkprof, поставляемой 
в комплекте Oracle Server. Формат вызова команды: 

$tkprof \ 
explain=/ sort=exeela fchela 

где

- - исходный необработанный файл трассировки; 
- - имя результирующего обработанного файла 
трассировки; 
- - имя пользователя, под которым работала трассируемая сес-сия; 
- - пароль пользователя. 

Анализ файлов трассировки. Анализ статистики работы сессии. 
Выявление проблемных SQL.предложений 

Обработанный файл трассировки состоит из последовательно расположенных 
блоков SQL-предложений, выполняемых данной сессией. В конце файла приводится 
суммарная статистика по всем SQL-предложениям, выполнявшимся данной сессией. 
SQL-предложения в файле располагаются в порядке, зависящем от параметра 
sort команды tkprof. Наиболее полезным параметром сортировки является 
elapsed time (общее затраченное время). Наибольшее время обычно занимает 
процедура выполнения (execute) или выборки (fetch) SQL-предложений, 
поэтому используются параметры sort = exeela или sort = fchela соответственно. 

При анализе файла трассировки необходимо обращать внимание на следующие 
статистики, сигнализирующие о возможном наличии узких или проблемных мест:

1. Большое общее затраченное время (столбец elapsed). 
Большое затраченное процессорное время (столбец cpu) в данном случае 
означает, что сессия тратит большое количество процессорного времени 
на данную операцию. Возможно проблема в неоптимальном SQL-предложении. 

Относительно маленькое затраченное процессорное время (столбец cpu) 
означает, что сессия большинство времени простаивает, ожидая выполнения 
какого-либо внешнего условия. Необходимо анализировать события ожидания 
сессии. Возможно проблема в настройке базы данных.

Большое время, зарачиваемое на разбор (parse) SQL-предложения 
сигнализирует о проблемах в настройках памяти базы данных. Возможно 
слишком маленький размер shared pool.

2. Большое количество обращений к блокам базы данных (большое суммарное 
значение столбцов query и current). Обычно сигнализирует о неверном 
плане выполнения SQL-предложения. 

3. Большой процент чтений блоков с диска (большое значение отношения 
disk/(query + current) может быть вызван неоптимальным планом выполнения 
SQL-предложения или неверной настройкой базы данных. 

4. Частые разборы SQL-предложений (поле Parse count > 1), скорее всего, 
вызваны неверной настройкой размера shared pool. 

5. Большое количество вызовов данного SQL-предложения, не согласующееся с 
выполняемыми им функциями, возможно вызвано ошибкой в данном программном 
модуле. 
Наиболее простой и продуктивный метод анализа файла трассировки 
- сравнение его с аналогичным файлом трассировки, собранной во время 
нормального функционирования программного модуля. Поскольку в различных 
файлах обычно содержится информация, накопленная за различное время, 
сравнивать следует нормированные значения статистик. Например, можно 
поделить все временные статистики SQL-предложения на количество вызовов 
той или иной операции, а статистики по обращениям к блокам базы данных 
- на количество обработанных записей.

середа, 23 березня 2016 р.

отслеживание изменений в Oracle. Если интересует дата/время последнего изменения данных

отслеживание изменений в Oracle. Если интересует только дата/время последнего изменения данных —
select max(ora_rowscn), scn_to_timestamp(max(ora_rowscn)) from scott.emp;

Подробнее у Кайта = Finding latest DML time on a table

Работаем с геоданными в Oracle Spatial

Задача: выявить неправильно проставленные КОАТУУ относительно координат.
(к примеру село слилось с городом)

Дано: таблица MOB_STA с перечнем радиостанций, их координатами в полях
longitude и latitude (с типом NUMBER) и с полем CODE_EDRPU - в котором
проставлен КОАТУУ населённого пункта в  границах которого установлена радиостанция.

вторая таблица SETTLEMENT_REGION c перечнем населённых пунктов, КОАТУ и
координатами в поле GEOMETRY, тип поля GEOMETRY. Таблица являеться эталонной.
Эта таблица создалась из ship файла, программы MapInfo, ship файл мы загрузили в Oracle с помощью программы MapBuilder, 
http://www.oracle.com/technetwork/middleware/mapviewer/downloads/index-100641.html


Решение: найдём вхождение координат радиостанций из табл. MOB_STA в границы населённых
пунктов из табл. SETTLEMENT_REGION и сравним КОАТУУ.

== В таблицу MOB_STA нужно добавить поле и назовём его- GEOMETRY, типом поля выберем GEOMETRY, это поле мы потом заполним данными из полей longitude и latitude.

Поехали:

1. Регистрируем в базе таблицу и поле (гео) иначе индекс не создастса

insert into user_sdo_geom_metadata values (
  'MOB_STA',
  'GEOMETRY',
   sdo_dim_array(
   mdsys.sdo_dim_element('X', -180, 180, 0.05),
   mdsys.sdo_dim_element('Y', -90, 90, 0.05)), 8307);


2. Трансформируем кооздинаты в точку и в тип геометрия и заполняем  поле GEOMETRY

declare
begin
for c in(select t.* from MOB_STA t)      ----
loop
update MOB_STA m set m.geometry = sdo_geometry(2001, 8307, sdo_point_type(c.longitude ,c.latitude, null),null,null)
 where m.id = c.id;
end loop;
end;


3. Создаём индекс

create index i_MOB_STA_indx on MOB_STA(geometry) indextype is mdsys.spatial_index;

5. Теперь можно делать выборку

select b.koatuu, b.name_obl, b.join_,b.name_rus,b.codename, c.code, c.address, c.owner_name
   from
  table(sdo_join('settlement_region','GEOMETRY','mob_sta','GEOMETRY','mask=ANYINTERACT')) a,
           settlement_region b,
           mob_sta           c
   where
         a.rowid1 = b.rowid
   and a.rowid2 = c.rowid
   and b.name_obl = 'Житомирська область'
   and b.koatuu <> c.code





Подробно описаны функци Spatial
http://www.oraclegis.com/blog/?p=2622

четвер, 3 березня 2016 р.

Иерархические запросы в ORACLE

Иерархические запросы в ORACLEПечатьE-mail


SELECT level, id, pid, title 
FROM test_table
START WITH pid is null
CONNECT BY PRIOR id = pid;




в Oracle присутствует специфический функционал для работы с данными в виде иерархии
-- connect by ключевой оператор который используется для работы и иерархией в oralce
-- данными где присутствует id и parent_id - ид родителя

Запрос перечисление

-- level является перечислением - цикл по датам
-- таким образом, для перечисления интервала дат
-- следует воспользоваться данным запросом
  select level nnnn 
       from dual
     connect by level <= 10   
      NNNN
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10

    

Запрос перечисление по датам

-- простое перечисление
-- специфическая переменная level отражает уровень иерархии ,который в данном запросе условен
 select trunc(sysdate-10-1+level) daten 
       from dual
     connect by level <= (sysdate-(sysdate-10))
      DATEN
    -----
      28.09.2012
      29.09.2012
      30.09.2012
      01.10.2012
      02.10.2012
      03.10.2012
      04.10.2012
      05.10.2012
      06.10.2012
      07.10.2012

    

Иерархический запрос

-- level яляется перечислением
-- пример иерархического запроса
-- специфическая переменная level отражает уровень иерархии в запросе
-- оператор connect BY отображает условие иерархии в запросе
-- в данном
WITH T AS
(
    SELECT 1 IDNULL parent_id, 'AAAA' lname FROM dual UNION ALL
    SELECT 2 ID1    parent_id, 'BBBB' lname FROM dual UNION ALL
    SELECT 3 ID1    parent_id, 'CCCC' lname FROM dual UNION ALL
    SELECT 5 ID3    parent_id, 'DDDD' lname FROM dual UNION ALL
    SELECT 4 IDNULL parent_id, 'FFFF' lname FROM dual
)
SELECT T.*,level,rpad(' ',(level-1)*4)||lname fstr
  FROM T
 connect BY PRIOR ID = parent_id

ID    PARENT_ID   LNAME LEVEL FSTR
--- ----- --- ----- ---- -----
      2 1  BBBB   1     BBBB
      3     1     CCCC  1     CCCC
      5     3     DDDD  2         DDDD
      5     3     DDDD  1     DDDD
      1           AAAA  1     AAAA
      2     1     BBBB  2         BBBB
      3     1     CCCC  2         CCCC
      5     3     DDDD  3             DDDD
      4           FFFF  1     FFFF

 start WITH

-- пример иерархии , когда выбираем ветку начала иерархии
-- опреатор  start WITH id = 1 отбражает условие выбора начальной ветки иерархии
WITH T AS
(
    SELECT 1 IDNULL parent_id, 'AAAA' lname FROM dual UNION ALL
    SELECT 2 ID1    parent_id, 'BBBB' lname FROM dual UNION ALL
    SELECT 3 ID1    parent_id, 'CCCC' lname FROM dual UNION ALL
    SELECT 5 ID3    parent_id, 'DDDD' lname FROM dual UNION ALL
    SELECT 4 IDNULL parent_id, 'FFFF' lname FROM dual
)
SELECT T.*,level,rpad(' ',(level-1)*4)||lname fstr
  FROM T
 start WITH id = 1
 connect BY PRIOR ID = parent_id

      ID    PARENT_ID   LNAME LEVEL FSTR
      1           AAAA  1     AAAA
      2     1     BBBB  2         BBBB
      3     1     CCCC  2         CCCC
      5     3     DDDD  3             DDDD



 пример иерархии , c сортировкой

-- как видим оператор order by не совсем соответствует нашим требованиям
WITH T AS
(
    SELECT 1 IDNULL parent_id, 'AAAA' lname FROM dual UNION ALL
    SELECT 2 ID1    parent_id, 'BBBB' lname FROM dual UNION ALL
    SELECT 3 ID1    parent_id, 'CCCC' lname FROM dual UNION ALL
    SELECT 5 ID3    parent_id, 'DDDD' lname FROM dual UNION ALL
    SELECT 4 IDNULL parent_id, 'FFFF' lname FROM dual
)
SELECT T.*,level,rpad(' ',(level-1)*4)||lname fstr
  FROM T
 connect BY PRIOR ID = parent_id
 ORDER SIBLINGS  by lname
ORDER SIBLINGS
--коректнее было бы использовать оперетор ORDER SIBLINGS
ID    PARENT_ID   LNAME LEVEL FSTR
      2     1     BBBB  1     BBBB
      3     1     CCCC  1     CCCC
      5     3     DDDD  2         DDDD
      5     3     DDDD  1     DDDD
      1           AAAA  1     AAAA
      2     1     BBBB  2         BBBB
      3     1     CCCC  2         CCCC
      5     3     DDDD  3             DDDD
      4           FFFF  1     FFFF







SELECT LPAD(name,LENGTH(name)+(level-1)*4) AS name 
  FROM my_table
  CONNECT BY PRIOR id = parent_id
  START WITH parent_id IS NULL
После выполнения такого иерархического запроса мы увидим примерно следующую картину:
oracle connect by