Gbase8t(Informix)死鎖問題

最近壓測國產數據庫Gbase8t,內核是Informix,壓測中遇到問題以下:前端

 Could not do a physical-order read to fetch netxt rowsql

解決方式:數據庫

一、設置鎖的級別從表變成行
  ALTER TABLE <table name> LOCK MODE (ROW) 
   update statistics high 
   SET LOCK MODE TO WAIT 10 (10ms)服務器

二、這個問題一般是由於鎖表產生的。要麼是多個用戶同時訪問數據庫致使該問題,要麼是由於某個進程死了之後資源未釋放致使的。若是是前一種狀況,能夠考慮將數據庫表的鎖級別改成行鎖,來減小撞鎖的機會;或在應用程序中,用set lock mode wait 3這樣的語句,在撞鎖後等待若干秒重試。若是是後一種狀況,能夠在數據庫端用onstat -g ses/onstat   -g   sql/onstat   -k等命令找出鎖表的進程,用onmode   -z命令結束進程;若是不行,就須要從新啓動數據庫來釋放資源。session

方法一
Onmode -u 將數據庫服務器強行進入單用戶模式,來釋放被鎖的表。生產環境不適合。
方法二
1:$ onstat -k | grep HDR+X
HDR+X 爲排他鎖
HDR 頭 
X 互斥 
owner 
是正持有鎖的線程的共享內存地址
2:$ onstat -u |grep c60a363c
c60a363c 爲1中查到的owner內容。
sessid 
是會話標識符編號
3:$ onstat -g ses sessid
根據sessid獲得進程pid
pid 
與此會話的前端關聯的進程標識 
$ onstat -g sql sessid 
經過上面命令查看執行的sql語句
4:$ ps -ef |grep pid
由此,咱們可獲得鎖表的進程,可根據實際鎖表進程的重要程度的具體狀況採起相映處理方法:
對於重要且該進程能夠自動重聯數據庫的進程,能夠用onmode  -z sesid 的方法殺掉鎖表session,
$ onmode –z sessid
不然也可直接殺掉鎖表的進程 kill pid。
$ kill -9 pid
 
將表的頁鎖改成行鎖   
  參考語句爲   
  unload   to   optimize.sql   delimiter   ""   select   'alter   table   '||tabname||     
  '   lock   mode(row)'||';'from   systables   where     locklevel="P"   and   tabid   >   99   
  將卸載的optimize.sql稍微刪除一下其中出現的字符或亂碼,後運行,便可把表的頁鎖改成行鎖
 
onstat -k 輸入內容描述:
address 
是鎖表中鎖的地址 
若是用戶線程正在等待該鎖,則鎖的地址出如今 onstat -u(用戶)輸出的 wait 字段中。
wtlist 
是正在等待鎖的用戶線程(若有)列表中的第一項 
owner 
是正持有鎖的線程的共享內存地址 
此地址對應於 onstat -u(用戶)輸出的 address 字段中的地址。
lklist 
是剛纔列出的全部者所持有鎖的連接列表中的下一個鎖 
類型 
使用如下代碼指示鎖的類型: 
HDR 
頭 

字節 

共享 

互斥 

意向 

更新 
IX 
意向-互斥 
IS 
意向-共享 
SIX 
共享的意向-互斥 
tblsnum 
是已鎖定資源的表空間編號 
rowid 
是行標識號 
行標識提供如下鎖信息:
若是行標識等於 0,則該鎖爲表鎖。 
若是行標識以 2 個 0 結束,則該鎖爲頁鎖。 
若是行標識爲 6 個數字或更少且不以 0 結束,則該鎖極可能是行鎖。 
若是行標識多於 6 個數字,則該鎖極可能是索引鍵值鎖。
key#/bsiz 
是索引鍵號或對 VARCHAR 鎖的已鎖定字節數 
若是該字段包含「K-」,後跟值,則是鍵鎖。值標識哪一個索引正在被鎖定。例如:K-1 表示對錶所定義的第一個索引上的鎖。
可用鎖的最大數量以 ONCONFIG 文件中的 LOCKS 進行指定。
 
查找鎖定的表名稱
經過onstat -k 查找的rowid 等於0的表鎖信息的 tblsnum 信息查找表名。 
如 tblsnum等於500e19
執行 select * from systables where hex(partnum)='0x00500e19'
查找到當前鎖表的表名。
 
 
Informix -244 錯誤 :
Could not do a physical-order read to fetch next row.
 
具體錯誤解釋:
   #finderr -244
 
緣由:
a.鎖表
b.記錄太多
c.頁損壞
d.某個進程死了之後資源未釋放致使
   在數據庫端用  onstat –g ses/onstat –g sql /
Onstat –k 等找出鎖表進程,用onmode –z結束該進程,
不行,重啓數據庫釋放。
鎖方式:
   行方式(row),頁方式(默認page),表方式(table)。
 
解決:
   1.下降鎖級別
   2.減小加鎖事務的時間跨度
   3.設置等待解瑣時間
 
相關命令:
   )檢查索引及頁損壞狀況
#oncheck  –cID  database_name:table_name
   ) 查看鎖級別
#oncheck  –pt  database_name:table_name
   )設置鎖級別(行方式)
#alter table table_name lock mode(row)
   )設置隔離級別
#set isolation to dirty read
   )設置等待解鎖時間(不宜過大)
#set lock mode to wait second(秒)
不等待
#set lock mode to not wait
 
 
還能夠這樣解決: 若是是日誌型數據庫,在執行的時候,能夠先鎖定 begin work; lock table tab_name in exclusive mode; 要執行的sql語句; commit work; 若是是非日誌的數據 lock table table_name in exclusive mode; 要執行的sql語句; unlock table tab_name; 
中間件全局事務鎖問題 中間件與informix鏈接時會出現onstat -k 中 owner 內容爲0的現象。 這是應該查看全局事務onstat -x 和onstat -G DATABASE sysmaster; select hex(tx_addr) trans_addr,hex(tx_lklist) lock_addr from systrans where hex(tx_addr) like '%c00000006e329778%'; 須要說明的是,c000000007674c58是使用onstat -x 或 onstat -G獲得的全局事務的地址。 上面SQL語句提供出該全局事務對應的鎖地址,這時若是獲得的鎖地址與鎖表的鎖地址相同的話,你就必需從應用端(一般是三層結構的中間件)發命令讓該全局事務回滾或提交,不然該鎖會被一直持有,直到你執行oninit。
 

onstat -k 的owner 列中的地址與onstat -x 中的userthread 對應。併發

 

以下解釋 onstat -x 的輸出curl

address
是事務結構的共享內存地址
flags
位置 1 的標誌代碼(當前事務狀態):
A
用戶線程已鏈接到事務
S
TP/XA 暫掛的事務
C
TP/XA 正在等待回滾
位置 2 的標誌代碼(事務方式):
分佈式

T
緊耦合方式(MTS)
L
鬆耦合方式(缺省方式)
位置 3 的標誌代碼(事務階段):
fetch

B
開始工做
P
準備好用於提交的分佈式查詢
X
準備好用於提交的 TP/XA
C
正在提交或已提交
R
正在回滾或已回滾
H
正在嘗試回滾或已回滾
位置 5 的標誌代碼(事務類型):
url

G
全局事務
C
分佈式查詢協調者
S
分佈式查詢從屬者
B
分佈式查詢協調者和從屬者
userthread
是擁有事務的線程(rstcb 地址)
locks
是事務持有的鎖數
beginlg
是 BEGIN WORK 記錄已記錄到其中的日誌
curlog
是事務正在寫入的當前日誌
logposit
是日誌位置
4 字節日誌位置的格式是 0xPPPPPBBB,其中 PPPPP 是日誌中的頁偏移量,BBB 是頁中的字節偏移量。logposit 能夠是日誌文件中的 0x100000(或 1048576)頁的最大數。

isol
是隔離級別。
retrys
是啓動分佈式查詢的恢復線程的嘗試次數
coord
是從屬者正在執行事務時事務協調者的名稱
該字段告訴您哪一個數據庫服務器正在協調兩階段提交。

onstat -x 輸出的最後一行指示 maximum concurrent 是自初始化數據庫服務器以來併發事務的最大數。

 

以下解釋 onstat -G 的輸出

address 是事務控制塊的內存中地址 flags 是全局事務的當前狀態(使用如下十六進制值組合): x00000001 用戶已鏈接到事務上 x00000002 打開事務 x00000004 xa_start() 和 xa_end() 之間的事務 x00000008 全局事務 x00000010 標記爲僅異常終止的事務 x00000020 TP/XA 準備的事務 x00000040 分佈式事務 x00000080 異常終止的事務 x00000100 已提交的事務 x00000200 已嘗試完成的事務 x00000400 已寫入 BEGIN WORK 日誌記錄 x00000800 回滾已完成 x00001000 已開始提交已刪除表和索引 x00002000 已開始異常終止事務 x00004000 未執行撤銷操做 x00008000 全局保存點處於活動狀態 x00010000 保存點回滾 x00020000 清除死事務 x00040000 事務用於遠程數據庫服務器 x00080000 事務條目在使用中 x00100000 事務已執行遠程工做 x00200000 保存點已開始 x00400000 分佈式事務中的協調者 x00800000 分佈式事務中的從屬者 x01000000 長事務或暫掛事務沒有全部者 x02000000 事務正在恢復中 x04000000 對該事務的重作失敗 x08000000 對該事務進行的撤銷失敗 x10000000 當發生 I/O 故障時事務是活動的 x20000000 事務在恢復過程當中執行了某些工做 x40000000 事務包含鎖 x80000000 事務執行了 DDR 工做 fID 是事務數據的格式標識 gtl 是全局事務的長度 bql 是事務的字節流長度 data 是事務標識和數據的十六進制轉儲 摘要定義 active 是活動全局事務的數量 total 是動態分配給數據庫服務器的事務的當前數量

相關文章
相關標籤/搜索