定期 (預設每 5 秒) 檢查資料庫狀態,若發現長時間運行交易 (>5 秒)、系統負載過高 (load > 30) 或鎖等待 (>5 筆),自動收集 db2pd 詳細輸出與應用 SQL 文字至時間戳記檔案,便於事後分析。
#!/bin/ksh
v_dbname=spshis
mo_run() {
# 1. 檢查是否有執行超過 5 秒的交易
start_or_not=`db2 -x "select count(*) from sysibmadm.SNAPAPPL
where uow_stop_time is null and current timestamp - uow_start_time > 5 with ur"`
# 2. 系統負載 (uptime 第 6 欄)
start_or_not1=`uptime | awk -F"," '{print $6}'`
# 3. 鎖等待計數
start_or_not2=`db2pd -d sample -lock wait | wc -l`
date >> monitor_log
# 情況 A:有長交易
if [ $start_or_not -gt 0 ]; then
v_f=`date +%y%m%H%M%S`
# 若有超過 200 秒的極長交易,收集完整 db2pd
start_or_not4=`db2 -x "select count(*) from sysibmadm.SNAPAPPL
where uow_stop_time is null and current timestamp - uow_start_time > 200 with ur"`
if [ $start_or_not4 -gt 0 ]; then
db2pd -d $v_dbname -tran -dyn -lock wait -app > monitor_log"$v_f"
fi
# 擷取長交易的 SQL 文字與用戶資訊
db2 -x "select a.agent_id, c.tpmon_client_wkstn, b.stmt_text,
current timestamp - a.uow_start_time used_time
from sysibmadm.SNAPAPPL a, sysibmadm.SNAPSTMT b, sysibmadm.SNAPAPPL_INFO c
where a.agent_id=b.agent_id and a.agent_id=c.agent_id
and a.uow_stop_time is null
and current timestamp - a.uow_start_time > 5 with ur" >> monitor_log"$v_f"
sh hj_file # 自訂清理函式
sleep 20
return
fi
# 情況 B:系統負載過高
if [[ $start_or_not1 > 30 ]]; then
v_f=`date +%d%m%H%M%S`
db2pd -d $v_dbname -tran -dyn -lock wait -app -latch >> monitor_log"$v_f"
sleep 20
return
fi
# 情況 C:鎖等待過多
if [ $start_or_not2 -gt 5 ]; then
v_f=`date +%d%m%H%M%S`
db2pd -d $v_dbname -tran -dyn -lock wait -app >> monitor_log"$v_f"
sleep 20
return
fi
}
# 主迴圈:最長運行 2 小時 (7200 秒)
db2 connect to $v_dbname > /dev/null
second=0
while true; do
echo 'start-------------------'
mo_run
sleep 5
let second=second+5
if [ ${second} -gt 7200 ]; then break; fi
done
db2 terminate
SYSIBMADM.SNAPAPPL:應用程式快照,含交易開始/結束時間。SYSIBMADM.SNAPSTMT:動態 SQL 文字。SYSIBMADM.SNAPAPPL_INFO:用戶工作站資訊。db2pd -lock wait:鎖等待鏈詳細資訊。db2inst 用戶排程 (crontab) 執行。