使用xtrabackup備份mysql數據庫

本文主要記錄下使用percona xtrabackup 2.4來備份mysql數據。最終效果是實現mysql所在主機定時進行全量備份和增量備份並自動刪除舊備份文件。另有一台數據存儲機,定時通過ssh抓取各個mysql主機上的備份文件,保存更長時間後刪除舊文件。

用到的軟件和技術有:xtrabackup(免費的mysql備份程序),qpress(xtrabackup壓縮需要的依賴,據說壓縮比很高),python3.5(ssh的遠程抓取,因為我不會bash)。

mkdir -p /root/42/script
cd /root/42/script
#安裝qpress
wget http://www.quicklz.com/qpress-11-linux-x64.tar
tar xf qpress-11-linux-x64.tar
mv qpress /usr/local/bin/
#centos6安裝xtrabackup
yum install http://www.percona.com/downloads/percona-release/redhat/0.1-4/percona-release-0.1-4.noarch.rpm
yum install libev -y
yum install percona-xtrabackup-24 -y
#新建backup.sh(來源未知)內容如下:
#!/bin/bash

PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
 
BACKUP_BASE_DIR="/data/backup/xtrabackup"
INC_BASE_LIST="${BACKUP_BASE_DIR}/inc_list.txt"
XTRABACKUP_PATH="/usr/bin/innobackupex"
 
MYSQL_CNF="/etc/my.cnf"
MYSQL_HOSTNAME=127.0.0.1
MYSQL_USERNAME=root
MYSQL_PASSWORD=""
 
LOCK_FILE="/tmp/innobackupex.lock"
THREAD=3
 
mkdir -p ${BACKUP_BASE_DIR}
CURRENT_BACKUP_PATH="${BACKUP_BASE_DIR}/$(date +%F_%H-%M)"
[[ -d ${CURRENT_BACKUP_PATH} ]] && CURRENT_BACKUP_PATH="${BACKUP_BASE_DIR}/$(date +%F_%H-%M-%S)"
 
print_help(){
    echo "--------------------------------------------------------------"
    echo "Usage: $0 full | inc | help               "
    echo "--------------------------------------------------------------"
    exit 1
}
 
