首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 單表突破 4GB 限制實戰:MAX_ROWS/AVG_ROW_LENGTH 參數調優原理與操作

     編輯:MySQL 資料庫相關知識

現象:The table is full 錯誤,數據寫入受阻

論壇回帖報錯 The table is full,表數據文件 .MYD 達 4,294,963,640 位元組 (≈ 4GB),MyISAM 預設 32 位元組文件指標僅能定址 4GB (2^32 位元組)。

環境基線

  • OS:RedHat 9 (Kernel 2.4.20),EXT3 文件系統 (單檔 2TB 上限,非瓶頸)。
  • CPU:雙 Athlon,SCSI RAID,2GB RAM。
  • MySQL:4.0.18-standard,MyISAM 引擎。
  • 問題表:cdb_posts (論壇帖子表)。

根因分析:MyISAM 內部指標位寬限制

# myisamchk -dv cdb_posts
...
Max datafile length: 4294967296  -- 4GB 上限
Max keyfile length: 4398046510079

Datafile pointer (bytes): 4 即 32 位指標。需擴大為 6/8 位元組以支援更大文件。

解決方案:ALTER TABLE 重建並指定容量參數

ALTER TABLE cdb_posts 
  MAX_ROWS = 1000000000 
  AVG_ROW_LENGTH = 15000;
  • MAX_ROWS:預估最大行數 (10 億)。
  • AVG_ROW_LENGTH:預估平均行長 (15000 位元組)。
  • MySQL 依此計算所需指標位寬:pointer_bytes = ceil(log2(MAX_ROWS * AVG_ROW_LENGTH) / 8)。

執行實錄與效果驗證

  • 執行耗時:30 分鐘 (雙 Athlon,表極大,全表重建)。
  • 重建後 myisamchk -dv:
    Datafile pointer (bytes): 6 (48 位,定址 256TB)
    Max datafile length: 281474976710654 (≈ 256TB)
    Max keyfile length: 4398046510079 (索引仍 4GB,如需更大需 myisam_max_sort_file_size 等參數)。
  • 文件體積增長:.MYI 索引文件略增 ~1MB (指標從 4→6 位元組),極小代價換海量容量。

原理通俗類比

日記本 10 頁,目錄 1 位數字 (0-9) 足夠。塞進 2 頁變 12 頁,1 位數字不夠用 → 錯誤。
ALTER TABLE 告訴資料庫:「這本子將有 10 億頁」,資料庫便分配 6 位數字目錄空間,徹底解決定址問題。

適用條件與避坑指南

  1. 僅限 MyISAM:InnoDB 使用表空間 (ibdata/.ibd),單表無 4GB 限制 (受限於表空間總大小 64TB)。
  2. 預估值宜大不宜小:MAX_ROWS * AVG_ROW_LENGTH 需 ≥ 未來最大可能體積,否則重建無效。
  3. 重建期間表鎖定:大表操作極慢,必須維護窗口或用 pt-online-schema-change (不支援 MyISAM) / 主從切換離線重建。
  4. 索引文件仍受 4GB 限制:極大表索引可能先撐爆,需拆分歸檔或遷移 InnoDB。
  5. 現代建議:新專案直接用 InnoDB,避開 MyISAM 歷史包袱。

延伸:InnoDB 單表大小限制

  • 表空間檔案上限 64TB (共享表空間) 或 64TB/檔 (獨立表空間 innodb_file_per_table=ON)。
  • 單行上限約半頁 (~8KB),大字段溢出頁存儲。
  • 主鍵長度 ≤ 3072 位元組 (視頁大小/版本)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved