oracle數據庫日常維護手冊

數據庫操作分類

  • DDL:數據庫模式定義語言,關鍵字:create

  • DML:數據操縱語言,關鍵字:Insert、delete、update

  • DCL:數據庫控制語言 ,關鍵字:grant、remove

  • DQL:數據庫查詢語言,關鍵字:select

鎖表
爲什麼會鎖表?
DML鎖又可以分爲,行鎖、表鎖、死鎖

行鎖:當事務執行數據庫插入、更新、刪除操作時,該事務自動獲得操作表中操作行的排它鎖。

表級鎖:當事務獲得行鎖後,此事務也將自動獲得該行的表鎖(共享鎖),以防止其它事務進行DDL語句影響記錄行的更新。事務也可以在進行過程中獲得共享鎖或排它鎖,只有當事務顯示使用LOCK TABLE語句顯示的定義一個排它鎖時,事務纔會獲得表上的排它鎖,也可使用LOCK TABLE顯示的定義一個表級的共享鎖(LOCK TABLE具體用法請參考相關文檔)。

死鎖:當兩個事務需要一組有衝突的鎖,而不能將事務繼續下去的話,就出現死鎖。
如事務1在表A行記錄#3中有一排它鎖,並等待事務2在表A中記錄#4中排它鎖的釋放,而事務2在表A記錄行#4中有一排它鎖,並等待事務1在表A中記錄#3中排它鎖的釋放,事務1與事務2彼此等待,因此就造成了死鎖。死鎖一般是因拙劣的事務設計而產生。
死鎖只能使用SQL下:alter system kill session “sid,serial#”;或者使用相關操作系統kill進程的命令,如UNIX下kill -9 sid,或者使用其它工具殺掉死鎖進程。

DDL鎖又可以分爲:排它DDL鎖、共享DDL鎖、分析鎖

排它DDL鎖:創建、修改、刪除一個數據庫對象的DDL語句獲得操作對象的 排它鎖。如使用alter table語句時,爲了維護數據的完成性、一致性、合法性,該事務獲得一排它DDL鎖。
共享DDL鎖:需在數據庫對象之間建立相互依賴關係的DDL語句通常需共享獲得DDL鎖。 如創建一個包,該包中的過程與函數引用了不同的數據庫表,當編譯此包時,該事務就獲得了引用表的共享DDL鎖。

分析鎖:ORACLE使用共享池存儲分析與優化過的SQL語句及PL/SQL程序,使運行相同語句的應用速度更快。一個在共享池中緩存的對象獲得它所引用數據庫對象的分析鎖。分析鎖是一種獨特的DDL鎖類型,ORACLE使用它追蹤共享池對象及它所引用數據庫對象之間的依賴關係。當一個事務修改或刪除了共享池持有分析鎖的數據庫對象時,ORACLE使共享池中的對象作廢,下次在引用這條SQL/PLSQL語句時,ORACLE重新分析編譯此語句。

涉及的表

SELECT FROM v$lock;
SELECT
FROM v$sqlarea;
SELECT FROM v$session;
SELECT
FROM v$process ;
SELECT FROM v$locked_object;
SELECT
FROM all_objects;
SELECT * FROM v$session_wait;

--查看被鎖的表
select b.owner,b.object_name,a.session_id,a.locked_mode from v$locked_object a,dba_objects b where b.object_id = a.object_id;

--查看那個用戶那個進程照成死鎖
select b.username,b.sid,b.serial#,logon_time from v$locked_object a,v$session b where a.session_id = b.sid order by b.logon_time;

--查看連接的進程
SELECT sid, serial#, username, osuser FROM v$session;
--查某session 正在執行的sql語句,從而可以快速定位到哪些操作或者代碼導致事務一直進行沒有結束等.

SELECT
sql_text
FROM v$sqltext a
WHERE (a.hash_value, a.address) IN
(SELECT DECODE(sql_hash_value, 0, prev_hash_value, sql_hash_value),
DECODE(sql_hash_value, 0, prev_sql_addr, sql_address)
FROM v$session b
WHERE b.sid = '321') / 此處爲SID/
ORDER BY piece ASC;

