Як ви ідентифікуєте корупцію таблиці InnoDB?


24

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

Ці помилки трапляються на двох серверах з різним обладнанням та O / S. Після запуску:

ALTER TABLE .... COALESCE PARTION n;

проблема зникає за цією таблицею.

Однак моє запитання має більші масштаби, і це "Як ви ідентифікуєте корупцію таблиці InnoDB?" або перефразовано "Як ви оцінюєте стан таблиці InnoDB?" Є "CHECK TABLE" єдиним інструментом для виявлення проблем, які попередньо завершуються збоєм?

Не впевнений, що це має значення, але збої сталися під керуванням: Версія: '5.5.15-55-log' socket: '/opt/mysql.sock' порт: 3306 Percona Server (GPL), випуск rel21.0, версія 15


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 шукає +1
marcio

2
Сервер Percona має деякі інші приємні функції. Див innodb_corrupt_table_action percona.com/doc/percona-server/5.5/reliability / ... (!!)
Morgan Tocker

@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 є синонімом 'check table ...' -1
randomx


Неправда. По-перше, mysqlcheck - це утиліта командного рядка, і CHECK TABLE є оператором SQL (це як порівнювати помаранчевий з лимонами). це теж не було б дуже продуктивним)
marcio

І у mysqlcheck є можливість автоматичного відновлення пошкоджених таблиць у той час як CHECK TABLE перевіряє, чи є таблиці пошкодженими чи ні, але не може зробити жодного ремонту.
marcio

2
@randymelder - Ви неправі сказати, що mysqlcheck є синонімом CHECK TABLE. У документації ви пов'язані з станами: " mysqlcheckвикористовує оператори SQL CHECK TABLE, REPAIR TABLE, ANALYZE TABLE, і OPTIMIZE TABLEв зручному для користувача чином Він визначає , які заяви використання для операції , яку ви хочете виконати, а потім відправляє заяви на сервер буде виконуватися .. " Це не синонім; тобто інтерфейс користувача до колекції заяв.
Нік Шамм

6

Відповідно до посібника з вивчення сертифікації MySQL 5.0, розділ 30.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 про примусове відновлення InnoDB  


3
FWIW, керівництво з сертифікації має дуже політично правильну відповідь :) Якщо ви перевірите таблицю на таблиці InnoDB і вона фактично є пошкодженою, вона ніколи не повернеться як "пошкоджена", вона зламає сервер. Заява майже застаріла в InnoDB, оскільки кожен раз, коли ви читаєте сторінки InnoDB, вона перевіряється на наявність корупції (через контрольні суми сторінок).
Морган Токер

2

Цікаво, що станеться, якщо хтось використовує дані InnoDB, створені за допомогою InnoDB Plugin, а потім перейде на іншу версію InnoDB. Це може створити можливу корупцію сторінки в очах mysqld.

Зауважте, що документація MySQL у форматі файлів InnoDB говорить про цю можливість:

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

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

  • Відкиньте всі бази даних за допомогою InnoDB на підлеглому
  • Вимкнення mysql на рабі
  • Видаліть ibdata1, ib_logfile0 та ib_logfile1 на підлеглому
  • Запустіть mysql на підлеглому, дозволяючи ibdata1, ib_logfile0 та ib_logfile1 відтворити
  • mysqldпередачі даних від ведучого в раб

Мій оригінальний опублікований андерсер вважається "старою школою". Однак у цьому випадку я б точно переглянув формати файлів, які використовуються .ibd та / або ibdata1.

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