Kesalahan ukuran baris dengan MySQL

11

Saya menjalankan server MySQL di Macbook saya (untuk pengujian). Versi 5.6.20 dari Homebrew. Saya mulai mengalami kesalahan "Ukuran baris terlalu besar", dan saya bisa menguranginya ke kasus uji ini. Meja:

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

Status tabel:

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

Kesalahan yang saya dapatkan saat mencoba memasukkan baris ke tabel di mana stuffkolom memiliki lebih dari 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.

Saya telah mencari-cari kesalahan ini, sebagian besar jawabannya melibatkan terlalu banyak kolom TEKS, dan masing-masing memiliki 768 byte yang disimpan sebaris. Seperti yang Anda lihat, bukan itu masalahnya bagi saya. Juga, nomor 5033932 tetap sama terlepas dari jumlah kolom yang saya miliki di tabel. Dalam aplikasi asli saya, ada lima kolom, dan pembaruan masih gagal ketika ukuran kolom melebihi 5033932.

Saya juga melihat orang menyelesaikan masalah dengan mengganti format baris, yang akan saya coba sedikit, tetapi saya ingin memahami persis apa yang menyebabkan kesalahan ini.

Terima kasih sebelumnya!

geoffliu
sumber

Jawaban:

12

Perubahan dalam catatan rilis 5.6.20:

Redo log menulis untuk bidang BLOB besar yang disimpan secara eksternal dapat menimpa pos pemeriksaan terbaru. Patch 5.6.20 membatasi ukuran redo log BLOB menulis hingga 10% dari ukuran file redo log. Patch 5.7.5 menangani bug tanpa memaksakan batasan. Untuk MySQL 5.5, bug tetap merupakan batasan yang diketahui.

Sebagai akibat dari batas penulisan redo log BLOB yang diperkenalkan untuk MySQL 5.6, innodb_log_file_size harus ditetapkan ke nilai yang lebih besar dari 10 kali ukuran data BLOB terbesar yang ditemukan di baris tabel Anda ditambah panjang bidang panjang variabel lainnya (VARCHAR, VARBINARY , dan bidang jenis TEXT). Gagal melakukannya dapat menyebabkan kesalahan "Ukuran baris terlalu besar".

(penekanan milikku)

Default untuk innodb_log_file_sizeadalah 50331648, yang berarti nilai BLOB / TEXT terbesar yang dapat Anda buat, terlepas dari tipe data, mendekati 5033164, dan Anda menemukan nilai yang tepat adalah 5033932. Saya kira secara internal perhitungan melibatkan beberapa faktor fudge.

Jadi, Anda perlu menambah innodb_log_file_sizejika Anda ingin menyimpan data BLOB / TEXT yang lebih besar. Untungnya, mengubah ukuran file log jauh lebih mudah di 5,6 daripada di versi InnoDB sebelumnya. Cukup tambahkan baris di my.cnf Anda dengan nilai baru, dan mulai ulang mysqld.

Bill Karwin
sumber
pemberitahuan kecil, Anda harus memulai ulang atau berhenti dan mulai lagi untuk membiarkan perubahan terpengaruh, muat ulang tidak berfungsi
Hieu Vo
1
Batas ukuran pengulangan ini dikurangi menjadi 10% dari total gabungan innodb_log_file_size (innodb_log_file_size * innodb_log_files_in_group) dari mysql 5.6.22. Dan longblob dapat memiliki panjang maksimum 4294967295 (2 ^ 32 - 1) karakter yaitu sekitar 4GB. Untuk menyimpan nilai longblob ini, kita harus memiliki minimum 40GB gabungan innodb_log_file_size (innodb_log_file_size * innodb_log_files_in_group).
kasi