MySQL 引擎特性:InnoDB IO 子系統

2021-03-02 數據分析與開發

(點擊上方公眾號,可快速關注)

來源:水中的淚

www.cnblogs.com/coderyuhui/p/6498382.html

前言

InnoDB做為一款成熟的跨平臺資料庫引擎,其實現了一套高效易用的IO接口,包括同步異步IO,IO合併等。本文簡單介紹一下其內部實現,主要的代碼集中在os0file.cc這個文件中。本文的分析默認基於MySQL 5.6,CentOS 6,gcc 4.8,其他版本的信息會另行指出。

基礎知識

WAL技術 : 日誌先行技術,基本所有的資料庫,都使用了這個技術。簡單的說,就是需要寫數據塊的時候,資料庫前臺線程把對應的日誌先寫(批量順序寫)到磁碟上,然後就告訴客戶端操作成功,至於真正寫數據塊的操作(離散隨機寫)則放到後臺IO線程中。使用了這個技術,雖然多了一個磁碟寫入操作,但是由於日誌是批量順序寫,效率很高,所以客戶端很快就能得到相應。此外,如果在真正的數據塊落盤之前,資料庫奔潰,重啟時候,資料庫可以使用日誌來做崩潰恢復,不會導致數據丟失。


數據預讀
: 與數據塊A「相鄰」的數據塊B和C在A被讀取的時候,B和C也會有很大的概率被讀取,所以可以在讀取B的時候,提前把他們讀到內存中,這就是數據預讀技術。這裡說的相鄰有兩種含義,一種是物理上的相鄰,一種是邏輯上的相鄰。底層數據文件中相鄰,叫做物理上相鄰。如果數據文件中不相鄰,但是邏輯上相鄰(id=1的數據和id=2的數據,邏輯上相鄰,但是物理上不一定相鄰,可能存在同一個文件中不同的位置),則叫邏輯相鄰。


文件打開模式
: Open系統調用常見的模式主要三種:O_DIRECT,O_SYNC以及default模式。O_DIRECT模式表示後續對文件的操作不使用文件系統的緩存,用戶態直接操作設備文件,繞過了內核的緩存和優化,從另外一個角度來說,使用O_DIRECT模式進行寫文件,如果返回成功,數據就真的落盤了(不考慮磁碟自帶的緩存),使用O_DIRECT模式進行讀文件,每次讀操作是真的從磁碟中讀取,不會從文件系統的緩存中讀取。O_SYNC表示使用作業系統緩存,對文件的讀寫都經過內核,但是這個模式還保證每次寫數據後,數據一定落盤。default模式與O_SYNC模式類似,只是寫數據後不保證數據一定落盤,數據有可能還在文件系統中,當主機宕機,數據有可能丟失。


