sql >> Databáze >  >> RDS >> Oracle

Monitorování změn tabulky v Oracle

Replikace databáze již není omezena na konfigurace Oracle-to-Oracle; Oracle-to-cloud a Oracle-to-BigQuery jsou jen dvě z různých možností, které lze nyní vybrat pro konfigurace replikace. V mnoha z těchto konfigurací spočívá GoldenGate jako nástroj volby, vzhledem k jeho všestrannosti a spolehlivosti. Bohužel při replikaci Oracle na jinou platformu mohou akce, jako jsou úpravy stolu, vrhnout do práce klíček. Bylo by tedy žádoucí sledovat takové změny v očekávání zacházení s extraktem GoldenGate elegantně a rychle. Pojďme se podívat na možné scénáře a určit nejlepší postup.

První myšlenka, kterou by DBA mohl mít, je Unified Auditing, protože poskytuje velké množství informací pro auditovatelné akce. Bohužel „tabulka auditu“ není na seznamu dostupných oprávnění k auditu:

SCOTT @ orcl> vytvořit zásady auditu alter_tab_pol 2 oprávnění alter table;privileges alter table *ERROR na řádku 2:ORA-46355:chybějící nebo neplatná možnost auditu oprávnění.SCOTT @ orcl>

Zajímavé je, že privilegium „ALTER ANY TABLE“ je auditovatelné, ale neaudituje to, co si myslíte, že bude auditováno:

SCOTT @ orcl> vytvořit zásady auditu table_pol 2 oprávnění vytvořit libovolnou tabulku, upravit libovolnou tabulku, odstranit libovolnou tabulku;Vytvořena zásada auditu.SCOTT @ orcl> zásada auditu table_pol;Audit proběhl úspěšně.SCOTT @ orcl> 

Taková politika pouze kontroluje udělení takových oprávnění jiným uživatelům a nemusí vždy vytvořit záznam auditu. Požadavek je zatím auditováním nesplněn, takže je třeba vytvořit jiné řešení. Naštěstí Oracle nabízí spouštěče na úrovni systému, které mohou pro takové akce vytvářet záznamy auditu. Níže je uveden příklad, jak to lze provést. Nejprve se vytvoří tabulka obsahující vygenerované záznamy auditu:

vytvoření tabulky ddl_log (operace varchar2(30),obj_owner varchar2(35),object_name varchar2(35),sql_text varchar2(200),attempt_by varchar2(35),attempt_dt timestamp); vytvořit index ddl_log_idx na ddl_log(obj_owner, operation);

Tabulka je indexována na obj_owner a operaci pro urychlení generování sestav. Dále je vytvořen spouštěč jako uživatel, který vlastní tabulky, které mají být monitorovány, pro protokolování všech příkazů CREATE, ALTER a DROP, které byly provedeny:

vytvořit nebo nahradit spouštěč ddl_triggerpřed vytvořením nebo změnou nebo dropon schemadeclare oper ddl_log.operation%type; sql_text ora_name_list_t; i pls_integer; begin i :=sql_txt(sql_text); pokud i =1 pak vložte do ddl_log vyberte ora_sysevent, ora_dict_obj_owner, ora_dict_obj_name, sql_text(1), user, v_systimestamp z dual; elsif i =2 pak vložte do ddl_log select ora_sysevent, ora_dict_obj_owner, ora_dict_obj_name, sql_text(1)||sql_text(2), user, v_systimestamp z dual; elsif i>=3 pak vložte do 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 z dual; end if;end ddl_trigger;/

Vzhledem k tomu, že počet 64bajtových ‚kusů‘ SQL textu může být poměrně velký, trigger omezuje sloupec SQL_TEXT na první tři ‚kusy‘, takže maximální délka řetězce je 192 znaků. Jak se očekává u větších příkazů, nebude poskytnut úplný text, ale měl by zachycovat všechny příkazy „alter table“ v jejich celistvosti. Všimněte si, že tento spouštěč zachytí nejen příkazy ALTER TABLE, ale také všechny příkazy CREATE/ALTER/DROP odeslané do databáze. To znamená, že příkazy alter user, alter trigger, alter package, alter function, alter tablespace, alter system, create … and drop … se také zaznamenají do tabulky DDL_LOG. Z tohoto důvodu může tabulka rychle růst a být poměrně velká, takže by měl být vytvořen plán pro udržení konečné historie. U většiny systémů by ke sledování změn tabulek v databázi mělo stačit 90 dní. Zprávy generované z protokolovaných dat lze před odstraněním uchovávat po delší dobu (například 12 měsíců).

Níže je uveden ukázkový skript pro správu dat tabulky; vynucuje 90denní okno dat. Vytvoří se adresář protokolu:

mkdir -p /u01/app/oracle/ddl_chg/purge_logs

Je napsán skript SQL, který odstraní staré záznamy z DDL_LOG:

sloupec sys_date new_value dt noprint název sloupce new_value db_nm noprintselect to_char(sysdate,'RRRRMMDD') sys_date from dual;select name from v$database;spool /u01/app/oracle/ddl_chg/purge_logs/ddl_log_purge.t. logset echo on---- Záznamy, které mají být odstraněny--vyberte * Z ddl_log kde Pokus_dt  

To samozřejmě nelze spustit přímo z cronu (nebo jiného podobného plánovače), takže je potřeba skript wrapper:

