MySQL备份意义
备份是消耗成本的,并不能带来更多客户,也不能节省成本,也不能促进业务更好的发展,但是MySQL备份可以帮助DBA在数据损坏时给最后一个救命稻草。测试环境和开发环境,严格控制访问权限,尽量只给开发人员select update delete insert权限,至于alter、create权限,掌握在DBA手中。测试和开发环境,建议一天做一个mysqldump就行。
MySQL冷备
数据库冷备份:把数据库关掉,系统级别的文件copy,备份时建议把配置文件(/etc/my.cnf)也备份一下。
MySQL热备
数据库热备份:数据库不停的情况下进行备份。不影响业务的使用。又分为:
1、逻辑备份,mysqldump(单线程),mydumper(第三方公司percona),mysqlpump(5.7才有,多线程并行备份,并不成熟)
2、裸文件备份,基于datafile Copy的备份(物理文件copy:percona公司提供的Xtrabackup工具,为了增量备份。另一个:MySQL Enterprise Backup官方,基本上不用)
一般情况下,数据量小时用mysqldump全备,500G以上使用Xtrabackup备份。数据量150 - 200G,使用mysqldump进行备份,时间大概一个小时,恢复时间大概是备份的2倍。
按照备份内容分为:
1、全量备份:整个数据库备份
2、增量备份:Log seq number向量
DBA在执行开发人员的sql语句更新或者删除某些数据之前,建议使用mysqldump进行备份,以防止误删除或者误更新:
[root@localhost ~]# mysqldump --single-transaction -uroot -proot test sbtest > /u01/databak/t_20210423_0900.sql
Warning: Using a password on the command line interface can be insecure.
-- --single-transaction该参数是备份时必加的一个参数,是配合RR隔离级别使用的
数据库中有一个参数:
mysql> show variables like ‘%sql_safe%‘;
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| sql_safe_updates | OFF |
+------------------+-------+
1 row in set (0.00 sec)
该参数作用是:数据安全模式,即没有where条件的update、delete语句不能执行,建议生产环境开启。
示例:
mysql> show variables like ‘%sql_safe%‘;
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| sql_safe_updates | OFF |
+------------------+-------+
1 row in set (0.00 sec)
mysql> set global sql_safe_updates=1;
Query OK, 0 rows affected (0.00 sec)
mysql> set session sql_safe_updates=1;
Query OK, 0 rows affected (0.00 sec)
mysql> show variables like ‘%sql_safe%‘;
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| sql_safe_updates | ON |
+------------------+-------+
1 row in set (0.00 sec)
mysql> delete from t;
ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
mysql> update t set id=0;
ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
mysqldump如何保证数据一致性:
--single-transaction:该参数是备份时必加的一个参数,是配合RR隔离级别使用的,可以保证数据一致性。
-opt :默认自带,锁表功能,保证数据一致性,该参数基本上不用添加。
-q:quick,数据不回内存,直接备份。
备份需要权限:select, show view, trigger, lock tables;
对于sql层的备份,都通过SQL和SERVER交互的,可以打开全量日志(general log)。
mysqldump备份流程:从数据文件读取数据到内存中,再转存到操作系统平面文件中。
mysqldump备份操作后可能出现性能抖动,就是因为mysqldump备份时,把内存中的热块冲掉,影响缓冲命中率。通过以下两个参数解决:
mysql> show variables like ‘%at_shutdown%‘;
+-------------------------------------+-------+
| Variable_name | Value |
+-------------------------------------+-------+
| innodb_buffer_pool_dump_at_shutdown | OFF |
+-------------------------------------+-------+
1 row in set (0.01 sec)
mysql> show variables like ‘%at_startup%‘;
+------------------------------------+-------+
| Variable_name | Value |
+------------------------------------+-------+
| innodb_buffer_pool_load_at_startup | OFF |
+------------------------------------+-------+
1 row in set (0.00 sec)
这两个参数,生产环境中建议设置为on,作用是:快速加载热数据,快速从磁盘中将热数据加载到内存中。
MySQL5.6之后,mysqldump造成的性能抖动减少了,由于MySQL5.6之后多加了一个young buffer pool,作用是:新的数据先进入young buffer pool,一秒内又再一次访问了,这个数据才进入warm区域(热块区),这样就不会冲掉热块。
buffer pool到底缓存了什么数据:
MySQL 5.7之后,多了一个sys库,会记录缓存了哪些表,多少行数据。MySQL在innodb读取数据都需要经过buffer pool。
MySQL5.5之后,出现了meta lock。在mysqldump备份过程中,meta lock锁不允许执行DDL操作,保证数据的一致性。
在mysqldump备份过程中,整个数据库不影响DML操作,不影响对外服务。
在mysqldump备份时,数据库会自动开启一个快照:start transaction with consistent snapshot;
一个事务只会在一个binlog里面,不会跨binlog。
比如:binlog最大定义的是max_binlog_size=128M,但为什么会出现大小是1G或者2G的binlog文件?原因就是事务不会跨越binlog文件,一个大的事务在一个binlog中,可能会突破设定的大小。
mysqldump只备份一个表的部分数据:加where条件。
[root@localhost ~]# mysqldump --single-transaction -uroot -proot test t --where "id=1" > /u01/databak/1.sql
Warning: Using a password on the command line interface can be insecure.
--添加参数 --where,可以根据where条件筛选导出的数据
MySQL5.7,官方推出mysqlpump备份机制:
- 基于并发的备份
- 备份可以看到进度显示
- 最后再去创建普通索引
- 创建出来create user,grant
- 支持压缩备份lz4格式
但是无法在线搭建从库(master-data,dump-slave)
一些参数:
--default-parallelism=N 并行的线程数
--parallel-schemas=[N:]db_list DB级别并行
mydumper:并行还是比较好的,基于glibc框架2.0开发。
数据库备份时建议开一下增量日志general log。
meta data lock现象MySQL5.5才有,查看show processlist会看见waiting for table metadata lock;
xtrabackup备份原理
对于innodb,xtrabackup基于innodb的crash-recovery功能进行备份。
crash-recovery是这样的:innodb维护了一个redo log,又称为transaction log,也叫事务日志,它包含了innodb数据的所有改动情况。innodb启动时会先去检查datafile和事务日志,然后应用所有已提交的事务并回滚所有未提交的事务。
xtrabackup在备份时并不锁定表,而是一页一页的复制innodb的数据文件,于此同时,xtrabackup还有另外一个线程监视着事务日志, 一旦log发生变化,就把变化过的log pages复制走(因为事务日志文件大小有限,写满之后,就会重新写到另一个日志中)
xtrabackup采用了其内置的innodb库以read-write模式打开innodb的数据文件,然后每次读写1MB(1MB/16kb=64page)的数据,一页一页的遍历,同时用innodb的buf_page_is_corruoted()函数检查此页的数据是否正常,如果正常则进行复制。
由于xtrabackup其内置的innodb库打开文件的时候是rw的,所以运行xtrabackup的用户,必须对innodb的数据文件具有读写权限。
由于xtrabackup要从文件系统中复制大量的数据,所以它尽可能的使用posix_fadvise(),来告诉OS不要缓存读取到的数据(因为这些数据不会重用到了),从而提升性能。如果要缓存的话,大量的数据会对OS的虚拟内存造成很大的压力。
由于不锁表,所以复制出来的数据是不一致的,数据的一致性是在恢复的时候使用crash-recovery进行实现的。
对于myisam存储引擎的表,xtrabackup还是先锁定所有的表,然后复制所有文件。
增量备份的原理:
在完整备份和增量备份文件中都有一个文件xtrabackup_checkpoint会记录备份完成时检查点的LSN,在进行新的增量备份时,xtrabackup会比较表空间中每页的LSN是否大于上次备份完成的LSN,如果是,则备份该页,并记录当前检查点的LSN。