MySQL备份恢复

Posted 辛辛之火可以开源

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL备份恢复相关的知识,希望对你有一定的参考价值。

备份恢复示例:

  • 逻辑备份恢复示例

  • 物理备份恢复示例

  • Xtrabackup备份恢复示例

 

逻辑备份恢复示例(完全备份+增量备份)

逻辑备份=======
 1. 检查数据库状态和确认数据库数据: [root@cephclient ~]# mysql -ursun -pEnter password:Welcome to the MySQL monitor. Commands end with ; or \g.Your MySQL connection id is 13Server version: 8.0.19-cluster MySQL Cluster Community Server - GPLCopyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.Oracle is a registered trademark of Oracle Corporation and/or itsaffiliates. Other names may be trademarks of their respectiveowners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> status;--------------mysql  Ver 8.0.19-cluster for Linux on x86_64 (MySQL Cluster Community Server - GPL)Connection id: 13Current database:Current user: rsun@localhostSSL: Not in useCurrent pager: stdoutUsing outfile: ''Using delimiter: ;Server version: 8.0.19-cluster MySQL Cluster Community Server - GPLProtocol version: 10Connection: Localhost via UNIX socketServer characterset: utf8mb4Db characterset: utf8mb4Client characterset: utf8mb4Conn. characterset: utf8mb4UNIX socket: /var/lib/mysql/mysql.sockBinary data as: HexadecimalUptime: 22 min 13 sec
