Как вы определяете повреждение таблицы InnoDB?

24

У меня есть несколько таблиц, которые разделены и имеют несколько индексов на реплицированном ведомом устройстве. После копирования моментального снимка (проверенного безопасного) на новое ведомое устройство и обновления mysqld с 5.1.42 до 5.5.15 и перезапуска репликации я получаю сбои InnoDB с сообщением об ошибке «Неверный указатель ...»

Эти ошибки произошли на 2 серверах с разным оборудованием и O / S. После запуска:

ALTER TABLE .... COALESCE PARTION n;

проблема уходит за этот стол.

Мой вопрос, однако, больше по объему, и это «Как вы определяете повреждение таблицы InnoDB?» или перефразировал "Как вы оцениваете здоровье таблицы InnoDB?" Является ли «CHECK TABLE» единственным доступным инструментом для выявления проблем до сбоя?

Не уверен, что это имеет значение, но произошли сбои во время работы: Версия: «5.5.15-55-log», сокет: «/opt/mysql.sock», порт: 3306 Percona Server (GPL), выпуск rel21.0, редакция 158

randomx
источник
2
Привет Рэнди! Я думаю, что ответы здесь заслуживают доверия - InnoDB выявил собственную коррупцию. Может быть, вам следует перефразировать свой вопрос, почему то, что вы делаете, приводит к повреждению InnoDB?
Морган Токер

Ответы:

18

В своем комментарии Морган намекает, что InnoDB постоянно проверяет наличие поврежденных страниц, выполняя контрольные суммы на страницах, которые он читает. Если InnoDB находит несоответствие контрольной суммы, он будет врезаться остановить сервер.

Если вы хотите ускорить этот процесс (вместо того, чтобы ждать, пока InnoDB прочитает поврежденную страницу), вы можете использовать innochecksum:

Поскольку из-за несоответствия контрольной суммы InnoDB намеренно отключает работающий сервер, может быть предпочтительнее использовать этот инструмент, а не ждать, пока сервер в производственном использовании обнаружит поврежденные страницы.

Интересная оговорка:

Нельзя использовать innochecksum для файлов табличного пространства, которые уже открыты на сервере. Для таких файлов вы должны использовать CHECK TABLE, чтобы проверить таблицы в табличном пространстве.

Так что да, для онлайн таблицы CHECK TABLE, вероятно, это инструмент (или, как указано в другом ответе, mysqlcheck если вы хотите сделать больше, чем одну базу данных одновременно).

Если вы можете закрыть свою базу данных, вы можете принудительно установить контрольные суммы, используя innochecksum

Анекдот: на табличном пространстве innodb размером 29 ГБ (с innodb_file_per_table=1) этот сценарий занял около 2 минут