--查出鎖定表的sid, serial#,os_user_name, machine_name, terminal,鎖的type,mode
SELECT s.sid, s.serial#, s.username, s.schemaname, s.osuser, s.process, s.machine,
s.terminal, s.logon_time, l.type
FROM v$session s, v$lock l
WHERE s.sid = l.sid
AND s.username IS NOT NULL
ORDER BY sid;

這個語句將查找到數據庫中所有的DML語句產生的鎖,還可以發現,
任何DML語句其實產生了兩個鎖,一個是表鎖,一個是行鎖。

--殺掉進程 sid,serial#
alter system kill session'111,12305';

誤刪數據恢復
刪除表數據有三種方式:delete、drop和truncate

delete誤刪除的解決方法
原理:

利用oracle提供的閃回方法,如果在刪除數據後還沒做大量的操作(只要保證被刪除數據的塊沒被覆寫),就可以利用閃回方式直接找回刪除的數據
具體步驟爲:
例如:
誤刪除了100條數據
刪除語句爲:
delete from 表名 where kid = '5';
確定刪除數據的時間(在刪除數據之前的時間就行,不過最好是刪除數據的時間點)
可以用一下語句找出執行刪除語句的時間
select r.FIRST_LOAD_TIME,r. from v$sqlarea r order by r.FIRST_LOAD_TIME desc ;
用以下語句找出刪除的數據:
select from 表名 as of timestamp to_timestamp('刪除時間點','yyyy-mm-dd hh24:mi:ss') where kid = '5'
select
from 表名 as of timestamp sysdate - 3/1440 where kid = '5' ; --3分鐘之前的數據
把刪除的數據重新插入原表:
注意要保證主鍵不重複。
insert into 表名 (select
from 表名 as of timestamp to_timestamp('刪除時間點','yyyy-mm-dd hh24:mi:ss') where kid = '5');
  insert into 表名 (select * from 表名 as of timestamp sysdate - 3/1440 where kid = '5');
如果表結構沒有發生改變,還可以直接使用閃回整個表的方式來恢復數據。
具體步驟爲:
表閃回要求用戶必須要有flash any table權限

--開啓行移動功能
·alter table 表名 enable row movement

--恢復表數據
·flashback table 表名 to timestamp to_timestamp(刪除時間點','yyyy-mm-dd hh24:mi:ss')
--關閉行移動功能 ( 千萬別忘記 )
·alter table 表名 disable row movement
drop、trancate誤刪除的解決方法
原理:由於oracle在刪除表時,沒有直接清空表所佔的塊,oracle把這些已刪除的表的信息放到了一個虛擬容器“回收站”中,而只是對該表的數據塊做了可以被覆寫的標誌,所以在塊未被重新使用前還可以恢復。
具體步驟:
查詢這個“回收站”或者查詢user_table視圖來查找已被刪除的表:
· select table_name,dropped from user_tables
· select object_name,original_name,type,droptime from user_recyclebin
在以上信息中,表名都是被重命名過的,字段table_name或者object_name就是刪除後在回收站中的存放表名
如果還能記住表名,則可以用下面語句直接恢復:
flashback table 原表名 to before drop
如果記不住了,也可以直接使用回收站的表名進行恢復,然後再重命名,參照以下語句:
flashback table "回收站中的表名(如:Bin$DSbdfd4rdfdfdfegdfsf==$0)" to before drop rename to 新表名
oracle的閃回功能除了以上基本功能外,還可以閃回整個數據庫:
使用數據庫閃回功能,可以使數據庫回到過去某一狀態, 語法如下:

SQL>alter database flashback on
SQL>flashback database to scn SCNNO;
SQL>flashback database to timestamp to_timestamp('2007-2-12 12:00:00','yyyy-mm-dd hh24:mi:ss');

誤更新恢復
可以用一下語句找出執行刪除語句的時間
select r.FIRST_LOAD_TIME,r.
from v$sqlarea r order by r.FIRST_LOAD_TIME desc ;
創建一個表保存取出的備份數據
create table 表名_bak
as
select
from 表名 as of timestamp sysdate -5/1440;
操作成功後你看看新表裏面是不是你之前的數據.如果是的話再把新表數據弄到原表就好了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章