Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

Theo dõi thay đổi bảng trong Oracle

Việc sao chép cơ sở dữ liệu không còn bị giới hạn đối với các cấu hình Oracle-to-Oracle; Oracle-to-cloud và Oracle-to-BigQuery chỉ là hai trong số các tùy chọn khác nhau hiện có thể được chọn cho các cấu hình sao chép. Trong số rất nhiều cấu hình này, GoldenGate là công cụ được lựa chọn, do tính linh hoạt và độ tin cậy của nó. Thật không may, khi sao chép Oracle sang một nền tảng khác, các hành động chẳng hạn như sửa đổi bảng có thể ném một cái cờ lê vào công việc. Do đó, chúng tôi mong muốn theo dõi những thay đổi như vậy để dự đoán việc xử lý trích xuất GoldenGate diễn ra một cách duyên dáng và nhanh chóng. Hãy xem xét các tình huống có thể xảy ra và xác định hướng hành động tốt nhất.

Ý tưởng đầu tiên mà DBA có thể có là Kiểm toán thống nhất, vì nó cung cấp nhiều thông tin cho các hành động có thể kiểm toán. Than ôi "bảng kiểm tra" không nằm trong danh sách các đặc quyền có sẵn để kiểm tra:

SCOTT @ orcl > create audit policy alter_tab_pol
  2  privileges alter table;
privileges alter table
           *
ERROR at line 2:
ORA-46355: missing or invalid privilege audit option.


SCOTT @ orcl >

Điều thú vị là đặc quyền ‘ALTER ANY TABLE’ is có thể kiểm tra, nhưng nó không kiểm tra những gì bạn có thể nghĩ rằng sẽ được kiểm toán:

SCOTT @ orcl > create audit policy table_pol
  2  privileges create any table, alter any table, drop any table;

Audit policy created.

SCOTT @ orcl > audit policy table_pol;

Audit succeeded.

SCOTT @ orcl > 

Chính sách như vậy chỉ kiểm tra việc cấp các đặc quyền đó cho người dùng khác và không phải lúc nào cũng có thể tạo ra hồ sơ kiểm tra. Yêu cầu này vẫn chưa được thực hiện bởi kiểm toán vì vậy một giải pháp khác phải được đưa ra. May mắn thay, Oracle cung cấp các trình kích hoạt cấp hệ thống có thể tạo ra các bản ghi kiểm tra cho các hành động như vậy. Dưới đây là một ví dụ về cách thực hiện điều này. Đầu tiên, một bảng được tạo để chứa các bản ghi kiểm tra được tạo:

create table ddl_log (
operation   varchar2(30),
obj_owner   varchar2(35),
object_name varchar2(35),
sql_text    varchar2(200),
attempt_by  varchar2(35),
attempt_dt  timestamp);
 
create index ddl_log_idx 
on ddl_log(obj_owner, operation);

Bảng được lập chỉ mục trên obj_owner và hoạt động để tăng tốc độ tạo báo cáo. Tiếp theo, một trình kích hoạt được tạo với tư cách là người dùng sở hữu các bảng được theo dõi để ghi lại tất cả các câu lệnh CREATE, ALTER và DROP đã được thực thi:

create or replace trigger ddl_trigger
before create or alter or drop
on schema

declare
 oper ddl_log.operation%type;
 sql_text ora_name_list_t;
 i        pls_integer; 
begin
  i := sql_txt(sql_text);
  if i = 1 then
        insert into ddl_log
        select ora_sysevent, ora_dict_obj_owner,
        ora_dict_obj_name, sql_text(1), user, v_systimestamp
        from dual;
  elsif i = 2 then
        insert into ddl_log
        select ora_sysevent, ora_dict_obj_owner,
        ora_dict_obj_name, sql_text(1)||sql_text(2), user, v_systimestamp
        from dual;
  elsif i >= 3 then
        insert into 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
        from dual;
  end if;

end ddl_trigger;
/

