oracle數據庫平常維護手冊

數據庫操做分類sql

  • DDL:數據庫模式定義語言,關鍵字:create
  • DML:數據操縱語言,關鍵字:Insert、delete、update
  • DCL:數據庫控制語言 ,關鍵字:grant、remove
  • DQL:數據庫查詢語言,關鍵字:select

鎖表數據庫

爲何會鎖表?緩存

DML鎖又能夠分爲,行鎖、表鎖、死鎖session

 

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

 

表級鎖:當事務得到行鎖後,此事務也將自動得到該行的表鎖(共享鎖),以防止其它事務進行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鎖。spa

共享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;

操做成功後你看看新表裏面是否是你以前的數據.若是是的話再把新表數據弄到原表就行了

相關文章
相關標籤/搜索