1. 程式人生 > >### mysql系統結構_3_Mysql_Learning_Notes

### mysql系統結構_3_Mysql_Learning_Notes

mysql系統結構_3_Mysql_Learning_Notes

儲存層,記憶體結構

  • 全域性(buferpool)
    • 只分配一次
    • 全域性共享
  • 連線/會話(session)
    • 針對每個會話/執行緒分配
    • 按需動態分配,查詢結束後釋放
    • 用於處理(緩衝,中轉)查詢結果
    • 每個會話的緩衝區大小都不一樣

Alt text

mysql 記憶體佔用主要分層情況

引擎層(記憶體部分):
  • innodb buffer
  • innodb log buffer
  • key buffer(是myisam使用,具體引數為myisam_sort_buffer_size)

    mysql server 層(記憶體,也叫SQL層):
  • 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)

    連線/會話層(記憶體):
  • 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;查詢)

[email protected] [information_schema]>select benchmark(100000,pow(2,10));
+-----------------------------+
| benchmark(100000,pow(2,10)) |
+-----------------------------+
|                           0 |
+-----------------------------+
1 row in set (0.02 sec)

[email protected] [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)
[email protected] [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)

關於huge page

  • 使用大頁是為了提高記憶體管理效率.RHEL6\SLES11\UEK2起預設是啟動的.
  • 透明大頁可以動態調整,無需重啟即可生效
  • 類似innodb data page 概念
  • 但啟用透明大頁可能反而導致MySQL(TokuDB)更容易發生記憶體洩漏\OOM等問題,所以建議關閉
  • 檢視是否關閉
    • cat /sys/kernel/mm/transparent_hugepage/enabled
    • cat /sys/kernel/mm/transparent_hugepage/defrag
    • grep AnonHugePages /proc/meminfo AnonHugePages > 0 同樣表示啟用了透明大頁
    • 如何禁用透明大頁:
      方法一:在 /etc/grub.conf 中新增一行記錄:transparent_hugepage=never
      方法二:配置/etc/rc.local 然後重啟伺服器:
      if test -f /sys/kernel/mm/redhat_transparent_hugepage/enabled; then
      echo never > /sys/kernel/mm/redhat_transparent_hugepage/enabled
      fi
      if test -f /sys/kernel/mm/redhat_transparent_hugepage/defrag; then
      echo never > /sys/kernel/mm/redhat_transparent_hugepage/defrag
      fi

不同引擎對比

主要可瞭解儲存引擎:Innodb\TokuDB\MyRocks
|引擎名|特點|使用建議|
|-|-|
|InnoDB|支援事務,基於MVCC設計,索引組織表,只能有一個聚焦索引|在絕大多數場景建議使用此引擎,尤其是OLTP|
|tokudb|支援事務,高壓縮,高速寫入|適用於基於時間有序資料的海量資料環境|
|MyIsam|早期版本引擎,堆表。在MariaDB用Aria替代,官方版本中也在減小對MyiSAM的使用|儘量少使用MyISQL,MyISQL對CPU,記憶體,記憶體利用率不高,併發支援不好|
|inforbright,infinidb|列式儲存引擎,高壓縮,快速載入資料.|適用於OLAP環境|
|Memory|以記憶體為儲存介質,請求速度高,但資料不安全|適用於資料安全要求不高的環境,如:臨時記數等|

plugin 管理

1.檢視plugin
檢視plugin-dir引數設定,查詢到plugin的存放位置(mysqladmin var|grep plugin_dir).
/usr/local/mysql/lib/plugin/
2.安裝plugin
mysql>install plugin rpl_semi_sync_master soname 'semisync_master.so'
3.刪除plugin
uninstall plugin rep_semi_sync_master;

其他plugin

  • rockdb

  • tokudb
    percona 公司收購,開源GPL協議,大資料儲存引擎,高速資料寫入\追加的業務場景,高效壓縮(10倍)\成本節省一半以上的備選方案.支援MVCC\Online DDL(大規模資料1T+,需要歸檔,頻繁增減欄位等場景適合)
    • 此外Xenon TokuDB是對Percona公司的TokuDB進行Patch優化。
    • 專案地址: https://github.com/XeLabs/tokudb
    • 引入的優化點:
    • 支援xtrabackup直接備份 https://github.com/XeLabs/tokudb-xtrabackup 針對TokuDB備份的Patch的分支。
    • 加入ZST壓縮演算法(From MyRocksDB)
    • 支援binlog group commit

