InnoDB:Failingassertion:page_get_n_recs(page)>1
我們知道,在MySQL5.5裡,insert buffer換了個說法,叫change buffer,能夠快取對二級索引的操作,直到將實際的page讀入bp時才進行合併,這在IO-bound並且表上有很多二級索引時,可以有效提升效能。
但存在一個蛋疼的bug,在5.5.31版本才被徹底fix掉.如果你不幸碰到如下斷言錯誤crash,那麼恭喜你中招了:
InnoDB: Failing assertion: page_get_n_recs(page) > 1
這個問題最初可以追溯到2012年1月份的中旬,春節前三四天,當時一個線上庫不幸觸發該bug,導致crash,並且無法重啟。 當時的處理方式是用innodb froce recovery起來,同時關掉innodb purge thread(另外一個bug,設定一個較大的innodb force recovery無法啟動mysqld),然後dump資料,重建庫..
比較早的關於該bug的討論見:http://bugs.mysql.com/bug.php?id=61104, 但bug#61104並沒用完全修復該bug,只是將斷言移除了而已,這樣使用者可以把例項起來,執行一次DDL來重建表的二級索引
後來Percona的Alexey Kopytov 在buglist上提出了該bug的導致的根本原因(http://bugs.mysql.com/bug.php?id=66819)在於刪除ibuf記錄和應用Ibuf記錄並不是原子的,也就是不在一個mtr中,那麼在不恰當的時間點掛掉,就可能導致無法crash recovery,實際上,即使我們將innodb_change_buffer設定inserts也不是安全的。。。。
再後來,這個bug被fix掉了,但我看了diff後,發現fix的不完整,DELETE的場景依然存在問題。於是俺在Facebook上吐槽了下,Percona的Valeriy Kravchuk很熱心的幫忙確認了..
主要涉及兩個函式
>ibuf_merge_or_delete_for_page,是對一個block上記錄進行change buffer合併的主要函式;
對於Purge操作,即IBUF_OP_DELETE型別:
先執行ibuf_delete後,會直接進行ibuf_btr_pcur_commit_specify_mtr,提交redo,然後再去刪除ibuf記錄(ibuf_delete_rec)
>ibuf_delete_rec,每完成一次change buffer記錄的合併,都會呼叫該函式去從Ibuf tree中將其刪除
在ibuf_delete_rec函式中,當進行btr_cur_optimistic_delete失敗後,會先去commit mitr(呼叫ibuf_btr_pcur_commit_specify_mtr),再去開啟新的mtr做btr_cur_pessimistic_delete
我們知道,Innodb是通過mtr寫入的redo日誌來做crash recovery的,如果我們在merge資料成功和刪除ibuf記錄之間crash掉,那麼就可能資料記錄被更新了,但ibuf記錄還沒被刪除,從而觸發前面提到的斷言失敗(在做ibuf_delete時,想刪除記錄,卻發現page上的記錄已經刪光了…)
也就是說,實際上對於所有的change buffer操作型別都可能存在問題,只是對於purge操作,概率更高點,因為它有兩個風險點
官方第一次fix,在MySQL5.5.29裡,修復了ibuf_delete_rec中存在的問題,方式是先標記刪除ibuf entry,再做悲觀刪除
官方第二次fix,在MySQL5.5.31裡,修復ibuf_merge_or_delete_for_page中存在的問題
相關文章
- 遭遇 bug InnoDB: Failing assertion: page_get_n_recs(page) > 1AI
- InnoDB: Error: space id and page n:o stored in the page?Error
- innblock 工具| InnoDB page觀察利器BloC
- InnoDB從內分析之Page(二)
- MySQL5.7 InnoDB Page CompressionMySql
- MySQL 8.0 Reference Manual(讀書筆記78節-- InnoDB Table and Page Compression (1))MySql筆記
- MySQL:Innodb page clean 執行緒 (二) 解析MySql執行緒
- 解決mysql innodb page corrupt一例MySql
- MySQL:Innodb page clean 執行緒 (一) 基礎MySql執行緒
- innodb page重組空間壓縮函式(btr_page_reorganize_low)註釋函式
- MySQL原理 - InnoDB引擎 - 行記錄儲存 - Off-page 列MySql
- coca 搭配 in vs on vs at | page1
- 關於MYSQL INNODB index page header學習和實驗總結MySqlIndexHeader
- MySQL 8.0 Reference Manual(讀書筆記79節-- InnoDB Table and Page Compression (2))MySql筆記
- PostgreSQL Page頁結構解析(1)-基礎SQL
- PostgreSQL 資料頁Page解析(1)- 基礎SQL
- MySQL啟動報錯InnoDB: The innodb_system data file './ibdata1' is of a differentMySql
- MySQL核心InnoDB儲存引擎(卷1)筆記MySql儲存引擎筆記
- [ERROR] InnoDB: Unable to lock ./ibdata1, error: 11Error
- MySQL data pageMySql
- create-a-page
- Mendix Page Template
- [ERROR] InnoDB: ibdata1 different size (rounded down to MB)Error
- The innodb_system data file 'ibdata1' must be writable
- Mysql優化系列(1)--Innodb重要引數優化MySql優化
- mysql之 [ERROR] InnoDB: Unable to lock ./ibdata1, error: 11MySqlError
- NGINX error_pageNginxError
- PostgreSQL Page頁結構解析(5)- B-Tree索引儲存結構#1SQL索引
- Page Lifecycle API 教程API
- Page Object設計模式Object設計模式
- 什麼是前端開發領域的 Page Blink 和 Page Flicker前端
- MySQL 8.0 Reference Manual(讀書筆記75節--Optimizer Statistics for InnoDB (1))MySql筆記
- 詳細瞭解INNODB_TRX、INNODB_LOCKs、INNODB_LOCK_waits、PROCESSLIST表AI
- Landing Page 製作指南
- Page Visibility API 教程API
- SAP Spartacus的page請求
- 搭建基礎架構-Page架構
- Apache2 Ubuntu Default PageApacheUbuntu