Репликацията на база данни вече не е ограничена до конфигурации Oracle-to-Oracle; Oracle-to-cloud и Oracle-to-BigQuery са само две от различните опции, които вече могат да бъдат избрани за конфигурации за репликация. В голям брой от тези конфигурации се крие GoldenGate като инструмент по избор, предвид неговата гъвкавост и надеждност. За съжаление, когато се репликира Oracle на друга платформа, действия като модификации на таблици могат да хвърлят гаечен ключ в работата. По този начин би било желателно да се проследяват подобни промени в очакване на обработката на GoldenGate екстракт се отклонява грациозно и бързо. Нека разгледаме възможните сценарии и да определим най-добрия начин на действие.
Първата мисъл, която DBA може да има, е Unified Auditing, тъй като предоставя богата информация за одитируеми действия. Уви, „таблица за одит“ не е сред списъка с налични привилегии за одит:
SCOTT @ orcl> създаване на политика за одит alter_tab_pol 2 привилегии променя таблицата; привилегии променят таблица *ГРЕШКА в ред 2:ORA-46355:липсва или невалидна опция за одит на привилегии.SCOTT @ orcl>
Интересното е, че привилегията „ПРОМЕНЯ ВСЯКА КАВА ТАБЛИЦА“е подлежащ на одит, но не одитира това, което смятате, че ще бъде одитирано:
SCOTT @ orcl> създаване на политика за одит table_pol 2 привилегии създаване на всяка таблица, промяна на всяка таблица, премахване на всяка таблица; Създадена политика за одит. SCOTT @ orcl> политика за одит table_pol; Одитът е успешен. SCOTT @ orcl>
Такава политика одитира само предоставянето на такива привилегии на други потребители и не винаги може да създаде одитен запис. Изискването все още не е изпълнено чрез одит, така че трябва да се предложи друго решение. За щастие Oracle предлага тригери на системно ниво, които могат да генерират одитни записи за такива действия. По-долу е показан пример как може да се направи това. Първо се създава таблица, която съдържа генерираните записи за одит:
създайте таблица ddl_log (операция varchar2(30),obj_owner varchar2(35),object_name varchar2(35),sql_text varchar2(200),attempt_by varchar2(35),attempt_dt timestamp); създайте индекс ddl_log_idx на ddl_log(obj_owner, операция);
Таблицата е индексирана на obj_owner и операция за ускоряване на генерирането на отчети. След това се създава тригер като потребител, който притежава таблиците, които трябва да бъдат наблюдавани, за да регистрира всички изпълнени изрази CREATE, ALTER и DROP:
създайте или заменете тригера ddl_trigger, преди да създадете или промените или пуснете schemadeclare oper ddl_log.operation%type; sql_text ora_name_list_t; i pls_integer; започвам i :=sql_txt(sql_text); ако i =1, тогава вмъкнете в ddl_log изберете ora_sysevent, ora_dict_obj_owner, ora_dict_obj_name, sql_text(1), user, v_systimestamp от dual; elsif i =2 след това вмъкнете в ddl_log изберете ora_sysevent, ora_dict_obj_owner, ora_dict_obj_name, sql_text(1)||sql_text(2), user, v_systimestamp от dual; elsif i>=3 след това вмъкнете в ddl_log select ora_sysevent, ora_dict_obj_owner, ora_dict_obj_name, sql_text(1)||sql_text(2)||sql_text(3), user, v_systimestamp от dual; край на if;край на ddl_trigger;/
Тъй като броят на 64-байтовите „парчета“ от SQL текста може да бъде доста голям, тригерът ограничава колоната SQL_TEXT до първите три „части“, което прави максималната дължина на низа 192 знака. Както се очаква за по-големи изрази, пълният текст няма да бъде предоставен, но трябва да обхваща всички изрази на „alter table“ в тяхната цялост. Имайте предвид, че този тригер ще улови не само ALTER TABLE изрази, но и всеки израз CREATE/ALTER/DROP, изпратен в базата данни. Това означава, че операторите alter user, alter trigger, alter package, alter function, alter tablespace, alter system, create ... и drop ... също се регистрират в таблицата DDL_LOG. Поради това таблицата може да расте бързо и да стане доста голяма, така че трябва да се създаде план за водене на крайна история. За повечето системи 90 дни трябва да са достатъчни за проследяване на промените в таблицата в базата данни. Отчетите, генерирани от регистрираните данни, могат да се съхраняват за по-дълги периоди от време (например 12 месеца), преди да бъдат премахнати.
Примерен скрипт за управление на данните в таблицата е предоставен по-долу; той налага 90-дневен прозорец с данни. Създава се лог директория:
mkdir -p /u01/app/oracle/ddl_chg/purge_logs
Написан е SQL скрипт за изчистване на старите записи от DDL_LOG:
column sys_date new_value dt noprintcolumn name new_value db_nm noprintselect to_char(sysdate,'RRRRMMDD') sys_date от dual;изберете име от v$database;spool /u01/app/oracle/purge_log_d_g/$mdl_log_d_g/ logset echo on---- Записите, планирани за премахване--select * От ddl_log, където try_dtТова, очевидно, не може да се стартира директно от cron (или друг подобен планировчик), така че е необходим скрипт за обвивка:
#!/bin/ksh## purge_ddl_log_90.sh## Shell скрипт за изчистване на стари записи за одит# от таблицата DDL_LOG### Намерете избраната база данни и задайте средата#set -A база данни `ps -ef | grep [p]mon | grep '<име>' | awk -F"_" '{print $3}'` for i в ${database[@]}## Задайте средата за базата данни#do ORACLE_SID=$i експортиране ORACLE_SID ORAENV_ASK=NO експортиране ORAENV_ASK ненастроено ORACLE_BASE експортиране ORACLE_BASE PATH=$PATH:. /oraenv -s LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ORACLE_HOME/lib:$ORACLE_HOME/precomp/public export LD_LIBRARY_PATH PATH=$ORACLE_HOME/bin:$PATH* експортиране на PATHl#exe Стартиране на SQLcu* sqlp#exe /nolog < Скриптът на обвивката задава правилната среда и ORACLE_SID въз основа на изхода на командата ps. Скриптът ще трябва да бъде редактиран, за да предостави името на базата данни за търсене и местоположението ORACLE_HOME. Може да се посочи повече от едно име на база данни с помощта на | като разделител:
'abd|def|ghi|jkl'Това осигурява начин за изчистване на таблицата DDL_LOG във всяка база данни, където е инсталирана тази комбинация таблица/тригер. Името на базата данни е включено в името на регистрационния файл, за да се поддържат отделни пътеки за прочистване за всяка база данни. Продължителността на съхранението на регистрационните файлове може да бъде променена, за да се изпълнят ограниченията за съхранение на наблюдаваната система.
Отчетите за промените могат да се генерират от данните, намерени в таблицата DDL_LOG:
set linesize 140column sdate new_value sdt noprintselect to_Char(sysdate, 'RRRRMMDDHH24')sdate от dual;column modlen new_value mlen noprintselect 'a'||nvl(max(length)(select oblength(seowner) owner) , име_на_обект име на раздел, substr(sql_text, instr(sql_text, 'modify')) модификация, try_dt mod_timefrom ddl_logwhere (instr(sql_text, 'alter table')> 0or instr(sql_text, 'ALTER TABLE')> m 0 obj); new_value olen noprintselect 'a'||nvl(max(length(owner||'.'||tabname)),60) objlen From(изберете obj_owner owner, object_name tabname, substr(sql_text, instr(sql_text, 'modify') ) modification, try_dt mod_timefrom ddl_logwhere (instr(sql_text, 'alter table')> 0or instr(sql_text, 'ALTER TABLE')> 0));формат за модификация на колона &mlencolumn mod_time format a29column tab_name| owner format||'. tabname tab_name, modification, mod_timefrom(изберете obj_owner собственик, object_name tabname, substr(sql_text, instr(sql_text, 'add')) modification, try_dt mod_timefrom ddl_logwhere instr(lower(sql_text), 'alter tableownname')> 0 tabname, substr(sql_text, instr(sql_text, 'drop')) модификация, try_dt mod_timefrom ddl_logwhere instr(lower(sql_text), 'alter table')> 0unionselect obj_owner owner, object_name tabname, substr(sql_qld_text, in ')) модификация, try_dt mod_timefrom ddl_logwhere instr(lower(sql_text), 'alter table')> 0unionselect obj_owner собственик, object_name tabname, substr(sql_text, instr(sql_text, 'ADD ')) modification, try_dtwer(strddl_time) sql_text), 'alter table')> 0unionselect obj_owner owner, object_name tabname, substr(sql_text, instr(sql_text, 'DROP')) модификация, try_dt mod_timefrom ddl_logwhere instr(lower(sql_text), 'alter table owner')> , обект _name tabname, substr(sql_text, instr(sql_text, 'MODIFY')) модификация, try_dt mod_timefrom ddl_logwhere instr(lower(sql_text), 'alter table')> 0) dlwhere bottom(dl.modification) не е като '%table%' и mod_time>=trunc(systimestamp)order by 1, 3spool /u01/app/oracle/ddl_chg/log/tab_chg_rpt_&sdt._&1..lst/spool offИмето на базата данни се предава на скрипта, така че ще бъде включено в името на файла на отчета. Кодът отчита само промени в таблицата (оттук и дългия низ от заявки UNION) и създава отчет, подобен на показания по-долу:
TAB_NAME МОДИФИКАЦИЯ MOD_TIME---------------- ---------------------------- -- -----------------------------SCOTT.DDL_LOG модификация sql_text varchar2(200) 23-NOV-19 01.23.49.859971 PMпредварително>Скриптът също така задава форматирането на колоните въз основа на максималната дължина на съхранените данни, за да намали евентуално дължината на реда. Данните за времеви отпечатъци бяха използвани, за да се осигурят стойности както за дата, така и за видими часове за генерираните записи за промяна. Тези скриптове са тествани, но може да изискват някои модификации въз основа на внедряването на Linux/Unix от доставчика на операционна система.
За тези DBA, които не работят с репликирани системи, това може да не е от голяма полза. Но за тези, които репликират данни от Oracle към други системи (като BigQuery, Snowflake и други подобни), знанието кога са настъпили промени в таблицата може да улесни справянето с неуспехите при репликация, създадени от тези промени. Колкото по-бързо може да се върне процесът на репликация, толкова по-бързо системите, които разчитат на тези репликирани данни, могат да се върнат към функционалност.
# # #
Вижте статии отДейвид Фицярел