Oracle Supplemental 补全日志介绍
轉(zhuǎn)。
Oracle補(bǔ)全日志(Supplemental logging)特性因其作用的不同可分為以下幾種:最小(Minimal),支持所有字段(all),支持主鍵(primary key),支持唯一鍵(unique),支持外鍵(foreign key)。包括LONG,LOB,LONG RAW及集合等字段類型均無法利用補(bǔ)全日志。
最小(Minimal)補(bǔ)全日志開啟后可以使得logmnr工具支持鏈?zhǔn)叫?#xff0c;簇表和索引組織表。可以通過以下SQL檢查最小補(bǔ)全日志是否已經(jīng)開啟:
| SELECT supplemental_log_data_min FROM v$database; |
若結(jié)果返回YES或IMPLICIT則說明已開啟最小補(bǔ)全日志,當(dāng)使用ALL,PRIMARY,UNIQUE或FOREIGN補(bǔ)全日志時(shí)最小補(bǔ)全日志默認(rèn)開啟(即檢查結(jié)果為IMPLICIT)。
一般情況下我們?cè)谑褂眠壿媯鋷?kù)時(shí)啟用主鍵和惟一鍵的補(bǔ)全日志,而有時(shí)表上可能沒有主鍵,惟一鍵或唯一索引;我們通過以下實(shí)驗(yàn)總結(jié)這種情況下Oracle的表現(xiàn)。
首先建立相關(guān)的測(cè)試表:
| alter database add supplemental log data (primary key,unique index) columns ; ? create table test (t1 int , t2 int ,t3 int ,t4 int ); alter table test add constraint pk_t1 primary key (t1); --添加主鍵 隨后使用循環(huán)插入一定量的數(shù)據(jù) update test set t2=10;?????? commit;?? -- 更新數(shù)據(jù) |
使用LOGMNR工具分析之前的操作,可以看到REDO中記錄的SQL形式如下:
| update "SYS"."TEST" set "T2" = '10' where "T1" = '64' and "T2" = '65' and ROWID = 'AAAMiSAABAAAOhiAA/'; |
其中where字句后分別記錄了主鍵值,被修改字段的值和原行的ROWID。
現(xiàn)在我們將原表上的主鍵去掉來觀察。
| alter table test drop constraint pk_t1 ; ? update test set t2=11;?????? commit;?? -- 更新數(shù)據(jù) 使用LOGMNR分析可以發(fā)現(xiàn),REDO中的SQL記錄如下: update "SYS"."TEST" set "T2" = '11' where "T1" = '1' and "T2" = '10' and "T3" = '3' and "T4" = '4' and ROWID = 'AAAMiSAABAAAOhiAAA'; |
當(dāng)沒有主鍵的情況下,where子句后記錄了所有列值和ROWID。
| 以下實(shí)驗(yàn)在存在唯一索引情況下的表現(xiàn) ? create unique index pk_t1 on test(t1); update test set t2=15; commit; 使用LOGMNR分析可以發(fā)現(xiàn),REDO中的SQL記錄如下: update "SYS"."TEST" set "T2" = '15' where "T1" = '9' and "T2" = '11' and "T3" = '11' and "T4" = '12' and ROWID = 'AAAMiSAABAAAOhiAAI'; 以上是t1列有唯一索引但不限定not null的情況,下面我們加上not null限制 alter table test modify t1 not null; update test set t2=21; commit; 使用LOGMNR分析可以發(fā)現(xiàn),REDO中的SQL記錄如下: update "SYS"."TEST" set "T2" = '21' where "T1" = '2' and "T2" = '15' and ROWID = 'AAAMiSAABAAAOhiAAB'; |
如以上SQL所示,在存在唯一索引的情況下where子句后仍記錄了所有列和ROWID;在存在唯一索引和非空約束的情況下表現(xiàn)與存在主鍵的情況一致。
當(dāng)某個(gè)表上的列數(shù)量較多時(shí)且沒有主鍵或唯一索引和非空約束的情況下,開啟補(bǔ)全日志可能導(dǎo)致重做日志總量大幅提高。
| 首先建立一個(gè)存在250列的表: ? Drop table test; create table test ( t1 varchar2(5), t2 varchar2(5), t3 varchar2(5), t4 varchar2(5),? …t250 varchar2(5)) ? insert into test values ('TEST','TEST' ……);?? commit; --將255個(gè)列填入數(shù)據(jù) alter database drop supplemental log data (primary key,unique index) columns;? --關(guān)閉補(bǔ)全日志 set autotrace on; update test set t2='BZZZZ' where t1='TEST'; commit; 可以從自動(dòng)跟蹤信息中看到,本條更新產(chǎn)生了516的重做量。 alter database add supplemental log data (primary key,unique index) columns;? --重新開啟補(bǔ)全日志 update test set t2='FSDSD' where t1='TEST'; 跟蹤信息顯示產(chǎn)生了3044的重做量。 |
補(bǔ)全日志因作用域的不同又可分為數(shù)據(jù)庫(kù)級(jí)的和表級(jí)的。表級(jí)補(bǔ)全日志又可以分為有條件的和無條件的。有條件限制的表級(jí)補(bǔ)全日志僅在特定列被更新時(shí)才會(huì)起作用,有條件限制的表級(jí)補(bǔ)全日志較少使用,這里我們不做討論。
下面我們來觀察無條件限制表級(jí)補(bǔ)全日志的具體表現(xiàn):
| alter database drop supplemental log data (primary key,unique index) columns; ? alter table test add supplemental log data (primary key,unique index) columns; update test set t2='ZZZZZ'; commit; 使用LOGMNR工具查看redo中的SQL: 可以發(fā)現(xiàn)where子句之后包含了所有列值。 delete test; commit; 使用LOGMNR工具查看redo中的SQL: delete from "SYS"."TEST" where "T1" = 'TEST' and "T2" = 'ZZZZZ' and "T3" = 'TEST' and "T4" = 'TEST' and "T5" …… delete操作同樣在where子句之后包含了所有列值。 又我們可以針對(duì)表上字段建立特定的補(bǔ)全日志組,以減少where子句后列值的出現(xiàn)。 alter table test drop supplemental log data (primary key,unique index) columns;? --關(guān)閉表上原先的補(bǔ)全日志 alter table test add supplemental log group test_lgp (t1 ,t2,t3,t4,t5,t6,t12,t250) always; --創(chuàng)建補(bǔ)全日志組 update test set t2='XXXXX' ; commit; 使用LOGMNR工具查看redo中的SQL: update "SYS"."TEST" set "T2" = 'XXXXX' where "T1" = 'TEST' and "T2" = 'TEST' and "T3" = 'TEST' and "T4" = 'TEST' and "T5" = 'TEST' and "T6" = 'TEST' and "T12" = 'TEST' and "T250" = 'TEST' and ROWID = 'AAAMieAABAAAOhnAAA'; 如上所示重做日志中正確地顯示了UPDATE操作中用戶指定的字段值。 delete test; 使用LOGMNR工具查看redo中的SQL: delete from "SYS"."TEST" where "T1" = 'TEST' and "T2" = 'XXXXX' and "T3" = 'TEST' …… delete操作在重做日志中仍然保留了所有列值。 |
針對(duì)字段較多的表,我們?cè)谀軌蛞远鄠€(gè)列保證數(shù)據(jù)唯一性且非空的情況下(即應(yīng)用概念上的主鍵)來指定表上的補(bǔ)全日志組,以減少update操作時(shí)所產(chǎn)生的重做日志,而對(duì)于delete操作則無法有效改善。
轉(zhuǎn)載于:https://www.cnblogs.com/andy6/p/5721118.html
總結(jié)
以上是生活随笔為你收集整理的Oracle Supplemental 补全日志介绍的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jQuery加载一个html页面到指定的
- 下一篇: 散列表的初步实现