[[ $# -lt 1 || "$1" == "help" ]] && print_help
 
[[ -f "$LOCK_FILE" ]] && echo -e "Usage: rm -f $LOCK_FILE\nUsage: chattr -i $LOCK_FILE && rm -f $LOCK_FILE" && exit 1
 
FullBackup(){
    touch $LOCK_FILE
    chattr +i $LOCK_FILE
    local rc=0
    ${XTRABACKUP_PATH} \
    --defaults-file=${MYSQL_CNF} \
    --user=${MYSQL_USERNAME} \
    --password=${MYSQL_PASSWORD} \
    --host=${MYSQL_HOSTNAME} \
    --compress \
    --compress-threads=${THREAD} \
    --parallel=${THREAD} \
    --no-timestamp ${CURRENT_BACKUP_PATH} > ${CURRENT_BACKUP_PATH}_full.log 2>&1
    grep ".*\ completed\ OK\!" ${CURRENT_BACKUP_PATH}_full.log > /dev/null 2>&1
    if [ $? -ne 0 ];then
        rc=1
        [[ -d ${CURRENT_BACKUP_PATH} && $(pwd) != "/" ]] && rm -rf ${CURRENT_BACKUP_PATH}
    else
        echo "NULL|${CURRENT_BACKUP_PATH}|full" >> ${INC_BASE_LIST}
        [[ -d ${CURRENT_BACKUP_PATH} && $(pwd) != "/" ]] && chattr +i ${CURRENT_BACKUP_PATH} || rc=1
    fi
    chattr -i ${LOCK_FILE}
    rm -f $LOCK_FILE
    chattr +a ${INC_BASE_LIST}
    return $rc
}
 
IncBackup(){
    touch $LOCK_FILE
    chattr +i $LOCK_FILE
    local rc=0
    PREV_BACKUP_DIR=$(sed '/^$/d' ${INC_BASE_LIST} | tail -1 | awk -F '|' '{print $2}')
    ${XTRABACKUP_PATH} \
    --defaults-file=${MYSQL_CNF} \
    --user=${MYSQL_USERNAME} \
    --password=${MYSQL_PASSWORD} \
    --host=${MYSQL_HOSTNAME} \
    --compress \
    --compress-threads=${THREAD} \
    --no-timestamp --incremental ${CURRENT_BACKUP_PATH} \
    --incremental-basedir=${PREV_BACKUP_DIR} > ${CURRENT_BACKUP_PATH}_inc.log 2>&1
    grep ".*\ completed\ OK\!" ${CURRENT_BACKUP_PATH}_inc.log > /dev/null 2>&1
    if [ $? -ne 0 ];then
        rc=1
        [[ -d ${CURRENT_BACKUP_PATH} && $(pwd) != "/" ]] && rm -rf ${CURRENT_BACKUP_PATH}
    else
        echo "${PREV_BACKUP_DIR}|${CURRENT_BACKUP_PATH}|inc" >> ${INC_BASE_LIST}
        [[ -d ${CURRENT_BACKUP_PATH} && $(pwd) != "/" ]] && chattr +i ${CURRENT_BACKUP_PATH} || rc=1
    fi
    chattr -i ${LOCK_FILE}
    rm -f $LOCK_FILE
    chattr +a ${INC_BASE_LIST}
    return $rc
}
 
## 全量備份
if [ "$1" == "full" ];then
    FullBackup
fi
 
## 增量備份
if [ "$1" == "inc" ];then
    ## 若全量備份不存在,則執行全量備份
    if [[ ! -f ${INC_BASE_LIST} || $(sed '/^$/d' ${INC_BASE_LIST} | wc -l) -eq 0 ]];then
        FullBackup
    else
        IncBackup
    fi
fi
 
## 刪除22天前的備份
if [[ -d ${BACKUP_BASE_DIR} && $(pwd) != "/" ]];then
    find ${BACKUP_BASE_DIR} -name "$(date -d '22 days ago' +'%F')_*" | xargs chattr -i
    find ${BACKUP_BASE_DIR} -name "$(date -d '22 days ago' +'%F')_*" | xargs rm -rf
fi

#可能需要修改backup.sh中的如下參數
BACKUP_BASE_DIR="/data/backup/xtrabackup"
XTRABACKUP_PATH="/usr/bin/innobackupex"
 
MYSQL_CNF="/etc/my.cnf"
MYSQL_HOSTNAME=127.0.0.1
MYSQL_USERNAME=root
MYSQL_PASSWORD=""
#給腳本添加執行權限
chmod 755 /root/42/script/backup.sh
#执行一次全量备份
/root/42/script/backup.sh full
#如果沒有錯誤信息,就可以看到BACKUP_BASE_DIR下生成了備份文件
#檢查下cron是否啟動
service crond status
#如果未啟動則將cron設置為開機啟動並手動啟動下
chkconfig crond on
service crond start
#添加定時任務
crontab -e
#在底部新增內容
## 每周六凌晨3:30一次全量备份
## 每周二、四、日的凌晨3:30点执行增量备份
30 3 * * 6 /root/42/script/backup.sh full
30 3 * * 2,4,7 /root/42/script/backup.sh inc

我的Git命令記錄

在服務器上初始化項目

cd /temp
git clone --bare /home/fred/Documents/workspace/amazon/.git amazon.git
scp -P 2009 -r amazon.git root@127.0.0.1:/data/42/git

在本地添加遠程項目

git remote add origin ssh://root@127.0.0.1:2009/data/42/git/amazon.git
git remote -v
#推送
git push origin master
#下載更新
git clone ssh://root@127.0.0.1:2009/data/42/git/unlock.git

外賣

早上看到樓道里的廣告,外面狂風暴雨,用戶享受外賣員冒風雨送來的食物非常開心。我和Emanon從不點外賣,如果是外面那麼大風雨,自己不願意淋雨就付錢讓別人淋,我們心裡過不去;如果是好天氣為什麼不自己出去吃呢,還能活動一下。另一個方面是外面的食物不可能比去店裡吃好吃,想象一下任何菜,直接出鍋裝盤上桌吃,和出鍋進外賣盒密封10分鐘吃口味色澤肯定是不同的。但現在似乎很多人完全不在乎口味,吃飯只是補充能量而以,並無樂趣可言。對於又懶又沒有味覺的人,我們表示遺憾;對於讓人變得更懶更麻木的公司,我們表示抵制。

Fedora25使用DNSCrypt

DNSCrypt是一種認證DNS客戶端和DNS解析器之間通信的協議。 它可以防止DNS欺騙。下面記錄下在Fedora25上使用DNSCrypt的步驟。

安裝dnscrypt-proxy並新建一個執行用戶

sudo dnf install dnscrypt-proxy
sudo adduser -m -N  -r -s /bin/false dnscrypt

安裝完成後可以從/usr/share/dnscrypt-proxy/dnscrypt-resolvers.csv的第一列挑選一個服務商,我嘗試用香港的發現連接不上,於是選擇法國cs-fr。嘗試運行dnscrypt-proxy:

sudo dnscrypt-proxy -u dnscrypt -R cs-fr

我的桌面是Xfce,所以設置DNS很方便。找到程序/設定值/網路連線,選中需要編輯的網路點編輯。在IPv4設定面板中,如果你之前方法是“自動(DHCP)”,則變更方法為“只用自動(DHCP)位址”,並在DNS伺服器一欄填入127.0.0.1。如果之前就有固定IP,則只需要把DNS伺服器一欄改為127.0.0.1即可。多個DNS伺服器可以用半角逗號隔開。

如果沒有桌面環境,要設置DNS的話可以參考The adventurous can edit the appropriate script in /etc/sysconfig/network-scripts/. If you don't have NetworkManager installed, editing /etc/resolv.conf would work too.

重啟網絡服務已使剛剛新設置的DNS生效。可以使用dig驗證當前dns,出現SERVER: 127.0.0.1#53即說明成功。

sudo systemctl restart network.service
dig ft.wupo.info

設置自動重啟也很簡單,新建文件/etc/systemd/system/dnscrypt.service,內容如下:

[Unit]
Description=dnscrypt - Encrypted DNS service provided by OpenDNS
After=NetworkManager.service

[Service]
ExecStart=/usr/sbin/dnscrypt-proxy -u dnscrypt -R cs-fr
ExecReload=/bin/kill -HUP $MAINPID

[Install]
WantedBy=basic.target

重啟系統守護

sudo systemctl daemon-reload

添加dnscrypt到開啟啟動

sudo systemctl enable dnscrypt.service

當然你也可以手動通過systemctl命令來啟動和停止dnscrypt-proxy,像這樣:

sudo systemctl start dnscrypt.service

參考鏈接:Lucid Electric Dreams: Setting up dnscrypt on Fedora

fla文件損壞

端午節的第一天,Emanon在家用Flash畫了一天動畫線稿。晚上去吃了樓下新開的小火鍋店,口味一般。吃完飯感覺外面空氣不錯,還去深大湖邊遛了一圈。

回家後發現flash卡的不幸,幾乎無法動彈。Emanon有隨時保存文件的習慣,所以打算關掉Flash但是關閉也沒反應。等了一會兒,有反應了,彈出提示詢問是否保存,在本能的點擊“保存”按鈕後Flash又回到了假死狀態,期間又有過彈窗詢問是否關閉程序,選了關閉。

使用Win10的這兩個月,給我倆帶了無盡的痛苦,比如開機後時間總是不對,比如無線網卡總是總是莫名其妙斷線,比如顯示器完全隨機的出現黑屏……這些問題在另一塊硬盤的Ubuntu上都沒有出現,我只能懷疑win10。至於上面導致電腦卡的動不了,甚至文件管理器和關機都卡到爆的原因,也是windows在執行一個Antimalware Service Executable的進程,占滿了CPU。由於最後一次保存失敗,所以之前的fla文件只寫入了七百KB就斷掉了,fla文件便損壞了。

在網上找到一些搶救fla文件的方法都失敗了,因為我這種是損壞的太嚴重了。搶救方法有:讓朋友用高版本Flash打開,如果能打開則可另存檔案後發回來。或者複製一個fla文件,變更fla文件後綴名為zip,然後解壓開後嘗試找到並修正其中xml文件的錯誤。除了上面的方法還搜索到有種軟件號稱可以把swf轉換成fla,病急亂投醫,不僅沒有把fla轉會來反而中了使Win10感染了病毒。這裡要嚴重吐槽下Win10自帶的病毒防護軟件Windows Defender,我即使進行了全盤掃描,也未能根除感染的病毒。雖然雙系統重裝Windows比較麻煩,但這已經無法阻擋我返回Win7的決心了。

最後把線稿的輸出放上來緬懷下(手機應該是看不了swf):