##########################################
redo:用來保障在故障時事務能夠被恢復。
undo:保障事務能夠被回滾或者撤銷。
redo
redo的功能主要有3個組件來實現:redo log buffer,lgwr後臺進程,redo log file(在歸檔模式下,redo log file最終會由ARCn進程寫爲歸檔日誌文件)。
redo log buffer位於SGA中,是一塊循環使用的內存區域。oracle會經過LGWR進程不斷的把redo log buffer的內容寫出到redo log file中。
查看默認日誌組:
日誌視圖:
desc v$log;
Name Null? Type
----------------- -------- ------------
GROUP# NUMBER
THREAD# NUMBER
SEQUENCE# NUMBER
BYTES NUMBER
BLOCKSIZE NUMBER
MEMBERS NUMBER
ARCHIVED VARCHAR2(3)
STATUS VARCHAR2(16)
FIRST_CHANGE# NUMBER
FIRST_TIME DATE
NEXT_CHANGE# NUMBER
NEXT_TIME DATE
select group#,members from v$log;
select a.group#,a.bytes,a.blocksize,a.status,b.member from v$log a join v$logfile b on a.group#=b.group#;
默認建立三個日誌組
1.current:活動狀態,當前正在被使用。
2.active:日誌是活動的非當前日誌,該日誌可能已經完成歸檔也可能沒有完成歸檔。
3.inactive:是非活動日誌,該日誌在實例恢復時不須要,在介質恢復時可能用到。INACTIVE狀態的日誌可能已經完成歸檔也可能沒有完成歸檔。在歸檔模式下,未完成歸檔以前,日誌文件不容許被覆蓋。
4.unused:該日誌未被寫入,這類日誌可能剛添加到數據庫或者resetlog以後被重置。
查看是否有log file switch等待時間
select sid,event,state from v$session_wait where event like '%log%';
log file switch的多個緣由:
(1)日誌文件太小,致使日誌切換過於頻繁。
(2)日誌組太少,不能知足正常事務量的需求
(3)日誌文件所在磁盤I/O存在瓶頸,致使寫出緩慢,阻塞數據庫正常運行。
(4)因爲數據文件磁盤I/O瓶頸,DBWR寫出過於緩慢。
(5)因爲事務量大,DBWR負荷太高,不堪重負。
解決方法:
(1)適當增長日誌大小
(2)適當增長日誌組數
(3)使用快速磁盤存儲日誌文件
(4)改善I/O性能
(5)使用多個DBWn進程或使用異步I/O等
//日誌塊的大小:
redo block sizes是源碼固定的,與操做系統無關,從X$kccle
select max(lebsz) from x$kccle;
MAX(LEBSZ)
----------
512
//獲取表結構
set long 9999;
select dbms_metadata.get_ddl('TABLE','EMP') from dual;
表建立基於tablespace建立
建立表前先建立表空間
查看redo日誌量
select a.name,b.value from v$statname a join v$mystat b on a.statistic#=b.statistic# where a.name='redo size';
NAME VALUE
---------------------------------------------------------------- ----------
redo size 0
create table s01(id int,name varchar(50),addr varchar(100),primary key(id));
select a.name,b.value from v$statname a join v$mystat b on a.statistic#=b.statistic# where a.name='redo size';
NAME VALUE
---------------------------------------------------------------- ----------
redo size 22024
###############################
LISN@orcl>select a.name,b.value from v$statname a join v$mystat b on a.statistic#=b.statistic# where a.name='redo size';
select a.name,b.value from v$statname a join v$mystat b on a.statistic#=b.statistic# where a.name='redo size';
NAME VALUE
---------------------------------------------------------------- ----------
redo size 712
LISN@orcl>create table s01(id int,name varchar(50),addr varchar(100),primary key(id));
create table s01(id int,name varchar(50),addr varchar(100),primary key(id));
Table created.
LISN@orcl>select a.name,b.value from v$statname a join v$mystat b on a.statistic#=b.statistic# where a.name='redo size';
select a.name,b.value from v$statname a join v$mystat b on a.statistic#=b.statistic# where a.name='redo size';
NAME VALUE
---------------------------------------------------------------- ----------
redo size 16976
LISN@orcl>insert into s01(id) select rownum from dual connect by level < 1000;
insert into s01(id) select rownum from dual connect by level < 1000;
999 rows created.
LISN@orcl>select a.name,b.value from v$statname a join v$mystat b on a.statistic#=b.statistic# where a.name='redo size';
select a.name,b.value from v$statname a join v$mystat b on a.statistic#=b.statistic# where a.name='redo size';
NAME VALUE
---------------------------------------------------------------- ----------
redo size 89088
LISN@orcl>delete from s01;
delete from s01;
999 rows deleted.
LISN@orcl>select a.name,b.value from v$statname a join v$mystat b on a.statistic#=b.statistic# where a.name='redo size';
select a.name,b.value from v$statname a join v$mystat b on a.statistic#=b.statistic# where a.name='redo size';
NAME VALUE
---------------------------------------------------------------- ----------
redo size 546636
insert into s01 select rownum from dual connect by level < 100000;
//建立即增長redo日誌logfile
alter database add logfile group 4 '/u01/app/oracle/oradata/orcl/redo04.log' size 50m;
select group#,status from v$log;
GROUP# STATUS
---------- ----------------
1 ACTIVE
2 INACTIVE
3 INACTIVE
4 CURRENT
//手動強制切換日誌文件
alter system switch logfile;
查看
select group#,status from v$log;
GROUP# STATUS
---------- ----------------
1 ACTIVE
2 CURRENT
3 INACTIVE
4 ACTIVE
////能夠刪除inactive redo log
LISN@orcl>alter database drop logfile group 3;
//手動刪除日誌文件,釋放存儲空間:
[root@nan86 orcl]# pwd
/u01/app/oracle/oradata/orcl
[root@nan86 orcl]# rm -f redo03.log
//歸檔日誌的查詢:
系統管理員可查
desc v$archived_log
查詢歸檔日誌名 歸檔時間 大小 blocks爲塊數
select name,completion_time,blocks*block_size/1024/1024 size_mb from v$archived_log;
###undo
undo詳解:認爲undo用於數據庫物理恢復到執行語句或事務以前的樣子,其實數據庫只是邏輯地恢復到原來的樣子,全部修改都是邏輯的取消。可是數據結構以及數據庫自己在回滾後可能大不相同。
set autotrace on explain;
set autotrace on;
create table t as select * from all_objects where 1=0;
select * from t;
insert into t select * from all_objects;
select count(*) from t;
COUNT(*)
----------
71498
rollback;
事務的混滾是邏輯回滾
select count(*) from t;
COUNT(*)
----------
0
set autotrace on statistics;
//查看alter trace日誌
SYS@orcl>show parameter user_dump_dest;
show parameter user_dump_dest;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
user_dump_dest string /u01/app/oracle/diag/rdbms/orcl/orcl/trace
alter日誌命名方式:alter_$ORACLE_SID.log
數據庫