ข้อผิดพลาดขนาดแถวกับ MySQL


11

ฉันใช้เซิร์ฟเวอร์ MySQL บน Macbook (สำหรับการทดสอบ) รุ่นคือ 5.6.20 จาก Homebrew ฉันเริ่มพบข้อผิดพลาด "ขนาดแถวใหญ่เกินไป" และฉันสามารถลดขนาดลงได้ในกรณีทดสอบนี้ โต๊ะ:

mysql> describe test;
+-------+----------+------+-----+---------+----------------+
| Field | Type     | Null | Key | Default | Extra          |
+-------+----------+------+-----+---------+----------------+
| id    | int(11)  | NO   | PRI | NULL    | auto_increment |
| stuff | longtext | YES  |     | NULL    |                |
+-------+----------+------+-----+---------+----------------+

สถานะตาราง:

mysql> show table status where Name = 'test';
+------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------+
| Name | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time         | Update_time | Check_time | Collation       | Checksum | Create_options | Comment |
+------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------+
| test | InnoDB |      10 | Compact    |    1 |          16384 |       16384 |               0 |            0 |   5242880 |              2 | 2014-08-28 23:51:12 | NULL        | NULL       | utf8_general_ci |     NULL |                |         |
+------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------+

ข้อผิดพลาดที่ฉันได้รับเมื่อฉันพยายามแทรกแถวลงในตารางที่stuffคอลัมน์มีมากกว่า 5033932 ไบต์

mysql> select length(stuff) from test;
+---------------+
| length(stuff) |
+---------------+
|       5033932 |
+---------------+

mysql> update test set stuff = concat(stuff, 'a');
ERROR 1118 (42000): Row size too large (> 8126). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED may help. In current row format, BLOB prefix of 768 bytes is stored inline.

ฉันค้นหาข้อผิดพลาดนี้แล้วคำตอบส่วนใหญ่เกี่ยวข้องกับการมีคอลัมน์ TEXT มากเกินไปและแต่ละอันมี 768 ไบต์เก็บไว้แบบอินไลน์ อย่างที่คุณเห็นนั่นไม่ใช่กรณีของฉัน นอกจากนี้หมายเลข 5033932 ยังคงเหมือนเดิมโดยไม่คำนึงถึงจำนวนคอลัมน์ที่ฉันมีในตาราง ในแอปพลิเคชันดั้งเดิมของฉันมีห้าคอลัมน์และการปรับปรุงยังคงล้มเหลวเมื่อขนาดคอลัมน์เกิน 5033932

ฉันเคยเห็นผู้คนแก้ไขปัญหาด้วยการสลับรูปแบบแถวซึ่งฉันจะลองอีกเล็กน้อย แต่ฉันต้องการที่จะเข้าใจว่าอะไรเป็นสาเหตุของข้อผิดพลาดนี้

ขอบคุณล่วงหน้า!

คำตอบ:


12

การเปลี่ยนแปลงในบันทึกประจำรุ่น 5.6.20:

บันทึกการทำซ้ำสำหรับฟิลด์ BLOB ขนาดใหญ่ที่ถูกจัดเก็บภายนอกอาจเขียนทับจุดตรวจล่าสุดได้ แพ็ตช์ 5.6.20 จำกัด ขนาดของการทำซ้ำบันทึก BLOB เขียนถึง 10% ของขนาดไฟล์บันทึกการทำซ้ำ โปรแกรมแก้ไข 5.7.5 แก้ไขข้อผิดพลาดโดยไม่มีข้อ จำกัด สำหรับ MySQL 5.5 ข้อผิดพลาดยังคงเป็นข้อ จำกัด ที่ทราบ

เนื่องจากข้อ จำกัด การเขียน BLOB ซ้ำที่แนะนำสำหรับ MySQL 5.6, innodb_log_file_size ควรถูกกำหนดเป็นค่ามากกว่า 10 เท่าของขนาดข้อมูล BLOB ที่ใหญ่ที่สุดที่พบในแถวของตารางของคุณรวมถึงความยาวของฟิลด์ความยาวตัวแปรอื่น ๆ (VARCHAR, VARBINARY และเขตข้อมูลประเภทข้อความ) การไม่ทำเช่นนั้นอาจส่งผลให้เกิดข้อผิดพลาด "ขนาดแถวใหญ่เกินไป"

(เน้นที่เหมือง)

ค่าเริ่มต้นสำหรับinnodb_log_file_sizeคือ 50331648 ซึ่งหมายถึงค่า BLOB / TEXT ที่ใหญ่ที่สุดที่คุณสามารถสร้างได้โดยไม่คำนึงถึงชนิดข้อมูลใกล้เคียงกับ 5033164 และคุณค้นพบค่าที่แม่นยำคือ 5033932 ฉันคิดว่าการคำนวณภายในนั้นเกี่ยวข้องกับปัจจัยเหลวไหลบางประการ

ดังนั้นคุณต้องเพิ่มinnodb_log_file_sizeถ้าคุณต้องการเก็บข้อมูล BLOB / TEXT ที่ใหญ่ขึ้น โชคดีที่การเปลี่ยนขนาดไฟล์บันทึกนั้นง่ายกว่ามากใน 5.6 กว่าในรุ่นก่อนหน้าของ InnoDB เพียงเพิ่มบรรทัดใน my.cnf ของคุณด้วยค่าใหม่และเริ่ม mysqld


แจ้งให้ทราบล่วงหน้าขนาดเล็กที่คุณต้องเริ่มต้นหรือหยุดและเริ่มต้นอีกครั้งเพื่อให้ได้รับผลกระทบการเปลี่ยนแปลง, โหลดไม่ทำงาน
Hieu Vo

1
การ จำกัด ขนาดการทำซ้ำนี้จะลดลงเหลือ 10% ของการรวม innodb_log_file_size รวม (innodb_log_file_size * innodb_log_files_in_group) จาก mysql 5.6.22 และ longblob สามารถมีความยาวสูงสุด 4294967295 ตัวอักษร (2 ^ 32 - 1) เช่น 4GB รอบ ๆ ในการเก็บค่า longblob นี้เราควรมีอย่างน้อย 40GB รวม innodb_log_file_size (innodb_log_file_size * innodb_log_files_in_group)
kasi
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.