#!/bin/bash
for i in $(ls /var/lib/mysql/*/*.ibd)
do
  innochecksum -v $i
done

В качестве бонуса, тем не менее, поскольку вы используете Percona, они реализовали новый метод для быстрой проверки контрольной суммы innodb . Я никогда не использовал его, но это может ускорить процесс.

Дерек Дауни
источник
1
Собираюсь попробовать здесь, похоже, решение, которое ищет
@randymelder
2
Сервер Percona имеет ряд других приятных функций. См. Innodb_corrupt_table_action percona.com/doc/percona-server/5.5/reliability/… (!!)
Морган Токер
@DTest: путь innochecksum - это путь. Этот хранитель. +1 !!!
RolandoMySQLDBA
@DTest: Снимаю шляпу перед вами сегодня на этом !!!!
RolandoMySQLDBA
@MorganTocker Интересно. Мне нужно будет пустить мои знания и провести исследование перконы
Дерек Дауни,
6

ВНИМАНИЕ: перед выполнением любой из этих инструкций настоятельно рекомендуется убедиться в том, что на всякий случай имеется надежная резервная копия вашей базы данных. (спасибо @Nick за предупреждение)

Попробуйте использовать mysqlcheckкоманду. На терминале:

mysqlcheck -u username -p --databases database1 database2

Эта команда выведет список всех таблиц и статус, сообщающий о наличии каких-либо повреждений:

table1  OK
table2  OK
table3  OK
tableN  OK

Имея это в руках, вы уже будете знать, какие столы вам нужно починить. На всякий случай, если вы хотите починить все сразу:

mysqlcheck -u username -p --auto-repair --databases database1 database2 

Подробнее о mysqlcheck: http://dev.mysql.com/doc/refman/5.0/en/mysqlcheck.html

Примечание: вы пометили свой вопрос с помощью . Я понятия не имел, что это было, поэтому я погуглил. Кажется, это вилка MySQL, но у меня нет оснований полагать, что команды несовместимы (пальцы скрещены).


Кто-то указал мне на это руководство, в котором есть более конкретные инструкции по восстановлению базы данных InnoDB для более критических ситуаций, когда вся база данных не запускается: http://www.softwareprojects.com/resources/programming/t-how-to-fix-mysql -database-MyISAM-InnoDB-1634.html

Марсио
источник
1
mysqlcheck является синонимом «проверка таблицы ...» -1
randomx
Не правда. Во-первых, mysqlcheck - это утилита командной строки, а CHECK TABLE - оператор SQL (это все равно, что сравнивать оранжевый цвет с леммонами). Также вы НЕ МОЖЕТЕ проверять всю базу данных с помощью CHECK TABLE, не включая ВСЕ имена таблиц в операторе SQL ( это было бы не очень продуктивно)
Марсио
И у mysqlcheck есть опция --auto-восстанавливать поврежденные таблицы, в то время как CHECK TABLE проверяет только, повреждены ли таблицы или нет, но не может выполнить какое-либо восстановление.
Марсио
2
@randymelder - Вы ошибаетесь, говоря, что mysqlcheck является синонимом CHECK TABLE. В документации вы связаны с состояниями: " mysqlcheckиспользует операторы SQL CHECK TABLE, REPAIR TABLE, ANALYZE TABLE, и OPTIMIZE TABLEв удобном для пользователя образом Он определяет , какие заявления использования для операции , которую вы хотите выполнить, а затем отправляет заявления на сервер будет выполняться.. " Это не синоним; это пользовательский интерфейс для коллекции операторов.
Ник Чаммас
6

В соответствии с Руководством по изучению сертификации MySQL 5.0, раздел 45.4 :

Вы можете проверить таблицы InnoDB, используя команду CHECK TABLE или используя клиентскую программу, чтобы выдать инструкцию для вас. Однако, если у таблицы InnoDB есть проблемы, вы не можете исправить это с помощью REPAIR TABLE, потому что этот оператор применяется только к MyISAM.

Если проверка таблицы показывает, что у таблицы InnoDB есть проблемы, вы должны иметь возможность восстановить таблицу до согласованного состояния, выгрузив ее с помощью mysqldump, отбросив ее и воссоздав ее из этого дампа.

В случае сбоя сервера MySQL или хоста, на котором он работает, некоторые таблицы InnoDB могут нуждаться в ремонте. Обычно достаточно просто перезапустить сервер, потому что механизм хранения InnoDB выполняет автоматическое восстановление как часть своей последовательности запуска. В редких случаях сервер может не запуститься из-за сбоя автоматического восстановления InnoDB. Если это произойдет, используйте следующую процедуру:

  • Перезапустите сервер с параметром --innodb_force_recovery, установленным в значение в диапазоне от 1 до 6. Эти значения указывают на повышенные уровни предосторожности во избежание сбоя и повышающие уровни допуска к возможным несоответствиям в восстановленных таблицах. Хорошее значение для начала - 4.

  • Когда вы запускаете сервер с ненулевым значением --innodb_force_recovery, InnoDB обрабатывает табличное пространство только для чтения. Следовательно, вы должны сбросить таблицы InnoDB с помощью mysqldump, а затем отбросить их во время действия опции. Затем перезапустите сервер без параметра --innodb_force_recovery. Когда сервер загрузится, восстановите таблицы InnoDB из файлов дампа.

  • Если предыдущие шаги не удаются, необходимо восстановить таблицы InnoDB из предыдущей резервной копии.

Пожалуйста, прочтите MySQL Docs на InnoDB Forced Recovery  

RolandoMySQLDBA
источник
3
FWIW, руководство по сертификации имеет очень политически правильный ответ :) Если вы ПРОВЕРИТЕ ТАБЛИЦУ на таблице InnoDB, и она действительно повреждена, она никогда не вернется как «поврежденная», это приведет к сбою сервера. Оператор почти устарел в InnoDB, потому что каждый раз, когда вы читаете страницы InnoDB, он проверяет наличие повреждений (через контрольные суммы страниц).
Морган Токер
2

Интересно, что произойдет, если кто-нибудь использует данные InnoDB, созданные с помощью плагина InnoDB, а затем переключится на другую версию InnoDB. Это может привести к повреждению страницы в глазах mysqld.

Обратите внимание, что документация MySQL по формату файлов InnoDB говорит об этой возможности:

Как правило, более новая версия InnoDB может создавать таблицу или индекс, которые невозможно безопасно прочитать или записать с помощью предыдущей версии InnoDB без риска сбоев, зависаний, неправильных результатов или искажений. Плагин InnoDB представляет новый механизм для защиты от этих условий и помогает сохранить совместимость между файлами базы данных и версиями InnoDB.

Я бы скинул данные на раба. На самом деле, я бы просто использовал грубую силу, получив логический дамп (mysqldump) данных:

  • Удалите все базы данных, используя InnoDB на ведомом
  • Отключение mysql на раб
  • Удалите ibdata1, ib_logfile0 и ib_logfile1 на ведомом устройстве
  • Запустите mysql на ведомом устройстве, создавая воссозданные ibdata1, ib_logfile0 и ib_logfile1
  • mysqldump данные от мастера в раб

Мой оригинальный опубликованный ответ считается «старой школой». Тем не менее, в этом случае я бы определенно посмотрел на форматы файлов, используемые .ibd и / или ibdata1.

RolandoMySQLDBA
источник