引入效能計數器 show engine tokudb status ,更多選項。

  • spider
  • handlersocket

統計表DML情況

  • use sys

  • 統計根據索引的DML情況:
    select index_name,rows_selected,rows_inserted,rows_updated,rows_deleted from schema_index_statistics where table_schema='world' and table_name='city' and index_name='Conuntrycode';
    |index_name|rows_selected|rows_inserted|rows_updated|rows_deleted|
    |-|-|-|-|-|
    |ID|18131|0|0|0|
    |countrycode|2|0|0|0|

  • 檢視某個表的DML情況:

[email protected] [sys]>select table_name,rows_fetched,rows_inserted,rows_updated,rows_deleted,io_read,io_read_requests,io_write,io_write_requests from schema_table_statistics where table_schema='wenyz' and table_name='t2';
+------------+--------------+---------------+--------------+--------------+-----------+------------------+----------+-------------------+
| table_name | rows_fetched | rows_inserted | rows_updated | rows_deleted | io_read   | io_read_requests | io_write | io_write_requests |
+------------+--------------+---------------+--------------+--------------+-----------+------------------+----------+-------------------+
| t2         |        68282 |             0 |            0 |            0 | 48.85 KiB |               10 | 0 bytes  |                 0 |
+------------+--------------+---------------+--------------+--------------+-----------+------------------+----------+-------------------+
1 row in set (0.01 sec)
  • 檢視冗餘索引.
select * from schema_redundant_indexes\G
  • 檢視全表掃描的情況
[email protected] [sys]>select * from schema_tables_with_full_table_scans limit4;
+---------------+-------------+-------------------+---------+
| object_schema | object_name | rows_full_scanned | latency |
+---------------+-------------+-------------------+---------+
| wenyz         | t2          |             68650 | 1.20 s  |
+---------------+-------------+-------------------+---------+
1 row in set (0.00 sec)
  • 查指定表buffer
[email protected] [sys]>select * from schema_table_statistics_with_buffer  where table_schema='wenyz' and table_name='t2'\G;
*************************** 1. row ***************************
              table_schema: wenyz
                table_name: t2
              rows_fetched: 68866
             fetch_latency: 1.21 s
             rows_inserted: 0
            insert_latency: 0 ps
              rows_updated: 0
            update_latency: 0 ps
              rows_deleted: 0
            delete_latency: 0 ps
          io_read_requests: 10
                   io_read: 48.85 KiB
           io_read_latency: 2.10 ms
         io_write_requests: 0
                  io_write: 0 bytes
          io_write_latency: 0 ps
          io_misc_requests: 11
           io_misc_latency: 111.24 us
   innodb_buffer_allocated: 16.00 KiB
        innodb_buffer_data: 14.36 KiB
        innodb_buffer_free: 1.64 KiB
       innodb_buffer_pages: 1
innodb_buffer_pages_hashed: 0
   innodb_buffer_pages_old: 1
 innodb_buffer_rows_cached: 362
1 row in set (0.05 sec)

  • 檢視MDL鎖
select * from schema_table_lock_waits limit 4\G

percona toolkit(pt)

  • pt-summary、pt-mysql-summary 主機和mysql一般資訊採集
  • pt-mext show global status 結果輸出對比,發現差異
  • pt-variavle-advisor 配置引數建議
  • pt-ioprofile 類似ioprofile工具,檢查mysql中哪些檔案I/O壓力大.
  • pt-kill 殺掉符合某些特徵的查詢,如慢查詢或SQL注入等
  • pt-online-schema-change nline DDL為足的替代/補充工具
  • pt-query-digest 查詢分析日誌
  • pt-pmp 分析pstack的日誌資訊
#ps aux |grep mysql 
mysql     4279  9.4 80.9 23140516 19853348 ?   Sl   Sep12 7553:31 /usr/local/mysql/bin/mysqld --defaults-file=/data/mysql/mysql3306/my3306.cnf

#pstack 4279> /tmp/pstack.txt 

### pt-pmp /tmp/pstack.txt

pstack