1. 程式人生 > >Innodb Read IO 相關引數原始碼解析

Innodb Read IO 相關引數原始碼解析

前言:最近在閱讀Innodb IO相關部分的原始碼。在閱讀之前一直有個疑問,show global status 中有兩個指標innodb_data_reads 和 innodb_data_read。兩個計數器僅差一個字母,他們之間的含義到底有何差別呢?本文將通過解析這兩個引數的含義,分析Innodb對於磁碟IO相關的一些知識

 首先我們來看下MySQL官方文件裡對於這兩個引數的解釋:

    • The amount of data read since the server was started.

    • The total number of data reads.

 文件對於這兩個引數的解釋非常曖昧。這裡的讀是指什麼?是從哪裡讀?磁碟還是記憶體?甚至連計數器的單位也不知道。

詳細解析:

接下來我們從原始碼來解析這兩個引數。在src/Srv0srv.c中存在對這兩個引數和程式碼變數的對映關係的定義程式碼,如下:

     export_vars.innodb_data_read = srv_data_read;
     export_vars.innodb_data_reads = os_n_file_reads; 

接著讓我們來看下這兩個程式碼變數在哪裡進行了累加操作。

srv_data_read 盡有一處程式碼進行累加操作,buf0file.c 的 _fil_io 函式中,操作如下:

  srv_data_read+= len;

從這行可以看出,innodb_data_read中實際存的是從磁碟上進行物理IO的位元組數。

os_n_file_reads 也幾乎只有一處程式碼進行累加(其他是windows的sync讀這裡忽略),在buf0file.c 的 中,操作如下:os_file_pread

  os_n_file_reads++;

隨後,程式碼即呼叫os_aio_array_reserve_slot將IO請求推入 simulated array,再根據wake_later標誌位決定是否呼叫

os_aio_simulated_wake_handler_thread來立即喚醒IO工作佇列。從這裡也可以看到,innodb_data_reads記錄的是innodb對於磁碟發起的讀IO請求次數。

看到這裡我們就很容易產生一個疑問:既然兩個變數都是對磁碟發起的IO的計數器,為什麼不直接放在一個函式的相鄰行裡呢?

回答這個問題,我們就需要對於innodb的simulated-aio和read-ahead演算法有一定理解了。

進入到simulated的aio slot array的請求會有兩種,一種是通過buf_read_page 過來的普通頁的讀請求,一種是通過buf_read_ahead_random/linear 過來的預讀請求。從innodb的實現來說普通資料頁的請求是需要立即返回響應的,所以是同步(sync)IO。而對於預讀這樣資料並非SQL所需要,僅是用於提升效能的頁讀取,這樣的IO完全是可以非同步的。這兩個差異也是導致simulated aio出現的原因。把IO請求推入slot array後,資料頁同步請求立即通知worker thread去os做同步IO。而預讀IO請求會不斷的推入slot array直到一次預讀所需要的page全部推入slot中,然後再會通知worker thread。此外在worker thread中,也會判斷一個segment的io請求是否相鄰連續,如果連續則把這些請求合併後,作為一次OS IO發到下層儲存中。

明白了這些也就不難理解為什麼計數器要分開在不同的函式中計數了。如果累加都放在 _fil_io中進行,那麼 innodb_data_read = 16K * innodb_data_reads (這裡假設page沒有做壓縮)。然而在有了非同步IO合併這個操作後,實際的innodb_data_reads會少於_fil_io中獲得的計數次數。所以,通過 innodb_data_read / innodb_data_reads得到的比值也可以推斷出一個MySQL例項中順序IO或者可順序預讀的IO比例。

我們在production環境的伺服器上做一個驗證:

伺服器A:線上使用者訪問的資料庫,猜測隨機IO較多

SHOW GLOBAL STATUS LIKE '%innodb_data_read%';

Innodb_data_read 46384854470656
Innodb_data_reads 2812101578

每次IO平均讀取位元組數=16494

伺服器B:歷史資料統計的資料庫,資料內容和伺服器A完全一樣,猜測順序IO較多

SHOW GLOBAL STATUS LIKE '%innodb_data_read%';

Innodb_data_read 54835669766144
Innodb_data_reads 2604758776

每次IO平均讀取位元組數=21052

可見順序IO較多的MySQL的單次IO讀取位元組數確實要多於一個page的大小,說明IO合併效果明顯。

而隨機IO較多的MySQL的單詞IO讀取位元組數幾乎和一個page大小一致,即16K

相關推薦

Innodb Read IO 相關引數原始碼解析

前言:最近在閱讀Innodb IO相關部分的原始碼。在閱讀之前一直有個疑問,show global status 中有兩個指標innodb_data_reads 和 innodb_data_read。兩個計數器僅差一個字母,他們之間的含義到底有何差別呢?本文將通過解析這

innodb之執行緒及IO相關引數介紹

引用連結:http://www.cnblogs.com/henglxm/p/4284504.html   1.IO THREAD: 負責IO的相關執行緒IO THREAD 1. 引數innodb_write_io_threads  

Java中IO框架——FileInputStream原始碼解析

屬性 // 檔案描述類,處理開啟的檔案 private final FileDescriptor fd; // 檔案的路徑,如果該流是通過檔案描述類建立的,該屬性則

4. read()、write() 相關函數解析

