暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

数据库进阶篇10

王sir说大数据 2016-12-12
214

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)


#完成



文章转载自王sir说大数据,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论