Vì số lượng ‘phần’ 64 byte của văn bản SQL có thể khá lớn, trình kích hoạt giới hạn cột SQL_TEXT ở ba ‘phần’ đầu tiên, làm cho độ dài tối đa của chuỗi là 192 ký tự. Như mong đợi đối với các câu lệnh lớn hơn, văn bản hoàn chỉnh sẽ không được cung cấp nhưng nó sẽ ghi lại toàn bộ bất kỳ câu lệnh ‘bảng thay đổi’ nào. Lưu ý rằng trình kích hoạt này sẽ nắm bắt không chỉ các câu lệnh ALTER TABLE mà còn bất kỳ câu lệnh CREATE / ALTER / DROP nào được gửi đến cơ sở dữ liệu. Điều này có nghĩa là các câu lệnh thay đổi người dùng, thay đổi trình kích hoạt, thay đổi gói, thay đổi chức năng, thay đổi không gian bảng, thay đổi hệ thống, tạo… và thả… cũng được ghi vào bảng DDL_LOG. Bởi vì điều này, bảng có thể phát triển nhanh chóng và trở nên khá lớn, do đó, một kế hoạch để lưu giữ một lịch sử hữu hạn nên được tạo ra. Đối với hầu hết các hệ thống, 90 ngày là đủ để theo dõi các thay đổi của bảng trong cơ sở dữ liệu. Các báo cáo được tạo từ dữ liệu đã ghi có thể được lưu giữ trong thời gian dài hơn (ví dụ:12 tháng) trước khi bị xóa.

Tập lệnh mẫu để quản lý dữ liệu bảng được cung cấp bên dưới; nó thực thi thời hạn 90 ngày dữ liệu. Thư mục nhật ký được tạo:

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

Tập lệnh SQL được viết để xóa các bản ghi cũ khỏi DDL_LOG:

column sys_date new_value dt noprint
column name new_value db_nm noprint
select to_char(sysdate,'RRRRMMDD') sys_date from dual;
select name from v$database;

spool /u01/app/oracle/ddl_chg/purge_logs/ddl_log_purge_$db_nm._&dt..log
set echo on

--
-- Records slated for removal
--
select * From ddl_log where attempt_dt < sysdate - 90;

--
-- Delete selected records
--
delete from ddl_log where attempt_dt < sysdate - 90;

commit;

spool off
set echo off

Điều này, rõ ràng, không thể chạy trực tiếp từ cron (hoặc bất kỳ bộ lập lịch tương tự nào) vì vậy cần có một tập lệnh trình bao bọc:

#!/bin/ksh

#
# purge_ddl_log_90.sh
#
# Shell script to purge old audit records
# from the DDL_LOG table
#

#
# Find the selected database and set the environment
#
set -A database `ps -ef | grep [p]mon | grep '<name>' |  awk -F"_" '{print $3}'`

for i in ${database[@]}

#
# Set the environment for the database
#
do
        ORACLE_SID=$i
        export ORACLE_SID

        ORAENV_ASK=NO
        export ORAENV_ASK

        unset ORACLE_BASE
        export ORACLE_BASE

        PATH=$PATH:<ORACLE_HOME/bin location>

        . <ORACLE_HOME/bin>/oraenv -s

        LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ORACLE_HOME/lib:$ORACLE_HOME/precomp/public
        export LD_LIBRARY_PATH

        PATH=$ORACLE_HOME/bin:$PATH
        export PATH

#
# Start SQL*Plus and execute the script
#
        sqlplus /nolog <<EOF
connect / as sysdba
@/u01/app/oracle/ddl_chg/purge_ddl_log_90.sql
EOF

done

#
# Make the output files readable for all
*
cd /u01/app/oracle/ddl_chg/purge_logs

chmod 666 *.log

#
# Remove old purge logs
#

find . -name "purge*log" -mtime +365 -exec /bin/rm -rf {} ;

Tập lệnh shell đặt môi trường thích hợp và ORACLE_SID dựa trên đầu ra của lệnh ps. Tập lệnh sẽ cần được chỉnh sửa để cung cấp tên cơ sở dữ liệu cần tìm và vị trí ORACLE_HOME. Có thể chỉ định nhiều hơn một tên cơ sở dữ liệu bằng cách sử dụng | như một dấu phân cách:

'abd|def|ghi|jkl'

Điều này cung cấp một cách để xóa bảng DDL_LOG trong mọi cơ sở dữ liệu nơi kết hợp bảng / trình kích hoạt này đã được cài đặt. Tên cơ sở dữ liệu được bao gồm trong tên tệp nhật ký để giữ các đường mòn thanh lọc riêng biệt cho từng cơ sở dữ liệu. Khoảng thời gian lưu giữ các tệp nhật ký có thể được thay đổi để đáp ứng giới hạn lưu trữ của hệ thống đang được giám sát.

Báo cáo thay đổi có thể được tạo từ dữ liệu được tìm thấy trong bảng DDL_LOG:

