InnoDB引擎之-異步IO(Async IO)

InnoDB引擎有幾個重點特性,為其帶來了更好的性能和可靠性:

  • 插入緩沖(Insert Buffer)
  • 兩次寫(Double Write)
  • 自適應哈希索引(Adaptive Hash Index)
  • 異步IO(Async IO)
  • 刷新鄰接頁(Flush Neighbor Page)

關于AIO與SIO

為了提高磁盤操作性能,當前的數(shù)據(jù)庫系統(tǒng)都采用異步IO的方式來處理磁盤操作。

  1. 同步IO:我們常用的read/write函數(shù)(Linux上)就是這類IO,特點是,在函數(shù)執(zhí)行的時候,調(diào)用者會等待函數(shù)執(zhí)行完成,而且沒有消息通知機制,因為函數(shù)返回了,就表示操作完成了,后續(xù)直接檢查返回值就可知道操作是否成功。這類IO操作,編程比較簡單,在同一個線程中就能完成所有操作,但是需要調(diào)用者等待,在數(shù)據(jù)庫系統(tǒng)中,比較適合急需某些數(shù)據(jù)的時候調(diào)用,例如WAL中日志必須在返回客戶端前落盤,則進行一次同步IO操作。
  2. 異步IO:在數(shù)據(jù)庫中,后臺刷數(shù)據(jù)塊的IO線程,基本都使用了異步IO。數(shù)據(jù)庫前臺線程只需要把刷塊請求提交到異步IO的隊列中即可返回做其他事情,而后臺線程IO線程,則定期檢查這些提交的請求是否已經(jīng)完成,如果完成再做一些后續(xù)處理工作。同時異步IO由于常常是一批一批的請求提交,如果不同請求訪問同一個文件且偏移量連續(xù),則可以合并成一個IO請求。例如,第一個請求讀取文件1,偏移量100開始的200字節(jié)數(shù)據(jù),第二個請求讀取文件1,偏移量300開始的100字節(jié)數(shù)據(jù),則這兩個請求可以合并為讀取文件1,偏移量100開始的300字節(jié)數(shù)據(jù)。數(shù)據(jù)預讀中的邏輯預讀也常常使用異步IO技術。

Innodb 使用異步IO的場景

總的來說innodb 只會對數(shù)據(jù)文件采用異步IO,為了保存日志是真正被寫入到磁盤,innodb不會對日志文件啟用異步IO;innodb只會對數(shù)據(jù)文件的read-ahead ,write 這兩個操作啟用異步IO

異步IO在mysql中解決了什么問題

在沒有IO這個功能之前,innodb對數(shù)據(jù)的讀寫請求先放入任務隊列,后臺read-thread ,write-thread從任務隊列中拿出任務并執(zhí)行讀寫操作;后臺讀寫線程的個數(shù)可以通過show engine innodb status 語句來查看

show engine innodb status;

--------
FILE I/O
--------
I/O thread 0 state: waiting for i/o request (insert buffer thread)
I/O thread 1 state: waiting for i/o request (log thread)
I/O thread 2 state: waiting for i/o request (read thread)
I/O thread 3 state: waiting for i/o request (read thread)
I/O thread 4 state: waiting for i/o request (read thread)
I/O thread 5 state: waiting for i/o request (read thread)
I/O thread 6 state: waiting for i/o request (write thread)
I/O thread 7 state: waiting for i/o request (write thread)
I/O thread 8 state: waiting for i/o request (write thread)
I/O thread 9 state: waiting for i/o request (write thread)
Pending normal aio reads: [0, 0, 0, 0] , aio writes: [0, 0, 0, 0] ,
 ibuf aio reads:, log i/o's:, sync i/o's:
Pending flushes (fsync) log: 0; buffer pool: 0
376 OS file reads, 54 OS file writes, 7 OS fsyncs
41.77 reads/s, 21886 avg bytes/read, 6.00 writes/s, 0.78 fsyncs/s

由上面的內(nèi)容可以看出默認情況下innodb會有4個read-thread 和4個write-thread ,問題就出現(xiàn)在這里,如果業(yè)務繁重,讀寫任務會非常的多,而innodb只有八個讀寫線程,這樣的話隊列中的其它讀寫請求就沒能得到及時的響應。

引入異步IO之后,讀寫請求不再像之前那樣先放入隊列,等著后臺的讀寫線程去執(zhí)行任務;而是查詢線程直接發(fā)起異步請求,這樣一來沖破了讀寫線程個數(shù)的硬性限制,二來由于異步IO是否阻塞的這也進一步提高了性能。

怎么啟用mysql異步IO

首先OS要有異步io,且開啟,然后mysqld要鏈接,要不然OS異步io沒有開啟,數(shù)據(jù)庫的異步io也起不來。(this variable applies to Linux systems only, and cannot be changed while the server is running.)

  1. 文件系統(tǒng)層面需要打開這個功能:
    一般都是默認開啟的。
ldconfig -v|grep libaio
libaio.so.1.0.0 -> libaio.so.1.0.0
libaio.so.1 -> libaio.so.1.0.1
  1. AIO是數(shù)據(jù)庫層面的一個特性需要打開:
    默認是開啟,但是阿里云默認是關閉的,開啟的native aio性能提升,可以提高到75%。
mysql>show variables like 'innodb_use_native_aio';
+-------------------------+-----------------+
| Variable_name           | Value           |
+-------------------------+-----------------+
| innodb_use_native_aio   | OFF             |
+-------------------------+-----------------+

異步IO的優(yōu)缺點

優(yōu)點

  1. 不用等待直接響應上一個用戶的請求;
  2. 多次的請求在一起排序,請求的數(shù)據(jù)頁是在一起的,一次讀出來,減少多次讀。(數(shù)據(jù)庫的讀寫請求隊列放在文件系統(tǒng)中單獨分配的一塊小內(nèi)存結構里,非文件系統(tǒng)的緩存)

缺點

異步IO對于我們來說是不可控的,所以說在啟用異步IO的情況下相當于是我們把IO的控制權交出去了。

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容