asterisk 1.6.2 有個 bug 會使硬碟產生不必要的頻繁的 IO load
註:在 asterisk 10.x.x 版本以後 astdb 檔名改了,改成 astdb.sqlite3 和 astdb.sqlite3-journal 這兩個檔案,所以底下的程式碼也要相應的修改才行。
雖然我們在這兒看到有人有貼出修正檔出來,但我還不知要怎麼安裝那個修正檔,所以我用我自己的方式來解決這個 bug ,就是採用 ramdisk。 依據前面的 bug 回報,我們得知 /var/lib/asterisk/astdb 此檔會有頻繁的寫入動作,就是它引起頻繁的 IO load ,故底下是要介紹如何將它移到 ramdisk 。
1 掛載 ramdisk
vim /etc/fstab
貼上以下內容
/dev/shm /tmp tmpfs defaults 0 0
重開機後 /tmp 便會成了 ramdisk
底下步驟2開機自動執行的設定方法比較笨,而且容易發生一個問題,就是你設定的ramdisk裡的檔案,若是在開機啟動時的順序比asterisk 還要慢的話,那麼就會造成asterisk無法正常的啟動,因為它找不到 /tmp/asteriskdb 這個資料夾裡面的東西
1.5 修改asterisk啟動檔
一般來說,你若是使用apt-get 或 aptitude 來安裝asterisk的話,那麼它會自動幫你設定好開機啟動檔案,若你是使用原始碼安裝asterisk的話,而且參照我這一篇來安裝的話,也會有一個asterisk開機啟動檔。
我們現在就要編輯asterisk開機啟動檔,讓它啟動和關閉時都能自動的處理好ramdisk裡的資料
vim /etc/init.d/asterisk
重點是要找到 start) 和 stop) 這兩個區段加入一點程式碼
....................
....................
....................
case "$1" in
start)
###########以下為我加進的程式碼#################
#底下這行是比較精簡的寫法
#test -d /tmp/asteriskdb || mkdir /tmp/asteriskdb && cp -a /var/lib/asterisk/db/* /tmp/asteriskdb && chown -R asterisk.asterisk /tmp/asteriskdb
#底下這段程式碼是比較正規的寫法,兩者可擇一用之。
if [ -d /tmp/asteriskdb ];then
#上面那行是檢查 /tmp/asteriskdb 此資料夾是否存在
echo "ramdisk db exist, nothing to do!"
else
#若不存在則,設定ramdisk 4 asterisk
mkdir /tmp/asteriskdb
cp -a /var/lib/asterisk/db/* /tmp/asteriskdb
chown -R asterisk.asterisk /tmp/asteriskdb
fi
###########以上為我加進的程式碼#################
# Check if Asterisk is already running. If it is, then bug out, because
# starting up Asterisk when Asterisk is already running is very bad.
VERSION=`${DAEMON} -rx 'core show version' || ${TRUE}`
if [ "`echo $VERSION | cut -c 1-8`" = "Asterisk" ]; then
echo "Asterisk is already running. $0 will exit now."
exit 0
fi
....................
....................
....................
stop)
log_begin_msg "Stopping $DESC: $NAME"
# "start-stop-daemon --oknodo" returns 0 even if Asterisk was already stopped (as LSB expects):
start-stop-daemon --stop --oknodo --exec $DAEMON
log_end_msg $?
#關機設定備份 asterisk db
cp -a /tmp/asteriskdb/* /var/lib/asterisk/db
;;
....................
....................
執行 1.5 此步驟之後,底下的第2步驟就可以略過,直接跳往第3步驟
2 開關機自動執行
此步驟2的方法不建議使用,請使用步驟1.5 的方法。
由於 ramdisk 的特性,重開機之後檔案會消失,所以我們要寫個小程式讓它在開關機時能自動回存
vim /home/backup/script/astdb-ram.sh
貼上以下內容
#!/bin/bash
#開機設定ramdisk給 asterisk用
mkdir /tmp/asteriskdb
cp -a /var/lib/asterisk/db/* /tmp/asteriskdb
chown -R asterisk.asterisk /tmp/asteriskdb
vim /home/backup/script/save-astdb.sh
貼上以下內容
#!/bin/bash
#關機設定備份 asterisk db
cp -a /tmp/asteriskdb/* /var/lib/asterisk/db
chmod 755 /home/backup/script/astdb-ram.sh
chmod 755 /home/backup/script/save-astdb.sh
設定開機執行
vim /home/backup/script/startup.sh
貼上底下內容
### BEGIN INIT INFO
# Provides: iptables.sh
# Required-Start: $remote_fs $syslog
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start daemon at boot time
# Description: 自製開機程式
### END INIT INFO
#/bin/bash
bash /home/backup/script/astdb-ram.sh
chmod 755 /home/backup/script/startup.sh
ln -s /home/backup/script/startup.sh /etc/init.d/startup.sh
update-rc.d startup.sh defaults 19
設定關機回存
把這個檔連結到 /etc/rc0.d/下面 (專司halt) 以及 /etc/rc6.d/下面 (專司reboot)
ln -s /home/backup/script/save-astdb.sh /etc/rc0.d/save-astdb.sh
ln -s /home/backup/script/save-astdb.sh /etc/rc6.d/save-astdb.sh
3 修改路徑
vim /etc/asterisk/asterisk.conf
修改底下內容
[directories] (!); remove the (!) to enable this
;要移掉上面那行的 (!) 底下的設定才會生效
;astdbdir => /var/lib/asterisk
astdbdir => /tmp/asteriskdb
vim /etc/asterisk/res_config_sqlite.conf
修改底下內容
;dbfile => /var/lib/asterisk/sqlite.db
dbfile => /tmp/asteriskdb/sqlite.db
PS:後來發現 sqlite.db 似乎沒有那麼高的 IO 可以不用把它搬到 ramdisk 去,另外你需要注意一下若sqlite.db此檔案很大的話,就不適合放到 ramdisk裡去。
4 搬檔案、重開機
mkdir /var/lib/asterisk/db
#cp -a /var/lib/asterisk/astdb /var/lib/asterisk/db
cp -a /var/lib/asterisk/astdb.* /var/lib/asterisk/db
cp -a /var/lib/asterisk/sqlite.db /var/lib/asterisk/db
sync;sync;sync;reboot
重開機後,你可以觀察一下 /tmp/asteriskdb 裡面的檔案的時間,尤其時 astdb 此檔,它每分鐘都會更新一次。
這樣就是設定無誤了,然後你可以把這兩個檔案刪除了
rm /var/lib/asterisk/astdb
rm /var/lib/asterisk/sqlite.db
最後再用 iotop 工具去看, io load 是否真有減輕許多。
[note]參考資料:AstDB介紹(英文)、