此外,寫操作不僅需要修改或者增加的數據落盤,而且還需要文件元信息落盤,只有兩部分都落盤了,才能保證數據不丟。O_DIRECT模式不保證文件元信息落盤(但大部分文件系統都保證,Bug #45892),因此如果不做其他操作,用O_DIRECT寫文件後,也存在丟失的風險。O_SYNC則保證數據和元信息都落盤。default模式兩種數據都不保證。


調用函數fsync後,能保證數據和日誌都落盤,因此使用O_DIRECT和default模式打開的文件,寫完數據,需要調用fsync函數。


同步IO : 我們常用的read/write函數(Linux上)就是這類IO,特點是,在函數執行的時候,調用者會等待函數執行完成,而且沒有消息通知機制,因為函數返回了,就表示操作完成了,後續直接檢查返回值就可知道操作是否成功。這類IO操作,編程比較簡單,在同一個線程中就能完成所有操作,但是需要調用者等待,在資料庫系統中,比較適合急需某些數據的時候調用,例如WAL中日誌必須在返回客戶端前落盤,則進行一次同步IO操作。


異步IO : 在資料庫中,後臺刷數據塊的IO線程,基本都使用了異步IO。資料庫前臺線程只需要把刷塊請求提交到異步IO的隊列中即可返回做其他事情,而後臺線程IO線程,則定期檢查這些提交的請求是否已經完成,如果完成再做一些後續處理工作。同時異步IO由於常常是一批一批的請求提交,如果不同請求訪問同一個文件且偏移量連續,則可以合併成一個IO請求。例如,第一個請求讀取文件1,偏移量100開始的200位元組數據,第二個請求讀取文件1,偏移量300開始的100位元組數據,則這兩個請求可以合併為讀取文件1,偏移量100開始的300位元組數據。數據預讀中的邏輯預讀也常常使用異步IO技術。


目前Linux上的異步IO庫,需要文件使用O_DIRECT模式打開,且數據塊存放的內存地址、文件讀寫的偏移量和讀寫的數據量必須是文件系統邏輯塊大小的整數倍,文件系統邏輯塊大小可以使用類似sudo blockdev --getss /dev/sda5的語句查詢。如果上述三者不是文件系統邏輯塊大小的整數倍,則在調用讀寫函數時候會報錯EINVAL,但是如果文件不使用O_DIRECT打開,則程序依然可以運行,只是退化成同步IO,阻塞在io_submit函數調用上。

InnoDB常規IO操作以及同步IO

在InnoDB中,如果系統有pread/pwrite函數(os_file_read_func和os_file_write_func),則使用它們進行讀寫,否則使用lseek+read/write方案。這個就是InnoDB同步IO。查看pread/pwrite文檔可知,這兩個函數不會改變文件句柄的偏移量且線程安全,所以多線程環境下推薦使用,而lseek+read/write方案則需要自己使用互斥鎖保護,在高並發情況下,頻繁的陷入內核態,對性能有一定影響。

在InnoDB中,使用open系統調用打開文件(os_file_create_func),模式方面除了O_RDONLY(只讀),O_RDWR(讀寫),O_CREAT(創建文件)外,還使用了O_EXCL(保證是這個線程創建此文件)和O_TRUNC(清空文件)。默認情況下(資料庫不設置為只讀模式),所有文件都以O_RDWR模式打開。innodb_flush_method這個參數比較重要,重點介紹一下:

如果innodb_flush_method設置了O_DSYNC,日誌文件(ib_logfileXXX)使用O_SYNC打開,因此寫完數據不需要調用函數fsync刷盤,數據文件(ibd)使用default模式打開,因此寫完數據需要調用fsync刷盤。

如果innodb_flush_method設置了O_DIRECT,日誌文件(ib_logfileXXX)使用default模式打開,寫完數據需要調用fsync函數刷盤,數據文件(ibd)使用O_DIRECT模式打開,寫完數據需要調用fsync函數刷盤。

如果innodb_flush_method設置了fsync或者不設置,數據文件和日誌文件都使用default模式打開,寫完數據都需要使用fsync來刷盤。

如果innodb_flush_method設置為O_DIRECT_NO_FSYNC,文件打開方式與O_DIRECT模式類似,區別是,數據文件寫完後,不調用fsync函數來刷盤,主要針對O_DIRECT能保證文件的元數據也落盤的文件系統。
InnoDB目前還不支持使用O_DIRECT模式打開日誌文件,也不支持使用O_SYNC模式打開數據文件。
注意,如果使用linux native aio(詳見下一節),innodb_flush_method一定要配置成O_DIRECT,否則會退化成同步IO(錯誤日誌中不會有任務提示)。

InnoDB使用了文件系統的文件鎖來保證只有一個進程對某個文件進行讀寫操作(os_file_lock),使用了建議鎖(Advisory locking),而不是強制鎖(Mandatory locking),因為強制鎖在不少系統上有bug,包括linux。在非只讀模式下,所有文件打開後,都用文件鎖鎖住。

InnoDB中目錄的創建使用遞歸的方式(os_file_create_subdirs_if_needed和os_file_create_directory)。例如,需要創建/a/b/c/這個目錄,先創建c,然後b,然後a,創建目錄調用mkdir函數。此外,創建目錄上層需要調用os_file_create_simple_func函數,而不是os_file_create_func,需要注意一下。

InnoDB也需要臨時文件,臨時文件的創建邏輯比較簡單(os_file_create_tmpfile),就是在tmp目錄下成功創建一個文件後直接使用unlink函數釋放掉句柄,這樣當進程結束後(不管是正常結束還是異常結束),這個文件都會自動釋放。InnoDB創建臨時文件,首先復用了server層函數mysql_tmpfile的邏輯,後續由於需要調用server層的函數來釋放資源,其又調用dup函數拷貝了一份句柄。

如果需要獲取某個文件的大小,InnoDB並不是去查文件的元數據(stat函數),而是使用lseek(file, 0, SEEK_END)的方式獲取文件大小,這樣做的原因是防止元信息更新延遲導致獲取的文件大小有誤。

InnoDB會預分配一個大小給所有新建的文件(包括數據和日誌文件),預分配的文件內容全部置為零(os_file_set_size),當前文件被寫滿時,再進行擴展。此外,在日誌文件創建時,即install_db階段,會以100MB的間隔在錯誤日誌中輸出分配進度。

總體來說,常規IO操作和同步IO相對比較簡單,但是在InnoDB中,數據文件的寫入基本都用了異步IO。

InnoDB異步IO

由於MySQL誕生在Linux native aio之前,所以在MySQL異步IO的代碼中,有兩種實現異步IO的方案。


第一種是原始的Simulated aio,InnoDB在Linux native air被import進來之前以及某些不支持air的系統上,自己模擬了一條aio的機制。異步讀寫請求提交時,僅僅把它放入一個隊列中,然後就返回,程序可以去做其他事情。後臺有若干異步io處理線程(innobase_read_io_threads和innobase_write_io_threads這兩個參數控制)不斷從這個隊列中取出請求,然後使用同步IO的方式完成讀寫請求以及讀寫完成後的工作。
另外一種就是Native aio。目前在linux上使用io_submit,io_getevents等函數完成(不使用glibc aio,這個也是模擬的)。提交請求使用io_submit, 等待請求使用io_getevents。另外,window平臺上也有自己對應的aio,這裡就不介紹了,如果使用了window的技術棧,資料庫應該會選用sqlserver。目前,其他平臺(Linux和window之外)都只能使用Simulate aio。

首先介紹一下一些通用的函數和結構,接下來分別詳細介紹一下Simulate alo和Linux上的Native aio。


在os0file.cc中定義了全局數組,類型為os_aio_array_t,這些數組就是Simulate aio用來緩存讀寫請求的隊列,數組的每一個元素是os_aio_slot_t類型,裡面記錄了每個IO請求的類型,文件的fd,偏移量,需要讀取的數據量,IO請求發起的時間,IO請求是否已經完成等。另外,Linux native io中的struct iocb也在os_aio_slot_t中。數組結構os_aio_slot_t中,記錄了一些統計信息,例如有多少數據元素(os_aio_slot_t)已經被使用了,是否為空,是否為滿等。這樣的全局數組一共有5個,分別用來保存數據文件讀異步請求(os_aio_read_array),數據文件寫異步請求(os_aio_write_array),日誌文件寫異步請求(os_aio_log_array),insert buffer寫異步請求(os_aio_ibuf_array),數據文件同步讀寫請求(os_aio_sync_array)。日誌文件的數據塊寫入是同步IO,但是這裡為什麼還要給日誌寫分配一個異步請求隊列(os_aio_log_array)呢?原因是,InnoDB日誌文件的日誌頭中,需要記錄checkpoint的信息,目前checkpoint信息的讀寫還是用異步IO來實現的,因為不是很緊急。在window平臺中,如果對特定文件使用了異步IO,就這個文件就不能使用同步IO了,所以引入了數據文件同步讀寫請求隊列(os_aio_sync_array)。日誌文件不需要讀異步請求隊列,因為只有在做奔潰恢復的時候日誌才需要被讀取,而做崩潰恢復的時候,資料庫還不可用,因此完全沒必要搞成異步讀取模式。這裡有一點需要注意,不管變量innobase_read_io_threads和innobase_write_io_threads兩個參數是多少,os_aio_read_array和os_aio_write_array都只有一個,只不過數據中的os_aio_slot_t元素會相應增加,在linux中,變量加1,元素數量增加256。例如,innobase_read_io_threads=4,則os_aio_read_array數組被分成了四部分,每一個部分256個元素,每個部分都有自己獨立的鎖、信號量以及統計變量,用來模擬4個線程,innobase_write_io_threads類似。從這裡我們也可以看出,每個異步read/write線程能緩存的讀寫請求是有上限的,即為256,如果超過這個數,後續的異步請求需要等待。256可以理解為InnoDB層對異步IO並發數的控制,而在文件系統層和磁碟層面也有長度限制,分別使用cat /sys/block/sda/queue/nr_requests和cat /sys/block/sdb/queue/nr_requests查詢。


os_aio_init在InnoDB啟動的時候調用,用來初始化各種結構,包括上述的全局數組,還有Simulate aio中用的鎖和互斥量。os_aio_free則釋放相應的結構。os_aio_print_XXX系列的函數用來輸出aio子系統的狀態,主要用在show engine innodb status語句中。

Simulate aio

Simulate aio相對Native aio來說,由於InnoDB自己實現了一套模擬機制,相對比較複雜。

入口函數為os_aio_func,在debug模式下,會校驗一下參數,例如數據塊存放的內存地址、文件讀寫的偏移量和讀寫的數據量是否是OS_FILE_LOG_BLOCK_SIZE的整數倍,但是沒有檢驗文件打開模式是否用了O_DIRECT,因為Simulate aio最終都是使用同步IO,沒有必要一定要用O_DIRECT打開文件。

校驗通過後,就調用os_aio_array_reserve_slot,作用是把這個IO請求分配到某一個後臺io處理線程(innobase_xxxx_io_threads分配的,但其實是在同一個全局數組中)中,並把io請求的相關信息記錄下來,方便後臺io線程處理。如果IO請求類型相同,請求同一個文件且偏移量比較接近(默認情況下,偏移量差別在1M內),則InnoDB會把這兩個請求分配到同一個io線程中,方便在後續步驟中IO合併。

提交IO請求後,需要喚醒後臺io處理線程,因為如果後臺線程檢測到沒有IO請求,會進入等待狀態(os_event_wait)。

至此,函數返回,程序可以去幹其他事情了,後續的IO處理交給後臺線程了。
介紹一下後臺IO線程怎麼處理的。

InnoDB啟動時,後臺IO線程會被啟動(io_handler_thread)。其會調用os_aio_simulated_handle從全局數組中取出IO請求,然後用同步IO處理,結束後,需要做收尾工作,例如,如果是寫請求的話,則需要在buffer pool中把對應的數據頁從髒頁列表中移除。

os_aio_simulated_handle首先需要從數組中挑選出某個IO請求來執行,挑選算法並不是簡單的先進先出,其挑選所有請求中offset最小的請求先處理,這樣做是為了後續的IO合併比較方便計算。但是這也容易導致某些offset特別大的孤立請求長時間沒有被執行到,也就是餓死,為了解決這個問題,在挑選IO請求之前,InnoDB會先做一次遍歷,如果發現有請求是2s前推送過來的(也就是等待了2s),但是還沒有被執行,就優先執行最老的請求,防止這些請求被餓死,如果有兩個請求等待時間相同,則選擇offset小的請求。

os_aio_simulated_handle接下來要做的工作就是進行IO合併,例如,讀請求1請求的是file1,offset100開始的200位元組,讀請求2請求的是file1,offset300開始的100位元組,則這兩個請求可以合併為一個請求:file1,offset100開始的300位元組,IO返回後,再把數據拷貝到原始請求的buffer中就可以了。寫請求也類似,在寫操作之前先把需要寫的數據拷貝到一個臨時空間,然後一次寫完。注意,只有在offset連續的情況下IO才會合併,有間斷或者重疊都不會合併,一模一樣的IO請求也不會合併,所以這裡可以算是一個可優化的點。

os_aio_simulated_handle如果發現現在沒有IO請求,就會進入等待狀態,等待被喚醒

綜上所述,可以看出IO請求是一個一個的push的對立面,每push進一個後臺線程就拿去處理,如果後臺線程優先級比較高的話,IO合併效果可能比較差,為了解決這個問題,Simulate aio提供類似組提交的功能,即一組IO請求提交後,才喚醒後臺線程,讓其統一進行處理,這樣IO合併的效果會比較好。但這個依然有點小問題,如果後臺線程比較繁忙的話,其就不會進入等待狀態,也就是說只要請求進入了隊列,就會被處理。這個問題在下面的Native aio中可以解決。


總體來說,InnoDB實現的這一套模擬機制還是比較安全可靠的,如果平臺不支持Native aio則使用這套機制來讀寫數據文件。

Linux native aio

如果系統安裝了libaio庫且在配置文件裡面設置了innodb_use_native_aio=on則啟動時候會使用Native aio。

入口函數依然為os_aio_func,在debug模式下,依然會檢查傳入的參數,同樣不會檢查文件是否以O_DIRECT模式打開,這算是一個有點風險的點,如果用戶不知道linux native aio需要使用O_DIRECT模式打開文件才能發揮出aio的優勢,那麼性能就不會達到預期。建議在此處做一下檢查,有問題輸出到錯誤日誌。

檢查通過之後,與Simulated aio一樣,調用os_aio_array_reserve_slot,把IO請求分配給後臺線程,分配算法也考慮了後續的IO合併,與Simulated aio一樣。不同之處,主要是需要用IO請求的參數初始化iocb這個結構。IO請求的相關信息除了需要初始化iocb外,也需要在全局數組的slot中記錄一份,主要是為了在os_aio_print_XXX系列函數中統計方便。

調用io_submit提交請求。

至此,函數返回,程序可以去幹其他事情了,後續的IO處理交給後臺線程了。
接下來是後臺IO線程。

與Simulate aio類似,後臺IO線程也是在InnoDB啟動時候啟動。如果是Linux native aio,後續會調用os_aio_linux_handle這個函數。這個函數的作用與os_aio_simulated_handle類似,但是底層實現相對比較簡單,其僅僅調用io_getevents函數等待IO請求完成。超時時間為0.5s,也就是說如果即使0.5內沒有IO請求完成,函數也會返回,繼續調用io_getevents等待,當然在等待前會判斷一下伺服器是否處於關閉狀態,如果是則退出。

在分發IO線程時,儘量把相鄰的IO放在一個線程內,這個與Simulate aio類似,但是後續的IO合併操作,Simulate aio是自己實現,Native aio則交給內核完成了,因此代碼比較簡單。


還要一個區別是,當沒有IO請求的時候,Simulate aio會進入等待狀態,而Native aio則會每0.5秒醒來一次,做一些檢查工作,然後繼續等待。因此,當有新的請求來時,Simulated aio需要用戶線程喚醒,而Native aio不需要。此外,在伺服器關閉時,Simulate aio也需要喚醒,Native aio則不需要。

可以發現,Native aio與Simulate aio類似,請求也是一個一個提交,然後一個一個處理,這樣會導致IO合併效果比較差。Facebook團隊提交了一個Native aio的組提交優化:把IO請求首先緩存,等IO請求都到了之後,再調用io_submit函數,一口氣提交先前的所有請求(io_submit可以一次提交多個請求),這樣內核就比較方便做IO優化。Simulate aio在IO線程壓力大的情況下,組提交優化會失效,而Native aio則不會。注意,組提交優化,不能一口氣提交太多,如果超過了aio等待隊列長度,會強制發起一次io_submit。

總結

本文詳細介紹了InnoDB中IO子系統的實現以及使用需要注意的點。InnoDB日誌使用同步IO,數據使用異步IO,異步IO的寫盤順序也不是先進先出的模式,這些點都需要注意。Simulate aio雖然有比較大的學習價值,但是在現代作業系統中,推薦使用Native aio。

系列文章

看完本文有收穫?請轉發分享給更多人

關注「資料庫開發」,提升 DB 技能

淘口令:複製以下紅色內容,再打開手淘即可購買

範品社,使用¥極客T恤¥搶先預覽(長按複製整段文案,打開手機淘寶即可進入活動內容)

相關焦點

  • MySQL InnoDB存儲引擎啟動過程源碼分析
    InnoDB 存儲引擎是MySQL默認的存儲引擎,MySQL的架構是Server-Engine架構,從代碼層來看,也可以理解為Server-Plugin架構,MySQL很多功能都是以插件Plugin方式實現的,包括存儲引擎在內。
  • Mysql innodb 存儲引擎的性能優化
    ,但是關於資料庫方面的翻譯的不好,大家就看看吧,翻譯本文只是想更 清楚的了解mysql 優化上的一些基本原則,而國內對於這個沒有完整的資料。鎖表(LOCK TABLES)是設計用來給那些表級鎖的存儲引擎。在行級鎖的存儲引擎中事務是更好的選擇。InnoDB的的鎖表行為在不同的mysql 版本是不同的,如果你 從MySQL4.0或者更新的版本升級,那你依賴於innodb_table_locks這個選項會導致很多問題。5. 主鍵簇5.1. 主鍵是特殊的5.1.1.
  • MySQL InnoDB 引擎中的 7 種鎖類型,你都知道嗎?
    前言大概幾個月之前項目中用到事務,需要保證數據的強一致性,期間也用到了mysql的鎖,但當時對mysql的鎖機制只是管中窺豹,所以本文打算總結一下mysql的鎖機制。本文主要論述關於mysql鎖機制,mysql版本為5.7,引擎為innodb,由於實際中關於innodb鎖相關的知識及加鎖方式很多,所以沒有那麼多精力羅列所有場景下的加鎖過程並加以分析,僅根據現在了解的知識,結合官方文檔,說說自己的理解,如果發現有不對的地方,歡迎指正。概述總的來說,InnoDB共有七種類型的鎖:mysql鎖詳解1.
  • MySQL慢查詢記錄原理和內容解析
    = 0) {} newtime= (ulonglong)t.tv_sec * 1000000 + t.tv_usec; return newtime;可以看到實際就是調用gettimeofday系統調用得到的系統當前時間。
  • 詳解MySQL資料庫優化的方案與實踐
    3.開啟Fastpath功能  Fastpath是LSI的新特性,在RAID控制器為SSD做了了優化,使用fastpath特性可以最大程度發揮出SSD的能力。如果使用SSD做RAID的方式,可以開啟fastpath功能。關於fastpath特性,可以從LSI官網下載資料,並諮詢自己的硬體提供商。
  • MySQL底層存儲結構
    從上面我們可以看出innodb存儲引擎的表空間和myisam存儲引擎的表空間,有一點不一樣:innodb存儲引擎的表空間對應的數據文件和索引是放在一個文件中的,而myisam存儲引擎的表對應的數據文件和索引文件是兩個分開的數據文件,這也是innodb表又稱為IOT,索引組織表的一個原因,它的數據和索引是存放在一個數據文件中的。
  • InnoDB加鎖實驗
    作者簡介:張方雪張方雪, 去哪兒網搜索系統開發工程師。這3種鎖如何鎖定, 如何確定範圍, 會在後面的試驗中講到, 這裡就先不舉例子了. III. 實驗環境準備mysql版本: 5.6.16-64.2 Percona Server.隔離級別:repeatable read.資料庫引擎設置: InnoDB.
  • MySQL優化原理分析及優化方案總結
    所有的跨存儲引擎的功能也在這一層實現:存儲過程、觸發器、視圖等。最下層為存儲引擎負責MySQL中的數據存儲和提取。和Linux下的文件系統類似,每種存儲引擎都有其優勢和劣勢。中間的服務層通過API與存儲引擎通信,這些API接口屏蔽了不同存儲引擎間的差異。我們想讓MySQL獲得更高的查詢性能,首先需要先了解MySQL怎樣進行優化和執行查詢的。
  • 統計信息查詢視圖|全方位認識 sys 系統庫
    在上一篇《會話和鎖信息查詢視圖|全方位認識 sys 系統庫》中,我們介紹了如何使用 sys
  • MySQL 存儲引擎如何完成一條更新語句的執行
    首先肯定是我們的系統通過一個資料庫連接發送到了MySQL上,然後肯定會經過SQL接口、解析器、優化器、執行器幾個環節,解析SQL語句,生成執行計劃,接著去由執行器負責這個計劃的執行,調用InnoDB存儲引擎的接口去執行。
  • 必須了解的mysql三大日誌-binlog、redo log和undo log
    binlog 是 mysql的邏輯日誌,並且由 Server 層進行記錄,使用任何存儲引擎的 mysql 資料庫都會記錄 binlog 日誌。binlog 是通過追加的方式進行寫入的,可以通過 max_binlog_size 參數設置每個 binlog文件的大小,當文件大小達到給定值之後,會生成新的文件來保存日誌。
  • MySQL InnoDB 索引原理
    InnoDB是 MySQL最常用的存儲引擎,了解InnoDB存儲引擎的索引對於日常工作有很大的益處,索引的存在便是為了加速資料庫行記錄的檢索。以下是我對最近學習的知識的一些總結,以及對碰到的以及別人提到過的問題的一些分析,如有錯誤,請指正,我會及時更正。
  • 淺析 MySQL Replication
    目前很多公司中的生產環境中都使用了MySQL Replication ,也叫 MySQL 複製,搭建配置方便等很多特性讓 MySQL Replication 的應用很廣泛,我們曾經使用過一主拖20多個從庫來分擔業務壓力。
  • MySQL 性能優化之骨灰級,高階神技 !
    1、資料庫層面檢查問題常用工具:mysqlmsyqladmin                                 mysql客戶端,可進行管理操作mysqlshow                                  功能強大的查看shell命令show [SESSION | GLOBAL] variables
  • MySQL InnoDB Cluster環境搭建和簡單測試
    要安裝InnoDB Cluster,環境的一個基本要求就是Python,我看了下,很多默認的系統版本是2.6,而它的最低要求是2.7及以上,所以還是需要提前準備下這個部分。    如果你的系統是Python 2.6版本的,可以考慮升級到2.7,參考如下的方法。
  • MySql面試題及答案大全
    此時即使系統崩潰,修改的數據也不會丟失。事務的隔離級別,mysql默認的隔離級別是什麼?讀未提交(Read uncommitted),一個事務可以讀取另一個未提交事務的數據,最低級別,任何情況都無法保證。
  • MySQL 大量 Opening tables 案例分析-愛可生
    一、現象  某項目反饋系統非常卡,登陸 MySQL 後發現大量 SQL 處於Opening tables狀態,斷斷續續,一會好一會又出現,比較離奇。  (row0mysql.cc:1738),ha_innobase::write_row(ha_innodb.cc:7566),handler::ha_write_row(handler.cc:7991),write_record(sql_insert.cc:1873),Sql_cmd_insert::mysql_insert(sql_insert.cc:769),Sql_cmd_insert::execute
  • MySQL 優化案例 - select count-愛可生
    簡單介紹下原理:聚簇索引:每一個 InnoDB 存儲引擎下的表都有一個特殊的索引用來保存每一行的數據,稱為聚簇索引(通常都為主鍵),聚簇索引實際保存了 B-Tree 索引和行數據,所以大小實際上約等於為表數據量二級索引:除了聚集索引,表上其他的索引都是二級索引,索引中僅僅存儲了對應索引列及主鍵列在 InnoDB 存儲引擎中,count(*) 函數是先從內存中讀取數據到內存緩衝區
  • 為什麼這次 MySQL 崩潰恢復要這麼久-愛可生
    4.2. innobase_start_or_create_for_mysql然後我們需要看下 validate參數的定義,分析崩潰恢復與正常啟動的區別。發現 validate 參數最早是在 innobase_start_or_create_for_mysql 函數中定義的,並且其注釋已經解釋得非常詳細。1.
  • 面試官:談談你對MySQL事務的認識?
    這篇文章屬於mysql資料庫系列,我們來談談事務方面的常見面試題。那麼,具體題目有下面這些:1、講講為什麼用事務?事務的四大特性?事務的隔離級別知道吧,你們生產用哪種?2、Innodb中ACID具體是如何實現的?3、redo log和binlog的一致性如何保證?4、大事務有哪些壞處?生產上遇到過大事務麼?你怎麼排查和解決的?