表空間狀态-READ ONLY、READ WRITE
1. 隻讀表空間的主要用途就是為了消除對資料庫大部分靜态資料的備份和恢複的需要。Oracle不會更新隻讀表空間愛你的檔案,是以這部分檔案可以存儲于隻讀媒體中,例如CD-ROM或WORM drives。
2. 隻讀表空間并不是為了滿足歸檔的要求。隻讀表空間不能修改。如果需要修改隻讀表空間中的記錄,則需要先将表空間置為read/write。更新表空間後,可以重置為隻讀。
3. 由于隻讀表空間不能修改,是以隻要沒有置為read/write,就不需要重複地進行備份。而且,如果需要恢複資料庫時,也不需要恢複隻讀表空間,原因就是他們未曾修改過。
4. 能從隻讀表空間中删除對象,例如表或索引,但不能建立或修改對象。可以執行修改資料字典中檔案描述的語句,例如ALTER TABLE ... ADD或ALTER TABLE ... MODIFY,但不能添加任何新的描述資訊,除非表空間置為read/write。
5. 隻讀表空間可以導出導入到其他資料庫。既然隻讀表空間不能修改,他們就能存儲于CD-ROM或WORM(一次寫-多次讀)這些設施中。
6. 所有表空間初始建立都是read/write。使用READ ONLY子句可以設定表空間為隻讀。前提是必須具有ALTER TABLESPACE或MANAGE TABLESPACE的系統權限。
使用ALTER TABLESPACE ... READ ONLY前,需要滿足以下條件:
> 表空間處于online狀态。這是為了確定不會有UNDO資訊需要應用到表空間。注:如果處于offline,則會将UNDO資訊存儲于SYSTEM表空間,待恢複online時應用這些UNDO資訊。
> 不能修改活動的UNDO表空間或SYSTEM表空間。
> 表空間不能處于目前正在進行的online備份中,因為備份結束時會更新表空間所有資料檔案的頭部資訊。
> 為了讓從隻讀表空間讀取資料得到更好的性能,可以在置為read-only之前執行一次通路表空間的表中所有資料塊的查詢。一個像SELECT COUNT(*)這樣簡單的查詢,就可以確定在表空間的資料塊在接下來的通路中獲得最佳的效率。因為這種做法就不需要資料庫檢查最近經常修改資料塊的交易狀态。
7. 可以在資料庫正處理交易的時候執行ALTER TABLESPACE ... READ ONLY語句。執行語句後,表空間就處于交易隻讀狀态。不會允許任何交易(DML操作)應用于表空間。如果嘗試進行交易操作,那麼此操作會被終止和復原。然而,那些已經做了變更并不再進行進一步修改的交易,就允許執行commit或roll back操作。
如果ALTER TABLESPACE ... READ ONLY語句執行前,一個交易已經執行了,但是復原到一個儲存點,復原了他對表空間的變更,那麼ALTER TABLESPACE ... READ ONLY語句不會等待這個活動的交易。
8. 交易級隻讀狀态僅僅當初始化參數COMPATIBLE是8.1.0或以上值時才能使用。如果參數值小于8.1.0,并且存在活動的交易,ALTER TABLESPACE ... READ ONLY語句會失敗。
9. 如果ATLER TABLESPACE語句執行時間太長了,那麼就需要找到阻止隻讀狀态生效的那些交易。如下語句可以找出執行ALTER TABLESPACE ... RAED ONLY語句的交易入口和session位址(saddr):
SELECT SQL_TEXT, SADDR
FROM V$SQLAREA,V$SESSION
WHERE V$SQLAREA.ADDRESS = V$SESSION.SQL_ADDRESS AND SQL_TEXT LIKE 'alter tablespace%';
SQL_TEXT SADDR
---------------------------------------- --------
alter tablespace tbs1 read only 80034AF0
每個活動交易的開始SCN會存儲于V$TRANSACTION視圖中。起始SCN越小,說明這步操作就越早。潛在地這條語句越可能阻止接下來隻讀狀态的變更。
SELECT SES_ADDR, START_SCNB
FROM V$TRANSACTION
ORDER BY START_SCNB;
SES_ADDR START_SCNB
-------- ----------
800352A0 3621 --> waiting on this txn
80035A50 3623 --> waiting on this txn
80034AF0 3628 --> this is the ALTER TABLESPACE statement
80037910 3629 --> don't care about this txn
可以用如下語句找到阻塞交易的使用者:
SELECT T.SES_ADDR, S.USERNAME, S.MACHINE
FROM V$SESSION S, V$TRANSACTION T
WHERE T.SES_ADDR = S.SADDR
ORDER BY T.SES_ADDR
SES_ADDR USERNAME MACHINE
-------- -------------------- --------------------
800352A0 DAVIDB DAVIDBLAP --> Contact this user
80035A50 MIKEL LAB61 --> Contact this user
80034AF0 DBA01 STEVEFLAP
80037910 NICKD NICKDLAP
将表空間置為read-only後,建議立即備份。隻要表空間一直處于隻讀狀态,那就不需要再次地備份,因為不會有對表空間的更新。
10. 使用LATER TABLESPACE ... READ WRITE語句可以恢複隻讀表空間,前提是具有ALTER TABLESPACE或MANAGE TABLESPACE權限。
表空間置為read/write的前提條件還需要表空間中的所有資料檔案以及表空間自身都處于online狀态。可以使用ALTER DATABASE ... DATAFILE ... ONLINE語句将資料檔案置為online狀态。V$DATAFILE視圖顯示了資料檔案目前的狀态。
将表空間置為可寫模式,需要更新控制檔案,目的就是為了可以使用資料檔案的隻讀版本作為恢複的起始點。
11. 在WORM裝置中建立一個隻讀表空間。
(1) 建立一個可寫表空間。建立對象、插入資料。
(2) 将表空間置為read-only隻讀模式。
(3) 使用作業系統指令将表空間的資料檔案複制到WORM裝置。
(4) 将表空間置為offline狀态。
(5) 重命名資料檔案以符合拷貝到WORM裝置中的資料檔案命名規範。使用ALTER TABLESPACE ... RENAME DATAFILE語句,重命名資料檔案的操作會修改控制檔案。
(6) 将表空間恢複為online狀态。
實驗:
1. 設定表空間為read only狀态:
SQL> alter tablespace dcsopen_tbs read only;
Tablespace altered.
2. 檢視資料檔案狀态:
SQL> select file#, name, status from v$datafile where file#=11;
FILE# NAME STATUS
----- ------------------------------------------------------- ------------------------
11 /oracle/oradata_petest/petest/dcsopen_tbs02.dbf ONLINE
3. 登入到隻讀表空間:
SQL> select * from test1;
T1ID T1V
---------- ----------
1 t1
2 t2
3 t3
可以讀其中的表。
SQL> insert into test1 values(12, 't12');
insert into test1 values(12, 't12')
*
ERROR at line 1:
ORA-00372: file 7 cannot be modified at this time
ORA-01110: data file 7: '/oracle/oradata_petest/petest/dcsopen_tbs01.dbf'
執行交易操作時提示7号資料檔案此時不能修改。