«ОШИБКА 1114 (HY000) таблица… заполнена» с innodb_file_per_table, установленной на автоматическое расширение

26

У меня есть база данных MySQL, которая содержит большой объем данных (100-200 ГБ - куча научных измерений). Подавляющее большинство данных хранится в одной таблице Sample. Сейчас я создаю подчиненную копию базы данных, и я хотел воспользоваться преимуществами innodb_file_per_tableэтого процесса. Поэтому я установил innodb_file_per_tableв своей ведомой конфигурации и импортировал дамп базы данных. К моему удивлению, это не удалось с

ОШИБКА 1114 (HY000) в строке 5602: таблица «Образец» заполнена

В Sample.ibdнастоящее время размер файла составляет около 93 ГБ, а в разделе доступно более 600 ГБ свободного места, поэтому проблема не связана с объемом свободного места на диске. Ни один из них, похоже, не достигает какого-либо ограничения файловой системы (я использую ext4).

Буду признателен за любые идеи, что может быть причиной, или что расследовать.


Обновление: я использую mysql Ver 14.14 Distrib 5.1.66, for debian-linux-gnu (x86_64).

SELECT @@datadir; -- returns `/home/var/lib/mysql/`
SHOW VARIABLES LIKE '%innodb_data_file_path%'; -- ibdata1:10M:autoextend 

df -h /home/var/lib/mysql/
768G   31G  699G   5% /home
Петр Пудлак
источник

Ответы:

33

ФАКТЫ

Вы сказали, что используете ext4. Ограничение размера файла составляет 16 ТБ. Таким образом, Sample.ibdне должно быть полным.

Вы сказали, что innodb_data_file_pathэто так ibdata1:10M:autoextend. Таким образом, сам файл ibdata1 не имеет ограничения на его размер, кроме как из ОС.

Почему это сообщение появляется вообще? Обратите внимание, что сообщение «Таблица ... заполнена», а не «Диск ... заполнен». Это полное условие таблицы с логической точки зрения . Подумайте о InnoDB. Какие взаимодействия происходят?

Я предполагаю, что InnoDB пытается загрузить 93 ГБ данных в виде одной транзакции. Откуда Table is Fullисходит сообщение? Я бы посмотрел на ibdata1 не с точки зрения его физического размера (который вы уже исключили), а с точки зрения того, какие пределы транзакций достигаются.

Что находится внутри ibdata1, когда включена innodb_file_per_table и вы загружаете новые данные в MySQL?

Мои подозрения говорят мне, что виноваты журналы отмены и / или журналы повторов.

Что это за логи? Согласно Книге

SxS

Глава 10: «Двигатели хранения» Стр. 203 В пунктах 3,4 говорится следующее:

Движок InnoDB хранит два типа журналов: журнал отмены и журнал восстановления. Цель журнала отмен - откат транзакций, а также отображение более старых версий данных для запросов, выполняющихся на уровне изоляции транзакций, который требует этого. Код, который обрабатывает журнал отмены, можно найти в хранилище / innobase / buf / log / log0log.c .

Цель журнала повторов - сохранить информацию, которая будет использоваться для восстановления после сбоя. Это позволяет процессу восстановления повторно выполнять транзакции, которые могли или не могли быть завершены до сбоя. После повторного выполнения этих транзакций база данных переводится в согласованное состояние. Код, связанный с журналом повторов, можно найти в хранилище / innobase / log / log0recv.c .

АНАЛИЗ

Внутри ibdata1 находится 1023 журналов отмены (см. Сегменты отката и Пробел отмены) . Поскольку в журналах отмены сохраняются копии данных, которые были представлены до перезагрузки, все журналы отмены 1023 достигли своего предела. С другой стороны, все журналы отмены 1023 могут быть выделены для одной транзакции, которая загружает Sampleтаблицу.

НО ЖДАТЬ...

Вы, вероятно, говорите: «Я загружаю пустую Sampleтаблицу». Как задействованы Undo Logs? До Sampleзагрузки таблицы с 93 ГБ данных она была пустой. Представление каждой несуществующей строки должно занимать некоторое пространство для очистки в журналах отмены. Заполнение 1023 Undo Logs кажется тривиальным, учитывая объем данных ibdata1. Я не первый человек, который подозревает это:

