mysql备份工具有很多,但是常用的就两个,mysqldump、extrabackup
只要掌握这两个就够了!
在学习备份操作之前,先看看一个概念
数据库的一致性:
银行的数据库中有两个用户A和B,上午十点时,A用户的账户中有5万元,B用户账户中有10万元,目前数据是处在一个一致状态的,因为A和B用户发现自己手中的金钱数额是对的,上午11点时,B用户向A用户转账了三万元,转账完成后,A用户账户有8万元,B用户账户有7万元,此刻,又处于一个一致性状,虽然连个人的账户有数据变化,但这都是转账后的结果,从逻辑上讲,这是没问题的,上午12点,A用户取走了自己账户里的7万元,此时只剩下了B用户,此时数据库又处于一个一致状态,这就是数据库的一致性!
总结:数据库的一致性是指数据库从一个一致性状态转变到另一个一致性状态。
借用大佬丁奇的话来说,数据库一致性想要表达的是,数据库中的数据一直保持在一致状态,虽然数据可能变化,但是状态一直是一致的!
如何保证数据一致性?
方法一:
在备份的时候施加表锁,备份结束之前不能修改数据,不管备份时间多长,都能够保证被分开时的那一刻数据库中的数据是一致的,这样做的缺点很明显,就是一旦备份就不能对数据库进行写操作了!
方法二:
在备份开始的时候,对所有的数据进行一个快照,由于快照记录了备份开始时所有数据的样子,在这个快照范围内读取到的数据,也具有一致性,在mysql中,我们能够利用事务实现类似的快照功能,如果表使用的是innodb引擎,我们就能使用隔离性保证数据的一致性,通过前面的学习你可能想到,‘可重复读’就能在备份的场景中保证数据的一致性;
有人会发问:可重复读不是会出现‘幻读’的情况吗?
是的,但是在当前事务中不进行更新操作,就不会出现‘幻读’的情况,恰巧备份仅仅是读取数据,我们只要能够保证把所有的备份操作放在同一个单独的事务中,并且将这个事务的隔离级别设置为‘可重复读’,从而就保证了整个备份过程中,所有数据对于某个时间点来说,是一致的,从而保证了数据的一致性!
这里说到备份中的数据一致性需要依赖事务中的隔离性,且隔离性需要为‘可重复读’,但是这并不是一定要求mysql的当前隔离级别是‘可重复读’,因为mysqldump会自动把备份操作操作放入一下‘可重读’的事务里,即使当前默认的隔离级别不是‘可重读’。
以上就是mysql的一致性读(快照读)的内容。
mysqldump:
mysqldump是mysql自带的逻辑备份工具;
优点:可以使用文本工具直接处理对应的备份数据
缺点:当数据为浮点类型时,会出现精度丢失,速度较慢,当数据量大时,我们一般不采用mysqldump来备份!
mysqldump对innodb引擎支持热备,对MyISAM引擎支持温备(施加表锁)
常用选项:
备份某个库的某张表数据,其实在备份数据的时候,dump下来的sql文件是包含了表结构信息的。
mysqldump -uroot -pzhangjian test wzpiku_prize_config > lala.sql
test库的wzpiku_prize_config表,中间是空格哦,不指定目录默认当前目录的lala.sql文件中,且表的结构以及数据都会被dump下来。
并且, 当你使用的用户没有锁表权限的时候,他会报错,dump失败,加个参数就好了:--single-transcation
把lala.sql表导入到test库中:
mysql -uroot -pzhangjian test < lala.sql
经DBA大佬指导,得到新的数据库备份方法:结构和数据分开放。
mysqldump -uroot -p --single-transaction -d -A >t_all.bak 库表结构
mysqldump -uroot -p --single-transaction -t -A >d_all.bak 数据
其中,‘-A’表示备份全部的库,如果想要仅仅备份业务库,可以使用‘--databases DB’的方式,如下:
仅备份库表结构:
#!/bin/bash
for db in `cat database_game`
do
mysqldump -uadmin -p**** -h**** --single-transaction -d --databases ${db} >> t_all.sql
echo ${db} done!
done
备份数据:
#!/bin/bash
for db in `cat database_game`
do
mysqldump -uadmin -p**** -h**** --single-transaction -t --databases ${db} >> d_all.sql
echo ${db} done!
done
在迁移的过程中,目标库中要先导入结构,再导入数据,同时需要注意,目标库一定要是空的,不能有脏数据。
如果不加‘--databases’参数,就必须要加个‘-A’,表示备份全部的库,包括四个系统库。
mysqldump几个重要的指令参数:
--master-data:之前说过,在进行数据恢复时,往往需要进行时间点的还原,通常的做法是先通过最近一次的全备将数据恢复到备份时的样子,再通过二进制日志(position),将备份之后的更改再重演一遍,这样就回复成了最近的模样,那么在还原的时候,我们怎么知道二进制日志的position值呢?
没错,我们必须在备份时做好标记!
典型问题:某台db已经运行的一段时间,里面已经存在了一些数据,此时,你想要将数据库架构从单台改为主从,首先你需要部署一台从db,再从当前的线上db备份出完整数据并导入到从库中,在这段操作期间,主库里新增的更改,依然需要从库去追过来,如何追?从哪里开始追?
在使用mysqldump进行备份时,需要使用‘--master-data’选项,标记备份开始时,binlog所对应的position,具体参数如下:
该值为0时:不记录对应二进制日志的位置,也就等于不适用此参数
该值为1时:记录对应的二进制日志的位置,该值也是默认值,也就是说--master-data=1与--master-data是同样的效果,在生成的备份文件中,会包含‘CHANGE MASTER TO’语句,来告诉从库从主库的哪个二进制日志的哪个position开始追,并且这里‘CHANGE MASTER TO’是没有被注释的!
该值为2时:记录对应的二进制日志的位置,但是是被注释掉的。
我们尝试操作下看看:
[root@VM-75-68 mysql]# mysqldump -uadmin -p**** --master-data=1 RW > RW.sql
[root@VM-75-68 mysql]# vim RW.sql
-- MySQL dump 10.13 Distrib 5.1.73, for redhat-linux-gnu (x86_64)
--
-- Host: localhost Database: RW
-- ------------------------------------------------------
-- Server version 5.6.41-log
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE=‘+00:00‘ */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE=‘NO_AUTO_VALUE_ON_ZERO‘ */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Position to start replication or point-in-time recovery from
--
CHANGE MASTER TO MASTER_LOG_FILE=‘mysql-bin.000011‘, MASTER_LOG_POS=120; #这里就是标记的binlog文件以及position
--flush-logs:mysql系统会设置binlog日志的文件大小,当备份开始时,二进制文件的position处于当前文件大小的居中位置时,当我们想要找到对应的position进行重演时,此位置之前的操作对我们来说都是‘无用的’,会产生一些多余的工作量,能否避免这种情况出现?
可以,那就是‘--flush-logs’参数,如果使用了该选项, 备份开始时就会滚动一次二进制日志,不管文件的大小是否达到上限,这样,我们就能够在二进制文件的开头部分开始重演,就会很高效!
其他常用选项:
我们说过备份的目的是还原,那么仅仅备份表中的数据是远远不够的,因为在数据库中,可能还存在一些存储过程和存储函数,存在一些触发器和事件表,这些东西也要备份,否则备份不全,在恢复的时候就懵逼了,我们来看看常用的选项:
--routines:表示备份时,存储过程和存储函数也会被备份
--triggers:表示备份时,触发器也会被备份
--events:表示备份时,事件表也会被备份
--single-transaction:表示开启一个‘可重读’事务,基于这个独立的事务,才是备份出一个满足数据一致性的备份!
因此,如果你的数据库中所有的表都是使用innodb存储引擎,而且你要对数据库进行热备,那么,一定要添加上--single-transaction选项,如果开启了二进制日志,还需要加上--master-data选项!
以上就是mysqldump相关的用法,共勉!