Итак, оказывается, что подход, предложенный в комментарии по ссылке в исходном посте, в конце концов работает. Удаление раздела, упомянутого в шаге «изменить таблицу ...» выше, было законным, поскольку он был намеренно удален в исходной таблице до потери файлов ibdata и журнала (но mysql все равно оставляет файлы .ibd не удаленными) . Процесс восстановления мучительно медленный, но мне удалось его написать, и я надеюсь, что он дойдет до завершения в течение следующих нескольких дней.
Вот несколько советов, если вы окажетесь в подобной ситуации, когда нужно восстановить много разделов. Предположим, у вас есть таблица TableName со 100 разделами. Обычно 100 разделов будут иметь последовательные идентификаторы innodb, если они были созданы с помощью оператора «create table», но в целом это может быть не так, поскольку разделы могли быть добавлены после создания. Итак, вот шаги:
1) Узнайте идентификатор innodb, соответствующий каждому разделу, используя метод календаря в блоге выше, как показано ниже. Обратите внимание, что этот шаг не требует перезапуска сервера mysql. Просто создайте таблицу типа TableName без каких-либо разделов и удалите ее табличное пространство. Затем переместите файл .ibd первого раздела (названный чем-то вроде TableName # P # pname1.ibd) в каталог базы данных как TableName.ibd и попробуйте импортировать его. Загляните в mysql error.log (обычно /var/log/mysql/error.log), чтобы узнать, какой у этого раздела innodb ID. Повторите этот шаг для каждого раздела (или по мере необходимости), пока у вас не будет двух кортежей (innodb_ID_i, partition_boundary_i) для всех разделов в файле.
2) Начните с пустого состояния innodb (остановите сервер, удалите ibdata и ib_logfile *, перезапустите сервер). Для каждой записи innodb_ID в файле на шаге 1 выше создайте таблицу TableName_i, например TableName. Например, если 100 разделов соответствуют идентификаторам 321, 322, ..., 370, 415, 416, ... 464 (два блока по 50 смежных идентификаторов в каждом), то напишите сценарий для создания 320 фиктивных таблиц, 50 таблиц. например TableName, 45 фиктивных таблиц и 50 таблиц, таких как TableName.
3) Для каждой таблицы TableName_i, созданной выше,
--do
(i) rename table TableName_i to TableName
(ii) alter table TableName discard tablespace // important to do this step before the next one
(iii) mv TableName#P#pname_i.ibd TableName.ibd // with the appropriate directory prefixes
(iv) alter table TableName import tablespace
(v) alter table partition by range (partition_field) (partition pname_i values less than (partition_boundary_i)) // This is the most and only time consuming step
(vi) rename table TableName to TableName_i // or some other name or just dump it to a file
--repeat
Обратите внимание, что все вышеперечисленные шаги являются сценариями и не требуют перезапуска сервера в любой момент, кроме начала шага 2, чтобы начать с пустого состояния innodb. Будьте внимательны, чтобы проверить успешность каждого подэтапа на шаге 3, прежде чем переходить к следующему, иначе последующие шаги могут завершиться неудачно и / или файлы .ibd могут быть перезаписаны. Если возможно, используйте копию на шаге 3 (iii) вместо mv.
Последнее замечание: может быть немного более простая альтернатива с использованием инструментария восстановления Percona с использованием шестнадцатеричного редактирования, но это не сработало для моего случая секционированных таблиц. Я столкнулся с той же, казалось бы, нерешенной проблемой с секционированными таблицами, как указано в одном из комментариев на http://www.mysqlperformanceblog.com/2011/05/13/connecting-orphaned-ibd-files/. Однако ваш пробег может отличаться. Если бы существовал способ избежать воссоздания разделов (как на шаге 3 (v) выше), это было бы очень быстро и быстро, но я не уверен, есть ли он.
person
Eva
schedule
03.09.2012