今天同事A找到我,說是Mysql server X的負載很高,查詢很慢。他自己搗鼓了一陣未果後,我們一起看了下。
[root@redhat var]# uname -a Linux xxx 2.6.18-128.el5 #1 SMP Wed Dec 17 11:41:38 EST 2008 x86_64 x86_64 x86_64 GNU/Linux [root@redhat var]# mysql -u root -p -e “select version();” +------------+ | version() | +------------+ | 5.1.32-log | +------------+
同事A的操作:
A一看mysql server有問題第一反應是重啟mysql server,囧!!o(╯□╰)
但是又使用了錯誤的命令
[root@redhat var]# /var/lib/mysql/libexec/mysqld restart ----操作① 100708 14:43:53 [ERROR] Fatal error: Please read "Security" section of the manual to find out how to run mysqld as root! 100708 14:43:53 [ERROR] Aborting 100708 14:43:53 [Note] /var/lib/mysql/libexec/mysqld: Shutdown complete
發現問題後,他又想起來應該是用下面的命令重啟
[root@redhat var]# service mysql restart ----操作② MySQL manager or server PID file could not be found! [FAILED] Starting MySQL......
CTRL+C取消
這時候
[root@redhat var]# ps aux | grep mysql
可以看到,系統又啟動了一個Mysql進程,但是過一會後,會自動消失,這時候看日志可以發現以下錯誤:
100708 15:26:52 [ERROR] Can't start server: Bind on TCP/IP port: Address already in use 100708 15:26:52 [ERROR] Do you already have another mysqld server running on port: 30017 ? 100708 15:26:52 [ERROR] Aborting
然後後面我們一起看。
首先我用client工具連接,發現mysql正常。web應用連接數據庫也正常只是查詢很慢。
其次我在命令下面,連接:
[root@redhat var]# mysql -u root -p
提示:
Enter password: ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
這時候同事A提醒我,可以重啟服務沒關系。囧,o(╯□╰)o,他在建議我重啟解決問題。
好吧,如他所願。於是我先:
[root@redhat var]# service mysql stop MySQL is running but PID file could not be found
然後去mysql data dir下面查看,果然沒有pid file。
這時候我的第一反應是配置文件不對,導致不能正常停止和重啟。
由於server是好的,因此我沒有急著去比較以前備份的/etc/my.cnf.bak和/etc/my.cnf。
我們先查找負載高的原因。因為命令行下無法進入mysql,在client下使用
復制代碼 代碼如下:show processlist;
可以看到裡面有很多locked的查詢,其中等待時間最久的一個是一個select查詢,顯示正在sending data,然後其余都是locked。
猜想是sending data的線程占用了“所有的分配給mysql的資源”,導致後來的線程全部掛起,由於“查詢(線程)是依次執行的”,後面locked的線程一直在等待前面sending data的線程結束。(這一段是猜想的…)
sending data的這個線程U是一個select 查詢,這個select對6張表進行了連接(公司的一個實習生提交的一個查詢),其中有兩張表的數據量在10w左右,另外有張data表數據量在 1000w左右,另外還有sum(distinct ) ,group by,order by… 可以想象下…不知道要到何年何月這個查詢才能執行完。
這個sending data的慢查詢的processid為799,當機立斷運行
復制代碼 代碼如下:kill 799
然後再運行
復制代碼 代碼如下:show processlist;
可以看到前面locked的線程在一個個依次執行,後面還有好多個跟線程U類似的select線程,全部kill掉後,被堵塞的別的正常的幾個Update,select,insert操作很快就執行完了。
而後,web應用恢復正常,速度變快。
返回linux命令行,使用
[root@redhat var]# top <shift+m 按內存使用排序> <1 顯示cpu使用情況>
這時候可以發現server負載恢復正常。
下面解決無法正常關閉重啟的情況。
也就是因為前面同事的誤操作引起的
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) 和MySQL manager or server PID file could not be found! [FAILED]
的錯誤。
我前面不是懷疑是配置文件裡面有什麼無法識別的參數選項麼。
通過
[root@redhat var]# diff /etc/my.cnf /etc/my.cnf.bak
發現,配置文件沒有問題。
#我的server的hostname,mysql pid文件默認名字為hostname.pid,如果沒有在/etc/my.cnf裡面指定特定和pid filename和pid file path的話,這個文件是跟mysql數據在一起的。
[root@redhat var]# diff /etc/my.cnf /etc/my.cnf.bak
這時候通過
#切換到mysql data dir(mysql的數據文件目錄下) #你們的mysql data dir或許跟我的不一樣哦,我的是/var/lib/mysql/var/ [root@redhat var]# cd /var/lib/mysql/var/
獲取mysql用戶運行的mysql進程的 pid,然後導入到hostname.pid文件裡面
[root@redhat var]# echo `ps aux | grep mysql | grep "user=mysql" | grep -v "grep" | awk '{print $2}'`>> redhat.pid #注意這裡的redhat.pid跟hostname相關,這裡是我的hostname.pid
將文件的屬主和屬主組改為mysql:mysql
[root@redhat var]# chown mysql:mysql redhat.pid
然後運行
[root@redhat var]# mysql -u root -p
還是會提示:
Enter password: ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
[root@redhat var]# ls /tmp | grep sock
果然沒有mysql.sock這個文件
但是這時候運行
[root@redhat var]# service mysql status
顯示
MySQL running (10949) [ OK ]
恩,pid file文件恢復正常,然後運行
[root@redhat var]# service mysql restart Shutting down MySQL. [ OK ] Starting MySQL. [ OK ]
這時候再運行
[root@redhat var]# ls /tmp | grep sock
可以發現重啟後,/tmp下有了mysql.sock這個文件。
大家可以搜索下mysql.sock的用途以及使用產生等等。
同事A的 操作① 導致pid 文件丟失, 操作② 導致mysql.sock文件丟失,大家感興趣可以去vi mysqld腳本和server mysql腳本,然後導致service mysql status/stop/start/restart運行異常,導致命令行下mysql -u root -p登錄mysql異常。
That's all.