復(fù)雜的故事簡(jiǎn)單說(shuō),復(fù)雜的問(wèn)題簡(jiǎn)單做碧注,您好嚣伐,這里是簡(jiǎn)露一手,歡迎瀏覽萍丐。
簡(jiǎn)述
16-7月轩端,一大型在線(xiàn)業(yè)務(wù)系統(tǒng)服務(wù)器突然一個(gè)個(gè)掛掉,重啟后不到撐不到五分鐘就犧牲逝变,導(dǎo)致生產(chǎn)系統(tǒng)業(yè)務(wù)故障基茵。
定位
因所有應(yīng)用都有問(wèn)題,且在未發(fā)布版本情況下突然發(fā)生壳影,預(yù)備進(jìn)行三個(gè)步驟排查定位拱层。
- 檢查數(shù)據(jù)庫(kù)情況.
- 檢查服務(wù)器日志.
- 檢查服務(wù)器網(wǎng)絡(luò)情況.
數(shù)據(jù)庫(kù)情況
這里不說(shuō)其它的檢查項(xiàng),直奔這次事因:“數(shù)據(jù)庫(kù)鎖”宴咧。
根據(jù)經(jīng)驗(yàn)根灯,我們進(jìn)行了數(shù)據(jù)庫(kù)鎖的檢查,幸運(yùn)的是直接找到了問(wèn)題點(diǎn)。
有一個(gè)業(yè)務(wù)表鎖的數(shù)量超過(guò)100烙肺,根據(jù)sql_id找出了所有sql芥驳,發(fā)現(xiàn)了全表鎖和鎖全表語(yǔ)句,是一條更新全表的update語(yǔ)句茬高。
查詢(xún)鎖:
select object_name as 對(duì)象名稱(chēng),s.sid,s.serial#,p.spid as 系統(tǒng)進(jìn)程號(hào),s.SQL_ID from v$locked_object l , dba_objects o , v$session s , v$process p where l.object_id=o.object_id and l.session_id=s.sid and s.paddr=p.addr;
查詢(xún)鎖表的語(yǔ)句:
select * from v$sql where sql_id='65gmqgahz6jp8'
處理
鎖一旦出現(xiàn) 兆旬,最簡(jiǎn)單的辦思路就是殺[kill]。
kill 分兩種:
- oracle 命令kill
ALTER SYSTEM KILL SESSION 'sid,serial#';
- 后臺(tái)殺oracle語(yǔ)句kill
kill -9 spid
<small>sid,serial#,spid 取值于 查詢(xún)鎖查詢(xún)結(jié)果怎栽。
開(kāi)始?xì)?/h3>
首殺
使用[oracle 命令]kill后 新的鎖又多了起來(lái)丽猬,改用[后臺(tái)殺]kill后,新的鎖仍在繼續(xù)熏瞄。
再查
分析鎖全部的update語(yǔ)句會(huì)話(huà)是oracle自己產(chǎn)生的脚祟,來(lái)源于存儲(chǔ)過(guò)程的概率比較大,在排查存儲(chǔ)過(guò)程中找到了它强饮,并根據(jù)它找到了一個(gè)job由桌,是job的重復(fù)執(zhí)行 導(dǎo)致了全表鎖的不斷產(chǎn)生。
二殺
刪除job后重新kill,第二次殺進(jìn)程后,情況并沒(méi)有好轉(zhuǎn),沒(méi)有了全表鎖邮丰,但是行鎖仍然多行您,問(wèn)題變得更為復(fù)雜。
再查
經(jīng)過(guò)漫長(zhǎng)的分析百種嘗試剪廉,最終找到來(lái)問(wèn)題.這是一個(gè)大意遺漏的點(diǎn)娃循。生產(chǎn)機(jī)器一般做了rac,有多個(gè)實(shí)例斗蒋,通過(guò)tns連接過(guò)去的會(huì)話(huà)一直在一個(gè)實(shí)例上捌斧,查看鎖情況始終只查看了一個(gè)實(shí)例的鎖情況,而oracle的job執(zhí)行 在兩個(gè)實(shí)例上都有可能存在泉沾。修改tns地址為第二個(gè)實(shí)例后捞蚂,在第二個(gè)實(shí)例上找到了好幾個(gè)全表鎖的進(jìn)程。
三殺
登陸到第二個(gè)實(shí)例上跷究,kill掉鎖的進(jìn)程后1分鐘不到姓迅,所有的鎖都降下去了,重啟應(yīng)用揭朝,恢復(fù)正常队贱。
總結(jié)
事情錯(cuò)綜,所以總結(jié)一下為兩點(diǎn)來(lái)將整體內(nèi)容再簡(jiǎn)化一下潭袱。
- 因: 生產(chǎn)業(yè)務(wù)表在業(yè)務(wù)繁忙期間執(zhí)行了全表更新語(yǔ)句柱嫌,與應(yīng)用上更新單條記錄的進(jìn)程形成循環(huán)鎖、阻塞屯换,導(dǎo)致整體應(yīng)用和數(shù)據(jù)庫(kù)問(wèn)題编丘。所以与学,生產(chǎn)業(yè)務(wù)表在業(yè)務(wù)繁忙期間應(yīng)禁止執(zhí)行全表更新語(yǔ)句。碰到必須在業(yè)務(wù)期間全表執(zhí)行則需采用分批更新和提交,來(lái)減小沖突的產(chǎn)生概率嘉抓,這里說(shuō)的全表更新包括更新語(yǔ)句沒(méi)有where條件和where條件的結(jié)果有大量數(shù)據(jù)的兩種情況索守。
- 果: 找出所有鎖,殺掉所有鎖抑片。需要注意的是:Job會(huì)不停產(chǎn)生更新任務(wù)卵佛。生產(chǎn)環(huán)境一般都做了rac,需檢查數(shù)據(jù)庫(kù)的多個(gè)實(shí)例,都進(jìn)行kill敞斋。
實(shí)際上這次事故處理時(shí)間有點(diǎn)長(zhǎng)截汪,中間停起應(yīng)用、分析日志這些都有做植捎,還有遷移接口衙解、排查代碼這些,處理的內(nèi)容也相當(dāng)多焰枢。回想起來(lái)做的事情就一項(xiàng)是有用的:找到所有鎖蚓峦,然后kill。