標籤:
在大量的用戶端,更新資料表的同一行時,會造成資料庫的輸送量大幅降低。
很多資料庫的前輩和同行分別通過實驗和源碼的方法,定位到了罪魁禍首----MySQL死結檢測
實驗方式:http://blog.csdn.net/zhaiwx1987/article/details/6952285
源碼方式:http://www.gpfeng.com/?p=426
請大家尤其注意這段代碼
#####
lock_mutex_enter();
ut_ad(lock_table_has(thr_get_trx(thr), index->table, LOCK_IX));
err = lock_rec_lock(TRUE, LOCK_X | LOCK_REC_NOT_GAP,
block, heap_no, index, thr);
MONITOR_INC(MONITOR_NUM_RECLOCK_REQ);
lock_mutex_exit();
#####
可以看出,MySQL在試圖擷取鎖期間,會有lock_mutex_enter 和lock_mutex_exit保護。
在一般情況下,lock_rec_lock執行速度很快,所以不成問題。
但是如果有大量鎖等待的情況,比如多個用戶端試圖更新同一行,則這個過程非常緩慢。因此整個innodb層就由並行變成了串列,大幅降低TPS。
解決辦法:
讓鎖等待盡量少,可以通過在資料庫層設定等待隊列達到這個效果,而OneSQL內建了這個方案。
測試案例:
update miaosha set mount=mount+1 where id=1;
測試環境
MySQL和OneSQL的關鍵參數配置如下,且均未開啟binlog
| 資料庫 |
innodb_flush_log_at_trx_commit |
innodb_log_file_size |
innodb_buffer_pool_size |
| OneSQL |
1 |
1000M |
8G |
| MySQL |
1 |
1000M |
8G |
硬體環境
| 記憶體 |
cpu |
磁碟 |
| 32g |
8c 每個core上有兩個超執行緒 Intel(R) Xeon(R) CPU E5620 @ 2.40GHz |
2塊raid0 7500r
|
測試結果:
在512個線程情況下,TPS為500/s
我實際測試,同樣的環境下使用OneSQL,TPS可以達到15682/s,效能提升達30倍左右。
如有任何疑問,請聯絡onesoft007
為什麼MySQL死結檢測會嚴重降低TPS