InnoDB створює помилку таблиці: "Розмір рядка занадто великий"


11

У нас є кілька інженерів, які згладжують нормалізовану структуру db у тимчасову таблицю для створення звіту. Стовпці вказані як TEXT NOT NULL(я знаю, "чому вони роблять це?"; Припустимо лише, що ми вирішуємо це).

Ми використовуємо MySQL 5.1.48 Community RHEL5 із плагіном InnoDB 1.0.9 на Linux.

Під час використання MyISAM ми ніколи не стикалися з обмеженнями розміру таблиці максимальних стовпців або максимальної довжини рядків (під час розслідування ми досягли максимальної межі стовпців на рівні 2598 (2599-а викликає помилку 1117). З InnoDB ми вражаємо обмеження. Ці обмеження виявляються під час створення таблиця (без вставки даних) як:

ПОМИЛКА 1118 (42000) у рядку 1: розмір рядка занадто великий. Максимальний розмір рядка для використовуваного типу таблиці, не рахуючи BLOB, становить 8126. Ви повинні змінити деякі стовпці на TEXT або BLOBs

Я шукаю відповіді на наступне:

  1. Яка детальна формула для визначення конкретних розмірів рядків при використанні стовпців партії v / v / b / t? Я спробував кілька різних формалів, використовуючи varchar(N)стовпці (де N - від 1 до 512), діаграму UTF8 (* 3) та стільки ж стовпців, скільки буде тривати таблиця до відмови. Жоден із комбінацій, які я намагався, не давав значень, які відповідають фактичним результатам тесту.

  2. Які ще «накладні витрати» слід враховувати під час обчислення розміру рядка?

  3. Чому повідомлення про помилку змінюється з 8126 на 65535, коли я переходжу від створення таблиць із стовпцями varchar (109) до стовпців varchar (110)?


У мене була така ж проблема. Коли я перевіряв базу даних, я виявив, що один із доповнень у веб-браузер вставляв HTML-код у вихідний код сторінки (навіть у форму), і це спричиняло проблеми.

HTML - не лиходій. Ні розмір цього HTML-коду. У вас, мабуть, було кілька текстових / варчарських стовпців і ви досягли деяких обмежень, які можна вирішити.
Рік Джеймс

Відповіді:


19

Відповіді на ваші запитання є складними, оскільки залежать від формату файлу InnoDB . Сьогодні існує два формати, які називаються Антилопа і Барракуда.

Файл центрального простору таблиць (ibdata1) завжди знаходиться у форматі антилопи . Якщо ви використовуєте файл за столом, ви можете змусити окремі файли використовувати формат Barracuda , встановивши innodb_file_format=Barracudaв my.cnf.

Основні моменти:

  • Одна сторінка даних InnoDB на 16 КБ повинна містити щонайменше два рядки даних. Плюс до кожної сторінки є заголовок та колонтитул, що містить контрольні суми сторінки та номер послідовності журналу тощо. Ось де ви отримуєте ліміт трохи менше 8 КБ на рядок.

  • Типи даних фіксованого розміру, такі як INTEGER, DATE, FLOAT, CHAR, зберігаються на цій основній сторінці даних і рахуються до межі розміру рядка.

  • Типи даних змінного розміру, такі як VARCHAR, TEXT, BLOB, зберігаються на переливних сторінках, тому вони не враховуються повністю до межі розміру рядка. В Антилопі до 768 байт таких стовпців зберігаються на первинній сторінці даних, крім того, що вони зберігаються на сторінці переповнення. Barracuda підтримує динамічний формат рядків , тому він може зберігати лише 20-байтовий покажчик на основній сторінці даних.

  • Типи даних змінного розміру також мають префікс з 1 або більше байтами для кодування довжини. Формат рядків InnoDB також має масив зміщення поля. Отже, є внутрішня структура, більш-менш задокументована у їхній вікі . [EDIT] Мертве посилання - ось зараз виглядає краще.

Barracuda також підтримує ROW_FORMAT = COMPRESSED для отримання додаткової ефективності зберігання даних для переповнення даних.

Я також повинен прокоментувати, що я ніколи не бачив, щоб добре розроблена таблиця перевищувала обмеження розміру рядків. Це сильний "запах коду", що ви порушуєте умови повторюваних груп Першої нормальної форми.


2
Інженерам, які не мають базу даних БД, дуже просто пройти рівний маршрут даних. це НІКОЛИ не виконує. Мій власний застарілий БД, який має подібну ситуацію, не вражає розмір рядка, настільки менш драматичний, але хлопчик, це виграш від продуктивності! Я б сказав, що ваш інженер-звітник повинен прийняти, що їм доведеться робити приєднання, і просто компенсувати цю роботу добре протягом усієї індексації.
TechieGurl

1

Моя ситуація дещо інша. Один з елементів даних, який мені потрібно зберігати в кожному рядку, потенційно дуже великий. (Поле даних - це LONGBLOB для документа, який може містити декілька вбудованих зображень. Моя вибіркова база даних містить документи розміром від 25 до 30 Мб, але в деяких випадках ці документи можуть бути більшими.) Жодне із знайдених в Інтернеті рішень не надало полегшення . (Змінили тип файлу InnoDB на Barracuda, збільшили розмір файлу журналу, встановили формат рядка на COMPRESSED.)

Єдине знайдене нами рішення, це повернутися до MySQL 5.5.x з MySQL 5.6.x.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.