關於MySQL用戶會話及連接線程
0、概念理解:用戶會話和連接線程是什麽關系?
用戶會話和用戶連接線程是一一對應的關系,一個會話就一個用戶連接線程。
問題描述:
如果系統因為執行了一個非常大的dml或者ddl操作導致系統hang住,我們想斷掉這個操作,怎麽辦?
解決辦法:
1、kill thread:殺死用戶的會話
但是時間長,效果不佳:前滾+回滾,前提是已經進行了很長時間,回滾就需要更多的時間
2、kill mysqld進程:推薦,用這種殺進程的方式,速度快
kill -9 進程號(ps aux 查看進程號)
數據庫先前滾,不主動回滾,直接可以對外進行服務了,當讀到哪個未提交事務時再去慢慢回滾。
一、kill用戶會話及用戶連接線程
1、如何查看用戶會話,如何殺掉用戶會話
[[email protected] ~]# netstat -anp |grep 3306 tcp 0 0 :::3306 :::* LISTEN 17324/mysqld [[email protected] ~]# ps -ef |grep ‘mysql -px x‘ root 20510 20483 0 15:59 pts/1 00:00:00 mysql -px x root 2052846646 0 15:59 pts/4 00:00:00 grep mysql -px x root 45626 45565 0 05:44 pts/3 00:00:00 mysql -px x [[email protected] ~]# kill -9 20510
# kill -9 <mysql會話進程PID> //快速釋放資源(推薦)
註意:千萬不要將mysqld給kill掉了,不要殺掉LISTEN進程
2、如何查看用戶連接線程,如何殺掉用戶連接線程
mysql> show processlist;
+--------+
| Id |
+--------+
| 194850 |
| 194851 |
+--------+
mysql> kill 194850;
mysql> show processlist;
+--------+
| Id |
+--------+
| 194851 |
| 194852 |
+--------+
註意:如果將用戶連接線程殺死斷掉,而會話沒有殺掉的話,該用戶會話又會重新開啟一個用戶連接線程。
3、殺掉用戶連接線程的工作過程、弊端風險
1、過程:
rollback--->釋放資源--->kill線程
2、弊端與風險:
1、可能出現系統更加繁忙的情況(因為大量的rollback)
2、會話釋放需要很長的時間
Q:假設現在有1000個用戶連接,如何快速殺掉?
A:
1、使用concat寫腳本
mysql> select concat(‘kill ‘,ID,‘;‘) into outpfile ‘/tmp/kill.txt‘ from information_schema.PROCESSLIST;
shell> cat kill.txt
kill 194850;
kill 194851;
然後,復制到mysql中進行執行,將用戶連接線程都kill掉。
2、使用awk取出用戶會話進程ID都kill掉
shell> netstat -anp|grep mysql|grep -v mysqld|awk ‘{print $8}‘|awk -F ‘/‘ ‘{print $1}‘|xargs kill -9
關於mysqld_safe的註意點:
在os層面將用戶連接線程kill掉,通過pstree -p可以看到MySQL相關進程及線程ID,#kill -9 mysql任一線程,會導致該mysqld進程被kill;但是通過mysqld_safe的安全機制,又會重新啟一個mysqld進程;如此原來的用戶連接線程也就隨原來的進程一塊被幹掉了。
二、MySQL客戶端的連接
1、最大連接數
mysql> show variables like ‘max_connections‘;
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | 151 |
+-----------------+-------+
由上可見,MySQL默認客戶端的最大連接數是151,但是,在大並發下一百多的連接數就會不夠用,需要調整最大連接數,修改並寫入配置文件中:
max_connections = 1000
wait_timeout = 1000000 #超時時間
重啟MySQL服務
2、查看當前有多少連接
mysql> show status like ‘%Threads_connected%‘;
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| Threads_connected | 1 |
+-------------------+-------+
1 row in set (0.01 sec)
mysql> show processlist;
+-------+------+-----------+------+---------+------+----------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+-------+------+-----------+------+---------+------+----------+------------------+
| 17219 | root | localhost | NULL | Query | 0 | starting | show processlist |
+-------+------+-----------+------+---------+------+----------+------------------+
1 row in set (0.01 sec)
3、最大失敗連接數:max_connect_errors
mysql> show variables like ‘max%errors‘;
+--------------------+-------+
| Variable_name | Value |
+--------------------+-------+
| max_connect_errors | 100 |
+--------------------+-------+
1 row in set (0.00 sec)
是一個MySQL中與安全有關的計數器值,負責阻止過多嘗試失敗的客戶端以暴力破解密碼的情況,值的大小與性能無太大的關系。
默認是100,也就是說如果某一客戶端嘗試連接此MySQL服務器,但是失敗(如密碼錯誤等等)10次,則MySQL會無條件強制阻止此客戶端連接。如果想重置計數器對某一客戶端的值,則必須重啟mysqld或者mysql> flush hosts;,當該客戶端成功連接一次mysqld後,針對此客戶端的max_connect_errors會清零。
如果max_connect_errors的設置過小,則網頁可能提示無法連接數據庫服務器。
一般來說建議數據庫服務器不監聽來自網絡的連接,僅僅通過sock連接,這樣可以防止絕大多數針對mysql的攻擊;如果必須要開啟mysql的網絡連接,則最好設置此值,以防止窮舉密碼的攻擊手段。
三、關於用戶工作空間
Q:如何判斷用戶會話線程空間(用戶工作空間)是否分配過小?
A:
1、sort_buffer_size:需要排序會話的緩存大小(默認256K),是針對每一個connection的;過大的配置+高並發可能會耗盡系統內存資源。
2、binlog_cache_size:二進制日誌緩沖區(默認32K),基於會話;
一個事務做出的修改,
當小於4binlog_cache_size時,所有修改內容存入binary log cache;
當大於binlog_cache_size時,內容存入磁盤臨時表。
3、join_buffer_size:多表連接結果集緩沖區,基於會話;
(每次join操作都會調用my_malloc、my_free函數申請/釋放join_buffer_size大小的內存)
也就是說,sort_buffer、binlog_cache、join_buffer的組成,形成用戶會話線程空間。一般的,當Sort_merge_passes(磁盤排序)每秒值很大時,就說明用戶工作空間分配過小,就應該考慮增加sort_buffer_size值。
關於MySQL用戶會話及連接線程