+380(66)433-69-36 | |
+380(66)433-69-36 | |
+380(66)433-69-36 |
- BitLocker с GUI под linux
- Ищем вирус elTest
- Работаем с бесплатным SSL сертификатом Letsencrypt с помощью certbot
- Синхронизация ресурсов с удаленного сервера локально
- Применение нестандартного SEO и статус 404
- MySQL синхронизируем права с разных серверов
- IPSec VPN соединение между офисами.
- "Зеркало" сайта на стороне. Донастраиваем nginx
- Дефрагментация таблиц всех баз MySQL
- Месяц в родительном падеже strftime PHP
- INIT скрипт для Dropbox
- osCommerce VAM Edition 226. Ошибки
- PositiveSSL порядок сертификатов
- osCommerce. Создаем модуль доставки
- Восстановление mySQL баз данных
- osCommerce.Перенос магазина в другой домен
- osCommerce.Прячем адмику
- osCommerce. Продление жизни сессий
- osCommerce. Создаем платежный модуль
- 10 причин выбрать нас
- GRUB2 восстановление
- osCommerce не пересчитывает общую сумму заказа
- Список потенциально опасных скриптов
- Отправка файлов из Dropbox по e-mail
- "Черный список" почтовых доменов
- Боремся с назойливыми иностранцами
- Яндекс-Диск, и стоит ли им пользоваться.
- Обновление модуля Интеркассы для osCommerce
- Веб-почта на сайте хостинга
- Подключение Outlook Express к хостингу
Восстановление mySQL баз данных
Для того, чтобы сделать несколько mySQL баз данных одинаковыми на разных серверах можно применить по меньшей мере несколько вариантов. Каждый из них имеет свои достоинства и недостатки.
Самый простейший - делать полный дамп всех баз данных на одном сервере и восстанавливать их на другом. Плохо - потому что не получится восстановить промежуточное состояние базы данных между дампами, не говоря уже о том, что передача дампов между серверами займет большой объем сетевого трафика.
Второй вариант - настроить синхронизацию баз данных с помощью Rsync протокола. Хорошо - не передается вся база данных, а только изменившаяся часть. Плохо - применимо только для myISAM типов таблиц. Учитывая тот факт, что сообщество mySQL рекомендует переходить на использование InnoDB - вариант уже отпадает. Кроме того, он все-таки синтетический. Т.е. в случае сбоя придется восстанавливаться из полной базы данных, или удовольствоваться уже "битой".
Не будем рассматривать другие варианты - их действительно много, а обратимся к встроенному механизму репликаций mySQL. Мы не будем описывать сам процесс создания и связывания серверов - документации по этому вопросу в Интернете много, рассмотрим только прикладной случай который используется на наших хостинговых площадках. Стоит все-таки сразу заметить - что репликация в mySQL все-таки пока еще (до версии 5.5 включительно) асинхронная - т.е. присутствует некоторая задержка между изменениями на одном сервере и обновлением данных на другом. В нашем случае настроена MASTER-MASTER репликация, и включен журнал бинарных логов. Такой подход позволяет восстановить базу данных с точностью до секунд. Правда, для этого понадобится вмешательство наших администраторов - но это не столь существенно. В типе репликации, используемом у нас есть один неприятный момент - это возможный конфликт изменений, сделанных на разных серверах. т.е. если в одно и то же время произойдет изменение одной и той же записи в базе данных на разных серверах, то механизм репликации будет остановлен, и его придется заводить вручную. Конечно, плохо что вручную - но все таки это лучше чем доверить такой тонкий момент автоматическим алгоритмам. Итак. Если вдруг произошла такая ситуация - и механизм репликации остановился - то придется что-то делать. Во-первых, как именно определяется - что есть ошибка в данных. Можно задать запрос в mySQL SHOW SLAVE STATUS; который отобразит состояние репликации. В норме, когда механизм работает - колонки Slave_IO_Running и Slave_SQL_Running должны быть в состоянии Yes. Если Slave_SQL_Running установлен в состояние No - то механизм остановился. Тогда смотрим на значения колонок: Master_Log_File и Relay_Master_Log_File. Если они одинаковы - то это означает по меньшей мере, что остановка произошла недавно, и не придется проверять, существует ли еще более древний файл бинарного лога. Если они различаются - то обязательно смотрим на другом сервере в каталоге бинарных логов - а есть ли такой файл. Если такого файла уже нет - нам не повезло, это означает что изменения утеряны скорее всего навсегда. И остается только восстановить данные из дампа баз данных - мы ведь каждый день их делаем, правда? :) .
Возьмем конкретный пример. Репликация остановилась. Master_Log_File =mysql-bin.000299, а Relay_Master_Log_File = mysql-bin.000298. Смотрим на нашем другом сервере наличие файла mysql-bin.000298 - ура. Он есть, еще ничего не потеряно, есть шанс восстановить репликацию и не потерять ничего. Теперь нужно посмотреть в чем проблема, на какой позиции бинарного лога произошла ошибка и в чем эта ошибка состоит. Для этого существуют колонки Exec_Master_Log_Pos и Last_error. В первой из них указывается позиция запроса в бинарном логе - из-за которого произошла остановка,во втором - причина обработки запроса. Обычно это могут быть несоответствия первичных ключей, или отсутствие какой-то колонки. В данном случае не суть важно - ошибка представляет собой интерес для тех, кто работает с базой данных и знает что и к чему. Если ошибка незначительна и ее можно просто "перескочить" - то делаем следующее. Есть замечательная во всех смыслах утилита mysqlbinlog- которая из бинарного лога создает текстовый файл с sql запросами, которые в нем имеются. В этом же файле указаны временные метки, когда этот запрос был сделан, сам по себе запрос - и позиция в бинарном журнале. Синтаксис ее использования довольно прост: mysqlbinlog mysql-bin.000298 > 1.sql У нас создастся файл 1.sql с полным журналом запросов. Ищем в нем позицию ошибки Пусть она будет равна 486062541. Файл запросов может выглядеть примерно так:
# at 486062541
#141230 6:25:07 server id 3 end_log_pos 486062676 Query thread_id=488505exec_time=0 error_code=0
SET TIMESTAMP=1419913507/*!*/;
delete from whos_online where time_last_click < '1419912607'
/*!*/;
# at 486062676
#141230 6:25:07 server id 3 end_log_pos 486062757 Query thread_id=488505exec_time=0 error_code=0
SET TIMESTAMP=1419913507/*!*/;
COMMIT
/*!*/;
Как видим, ошибочный запрос это delete from whos_online where time_last_click < '1419912607'., который не был по какой-то причине выполнен. Ищем в журнале следующую позицию Она следует за записью: # at - в нашем случае это 486062676. Вот сюда мы и должны переместиться, чтобы "перепрыгнуть" через некорректный запрос и попробовать работать дальше. Для это существует механизм изменения позиции в мастер файле репликации. Во-первых останавливаем сервис: stop slave; Теперь меняем позицию: change master to MASTER_LOG_POS=486062676; и запускаем сервис опять: start slave; . Смотрим статус: show slave status; При хорошем стечении обстоятельств имена файлов в колонках Master_Log_File и Relay_Master_Log_File станут со временем одинаковыми, так же как и номера позиций. Если такое произошло - значит все нормально. Если нет - повторяем наши действия до полной и окончательной победы.
Теперь вернемся к вопросу восстановления базы данных с точностью до секунды. Когда создается дамп базы данных штатными средствами утилитой mysqldump , то в конце дампа как правило можно найти запись вида -- Dump completed on ......после которой идет время, когда дамп был завершен. это нам понадобится для того, корректно восстановится. Дело в том, что как правило время дампа, и время ротации бинарных логов в силу ряда причин не совпадают. Но у нас есть прекрасный механизм встроенный в mysqlbinlog - и он позволяет "сместиться" от начала бинарного журнала на какое-то количество позиций --start-position --stop-position или на какое-то определенное время --start-datetime --stop-datetime. Кроме того, у утилиты есть возможность задать строго определенную базу данных для восстановления журнала из бинарного лога --database . Пусть нам нужно восстановить базу данных test на время 15:00. А дамп был создан 1 декабря 2014 года в 2 ч.07 минут 59 секунд. 2014-12-01 2:07:59.
Во-первых, делаем дамп текущей базы данных test на случай, если что-то пойдет не так. Уж лучше иметь слегка испорченную базу, чем вообще никакой.
mysqldump -u user_name --password=password --add-drop-database --databases test > test.dump.sql
и восстанавливаем базу данных из дампа
mysql -u user_name --password=password test< test.dump.sql
Теперь по времени создания файлов бинарных логов находим те логи, которые нам нужны. Пусть это будет бинарный лог за сегодня - к примеру была удалена таблица, и ее нужно восстановить. С помощью нашей волшебной утилиты создаем файл запросов:
mysqlbinlog mysql-bin.000298 --database=test --start-datetime="2014-12-01 02:07:59" --stop-datetime="2014-12-01 15:00:00" > journal.sql
последнюю опцию --stop-datetime можно не задавать, если нужна последняя версия базы данных со всеми обновлениями, но она может быть полезна, чтобы исключить запрос на удаление таблицы. Тогда нужно обязательно остановится до этого времени, ну или через опции позиционирования --stop-position.
В результате мы получаем файл journal.sql который нужно просто выполнить с базой данных test
mysql -u user_namee --password=password test< journal.sql
Для выполнения этой операции нужны права суперпользователя на базу данных. И только для этой операции.
Чтобы не возится с позициями - можно просто в результирующем файле journal.sql вырезать все некорректные запросы и запустить на выполнения скорректированную версию.