程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> MySQLStudy之--MySQL體系結構深入解析

MySQLStudy之--MySQL體系結構深入解析

編輯:MySQL綜合教程

MySQLStudy之--MySQL體系結構深入解析


MySQL Study之--MySQL體系結構深入解析

MySQL體系架構

\

由連接池組件、管理服務和?工具組件、sql接口組件、查詢分析器組件、優化器組件、緩沖組件、插件式存儲引擎、物理?文件組成。mysql是獨有的插件式體系結構,各個存儲引擎有自己的特點。


MySQL內存結構: \

Mysql 進程結構

Mysql不像oracle那樣是通過多進程來完成其功能的。默認情況下,InnoDB存儲引擎的後台線程有7個:

4個IO thread,

1個master thread,

1個鎖(lock)監控線程,

1個錯誤監控線程;

在InnoDB Plugin版本開始增加了默認IO thread的數量,默認的read thread和write thread分別增大到了4個,並且不再使用innodb_file_ io_threads參數,而是分別使用innodb_read_io_threads和innodb_write_io_threads參數。

查看mysql thread:

 

mysql> show variables like 'innodb_%version%';
+----------------+-------+
| Variable_name  | Value |
+----------------+-------+
| innodb_version | 1.2.4 |
+----------------+-------+
1 row in set (0.00 sec)

 

mysql> show engine innodb status;
=====================================
150709 15:26:40 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from thelast 12 seconds
-----------------
BACKGROUND THREAD
-----------------
srv_master_thread loops: 0 srv_active, 0srv_shutdown, 804 srv_idle
srv_master_thread log flush and writes: 804
----------
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 2
OS WAIT ARRAY INFO: signal count 2
Mutex spin waits 0, rounds 0, OS waits 0
RW-shared spins 2, rounds 60, OS waits 2
RW-excl spins 0, rounds 0, OS waits 0
Spin rounds per wait: 0.00 mutex, 30.00RW-shared, 0.00 RW-excl
------------
TRANSACTIONS
------------
Trx id counter 5377
Purge done for trx's n:o < 4872 undo n:o< 0
History list length 1
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 0, not started
MySQL thread id 3, OS thread handle0x7f1656c75700, query id 5 localhost root init
show engine innodb status
--------
FILE I/O
--------
I/O thread 0 state: waiting for completedaio requests (insert buffer thread)
I/O thread 1 state: waiting for completedaio requests (log thread)
I/O thread 2 state: waiting for completedaio requests (read thread)
I/O thread 3 state: waiting for completedaio requests (read thread)
I/O thread 4 state: waiting for completedaio requests (read thread)
I/O thread 5 state: waiting for completedaio requests (read thread)
I/O thread 6 state: waiting for completedaio requests (write thread)
I/O thread 7 state: waiting for completedaio requests (write thread)
I/O thread 8 state: waiting for completedaio requests (write thread)
I/O thread 9 state: waiting for completedaio requests (write thread)
Pending normal aio reads: 0 [0, 0, 0, 0] ,aio writes: 0 [0, 0, 0, 0] ,
 ibufaio reads: 0, log i/o's: 0, sync i/o's: 0
Pending flushes (fsync) log: 0; bufferpool: 0
283 OS file reads, 5 OS file writes, 5 OSfsyncs
0.00 reads/s, 0 avg bytes/read, 0.00writes/s, 0.00 fsyncs/s
-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 1, free list len 0, seg size 2,0 merges
merged operations:
 insert 0, delete mark 0, delete 0
discarded operations:
 insert 0, delete mark 0, delete 0
