oracle的redo與undio

##########################################
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

數據庫

相關文章
相關標籤/搜索