注意InnoDB的記錄長度,控制Blob字段的數量

注意InnoDB的記錄長度,控制Blob字段的數量

由於熊熊內測希望換64MySQL DB。有點擔心穩定問題,研究了半天kavin當年給的innodb db bug 記錄。我們用的MySQL都是5.0

090609 22:09:41InnoDB: Assertion failure in thread 696346 in file btr0cur.c line 3781

InnoDB: Failing assertion: copied_len == local_len + extern_len

InnoDB: We intentionally generate a memory trap.

後面又仔細看了robinfujackai的總結帖。 發現可能是由於InnoDB,Got error 139 from storage engine錯誤導致的。

 

又看了半天MySQLinnodb 的手冊,發現對於Got error 139 from storage engine 錯誤,innodb有比較詳細的解釋。

http://dev.mysql.com/doc/refman/5.0/en/innodb-restrictions.html

http://dev.mysql.com/doc/refman/5.0/en/innodb-file-space.html

簡單說就是一個記錄()的長度不要超過的1半(默認大約8K),行的長度一般情況下就是字段數據長度綜合,但數據字段中如果有BLOBTEXT)。

BLOBTEXT)的長度如果大於768字節,就會在這個頁面上放一部分(768個字節)的數據,其他數據放到其他頁面上,所以當BLOB字段的總數大約10

且每個字段都大於768個字節時,總長度就會大於8000(準確可能是8192),就會出現Got error 139 from storage engine 錯誤,(注意這個錯誤只是修改失敗,不會Crash

但注意這個是充分條件。不是必要條件。充分必要條件就是數據記錄長度大於8000,你要考慮你還有其他字段也要佔用空間。

 

解決這個問題的最簡單的方法就是減少blob的字段,同時老老實實的估計自己的行長度。(熊熊現在的BLOB字段5個。)

對於這個錯誤的最簡單的規避方法還可以調整innodb_page_size(默認長度是16K)的長度。這樣你可以容納更多的BLOB字段了。但擴大可能會引發髒空間的問題。

當然你還可以不用innodb,但是innodb現在已經是用的最廣泛的MYSQL引擎了,靠的是實力。

隨便說一句,我看一個修改記錄MYSQL3.23的某個版本就說過Innodb解決了一行8000的限制問題,怎麼改着改着又改回去了。

 

但這個問題是否會引發innodb crash,我的觀點和jackai類似,出現這個錯誤後的確出現了Crash,但是未必是這個錯誤導致的。從crash的斷言附近的代碼看,應該是出現了數據異常。我google半天發現一個比較類似的問題報告。(斷言發發生的地方一樣)http://bugs.mysql.com/bug.php?id=18410

但是沒有結論,MySQL的開發者認爲可能是磁盤或者硬件異常導致的,或者說是出現故障後錯誤的修復導致的。由於無法瞭解當時場景和是否操作(有點懷疑我收到的錯誤信息是否正確),所以我也無從判斷是否有這類可能。

另外的可能是在錯誤處理上沒有回滾好。導致了某些數據的異常,但我無法重現。據說公司出現過多起這類事故。但MYSQL的開發者信誓旦旦No bug has ever been found in InnoDB that could explain the file corruption cases that have been reported from Linux in the past 5 years. 2006年)

看過新的版本5.0.85的版本感覺在這個代碼附近也沒有什麼修正。

 

謝謝robinfujackai的總結。

 

BTW,看了一下最近的MySQL的發展,驚訝的發現google居然幫助了MySQL進行了很多修補。MySQL5.4版本和Innodb新的plugin都是和Google幫助有關。

Google的境界和實力不服不行。

發佈了79 篇原創文章 · 獲贊 32 · 訪問量 56萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章