半自動化運維之動態新增資料檔案(一)
在測試環境中,伺服器和資料庫例項真是多得數不勝數,自己也沒有下意識去記住那個資料庫例項在哪個伺服器上,都是出了問題直接連過去解決。
這麼多的資料庫例項需要管理,表空間的監控是極為重要的,一般來說都會在給表空間設定一個閥值,比如說表空間剩餘10%,20%等等,超出了閥值就會自動傳送郵件,提醒DBA去做相應的處理,表空間監控如此,檔案系統監控也是類似的思路。
最近處理了一些緊急的問題,看似是很小的問題,但是比較折騰人,比如說表空間超出了閥值,就會傳送警告郵件,這個時候DBA就會連過去,處理問題的思路就是新增資料檔案,這個時候就得考慮檔案系統的空間情況。
比如有下面10個掛載點。
/u01,/u02,/u03....., /u10, 資料檔案被打散分佈在這幾個掛載點上,如果對於資料檔案的位置沒有嚴格的要求,就是希望把資料檔案分散分佈,這個時候處理的思路就是使用df -k來得到對應的掛載點資訊,然後在其中選擇一個合適的,建立資料檔案,僅此而已。
但是這個過程如果細細來看,確實是沒有太多技術含量的,而且手動處理液不夠及時,能不能傳送了警告郵件,然後在資料庫層面建立資料檔案,可以在DBA稍後進行驗證,這樣問題處理也很及時,也不用DBA來總是手工處理這種看似緊急的問題。這也就是我為什麼說是半自動化運維的一個思路。
解釋了一通,來個圖看看可能就更清楚了。
下面就是一些掛載點,在不同的伺服器上會有所不同,在監控的時候如果需要新增資料檔案,就需要儘量把資料檔案分散到這些掛載點上,可以使用hash或者random的方式。
當然要實現也是看起來容易,做起來難。
先來看看錶空間監控的部分,我們先來看看錶空間監控的部分是怎麼寫的,在後續的章節補充是怎麼新增資料檔案的。
這個指令碼依賴於一個配置檔案。就是需要提供資料庫例項名和主機名,像下面的形式,資料庫TEST11G在主機oel1上。
$ cat master_sid.lst
TEST11G oel1
DG11G oel1
LOG_DIR=/home/ora11g/logs
DAY=`date +%d-%m-%Y:%H:%M" CST"`
HOST=`hostname`
SCRIPTNAME=free_tbs_alert.ksh
SCR_DIR=/home/ora11g/sid_list --配置檔案的路徑
TARGET_CONN=n1/n1
export PATH=$ORACLE_SID/bin:$PATH
cp /dev/null $LOG_DIR/${1}_${SCRIPTNAME}_final_report_free_tablespace
cp /dev/null $LOG_DIR/${1}_${SCRIPTNAME}_final_report_free_tablespace.new
cp /dev/null $LOG_DIR/${1}_${SCRIPTNAME}_tablespace.alert
##MAIN
for SID in ` cat $SCR_DIR/master_sid.lst |grep -v "^\#"|awk '{print $1}'`
do
_hst=`grep -iw $SID $SCR_DIR/master_sid.lst |grep -v "^\#"|awk '{ print $2}'`
#if [ `grep -iw $_hst $SCR_DIR/maint_hosts| wc -l ` -eq 0 ]
#then
$ORACLE_HOME/bin/sqlplus -s /nolog << EOF
conn ${TARGET_CONN}@$SID
set feed off head off
set linesize 65
set pagesize 0
col TABLESPACE_NAME format a15
col "USED (MB)" format a12
col "FREE (MB)" format a10
col "PER_FREE (MB)" format a17
col "TOTAL (MB)" format a12
spool $LOG_DIR/${1}_${SCRIPTNAME}_tablespace.alert
SELECT F.TABLESPACE_NAME,
TO_CHAR ((T.TOTAL_SPACE - F.FREE_SPACE),'999999') "USED (MB)",
TO_CHAR (F.FREE_SPACE, '999999') "FREE (MB)",
TO_CHAR (T.TOTAL_SPACE, '999999') "TOTAL (MB)",
TO_CHAR ((ROUND ((F.FREE_SPACE/T.TOTAL_SPACE)*100)),'999')||' %' PER_FREE
FROM (SELECT TABLESPACE_NAME,
ROUND (SUM (BLOCKS*(SELECT VALUE/1024 FROM V\$PARAMETER
WHERE NAME = 'db_block_size')/1024)) FREE_SPACE
FROM DBA_FREE_SPACE
GROUP BY TABLESPACE_NAME) F,
(SELECT TABLESPACE_NAME,
ROUND (SUM (BYTES/1048576)) TOTAL_SPACE
FROM DBA_DATA_FILES
GROUP BY TABLESPACE_NAME) T
WHERE F.TABLESPACE_NAME = T.TABLESPACE_NAME
AND (ROUND ((F.FREE_SPACE/T.TOTAL_SPACE)*100)) < 10;
spool off
/
prompt
exit
EOF
#fi
HOST1=`$ORACLE_HOME/bin/tnsping $SID | tr -d " "|tr 'A-Z' 'a-z'|grep host |awk -F "host=" ' { print $2} '| awk -F ")" '{ print $1}'`
if [[ `cat $LOG_DIR/${1}_${SCRIPTNAME}_tablespace.alert|wc -l` -gt 0 && `grep ORA- $LOG_DIR/${1}_${SCRIPTNAME}_tablespace.alert|wc -l` -lt 1 ]]
then
cp /dev/null $LOG_DIR/${1}_${SCRIPTNAME}_free_tablespace.tmp
grep "%" $LOG_DIR/${1}_${SCRIPTNAME}_tablespace.alert|awk '{ print $3}'|sort|
while read _freeMB
do
if [[ $_freeMB -lt 2048 ]]
then
grep "%" $LOG_DIR/${1}_${SCRIPTNAME}_tablespace.alert|grep -w $_freeMB >> $LOG_DIR/${1}_${SCRIPTNAME}_free_tablespace.tmp
fi
done
cp /dev/null $LOG_DIR/${1}_${SCRIPTNAME}_free_tablespace.tmp1
#if [ `cat $LOG_DIR/${1}_${SCRIPTNAME}_free_tablespace.tmp |wc -l ` -gt 0 ]
if [ `cat $LOG_DIR/${1}_${SCRIPTNAME}_free_tablespace.tmp |grep -iv "UNDO" |wc -l ` -gt 0 ]
then
echo "DB Name: $SID Host: $HOST1" >> $LOG_DIR/${1}_${SCRIPTNAME}_free_tablespace.tmp1
cat $LOG_DIR/${1}_${SCRIPTNAME}_free_tablespace.tmp|sort -u >> $LOG_DIR/${1}_${SCRIPTNAME}_free_tablespace.tmp1
cat $LOG_DIR/${1}_${SCRIPTNAME}_free_tablespace.tmp1|sed "/^$/ d;" >>$LOG_DIR/${1}_${SCRIPTNAME}_final_report_free_tablespace
echo "=============================================================" >>$LOG_DIR/${1}_${SCRIPTNAME}_final_report_free_tablespace
fi
fi
done
echo "TABLESPACE_NAME USED (MB) FREE (MB) TOTAL (MB) PER_FR
--------------- ------------ ---------- ------------ ------
" >> $LOG_DIR/${1}_${SCRIPTNAME}_final_report_free_tablespace.new
cat $LOG_DIR/${1}_${SCRIPTNAME}_final_report_free_tablespace >> $LOG_DIR/${1}_${SCRIPTNAME}_final_report_free_tablespace.new
echo "DBA Team"| tee -a $LOG_DIR/${1}_${SCRIPTNAME}_final_report_free_tablespace.new
echo "Script Location on $HOST ${SCR_DIR}/${SCRIPTNAME}" | tee -a $LOG_DIR/${1}_${SCRIPTNAME}_final_report_free_tablespace.new
if [ `cat $LOG_DIR/${1}_${SCRIPTNAME}_final_report_free_tablespace|wc -l` -gt 2 ]
then
cat $LOG_DIR/${1}_${SCRIPTNAME}_final_report_free_tablespace.new
echo 'need to notify jianrong to help '
mailx -s "$1 : < 10% or 2 GB Free TableSpace Report: $DAY" ' xxxxxx@xxxx.com' < $LOG_DIR/${1}_${SCRIPTNAME}_final_report_free_tablespace.new --傳送郵件
fi
整個過程就完成了表空間的監控,當然是一個初步的指令碼還有一些不嚴謹的地方。
這個時候我們需要繼續完成作業系統級的監控,這個監控是有一定的範圍的。
我們可以先從得到資料庫中資料檔案的格式。
conn_str=n1/n1
print "
conn $conn_str
set feedback off
set pages 0
select file_name from dba_data_files;
" |sqlplus -s /nolog |awk -F"/" '{print "/"$2}'|sort|uniq|awk '{print "df -k |grep -i \""$1 "\""}' > df_k_chk_tmp.ksh
比如資料檔案為 /u02/ora11g/oradata/TEST11G/sysaux01.dbf 我們需要得到掛載點,即 /u02,其他的資料檔案,掛載點可能是 /u03,/u04....
然後使用df -k來檢視這些掛載點的空間使用情況,這個地方我是使用awk '{print "df -k |grep -i \""$1 "\""}' > df_k_chk_tmp.ksh來直接生成對應的df -k的指令碼。
這個時候比如還是有10個掛載點,我們需要新增檔案,比如說需要新增2G的檔案,這個時候就需要在這些掛載點中進行校驗,首先大小要超過2G的掛載點才可以考慮。
然後對輸出的結果進行過濾。這裡有一個問題是在Unix和linux下使用df -k的時候,輸出可能會有一些不同。
版本1:
/dev/sda3 30969600 24844420 4552016 85% /u02
版本2:
30969600 24844420 4552016 85% /u02
這個時候可以根據要求反向得到最後三列的值,作為我們分析的基礎。
這個部分使用一個函式即可搞定,假設我們生成的動態df -k的指令碼為df_k_chk_tmp.ksh 需要新增的資料檔案大小為800M,可以這麼過濾。
function get_db_file_mount
{
ksh $1 | awk -v file_size=$2 'NR>=1{ if($(NF-2)-$file_size>0) print $(NF-2),$(NF-1),$NF}' |sort
}
get_db_file_mount df_k_chk_tmp.ksh 8100000 > tmp_FS_mount
接下來的部分就是如何做hash或者random分佈了,怎麼儘量把資料檔案分散出去,選擇一個可用的掛載點。我們們可以定義一個random函式。
function get_random
{
min=$1;
max=$2
num=$(date +%s+%N);
((retnum=num%max+min));
echo $retnum;
}
透過下面的程式碼進行過濾,能夠隨機抓取到一個合適的掛載點。
tmp_FS_mount_cnt=`cat tmp_FS_mount|wc -l`
echo $tmp_FS_mount_cnt
tmp_random=`get_random 1 ${tmp_FS_mount_cnt}`
echo $tmp_random
cat tmp_FS_mount|sed -n "${tmp_random}p"|awk '{print $3}'
接下來的事情就是生成資料檔案的部分了。明天繼續。
這麼多的資料庫例項需要管理,表空間的監控是極為重要的,一般來說都會在給表空間設定一個閥值,比如說表空間剩餘10%,20%等等,超出了閥值就會自動傳送郵件,提醒DBA去做相應的處理,表空間監控如此,檔案系統監控也是類似的思路。
最近處理了一些緊急的問題,看似是很小的問題,但是比較折騰人,比如說表空間超出了閥值,就會傳送警告郵件,這個時候DBA就會連過去,處理問題的思路就是新增資料檔案,這個時候就得考慮檔案系統的空間情況。
比如有下面10個掛載點。
/u01,/u02,/u03....., /u10, 資料檔案被打散分佈在這幾個掛載點上,如果對於資料檔案的位置沒有嚴格的要求,就是希望把資料檔案分散分佈,這個時候處理的思路就是使用df -k來得到對應的掛載點資訊,然後在其中選擇一個合適的,建立資料檔案,僅此而已。
但是這個過程如果細細來看,確實是沒有太多技術含量的,而且手動處理液不夠及時,能不能傳送了警告郵件,然後在資料庫層面建立資料檔案,可以在DBA稍後進行驗證,這樣問題處理也很及時,也不用DBA來總是手工處理這種看似緊急的問題。這也就是我為什麼說是半自動化運維的一個思路。
解釋了一通,來個圖看看可能就更清楚了。
下面就是一些掛載點,在不同的伺服器上會有所不同,在監控的時候如果需要新增資料檔案,就需要儘量把資料檔案分散到這些掛載點上,可以使用hash或者random的方式。
當然要實現也是看起來容易,做起來難。
先來看看錶空間監控的部分,我們先來看看錶空間監控的部分是怎麼寫的,在後續的章節補充是怎麼新增資料檔案的。
這個指令碼依賴於一個配置檔案。就是需要提供資料庫例項名和主機名,像下面的形式,資料庫TEST11G在主機oel1上。
$ cat master_sid.lst
TEST11G oel1
DG11G oel1
LOG_DIR=/home/ora11g/logs
DAY=`date +%d-%m-%Y:%H:%M" CST"`
HOST=`hostname`
SCRIPTNAME=free_tbs_alert.ksh
SCR_DIR=/home/ora11g/sid_list --配置檔案的路徑
TARGET_CONN=n1/n1
export PATH=$ORACLE_SID/bin:$PATH
cp /dev/null $LOG_DIR/${1}_${SCRIPTNAME}_final_report_free_tablespace
cp /dev/null $LOG_DIR/${1}_${SCRIPTNAME}_final_report_free_tablespace.new
cp /dev/null $LOG_DIR/${1}_${SCRIPTNAME}_tablespace.alert
##MAIN
for SID in ` cat $SCR_DIR/master_sid.lst |grep -v "^\#"|awk '{print $1}'`
do
_hst=`grep -iw $SID $SCR_DIR/master_sid.lst |grep -v "^\#"|awk '{ print $2}'`
#if [ `grep -iw $_hst $SCR_DIR/maint_hosts| wc -l ` -eq 0 ]
#then
$ORACLE_HOME/bin/sqlplus -s /nolog << EOF
conn ${TARGET_CONN}@$SID
set feed off head off
set linesize 65
set pagesize 0
col TABLESPACE_NAME format a15
col "USED (MB)" format a12
col "FREE (MB)" format a10
col "PER_FREE (MB)" format a17
col "TOTAL (MB)" format a12
spool $LOG_DIR/${1}_${SCRIPTNAME}_tablespace.alert
SELECT F.TABLESPACE_NAME,
TO_CHAR ((T.TOTAL_SPACE - F.FREE_SPACE),'999999') "USED (MB)",
TO_CHAR (F.FREE_SPACE, '999999') "FREE (MB)",
TO_CHAR (T.TOTAL_SPACE, '999999') "TOTAL (MB)",
TO_CHAR ((ROUND ((F.FREE_SPACE/T.TOTAL_SPACE)*100)),'999')||' %' PER_FREE
FROM (SELECT TABLESPACE_NAME,
ROUND (SUM (BLOCKS*(SELECT VALUE/1024 FROM V\$PARAMETER
WHERE NAME = 'db_block_size')/1024)) FREE_SPACE
FROM DBA_FREE_SPACE
GROUP BY TABLESPACE_NAME) F,
(SELECT TABLESPACE_NAME,
ROUND (SUM (BYTES/1048576)) TOTAL_SPACE
FROM DBA_DATA_FILES
GROUP BY TABLESPACE_NAME) T
WHERE F.TABLESPACE_NAME = T.TABLESPACE_NAME
AND (ROUND ((F.FREE_SPACE/T.TOTAL_SPACE)*100)) < 10;
spool off
/
prompt
exit
EOF
#fi
HOST1=`$ORACLE_HOME/bin/tnsping $SID | tr -d " "|tr 'A-Z' 'a-z'|grep host |awk -F "host=" ' { print $2} '| awk -F ")" '{ print $1}'`
if [[ `cat $LOG_DIR/${1}_${SCRIPTNAME}_tablespace.alert|wc -l` -gt 0 && `grep ORA- $LOG_DIR/${1}_${SCRIPTNAME}_tablespace.alert|wc -l` -lt 1 ]]
then
cp /dev/null $LOG_DIR/${1}_${SCRIPTNAME}_free_tablespace.tmp
grep "%" $LOG_DIR/${1}_${SCRIPTNAME}_tablespace.alert|awk '{ print $3}'|sort|
while read _freeMB
do
if [[ $_freeMB -lt 2048 ]]
then
grep "%" $LOG_DIR/${1}_${SCRIPTNAME}_tablespace.alert|grep -w $_freeMB >> $LOG_DIR/${1}_${SCRIPTNAME}_free_tablespace.tmp
fi
done
cp /dev/null $LOG_DIR/${1}_${SCRIPTNAME}_free_tablespace.tmp1
#if [ `cat $LOG_DIR/${1}_${SCRIPTNAME}_free_tablespace.tmp |wc -l ` -gt 0 ]
if [ `cat $LOG_DIR/${1}_${SCRIPTNAME}_free_tablespace.tmp |grep -iv "UNDO" |wc -l ` -gt 0 ]
then
echo "DB Name: $SID Host: $HOST1" >> $LOG_DIR/${1}_${SCRIPTNAME}_free_tablespace.tmp1
cat $LOG_DIR/${1}_${SCRIPTNAME}_free_tablespace.tmp|sort -u >> $LOG_DIR/${1}_${SCRIPTNAME}_free_tablespace.tmp1
cat $LOG_DIR/${1}_${SCRIPTNAME}_free_tablespace.tmp1|sed "/^$/ d;" >>$LOG_DIR/${1}_${SCRIPTNAME}_final_report_free_tablespace
echo "=============================================================" >>$LOG_DIR/${1}_${SCRIPTNAME}_final_report_free_tablespace
fi
fi
done
echo "TABLESPACE_NAME USED (MB) FREE (MB) TOTAL (MB) PER_FR
--------------- ------------ ---------- ------------ ------
" >> $LOG_DIR/${1}_${SCRIPTNAME}_final_report_free_tablespace.new
cat $LOG_DIR/${1}_${SCRIPTNAME}_final_report_free_tablespace >> $LOG_DIR/${1}_${SCRIPTNAME}_final_report_free_tablespace.new
echo "DBA Team"| tee -a $LOG_DIR/${1}_${SCRIPTNAME}_final_report_free_tablespace.new
echo "Script Location on $HOST ${SCR_DIR}/${SCRIPTNAME}" | tee -a $LOG_DIR/${1}_${SCRIPTNAME}_final_report_free_tablespace.new
if [ `cat $LOG_DIR/${1}_${SCRIPTNAME}_final_report_free_tablespace|wc -l` -gt 2 ]
then
cat $LOG_DIR/${1}_${SCRIPTNAME}_final_report_free_tablespace.new
echo 'need to notify jianrong to help '
mailx -s "$1 : < 10% or 2 GB Free TableSpace Report: $DAY" ' xxxxxx@xxxx.com' < $LOG_DIR/${1}_${SCRIPTNAME}_final_report_free_tablespace.new --傳送郵件
fi
這個時候我們需要繼續完成作業系統級的監控,這個監控是有一定的範圍的。
我們可以先從得到資料庫中資料檔案的格式。
conn_str=n1/n1
print "
conn $conn_str
set feedback off
set pages 0
select file_name from dba_data_files;
" |sqlplus -s /nolog |awk -F"/" '{print "/"$2}'|sort|uniq|awk '{print "df -k |grep -i \""$1 "\""}' > df_k_chk_tmp.ksh
比如資料檔案為 /u02/ora11g/oradata/TEST11G/sysaux01.dbf 我們需要得到掛載點,即 /u02,其他的資料檔案,掛載點可能是 /u03,/u04....
然後使用df -k來檢視這些掛載點的空間使用情況,這個地方我是使用awk '{print "df -k |grep -i \""$1 "\""}' > df_k_chk_tmp.ksh來直接生成對應的df -k的指令碼。
這個時候比如還是有10個掛載點,我們需要新增檔案,比如說需要新增2G的檔案,這個時候就需要在這些掛載點中進行校驗,首先大小要超過2G的掛載點才可以考慮。
然後對輸出的結果進行過濾。這裡有一個問題是在Unix和linux下使用df -k的時候,輸出可能會有一些不同。
版本1:
/dev/sda3 30969600 24844420 4552016 85% /u02
版本2:
30969600 24844420 4552016 85% /u02
這個時候可以根據要求反向得到最後三列的值,作為我們分析的基礎。
這個部分使用一個函式即可搞定,假設我們生成的動態df -k的指令碼為df_k_chk_tmp.ksh 需要新增的資料檔案大小為800M,可以這麼過濾。
function get_db_file_mount
{
ksh $1 | awk -v file_size=$2 'NR>=1{ if($(NF-2)-$file_size>0) print $(NF-2),$(NF-1),$NF}' |sort
}
get_db_file_mount df_k_chk_tmp.ksh 8100000 > tmp_FS_mount
接下來的部分就是如何做hash或者random分佈了,怎麼儘量把資料檔案分散出去,選擇一個可用的掛載點。我們們可以定義一個random函式。
function get_random
{
min=$1;
max=$2
num=$(date +%s+%N);
((retnum=num%max+min));
echo $retnum;
}
透過下面的程式碼進行過濾,能夠隨機抓取到一個合適的掛載點。
tmp_FS_mount_cnt=`cat tmp_FS_mount|wc -l`
echo $tmp_FS_mount_cnt
tmp_random=`get_random 1 ${tmp_FS_mount_cnt}`
echo $tmp_random
cat tmp_FS_mount|sed -n "${tmp_random}p"|awk '{print $3}'
接下來的事情就是生成資料檔案的部分了。明天繼續。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23718752/viewspace-1683250/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 半自動化運維之動態新增資料檔案(二)運維
- 半自動化運維之伺服器資訊維護運維伺服器
- IT運維之自動化運維運維
- 半自動化運維之快速連線到指定環境(一)運維
- 運維效率之資料遷移自動化運維
- 自動化運維工具之Puppet常用資源(一)運維
- ansible自動化運維資料庫運維資料庫
- Devops-運維效率之資料遷移自動化dev運維
- Oracle自動新增資料檔案過程Oracle
- 自動化運維工具之Puppet模組運維
- 自動化運維工具之Puppet常用資源(二)運維
- 自動化運維 Expect運維
- Python自動化運維之IPy模組Python運維
- MySQL自動化運維之安裝篇MySql運維
- 運維自動化之賬單系統運維
- 自動化運維-修改主機名&hosts檔案指令碼運維指令碼
- 用自動化運維工具解放IT運維運維
- 自動化運維 Ansible運維
- 運維開發裡的資料動態獲取和自動補錄運維
- mysql-inception自動化運維MySql運維
- Ansible自動化運維工具運維
- 【DB】有贊資料庫自動化運維實踐之路資料庫運維
- 自動化運維工具——ansible詳解(一)運維
- 自動化運維工具之Puppet基礎入門運維
- 品運維自動化之cobbler的安裝序運維
- 什麼是自動化運維?為什麼選擇Python做自動化運維?運維Python
- 簡化IT運維工作,就要學會使用自動化運維工具!運維
- 介紹一個 MySQL 自動化運維利器 - InceptionMySql運維
- ansible自動化運維入門運維
- 自動化運維的快速演進運維
- 自動化運維的發展方向運維
- 分層運維自動化監控運維
- Linux Shell互動式自動化運維程式Linux運維
- 自動化運維,國產化信創替代方案運維
- 非OMF管理 自動新增資料檔案add_datafiles.sh
- oracle 新增儲存自動擴充套件資料檔案流程(auto)Oracle套件
- 從零打造B/S自動化運維平臺(一、自動化運維平臺的應用及業務流程)運維
- 論IT運維自動化的重要性運維