共計 3578 個字符,預計需要花費 9 分鐘才能閱讀完成。
這期內容當中丸趣 TV 小編將會給大家帶來有關 MySQL 數據庫單一表突破 4G 限制的實現方法是怎么樣的,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
問題:在發表回復時出現“The table is full”的提示,字面意義上是數據表已滿的意思。因為很少有開發者遭遇單一表超過 4G 的情況,因此朋友間的討論只能提供一些外圍的信息。為解決此問題,我翻閱了很多資料,本文將以我此次問題的解決過程,介紹問題發生的原因及對策。
根據經驗,The table is full 提示往往出現在以下兩種情況:
1. 表中設置了 MAX_ROWS 值,簡單的說,若 MAX_ROWS 設置為 100,而程序試圖寫入第 101 條記錄,會出現此錯誤。
2. 表滿。這種情況是本文討論的重點
我們認為 MySQL 在存取表的時候,存在一種定位分配規律。這個規律在默認的情況下,可以尋址 4G 以內的數據。超過這個大小,數據庫將不能對數據定位,因而也無法進行讀寫。經過實驗,這個限制是完全可以被突破的。
用戶的系統環境為雙 Athlon 處理器、SCSI 硬盤 72G、2G 內存,用戶的帖子表數據尺寸為 4294963640,接近 4G(4G 的實際字節數為 4294967296)。
首先 SSH 登錄后,查看用戶的系統信息:
# uname -a
zichen.com 2.4.20-8smp #1 SMP Thu Mar 13 16:43:01 EST 2003 i686 athlon i386 GNU/Linux
證明是 Linux 系統,根據內核版本 2.4.20-8smp,加上國內使用的常見系統,估計應該是 redhat 9 發行包。
# cat /etc/*release*
Red Hat Linux release 9 (Shrike)
這也證明了我們對系統版本的猜想。
然后看一下用的是什么文件系統。因為該用戶并非高手,估計在裝系統的時候就是一路回車下來,redhat 9 默認的應該是 EXT3,不過我們還是看一下:
# parted
GNU Parted 1.6.3
Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
This program is free software, covered by the GNU General Public License.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
Using /dev/sda
Information: The operating system thinks the geometry on /dev/sda is 8942/255/63. Therefore, cylinder 1024 ends at 8032.499M.
(parted) print
Disk geometry for /dev/sda: 0.000-70149.507 megabytes
Disk label type: ms
Minor Start End Type Filesystem Flags
1 0.031 101.975 primary ext3 boot
2 101.975 10103.378 primary linux-swap
證明確實是這樣子。隨后我們翻閱了 EXT3 文件系統的相關技術參數,EXT3 是在 EXT2 基礎上演變而來。EXT2 所支持最大單一文件長度是 2G,這個是很蹩腳的一個限制。EXT3 做的很大一個改善就是將這個限制放大到了 2TB,由此稍松一口氣,起碼不是操作系統上的限制。
經過朋友的開導,了解到單一文件大小有如下幾個因素:
1. 文件系統的限制(如剛存所說 EXT3 的 2TB 限制)
2. 某一程序進程所能存取的第一文件最大尺寸(例如 apache 在 Linux EXT3 下能存取的最大尺寸為 2G,諸如日志)
初步判斷瓶頸就在上述其中第二項。隨后找到 myisamchk 來顯示一下表信息,證明了瓶頸就在 MySQL 本身的存取上。
# myisamchk -dv cdb_posts
結果就不貼了,其中有一項 Max datafile length 的值恰好就是 4G。由此產生了瓶頸。
后來翻閱了 N 多資料,進行了 N 多嘗試,也走了不少彎路,最終覺得還是官方文檔比較可靠。比較老的文檔里寫道這是由于 tmp_table_size 的值造成的,也有提到用 BIG-TABLES 這個參數。事實證明這些都是歧途。大晚上的確實很累,這里只給出最終的解決方案吧,中間的就不羅嗦了。
進到 mysql 客戶端。
# mysql -uroot -p
Enter password: ******
Welcome to the MySQL monitor. Commands end with ; or g.
Your MySQL connection id is 59411 to server version: 4.0.18-standard
Type help; or h for help. Type c to clear the buffer.
mysql use ******
Database changed
mysql ALTER TABLE cdb_posts MAX_ROWS=1000000000 AVG_ROW_LENGTH=15000;
因為這個表非常大,執行時間在雙 Athlon 的專業服務器上竟然花了 30 分鐘!
之后再通過 myisamchk 查看該表的信息:
# myisamchk -dv cdb_posts
MyISAM file: cdb_posts
Record format: Packed
Character set: latin1 (8)
File-version: 1
Creation time: 2004-08-30 22:19:48
Recover time: 2004-08-30 22:42:47
Status: open,changed
Auto increment key: 1 Last value: 1063143
Data records: 619904 Deleted blocks: 5
Datafile parts: 619909 Deleted data: 323872
Datafile pointer (bytes): 6 Keyfile pointer (bytes): 4
Datafile length: 4295287332 Keyfile length: 40421376
Max datafile length: 281474976710654 Max keyfile length: 4398046510079
Recordlength: 149
table description:
Key Start Len Index Type Rec/key Root Blocksize
1 1 4 unique unsigned long 1 4535296 1024
2 5 2 multip. unsigned short 13776 12540928 1024
3 111 4 multip. unsigned long 1 18854912 1024
4 28 3 multip. uint24 18 24546304 1024
5 7 3 multip. uint24 7 32827392 1024
111 4 unsigned long 1
6 7 3 multip. uint24 7 40418304 1024
28 3 uint24
令人振奮的事情發生了,該表的 Max datafile length: 281474976710654 Max keyfile length: 4398046510079,即最大數據尺寸 (MYD 文件) 達到了 2TB,最大索引尺寸 (MYI) 仍然為 4G。
由此默認的 4G 限制被突破了。關于其中的原理,其實很簡單:假設你有一個日記本,上面有 10 頁紙可以寫東西,編排目錄只需要 1 個字節 (因為 0~9 就夠了)。如果你把這本子又塞進兩張紙,變成 12 頁,1 個字節的目錄空間就無法尋址到后面的兩頁中,進而產生了錯誤。上面那個 ALTER 語句中的數值都是我為保證成功,取的比較大的值(因為 ALTER 一次實在是太慢了,沒時間在那亂試驗),相當于告訴,這個本子有 1000000000 頁,每頁平均有 15000 個字節。這樣數據庫便知道這是很大的一個本子,因此不遺余力的拿出了 100 頁(假設說) 做目錄編排,這樣這個新的目錄就可以尋址到日記本的所有內容了。錯誤消失。
惟一的缺點就是,目錄占用的空間多了一些,但已經微乎其微了,做了這種改變其實 4G 的文件尺寸大小只增大了 1M 多,非常令人振奮。
上述就是丸趣 TV 小編為大家分享的 MySQL 數據庫單一表突破 4G 限制的實現方法是怎么樣的了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注丸趣 TV 行業資訊頻道。