Hash table size 276707, node heap has 0buffer(s)
0.00 hash searches/s, 0.00 non-hashsearches/s
---
LOG
---
Log sequence number 1611537
Log flushed up to   1611537
Pages flushed up to 1611537
Last checkpoint at  1611537
0 pending log writes, 0 pending chkp writes
8 log i/o's done, 0.00 log i/o's/second
----------------------
BUFFER POOL AND MEMORY
----------------------
Total memory allocated 137363456; inadditional pool allocated 0
Dictionary memory allocated 39010
Buffer pool size   8192
Free buffers       8040
Database pages     152
Old database pages 0
Modified db pages  0
Pending reads 0
Pending writes: LRU 0, flush list 0 singlepage 0
Pages made young 0, not young 0
0.00 youngs/s, 0.00 non-youngs/s
Pages read 152, created 0, written 1
0.00 reads/s, 0.00 creates/s, 0.00 writes/s
No buffer pool page gets since the lastprintout
Pages read ahead 0.00/s, evicted withoutaccess 0.00/s, Random read ahead 0.00/s
LRU len: 152, unzip_LRU len: 0
I/O sum[0]:cur[0], unzip sum[0]:cur[0]
--------------
ROW OPERATIONS
--------------
0 queries inside InnoDB, 0 queries in queue
0 read views open inside InnoDB
Main thread process no. 2461, id139733873489664, state: sleeping
Number of rows inserted 0, updated 0,deleted 0, read 0
0.00 inserts/s, 0.00 updates/s, 0.00deletes/s, 0.00 reads/s
----------------------------
END OF INNODB MONITOR OUTPUT

 

 

[root@mysrv ~]# mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.6.4-m7-log Sourcedistribution
 
Copyright (c) 2000, 2011, Oracle and/or itsaffiliates. All rights reserved.
 
Oracle is a registered trademark of OracleCorporation and/or its
affiliates. Other names may be trademarksof their respective
owners.
 
Type 'help;' or '\h' for help. Type '\c' toclear the current input statement.
 
mysql> show variables like'innodb_%io%';
+---------------------------------+---------+
| Variable_name                   | Value   |
+---------------------------------+---------+
| innodb_additional_mem_pool_size | 8388608|
| innodb_io_capacity              | 200     |
| innodb_read_io_threads          | 4       |
| innodb_replication_delay        | 0       |
| innodb_use_native_aio           | ON      |
| innodb_version                  | 1.2.4   |
| innodb_write_io_threads         | 4       |
+---------------------------------+---------+
7 rows in set (0.01 sec)

 

後台線程主要作用有三個:

1. 刷新內存池中的數據,保證緩沖池中的內存緩存的是最近的數據

2. 將修改的數據文件刷新到磁盤文件

3. 在數據庫發生異常情況下,保證InnoDB能恢復到正常運行狀態

master thread的線程優先級別最高。其內部由幾個循環(loop)組成:主循環(loop)、後台循環(backgroundloop)、刷新循環(flush loop)、暫停循環(suspend loop)。master thread會根據數據庫運行的狀態在loop、background loop、 flush loop和suspend loop中進行切換。loop稱為主循環,因為大多數的操作都在這個循環中,其中有兩大部分操作:每秒鐘的操作和每10秒的操作.

Loop為主循環,如果沒有用戶活動,就切換到backgroundloop中,然後跳轉會loop,如果還需要flush刷新,那就轉到flush loop,如果在flush loop中也空閒,那就切換到suspend loop中,將master thread掛起等待事件的發生。

 

Mysql 進程結構

\

\

 

Loop:

每秒一次的操作包括:

? 日志緩沖刷新到磁盤,即使這個事務還沒有提交(總是)。

? 合並插入緩沖(可能)。

? 至多刷新100個InnoDB的緩沖池中的髒頁到磁盤(可能)。

? 如果當前沒有用戶活動,切換到background loop(可能)。

接著來看每10秒的操作,包括如下內容

? 刷新100個髒頁到磁盤(可能)。

? 合並至多5個插入緩沖(總是)。

? 將日志緩沖刷新到磁盤(總是)。

? 刪除無用的Undo頁(總是)。

? 刷新100個或者10%髒頁到磁盤(總是)。

