zoukankan      html  css  js  c++  java
  • 08 : mysql备份恢复(2)

    我们先回顾一下前一遍的知识,然后在讲解xtrabackup物理备份

    1、mysqldump
    逻辑备份工具,备份的SQL语句,可读性高,压缩比大,速度较慢,比较适合于小数据量级
    -B

    -A
    -R
    --triggers
    --master-data=2
    --single-transaction

    2、mysqldump+mysqlbinlog实现基于时间点的恢复
    (1)恢复全备
    (2)截取二进制日志
    起点:备份开始的时刻,--master-data=2,备份文件22行,会记录起点
    终点:需要分析二进制日志内容,找到故障之前的位置点


    ***(扩展)
    3、利用sed grep,从全备中截取单个库、单个表进行单独恢复。
    需求:备份策略是全备,数据量是100G,有其中一个表数据损坏,这个表2M
    按照以往的处理方法:恢复全备+全备之后到故障点之前的二进制日志
    新的思路:
    利用sed grep命令过滤出来损坏表的数据。

    从全备份中只恢复report库(report --one-database)
     mysql -uroot -p123456 report --one-database <fulldump.sql

    利用sed和grep 分别导出表结构和表内容,恢复到数据库

    sed -e'/./{H;$!d;}' -e 'x;/CREATE TABLE `user`/!d;q' 3306.sql > biao.sql    (导出表结构语句)
    grep -i 'INSERT INTO `user`' 3306.sql >>biao.sql (导出插入数据的语句)
    进入数据库source biao.sql (导入表数据,恢复表数据)

    4、二进制日志flashback(binlog2sql闪回)(扩展)
    update
    delete
    row、statement、mixed

    故障描述:
    误删除了某表10行数据 delete from t1 where id<10;可能这10行数据只有几十K或者几百K
    全备假如说是100G
    基于原有的恢复思路?
    全备+全备之后到误删除之前的二进制日志

    新的思路: 只把误删除的日志,进行翻转。
    delete ----->insert
    update a b ------> update b a
    insert ------> delete

    mysqlbinlog --flashback

    ------------------------------------------------------------------------------------------------------------- 

    xtrabackup


    物理备份,类型cp 数据目录下的数据文件到备份路径
    MyIsam,进行锁表备份
    innodb,进行热备,备份数据的同时,会将备份过程中产生的数据变化(redo+undo)。
    在恢复时,提前进行备份准备,“合并”redo和undo到全备数据文件,前滚和回滚的过程。
    模拟的MySQL的ACSR

    1、安装  

    安装epel源(阿里的就行,或者清华 的)
    yum -y install perl perl-devel libaio libaio-devel perl-Time-HiRes perl-DBD-MySQL
    或者官网:https://www.percona.com/downloads/XtraBackup/
    我们直接yum安装
    yum install -y percona-xtrabackup


    备份命令:
    xtrabackup
    innobackupex *****

    2、innobackupex备份命令使用
    (1)物理备份(可以理解为拷贝数据文件)
    (2)对于Myisam表,进行自动锁表拷贝
    (3)对于InnoDB的表,进行热备(不光是备份数据文件+备份在备份过程中产生的数据变化)
    1、拷贝数据文件
    2、拷贝Redo和Undo:为了实现热备
    (4)基本使用(全备)


    innobackupex --user=root --password=123 /backup

    xtrabackup_binlog_info :存储二进制日志位置号
    xtrabackup_info :备份过程中的详细信息
    xtrabackup_checkpoints :备份时的数据文件的lsn和redo日志文件的lsn
    xtrabackup_logfile :备份过程中产生的redo日志

    全备(自己指定备份路径):
    innobackupex --user=root --password=123 --no-timestamp /backup/full

    全备恢复:
    1、数据库要关闭
    2、恢复路径要是空的

    [root@db01 data]# rm -rf *
    [root@db01 data]# pkill mysqld
    3、备份准备(模拟了mysql crash safe recovery),将已提交的事务合并到数据文件,将未提交的数据回滚
    innobackupex --apply-log /backup/full
    4、恢复备份
    方法1:
    cp /backup/full/* /application/mysql/data
    方法2:
    innobackupex --copy-back /backup/full/
    5、修改归属
    chown -R mysql.mysql /application/mysql/data/*

    6、启动数据库
    /etc/init.d/mysqld start
    ----------------------------------------------
    增量:针对上次备份的做的增量
    差异:针对全备的差异
    总之,不管是哪种增量备份,都是不能单独恢复的,都是依赖于全备才能恢复的。
    ----------------------------------------------
    3、innobackupex实现增量备份
    (1)周日全备
    innobackupex --user=root --password=123 --no-timestamp /backup/full

    [root@db01 backup]# cat /backup/full/xtrabackup_checkpoints
    backup_type = full-backuped
    from_lsn = 0
    to_lsn = 2629682
    last_lsn = 2629682
    compact = 0
    recover_binlog_info = 0

    (2)模拟数据变化
    source /root/world.sql
    use world
    create table city1 select * from city;

    (3)开始周一增量备份
    --incremental 打开增量备份开关
    --incremental-basedir=/backup/full 基于哪次备份进行增量

    innobackupex --user=root --password=123 --no-timestamp --incremental --incremental-basedir=/backup/full /backup/inc1


    [root@db01 inc1]# cat /backup/full/xtrabackup_checkpoints /backup/inc1/xtrabackup_checkpoints
    backup_type = full-backuped
    from_lsn = 0
    to_lsn = 2629682
    last_lsn = 2629682
    compact = 0
    recover_binlog_info = 0
    ----------------------------
    backup_type = incremental
    from_lsn = 2629682
    to_lsn = 3186615
    last_lsn = 3186615
    compact = 0
    recover_binlog_info = 0

    (4)再次模拟数据变化
    use world
    create table city2 select * from city;

    (5)周二进行第二次增量备份

    innobackupex --user=root --password=123 --no-timestamp --incremental --incremental-basedir=/backup/inc1 /backup/inc2

    cat /backup/full/xtrabackup_checkpoints /backup/inc1/xtrabackup_checkpoints /backup/inc2/xtrabackup_checkpoints
    ------------------------------
    backup_type = full-backuped
    from_lsn = 0
    to_lsn = 2629682
    last_lsn = 2629682
    compact = 0
    recover_binlog_info = 0
    -----------------------------
    backup_type = incremental
    from_lsn = 2629682
    to_lsn = 3186615
    last_lsn = 3186615
    compact = 0
    recover_binlog_info = 0
    -----------------------------
    backup_type = incremental
    from_lsn = 3186615
    to_lsn = 3744834
    last_lsn = 3744834
    compact = 0
    recover_binlog_info = 0
    -----------------------------
    (6)破坏数据(把data目录数据全删掉,此操作有风险,不代表生产环境可以这么做)

    cd /application/mysql/data/
    rm -rf *
    pkill mysqld

    (7)恢复过程
    1、增量没法直接恢复使用,必须要合并到全备中,才能恢复。
    2、在合并过程中,顺便进行备份的准备(apply-log),在准备过程中只有最后一次合并的增量redo和undo都应用。
    中间和合并过程,应用redo
    <1>全备的准备(只对redo进行应用,前滚)
    innobackupex --apply-log --redo-only /backup/full/
    <2>第一次增量的合并到全备
    --incremental-dir=/backup/inc1 ----->要和并的增量备份路径
    innobackupex --user=root --password=123 --apply-log --redo-only --incremental-dir=/backup/inc1 /backup/full/

    ---------验证--------------------------
    [root@db01 data]# cat /backup/full/xtrabackup_checkpoints /backup/inc1/xtrabackup_checkpoints
    backup_type = log-applied
    from_lsn = 0
    to_lsn = 3186615
    last_lsn = 3186615
    compact = 0
    recover_binlog_info = 0
    backup_type = incremental
    from_lsn = 2629682
    to_lsn = 3186615
    last_lsn = 3186615
    compact = 0
    recover_binlog_info = 0
    [root@db01 data]#
    ------------------------
    <3>第二次增量合并到全备(最后一次增量)
    innobackupex --user=root --password=123 --apply-log --incremental-dir=/backup/inc2 /backup/full/

    ---------验证--------------------------
    [root@db01 data]# cat /backup/full/xtrabackup_checkpoints /backup/inc2/xtrabackup_checkpoints
    backup_type = full-prepared
    from_lsn = 0
    to_lsn = 3744834
    last_lsn = 3744834
    compact = 0
    recover_binlog_info = 0
    backup_type = incremental
    from_lsn = 3186615
    to_lsn = 3744834
    last_lsn = 3744834
    compact = 0
    recover_binlog_info = 0

    <4>最后统一进行备份准备
    innobackupex --apply-log /backup/full

    --------------------------------------------------------------------------
    --redo-only This option should be used when preparing the base full
    backup and when merging all incrementals except the last
    one. This forces xtrabackup to skip the "rollback" phase
    and do a "redo" only. This is necessary if the backup
    will have incremental changes applied to it later. See
    the xtrabackup documentation for details.
    --------------------------------------------------------------------------
    <5> 恢复备份,修改权限、启动数据库
    innobackupex --copy-back /backup/full/
    ----------------------------------

    企业案例一则:
    背景:
    某大型网站,mysql数据库,数据量500G,每日更新量100M-200M •
    备份策略:
    – xtrabackup,每周六0:00进行全备,周一到周五及周日00:00进行增量备份。
    故障场景:
    – 周三下午2点出现数据库意外删除表操作(这个表只有2M,drop table)。
    如何恢复?


    第一种方法:
    1、Xtrabackup恢复到周二晚上
    2、从0:00-14:00之前的binlog,截取到误操作之前
    ------------------------
    <1> 周六凌晨的全备
    清理/backup下已有的备份
    rm -rf /backup/*
    innobackupex --user=root --password=123 --no-timestamp /backup/full

    <2>模拟周六白天数据
    mysql> use world
    mysql> create table c1 select * from city;

    <3>周日的凌晨增量inc1
    innobackupex --user=root --password=123 --no-timestamp --incremental --incremental-basedir=/backup/full /backup/inc1

    <4>模拟周日白天的数据变化
    use world
    create table c2 select * from city;


    <5>周一凌晨增量inc2
    innobackupex --user=root --password=123 --no-timestamp --incremental --incremental-basedir=/backup/inc1 /backup/inc2

    <6>周一白天的数据变化
    use world;
    create table c3 select * from city;

    <7>搞破坏

    use world;
    drop table c3

    <8>正常变更
    mysql> delete from c1 where id=4079;
    Query OK, 1 row affected (0.06 sec)
    mysql> delete from c1 where id=4078;
    Query OK, 1 row affected (0.01 sec)
    mysql>commit;

    <9>发现故障,立即恢复

    停业务,找到新的备用库,进行恢复数据
    (1)准备xtrabackup备份
    innobackupex --apply-log --redo-only /backup/full/
    innobackupex --apply-log --redo-only --incremental-dir=/backup/inc1 /backup/full
    innobackupex --apply-log --incremental-dir=/backup/inc2 /backup/full
    innobackupex --apply-log /backup/full/

    (2)恢复xtrabackup备份,到周一凌晨位置
    [root@db01 ~]# cd /application/mysql/data/
    [root@db01 data]# rm -rf *
    [root@db01 data]# pkill mysqld
    [root@db01 data]# innobackupex --copy-back /backup/full/
    [root@db01 data]# chown -R mysql.mysql /application/mysql/data/*
    [root@db01 data]# /etc/init.d/mysqld start

    (3)截取并追加后续binlog
    第一段:从0点到误操作之前

    起点:
    [root@db01 inc2]# cat /backup/inc2/xtrabackup_binlog_info
    mysql-bin.000016 267884
    终点:
    mysql> show binlog events in 'mysql-bin.000016';

    | mysql-bin.000016 | 401766 | Query | 6 | 401883 | use `world`; DROP TABLE `c3`

    mysqlbinlog --start-position=267884 --stop-position=401766 /data/mysql/mysql-bin.000016 >/backup/binlog1.sql


    恢复第一段的binlog
    mysql> set sql_log_bin=0;
    mysql> source /backup/binlog1.sql;

    第二段:误操作之后到最后阶段的所有binlog记录,在导出来导入到数据库就可以了。
    #由于忘记提交了,所有后续操作都没有了。


    第二种方法:
    思路:
    <1>创建被删除的表结构(可以去binlog里面找原始的,或者和开发要一下当时的创建表结构语句)
    mysql> create table c2 xxxxx;(创建表结构)
    <2>alter table c2 discard tablespace;(清空数据库目录 c2表的ibd文件)
    <3>把xtrabackup 备份目录下面的word数据库目录下的c2.ibd 文件直接copy到mysql数据库word数据库目录下面
    cp c2.ibd /application/mysql/data/word/
    chown mysql.mysql /application/mysql/data/word/*
    <4>alter table c2 import tablespace;(导入c2数据库)

    -------------------------------------

  • 相关阅读:
    Xshell 使用纪要
    矩阵求逆
    Ubuntu 增加新用户
    matlab 常用图像处理
    Surface Evolver 基本操作、使用指南和珍贵资料
    latex 裁剪图片
    Inkscape 输入希腊字母
    Pyton——int内部功能介绍
    python——登陆接口设计(循环方法)
    Python之三层菜单
  • 原文地址:https://www.cnblogs.com/jim-xu/p/11619618.html
Copyright © 2011-2022 走看看