#!/bin/ksh## purge_ddl_log_90.sh## Shell skript pro vyčištění starých záznamů auditu# z tabulky DDL_LOG### Najděte vybranou databázi a nastavte prostředí#set -A databázi `ps -ef | grep [p]mon | grep '' | awk -F"_" '{print $3}'`for i v ${database[@]## Nastavit prostředí pro databázi#do ORACLE_SID=$i export ORACLE_SID ORACLE_SID ORACLE_SID ORAENV_ASK=ŽÁDNÝ export ORAENV_ASK nenastaven ORACLE_BASE export ORACLE_BASE PATH=$PATH: . /oraenv -s LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ORACLE_HOME/lib:$ORACLE_HOME/precomp/veřejný export LD_LIBRARY_PATH PATH=$ORACLE_HOME/bin:$PATH export PATH## Spusťte SQL*Plus## Spusťte SQL*Plus /nolog < 

Shell skript nastaví správné prostředí a ORACLE_SID na základě výstupu příkazu ps. Skript bude muset být upraven tak, aby poskytoval název databáze k hledání a umístění ORACLE_HOME. Pomocí | lze zadat více než jeden název databáze jako oddělovač:

'abd|def|ghi|jkl'

To poskytuje způsob, jak vyčistit tabulku DDL_LOG v každé databázi, kde byla tato kombinace tabulky/spouštěče nainstalována. Název databáze je součástí názvu souboru žurnálu, aby byly stopy čištění oddělené pro každou databázi. Dobu uchování souborů protokolu lze změnit, aby byly splněny limity úložiště monitorovaného systému.

Zprávy o změnách lze generovat z dat nalezených v tabulce DDL_LOG:

0nebo instr(text_sql, 'ALTER TABLE')> 0)); new_value olen noprintselect 'a'||nvl(max(délka(vlastník||'.'||název karty)),60) objlen From(vybrat vlastníka obj_owner, název_objektu název karty, substr(sql_text, instr(text_sql, 'upravit ') ) modifikace, pokus_dt mod_timefrom ddl_logwhere (instr(sql_text, 'alter table')> 0nebo instr(sql_text, 'ALTER TABLE')> 0));formát úpravy sloupce &mlencolumn formát_času modu a29sloupec formát názvu_tabulky &olenselect owner||'.'. název_karty název_karty, modifikace, mod_timefrom(vybrat vlastníka_obj., název_objektu název_tabulky, substr(text_sql, instr(text_sql, 'add ')) úprava, pokus_dt čas_modufrom ddl_logwhere instr(nižší(text_sql), 'změnit název_objektu')> 0vlastník vlastníka, název_objektu tabname, substr(sql_text, instr(sql_text, 'drop ')) modifikace, pokus_dt mod_timefrom ddl_logwhere instr(lower(sql_text), 'alter table')> 0unionselect obj_owner owner, object_name tabname, substrify(sql_text, instr(sql) ')) modifikace, pokus_dt mod_timefrom ddl_logwhere instr(lower(sql_text), 'alter table')> 0unionselect vlastník_obj., název_objektu název_karty, substr(sql_text, instr(sql_text, 'ADD ')) úprava, pokus_dt mod_timefrom instrdl(low sql_text), 'alter table')> 0unionselect obj_owner owner, object_name tabname, substr(sql_text, instr(sql_text, 'DROP ')) modifikace, pokus_dt mod_timefrom ddl_logwhere instr(lower(sql_text), 'změnit vlastníka_obj.')> 0un , objekt _name tabname, substr(sql_text, instr(sql_text, 'MODIFY ')) modifikace, pokus_dt mod_timefrom ddl_logwhere instr(lower(sql_text), 'alter table')> 0) dlwhere lower(dl.modification) ne jako '%table%' a mod_time>=trunc(systimestamp) order by 1, 3spool /u01/app/oracle/ddl_chg/log/tab_chg_rpt_&sdt._&1..lst/spool off

Název databáze je předán skriptu, takže bude zahrnut do názvu souboru sestavy. Kód hlásí pouze změny v tabulce (proto dlouhý řetězec UNION dotazů) a vytváří zprávu podobnou té, která je zobrazena níže:

TAB_NAME MODIFICATION MOD_TIME---------------- ---------------------------- -- -----------------------------SCOTT.DDL_LOG upravit sql_text varchar2(200) 23-NOV-19 01.23.49.859971 PM 

Skript také nastaví formátování sloupců na základě maximální délky uložených dat, aby se případně zkrátila délka řádku. Data časových razítek byla použita za účelem poskytnutí jak data, tak viditelných časových hodnot pro generované záznamy změn. Tyto skripty byly testovány, ale mohou vyžadovat určité úpravy na základě implementace Linux/Unix dodavatelem operačního systému.

Pro ty DBA, kteří nepoužívají replikované systémy, to nemusí být příliš užitečné. Ale pro ty, kteří replikují data z Oracle do jiných systémů (jako je BigQuery, Snowflake a podobně), může znalost, kdy došlo ke změnám v tabulce, usnadnit řešení selhání replikace způsobených těmito změnami. Čím rychleji se proces replikace může vrátit na správnou cestu, tím rychleji se mohou systémy, které na tato replikovaná data spoléhají, vrátit k funkčnosti.

# # #

Viz články odDavida Fitzjarrella


  1. Vygenerujte sql s poddotazem jako sloupec v příkazu select pomocí SQLAlchemy

  2. Zjistěte typ dat vrácených sloupců v sadě výsledků na serveru SQL Server

  3. Jak získat čas vytvoření databáze v PostgreSQL 9.0?

  4. Skupiny konverzace SQL Server Service Broker