? 產生一個檢查點(總是)。

Background loop會執行以下操作

? 刪除無用的Undo頁(總是)。

? 合並20個插入緩沖(總是)。

? 跳回到主循環(總是)。

? 不斷刷新100個頁,直到符合條件(可能,跳轉到flush loop中完成)。

Mysql進程結構--控制磁盤io的參數

? innodb_io_capacity

? 用來表示磁盤IO的吞吐量,默認值為200。對於刷新到磁盤的數量(髒緩沖),會按照innodb_io_capacity的百分比來刷新相對數量的頁

? 在合並插入緩沖時,合並插入緩沖的數量為innodb_io_capacity數值的5%。

? 在從緩沖區刷新髒頁時,刷新髒頁的數量為innodb_io_capacity。

? innodb_max_dirty_pages_pct

? 默認值為75%。加快髒頁刷新頻率,減少恢復時間,也可保證磁盤IO負載。

? innodb_adaptive_flushing:

? 在innodbplugin中。該值影響每1秒刷新髒頁的數量。原來的刷新規則是:如果髒頁在緩沖池所占的比例小於innodb_max_dirty_pages_pct時,不刷新髒頁。大於innodb_max_dirty_pages_pct時,刷新100個髒頁,而innodb_adaptive_flushing參數的引入,InnoDB存儲引擎會通過一個名為buf_flush_get_desired_flush_rate的函數判斷產生重做日志的速度來判斷最合適的刷新髒頁的數量。因此,當髒頁的比例小於innodb_max_dirty_pages_pct時,也會刷新一定量的髒頁。

? 還有兩個和mysql啟動和關閉有關的參數

? innodb_fast_shutdown

? 這個參數影響著innodb表的行為,該參數可設置為0,1,2

? 0: 表示當MySQL關閉時,InnoDB需要完成所有的full purge和merge insert buffer操作。耗時

? 比較長。

? 1: 是默認值。表示不需要完成full purge和merge insert buffer操作,但是在緩沖池中的一

? 些數據髒頁會刷新到磁盤。

? 2: 表示不完成full purge和merge insert buffer操作,也不將緩沖池中的數據髒頁寫回到磁

? 盤,而是將日志寫入到日志文件。MySQL下次啟動時,會執行恢復操作。

? innodb_force_recovery

? 影響InnoDB的恢復狀況。默認為0,表示需恢復時執行所有的恢復操作。若不能有效恢復,則MySQL有可能宕機,錯誤信息會被寫入錯誤日志文件。還有 1~6等不同值,根據

? 需要可以設置。

? 0 :正常的關閉和啟動,不會做任何強迫恢復操作;

? 1 :跳過錯誤頁,讓mysqld服務繼續運行。跳過錯誤索引記錄和存儲頁,可以執行備份操作

? 2 :阻止InnoDB的主線程運行。清理操作時出現mysqld服務崩潰,則會阻止數據恢復操作;

? 3 :恢復的時候,不進行事務回滾;

? 4 :阻止INSERT緩沖區的合並操作。不做合並操作,為防止出現mysqld服務崩潰。不計算表的統計信息

? 5 :mysqld服務啟動的時候不檢查回滾日志:InnoDB引擎對待每個不確定的事務就像提交的事務一樣;

? 6 :不做事務日志前滾恢復操作;

 

Mysql內存結構—buffer pool

InnoDB存儲引擎內存主要由幾個部分組成:緩沖池(bufferpool)、重做日志緩沖池(redo log buffer)以及額外的內存池(additional memory pool)

緩沖池是占內存最大的部分,用來存放各種數據的緩存。因為InnoDB的存儲引擎的工作方式總是將數據庫文件按頁(每頁16K)讀取到緩沖池,然後按最近最少使用(LRU)的算法來保留在緩沖池中的緩存數據。如果數據庫文件需要修改,總是首先修改在緩存池中的頁(發生修改後,該頁即為髒頁),然後再按照一定的頻率將緩沖池的髒頁刷新(flush)到文件。

