国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > 綜合 > 正文

關(guān)于數(shù)據(jù)庫的鎖相關(guān)問題及其引申思想

2024-07-21 02:36:30
字體:
供稿:網(wǎng)友

  問題背景:考慮到我局內(nèi)部數(shù)據(jù)庫關(guān)系復(fù)雜,“死鎖”現(xiàn)象時(shí)有發(fā)生,而據(jù)我所知,目前的系統(tǒng)死鎖發(fā)現(xiàn)機(jī)制,全憑人工干預(yù),發(fā)現(xiàn)死鎖需要手工運(yùn)行相應(yīng)腳本或者得到用戶的“舉報(bào)”,然后根據(jù)腳本查詢結(jié)果,調(diào)用相應(yīng)命令殺死要害進(jìn)程,。
  
  
  實(shí)現(xiàn)目標(biāo):解決以往人工干預(yù)的弊端,及時(shí)快速的發(fā)現(xiàn)問題,解決問題,在用戶“舉報(bào)”之前解決問題。
  
  分析問題:實(shí)現(xiàn)目標(biāo)重在“及時(shí)性”。原有思想有兩個(gè):
  1、 采用報(bào)警機(jī)制,即在出現(xiàn)死鎖的時(shí)候采用郵件通知之類的方式告訴治理員,然后由治理員查殺死鎖進(jìn)程。
  2、 采用自動判定、自動解除死鎖的機(jī)制,同時(shí)可以記錄相應(yīng)操作。
  結(jié)合兩種思路,分析其實(shí)現(xiàn)的可行性和優(yōu)劣性。
  方案1:這種思路主要是出于安全性考慮,在查殺進(jìn)程方面,人工判定究竟相對來說比較安全可靠,不至于亂操作。但是,對于“及時(shí)性”要求還不能滿足,因?yàn)槲覀儫o法保證治理員能按時(shí)查看郵件(因?yàn)樗豢赡芸偸窃陔娔X前盯著屏幕)。
  方案2:這種思路主要是出于“及時(shí)性”考慮,也就是說,對于死鎖,一經(jīng)發(fā)現(xiàn),立斃無疑。
  
  個(gè)人認(rèn)為方案2比較可行,在查找資料的過程中,都是以基于方案2的思路展開的。
  
  具體解決步驟:
  死鎖,從定義上講,即:同一進(jìn)程集合中的每一個(gè)進(jìn)程都在等待同一集合中的其他進(jìn)程釋放資源。這便是真正意義上的死鎖,而我們結(jié)合具體問題,賦予我們這的“死鎖”兩種概念。其一、上述概念中的死鎖,亦稱真正意義上的死鎖。其二,“假死鎖”,也就是鎖等待現(xiàn)象,等待時(shí)間過長也被判作死鎖。
  所以,考慮到這兩種鎖,我們實(shí)際上可以用同一種名詞予以描述,即“鎖等待”,不同的是,第一種鎖是“無限期鎖等待”,第二種鎖是“有限期鎖等待”。
  
  要實(shí)現(xiàn)方案2中的目標(biāo),首先我們需要一個(gè)駐留在系統(tǒng)中的不斷定時(shí)執(zhí)行的進(jìn)程,該進(jìn)程的作用是查殺用戶見死鎖進(jìn)程,并匯報(bào)結(jié)果。下面先就如何使一個(gè)進(jìn)程在系統(tǒng)中定時(shí)執(zhí)行展開討論。
  【如何使一個(gè)自定義的進(jìn)程定時(shí)執(zhí)行?】
  方法一,采用Oracle提供的DBMS_JOB包來實(shí)現(xiàn)。
  步驟1、構(gòu)造一個(gè)實(shí)現(xiàn)既定目標(biāo)的自定義過程。例如:
  SQL>Create or replace PRocedure test as
  Begin
  ……
  語句段;
  ……,
  end;
  這樣便創(chuàng)建好了一個(gè)過程。下面就是要使其自動執(zhí)行了。
  步驟二、定義一個(gè)返回JOB號的參數(shù),并創(chuàng)建過程。
  SQL>variable job1 number
  SQL>begin
  DBMS_JOB.submit(:job1,’test;’,sysdate,sysdate+1/1440’);
  ――天天1440分鐘,即一分鐘運(yùn)行test過程以此,間隔可自定;
  end;
  /
  步驟三,運(yùn)行該JOB。
  SQL>begin
  DBMS_job.run(:job1);
  End;
  /
  這樣便創(chuàng)建出了自己定義的進(jìn)程,而且能夠定時(shí)執(zhí)行。
  當(dāng)不需要的時(shí)候可以刪除JOB。
  SQL> begin
  Dbms_JOB.remove(:job1);
  End;
  要?jiǎng)h除特定進(jìn)程,可以通過查詢user/all/dba-jobs視圖中的job字段,然后通過DBMS_job.remove刪掉。
  
  (Oracle提供的程序包很有用,下面還將陸續(xù)提到的主要有DBMS_Alert, DBMS_pipe, DBMS_output, UTL_file等,具體用法可以查詢幫助信息,或通過OEM工具直接查看這些包的源代碼).
  
  方法二:采用快照和觸發(fā)器結(jié)合使用以達(dá)到定時(shí)執(zhí)行的目的。
  已經(jīng)知道的是快照刷新可以定時(shí)執(zhí)行,這在創(chuàng)建快照的時(shí)候便已經(jīng)定義了其刷新間隔,因此很輕易結(jié)合觸發(fā)器思想定時(shí)執(zhí)行相應(yīng)操作。
  例如:
  create snapshot 快照名 refresh next round(sysdata+0.5)+116/144
  as select * from dual;
  天天完19:20執(zhí)行,這個(gè)快照什么也不錯(cuò),只是為了觸發(fā)下面的觸發(fā)器。
  Create or replace trigger 觸發(fā)器名 before insert on 快照基表 for each row
  Begin
  …..;
  自定義過程語句;
  …….
  Exception when other then
  錯(cuò)誤提示;
  end;
  這樣就可以根據(jù)快照的刷新間隔調(diào)用自定義的PL/SQL過程了。
  
  說明:通過上述思想實(shí)現(xiàn)的定時(shí)執(zhí)行操作,必須結(jié)合操作系統(tǒng)中的進(jìn)程調(diào)度算法考慮,也就是說,并不是你定義的間隔是多少,它就多長時(shí)間執(zhí)行一次。
  因?yàn)檫@其中需要涉及到操作系統(tǒng)的時(shí)間片分配,實(shí)際的時(shí)間間隔最后將會是時(shí)間片的整數(shù)倍。因此應(yīng)該意識到這一點(diǎn),尤其是當(dāng)前的服務(wù)器中運(yùn)行的進(jìn)程數(shù)量眾多的情況下,這種時(shí)間“差距”體現(xiàn)的更加明顯。

  
  到這一步,關(guān)于自定義過程的定時(shí)執(zhí)行,我們已經(jīng)解決了。那么下一步就是發(fā)現(xiàn)死鎖進(jìn)程,并對其進(jìn)行操作。
  【如何發(fā)現(xiàn)死鎖進(jìn)程?】
  有很多腳本可以發(fā)現(xiàn)死鎖進(jìn)程,以下提供的一個(gè)腳本,也能實(shí)現(xiàn)這項(xiàng)要求。
  首先創(chuàng)建幾個(gè)基表及索引:
  create table My_session as
  select a.username,a.sid,a.serial#,a.lockwait,a.machine,a.status,a.last_call_et,
  a.sql_hash_value,a.program
  from v$session a
  where 1=2;
  create unique index my_session_ul on my_session(sid);
  create index my_session_n2 on my_session(lockwait);
  create index my_session_n3 on my_session(sql_hash_value);
  
  Create table my_lock as
  Select id1,kaddr,sid,request,type
  From v$lock
  Where 1=2;
  
  Create index my_lock_n1 on my_lock(sid);
  Create index my_lock_n2 on my_lock(kaddr);
  
  Create table my_sqltext as
  Select hash_value,sql_text
  From v$sqltext
  Where 1=2;
  Create index my_sqltext_n1 on my_sqltext(hash_value);
  
  (從V$session,V$lock,V$sqltext視圖中取出字段,創(chuàng)建my_sqlText表,并在查詢要用到的字段上創(chuàng)建索引,加快查詢速度)
  然后構(gòu)造SQL腳本如下:
  
  
  Set echo off
  set feedback off
  prompt '刪除舊記錄...'
  truncate table my_session;
  truncate table my_lock;
  truncate table my_sqltext;
  
  prompt '獲取數(shù)據(jù)....'
  insert into my_session
  select a.username,a.sid,a.serial#,a.lockwait,a.machine,a.status,
  a.last_call_et,a.sql_hash_value,a.program
  From v$session a
  where nvl(a.username,'NULL')<>'NULL';
  
  insert into my_lock
  select id1,kaddr,sid,request,type
  from v$lock;
  
  insert into my_sqltext
  select hash_value,sql_text
  from v$sqltext s,my_session m
  where s.hash_value=m.sql_hash_value;
  
  column username format a10
  column machine format a15
  column last_call_et format 99999 heading "seconds"
  column sid format 9999
  
  prompt "正在等待別人的用戶"
  select a.sid,a.serial#,
  a.machine,a.last_call_et,a.username,b.id1
  from my_session a,my_lock b
  where a.lockwait=b.kaddr;
  
  prompt "被等待的用戶..."
  select a.sid,a.serial#,a.machine,a.last_call_et,a.username,
  b.type,a.status,b.id1
  from my_session a,my_lock b
  where b.id1 in
  (select distinct e.id1
  from my_session d,my_lock e
  where d.lockwait=e.kaddr)
  and a.sid=b.sid
  and b.request=0;
  
  prompt "查出其 SQL.."
  select a.username,a.sid,a.serial#,a.status,a.last_call_et,b.id1,b.type,c.sql_text
  from my_session a,my_lock b, my_sqltext c
  where b.id1 in
  (select distinct e.id1
  from my_session d,my_lock e
  where d.lockwait=e.kaddr)
  and a.sid=b.sid
  and b.request=0
  and c.hash_value=a.sql_hash_value;
  這樣便可以查出死鎖進(jìn)程。
  【如何根據(jù)查出的死鎖進(jìn)程自動調(diào)用語句殺死進(jìn)程?】
  這涉及到查詢字段和自定義變量的信息互通,普通的SQL中的查詢語句select出的字段只是供屏幕輸出之用,而我們最終的實(shí)現(xiàn)思想則是要根據(jù)上面的那幾個(gè)查詢出來的字段數(shù)據(jù)作相應(yīng)處理操作。