Threads: 2 Questions: 238 Slow queries: 0 Opens: 263 Flush tables: 3 Open tables: 183 Queries per second avg: 0.178--------------mysql> show databases;+--------------------+| Database |+--------------------+| information_schema || mysql || performance_schema || sys |+--------------------+4 rows in set (0.01 sec)
mysql> use mysql;Reading table information for completion of table and column namesYou can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;+---------------------------+| Tables_in_mysql |+---------------------------+| columns_priv || component || db || default_roles || engine_cost || func || general_log || global_grants || gtid_executed || help_category || help_keyword || help_relation || help_topic || innodb_index_stats || innodb_table_stats || ndb_binlog_index || password_history || plugin || procs_priv || proxies_priv || role_edges || server_cost || servers || slave_master_info || slave_relay_log_info || slave_worker_info || slow_log || tables_priv || test || time_zone || time_zone_leap_second || time_zone_name || time_zone_transition || time_zone_transition_type || user |+---------------------------+35 rows in set (0.00 sec)
mysql> create table rsun_test as select * from server_cost;Query OK, 6 rows affected (0.02 sec)Records: 6 Duplicates: 0 Warnings: 0
mysql> insert into rsun_test select * from rsun_test;Query OK, 6 rows affected (0.02 sec)Records: 6 Duplicates: 0 Warnings: 0
mysql> select count(*) from rsun_test;+----------+| count(*) |+----------+| 12 |+----------+1 row in set (0.01 sec)
mysql> insert into rsun_test select * from rsun_test;Query OK, 12 rows affected (0.00 sec)Records: 12 Duplicates: 0 Warnings: 0
mysql> select count(*) from rsun_test;+----------+| count(*) |+----------+| 24 |+----------+1 row in set (0.00 sec)
mysql> commit;Query OK, 0 rows affected (0.00 sec)
《注释》:使用`date +%y%m%d` Example: mkdir `date +%y%m%d` tar cfvz /tmp/bak.`date +%y%m%d`.tar.gz /etc YmdHM代表年月日时分,可以通过date --hlep查看哪些字母代表什么注意:`这个符号是键盘上~,而不是'。
重要说明点:那个日期$(date +%Y%m%d)的date命令和后边的日期格式的+号之前有一个空格。直接连写生成不了日期。
2. 完全备份:
[root@cephclient data]# mysqldump -uroot -p --all-databases --flush-logs --single-transaction --master-data=2 --log-error=/data/full_backup_log`date +%y%m%d%H%M`.log > /data/full_backu`date +%y%m%d%H%M`.sqlEnter password:[root@cephclient data]# lsfull_backu2102210219.sql full_backup_log2102210219.log
vim full_backu2102210219.sql-- CHANGE MASTER TO MASTER_LOG_FILE='binlog.000019', MASTER_LOG_POS=155;备份文件里记录了二进制日志的位置。
3. 增量数据:
mysql> create table 999test as select * from slave_master_info;Query OK, 0 rows affected (0.12 sec)Records: 0 Duplicates: 0 Warnings: 0
4. 检查此时的二进制日志的位置:从备份文件里边记录的位置到我们此时的位置,即为增量的部分。
mysql> show master status;+---------------+----------+--------------+------------------+-------------------+| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |+---------------+----------+--------------+------------------+-------------------+| binlog.000019 | 3956 | | | |+---------------+----------+--------------+------------------+-------------------+1 row in set (0.00 sec)
5. 增量备份:[root@docker-test ~]# mysqlbinlog --start-position=155 --stop-position=3956 /var/lib/mysql/binlog.000019 > /data/incremental_backup`date +%y%m%d%H%M`.sql

逻辑恢复(恢复到另外一个数据库)===========================
1. 检查数据库当前数据:
mysql> use mysqlReading table information for completion of table and column namesYou can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;+---------------------------+| Tables_in_mysql |+---------------------------+| 123test || aaa || columns_priv || component || db || default_roles || engine_cost || func || general_log || global_grants || gtid_executed || help_category || help_keyword || help_relation || help_topic || innodb_index_stats || innodb_table_stats || ndb_binlog_index || newtest || password_history || plugin || procs_priv || proxies_priv || role_edges                |                 || server_cost || servers || slave_master_info || slave_relay_log_info || slave_worker_info || slow_log || tables_priv || test || test123 || time_zone || time_zone_leap_second || time_zone_name || time_zone_transition || time_zone_transition_type || user |+---------------------------+39 rows in set (0.00 sec)
2. 获取数据库备份:
[root@docker-test mysqldump]# scp 192.168.189.77:/data/* ./root@192.168.189.77's password:full_backu2102210222.sql 100% 1012KB 18.8MB/s 00:00full_backup_log2102210222.log 100% 0 0.0KB/s 00:00incremental_backup2102210231.sql                                                                                                                      100% 5749     2.1MB/s   00:00                                                                                                                  100% 5749     4.1MB/s   00:00[root@docker-test mysqldump]# lsfull_backu2102210222.sql  full_backup_log2102210222.log  incremental_backup2102210231.sql[root@docker-test mysqldump]#
3. 首先恢复完全备份文件:
[root@docker-test mysqldump]# mysql -uroot -p < full_backu2102210222.sqlEnter password:
mysql> show tables;+---------------------------+| Tables_in_mysql |+---------------------------+| 123test || aaa || columns_priv || component || db || default_roles || engine_cost || func || general_log || global_grants || gtid_executed || help_category || help_keyword || help_relation || help_topic || innodb_index_stats || innodb_table_stats || ndb_binlog_index || newtest || password_history || plugin || procs_priv || proxies_priv || role_edges || rsun_test || server_cost || servers || slave_master_info || slave_relay_log_info || slave_worker_info || slow_log || tables_priv || test || test123 || time_zone || time_zone_leap_second || time_zone_name || time_zone_transition || time_zone_transition_type || user |+---------------------------+40 rows in set (0.00 sec)
4. 然后恢复增量备份文件:
[root@docker-test mysqldump]# mysql -uroot -p < incremental_backup2102210231.sqlEnter password:
mysql> use mysql;Reading table information for completion of table and column namesYou can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;+---------------------------+| Tables_in_mysql |+---------------------------+| 123test || 999test || aaa || columns_priv || component || db || default_roles || engine_cost || func || general_log || global_grants || gtid_executed || help_category || help_keyword || help_relation || help_topic || innodb_index_stats || innodb_table_stats || ndb_binlog_index || newtest || password_history || plugin || procs_priv || proxies_priv || role_edges || rsun_test || server_cost || servers || slave_master_info || slave_relay_log_info || slave_worker_info || slow_log || tables_priv || test || test123 || time_zone || time_zone_leap_second || time_zone_name || time_zone_transition || time_zone_transition_type || user |+---------------------------+40 rows in set (0.00 sec)



物理备份恢复示例
物理备份========
1. 完全关闭数据库:
mysql> shutdown;Query OK, 0 rows affected (0.06 sec)
# systemctl stop mysqld
2. 在文件系统层级备份数据库所有文件:
# tar -cf mysql.tar /var/lib/mysql/*

物理恢复(恢复到另外一台机器)===========================
1. 获取物理备份文件:
[root@docker-test lib]# scp 192.168.189.77:/var/lib/mysql.tar /var/lib/root@192.168.189.77's password:mysql.tar 100% 154MB 33.6MB/s 00:04
2. 恢复物理备份文件到/var/lib/mysql文件夹:
[root@docker-test lib]# tar xfv mysql.tar
[root@docker-test lib]# chown mysql mysqlor[root@docker-test lib]# sudo mysql tar xfv mysql.tar
3. 启动数据库:
[root@docker-test lib]# systemctl start mysqld[root@docker-test lib]# systemctl status mysqld● mysqld.service - MySQL Server Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor prese t: disabled) Active: active (running) since Sun 2021-02-21 03:00:51 EST; 2s ago Docs: man:mysqld(8) http://dev.mysql.com/doc/refman/en/using-systemd.html Process: 46778 ExecStartPre=/usr/bin/mysqld_pre_systemd (code=exited, status=0 /SUCCESS) Main PID: 46807 (mysqld) Status: "Server is operational" Tasks: 39 Memory: 398.3M CGroup: /system.slice/mysqld.service └─46807 /usr/sbin/mysqld
Feb 21 03:00:46 docker-test systemd[1]: Starting MySQL Server...Feb 21 03:00:51 docker-test systemd[1]: Started MySQL Server.[root@docker-test lib]#
4. 验证数据库恢复:
mysql> select * from rsun_test;+------------------------------+------------+---------------------+---------+---------------+| cost_name | cost_value | last_update | comment | default_value |+------------------------------+------------+---------------------+---------+---------------+| disk_temptable_create_cost | NULL | 2021-02-17 22:30:23 | NULL | 20 || disk_temptable_row_cost | NULL | 2021-02-17 22:30:23 | NULL | 0.5 || key_compare_cost | NULL | 2021-02-17 22:30:23 | NULL | 0.05 || memory_temptable_create_cost | NULL | 2021-02-17 22:30:23 | NULL | 1 || memory_temptable_row_cost | NULL | 2021-02-17 22:30:23 | NULL | 0.1 || row_evaluate_cost | NULL | 2021-02-17 22:30:23 | NULL | 0.1 || disk_temptable_create_cost | NULL | 2021-02-17 22:30:23 | NULL | 20 || disk_temptable_row_cost | NULL | 2021-02-17 22:30:23 | NULL | 0.5 || key_compare_cost | NULL | 2021-02-17 22:30:23 | NULL | 0.05 || memory_temptable_create_cost | NULL | 2021-02-17 22:30:23 | NULL | 1 || memory_temptable_row_cost | NULL | 2021-02-17 22:30:23 | NULL | 0.1 || row_evaluate_cost | NULL | 2021-02-17 22:30:23 | NULL | 0.1 || disk_temptable_create_cost | NULL | 2021-02-17 22:30:23 | NULL | 20 || disk_temptable_row_cost | NULL | 2021-02-17 22:30:23 | NULL | 0.5 || key_compare_cost | NULL | 2021-02-17 22:30:23 | NULL | 0.05 || memory_temptable_create_cost | NULL | 2021-02-17 22:30:23 | NULL | 1 || memory_temptable_row_cost | NULL | 2021-02-17 22:30:23 | NULL | 0.1 || row_evaluate_cost | NULL | 2021-02-17 22:30:23 | NULL | 0.1 || disk_temptable_create_cost | NULL | 2021-02-17 22:30:23 | NULL | 20 || disk_temptable_row_cost | NULL | 2021-02-17 22:30:23 | NULL | 0.5 || key_compare_cost | NULL | 2021-02-17 22:30:23 | NULL | 0.05 || memory_temptable_create_cost | NULL | 2021-02-17 22:30:23 | NULL | 1 || memory_temptable_row_cost | NULL | 2021-02-17 22:30:23 | NULL | 0.1 || row_evaluate_cost | NULL | 2021-02-17 22:30:23 | NULL | 0.1 |+------------------------------+------------+---------------------+---------+---------------+24 rows in set (0.00 sec)



附:官方文档


This section discusses a procedure for performing backups that enables you to recover data after several types of crashes:

  • Operating system crash

  • Power failure

  • File system crash

  • Hardware problem (hard drive, motherboard, and so forth)

The example commands do not include options such as --user and --password for the mysqldump and mysql client programs. You should include such options as necessary to enable client programs to connect to the MySQL server.

Assume that data is stored in the InnoDB storage engine, which has support for transactions and automatic crash recovery. Assume also that the MySQL server is under load at the time of the crash. If it were not, no recovery would ever be needed.

For cases of operating system crashes or power failures, we can assume that MySQL's disk data is available after a restart. The InnoDB data files might not contain consistent data due to the crash, but InnoDB reads its logs and finds in them the list of pending committed and noncommitted transactions that have not been flushed to the data files. InnoDB automatically rolls back those transactions that were not committed, and flushes to its data files those that were committed. Information about this recovery process is conveyed to the user through the MySQL error log. The following is an example log excerpt:

InnoDB: Database was not shut down normally.
InnoDB: Starting recovery from log files...
InnoDB: Starting log scan based on checkpoint at
InnoDB: log sequence number 0 13674004
InnoDB: Doing recovery: scanned up to log sequence number 0 13739520
InnoDB: Doing recovery: scanned up to log sequence number 0 13805056
InnoDB: Doing recovery: scanned up to log sequence number 0 13870592
InnoDB: Doing recovery: scanned up to log sequence number 0 13936128
...
InnoDB: Doing recovery: scanned up to log sequence number 0 20555264
InnoDB: Doing recovery: scanned up to log sequence number 0 20620800
InnoDB: Doing recovery: scanned up to log sequence number 0 20664692
InnoDB: 1 uncommitted transaction(s) which must be rolled back
InnoDB: Starting rollback of uncommitted transactions
InnoDB: Rolling back trx no 16745
InnoDB: Rolling back of trx no 16745 completed
InnoDB: Rollback of uncommitted transactions completed
InnoDB: Starting an apply batch of log records to the database...
InnoDB: Apply batch completed
InnoDB: Started
mysqld: ready for connections


Establishing a Backup Policy

To be useful, backups must be scheduled regularly. A full backup (a snapshot of the data at a point in time) can be done in MySQL with several tools. For example, MySQL Enterprise Backup can perform a physical backup of an entire instance, with optimizations to minimize overhead and avoid disruption when backing up InnoDB data files; mysqldump provides online logical backup. This discussion uses mysqldump.

Assume that we make a full backup of all our InnoDB tables in all databases using the following command on Sunday at 1 p.m., when load is low:

shell> mysqldump --all-databases --master-data --single-transaction > backup_sunday_1_PM.sql

The resulting .sql file produced by mysqldump contains a set of SQL INSERT statements that can be used to reload the dumped tables at a later time.

This backup operation acquires a global read lock on all tables at the beginning of the dump (using FLUSH TABLES WITH READ LOCK). As soon as this lock has been acquired, the binary log coordinates are read and the lock is released. If long updating statements are running when the FLUSH statement is issued, the backup operation may stall until those statements finish. After that, the dump becomes lock-free and does not disturb reads and writes on the tables.

It was assumed earlier that the tables to back up are InnoDB tables, so --single-transaction uses a consistent read and guarantees that data seen by mysqldump does not change. (Changes made by other clients to InnoDB tables are not seen by the mysqldump process.) If the backup operation includes non transactional tables, consistency requires that they do not change during the backup. For example, for the MyISAM tables in the mysql database, there must be no administrative changes to MySQL accounts during the backup.

Full backups are necessary, but it is not always convenient to create them. They produce large backup files and take time to generate. They are not optimal in the sense that each successive full backup includes all data, even that part that has not changed since the previous full backup. It is more efficient to make an initial full backup, and then to make incremental backups. The incremental backups are smaller and take less time to produce. The tradeoff is that, at recovery time, you cannot restore your data just by reloading the full backup. You must also process the incremental backups to recover the incremental changes.

To make incremental backups, we need to save the incremental changes. In MySQL, these changes are represented in the binary log, so the MySQL server should always be started with the --log-bin option to enable that log. With binary logging enabled, the server writes each data change into a file while it updates data. Looking at the data directory of a MySQL server that has been running for some days, we find these MySQL binary log files:

-rw-rw---- 1 guilhem  guilhem   1277324 Nov 10 23:59 gbichot2-bin.000001
-rw-rw---- 1 guilhem guilhem 4 Nov 10 23:59 gbichot2-bin.000002
-rw-rw---- 1 guilhem guilhem 79 Nov 11 11:06 gbichot2-bin.000003
-rw-rw---- 1 guilhem guilhem 508 Nov 11 11:08 gbichot2-bin.000004
-rw-rw---- 1 guilhem guilhem 220047446 Nov 12 16:47 gbichot2-bin.000005
-rw-rw---- 1 guilhem guilhem 998412 Nov 14 10:08 gbichot2-bin.000006
-rw-rw---- 1 guilhem guilhem 361 Nov 14 10:07 gbichot2-bin.index

Each time it restarts, the MySQL server creates a new binary log file using the next number in the sequence. While the server is running, you can also tell it to close the current binary log file and begin a new one manually by issuing a FLUSH LOGS SQL statement or with a mysqladmin flush-logs command. mysqldump also has an option to flush the logs. The .index file in the data directory contains the list of all MySQL binary logs in the directory.

The MySQL binary logs are important for recovery because they form the set of incremental backups. If you make sure to flush the logs when you make your full backup, the binary log files created afterward contain all the data changes made since the backup. Let's modify the previous mysqldump command a bit so that it flushes the MySQL binary logs at the moment of the full backup, and so that the dump file contains the name of the new current binary log:

shell> mysqldump --single-transaction --flush-logs --master-data=2 \
--all-databases > backup_sunday_1_PM.sql

After executing this command, the data directory contains a new binary log file, gbichot2-bin.000007, because the --flush-logs option causes the server to flush its logs. The --master-data option causes mysqldump to write binary log information to its output, so the resulting .sql dump file includes these lines:

-- Position to start replication or point-in-time recovery from
-- CHANGE MASTER TO MASTER_LOG_FILE='gbichot2-bin.000007',MASTER_LOG_POS=4;

Because the mysqldump command made a full backup, those lines mean two things:

  • The dump file contains all changes made before any changes written to the gbichot2-bin.000007 binary log file or higher.

  • All data changes logged after the backup are not present in the dump file, but are present in the gbichot2-bin.000007 binary log file or higher.

On Monday at 1 p.m., we can create an incremental backup by flushing the logs to begin a new binary log file. For example, executing a mysqladmin flush-logs command creates gbichot2-bin.000008. All changes between the Sunday 1 p.m. full backup and Monday 1 p.m. are written in gbichot2-bin.000007. This incremental backup is important, so it is a good idea to copy it to a safe place. (For example, back it up on tape or DVD, or copy it to another machine.) On Tuesday at 1 p.m., execute another mysqladmin flush-logs command. All changes between Monday 1 p.m. and Tuesday 1 p.m. are written in gbichot2-bin.000008 (which also should be copied somewhere safe).

The MySQL binary logs take up disk space. To free up space, purge them from time to time. One way to do this is by deleting the binary logs that are no longer needed, such as when we make a full backup:

shell> mysqldump --single-transaction --flush-logs --master-data=2 \
--all-databases --delete-master-logs > backup_sunday_1_PM.sql


Note:

Deleting the MySQL binary logs with mysqldump --delete-master-logs can be dangerous if your server is a replication source server, because replicas might not yet fully have processed the contents of the binary log. The description for the PURGE BINARY LOGS statement explains what should be verified before deleting the MySQL binary logs. See Section 13.4.1.1, “PURGE BINARY LOGS Statement”.


以上是关于MySQL备份恢复的主要内容,如果未能解决你的问题,请参考以下文章

mysql数据没有备份误删了怎么恢复

mysql数据没有备份误删了怎么恢复

mysql备份与恢复

MySQL基于mysqldump及lvmsnapshot备份恢复

MySQL数据库 数据备份与恢复

MySQL备份恢复