Відновлення після збоїв
Тут ми обговорюємо, як відновити дані після:
- збою операційної системи
- відмови електроживлення
- збою файлової системи
- апаратних збоїв (жорсткого диска, материнської плати.)
Ми будемо використовувати версію 4.1.8 сервера MySQL. Будемо вважати, що дані збережені за допомогою механізму InnoDB, який підтримує транзакції і автоматичне відновлення після збоїв. Будемо також вважати, що сервер MySQL в момент збою знаходиться під навантаженням. Якщо це не так, ніякого відновлення не буде потрібно.
Випадки 1) і 2)
У цих випадках ми можемо припустити, що диск з даними MySQL доступний після рестарту операційної системи. Під час рестарту несуперечливість даних в файлах InnoDB через збій виявляється порушеною, але InnoDB зчитує свої протоколи, знаходить там список затриманих (чиї результатів не скинуті в файл) завершених і незавершених транзакцій, автоматично відкочується незавершені, і скидає в файл результати завершених транзакцій. Інформація про процес відновлення після збою передається користувачеві через протокол помилок MySQL. Витяг з протоколу:
Випадки 3) і 4)
У цих випадках ми вважаємо, що диск з даними MySQL недоступний після рестарту системи; оскільки ряд блоків диска з даними більш неможливо прочитати, MySQL не зможе успішно стартувати. Добре, ми форматіруем диск, або встановлюємо новий, і настає момент відновити наші дані з резервних копій. ах, нам потрібно було вчасно подбати про них! Давайте зробимо крок в минуле і розробимо політику резервування даних.
Політика резервування даних
Всі ми знаємо, що періодичне створення резервних копій (відкатів) повинне плануватися заздалегідь. Повні відкати (моментальні знімки даних на певний момент часу) створюються за допомогою декількох інструментальних засобів MySQL. Гарячий відкат (Hot Backup) InnoDB забезпечує онлайновий (не блокує) фізичний (копії файлів даних) відкат. mysqldump забезпечує онлайновий логічний відкат, який ми розглянемо далі в ході обговорення. приклад:
Так створюється відкат всіх наших InnoDB-таблиць з усіх баз даних, що не перешкоджає виконанню поточних операцій читання / запису цих таблиць. Вміст .sql-файлу - це набір SQL-операторів INSERT. (Припустимо, що це повний відкат на 1 годині дня неділі, коли завантаження сервера мала.)
Робити повні резервні копії необхідно, але не завжди зручно. Вони породжують великі файли відкату і вимагають часу. Вони не оптимальні в тому сенсі, що знову зберігають ті дані, які не змінювалися з часу створення попереднього повного відкату. Більш оптимально робити відкати змін (хоча, вони економлять час відкоту за рахунок часу відновлення).
Щоб робити відкати змін, нам необхідно їх фіксувати. Щоб сервер зберігав інформацію про зміни в файлі під час модифікації даних, він повинен бути запущений з опцією --log-bin. Тоді кожен SQL-оператор, що модифікує дані, буде записаний у файл (який ми називаємо "двійковим протоколом MySQL"). Подивимося на вміст директорія даних сервера MySQL, що працює кілька днів в режимі --log-bin. Ми побачимо тут виконавчі протоколи MySQL:
Щоразу під час рестарту сервер MySQL припиняє запис в поточний файл двійкового протоколу, створює новий і з цього моменту новий файл стане поточним (тим, в який відбувається запис). Таке переключення можна здійснити вручну по команді SQL FLUSH LOGS. index-файл містить список всіх довічних протоколів, збережених в директорії (він використовується для реплікації).
Ці виконавчі протоколи MySQL відображають зміни. Трохи змінимо поведінку mysqldump, щоб відбулося перемикання довічного протоколу в момент створення повної резервної копії; давайте подивимося, яке ім'я присвоєно новому поточному бінарного протоколу:
Тепер ми бачимо в директорії даних файл gbichot2-bin.007. Наш .sql-файл містить рядки:
Це означає, що всі модифікації даних, відображені в довічних протоколах, старіших ніж gbichot2-bin.007. присутні в .sql-файлі. а всі модифікації даних, відображені в файлі gbichot2-bin.007 або новіших, відсутні в .sql-файлі. У понеділок о 1 годині дня ми, щоб зробити відкат змін, всього лише введемо команду mysqladmin --flush-logs. яка створить gbichot2-bin.008. Всі зміни, зроблені між 1 годиною дня неділі, коли був зроблений повний відкат, і 1 годиною дня понеділка відображені в файлі gbichot2-bin.007. Копіюємо цей дорогоцінний файл в місце безпечного зберігання резервних копій (на стрічку, резервну машину, DVD-диск і т.д.).
У вівторок, о 1 годині дня, знову виконаємо mysqladmin --flush-logs. Всі зміни, зроблені між 1 годиною дня понеділка і 1 годиною дня вівторка, відображені в файлі gbichot2-bin.008. Копіюємо і його в місце безпечного зберігання.
Ці виконавчі протоколи MySQL займають дисковий простір; час від часу ми повинні його звільняти. Доброю ідеєю є видаляти виконавчі протоколи, які вже ніколи не знадобляться, тобто після створення повної резервної копії:
Назад до відновлення з резервних копій
Отже, відбувається відмова, скажімо в середу, о 8 годині ранку. Ми відновлюємо останній наявний у нас повний відкат, на неділю, 1 година дня. Оскільки він є всього лише набір SQL-операторів, процес відновлення дуже простий:
Тепер наші дані знаходяться в стані, в якому вони були в неділю, о 1 годині дня. Для відновлення відкатів змін всього лише витягніть їх з місця безпечного зберігання і зробіть:
Тепер наші дані знаходяться в стані на вівторок, 1 годині дня. Ми все ж втрачаємо зміни з цього моменту до моменту збою. Щоб не втратити їх, потрібно було, щоб сервер MySQL зберігав свої виконавчі протоколи на пристрої (диски RAID, SAN.) Відмінному від того, де він зберігає файли даних, і тоді ці протоколи не опинилися б на що вийшов з ладу диску. Якби ми подбали про це (тепер ми зробимо це, обіцяємо!), У нас був би файл gbichot2-bin.009. і ми відновили б його, і наші дані були б такими, як в момент збою (нічого б не загубилося). Ми могли б діяти навіть ще більш гнучко; якби замість відмови помилково виконався оператор DROP DATABASE. ми могли б відкинути редагування з gbichot2-bin.009 на момент безпосередньо передує DROP DATABASE так, щоб наші дані прийшли в стан, безпосередньо передує його виконання! Наприклад, якби Ви знали, що помилковий оператор спрацював близько 7:30 ранку, то зробили б відкат до стану на 7 ранку (з 30-хвилинним запасом):
Це трохи неточно (Ви втрачаєте приблизно півгодинні зміни), але цілком підходить в ряді випадків; в тих випадках, коли Ви реально не можете дозволити собі втратити хоч що-небудь, Ви захочете, щоб mysqlbinlog допрацював якраз до цього DROP DATABASE. Є кілька способів зробити це, ось один:
Ми видаляємо всі рядки, починаючи з DROP DATABASE, зберігаємо a_temp_file.sql і запускаємо
mysql Щоб спати спокійно: Зауваження 1: в реальному житті потрібно було б включення опцій --user і --password (і вказівку правильних імені та пароля) в виклики програм mysqldump і mysql, щоб вони могли встановити з'єднання з сервером MySQL. Зауваження 2: видалення довічних протоколів MySQL по команді mysqldump --delete-master-logs може бути небезпечним, якщо ваш сервер є головним сервером реплікації; в розділі "Реплікація" пояснюється, в чому необхідно переконатися перед видаленням довічних протоколів.
Схожі статті