也有 工作 不為 作用 自己 這也 struct ioc 應用 我們在前面講到了file_operations,其是一個函數指針的集合,用於存放我們定義的用於操作設備的函數的指針,如果我們不定義,它默認保留為NULL。其中有最重要的幾個函數,分別是open()、read()

Activiti5.22引數配置原始碼解析

package org.activiti.spring.boot; import org.activiti.spring.SpringProcessEngineConfiguration; /** * Interface to be implemented by a b

spring core io原始碼解析

一、 一、Resource介面和WritableResource介面   InputStreamSource介面是Resource介面的父介面,Resource介面表示一個可讀的資源物件的公共方法,包含的方法如下圖所示。其中readableChannel方法返回

Spring Security Web 5.1.2 原始碼解析 -- 安全相關Filter清單

名稱 簡介 WebAsyncManagerIntegrationFilter TODO SecurityContextPersistenceFilter

MySQL timeout相關引數解析和測試 • cenalulu's Tech Blog

MySQL中有兩個關於連線超時的配置項: wait_timeout和interactive_timeout。他們之間在某些條件下會互相繼承,那究竟這兩個引數會在什麼情況下起作用呢? 本文將會通過一些測試例項來證明總結兩者的相互關係。 引數介紹 interactive_timeout

MySQL IO執行緒及相關引數調優

一、關於一個SQL的簡單的工作過程 1、工作前提描述   1、啟動MySQL,在記憶體中分配一個大空間innodb_buffer_pool(還有log_buffer)   2、多使用者執行緒連線MySQL,從記憶體分配使用者工作空間(其中排序空間)   3、磁碟上有資料庫檔

2017資料庫大會實錄-MySQL核心引數含義的原始碼解析

5月11-13日在北京國際會議中心舉行資料庫大會,有幸得友人推薦在大會上講了一場。源於自己曾經參加一些技術大會的感受——抱著學習的目的,非常興奮非常飢渴的過去了,但往往也是相當飢渴的回來了,並不是老師分享的內容沒有營養跟價值,而往往是老師講得內容太高大上,太豐富,營養價值過高,難以在短短的一個小時內

netty5.0原始碼解析 ByteBuf和相關輔助類

static final class Stack<T> implements Handle<T> { private static final int INITIAL_CAPACITY = 256; final Recycler<T> p

【Hibernate實戰】原始碼解析Hibernate引數繫結及PreparedStatement防SQL注入原理

    本文采用mysql驅動是5.1.38版本。    本篇文章涉及內容比較多,單就Hibernate來講就很大,再加上資料庫驅動和資料庫相關,非一篇文章或一篇專題就能說得完。本文從使用入手在【Spring實戰】----Spring4.3.2整合Hibernate5.2

PyCrypto密碼學庫原始碼解析(二)RSA引數生成

Python Crypto庫原始碼解析(二) RSA引數生成 引用請註明出處,轉載請聯絡: [email protected] 本文主要講解pycrypto庫中RSA引數生成的實現方法。主要涉及的模組是PublicKey.RSA 和其繼承模

List相關原始碼解析--這一篇全瞭解

ArrayList原始碼解析(基於JDK1.7,JDK1.8比較) ArrayList屬性 //JDK1.7 public class ArrayList<E> extends AbstractList<E> implements

mysql之 binlog維護詳細解析(開啟、binlog相關引數作用、mysqlbinlog解讀、binlog刪除)

binary log 作用:主要實現三個重要的功能:用於複製,用於恢復,用於審計。 binary log 相關引數: log_bin 設定此引數表示啟用binlog功能,並指定路徑名稱 log_bin_index 設定此引數是指定二進位制索引檔案的路徑與名稱 binlog_

Spring中AOP相關原始碼解析

前言 在Spring中AOP是我們使用的非常頻繁的一個特性。通過AOP我們可以補足一些面向物件程式設計中不足或難以實現的部分。 AOP 前置理論 首先在學習原始碼之前我們需要了解關於AOP的相關概念如切點切面等,以及如何使用AOP,這裡可以看我之前的文章:Spring系列之AOP的原理及手動實現 建立AOP相

dubbo原始碼解析spring整合DubboNamespaceHandler配置引數

說在前面 從今天開始系統的進行dubbo原始碼解析,本次先介紹下dubbo與spring進行整合相關的內容,更多原始碼解析請關注

HashMap原始碼解析、jdk7和8之後的區別、相關問題分析(多執行緒擴容帶來的死迴圈)

# 一、概覽 ```java HashMap map = new HashMap(); ``` 這個語句執行起來,在 jdk1.8 之前,會建立一個長度是 16 的 `Entry[]` 陣列,叫 `table`,用來儲存鍵值對。 在 jdk 1.8 後,不在這裡建立陣列了,而是在第一次 `pu

原始碼解析之 Mybatis 對 Integer 引數做了什麼手腳?

--- title: 原始碼解析之 Mybatis 對 Integer 引數做了什麼手腳? date: 2021-03-11 updated: 2021-03-11 categories: - Mybatis - 原始碼解析 tags: - Mybatis - 原始碼解析 --- 解決方案放在第二節,急需

java IO 包源碼解析

bytes lte 分配 target 來看 等等 ase 大小限制 updater 本文參考連接:http://blog.csdn.net/class281/article/details/24849275 http://z