Из документации MySQL 4.1 обратите внимание Posted by Chris Calender on September 4 2009 4:25pm:

Обратите внимание, что в 5.0 (до 5.0.85) и в 5.1 (до 5.1.38) вы могли получить сообщение об ошибке «таблица заполнена» для таблицы InnoDB, если в InnoDB заканчиваются интервалы отмены (ошибка № 18828).

Вот отчет об ошибке для MySQL 5.0: http://bugs.mysql.com/bug.php?id=18828

SUGGESTIONS

Когда вы создаете mysqldump Sampleтаблицы, пожалуйста, используйте --no-autocommit

mysqldump --no-autocommit ... mydb Sample > Sample.sql

Это будет ставить явное COMMIT;после каждого INSERT. Затем перезагрузите стол.

Если это не работает ( вам это не понравится ), сделайте это

mysqldump --no-autocommit --skip-extended-insert ... mydb Sample > Sample.sql

Это заставит каждую вставку иметь только одну строку. Mysqldump будет намного больше (в 10 раз больше) и может потребовать от 10 до 100 раз больше времени для перезагрузки.

В любом случае это избавит журналы отмены от затопления.

Попробуйте!

ОБНОВЛЕНИЕ 2013-06-03 13:05 ПО ВОСТОЧНОМУ ВРЕМЕНИ

ДОПОЛНИТЕЛЬНОЕ ПРЕДЛОЖЕНИЕ

Если системная таблица InnoDB (также известная как ibdata1) выходит за пределы размера файла и Журналы отмены не могут быть использованы, вы можете просто добавить другое системное табличное пространство (ibdata2).

Я только столкнулся с этой ситуацией всего два дня назад. Я обновил свой старый пост тем, что сделал: см. Дизайн базы данных - Создание нескольких баз данных, чтобы избежать головной боли при ограничении размера таблицы.

По сути, вы должны изменить innodb_data_file_path, чтобы разместить новый системный файл табличного пространства. Позвольте мне объяснить, как:

СЦЕНАРИЙ

На диске (ext3) сервер моего клиента имел следующее:

[root@l*****]# ls -l ibd*
-rw-rw---- 1 s-em7-mysql s-em7-mysql     362807296 Jun  2 00:15 ibdata1
-rw-rw---- 1 s-em7-mysql s-em7-mysql 2196875759616 Jun  2 00:15 ibdata2

Настройка была

innodb_data_file_path=ibdata1:346M;ibdata2:500M:autoextend:max:10240000M

Обратите внимание, что ibdata2вырос до 2196875759616, что 2145386484M.

Мне пришлось вставить размер файла ibdata2в innodb_data_file_path и добавитьibdata3

innodb_data_file_path=ibdata1:346M;ibdata2:2196875759616;ibdata3:10M:autoextend

Когда я перезапустил mysqld, это сработало:

[root@l*****]# ls -l ibd*
-rw-rw---- 1 s-em7-mysql s-em7-mysql     362807296 Jun  3 17:02 ibdata1
-rw-rw---- 1 s-em7-mysql s-em7-mysql 2196875759616 Jun  3 17:02 ibdata2
-rw-rw---- 1 s-em7-mysql s-em7-mysql   32315015168 Jun  3 17:02 ibdata3

В 40 часов ibdata3вырос до 31G. MySQL снова работал.

RolandoMySQLDBA
источник
Я предполагаю по имени владельца, что ваш клиент использовал готовый инструмент мониторинга ... Спасибо, похоже, это также исправило проблему и для меня.
Стив
Интересно, если это все еще проблема (надеюсь, нет)
Эван Кэрролл
3

У меня была та же проблема, и я просто сделал одну вещь, и это сработало.

У вас слишком маленький максимальный размер для innodb_data_file_pathвашего my.cnfфайла конфигурации. Просто измените код ниже -

innodb_data_file_path = ibdata1:10M:autoextend:max:512M

Важное примечание Вы не можете разместить больше 512MBданных во всех InnoDB таблицах вместе взятых.

Вы также можете переключиться на схему innodb-per-table, используя innodb_file_per_table.

Joomler
источник