вторник, 26 апреля 2016 г.

Проверка правильности переноса дампа

Очень часто сталкиваюсь с проблемой, когда администраторы разворачивают дамп с неконсистентными данными, при этом теряются констрейнты, форенкеи.......
Для проверки о том что был ли дамп перенесен консистентно, я создал таблицу a$schema_statistics:

declare
  v_table_name   varchar2(30)   := 'a$schema_statistics';
  v_create_table varchar2(2000) := 'create table ' || v_table_name || ' '
                                || '(object_type varchar2(30)'
                                || ',object_name varchar2(4000)'
                                || ',status      varchar2(20))'
                                || 'tablespace itap_data01';
  v_trunc_table  varchar2(200)  := 'truncate table ' || v_table_name;
  v_cnt integer;
begin
  select count(*)
    into v_cnt
    from user_tables
    where table_name = upper(v_table_name);

  execute immediate case v_cnt
                      when 0 then v_create_table
                      else v_trunc_table
                    end;
end;

/

И два представления:

CREATE OR REPLACE FORCE VIEW v_schema_statistics
AS
WITH cons_columns AS
  (SELECT table_name
       || '#'
       || listagg(column_name, ':') WITHIN GROUP (ORDER BY position) cons_name, constraint_name
     FROM user_cons_columns uccs
    GROUP BY table_name
            , constraint_name)
SELECT 'CONSTRAINTS' AS object_type
     , CASE
         WHEN constraint_name LIKE 'SYS%'
         THEN CASE urcs.constraint_type
                 WHEN 'R' THEN urcs.constraint_type
                            || '='
                            || (SELECT cons_name FROM cons_columns cscs WHERE cscs.constraint_name = urcs.constraint_name)
                            || '&'
                            || (SELECT cons_name FROM cons_columns cscs WHERE cscs.constraint_name = urcs.r_constraint_name)
                 WHEN 'P' THEN urcs.constraint_type
                            || '='
                            || (SELECT cons_name FROM cons_columns cscs WHERE cscs.constraint_name = urcs.constraint_name)
                 WHEN 'U' THEN urcs.constraint_type
                            || '='
                            || (SELECT cons_name from cons_columns cscs WHERE cscs.constraint_name = urcs.constraint_name)
                 WHEN 'C' THEN urcs.constraint_type
                            || '='
                            || (SELECT cons_name from cons_columns cscs WHERE cscs.constraint_name = urcs.constraint_name)
               END
         ELSE urcs.constraint_name
       END object_name
     , urcs.status
  FROM user_constraints urcs
UNION ALL
SELECT 'INDEX' as object_type
     , CASE
         WHEN index_name LIKE 'SYS%'
         THEN CASE index_type
                WHEN 'LOB' then index_type || '=' || uris.table_name
                ELSE (SELECT table_name
                          || '#'
                          || LISTAGG(column_name || '&' || descend, ':') WITHIN GROUP (ORDER BY column_position) index_name
                        FROM user_ind_columns uics
                       WHERE uics.index_name = uris.index_name
                       GROUP BY table_name)
              END
         ELSE index_name
       END object_name
     , uris.status
  FROM user_indexes uris
WHERE uris.index_type <> 'LOB'
UNION ALL
SELECT object_type
     , object_name
     , status
  FROM user_objects
WHERE object_type not in ('LOB', 'INDEX')
   AND ((object_type <> 'TYPE') OR (object_name not LIKE 'SYS%'))
/
CREATE OR REPLACE FORCE VIEW v_schema_statistics_compare
AS
SELECT *
  FROM (SELECT CASE
                 WHEN sass.object_name IS NULL
                   OR vsss.object_name IS NULL   THEN 'NOT MATCHED'
                 WHEN sass.status <> vsss.status THEN 'DIFF STATUS'
                 ELSE 'OK'
               END compare_result
             , sass.object_type AS a$_object_type
             , sass.object_name AS a$_object_name
             , sass.status      AS a$_status
             , vsss.object_type AS sh_object_type
             , vsss.object_name AS sh_object_name
             , vsss.status      AS sh_status
          FROM a$schema_statistics sass
          FULL OUTER JOIN
               v_schema_statistics vsss
            ON sass.object_type = vsss.object_type
           AND sass.object_name = vsss.object_name)
WHERE compare_result <> 'OK'
/
Первое представление v_schema_statistics отображает статистику по текущей схеме, а второе v_schema_statistics_compare сравнивает сохраненную статистику в таблице  a$schema_statistics с текущей статистикой. При каждом обновлении схемы, я запускаю следующий скрипт;

truncate table a$schema_statistics
/
insert
  into a$schema_statistics
     ( object_type
     , object_name
     , status
     )
select object_type
     , object_name
     , status
  from v_schema_statistics
/
commit
/
Он собирает статистику по схеме и сохраняет в таблице a$schema_statistics.
Если мне нужно узнать, целостность перенесенного дампа, я выполняю запрос 

select * from v_schema_statistics_compare

Колонки с префиксом A$ отображают сохраненную статистику, а с префиксом SH текущую статистику по схеме.

Комментариев нет:

Отправить комментарий