MySQL备份
在生产环境中最重要的什么?服务器的硬件坏了可以维修或者换新, 软件问题可以修复或重新安装, 但是如果数据没了呢?那可真就over了。 那么我们是否可以提前进行风险规避,使数据丢失后可以快速恢复呢?答案是可以的。
为了在数据丢失之后能够快速的恢复数据, 比较好的方法就是我们定期的把数据进行备份, 备份的策略在不同的应用场景也不尽相同, 大致有几个可以进行参考的数值, 我们可以根据这些数值来制定符合特定应用场景的数据备份策略:
1、能够容忍丢失多少数据
2、恢复数据需要多长时间
3、需要恢复哪一些数据
数据备份类型
1、完全备份
完全备份指的是备份整个数据集( 即整个数据库 )
2、部分备份
部分备份指的是备份部分数据集(例如: 只备份一个表)
部分备份又分为以下两种
1)增量备份
2)差异备份
增量备份指的是备份自上一次备份以来(增量或完全)以来变化的数据; 特点: 节约空间、还原麻烦
差异备份指的是备份自上一次完全备份以来变化的数据 特点: 浪费空间、还原比增量备份简单


MySQL备份数据的方式
在MySQl中我们备份数据一般有几种方式
热备份:当数据库进行备份时, 数据库的读写操作均不是受影响
温备份:当数据库进行备份时, 数据库的读操作可以执行, 但是不能执行写操作
冷备份:当数据库进行备份时, 数据库不能进行读写操作, 即数据库要下线
MySQL中进行不同方式的备份还要考虑存储引擎是否支持
MyISAM :支持温备份和冷备份,不支持热备份
InnoDB:支持备份、温备份和冷备份
MySQL数据库中数据的备份方式
物理备份一般就是通过tar,cp等命令直接打包复制数据库的数据文件达到备份的效果
逻辑备份一般就是通过特定工具从数据库中导出数据并另存备份(逻辑备份会丢失数据精度)
备份需要考虑的问题
1、我们要备份那些内容或者数据
一般来说, 我们需要备份的数据主要包括:
数据、二进制日志, InnoDB事务日志、代码(存储过程、存储函数、触发器、事件调度器)、服务器配置文件。
备份工具
mysqldump : 逻辑备份工具, 适用于所有的存储引擎, 支持温备、完全备份、部分备份、对于InnoDB存储引擎支持热备
cp, tar 等归档复制工具: 物理备份工具, 适用于所有的存储引擎, 冷备、完全备份、部分备份
xtrabackup: 一款非常强大的InnoDB/XtraDB热备工具, 支持完全备份、增量备份
设计合适的备份策略
针对不同的场景下, 对数据库进行备份的策略也不同, 备份策略一般为以下三种
1、直接cp,tar复制数据库文件
2、mysqldump+复制BIN LOGS
3、xtrabackup
以上的几种解决方案分别针对于不同的场景
如果数据量较小, 可以使用第一种方式, 直接复制数据库文件
如果数据量中等, 可以使用第二种方式, 先使用mysqldump对数据库进行完全备份, 然后定期备份BINARY LOG达到增量备份的效果
如果数据量很大, 而又不过分影响业务运行, 可以使用第三种方式, 使用xtrabackup进行完全备份后, 定期使用xtrabackup进行增量备份或差异备份
实例(参考链接http://www.cnblogs.com/liangshaoye/p/5464794.html)
使用cp进行备份
查看数据库的信息
mysql> SHOW DATABASES; #查看当前的数据库, 我们的数据库为employees
+--------------------+
| Database |
+--------------------+
| information_schema |
| employees |
| mysql |
| test |
+--------------------+
4 rows in set (0.00 sec)
mysql> USE employees;
Database changed
mysql> SHOW TABLES; #查看当前库中的表
+---------------------+
| Tables_in_employees |
+---------------------+
| departments |
| dept_emp |
| dept_manager |
| employees |
| salaries |
| titles |
+---------------------+
6 rows in set (0.00 sec)
mysql> SELECT COUNT(*) FROM employees; #由于篇幅原因, 我们这里只看一下employees的行数为300024
+----------+
| COUNT(*) |
+----------+
| 300024 |
+----------+
1 row in set (0.05 sec)
向数据库施加读锁
mysql> FLUSH TABLES WITH READ LOCK; #向所有表施加读锁
Query OK, 0 rows affected (0.00 sec)
备份数据文件
[root@node1 ~]# mkdir backup #创建文件夹存放备份数据库文件
[root@node1 ~]# cp -a var/lib/mysql/* backup #保留权限的拷贝源数据文件
[root@node1 ~]# ls backup #查看目录下的文件
employees ibdata1 ib_logfile0 ib_logfile1 mysql mysql.sock test
模拟数据丢失并恢复
[root@node1 ~]# rm -rf var/lib/mysql/* #删除数据库的所有文件
[root@node1 ~]# service mysqld restart #重启MySQL, 如果是编译安装的应该不能启动, 如果rpm安装则会重新初始化数据库
mysql> SHOW DATABASES; #因为我们是rpm安装的, 连接到MySQL进行查看, 发现数据丢失了!
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| test |
+--------------------+
3 rows in set (0.00 sec)
[root@node1 ~]# rm -rf var/lib/mysql/* #这一步可以不做
[root@node1 ~]# cp -a backup/* var/lib/mysql/ #将备份的数据文件拷贝回去
[root@node1 ~]# service mysqld restart #重启MySQL
#重新连接数据并查看
mysql> SHOW DATABASES; #数据库已恢复
+--------------------+
| Database |
+--------------------+
| information_schema |
| employees |
| mysql |
| test |
+--------------------+
4 rows in set (0.00 sec)
mysql> USE employees;
mysql> SELECT COUNT(*) FROM employees; #表的行数没有变化
+----------+
| COUNT(*) |
+----------+
| 300024 |
+----------+
1 row in set (0.06 sec)
##完成
使用mysqldump+复制BINARY LOG备份
我们通过mysqldump进行一次完全备份, 再修改表中的数据, 然后再通过binary log进行恢复 二进制日志需要在mysql配置文件中添加 log_bin=on 开启。
#基本语法格式
shell> mysqldump [options] db_name [tbl_name ...] 恢复需要手动CRATE DATABASES
shell> mysqldump [options] --databases db_name ... 恢复不需要手动创建数据库
shell> mysqldump [options] --all-databases 恢复不需要手动创建数据库
其他选项:
-E, --events: 备份事件调度器
-R, --routines: 备份存储过程和存储函数
--triggers: 备份表的触发器; --skip-triggers
--master-date[=value]
1: 记录为CHANGE MASTER TO 语句、语句不被注释
2: 记录为注释的CHANGE MASTER TO语句
基于二进制还原只能全库还原
--flush-logs: 日志滚动
锁定表完成后执行日志滚动
查看数据库的信息
mysql> SHOW DATABASES; #查看当前的数据库, 我们的数据库为employees
+--------------------+
| Database |
+--------------------+
| information_schema |
| employees |
| mysql |
| test |
+--------------------+
4 rows in set (0.00 sec)
mysql> USE employees;
Database changed
mysql> SHOW TABLES; #查看当前库中的表
+---------------------+
| Tables_in_employees |
+---------------------+
| departments |
| dept_emp |
| dept_manager |
| employees |
| salaries |
| titles |
+---------------------+
6 rows in set (0.00 sec)
mysql> SELECT COUNT(*) FROM employees; #由于篇幅原因, 我们这里只看一下employees的行数为300024
+----------+
| COUNT(*) |
+----------+
| 300024 |
+----------+
1 row in set (0.05 sec)
使用mysqldump
备份数据库
[root@node1 ~]# mysql -e 'SHOW MASTER STATUS' #查看当前二进制文件的状态, 并记录下position的数字
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000003 | 106 | | |
+------------------+----------+--------------+------------------+
[root@node1 ~]# mysqldump --all-databases --lock-all-tables > backup.sql #备份数据库到backup.sql文件中
mysql> CREATE DATABASE TEST1; #创建一个数据库
Query OK, 1 row affected (0.00 sec)
mysql> SHOW MASTER STATUS; #记下现在的position
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000003 | 191 | | |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
[root@node1 ~]# cp var/lib/mysql/mysql-bin.000003 root #备份二进制文件
[root@node1 ~]# service mysqld stop #停止MySQL
[root@node1 ~]# rm -rf var/lib/mysql/* #删除所有的数据文件
[root@node1 ~]# service mysqld start #启动MySQL, 如果是编译安装的应该不能启动(需重新初始化), 如果rpm安装则会重新初始化数据库
mysql> SHOW DATABASES; #查看数据库, 数据丢失!
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| test |
+--------------------+
3 rows in set (0.00 sec)
mysql> SET sql_log_bin=OFF; #暂时先将二进制日志关闭
Query OK, 0 rows affected (0.00 sec)
mysql> source backup.sql #恢复数据,所需时间根据数据库时间大小而定
mysql> SET sql_log_bin=ON; 开启二进制日志
mysql> SHOW DATABASES; #数据库恢复, 但是缺少TEST1
+--------------------+
| Database |
+--------------------+
| information_schema |
| employees |
| mysql |
| test |
+--------------------+
4 rows in set (0.00 sec)
[root@node1 ~]# mysqlbinlog --start-position=106 --stop-position=191 mysql-bin.000003 | mysql employees #通过二进制日志增量恢复数据
mysql> SHOW DATABASES; #现在TEST1出现了!
+--------------------+
| Database |
+--------------------+
| information_schema |
| TEST1 |
| employees |
| mysql |
| test |
+--------------------+
5 rows in set (0.00 sec)
#完成




