1. 前言
在我登錄我自己開發(fā)的產(chǎn)品血玉鉆的時(shí)候以现,我發(fā)現(xiàn)接口沒有數(shù)據(jù)返回,遠(yuǎn)程登錄發(fā)現(xiàn)服務(wù)器也并沒有掛掉。因?yàn)槲沂峭ㄟ^(guò)pm2管理我的應(yīng)用的侦厚,于是乎,我日常pm2 restart 項(xiàng)目拙徽,發(fā)現(xiàn)接口還是數(shù)據(jù)沒有返回刨沦,也沒有報(bào)錯(cuò),于是我沒有用pm2啟動(dòng)項(xiàng)目膘怕,直接node main.js啟動(dòng)項(xiàng)目想诅,發(fā)現(xiàn)MySql Lock wait timeout exceeded 這個(gè)錯(cuò)誤。
然后我又進(jìn)行萬(wàn)能重啟操作岛心,重啟mysql来破,先systemctl stop mysqld,然后再systemctl start mysqld忘古,這問(wèn)題就出來(lái)了徘禁,啟動(dòng)失敗,報(bào)如下錯(cuò)誤髓堪。
Starting mysqld (via systemctl): Job for mysqld.service failed because the control process exited with error code. See "systemctl status mysqld.service" and "journalctl -xe" for details.
[FAILED]
然后我就看我之前寫的記錄mysql的文章云服務(wù)器Mysql安裝配置和linux安裝mysql啟動(dòng)不起來(lái)總結(jié)這兩篇文章晌坤,果然安裝記錄的文章,發(fā)現(xiàn)了mysql啟動(dòng)不起來(lái)的原因旦袋,如下:
Disk is full writing './binlog.000039' (OS errno 28 - No space left on device). Waiting for someone to free space... Retry in 60 secs. Message reprinted in 600 secs
2. linux命令查看磁盤使用情況
通過(guò)上面我們已經(jīng)知道骤菠,mysql啟動(dòng)不成功的原因是因?yàn)榇疟P不足。 這里我們就先來(lái)學(xué)習(xí)下疤孕,怎么查看linux服務(wù)器磁盤空間使用情況商乎。
2.1 使用df -h命令查看磁盤空空間
使用df -h命令查看磁盤空間,若磁盤空間不足則清理(當(dāng)然這是我解決之后的截圖祭阀,之前的磁盤滿的情況忘了截圖)鹉戚。
2.2 du的用法
du命令用來(lái)查看目錄或文件所占用磁盤空間的大小。常用選項(xiàng)組合為:du -sh
du常用的選項(xiàng):
-h:以人類可讀的方式顯示
-a:顯示目錄占用的磁盤空間大小专控,還要顯示其下目錄和文件占用磁盤空間的大小
-s:顯示目錄占用的磁盤空間大小抹凳,不要顯示其下子目錄和文件占用的磁盤空間大小
-c:顯示幾個(gè)目錄或文件占用的磁盤空間大小,還要統(tǒng)計(jì)它們的總和
--apparent-size:顯示目錄或文件自身的大小
-l :統(tǒng)計(jì)硬鏈接占用磁盤空間的大小
-L:統(tǒng)計(jì)符號(hào)鏈接所指向的文件占用的磁盤空間大小
du -lh --max-depth=1: 查看當(dāng)前目錄下一級(jí)子文件和子目錄占用的磁盤容量伦腐。
du -h -x --max-depth=1:查看哪個(gè)目錄占用過(guò)高
du -sh * | sort -n 統(tǒng)計(jì)當(dāng)前文件夾(目錄)大小赢底,并按文件大小排序
du -sk filename 查看指定文件大小
3. 查看占用空間大的文件
然后用du命令查看linux文件占用磁盤大小情況。
然后我們查到原因了,是mysql文件夾里面就占用了25G磁盤幸冻,總共磁盤才40G粹庞,然后在進(jìn)入mysql文件夾查看
發(fā)現(xiàn)binglog之類的文件竟然達(dá)到了20多G。
binlog是什么呢洽损?
Mysql Binlog是二進(jìn)制格式的日志文件庞溜,但是不能把binlog文件等同于OS系統(tǒng)某目錄下的具體文件,這是狹隘的碑定。Binlog是用來(lái)記錄Mysql內(nèi)部對(duì)數(shù)據(jù)庫(kù)的改動(dòng)(只記錄對(duì)數(shù)據(jù)的修改操作)流码,主要用于數(shù)據(jù)庫(kù)的主從復(fù)制以及增量恢復(fù)。
然后我們知道這寫文件主要是記錄對(duì)數(shù)據(jù)的修改操作延刘,主要用于數(shù)據(jù)庫(kù)的主從復(fù)制漫试,但是我的應(yīng)用并沒有用到主從復(fù)制,所以是可以刪除的访娶。
4. mysql的binlog安全刪除
默認(rèn)情況下mysql會(huì)一直保留mysql-bin文件商虐,這樣到一定時(shí)候觉阅,磁盤可能會(huì)被撐滿崖疤,這時(shí)候是否可以刪除這些文件呢,是否可以安全刪除典勇,是個(gè)問(wèn)題劫哼。
首先要說(shuō)明一下,這些文件都是mysql的日志文件割笙,如果不做主從復(fù)制的話权烧,基本上是沒用的,雖然沒用伤溉,但是不建議使用rm命令刪除般码,這樣有可能會(huì)不安全,正確的方法是通過(guò)mysql的命令去刪除乱顾。
我們登錄mysql之后板祝,使用命令
mysql> reset master;
Query OK, 0 rows affected (3 min 37.65 sec)
其實(shí)關(guān)鍵的命令就是reset master;這個(gè)命令會(huì)清空mysql-bin文件。
另外如果你的mysql服務(wù)器不需要做主從復(fù)制的話走净,建議通過(guò)修改my.cnf文件避矢,來(lái)設(shè)置不生成這些文件诈闺,只要?jiǎng)h除my.cnf中的下面一行就可以了。
log-bin=mysql-bin
如果你需要復(fù)制,最好控制一下這些日志文件保留的天數(shù)映企,可以通過(guò)下面的配置設(shè)定日志文件保留的天數(shù):
expire_logs_days = 7
表示保留7天的日志,這樣老日志會(huì)自動(dòng)被清理掉析孽。
另外的方法
4.1 手動(dòng)清理binlog
① 查看主庫(kù)和從庫(kù)正在使用的binlog是哪個(gè)文件
show master status\G
show slave status\G \
② 在刪除binlog日志之前律歼,首先對(duì)binlog日志備份,以防萬(wàn)一
開始動(dòng)手刪除binlog:
purge master logs before'2016-09-01 17:20:00'; //刪除指定日期以前的日志索引中binlog日志文件
或
purge master logs to'mysql-bin.000022'; //刪除指定日志文件的日志索引中binlog日志文件
注意:
時(shí)間和文件名一定不可以寫錯(cuò),尤其是時(shí)間中的年和文件名中的序號(hào)抛虏,以防不小心將正在使用的binlog刪除2┢洹!迂猴!
切勿刪除正在使用的binlogD降!沸毁!
使用該語(yǔ)法峰髓,會(huì)將對(duì)應(yīng)的文件和mysql-bin.index中的對(duì)應(yīng)路徑刪除。
4.2 通過(guò)設(shè)置binlog過(guò)期的時(shí)間息尺,使系統(tǒng)自動(dòng)刪除binlog文件
這種就是類似上面的expire_logs_days = 7
mysql> show variables like 'expire_logs_days';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| expire_logs_days | 0 |
+------------------+-------+
mysql> set global expire_logs_days = 30; #設(shè)置binlog多少天過(guò)期
————————————————
注意:
過(guò)期時(shí)間設(shè)置的要適當(dāng)携兵,對(duì)于主從復(fù)制,要看從庫(kù)的延遲決定過(guò)期時(shí)間搂誉,避免主庫(kù)binlog還未傳到從庫(kù)便因過(guò)期而刪除徐紧,導(dǎo)致主從不一致!L堪谩并级!
通過(guò)上面的方法之后,我們?cè)僖淮尾榭创疟P使用情況侮腹,發(fā)現(xiàn)刪除binlog之后嘲碧,足足多出了一半以上的磁盤空間,開心父阻。
5. mysql擴(kuò)展
5.1 innodb_file_per_table 的簡(jiǎn)要說(shuō)明
在很久很久以前也就是說(shuō)還沒有innodb_file_per_table 的那個(gè)年代愈涩,所有的innodb表的數(shù)據(jù)都是保存在innodb系統(tǒng)表空間中的,
在有了innodb_file_per_table參數(shù)后innodb可以把每個(gè)表的數(shù)據(jù)單獨(dú)保存加矛。單獨(dú)保存有兩方面的優(yōu)勢(shì)一個(gè)是方便管理履婉,二個(gè)是提長(zhǎng)性能。
5.2 mysql 引用innodb_file_per_table是為了解決什么問(wèn)題
在沒有innodb_file_per_table之前所有的innodb表的數(shù)據(jù)都是統(tǒng)一保存到,innodb系統(tǒng)表空間文件中的斟览,如果想讓mysql的行為
與innodb_file_per_table還沒有引入時(shí)的行為一致毁腿,那么把innodb_file_per_table設(shè)置為OFF就行。
1趣惠、由于數(shù)據(jù)都統(tǒng)一保存到innodb系統(tǒng)表空間文件中狸棍,在drop table ,truncate table后表空間文件并不會(huì)進(jìn)行收縮味悄,也就是說(shuō)表空間文件所占的磁盤空間并不會(huì)因?yàn)閐rop table , truncate table 而釋放草戈。
2、對(duì)于mysql來(lái)說(shuō)alter table 的過(guò)程大概可以概括為 1)根據(jù)alter table 的指示創(chuàng)建出一張新的表 . 2)把老表的數(shù)據(jù)插入表新表中3)刪了老表. 4)把新表的表名字重命名成老表的名字侍瑟;當(dāng)然如今的mysql已經(jīng)有inplace對(duì)上面的過(guò)程進(jìn)行優(yōu)化了唐片,不過(guò)并不是所有的alter table 都支持inplace丙猬,更多關(guān)于inplace的問(wèn)題在此不表了。還是回到alter table 的第2)步 由這里可以看出系統(tǒng)表空間是要增大的(理由是:創(chuàng)建了新的表费韭,又在向新的表中插入數(shù)據(jù)) 所以啊alter table 會(huì)導(dǎo)致系統(tǒng)表空間的進(jìn)一步加大茧球。
3、在linux系統(tǒng)中不允許并行的對(duì)一個(gè)文件進(jìn)行寫入(innodb_flush_method=O_DIRECT的情況下是這樣的)星持,這可能成為一個(gè)性能問(wèn)題
4抢埋、對(duì)于使用innodb_file_per_table=ON的情況下,默認(rèn)創(chuàng)建出來(lái)的ibd文件的格式是Barracuda督暂,在這個(gè)文件格式下innodb數(shù)據(jù)行的格式就可以設(shè)置為compressed 或 dynamic 格式了揪垄。compressed 提供壓縮功能節(jié)約空間,dynamic能優(yōu)化對(duì)blob,text這樣的數(shù)據(jù)類型的存儲(chǔ)以提升性能逻翁。
5.3 Mysql刪除數(shù)據(jù)后磁盤空間未釋放的解決辦法
官方推薦使用 OPTIMIZE TABLE命令來(lái)優(yōu)化表饥努,該命令會(huì)重新利用未使用的空間,并整理數(shù)據(jù)文件的碎片八回。
語(yǔ)法如下:
OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] ...
注:該命令將會(huì)整理表數(shù)據(jù)和相關(guān)的索引數(shù)據(jù)的物理存儲(chǔ)空間酷愧,用來(lái)減少占用的磁盤空間,并提高訪問(wèn)表時(shí)候的IO性能缠诅。但是溶浴,具體對(duì)表產(chǎn)生的影響是依賴于表使用的存儲(chǔ)引擎的。該命令對(duì)視圖無(wú)效滴铅。
執(zhí)行語(yǔ)句:show table status like 'table_name'查看表信息
查詢結(jié)果中:
Index_length 代表索引的數(shù)量
Data_free 代表碎片數(shù)量
然后執(zhí)行下面命令進(jìn)行優(yōu)化整理:
mysql > optimize table table_name
如果之前的碎片數(shù)量多戳葵,執(zhí)行時(shí)間可能會(huì)久一點(diǎn)就乓,執(zhí)行結(jié)束后出現(xiàn)下面框內(nèi)的數(shù)據(jù)則優(yōu)化成功汉匙。
注意事項(xiàng):
由于命令optimize會(huì)進(jìn)行鎖表操作,所以進(jìn)行優(yōu)化時(shí)要避開表數(shù)據(jù)操作時(shí)間生蚁,避免影響正常業(yè)務(wù)的進(jìn)行噩翠。
MySQL5.7已經(jīng)推薦對(duì)于InnoDB的table使用 alter table table_name engine=innodb;語(yǔ)句的方式來(lái)進(jìn)行表碎片優(yōu)化。