set linesize 140
column sdate new_value sdt noprint
select to_Char(sysdate, 'RRRRMMDDHH24')sdate from dual;

column modlen new_value mlen noprint
select 'a'||nvl(max(length(modification)),25) modlen From
(select obj_owner owner, object_name tabname, substr(sql_text, instr(sql_text, 'modify ')) modification, attempt_dt mod_time
from ddl_log
where (instr(sql_text, 'alter table') > 0
or instr(sql_text, 'ALTER TABLE') > 0));
column objlen new_value olen noprint
select 'a'||nvl(max(length(owner||'.'||tabname)),60) objlen From
(select obj_owner owner, object_name tabname, substr(sql_text, instr(sql_text, 'modify ')) modification, attempt_dt mod_time
from ddl_log
where (instr(sql_text, 'alter table') > 0
or instr(sql_text, 'ALTER TABLE') > 0));

column modification format &mlen
column mod_time format a29
column tab_name format &olen

select owner||'.'|| tabname tab_name, modification, mod_time
from
(select obj_owner owner, object_name tabname, substr(sql_text, instr(sql_text, 'add ')) modification, attempt_dt mod_time
from ddl_log
where instr(lower(sql_text), 'alter table') > 0
union
select obj_owner owner, object_name tabname, substr(sql_text, instr(sql_text, 'drop ')) modification, attempt_dt mod_time
from ddl_log
where instr(lower(sql_text), 'alter table') > 0
union
select obj_owner owner, object_name tabname, substr(sql_text, instr(sql_text, 'modify ')) modification, attempt_dt mod_time
from ddl_log
where instr(lower(sql_text), 'alter table') > 0
union
select obj_owner owner, object_name tabname, substr(sql_text, instr(sql_text, 'ADD ')) modification, attempt_dt mod_time
from ddl_log
where instr(lower(sql_text), 'alter table') > 0
union
select obj_owner owner, object_name tabname, substr(sql_text, instr(sql_text, 'DROP ')) modification, attempt_dt mod_time
from ddl_log
where instr(lower(sql_text), 'alter table') > 0
union
select obj_owner owner, object_name tabname, substr(sql_text, instr(sql_text, 'MODIFY ')) modification, attempt_dt mod_time
from ddl_log
where instr(lower(sql_text), 'alter table') > 0) dl
where lower(dl.modification) not like '%table%'
and mod_time >= trunc(systimestamp)
order by 1, 3

spool /u01/app/oracle/ddl_chg/log/tab_chg_rpt_&sdt._&1..lst
/
spool off

Tên cơ sở dữ liệu được chuyển cho tập lệnh vì vậy nó sẽ được bao gồm trong tên tệp báo cáo. Mã chỉ báo cáo về các thay đổi của bảng (do đó là chuỗi dài các truy vấn UNION) và tạo ra một báo cáo tương tự như báo cáo được hiển thị bên dưới:

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

Tập lệnh cũng đặt định dạng cột dựa trên độ dài tối đa của dữ liệu được lưu trữ để có thể giảm độ dài dòng. Dữ liệu dấu thời gian đã được sử dụng để cung cấp cả giá trị ngày tháng và thời gian hiển thị cho các bản ghi thay đổi đã tạo. Các tập lệnh này đã được thử nghiệm nhưng có thể yêu cầu một số sửa đổi dựa trên việc triển khai Linux / Unix của nhà cung cấp hệ điều hành.

Đối với những DBA không chạy hệ thống sao chép, điều này có thể không được sử dụng nhiều. Tuy nhiên, đối với những dữ liệu sao chép từ Oracle sang các hệ thống khác (chẳng hạn như BigQuery, Snowflake và các hệ thống tương tự), việc biết khi nào các thay đổi bảng xảy ra có thể giúp dễ dàng xử lý các lỗi sao chép do những thay đổi đó tạo ra. Quá trình sao chép có thể trở lại đúng hướng càng nhanh thì các hệ thống dựa vào dữ liệu được sao chép đó có thể trở lại chức năng càng nhanh.

# # #

Xem các bài viết của David Fitzjarrell


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tên Ràng buộc Mặc định trong Oracle là gì?

  2. Cách kiểm tra cơ sở dữ liệu Oracle để tìm các truy vấn chạy dài

  3. Cách hiển thị dữ liệu bảng rõ ràng hơn trong oracle sqlplus

  4. Cách lấy thông tin về lỗi biên dịch trong Oracle / TOAD

  5. Ví dụ về Java trong Cơ sở dữ liệu Oracle