1)物理备份:对数据库操作系统的物理文件(如数据文件、日志文件等)的备份。
冷备份(脱机备份) :是在关闭数据库的时候进行的
热备份(联机备份) :数据库处于运行状态,依赖于数据库的日志文件
温备份:数据库锁定表格(不可写入但可读)的状态下进行备份操作
2)逻辑备份
逻辑备份:对数据库逻辑组件(如:表等数据库对象)的备份。
即以sql语句的形式,把库、表结构、表数据保存下来。
3)数据库的备份策略
完全备份(全量备份):每次对数据库进行完整的备份。
差异备份:备份自从上次完全备份之后被修改过的文件。
增量备份:只有在上次完全备份或者增量备份后被修改的文件才会被备份。
1)物理冷备: (完全备份)
备份时数据库处于关闭状态,直接打包数据库文件。
至少包括 data 目录,my.cnf,binlog 一般都放在 data 目录中。所以在 mysql 安装时规划好目录,利于后期备份,迁移,升级等操作。
备份速度快,恢复时也是最简单的
2)专用备份工具mydump或mysqlhotcopy (完全备份,逻辑备份)
mysqldump常用的逻辑备份工具 (导出为sql脚本)
mysqlhotcopy仅拥有备份MyISAM和ARCHIVE表
3)启用二进制日志进行增量备份 (增量备份)
进行增量备份,需要刷新二进制日志
4)第三方工具备份
免费的MySQL热备份软件 Percona XtraBackup;阿里云的工具 dts,支持热迁移;ogg;Pentaho(习惯称为Kettle);Canal;percona-toolkit 等
mysqldump是常用的逻辑备份工具。
mysqldump可以将指定的库、表导出为SQL脚本。
mysqldump 的备份流程大致如下:
==对某个库下所有表加读锁;==刷新 binlog 日志;
备份表数据;
释放读锁;
循环上面三个步骤;直到备份完毕。
由于 mysqldump 备份流程对每个库加锁进行导出的循环方式,所以并不能保证各库之间的数据一致性。要保证完整的数据一致性使用–lock-all-tables参数,在备份开始时会对 mysql 加全局读锁,直至整个备份结束。但此种方式对于PXC或业务连续性高的场景不适用。对于mysqldump 方式数据一致性细化要求,需要了解**—lock-all-tables;—single-transaction;—lock-tables**三个参数。一般情况下–single-transaction 参数,通过将导出行为放入一个事务执行,从而可以在保证数据一致性情况下,不影响业务导出数据。–single-transaction 只能用在 innodb 引擎,导出过程中不能有任何人执行 alter table,drop table,rename table,truncate table 等 DDL 语句。DDL 语句会被导出事务的 metadata lock 阻塞。参见 myusqldump 常用参数。
mysqldump导出数据是备份开始时的数据,而非备份结束时的数据。
mysqldump -uroot -p[密码] --databases 库名1 [库名2].. >/备份路径/备份文件名.sql
mysqldump -uroot -p[密码] --all-databases > /备份路径/备份文件名.sql
mysqldump -uroot -p --all-databases --routines > ymt`date +'%Y%m%d%H'`.sql
备份出来的文件就是文本的 sql 语句,可以直接查看。
可按全库恢复,单独库恢复,表恢复
##删除数据库yuji##
mysql -u root -p -e 'drop database yuji;'
#"-e"选项,用于指定连接MySQL后执行的命令,命令执行完后自动退出
mysql -u root -p -e 'SHOW DATABASES;' #查看当前有哪些数据库
##恢复全部数据库##
mysql -uroot -p < ymt2022082308.sql
##恢复数据库yuji##
mysql -u root -p < /work/mysql_bak/ymt2022082308.sql #重定向输入库文件
mysql -u root -p -e 'SHOW DATABASES;' #查看当前有哪些数据库
##备份yuji库中的class表##
mysqldump -uroot -p yuji class > /work/mysql_bak/ymt_class.sql
##删除yuji库中的class表##
mysql -u root -p -e 'drop table yuji.class;'
mysql -u root -p -e 'show tables from yuji;' #查看yuji库中的表,已无class表
##恢复yuji库中的class表##
mysql -u root -p yuji < /work/mysql_bak/ymt_class.sql #重定向导入备份文件,必须指定库名,且目标库必须存在
mysql -u root -p -e 'show tables from yuji;'
异机恢复只需初始化一个空库,并启动 mysql服务
初始化一个空库:
./bin/mysqld --initialize --user=mysql --datadir=/work/mysql/data --basedir=/work/mysql
启动数据库,查初始密码
grep 'temporary password' /var/log/mysqld.log
修改初始密码
mysql -u root -p
ALTER USER 'root'@'localhost' IDENTIFIED BY '1qaz!QAZ';
flush privileges;
全库备份时通过查看备份文件,包括用户数据库外还包含 mysql 库。
PXC 集群环境下使用 mysqldump 备份有些特殊,要加入这三个参数:–skip_add_locks --skip-lock-tables --set-gtid-purged=OFF
GTID是MySQL5.6以后,加入了全局事务 ID (GTID) 来强化数据库的主备一致性,故障恢复,以及容错能力。所以可能是因为在一个数据库里面唯一,但是当导入其他的库就有可能重复。如果进行mysqldump时,没有使用–set-gtid-purged=OFF参数,备份出来的SQL就会出现SET @@GLOBAL.GTID_PURGED='4e53cb9a-fa5e-ee17-6889-8815f2fe1df6:1-54398’的情况,1-54398这个的区间是主库中当前所完成的所有事务号。这条语句在备份被恢复的时候,起到的作用是:不再从主库同步1-54398 这个范围内的事务了。
–set-gtid-purged=OFF 不导出 gtid 号
–skip_add_locks 导出文件中,不在每个表之前增加 lock tables 并且在之后 unlock tables 语句。
–skip-lock-tables 导出过程中不锁表
参考语句:
# mysqldump -uroot -p --all-databases --set-gtid-purged=OFF --skip_add_locks --master-data --single-transaction --triggers --routines > ymt`date +'%Y%m%d%H'`.sql
--all-databases , -A
导出全部数据库。
mysqldump -uroot -p --all-databases
--databases, -B
导出几个数据库。参数后面所有名字参量都被看作数据库名。
mysqldump -uroot -p --databases test mysql
--flush-logs, -F
开始导出之前刷新日志。
请注意:假如一次导出多个数据库(使用选项--databases或者--all-databases),将会逐个数据库刷新日志。除使用--lock-all-tables或者--master-data外。在这种情况下,日志将会被刷新一次,相应的所有表同时被锁定。因此,如果打算同时导出和刷新日志应该使用--lock-all-tables 或者--master-data 和--flush-logs。
mysqldump -uroot -p --all-databases --flush-logs
--ignore-table
不导出指定表。指定忽略多个表时,需要重复多次,每次一个表。每个表必须同时指定数据库和表名。例如:--ignore-table=database.table1 --ignore-table=database.table2 ……
mysqldump -uroot -p --host=localhost --all-databases --ignore-table=mysql.user
--lock-all-tables, -x
提交请求锁定所有数据库中的所有表,以保证数据的一致性。这是一个全局读锁,并且自动关闭--single-transaction 和--lock-tables 选项。
mysqldump -uroot -p --host=localhost --all-databases --lock-all-tables
--lock-tables, -l
开始导出前,锁定所有表。用READ LOCAL锁定表以允许MyISAM表并行插入。对于支持事务的表例如InnoDB和BDB,--single-transaction是一个更好的选择,因为它根本不需要锁定表。
请注意当导出多个数据库时,--lock-tables分别为每个数据库锁定表。因此,该选项不能保证导出文件中的表在数据库之间的逻辑一致性。不同数据库表的导出状态可以完全不同,默认为 on。
mysqldump -uroot -p --host=localhost --all-databases --lock-tables
--single-transaction
该选项在导出数据之前提交一个BEGIN SQL语句,BEGIN 不会阻塞任何应用程序且能保证导出时数据库的一致性状态。它只适用于多版本存储引擎,仅InnoDB。本选项和--lock-tables 选项是互斥的,因为LOCK TABLES 会使任何挂起的事务隐含提交。要想导出大表的话,应结合使用--quick 选项。
mysqldump -uroot -p --host=localhost --all-databases --single-transaction
--log-error
附加警告和错误信息到给定文件
mysqldump -uroot -p --host=localhost --all-databases --log-error=/tmp/mysqldump_error_log.err
--master-data
该选项将binlog的位置和文件名追加到输出文件中。如果等于1,则将其打印为CHANGE MASTER命令; 如果等于2,那么该命令将以注释符号为前缀。该选项将打开--lock-all-tables 选项,除非--single-transaction也被指定(在这种情况下,全局读锁在开始导出时获得很短的时间;其他内容参考下面的--single-transaction选项)。该选项自动关闭--lock-tables选项。
mysqldump -uroot -p --host=localhost --all-databases --master-data=1;
mysqldump -uroot -p --host=localhost --all-databases --master-data=2;
--triggers
导出触发器。该选项默认启用,用--skip-triggers禁用它。
mysqldump -uroot -p --host=localhost --all-databases --triggers
--routines, -R
备份存储过程和函数数据
二进制日志保存了所有更新或者可能更新数据库的操作
二进制日志在启动MySQL服务后开始记录,并在文件达到 max_binlog_size所设置的大小或者接收到 mysql> flush logs; 命令后重新创建新的日志文件
只需定时执行flush logs方法重新创建新的日志,生成二进制文件序列,并及时把这些日志保存到安全的地方就完成了一个时间段的增量备份。
Binlog日志需要在 my.cnf 中单独配置开启,一般来说开启binlog日志大概会有1%的性能损耗。
设置binlog文件保存事件,过期删除,单位天 set global expire_log_days=3;
一般恢复:将所有备份的二进制日志内容全部恢复
基于位置恢复:数据库在某一时间点可能既有错误的操作也有正确的操作,可以基于精准的位置跳过错误的操作
基于时间点恢复:跳过某个发生错误的时间点实现数据恢复
–start-datetime:从二进制日志中读取指定等于时间戳或者晚于本地计算机的时间
–stop-datetime:从二进制日志中读取指定小于时间戳或者等于本地计算机的时间 取值和上述一样
–start-position:从二进制日志中读取指定position 事件位置作为开始。
–stop-position:从二进制日志中读取指定position 事件位置作为事件截至
##查看是否开启 binlog及 binlog 位置##
show variables like '%log_bin%';
##查看所有binlog日志文件列表##
show master logs;
##查看当前 binlog 使用情况##
show master status;
##查看指定 binlog 文件内容信息##
show binlog events;
show binlog events in 'mysql-bin.000001';
##全部清空 binlog 文件##
reset master;
本机恢复:适用误操作,误删除场景
登录mysql 查看文件 binlog6 :
show binlog events in ‘mysql-bin.000006’,
通过查看日志要恢复的开始 pos 点和结束 pos 点,执行命令如下:
/work/mysql/bin/mysqlbinlog --start-position=430 --stop-position=435 --database=hello /var/lib/mysql/mysql-bin.000006 | /usr/bin/mysql -uroot -p密码 -v hello
其中整个命令的含义是通过mysqlbinlog读取日志内容并通过管道传给mysql命令。
恢复开始点、结束点跨 binlog 时需要把所有 binlog 文件都写上。
为了防止干扰在恢复操作前,执行 flush logs,产生一个新的 binlog 文件。如果删除表或者库,直接恢复时需提前建出要恢复的表或者库。
恢复的顺序:
正常的恢复是先恢复全备,然后恢复增量;恢复 mysqldump 备份
mysql -uroot -p < ymt2022082308.sql
把源库的 binlog 日志拷贝到本地 /bak 目录下
查看二进制日志文件的内容
mysqlbinlog --no-defaults --base64-output=decode-rows -v /bak/mysql-bin.000002
从指定时间点恢复:
mysqlbinlog --no-defaults --start-position='219' mysql-bin.000004 mysql-bin.000005|mysql -u root -p
mysqlbinlog --no-defaults --start-position='位置点' 文件名 | mysql -u root -p
#从某一个位置点开始恢复,一直到日志结尾
mysqlbinlog --no-defaults --stop-position='位置点' 文件名 | mysql -u root -p
#从日志开头,一直恢复到某一个位置点前结束
mysqlbinlog --no-defaults --start-position='xxx'--stop-position='位置点' 文件名 | mysql -u root -p
#从某一个位置点开始恢复,一直到某一个位置点前结束
"--no-defaults"选项:在Mysql5.5以下版本使用mysqlbinlog命令时如果报错,就加上
Xtrabackup是一个对InnoDB做数据备份的工具,支持在线热备份(备份时不影响数据读写),是商业备份工具InnoDB Hotbackup的一个很好的替代品。
Xtrabackup有两个主要的工具:xtrabackup、innobackupex
(1)xtrabackup只能备份InnoDB和XtraDB两种数据表,而不能备份MyISAM数据表
(2)innobackupex-1.5.1则封装了xtrabackup,是一个脚本封装,所以能同时备份处理innodb和myisam,但在处理myisam时需要加一个读锁
一般使用的是innobackupex脚本。XtraBackup8.0以后移除innobackupex,整合为xtrabackup。
XtraBackup8.0 不支持备份 Mysql8.0之前版本的数据库,mysql8以前的版本需使用 XtraBackup 2.4 备份恢复。XtraBackup 8.0-8.0.11不支持MySQL 8.0.20以上版本的 Msyql 、Percona Server for MySQL 和 Percona XtraDB Cluster。
命令格式:
innobackupex [参数] [目的地址] [源地址]
常用参数:
--user # 以什么用于身份进行操作
--password # 数据库用户的密码
--port # 数据库的端口号,默认3306
--stream # 打包(数据流)
--defaults-file # 指定默认配置文件,默认读取/etc/my.cnf
--no-timestamp # 不创建时间戳文件,而改用目的地址(可以自动创建)
--copy-back # 备份还原的主要选项
--incremental # 使用增量备份,默认使用的完整备份
--incremental-basedir # 与--incremental选项联合使用,该参数指定上一级备份的地址来做增量备份
使用单独的备份用户(可选):
mysql> CREATE USER 'bkpuser'@'localhost' IDENTIFIED BY 's3cr%T';
mysql> GRANT BACKUP_ADMIN, PROCESS, RELOAD, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'bkpuser'@'localhost';
mysql> GRANT SELECT ON performance_schema.log_status TO 'bkpuser'@'localhost';
mysql> GRANT SELECT ON performance_schema.keyring_component_status TO bkpuser@'localhost'
mysql> FLUSH PRIVILEGES;
innobackupex --user=root --password='1qaz!QAZ' /work/mysqlbackup/
# systemctl stop mysqld
# rm -rf /work/mysql/data/* # 危险操作,请在测试环境测试
# innobackupex --copy-back /work/mysqlbackup/2022-08-29_01-06-13/
# chown -R mysql:mysql /work/mysql/data
# innobackupex --user=root --password='1qaz!QAZ' --incremental /work/mysqlbackup/ --incremental-basedir=/work/mysqlbackup/2022-08-29_01-06-13/ # 创建增量备份
4.1)把全量备份进行一次apply
# innobackupex --apply-log --redo-only /work/mysqlbackup/2022-08-29_01-06-13/
4.2)应用第一次增量备份到全量备份(把全量备份跟增量备份进行一个结合)
# innobackupex --apply-log --redo-only /work/mysqlbackup/2022-08-29_01-06-13/ --incremental-dir=/work/mysqlbackup/2022-08-29_01-09-54
如果有多个增量则按增量顺序,多次执行合并。
4.3)查看全量备份xtrabackup_checkpoints
# cat 2022-08-29_01-06-13/xtrabackup_checkpoints
backup_type = log-applied
from_lsn = 0
to_lsn = 8032865
last_lsn = 8032874
compact = 0
recover_binlog_info = 0
flushed_lsn = 8032874
# cat 2022-08-29_01-09-54/xtrabackup_checkpoints
backup_type = incremental
from_lsn = 7765038
to_lsn = 8032865
last_lsn = 8032874
compact = 0
recover_binlog_info = 0
flushed_lsn = 8032874
在应用增量备份成功后全量备份与增量备份的 last_lsn 值相同
4.4)停止mysqld服务并移除数据目录(生产环境建议用mv)
# systemctl stop mysqld
# rm -rf /work/mysql/data
4.5)使用–copy-back参数恢复拷贝到data目录(合并的全备目录)
# innobackupex --copy-back /work/mysqlbackup/2022-08-29_01-06-13
4.6)验证数据还原
# ls /work/mysql/data
查看还原的表文件等是否全
4.7)授权并启用MySQL
如果操作 innobackupex 的用户为 root,则还原的 data 目录及文件权限为root。需要修改成 mysql 用户。
# chown -R mysql:mysql /work/mysql/data
至此恢复完成可启动数据库
# systemctl start mysql
# mysql -uroot -p
几个 mysql 文件解释:
ibdata文件:存放InnoDB表(InnoDB数据字典)元数据、undo logs、the change buffer, and the doublewrite buffer
独享表空间存储方式使用“.ibd”文件来存放数据,且每个表一个“.ibd”文件,文件存放在和MyISAM 数据相同的位置;共享存储表空间来存放数据,则会使用ibdata 文件来存放,所有表共同使用一个(或者多个,可自行配)ibdata 文件。
frm文件:表结构,数据词典信息
ibd 文件:innodb 的表数据
在有建表语句的情况下,使用idb
文件恢复数据,相比使用frm
文件恢复表数据要简单方便很多
如果 mysql 启动不了
在 my.cnf 文件增加 innodb_force_recovery=6,启动数据库,在关闭数据库,去掉这个参数,后数据库正常启动。
删除当前的ibd
文件
use test;
alter table study discard tablespace;
将之前备份的 study.ibd 文件复制到对应的数据目录下,使用下面的命令将数据加载到MySQL数据库里
注意替换文件后的study.ibd
文件的权限,确保和其他文件的属主和属组是一样的
alter table study import tablespace;
再次查看数据表,发现之前的数据也回来了
select * from study;
+------+------+------+----------+---------+
| id | name | age | time | lang |
+------+------+------+----------+---------+
| 1 | tom | 26 | 20211024 | chinese |
+------+------+------+----------+---------+
参考文件:
InnoDB引擎ibdata文件损坏/删除后使用frm和ibd文件恢复数据
手动恢复frm文件
MySQL 利用frm文件和ibd文件恢复表结构和表数据
记一次 ibdata1
误删后的恢复过程
同步方案很多