這兩天在測試一個程序,該程序對mysql數據庫有較大數據量的訪問,最近,一不小心出現了無法查詢的情況。
利用navicat排查服務器狀態發現,很多進程都locked了,有一條查詢語句一直處於sending data狀態,其他進程全部locked。
結束這個進程之後,mysql數據庫又恢復正常。
因此,遇到mysql被locked的情況,有以下幾種處理方法:
1. 關閉導致locked的進程;
2. 多次查詢,處理工作全部交給程序來做,減輕數據庫負擔;
3. 優化服務器:
以下轉自ChinaUnix論壇一個帖子:
數據庫有7G數據,隨著數據的增大,現在每天出現一次崩潰。
mysqladmin processlist 查詢進程,發現locked進程超多,而且一直locked不會解鎖,到最後整個mysql被locked進程占滿,崩潰。
是否和my.cnf裡如下配置有關。
根據網上資料,做了如下配置,效果不是很明顯:
MySQL調優性能的系統變量
(1)、back_log:
要求MySQL 能有的連接數量。當主要MySQL線程在一個很短時間內得到非常多的連接請求,這就起作用,然後主線程花些時間(盡管很短)檢查連接並且啟動一個新線程。
back_log值指出在MySQL暫時停止回答新請求之前的短時間內多少個請求可以被存在堆棧中。只有如果期望在一個短時間內有很多連接,你需要增加它,換句話說,這值對到來的TCP/IP連接的偵聽隊列的大小。你的操作系統在這個隊列大小上有它自己的限制。 試圖設定back_log高於你的操作系統的限制將是無效的。
當你觀察你的主機進程列表,發現大量264084 | unauthenticated user | xxx.xxx.xxx.xxx | NULL | Connect | NULL | login | NULL 的待連接進程時,就要加大back_log 的值了。默認數值是50,我把它改為500。
(2)、interactive_timeout:
服務器在關閉它前在一個交互連接上等待行動的秒數。一個交互的客戶被定義為對mysql_real_connect()使用CLIENT_INTERACTIVE 選項的客戶。 默認數值是28800,我把它改為7200。
(3)、key_buffer_size:
索引塊是緩沖的並且被所有的線程共享。key_buffer_size是用於索引塊的緩沖區大小,增加它可得到更好處理的索引(對所有讀和多重寫),到你能負擔得起那樣多。如果你使它太大,系統將開始換頁並且真的變慢了。默認數值是8388600(8M),我的MySQL主機有2GB內存,所以我把它改為402649088(400MB)。
(4)、max_connections:
允許的同時客戶的數量。增加該值增加mysqld 要求的文件描述符的數量。這個數字應該增加,否則,你將經常看到Too many connections 錯誤。 默認數值是100,我把它改為1024 。
(5)、record_buffer:
每個進行一個順序掃描的線程為其掃描的每張表分配這個大小的一個緩沖區。如果你做很多順序掃描,你可能想要增加該值。默認數值是131072(128K),我把它改為16773120 (16M)
(6)、sort_buffer:
每個需要進行排序的線程分配該大小的一個緩沖區。增加這值加速ORDER BY或GROUP BY操作。默認數值是2097144(2M),我把它改為16777208 (16M)。
(7)、table_cache:
為所有線程打開表的數量。增加該值能增加mysqld要求的文件描述符的數量。MySQL對每個唯一打開的表需要2個文件描述符。默認數值是64,我把它改為512。
(8)、thread_cache_size:
可以復用的保存在中的線程的數量。如果有,新的線程從緩存中取得,當斷開連接的時候如果有空間,客戶的線置在緩存中。如果有很多新的線程,為了提高性能可以這個變量值。通過比較Connections 和Threads_created 狀態的變量,可以看到這個變量的作用。我把它設置為80。
(10)、wait_timeout:
服務器在關閉它之前在一個連接上等待行動的秒數。 默認數值是28800,我把它改為7200。
mysql> show engines;
+------------+----------+----------------------------------------------------------------+
| Engine | Support | Comment |
+------------+----------+----------------------------------------------------------------+
| MyISAM | DEFAULT | Default engine as of MySQL 3.23 with great performance |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables |
| InnoDB | DISABLED | Supports transactions, row-level locking, and foreign keys |
| BerkeleyDB | NO | Supports transactions and page-level locking |
| BLACKHOLE | NO | /dev/null storage engine (anything you write to it disappears) |
| EXAMPLE | NO | Example storage engine |
| ARCHIVE | YES | Archive storage engine |
| CSV | NO | CSV storage engine |
| ndbcluster | NO | Clustered, fault-tolerant, memory-based tables |
| FEDERATED | NO | Federated MySQL storage engine |
| MRG_MYISAM | YES | Collection of identical MyISAM tables |
| ISAM | NO | Obsolete storage engine |
+------------+----------+-----------------------------------------------------------
mysql> show processlist;
+--------+---------+---------------------+--------+---------+------+-------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+--------+---------+---------------------+--------+---------+------+-------+------------------+
| 7572 | bbsuser | 61.152.X.89:1885 | wy**| Sleep | 4569 | | NULL |
| 235419 | bbsuser | 61.152.X.89:1935 | wy** | Sleep | 7 | | NULL |
| 262995 | root | localhost | NULL | Query | 0 | NULL | show processlist |
| 263404 | bbsuser | 61.152.X.76:53934 | wy** | Sleep | 93 | | NULL |
| 263948 | bbsuser | 61.152.X.76:54559 | wy** | Sleep | 9 | | NULL |
| 263986 | bbsuser | 61.152.X.76:54600 | wy** | Sleep | 4 | | NULL |
| 264005 | bbsuser | 61.152.X.76:54623 | wy** | Sleep | 1 | | NULL |
| 264010 | bbsuser | 61.152.X.76:54629 | wy** | Sleep | 0 | | NULL |
+--------+---------+---------------------+--------+---------+------+-------+------------------+
8 rows in set (0.00 sec)
1. 升級基本上沒幫助
2. 改用innodb試試看
3. 優化你的sql
4. 優化你的索引,緩存等
5. 優化你的程序
6. 換更好的server
vi /etc/my.cnf
# The following options will be passed to all MySQL clients
[client]
#password = your_password
port = 3306
socket = /tmp/mysql.sock
# Here follows entries for some specific programs
# The MySQL server
[mysqld]
port = 3306
socket = /tmp/mysql.sock
skip-bdb
skip-innodb
skip-locking
back_log=500
skip-name-resolve
#interactive_timeout=20
#wait_timeout=5
#connect_timeout=10
max_connections=10000
key_buffer = 512M
max_allowed_packet = 4M
table_cache = 1024
sort_buffer_size = 32M
read_buffer_size = 32M
join_buffer_size=32M
read_rnd_buffer_size = 4M
myisam_sort_buffer_size = 128M
thread_cache_size = 64
query_cache_limit=4M
query_cache_size = 64M
query_cache_type=1
# Try number of CPU's*2 for thread_concurrency
thread_concurrency = 8
#
#skip-networking
# Replication Master Server (default)
# binary logging is required for replication
#log=/usr/local/mysql/data/mysql.log
# required unique id between 1 and 2^32 - 1
# defaults to 1 if master-host is not set
# but will not function as a master if omitted
server-id = 1
[mysqldump]
quick
max_allowed_packet = 16M
[mysql]
no-auto-rehash
# Remove the next comment character if you are not familiar with SQL
#safe-updates
[isamchk]
key_buffer = 256M
sort_buffer_size = 256M
read_buffer = 2M
write_buffer = 2M
[myisamchk]
key_buffer = 256M
sort_buffer_size = 256M
read_buffer = 2M
write_buffer = 2M
[mysqlhotcopy]
interactive-timeout
很多時候MYISAM鎖表是由於查詢語句的問題,我公司的數據庫也是這樣的情況,我有次觀察到連接量的高峰值竟會達到5000,當時覺得很奇怪,因為根據狀態參數最多連接量也是百來個,抓取當時的快照才發現,都是LOCKED ,就象馬路上的車一樣一輛堵了引起整條路交通癱瘓,而首先引起LOCK的是一條很惡心的查詢,而這條查詢又頻繁出現。
我覺得你還是得從分析引起LOCK的查詢入手
摘自 yahohi的專欄