mysql系統結構_3_Mysql_Learning_Notes
存儲層,內存結構
- 全局(buferpool)
- 鏈接/會話(session)
- 針對每一個會話/線程分配
- 按需動態分配,查詢結束後釋放
- 用於處理(緩衝,中轉)查詢結果
- 每一個會話的緩衝區大小都不同
mysql 內存佔用主要分層狀況
引擎層(內存):
- innodb buffer
- innodb log buffer
key buffer(是myisam使用,具體參數爲myisam_sort_buffer_size)mysql
mysql server 層(內存):
- query cache(默認禁用)
- table(def)cache(全局表的緩存)
- 首先嚐試從table cache中取table
- 當找到的TABLE實例是nam-locked的,或者一些線程正在flush tables,咱們須要等待,直到鎖釋放
- 若是不存在這樣的TABLE,咱們須要建立TABLE,並將其加入到cache中這些操做都須要全局鎖:LOCK_open,來保護table cache和磁盤上的表定義
- thread cache
mdl cache (metadata_locks_cache_size)sql
鏈接/會話層(內存):
- net/read/join/sort/bulk insert buffer
- tmp/heap table (系統產生的臨時表和用戶建立的)
binlog cache
緩存
mysqld 進行消耗內存估算因素(大多數不會把全部算滿,只是作最極端狀況):
- global buffers(相似於SGA):
- innodb buffer pool
- innodb log buffer
- key buffer
- query cache
- table cache
- thread cache
- 會話/線程級分配的all thread buffers(相似於PGA)
- max_threads * (read buffer+
- read rnd buffer+
- sort buffer+
- join buffer+
- tmp table+
- binlog cache)
- 有時系統提示:buffer pool設置太大不能啓動,這是一個通用報錯,好多時候多是由於版本問題等.
- 如何查看buffer pool 是否夠用?
- show engine innnodb status,結果中專門有一段是:"BUFFER POOL AND MEMORY",能夠從free buffers.
- show global status like 'innodb%buffer%';中能夠innodb_buffer_pool_pages_free<10或innodb_buffer_pool_wait_free>0就表明嚴重不足.
- show global status like '%table%';中opened_tables和open_tables的數是不差距很大,若是大就表明table cache不夠用,監控時,主要觀測固定週期的opened_tables數量的增長狀況.
- show global status like '%thread%';中thread_created、thread_connected的數是不差距很大,若是大就表明thread cache不夠用.能夠觀測固定週期的thread_created數量的增長狀況.
- show global status like '%sort%merg%';中sort_merge_passes的數量.
- show global status like '%tmp%table%';中created_tmp_tables的數量.更嚴重的是created_tmp_disk_tables
- 兩個容易被設置很大的內存選項:
- 都是session級
- max_heap_table_size限制MEMORY表的最大容量,無論其餘執行SQL產生的臨時表,若內存不夠用,則不容許寫入新的數據,MEMORY表也不會轉成磁盤表,只會告警超限後拒絕寫入.
- tmp_table_size 不限制MEMORY表最大容量,若是執行SQL產生臨時表超過tmp_table_size或max_heap_table_size,則會產生基於磁盤的臨時表.
- 這2個選項特別容易分配較大,如有須要,可臨時調大,不要修改全局值.
觀察SQL執行過程(有沒有建立臨時等):
1.設置set profiling=1&set profiling_history_size=2
2.執行SQL(select benchmark(100000,pow(2,10));)
3.use information_schema;
3.select Query_ID,state,DURATION from PROFILING order by query_id desc limit 1;(8.0之前能夠直接用show profiles;查詢)session
root@localhost [information_schema]>select benchmark(100000,pow(2,10));
+-----------------------------+
| benchmark(100000,pow(2,10)) |
+-----------------------------+
| 0 |
+-----------------------------+
1 row in set (0.02 sec)
root@localhost [information_schema]>select Query_ID,state,DURATION from PROFILING order by query_id desc limit 1;
+----------+-------+----------+
| Query_ID | state | DURATION |
+----------+-------+----------+
| 3 | init | 0.000024 |
+----------+-------+----------+
1 row in set, 1 warning (0.00 sec)
root@localhost [information_schema]>show profiles;
+----------+------------+------------------------------------------------------------------------------+
| Query_ID | Duration | Query |
+----------+------------+------------------------------------------------------------------------------+
| 3 | 0.01043275 | select benchmark(100000,pow(2,10)) |
| 4 | 0.00082200 | select Query_ID,state,DURATION from PROFILING order by query_id desc limit 1 |
+----------+------------+------------------------------------------------------------------------------+
2 rows in set, 1 warning (0.00 sec)