Lỗi kích thước hàng với MySQL


11

Tôi đang chạy máy chủ MySQL trên Macbook của mình (để thử nghiệm). Phiên bản là 5.6.20 từ Homebrew. Tôi bắt đầu gặp phải lỗi "Kích thước hàng quá lớn" và tôi đã có thể giảm nó xuống trường hợp thử nghiệm này. Bàn:

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

Bảng trạng thái:

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 |                |         |
+------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------+

Lỗi tôi gặp phải khi tôi cố gắng chèn một hàng vào bảng trong đó stuffcột có hơn 5033932 byte.

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.

Tôi đã tìm kiếm xung quanh cho lỗi này, hầu hết các câu trả lời liên quan đến việc có quá nhiều cột văn bản và mỗi cột có 768 byte được lưu trữ nội tuyến. Như bạn thấy, đó không phải là trường hợp của tôi. Ngoài ra, số 5033932 vẫn giữ nguyên cho dù số lượng cột tôi có trong bảng là bao nhiêu. Trong ứng dụng ban đầu của tôi, có năm cột và các cập nhật vẫn không thành công khi kích thước cột vượt quá 5033932.

Tôi cũng đã thấy mọi người giải quyết vấn đề bằng cách chuyển đổi định dạng hàng, tôi sẽ thử một chút, nhưng tôi muốn hiểu chính xác điều gì gây ra lỗi này.

Cảm ơn trước!

Câu trả lời:


12

Một thay đổi trong ghi chú phát hành 5.6.20:

Làm lại nhật ký ghi cho các trường BLOB lớn, được lưu trữ bên ngoài có thể ghi đè lên điểm kiểm tra gần đây nhất. Bản vá 5.6.20 giới hạn kích thước của bản ghi nhật ký BLOB ghi lại tới 10% kích thước tệp nhật ký làm lại. Bản vá 5.7.5 giải quyết lỗi mà không áp đặt giới hạn. Đối với MySQL 5.5, lỗi vẫn là một giới hạn đã biết.

Do giới hạn ghi BLOB ghi lại được giới thiệu cho MySQL 5.6, innodb_log_file_size phải được đặt thành giá trị lớn hơn 10 lần kích thước dữ liệu BLOB lớn nhất được tìm thấy trong các hàng của bảng của bạn cộng với độ dài của các trường có độ dài biến khác (VARCHAR, VARBINARY và các trường loại văn bản). Không làm như vậy có thể dẫn đến lỗi "Kích thước hàng quá lớn".

(nhấn mạnh của tôi)

Giá trị mặc định innodb_log_file_sizelà 50331648, có nghĩa là giá trị BLOB / TEXT lớn nhất bạn có thể tạo, bất kể loại dữ liệu, gần với 5033164 và bạn đã phát hiện ra giá trị chính xác là 5033932. Tôi cho rằng tính toán bên trong liên quan đến một số yếu tố mờ nhạt.

Vì vậy, bạn cần tăng innodb_log_file_sizenếu bạn muốn lưu trữ dữ liệu BLOB / TEXT lớn hơn. May mắn thay, việc thay đổi kích thước tệp nhật ký dễ dàng hơn rất nhiều trong 5.6 so với các phiên bản trước của InnoDB. Chỉ cần thêm một dòng trong my.cnf của bạn với giá trị mới và khởi động lại mysqld.


Thông báo nhỏ, bạn phải khởi động lại hoặc dừng và bắt đầu lại để thay đổi bị ảnh hưởng, tải lại không hoạt động
Hiếu Võ

1
Giới hạn kích thước làm lại này được giảm xuống 10% trên tổng số innodb_log_file_size (innodb_log_file_size * innodb_log_files_in_group) từ mysql 5.6.22. Và longblob có thể có độ dài tối đa 4294967295 (2 ^ 32 - 1) ký tự, tức là 4GB xung quanh. Để lưu trữ giá trị longblob này, chúng ta nên có tối thiểu 40GB kết hợp innodb_log_file_size (innodb_log_file_size * innodb_log_files_in_group).
kasi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.