因此如何將這些字段數(shù)據(jù)和DBA命令中的參數(shù)掛鉤,是能夠自動執(zhí)行殺進(jìn)程的很重要的一點(diǎn)。
  對于單條記錄,可以采用select…into語句將用戶查詢的記錄數(shù)據(jù)賦給PL/SQL變量。對于多條記錄,則應(yīng)該采用游標(biāo)(cursor)來實(shí)現(xiàn)。
  由于查出的死鎖進(jìn)程可能不止一個(gè),因此需要使用游標(biāo)(cursor)記錄下數(shù)據(jù),再自動kill掉。
  這方面的內(nèi)容需要在自定義過程中完成,具體的細(xì)節(jié)問題在此不一一細(xì)列。
  【在查殺進(jìn)程的過程中自動產(chǎn)生報(bào)警信息】
  1. 關(guān)于DBMS_Alert包的應(yīng)用。
  當(dāng)數(shù)據(jù)庫中發(fā)生了一個(gè)事件時(shí),用DBMS_ALERT包對一個(gè)會話提出警告,用戶的會話登記所關(guān)心的事件,當(dāng)該事件發(fā)生時(shí),這個(gè)警告就給會話發(fā)出信號。該包中有以下幾個(gè)模塊。
  名稱 說明
  REGISTER 注冊登記用戶的會話關(guān)心一個(gè)警告
  REMOVE 告訴數(shù)據(jù)庫用戶的會話取消警告關(guān)聯(lián)
  REMOVEALL 從所有的警告注冊表中刪除用戶的會話
  SET_DEFAULTS 設(shè)置包開始一個(gè)檢查循環(huán)時(shí)的等待事件
  SIGNAL 發(fā)出警告

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 贺兰县| 海丰县| 乌拉特前旗| 慈溪市| 巢湖市| 同德县| 若羌县| 红安县| 湟中县| 岢岚县| 嵊州市| 高淳县| 启东市| 大英县| 南华县| 定结县| 贵南县| 交口县| 东港市| 喀什市| 龙岩市| 乌拉特中旗| 侯马市| 内黄县| 大同市| 义乌市| 绥芬河市| 洪雅县| 抚远县| 灌阳县| 桃源县| 吉首市| 邓州市| 五峰| 洞头县| 建水县| 牡丹江市| 沿河| 黔江区| 视频| 宁海县|