MySQL是典型的三層架構模式,在日常使用中對MySQL問題排查和優化,也應該針對具體問題,從對應的層解決問題前端
max_connections參數用來設置最大鏈接 ( 用戶 ) 數 。每一個鏈接MySQL的用戶均算做一個鏈接,mysql
max_connections的默認值爲100 。linux
MySQL不管如何都會爲管理員保留一個用於登陸的鏈接,所以實際MySQL最大可鏈接數爲面試
max_connections+1。sql
max_connections 最大爲16384 。數據庫
該參數設置太小的話,會出現」Too many connections」錯誤。後端
查看max_connections參數的方法:緩存
mysql> show variables like "max_connections";
修改最大可鏈接數的方法有:安全
# 方法一:即時生效,無需重啓MySQL,重啓失效 1.root登陸MySQL: $ mysql -uroot -p 2.查看當前的Max_connections參數值: mysql> SELECT @@MAX_CONNECTIONS AS 'Max Connections'; 3.設置該參數的值: mysql> set global max_connections = 200; # 方法二:須要重啓MySQL,重啓不失效,修改my.conf max_connections=200 # 方法三:編譯MySQL的時候,設置默認最大鏈接數 1.打開MySQL源碼,進入SQL目錄,修改mysqld.cc文件: {"max_connections", OPT_MAX_CONNECTIONS, "The number of simultaneous clients allowed.", (gptr*) &max_connections, (gptr*) &max_connections, 0, GET_ULONG, REQUIRED_ARG, 100, 1, 16384, 0, 1, 0}, 2. 編譯三部曲 $ ./configure $ make $ make install
maxconnecterrors是一個MySQL中與安全有關的計數器值,它負責阻止過多嘗試失敗的客戶端以防止暴力破解密碼的狀況。maxconnecterrors的值與性能並沒有太大關係。bash
因爲出現某臺host鏈接錯誤次數等於maxconnecterrors , 日誌中會出現相似blocked because of many connection errors 的信息,解決方法以下:
1.執行mysqladmin flush-hosts或者重啓 MySQL服務,將錯誤計數器清零 2.my.cnf修改max_connect_errors的值,能夠適當大些
是在特定場合下才能使用的,這個變量是針對Solaris系統的,若是設置這個變量的話,mysqld就會調用thr_setconcurrency()
.這個函數使應用程序給同一時間運行的線程系統提供指望的線程數目。
CPU核數的2倍,好比有一個雙核的CPU,那麼thread_concurrency
的應該爲4;2個雙核的cpu, thread_concurrency的值應爲8。
這個參數是限制server容許通訊的最大數據包大小,有時候可能由於這個參數設置太小,比較大的insert或者update操做會失敗,因此參數應該設置大一些
關鍵詞緩衝區大小,緩存MyISAM索引塊 ,決定索引處理速度,讀取索引處理。
根據增大Key_reads / Uptime
來優化這個參數查看Key_reads / Uptime
的方法:
$ mysqladmin ext -ri10 | grep Key_reads
此參數用來緩存空閒的線程,以致不被銷燬,若是線程緩存中有空閒線程,這時候若是創建新鏈接,MYSQL就會很快的響應鏈接請求。
使用 show status查看當前mysql鏈接狀況 :
mysql>SHOW STATUS WHERE Variable_name LIKE '%Thread%'; Threads_cached:表明當前此時此刻線程緩存中有多少空閒線程。 Threads_connected:表明當前已創建鏈接的數量,由於一個鏈接就須要一個線程,因此也能夠當作當前被使用的線程數。 Threads_created:表明從最近一次服務啓動,已建立線程的數量。 Threads_running:表明當前激活的(非睡眠狀態)線程數。並非表明正在使用的線程數,有時候鏈接已創建,可是鏈接處於sleep狀態,這裏相對應的線程也是sleep狀態。
建議threadcachesize設置成與threads_connected同樣 。
每一個鏈接須要使用 buffer 時分配的內存大小,不是越大越好。例 : 1000個鏈接 , 一個1MB,會佔用1GB內存,200WX1MB=20GB
爲了減小參與 join 的 」 被驅動表 「的讀取次數以提升性能 , 須要使用到join buffer來協助完成 join 操做當 join buffer 過小,MySQL 不會將該buffer存入磁盤文件而是先將join buffer中的結果與需求join的表進行操做,而後清空 join buffer 中的數據,繼續將剩餘的結果集寫入次buffer中,如此往復,這勢必會形成被驅動表須要被屢次讀取,成倍增長IO訪問,下降效率 。
查詢緩存大小,再查詢時返回緩存,緩存期間表必須沒有被更改,不然緩存失效,多寫入操做的話設置大了會影響寫入效率。
mySQL用於查詢的緩存的內存被分紅一個個變長數據塊,用來存儲類型,大小,數據等信息。 當服務器啓動的時候,會初始化緩存須要的內存,是一個完整的空閒塊。當查詢結果須要緩存的時候,先從空閒塊中申請一個數據塊大於參數querycacheminresunit的配置,即便緩存數據很小,申請數據塊也是這個,由於查詢開始返回結果的時候就分配空間,此時沒法預知結果多大。
配內存塊須要先鎖住空間塊,因此操做很慢,MySQL會盡可能避免這個操做,選擇儘量小的內存塊,若是不夠,繼續申請,若是存儲完時有空餘則釋放多餘的。 緩存存放在一個引用表中,經過一個哈希值引用,這個哈希值包括查詢自己,數據庫,客戶端協議的版本等,任何字符上的不一樣,例如空格,註釋都會致使緩存不命中。
當查詢中有一些不肯定的數據時,是不會緩存的,比方說now(),current_date(),自定義函數,存儲函數,用戶變量,字查詢等。因此這樣的查詢也就不會命中緩存,可是還會去檢測緩存的,由於查詢緩存在解析SQL以前,因此MySQL並不知道查詢中是否包含該類函數,只是不緩存,天然不會命中。 緩存存放在一個引用表中,經過一個哈希值引用,這個哈希值包括查詢自己,數據庫,客戶端協議的版本等,任何字符上的不一樣,例如空格,註釋都會致使緩存不命中。
這個參數是MySQL讀入緩衝區的大小,將對錶進行順序掃描的請求將分配一個讀入緩衝區,mysql會爲它分配一段內存緩衝區,readbuffersize變量控制這一緩衝區的大小,若是對錶的順序掃描很是頻繁,並你認爲頻繁掃描進行的太慢,能夠經過增長該變量值以及內存緩衝區大小提升其性能,read_buffer_size
變量控制這一提升表的順序掃描的效率 數據文件順序。
這個參數是MySQL的隨機讀緩衝區大小,當按任意順序讀取行時(列如按照排序順序)將分配一個隨機讀取緩衝區,進行排序查詢時,MySQL會首先掃描一遍該緩衝,以免磁盤搜索,提升查詢速度,若是須要大量數據可適當的調整該值,但MySQL會爲每一個客戶鏈接分配該緩衝區因此儘可能適當設置該值,以避免內存開銷過大。表的隨機的順序緩衝 提升讀取的效率。從排序好的數據中讀取行時,行數據從緩衝區讀取的大小,會提高order by性能 注意:MySQL會爲每一個客戶端申請這個緩衝區,併發過大時,設置過大影響內存開銷。
MyISAM表發生變化時,從新排序所需的緩存。
InnoDB 使用緩存保存索引,保存原始數據的緩存大小,能夠有效減小讀取數據所需的磁盤IO。
數據日誌文件大小,大的值能夠提升性能,但增長了恢復故障數據庫的時間(恢復故障數據庫時須要讀取數據日誌文件,當日志過大會致使時間過長)。
日誌文件緩存,增大該文件能夠提升性能,但增大了突然宕機後損失數據的風險(日誌文件在緩存中,還沒來得及存進硬盤就斷電了)。
執行事務的時候,會往InnoDB存儲引擎的日誌緩存插入事務日誌,寫數據前先寫日誌(預寫日誌方式)設置爲0,實時寫入;當設置爲1時,緩存實時寫入磁盤;2時,緩存實時寫入文件,每秒文件實時寫入磁盤。
回滾前(當一個事務被撤銷時),一個InnoDB事務,應該等待一個鎖被批准多久,當InnoDB沒法檢測死鎖時,這個值就有用了。
MyISAM 索引順序訪問方法,支持全文索引,非事務安全,不支持外鍵,會加表級鎖存在三個文件:
InnoDB 事務型存儲引擎,加行鎖,支持回滾,崩潰恢復,ACID事務控制,表和索引放在一個表空間裏頭,表空間多個文件。
例:
update tableset age=3 where name like "%jeff%"; //會鎖表
給合適的列表創建索引,給where子句,鏈接子句創建索引,而不是select選擇列表索引值應該不相同,惟一值時效果最好,大量重複效果不好使用短索引,指定前綴長度char(50)的前20,30值惟一例。文件名索引緩存必定(小)時,存的索引多,消耗IO更小,能提升查找速度最左前綴n列索引,最左列的值匹配,更快。
like查詢,索引會失效,儘可能少用like。百萬、千萬數據時,用like Sphinx開源方案結合MySQL不能濫用索引。
「」 和 NULL問題
{「name」:」myf」} {「name」:」」} {「hobby」:空array}
NULL佔空間
例:安卓須要判斷」」仍是NULL
Java和OC都是強類型,會形成APP閃退
寫文件:文件延遲寫入機制,先把文件存放到緩存,達到必定程度寫進硬盤。
讀文件:同時讀文件到緩存,下次須要相同文件直接從緩存中取,而不是從硬盤取。
本地緩存:數據防盜服務器內存的文件中。
分佈式緩存:Redis, Mencache 讀寫性能很是高,QPS(每秒查詢請求數)每秒達到1W以上;數據持久化用Redis,不持久化二者均可以。
日誌和數據分開存儲,日誌順序讀寫 – 機械硬盤,數據隨機讀寫 – SSD
能夠調參數
#操做系統禁用緩存,直接經過fsync方式將數據刷入機械硬盤 innodb_flush_method = O_DIRECT # 控制MySQL中一次刷新髒頁的數量,SSD io 加強,增大一次輸入髒頁的數量 innodb_in_capacity = 1000
水平拆分:數據分紅多個表拆分後的每張表的表頭相同。
垂直拆分:字段分紅多個表。
插入數據、更新數據、刪除數據、查詢數據時:MyISAM MERGE存儲引擎,多個表合成一個表,InnoDB用alter table,變成MyISAM存儲引擎,而後MEGRE。
面試題:MERGE存儲引擎將N個表合併,數據庫中如何存儲?答: 真實存儲爲N個表,表更大的話就須要分庫了。
讀是一些機器,寫是一些機器,二進制文件的主從複製,延遲解決方案。數據庫壓力大了,能夠把讀和寫拆開,對應主從服務器,主服務器寫操做、從服務器是讀操做。大多數業務是讀業務。京東、淘寶大量瀏覽商品、挑選商品是讀操做(多),購買是寫操做(少)。主服務器寫操做的同時,同步到從服務器,保持數據完整性——主從複製。
主從複製原理:基於主服務器的二進制日誌(binlog)跟蹤全部的對數據庫的完整更改實現要實現主從複製,必須在主服務器上啓動二進制日誌主從複製是異步複製。
三個線程參與:主服務器一個線程(IO線程)、從服務器兩個(IO線程和SQL線程)
主從複製過程:
弊端:延遲
主從複製延遲解決方案:
Cobar方案:阿里開源(後續無更新)
MyCat基於Cobar,MySQL通信協議,代理服務器,無狀態,容易部署,負載均衡。
原理:應用服務器傳SQL語句,路由解析,轉發到不一樣的後臺數據庫,結果彙總,返回MyCat把邏輯數據庫和數據表對應到物理真實的數據庫、數據表,遮蔽了物理差別性。
MyCat工做流程:
慢查詢:指執行超過必定時間的SQL查詢語句記錄到慢查詢日誌,方便開發人員查看日誌
找問題:
long_qeury_time定義慢查詢時間 slow_query_log設置慢查詢開關 slow_query_log_file設置慢查詢日誌文件路徑
設置方法1:
set log_query_time = 1; set slow_query_log = on; set slow_query_log_file = '/data/slow.log'
設置方法2:
/etc/my.comf設置參數
分析:
explain命令進行分析,輸出結構含義,官方文檔。