материализованные представления внешней базы данных не обновляются в указанное время - SQL * Net больше данных из dblink - PullRequest
3 голосов
/ 18 июля 2011

Мы используем веб-сервис, который работает на Oracle.Они строго разрешают только доступ к ODBC только для SELECT.Некоторые из отчетов, которые мы делаем, не очень хорошо объясняются представлениями, которые предоставляет компания, поэтому мы создали db_link, используя экспресс-выпуск Oracle 11g, и переписали некоторые из наиболее важных запросов в виде материализованных представлений, используя обновление:укажите настройки для повторного выполнения запросов ежечасно, что достаточно для наших целей.Пока все хорошо.

Я заметил, что некоторые из MV перестают обновляться, и за ними нет реальной картины.При дальнейшем расследовании время от времени выглядит, что внешняя база данных (та, к которой мы подключены через db_link) не выполняет запрос время от времени, и процесс обновления терпеливо ожидает события «SQL * Net more data»из dblink 'на неопределенный срок.

Вот запрос, который я выполнил, чтобы получить данные о застрявших сеансах обновления и трех сеансах, которые кажутся застрявшими операторами обновления:

select a.username, a.osuser, a.sid, a.serial#, b.spid, a.seconds_in_wait, 
       a.event, a.state, a.wait_class
from v$session a, v$process b
where a.paddr = b.addr
and a.seconds_in_wait > 500 and a.username is not null;

USERNAME    OSUSER  SID SERIAL# SPID    SECONDS_IN_WAIT EVENT                         STATE   WAIT_CLASS
KIPP_NWK    SYSTEM  27  7904    2704    161991          SQL*Net more data from dblink WAITING Network
KIPP_NWK    SYSTEM  35  2469    3880    139489          SQL*Net more data from dblink WAITING Network
KIPP_NWK    SYSTEM  37  6051    1408    40860           SQL*Net more data from dblink WAITING Network

Я думаю, что мой вопростаким образом, «есть ли какие-либо предложения относительно сценария, который будет периодически (скажем, ежечасно) сканировать застрявшие сеансы типа« больше данных из dblink »и завершать их?»Желаемое для меня поведение - это то, что это обновление более устойчивое - если оно истечет, я бы хотел, чтобы оно началось заново и попробуйте, попробуйте снова ...

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

Я читал о настройке idle_time и изменении набора SQLNET.EXPIRE_TIME в файле sqlnet.ora - но я не понимаю, что это правильный подход, так как соединения не простаивают, они активны, но ждутнеопределенно, а также усложняющий фактор, что эти сеансы инициируются самой базой данных.

Как сделать это обновление более устойчивым / автоматически убить эти долгожданные обновления?

Ответы [ 3 ]

1 голос
/ 25 октября 2015

Недавно мы также столкнулись с той же проблемой в процессе полного обновления нашего материализованного представления. Эта проблема была сведена к минимуму за счет дальнейшей оптимизации сетевого времени, необходимого для обновления (от около 25 минут до около 2 минут; хотя сквозное обновление все еще занимало около 10 минут). Вот что мы сделали:

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

Шаг 1) Создание материализованного представления в режиме NOLOGGING (без индексов и без расписания автоматического обновления) на машине, где существует исходное материализованное представление

Шаг 2) Воссоздание исходного материализованного представления в режиме LOGGING с указанным выше материализованным представлением в качестве локального источника данных (с необходимыми индексами и без расписания автоматического обновления)

Шаг 3) Создайте процедуру обновления, которая выполняет следующие задачи:

1 - обновить материализованное представление, созданное в режиме NOLOGGING

2 - проверить целостность данных между локальным и удаленным источником данных

3 - при проверке выполнить полное обновление материализованного представления (созданного в режиме LOGGED)

Я не эксперт, поэтому, пожалуйста, поправьте меня, если какие-либо из моих предположений неверны. Я задокументировал этот процесс в своем сообщении в блоге Oracle Materialized View Complete Refresh over Database Link

Отказ от ответственности: это мой личный блог

1 голос
/ 18 июля 2011

Не подключайтесь через dblink только для того, чтобы выполнить обновление представления mat на удаленном экземпляре Oracle. Просто настройте задание планировщика, чтобы запустить обновление на том же экземпляре, что и представление.

Вам не нужно открывать соединение и ждать завершения обновления. Это скорее автоматизированная работа администратора, чем то, что должен запускать внешний клиент и присматривать за ребенком. Если вам нужно проверить его состояние, вы можете проверить dba_scheduler_jobs, dba_scheduler_job_log, dba_scheduler_run_details, all_scheduler_running_jobs и т. Д. (Более того, но это многое скажет).

См. здесь для некоторых хороших примеров. Другие улучшения, если вы на 11g.

0 голосов
/ 20 июля 2011

@ tbone, спасибо за ресурсы dbms_scheduler. Я закончил тем, что создал запланированную работу, которая ищет застрявшие обновления dblink и завершает их. Вроде хорошо работает.

Я создал эту хранимую процедуру, которая убивает задания, ожидающие 10 минут в SQL * Чистая дополнительная информация из dblink:

create or replace procedure kill_stuck_refresh
as
begin     
    for x in (  
            select username, osuser, sid, serial#, seconds_in_wait, 
            event, state, wait_class
            from v$session
            where username is not null 
                  and seconds_in_wait > 600 
                  and event = 'SQL*Net more data from dblink'  
        ) loop  
        execute immediate 'alter system disconnect session '''|| x.sid  
                     || ',' || x.serial# || ''' immediate';
        dbms_output.put_line( 'Alter session done' );             
    end loop;  
end;  

и затем это задание dbms, которое регулярно запускает хранимую процедуру:

BEGIN
DBMS_SCHEDULER.CREATE_JOB(job_name        => 'kill_stuck_refresh_jobs',
                          job_type        => 'STORED_PROCEDURE',
                          job_action      => 'kill_stuck_refresh',
                          start_date      => sysdate,
                          repeat_interval => 'freq=minutely; interval=15',
                          end_date        => NULL,
                          enabled         => TRUE,
                          comments        => 'calls kill_stuck_refresh every 15 minutes');
END;
/

это руководство было полезно, хотя и не использует новый синтаксис для запланированных заданий: http://baurdotnet.wordpress.com/2010/11/11/oracle-job-session-killer/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...