7.5.2 Восстановление базы данных на определённый момент времени с использованием позиций событий
В предыдущем разделе раздел 7.5.1 «Восстановление базы данных на определённый момент времени с использованием двоичного журнала» объясняется общий принцип использования двоичного журнала для выполнения восстановления базы данных на определённый момент времени. В этом разделе подробно описаны операции с примером.
В качестве примера предположим, что около 13:00:00 27 мая 2020 года было выполнено оператор SQL, удаливший таблицу. Вы можете выполнить восстановление на определённый момент времени, чтобы восстановить сервер до состояния непосредственно перед удалением таблицы. Вот примерные шаги для достижения этого:
-
Восстановите последнюю полную резервную копию, созданную до интересующего момента времени (назовём его
tp, что в нашем примере равно 13:00:00 27 мая 2020 года). По завершении запишите позицию двоичного журнала, до которой вы восстановили сервер, для последующего использования, и перезапустите сервер.ПримечаниеПозиция последнего восстановленного двоичного журнала также отображается InnoDB после восстановления и перезапуска сервера, но это ненадёжный способ получения конечной позиции журнала восстановления, так как после момента времени, отражённого в отображаемой позиции, могут произойти события DDL и изменения, не относящиеся к InnoDB. Ваша утилита резервного копирования и восстановления должна предоставлять вам последнюю позицию двоичного журнала для восстановления: например, если вы используете mysqlbinlog для этой задачи, проверьте конечную позицию повторного применения двоичного журнала; если вы используете MySQL Enterprise Backup, последняя позиция двоичного журнала была сохранена в вашей резервной копии. См. …
-
Найдите точную позицию события в двоичном журнале, соответствующую моменту времени, до которого вы хотите восстановить свою базу данных. В нашем примере, зная приблизительное время удаления таблицы (
tp), мы можем найти позицию журнала, проверив содержимое журнала вблизи этого времени, используя утилиту mysqlbinlog. Используйте опции--start-datetimeи--stop-datetimeдля указания короткого временного интервала вокругtp, а затем найдите событие в выводе. Например:$>
mysqlbinlog --start-datetime="2020-05-27 12:59:00" --stop-datetime="2020-05-27 13:06:00" \ --verbose /var/lib/mysql/bin.123456 | grep -C 12 "DROP TABLE"# at 1868 #200527 13:00:30 server id 2 end_log_pos 1985 CRC32 0x8b894489 Query thread_id=8 exec_time=0 error_code=0 use `pets`/*!*/; SET TIMESTAMP=1590598830/*!*/; SET @@session.pseudo_thread_id=8/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.sql_mode=1436549152/*!80005 &~0x1003ff00*//*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; SET @@session.lc_time_names=0/*!*/; SET @@session.collation_database=DEFAULT/*!*/; DROP TABLE `cats` /* generated by server */ /*!*/; # at 1985 #200527 13:05:06 server id 2 end_log_pos 2050 CRC32 0x2f8d0249 Anonymous_GTID last_committed=6 sequence_number=7 rbr_only=yes original_committed_timestamp=0 immediate_commit_timestamp=0 transaction_length=0 /*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/; # original_commit_timestamp=0 (1969-12-31 19:00:00.000000 EST) # immediate_commit_timestamp=0 (1969-12-31 19:00:00.000000 EST) /*!80001 SET @@session.original_commit_timestamp=0*//*!*/; /*!80014 SET @@session.original_server_version=0*//*!*/; /*!80014 SET @@session.immediate_server_version=0*//*!*/; SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/; # at 2050 #200527 13:05:06 server id 2 end_log_pos 2122 CRC32 0x56280bb1 Query thread_id=8 exec_time=0 error_code=0Из вывода mysqlbinlog оператор
DROP TABLE `pets`.`cats`может быть найден в сегменте двоичного журнала между строками# at 1868и# at 1985, что означает, что оператор выполняется после позиции журнала 1868, и журнал находится на позиции 1985 после оператораDROP TABLE.ПримечаниеИспользуйте опции
--start-datetimeи--stop-datetimeтолько для поиска фактических позиций интересующих событий. Не рекомендуется использовать эти опции для указания диапазона сегмента двоичного журнала для применения: существует большая вероятность пропустить события двоичного журнала при использовании этих опций. Используйте--start-positionи--stop-positionвместо этого. -
Примените события в файле двоичного журнала к серверу, начиная с позиции журнала, найденной в шаге 1 (предположим, это 1006), и заканчивая позицией, найденной в шаге 2, которая находится до интересующего момента времени (которая составляет 1868):
$>
mysqlbinlog --start-position=1006 --stop-position=1868 /var/lib/mysql/bin.123456 \| mysql -u root -pКоманда восстанавливает все транзакции с начальной позиции до позиции непосредственно перед конечной позицией. Так как вывод mysqlbinlog включает операторы
SET TIMESTAMPперед каждым записанным оператором SQL, восстановленные данные и связанные журналы MySQL отражают исходные моменты времени выполнения транзакций.Ваша база данных теперь восстановлена до интересующего момента времени,
tp, непосредственно перед удалением таблицыpets.cats. -
Помимо восстановления на определённый момент времени, если вы также хотите повторно выполнить все операторы после интересующего момента времени, снова воспользуйтесь mysqlbinlog для применения всех событий после
tpк серверу. В шаге 2 мы отметили, что после оператора, который мы хотели пропустить, журнал находится на позиции 1985; мы можем использовать её для опции--start-position, чтобы включить любые операторы после этой позиции:$>
mysqlbinlog --start-position=1985 /var/lib/mysql/bin.123456 \| mysql -u root -pВаша база данных была восстановлена до последнего записанного оператора в файле двоичного журнала, но с пропущенным выбранным событием.
© 2025 Oracle
Licensed under the GPLv2 License.