buffer pool是通過三種list來管理的:

1) free list

2) lru list

3) flush list

buffer pool中的最小單位是page,在innodb中定義三種page

1) free page :此page未被使用,此種類型page位於free鏈表中

2) clean page:此page被使用,對應數據文件中的一個頁面,但是頁面沒有被修改,此種類型

page位於lru鏈表中

3) dirty page:此page被使用,對應數據文件中的一個頁面,但是頁面被修改過,此種類型page

位於lru鏈表和flush鏈表中

 

插入緩沖:

不是緩沖池的一部分,InsertBuffer是物理頁的一個組成部分,它帶來InnoDB性能的提高。根據B+算法(下文會提到)的特點,插入數據的時候會主鍵索引是順序的,不會造成數據庫的隨機讀取,而對於非聚集索引(即輔助索引),葉子節點的插入不再是順序的了,這時需要離散地訪問非聚集索引,插入性能在這裡變低了。InnoDB引入插入緩沖,判斷非聚集索引頁是否在緩沖池中,如果在則直接插入;不在,則先放在插入緩沖區中。然後根據上述master thread中介紹的,會有一定的頻率將插入緩沖合並。此外,輔助索引不能是唯一的,因為插入到插入緩沖時,並不去查找索引頁的情況,否則仍然會造成隨機讀,失去插入緩沖的意義了。插入緩沖可能會占緩沖池中內存,默認也能會占到1/2,所以可以將這個值調小點,到1/3。通過IBUF_POOL_SIZE_PER_MAX_SIZE來設置,2表示1/2,3表示1/3。

兩次寫:

它帶來InnoDB數據的可靠性。如果寫失效,可以通過重做日志進行恢復,但是重做日志中記錄的是對頁的物理操作,如果頁本身損壞,再對其進行重做是沒有意義的。所以,在應用重做日志前,需要一個頁的副本,當寫入失效發生時,先通過頁的副本來還原該頁,再進行重做,這就是doublewire。
恢復數據=頁副本+重做日志

\

Mysql內存結構—log buffer與管理池

日志緩沖:

日志緩沖將重做日志信息先放入這個緩沖區,然後按一定頻率將其刷新到重做日志文件。該值一般不需要設置為很大,因為一般情況下每一秒鐘就會將重做日志緩沖刷新到日志文件,因此我們只需要保證每秒產生的事務量在這個緩沖大小之內即可。

額外的內存池:

額外的內存池同樣十分重要。在InnoDB存儲引擎中,對內存的管理是通過一種稱為內存堆(heap)的方式進行的,他是用於緩存InnoDB引擎的數據字典信息和內部數據結構,在對一些數據結構本身分配內存時,需要從額外的內存池中申請,當該區域的內存不夠時,會從緩沖池中申請,若是mysqld服務上的表對象數量較多,InnoDB引擎數據量很大,且innodb_buffer_pool_size的值設置較大,則應該適當地調整innodb_additional_mem_pool_size的值。若是出現緩存區的內存不足,則會直接向操作系統申請內存分配,並且會向MySQL的error log文件寫入警告信息。

binlog和redolog區別:

1) binary log,會記錄所有與MySQL有關的日志記錄,包括 Innodb、MyISAM、Heap等其他存儲引

擎的日志而 innodb存儲引擎的重做日志(redolog),只記錄有關其本身的事務日志


2) 記錄內容不同:
binary log:不管你將二進制日志文件的記錄格式設置為STATEMENT,還是ROW,又或是

MIXED, 其記錄的都是關於一個事務的具體操作內容.
redo log: 記錄innodb 每個頁的更改的物理情況

3)寫入時間不同:
binary log:事務提交前進行記錄
redo log :事物進行過程中,不斷寫入。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved