supplemental log,primary key,logminer 的一些测试

参考文档:

https://docs.oracle.com/cd/E11882_01/server.112/e22490/logminer.htm#SUTIL1582

Supplemental Logging

Redo log files are generally used for instance recovery and media recovery. The data needed for such operations is automatically recorded in the redo log files. However, a redo-based application may require that additional columns be logged in the redo log files. The process of logging these additional columns is called supplemental logging.

By default, Oracle Database does not provide any supplemental logging, which means that by default LogMiner is not usable. Therefore, you must enable at least minimal supplemental logging before generating log files which will be analyzed by LogMiner.

The following are examples of situations in which additional columns may be needed:

  • An application that applies reconstructed SQL statements to a different database must identify the update statement by a set of columns that uniquely identify the row (for example, a primary key), not by the ROWID shown in the reconstructed SQL returned by the V$LOGMNR_CONTENTS view, because the ROWID of one database will be different and therefore meaningless in another database.

  • An application may require that the before-image of the whole row be logged, not just the modified columns, so that tracking of row changes is more efficient.

A supplemental log group is the set of additional columns to be logged when supplemental logging is enabled. There are two types of supplemental log groups that determine when columns in the log group are logged:

  • Unconditional supplemental log groups: The before-images of specified columns are logged any time a row is updated, regardless of whether the update affected any of the specified columns. This is sometimes referred to as an ALWAYS log group.

  • Conditional supplemental log groups: The before-images of all specified columns are logged only if at least one of the columns in the log group is updated.

Supplemental log groups can be system-generated or user-defined.

In addition to the two types of supplemental logging, there are two levels of supplemental logging, as described in the following sections:

以下测试在19c下测试

1 有主键,没有开补充日志,  username列是unknown

ALTER DATABASE DROP SUPPLEMENTAL LOG DATA;
SELECT SUPPLEMENTAL_LOG_DATA_MIN FROM V$DATABASE; 
alter system switch logfile; 
create table test3 ( n3 number primary key); 
insert into test3 values ( 3311); 
insert into test3 values ( 3322); 
commit;
connect / as sysdba 
alter system switch logfile; 
SELECT NAME FROM V$ARCHIVED_LOG WHERE FIRST_TIME = (SELECT MAX(FIRST_TIME) FROM V$ARCHIVED_LOG); 
EXECUTE DBMS_LOGMNR.ADD_LOGFILE(LOGFILENAME =>'/u01/archivelog/1_35_1020495413.dbf' ,OPTIONS => DBMS_LOGMNR.NEW);
EXECUTE DBMS_LOGMNR.START_LOGMNR(OPTIONS => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG);
SELECT SQL_REDO , SQL_UNDO FROM V$LOGMNR_CONTENTS WHERE username='ZBB'; 
EXECUTE DBMS_LOGMNR.END_LOGMNR(); 
create table logmin_tmp as select * from v$logmnr_contents;
select SQL_REDO,SQL_UNDO from logmin_tmp where table_name='TEST3';


SYS@test>ALTER DATABASE DROP SUPPLEMENTAL LOG DATA;

Database altered.

SYS@test>SELECT SUPPLEMENTAL_LOG_DATA_MIN FROM V$DATABASE;

SUPPLEME
--------
NO

SYS@test>alter system switch logfile;

System altered.

SYS@test>
SYS@test>alter system switch logfile;

System altered.

SYS@test>conn zbb/oracle
Connected.
ZBB@test>create table test3 ( n3 number primary key);

Table created.

ZBB@test>insert into test3 values ( 3311);

1 row created.

ZBB@test>insert into test3 values ( 3322);

1 row created.

ZBB@test>commit;

Commit complete.

ZBB@test>conn / as sysdba
Connected.
SYS@test>alter system switch logfile;

System altered.

SYS@test>SELECT NAME FROM V$ARCHIVED_LOG WHERE FIRST_TIME = (SELECT MAX(FIRST_TIME) FROM V$ARCHIVED_LOG);

NAME
--------------------------------------------------------------------------------
/u01/archivelog/1_35_1020495413.dbf


SYS@test>SELECT SQL_REDO , SQL_UNDO FROM V$LOGMNR_CONTENTS WHERE username='ZBB';

no rows selected

SYS@test>create table logmin_tmp as select * from v$logmnr_contents;

Table created.

SYS@test>
SYS@test>EXECUTE DBMS_LOGMNR.END_LOGMNR();

PL/SQL procedure successfully completed.

SYS@test>



SYS@test>select SQL_REDO,SQL_UNDO from logmin_tmp where table_name='TEST3';

SQL_REDO
--------------------------------------------------------------------------------
SQL_UNDO
--------------------------------------------------------------------------------
create table test3 ( n3 number primary key);


insert into "ZBB"."TEST3"("N3") values ('3311');
delete from "ZBB"."TEST3" where "N3" = '3311' and ROWID = 'AAASMdAAHAADPPuAAA';

insert into "ZBB"."TEST3"("N3") values ('3322');
delete from "ZBB"."TEST3" where "N3" = '3322' and ROWID = 'AAASMdAAHAADPPuAAB';


SYS@test>

2 没有开补充日志,没有主键, username 列为unknown 。

ALTER DATABASE DROP SUPPLEMENTAL LOG DATA;
SELECT SUPPLEMENTAL_LOG_DATA_MIN FROM V$DATABASE; 
alter system switch logfile; 
create table test4 ( n4 number); 
insert into test4 values ( 4411); 
insert into test4 values ( 422); 
commit;
connect / as sysdba 
alter system switch logfile; 
SELECT NAME FROM V$ARCHIVED_LOG WHERE FIRST_TIME = (SELECT MAX(FIRST_TIME) FROM V$ARCHIVED_LOG); 
EXECUTE DBMS_LOGMNR.ADD_LOGFILE(LOGFILENAME =>'/u01/archivelog/1_37_1020495413.dbf' ,OPTIONS => DBMS_LOGMNR.NEW);
EXECUTE DBMS_LOGMNR.START_LOGMNR(OPTIONS => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG);
--SELECT SQL_REDO , SQL_UNDO FROM V$LOGMNR_CONTENTS WHERE username='ZBB'; 
EXECUTE DBMS_LOGMNR.END_LOGMNR(); 
create table logmin_tmp4 as select * from v$logmnr_contents;
select SQL_REDO,SQL_UNDO from logmin_tmp where table_name='TEST4';


SYS@test>SELECT SUPPLEMENTAL_LOG_DATA_MIN FROM V$DATABASE;

SUPPLEME
--------
NO

SYS@test>alter system switch logfile;

System altered.

ZBB@test>create table test4 ( n4 number);

Table created.

ZBB@test>insert into test4 values ( 4411);

1 row created.

ZBB@test>insert into test4 values ( 422);

1 row created.

ZBB@test>commit;

Commit complete.

ZBB@test>conn / as sysdba
Connected.
SYS@test>
SYS@test>alter system switch logfile;

System altered.

SYS@test>SELECT NAME FROM V$ARCHIVED_LOG WHERE FIRST_TIME = (SELECT MAX(FIRST_TIME) FROM V$ARCHIVED_LOG);

NAME
--------------------------------------------------------------------------------
/u01/archivelog/1_37_1020495413.dbf

SYS@test>

SYS@test>select SQL_REDO,SQL_UNDO from  logmin_tmp4 where table_name ='TEST4';

SQL_REDO
--------------------------------------------------------------------------------
SQL_UNDO
--------------------------------------------------------------------------------
create table test4 ( n4 number);


create table test4 ( n4 number);


insert into "ZBB"."TEST4"("N4") values ('4411');
delete from "ZBB"."TEST4" where "N4" = '4411' and ROWID = 'AAASMhAAHAADPP/AAA';


SQL_REDO
--------------------------------------------------------------------------------
SQL_UNDO
--------------------------------------------------------------------------------
insert into "ZBB"."TEST4"("N4") values ('422');
delete from "ZBB"."TEST4" where "N4" = '422' and ROWID = 'AAASMhAAHAADPP/AAB';

drop table test4 purge;



SYS@test>

3 启用补充日志 ,没有主键,查询结果 ,username列有用户名

ALTER DATABASE ADD SUPPLEMENTAL LOG DATA; 
SELECT SUPPLEMENTAL_LOG_DATA_MIN FROM V$DATABASE; 
alter system switch logfile; 
create table test5 ( n5 number ); 
insert into test5 values ( 5511); 
insert into test5 values ( 5522); 
commit;
connect / as sysdba 
alter system switch logfile; 
SELECT NAME FROM V$ARCHIVED_LOG WHERE FIRST_TIME = (SELECT MAX(FIRST_TIME) FROM V$ARCHIVED_LOG); 
EXECUTE DBMS_LOGMNR.ADD_LOGFILE(LOGFILENAME =>'/u01/archivelog/1_39_1020495413.dbf' ,OPTIONS => DBMS_LOGMNR.NEW);
EXECUTE DBMS_LOGMNR.START_LOGMNR(OPTIONS => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG);
create table logmin_tmp5 as select * from v$logmnr_contents
SELECT SQL_REDO , SQL_UNDO FROM V$LOGMNR_CONTENTS WHERE username='ZBB'; 
EXECUTE DBMS_LOGMNR.END_LOGMNR(); 


SYS@test>SELECT SUPPLEMENTAL_LOG_DATA_MIN FROM V$DATABASE;

SUPPLEME
--------
YES

SYS@test>alter system switch logfile;

System altered.

SYS@test>conn zbb/oracle
Connected.
ZBB@test>create table test5 ( n5 number );

Table created.

ZBB@test>insert into test5 values ( 5511);

1 row created.

ZBB@test>insert into test5 values ( 5522);

1 row created.

ZBB@test>commit;

Commit complete.

ZBB@test>conn / as sysdba
Connected.
SYS@test>alter system switch logfile;

System altered.

SYS@test>SELECT NAME FROM V$ARCHIVED_LOG WHERE FIRST_TIME = (SELECT MAX(FIRST_TI                                                                             ME) FROM V$ARCHIVED_LOG);

NAME
--------------------------------------------------------------------------------
/u01/archivelog/1_39_1020495413.dbf

SYS@test>
SYS@test>EXECUTE DBMS_LOGMNR.ADD_LOGFILE(LOGFILENAME =>'/u01/archivelog/1_39_1020495413.dbf' ,OPTIONS => DBMS_LOGMNR.NEW);

PL/SQL procedure successfully completed.

SYS@test>EXECUTE DBMS_LOGMNR.START_LOGMNR(OPTIONS => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG);

PL/SQL procedure successfully completed.

SYS@test>create table logmin_tmp5 as select * from v$logmnr_contents;

Table created.

SYS@test>

 4 测试,有主键,有补充日志, username列有用户名

ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;
SELECT SUPPLEMENTAL_LOG_DATA_MIN FROM V$DATABASE; 
alter system switch logfile; 
create table test6 ( n6 number primary key); 
insert into test6 values ( 6611); 
insert into test6 values ( 6622); 
commit;
connect / as sysdba 
alter system switch logfile; 
SELECT NAME FROM V$ARCHIVED_LOG WHERE FIRST_TIME = (SELECT MAX(FIRST_TIME) FROM V$ARCHIVED_LOG); 
EXECUTE DBMS_LOGMNR.ADD_LOGFILE(LOGFILENAME =>'/u01/archivelog/1_41_1020495413.dbf' ,OPTIONS => DBMS_LOGMNR.NEW);
EXECUTE DBMS_LOGMNR.START_LOGMNR(OPTIONS => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG);
SELECT SQL_REDO , SQL_UNDO FROM V$LOGMNR_CONTENTS WHERE username='ZBB'; 
EXECUTE DBMS_LOGMNR.END_LOGMNR(); 
create table logmin_tmp6 as select * from v$logmnr_contents;
select SQL_REDO,SQL_UNDO from logmin_tmp6 where table_name='TEST6';


SYS@test>SELECT SUPPLEMENTAL_LOG_DATA_MIN FROM V$DATABASE;

SUPPLEME
--------
YES

SYS@test>alter system switch logfile;

System altered.

SYS@test>conn zbb/oracle
Connected.
ZBB@test>create table test6 ( n6 number primary key);

Table created.

ZBB@test>insert into test6 values ( 6611);

1 row created.

ZBB@test>insert into test6 values ( 6622);

1 row created.

ZBB@test>commit;

Commit complete.

ZBB@test>conn / as sysdba
Connected.
SYS@test>alter system switch logfile;

System altered.

SYS@test>SELECT NAME FROM V$ARCHIVED_LOG WHERE FIRST_TIME = (SELECT MAX(FIRST_TIME) FROM V$ARCHIVED_LOG);

NAME
--------------------------------------------------------------------------------
/u01/archivelog/1_41_1020495413.dbf

SYS@test>EXECUTE DBMS_LOGMNR.ADD_LOGFILE(LOGFILENAME =>'/u01/archivelog/1_41_1020495413.dbf' ,OPTIONS => DBMS_LOGMNR.NEW);

PL/SQL procedure successfully completed.

SYS@test>EXECUTE DBMS_LOGMNR.START_LOGMNR(OPTIONS => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG);

PL/SQL procedure successfully completed.

SYS@test>create table logmin_tmp6 as select * from v$logmnr_contents;

Table created.

 以上的总结

有没有username列(该列显示是那个用户发起的session),和primary key 无关,和supplemental logging有关。

MOS上有个文档,需要修改个参数。就可以显示username列了。但是这个参数是被废弃的。没有修改成功(在11gr2 ,19c下都没有成功)。V$LOGMNR_CONTENTS Shows Blank USERNAME Column Value (文档 ID 727633.1)

END

-- 2019-12-17 add

关于为什么要用补充日志,下面的图说的很清楚。(另外,从上面的例子发现,在SQL_UNDO里面,是根据rowid来进行操作的。

但是不同的库可能数据块结构不一样,也就是说rowid不一样。所以还是需要使用补充日志,通过主键来进行操作。)

-下图摘自《企业级IT运维宝典之GoldenGate实战》

END

发布了754 篇原创文章 · 获赞 31 · 访问量 19万+

猜你喜欢

转载自blog.csdn.net/xxzhaobb/article/details/102857659
今日推荐