記錄一次Zabbix-server由於磁盤空間不足遷移數據庫的過程

今天登陸zabbix,發現zabbix-server磁盤已經超過了80%,發出了告警,如圖:

4bb3b3971c3d830bbf9fa09978c17de8.png


96be50916b6449b67d120bfc74f25950.png


登入服務器一看,使用#ll -Shil發現以下幾個數據表太大了,佔用了磁盤空間很多:

c9ffa5361b2d200616b1f5d90b8176a2.png


在mysql裏查看也是這樣(我的zabbix的databases就叫zabbix):

mysql> select table_name, (data_length+index_length)/1024/1024 as total_mb, table_rows from information_schema.tables where table_schema='zabbix';
+----------------------------+---------------+------------+
| table_name                 | total_mb      | table_rows |
+----------------------------+---------------+------------+
| events                     | 2876.00000000 |   23659702 |
| history                    | 3005.60937500 |   36816179 |
| history_uint               | 2762.26562500 |   35895354 |
| trends_uint                | 1189.60937500 |   16612396 |
| trends                     |  831.59375000 |   11548652 |
+----------------------------+---------------+------------+
113 rows in set (0.08 sec)


上面幾個就是數據比較大的表,那麼我們重點就是對他們開刀。由於數據量太大,按照普通的方式delete數據的話基本上不太可能。所以決定直接採用truncate table的方式來快速清空這些表的數據,再使用mysqldump導出數據,刪除共享表空間數據文件,重新導入數據。


這個時候我們先停止zabbxi-server。

 systemctl stop zabbix-server
 systemctl stop httpd


然後登陸mysql,清除歷史數據:

[root@js-online-zabbixserver ~] # mysql -uroot -p
mysql > use zabbix;
Database changed
mysql > truncate table history;
Query OK, 123981681 rows affected (0.23 sec)
mysql > optimize table history;
1 row in set (0.02 sec)
mysql > truncate table history_uint;
Query OK, 57990562 rows affected (0.12 sec)
mysql > optimize table history_uint;
1 row in set (0.03 sec)


注意!如果在這一步,你先選擇了delete,比如先刪除了history_uint裏7天之前的數據:

mysql> delete from history_uint where clock<unix_timestamp(adddate(now(),-7));


但是你刪了半天,發現數據量太大,這麼刪太慢了,又想到zabbix還有每小時統計一次的趨勢數據,所以想幹脆連7天的記錄都不要了,於是查找並幹掉了delete進程然後改用了truncate,如下:

mysql> show processlist;
mysql> kill 136765
mysql> truncate table history_uint


這樣的話,你會發現truncate的速度很很慢的,就會很奇怪。答案其實不是truncate慢,而是直接死鎖了!這個時候如果查看一下線程就會發現truncate正在等待insert 、select等等鎖。


爲什麼會這樣呢?是因爲truncate沒有拿到mdl鎖,MySQL在回滾delete回滾結束前持有mdl鎖,truncate被鎖後續insert被truncate鎖(表鎖),殺掉truncate就可以正常 insert、select,完成delete回滾,回滾完成後就可以truncate了。這是一種鎖阻塞現象。


這個時候就只能殺掉truncate線程,等待MySQL的delete回滾結束,然後重新去truncate表。


插播結束,現在可以對原有的數據庫進行備份,#mysqldump -uroot -p密碼 zabbix > /home/zabbix_db.sql


備份完畢之後,就可以# systecmtl stop mariadb關閉掉mysql,同時刪除掉共享表空間數據文件,#rm -rf /var/lib/mysql/ib*


然後準備一個空間比較大的盤,比如這個新磁盤就叫ZabbixDB,然後在裏面建立一個DB文件夾。然後將/ZabbixDB/DB的所屬組和用戶都改成mysql,語句是:# chown -vR mysql:mysql /ZabbixDB/DB


改完了之後再給予700權限:# chmod -vR 700 /etc/ZabbixDB/DB


然後就把整個/var/lib/mysql*的內容都導入到ZabbixDB/DB裏:#cp -av /var/lib/mysql* /ZabbixDB/DB


修改my.cnf,在[mysqld]添加一句:innodb_file_per_table=1,這是修改InnoDB爲獨立表空間模式,每個數據庫的每個表都會生成一個數據空間。同時也要修改數據庫存放目錄:

10109693859979ee599849948a269afd.png


這個時候就可以# systemctl start mariadb重啓mysql服務,啓動完後查看一下剛剛在my.cnf裏設置的“獨立表空間”功能是否OK,檢查語句是 show variables like '%per_table%';,如果看到“ON”,就是說明已經開啓了:

07f6c768b6590694105a9040b5edd929.png


然後就可以還原數據庫了:

[root@js-online-zabbixserver zabbix]# mysql -uroot zabbix < /home/zabbix_db.sql


如果這個時候報錯,出現類似這樣的錯誤:

4e1b2903d176a7b8792e58600012a67c.png

這個可能是數據庫緩存造成的,這個時候可以在數據庫裏使用FLUSH TABLES; ,不過這多半會不好使。


那麼這個時候,就去新的mysql目錄夾,即/ZabbixDB/DB,然後進入數據庫zabbix,發現這個文件夾有很多文件,但是每一個文件都是既有一個.ibd又有一個.frm的,而這個“globalmacro”是隻有ibd而沒有.frm的,所以這個時候我們可以先把這個globalmacro.ibd轉移到別的地方去,然後重新執行

# mysql -uroot zabbix < /home/zabbix_db.sql

還原數據庫即可。


最後啓動zabbix-server: 

systemctl start zabbix-server
systemctl start httpd


最後查看一下磁盤空間情況:

519e982461b3a82834d4797d9ddae8ca.png

發現整個磁盤運行情況都OK了~,至此整個zabbix的數據庫遷移完成。


[參考資料]https://stackoverflow.com/questions/17914446/mysqldump-problems-with-restore-error-please-discard-the-tablespace-before-imp



最後的最後,如果您覺得本文對您升職加薪有幫助,那麼請不吝贊助之手,刷一下下面的二維碼,贊助本人繼續寫更多的博文!

wKioL1l16m3BMYDKAACPHEqd55Q687.jpg


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章