The table 'my_table' is full
กรุณาอย่าหลงกลโดยข้อผิดพลาด สถานการณ์ที่หายากนี้ไม่มีอะไรเกี่ยวข้องกับดิสก์ ตารางนี้มีเงื่อนไขอย่างครบถ้วนเกี่ยวกับระบบประปาภายในของ InnoDB
ขั้นแรกให้ดูที่แผนภาพของสถาปัตยกรรม InnoDB นี้
โปรดทราบว่าพื้นที่ตารางระบบ (ไฟล์ ibdata) มีเพียง128 เซ็กเมนต์ย้อนกลับและ 1,023 สล็อตย้อนกลับต่อเซ็กเมนต์ย้อนกลับ สถานที่นี้ จำกัด ขนาดของความสามารถในการย้อนกลับของธุรกรรม กล่าวอีกนัยหนึ่งถ้าเซ็กเมนต์ย้อนกลับเดียวต้องการมากกว่า 1023 สล็อตเพื่อสนับสนุนธุรกรรมธุรกรรมจะเข้าสู่table is full
เงื่อนไขนั้น
คิดว่าร้านอาหาร Red Lobster ในรัฐนิวเจอร์ซีย์ อาจมีความจุ 200 คน หากร้านอาหารเต็มผู้คนอาจออกไปข้างนอกเพื่อรอ หากผู้คนในสายได้รับความอดทนพวกเขาอาจออกไปเพราะร้านอาหารเต็ม เห็นได้ชัดว่าการแก้ปัญหาจะไม่ทำให้ New Jersey ใหญ่ขึ้น (หรือเพิ่มพื้นที่ว่างมากขึ้น) ทางออกจะทำให้ร้านอาหาร Red Lobster ใหญ่ขึ้น ด้วยวิธีนี้คุณสามารถเพิ่มความจุที่นั่งเป็น 240 ได้แม้ว่าจะมีเส้นข้างนอกหากคนมากกว่า 240 คนตัดสินใจมาที่ Red Lobster
เพียงเพื่อให้คุณตัวอย่างฉันมีลูกค้าที่มี 2TB ของพื้นที่ตารางระบบและinnodb_file_per_tableถูกปิดการใช้งาน (346G สำหรับ ibdata1 การรีเซ็ตสำหรับ ibdata2) ฉันเรียกใช้แบบสอบถามนี้
SELECT SUM(data_length+index+length) InnoDBDataIndexSpace
FROM information_schema.tables WHERE engine='InnoDB';
ต่อไปฉันย่อส่วน InnoDBDataIndexSpace จากผลรวมของขนาดไฟล์สำหรับ ibdata1 และ ibdata2 ฉันได้สองสิ่งที่ทำให้ฉันตกใจ
- มีพื้นที่เหลือ 106GB ในพื้นที่ตารางระบบ
- ฉันได้รับ
Table is Full
เงื่อนไขเดียวกันนี้
นี่หมายความว่า 106GB ใช้สำหรับระบบประปาภายในของ InnoDB ลูกค้ากำลังใช้ ext3 ในเวลานั้น
ทางออกสำหรับฉันคือการเพิ่ม ibdata3 ฉันพูดถึงเรื่องนี้ในโพสต์เก่าของฉันวิธีแก้ปัญหา "ตาราง ... เต็ม" กับ "innodb_file_per_table"?
ฉันได้กล่าวถึงเรื่องนี้ในกระทู้อื่น ๆ เช่นกัน
โปรดทราบว่าเงื่อนไขนี้สามารถเกิดขึ้นได้แม้ว่าinnodb_file_per_tableถูกเปิดใช้งาน อย่างไร? rollbacks และเลิกทำบันทึกเป็นแหล่งที่มาของแหลมไม่สามารถควบคุมได้คือการเจริญเติบโตสำหรับ ibdata1
คำถามจริงของคุณ
เนื่องจากคุณกำลังเพิ่มดัชนีลงในตารางและรับTable is Full
ตารางจะต้องมีขนาดใหญ่และไม่สามารถอยู่ในส่วนย้อนกลับเดียวได้ คุณต้องทำสิ่งต่อไปนี้:
ขั้นตอนที่ 01
รับข้อมูลลงในไฟล์ดัมพ์
mysqldump --no-create-info mydb mytable > table_data.sql
ขั้นตอนที่ 02
เข้าสู่ระบบ MySQL และเรียกใช้สิ่งนี้
USE mydb
CREATE TABLE mytable_new LIKE mytable;
ALTER TABLE mytable_new ADD INDEX ... ;
ALTER TABLE mytable RENAME mytable_old;
ALTER TABLE mytable_new RENAME mytable;
ขั้นตอนที่ 03
โหลดตารางพร้อมกับดัชนีเพิ่มเติมพร้อมข้อมูล
mysql -Dmydb < table_data.sql
นั่นคือทั้งหมดที่
ดูว่าปัญหาคือ ALTER TABLE จะพยายามแทรกแถวทั้งหมดในตารางขนาดใหญ่ของคุณเป็นธุรกรรมเดียว การใช้ mysqldump จะแทรกข้อมูลลงในตาราง (ตอนนี้มีดัชนีใหม่) หลายพันแถวพร้อมกันไม่ใช่ทุกแถวในธุรกรรมเดียว
ไม่ต้องกังวลเกี่ยวกับwhat if this doesn't work?
ตารางต้นฉบับจะมีชื่อmytable_old
ในกรณีที่มีอะไร สามารถใช้เป็นข้อมูลสำรองได้ คุณสามารถทำสำเนาสำรองเมื่อคุณรู้ว่าตารางใหม่นั้นเหมาะกับคุณ
ให้มันลอง !!!
อัพเดท 2014-06-16 11:13 EDT
หากคุณกังวลเกี่ยวกับการถ่ายโอนข้อมูลที่ใหญ่กว่าเดิมเพียงแค่ gzip
คุณสามารถทำตามขั้นตอนเดียวกัน แต่ดังต่อไปนี้
ขั้นตอนที่ 01
รับข้อมูลลงในไฟล์ดัมพ์
mysqldump --no-create-info mydb mytable | gzip > table_data.sql.gz
ขั้นตอนที่ 02
เข้าสู่ระบบ MySQL และเรียกใช้สิ่งนี้
USE mydb
CREATE TABLE mytable_new LIKE mytable;
ALTER TABLE mytable_new ADD INDEX ... ;
ALTER TABLE mytable RENAME mytable_old;
ALTER TABLE mytable_new RENAME mytable;
ขั้นตอนที่ 03
โหลดตารางพร้อมกับดัชนีเพิ่มเติมพร้อมข้อมูล
gzip -d < table_data.sql.gz | mysql -Dmydb
หรือ
gunzip < table_data.sql.gz | mysql -Dmydb
อัปเดต 2014-06-16 12:55 EDT
ฉันแค่คิดถึงแง่มุมอื่นเกี่ยวกับปัญหานี้
เนื่องจากคุณกำลังทำ DDL และไม่ใช่ DML เป็นไปได้ว่านี่ไม่ใช่การประปาภายในของ InnoDB เนื่องจากDDL ไม่สามารถย้อนกลับสำหรับ InnoDBได้ปัญหาจึงต้องมีการประปาภายนอก ท่อประปาภายนอกนี้ถูกอุดตันอยู่ที่ไหน ฉันสงสัยว่าโฟลเดอร์ชั่วคราวสำหรับระบบปฏิบัติการ ทำไม?
140616 13:04:33 InnoDB: Error: Write to file (merge) failed at offset 3 1940914176.
InnoDB: 1048576 bytes should have been written, only 970752 were written.
InnoDB: Operating system error number 0.
InnoDB: Check that your OS and file system support files of this size.
InnoDB: Check also that the disk is not full or a disk quota exceeded.
InnoDB: Error number 0 means 'Success'.
InnoDB: Some operating system error numbers are described at
InnoDB: http://dev.mysql.com/doc/refman/5.5/en/operating-system-error-codes.html
140616 13:04:33 [ERROR] /usr/libexec/mysqld: The table 'my_table' is full
เห็นdisk quota exceeded
ไหม โควต้าดิสก์นี้ถูกกำหนดไว้ที่ไหน
เรียกใช้แบบสอบถามนี้
SHOW GLOBAL VARIABLES LIKE 'tmpdir';
คุณบอกว่ามัน /var/lib/mysqltmp
ตอนนี้เรียกใช้สิ่งนี้ในระบบปฏิบัติการ
df -h /var/lib/mysqltmp
มีบางอย่างบอกฉันว่าพื้นที่สำหรับ/var/lib/mysqltmp
หมดแล้วคุณมีฟรี 14G ในสายตาของ DDL (เพื่อสร้างดัชนี) การย้อนกลับเกิดขึ้นไม่ใช่ในไฟล์ ibdata1 แต่อยู่ในtmpdir
ตำแหน่ง หาก/var/lib/mysqltmp
ไม่ได้เมาต์ทุกที่ข้อมูล temp จะถูกเขียนในพาร์ติชันรูท หาก/var/lib/mysqltmp
เมานต์ที่ใดที่หนึ่งแสดงว่าเมานท์นั้นเต็มไปด้วยข้อมูลแถว ในทั้งสองกรณีมีพื้นที่ไม่เพียงพอที่จะทำ DDL ให้เสร็จสมบูรณ์
คุณมีสองตัวเลือกที่นี่
ตัวเลือกที่ 1
คุณสามารถสร้างดิสก์ขนาดใหญ่ (อาจมี 100 + GB) และเชื่อม/var/lib/mysqltmp
ต่อกับดิสก์ขนาดใหญ่นั้น
OPTION # 2
คำแนะนำ 3 ขั้นตอนของฉันยังคงใช้ได้แม้จะมีพื้นที่ จำกัด ที่คุณมี
COMMENTARY
เป็นความอัปยศที่ข้อความแสดงข้อผิดพลาดที่คุณโพสต์แจ้งไว้
InnoDB: Operating system error number 0.
InnoDB: Error number 0 means 'Success'.
ซึ่งหมายความว่าระบบปฏิบัติการใช้ได้ดี นอกจากนี้ยังไม่มีหมายเลขข้อผิดพลาดที่เกี่ยวข้องสำหรับสถานการณ์นี้
มีอีกสิ่งที่คุณควรรู้ เอกสาร MySQL บอกว่าการสร้างดัชนีอย่างรวดเร็วสำหรับ InnoDB ยังคงไปที่ดิสก์ :
ระหว่างการสร้างดัชนีไฟล์จะถูกเขียนไปยังไดเร็กทอรีชั่วคราว ($ TMPDIR บน Unix,% TEMP% บน Windows หรือค่าของ --tmpdir ตัวแปรการตั้งค่า) แต่ละไฟล์ชั่วคราวมีขนาดใหญ่พอที่จะเก็บหนึ่งคอลัมน์ที่สร้างดัชนีใหม่และแต่ละไฟล์จะถูกลบทันทีที่รวมเข้ากับดัชนีสุดท้าย
เนื่องจากข้อ จำกัด ของ MySQL ตารางจะถูกคัดลอกแทนที่จะใช้“ การสร้างดัชนีอย่างรวดเร็ว” เมื่อคุณสร้างดัชนีในตารางชั่วคราว นี้ได้รับรายงานว่าเป็นMySQL bug #
อัพเดท 2014-06-16 13:58 EDT
[mysqld]
datadir = /mnt/cbsvolume1/var/lib/mysql
tmpdir = /mnt/cbsvolume1/var/lib/mysql
โปรดตรวจสอบให้แน่ใจว่า/mnt/cbsvolume1/var/lib/mysql
มี 100G หรือมากกว่านั้นฟรี