☆MySQL备份与恢复


解读binlog

通过配置参数 log-bin[=name] 可以启动二进制日志 。如果不指定name ,则默认二进制日志文件名为主机名,后缀名为二进制日志的序列号,所在路径为数据库数据所在目录 (datadir)。

注意!!修改配置文件后,要先停止服务,再启动服务!!

  • ①# mysqladmin -uroot -p shutdown -h127.0.0.1 -P3307
  • ②# mysqld_safe –defaults-file=/etc/mysqla.cnf &
  • ③# mysql -uroot -p -P3307 -h127.0.0.1

(1)binlog产生的过程:
用户连上数据库执行sql(这sql就是事务),在用户空间里开辟一块空间来存放事务的第一条、第二条…,用户事务提交的时候,事务才会写到binlog里面去。binlog小的话,超了后就会写到tmp里(有个状态值可以看)。
(2)binlog记录的格式:记录的是SQL语句。binlog存放在数据目录下,binlog会自动切换。
binlog切换的条件

  • ①大小达到阈值 max_binlog_size
  • ②数据库重启会出现自动切换(很多小的binlog)
  • ③flush logs 强行切换

(3)binlog的查看

#mysqlbinlog -vv mysqlserver.000035 | tail -1000        
#详细显示000035binlog的最后一千行

(4)恢复某段日志
法①
将binlog里的相中的某段复制到一个a.a,然后
cat a.a|mysql
法②

#mysqlbinlog --start-position=4777222 --stop-position=477487 -vv mysqlserver.000035 >a.a | mysql

多个binlog的时候:

#mysqlbinlog --start-position=4777222 --stop-position=477487 -vv mysqlserver.000001[3-9]

(法②由于-vv,会在选中的日志头尾各加上一些东西)


逻辑备份和物理备份、冷备、热备

按照备份的方法可以分为:

  • Hot Backup (热备)(ibbackup、xtrabackup)
  • Cold Backup (冷备)
  • Warm Backup (温备)

Hot Backup是指在数据库运行中直接备份,对正在运行的数据库没有任何影响 (用工具ibbackup、xtrabackup)。这种方式在MySQL 官方手册中称为 Online Backup(在线备份)。

Cold Backup是指在数据库停止的情况下进行备份(直接拷贝相关文件),这种备份最为简单,只需要拷贝相关的数据库物理文件即可。这种方式在MySQL官方手册中称为 Offline Backup (离线备份)。

Warm Backup备份同样是在数据库运行时进行 ,但是会对当前数据库的操作有所影响,例如加一个全局读锁以保证备份数据的一致性。

按照备份后文件的内容 ,又可以分为:

  • 逻辑备份(mysqldump、select * into outfile)
  • 裸文件(物理)备份

①逻辑备份:备份后的文件是内容是可读的,一般是文本文件,内容一般是sql语句,或表内的实际数据。
(将数据行抽取出来,写到一个文件中去)
方法:
mysqldump、select * into outfile
方法的好处:可以看到导出文件的内容,一般用于数据库的升级、迁移等,但是恢复的时间往往比较长。

②裸文件(物理)备份:是指拷贝数据库的物理文件,数据库既可以处于运行状态(ibbackup、xtrabackup),也可以处于停止状态。恢复时间比逻辑备份短。

(物理备份:shutdown(冷备)将数据库相关的文件cp备份出来、open(热备)使用相关的工具将数据备份出来)
(物理备份速度块、大小小)

按照备份的内容来分:

  • 完全备份
  • 增量备份
  • 日志备份

(都能用xtrabackup)

①完全备份:对数据库的完整备份。
②增量备份:是指在上次的完全备份基础上,对更新的数据进行备份。
③日志备份:主要针对binlog的备份。通过对一个完全备份进行binlog的重做来完成数据库的point-in-time的恢复工作。MySQL复制(Replication)的原理就是异步实时进行binlog 重做。


逻辑备份的工具之 mysqldump(mysql自带)

备份数据库

#mysqldump 数据库名 >数据库备份名
#mysqldump -A -u用户名 -p密码 数据库名>数据库备份名
#mysqldump -d -A --add-drop-table -uroot -p >xxx.sql

导出结构不导出数据:

mysqldump --opt -d 数据库名 -u root -p > xxx.sql

导出数据不导出结构:

mysqldump -t 数据库名 -uroot -p > xxx.sql

导出数据和表结构:

mysqldump 数据库名 -uroot -p > xxx.sql

导出特定表的结构:

mysqldump -uroot -p -B 数据库名 --table 表名 > xxx.sql

导入数据:

#mysql 数据库名 < 文件名
#source /tmp/xxx.sql  

常用的options :

  • ①-u:用户
  • ②-p:密码
  • ③-F:flush logs
  • ④–single-transaction:
    保证备份的一致性,实际上它的工作原理是设定本次会话的隔离级别为:REPEATABLE READ,以确保本次会话(dump)时,不会看到其他会话已经提交了的数据。
  • ⑤-l:lock tables。
    在备份前,例如9点,把所有表都加上lock。9点40备份完了,但是都是九点的。恢复=备份好的+40分钟内的binlog
  • ⑥-T:
    导出一行行的数据,默认以tab做分隔符。-T指定哪个文件夹,这条命令就得到哪个文件夹下面执行。
 -- fields-terminated-by=',!#'

列和列之间的分隔符设置为 ,或!或#

 --fields-terminated-by=name:

Fields in the output file are terminated(终止) by the given string(字符串).
(输出文件中的字段由给定字符串终止)

--fields-enclosed-by=name:

Fields in the output file are enclosed(封闭) by the given character(字符).
(输出文件中的字段由给定的字符封闭)

--fields-optionally-enclosed-by=name:

Fields in the output file are optionally(可选择的) enclosed by the given character.
(输出文件中的字段是由给定的字符可选的封闭)

--fields-escaped-by=name:

Fields in the output file are escaped(逃避) by the given character.
(输出文件中的字段是由给定的字符避开)

dump的选项很多,具体可以用–help看。

mysqldump备份命令

①备份指定的数据库或者此数据库中的某些表

#mysqldump [options] db_name [tables]

②备份指定的一个或多个数据库

#mysqldump [options] --database DB1 [DB2 DB3...]

③备份所有数据库

#mysqldump [options] --all-database

备份的例子:
①备份数据库test下的表emp:

#mysqldump -uroot -p -l test emp >emp.sql

②备份数据库test:

#mysqldump -uroot -p -l test >test.sql

③备份所有数据库:

#mysqldump -uroot -p -l --all-database >all.sql

④备份数据库test下的表emp和dept:

#mysqldump -uroot -p -l test emp dept >emp_demp.sql

⑤备份数据库test下的所有表为逗号分隔的文本,备份到/tmp

#mysqldump -uroot -T /tmp -l test emp --fields-terminated-by ','
#more emp.txt

这里写图片描述

备份一张表:

#mysqldump -uroot -p -l -F --single-transaction -S /usr/local/mysqldata/mysql.sock test t1 >aa.sql

恢复这张表:

#mysqldump -uroot -p -S /usr/local/mysqldata/mysql.sock <aa.sql

关注的点:
备份出来的数据对应的binlog的日志起点 备份时候要把表给锁住,对myisam来说,备份期间锁住的表是不能用的;对innodb来说,不锁表,在备份期间结合MVCC和undo把开始备份时刻和备份完成时刻之间的数据恢复。

跑binlog
法①
将binlog里的相中的某段复制到一个a.a,然后cat a.a|mysql
法②

#mysqlbinlog --start-position=4777222 --stop-position=477487 -vv mysqlserver.000035 >a.a | mysql

多个binlog的时候:

#mysqlbinlog --start-position=4777222 --stop-position=477487 -vv mysqlserver.000001[3-9]

(法②由于-vv,会在选中的日志头尾各加上一些东西)


物理备份工具之 mysqlhotcopy、ibbackup

mysqlhotcopy -> myisam
ibbackup -> innodb (花钱)

注意:只要对myisam表 备份,都会锁住表!
而对innodb来说,就不会锁表!


物理备份工具之 xtrabackup(第三方的备份工具)的安装

对 myisam、innodb均可备份,模拟的ibbackup
使用xtrabackup备份主库
主备库同时安装xtrabackup软件

yum install cmake gcc gcc-c++ libaio libaio-devel automake autoconf bison libtool ncurses-devel libgcrypt-devel libev-devel libcurl-devel vim-common

rpm -ivh libev4-4.15-7.1.x86_64.rpm

rpm -ivh libev-devel-4.15-21.1.x86_64.rpm

(上面两个软件需要单独安装)
④解压 percona-xtrabackup-2.3.4.tar.gz

#cmake -DBUILD_CONFIG=xtrabackup_release -DWITH_MAN_PAGES=OFF && make -j4
#make install

[root@mysqlserver ~]# echo $PATH
/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/usr/local/mysql/bin:/usr/local/xtrabackup/bin
[root@mysqlserver ~]# innobackupex --help

(修改PATH变量eg:)

[root@root mysql]# PATH=$PATH:/usr/local/mysql/bin
[root@root mysql]# vim /root/.bash_profile

(rpm版本的安装详见:
http://blog.csdn.net/qq_18312025/article/details/78897023

⑥建立备份目录 /backup/
⑦授权备份目录

#chown -R mysql:mysql /backup
# innobackupex --user=root --password=rootroot --no-timestamp /backup
# innobackupex --apply-log /backup/

Xtrabackup的介绍

是Percona公司开发的 基于InnoDB的在线热备工具。开源、免费、占磁盘小。
包含了两个主要的工具:xtrabackupinnobackupex
xtrabackup只能备份innodb和xtraDB两种表,不能备份myisam表;
innobackupex是一个封装了xtrabackup的perl脚本。支持myisam和innodb。但对myisam备份时需要加锁。

innobackupex的全备 原理过程

①备份开始时先会开启一个后台检测进程,实时检测mysql redo的变化,一旦发现redo有新的日志写入,立即将日志记入后台日志文件 xtrabackup_log 中;
②之后复制InnoDB的数据文件和系统表空间文件ibdata1;(大部分的时间耗在这里)
③复制结束后,执行 flush tables with read lock 操作,复制 .frm(表结构定义的文件)、.MYI、.MYD等文件。执行flush tables with read lock 是防止数据表发生DDL操作,并且在这一时刻获得binlog的位置;
④最后unlock tables,把表设为可读写状态,最终停止 xtrabackup_log 。
这里写图片描述

(其实,从flush tables 到unlock tables 是对myisam表的备份过程,所以有加锁;innodb是不用加锁的,不影响使用)
注意!在备份期间,产生的所有的redo log都会拷贝出来,放在/backup下的xtrabackup_logfile中

这里写图片描述

备份目录下的文件

①backup-my.cnf
②ibdata1、mysql、performance_schema、test、tpcc1000
③xtrabackup_logfile
④xtrabackup_info
⑤xtrabackup_binlog_info #从哪开始恢复
⑥xtrabackup_checkpoints

①backup-my.cnf:备份命令用到的配置选项信息

这里写图片描述

②ibdata1、mysql、performance_schema、test、tpcc1000:
这些是备份的数据文件
③xtrabackup_logfile:备份期间产生的redo log存放在此。
④xtrabackup_info:备份的详细信息

[root@LPeng backuptwo]# cat xtrabackup_info
uuid = d14b2e72-7d7a-11e6-a809-000c29f7a0ac   #通用唯一识别码 (Universally Unique Identifier)
name = 
tool_name = innobackupex    #备份工具的名字
tool_command = --defaults-file=/etc/mysqla.cnf --user=root --password=... --port=3307 --no-timestamp --socket=/usr/local/mysqldata/mysql.sock /backuptwo    #备份时执行的命令
tool_version = 2.3.4        #版本号
ibbackup_version = 2.3.4    #对应的ibbackup的
server_version = 5.6.15-log #mysql的版本
start_time = 2016-09-18 16:33:14    #备份的开始时间
end_time = 2016-09-18 16:35:13  #备份的结束时间
lock_time = 0   #锁了多少时间
binlog_pos = filename 'mybin.000010', position '120'    #binlog的位置。恢复的时候就从这开始恢复。
innodb_from_lsn = 0 #innodb的lsn开始。日志序号 (LSN:Log sequence number) 。
innodb_to_lsn = 1400172578  #innodb的lsn结束。最新的数据页。增量备份时从此处往后开始备份。
partial = N #局部的
incremental = N #增量=N,没有增量  
format = file   #备份的形式  
compact = N 
compressed = N  #没有压缩   
encrypted = N       #没有加密

⑤xtrabackup_binlog_info:mysql服务器当前正在使用的二进制日志文件及至备份这一刻为止binlog的位置。 -> 恢复时开始的位置
这里写图片描述
⑥xtrabackup_checkpoints:备份类型(如完全或增量)、备份状态(如是否已经为prepared状态)和LSN(日志序列号)范围信息。
这里写图片描述
from_lsn:从哪个lsn开始备份
to_lsn:备份的所有的lsn的一个范围
last_lsn:备份的最后一个lsn
(注:⑤⑥的信息都在xtrabackup_info里面有!)


用innobackupex 全备的操作步骤

1、首先新建一个备份目录/backup,然后将属主和属组均设置为mysql:

#chown -R mysql:mysql /backup

2、备份数据库:将相关的数据文件拷贝出来

#innobackupex --user=root --password="" --no-timestamp /backup (不建立带时间戳的目录)

如果sock文件不是默认或者端口不是3306时:

#innobackupex --defaults-file=/etc/mysqla.cnf --user=root --password=123123 --port=3307 --no-timestamp --socket=/usr/local/mysqldata/mysql.sock  /backup

备份成功的话,在最后会有一个complete!
然后模拟环境:插入数据/删除一张表/更新数据等(体验apply-log的功能)

3、apply-log

[root@localhost backup]# innobackupex --apply-log /backup/ 
[root@localhost backup]# cat xtrabackup_checkpoints
 backup_type = full-prepared 

不仅是全备而且apply log了

4、关闭数据库,删除数据库(注意一定不要删除binlog)
将binlog从里面剪切出来,注意不要放到backup下面,否则一会恢复的时候binlog页都给恢复了。

5、恢复数据库:就是把backup下面的文件再拷贝回去

[root@localhost backup]# innobackupex --defaults-file=/etc/mysla.cnf --copy-back /backup/ 
#注意:最好指定配置文件,有的会报如下错误

这里写图片描述

6、文件拷贝完成记得一定要修改datadir下面文件的属主和属组,重启数据库

# chown -R mysql:mysql /mysqldata/
# mysqld_safe --defaults-file=/etc/my.cnf --user=root &

7、跑binlog:

# cd /backup/
# cat xtrabackup_binlog_info
# mysqlbinlog --strat-position=686 /mysqlbin/mybin.000002 | mysql -uroot -p123123 -h127.0.0.1

备份与恢复的方案/思路

①备份对生产的影响、备份和数据传输
②备份的恢复时间:
重点是

  • 1.[copyback]备份拷贝回来的时间=500G(数据库大小)/100M(带宽,1000b/s)==5000s==1.5h
  • 2.binlog的恢复时间非常不可控,需实际测试![有可能某个sql特别慢]
    专门建立一个从库,从库就是用来放备份的。这样可以经常做全备。

  • 1.备份期间IO很大,库基本是不可用的;

  • 2.备份完成后取走时,会产生很大的带宽、IO(备份进来一次,取走一次)
  • 3.周一全备,,周二周三增量,每天备份binlog(恢复的时候时间非常长,20天常见的)

增量备份

主要是对innodb而言的,对于myisam和其他的表还是一个全拷贝。
每个数据页都会有一个lsn号,每产生一次变化,lsn都会发生改变。
增量备份:备份的是发生变化的页(这些数据页指的是LSN大于xtrabackup_checkpoints中给定的 LSN),增备是基于全备的,第一次的增备的数据必须基于上一次的全备。

增量备份的过程:
这里写图片描述

  • 缺点:要把所有的页都扫描一遍才能知道哪些页发生变化,所以备份的时候对库的压力并没有变小,只是备份出来的数据量有可能变少了。
  • 好处:恢复的时候是可控的,可以把增量apply到全备里面;备份完成之后就可以apply到全备里面去,不是非要等到恢复的时候再apply。

完全备份+增量备份+apply-log

增量备份在恢复的时候是可控的。
【注意!下面的备份恢复过程中,rpm安装的mysql,不用加–socket,–defaults-file,–port】
1.完全备份

#innobackupex --defaults-file=/etc/mysqla.cnf --user=root --password=123123 --port=3307 --socket=/usr/local/mysqldata/mysql.sock  /quanbei

(注意!不加 no-timestamp 就会自动生成带时间戳的目录,增备常带时间!)

①并行:

innobackupex [--parallel =NUMBER-OF-FORKS]  BACKUP-DIR

当IO没有达到最大吞吐量时,就可以采用并行。能够充分利用IO的性能。
并行:加大吞吐量,快点备份完。
②限流 –throttle =100
备份的时候可以限流,限制流量为100,即:控制IO使用量,延长备份时间,降低对备份库的使用影响。)
(注:innobackupex 备份myisam引擎的表(performance_schema和myisam两个库表都为myisam引擎)时注意会短时间加锁(flush table with read lock)!从而影响生产!;
备份时,建议加 –safe-slave-backup 选项,会停止从库的更新进行备份。会大大提升备份速度。)

模拟:随便添加点数据

2.新建增量备份的目录 /backup_incre ,然后授权

3.第一次增量备份 (–incremental-basedir 是上次全备的目录)(增量备份希望有时间戳)

#innobackupex --defaults-file=/etc/mysqla.cnf --user=root --password=123123 --socket=/usr/local/mysqldata/mysql.sock --incremental /backup_incre --incremental-basedir=/quanbei/

log scanned up to (日志lsn号)如果出现这些,说明产生了新页)
在备份的过程中会有大量的log scan up to:不断的记日志,数据页不断的更新;说明我读到的这个数据页在不断的更新。
!!注意:备份期间innodb表也会短时间的加锁,最好在从库上备份,并且暂停主库对从库的更新。

4.第二次增量备份(basedir应指定为上次增量备份的目录)
跟第一次一样,只不过要修改为上一次增备的目录 –incremental-basedir=/backup_incre/上次的时间戳目录/(有xtrabackup_checkpoints)

5.把增量prepare(即apply-log)到全备里面去,只要后面有增量就要一直redo-only!

#innobackupex --defaults-file=/etc/mysqla.cnf --user=root --password=123123 --port=3307 --socket=/usr/local/mysqldata/mysql.sock  --apply-log-(-only) --redo-only /quanbei/  --incremental-dir=/backup_incre/第一个时间戳目录/

(mysql5.7 –apply-log要加-only)

6.增量备份的prepare
将第二次的增备添加到全备中(由于是添加的最新的增备,后面没有增量了,所以不用再加–redo-only)

#innobackupex --user=root --password=123123 --apply-log(-only)  /quanbei/ --incremental-dir=/backup_incre/新的时间戳目录/

7.破坏数据库,但是一定不能破坏binlog!!
杀死mysqld进程(ps -ef|grep mysqld ; kill -9 进程号)、把/mysqldata/下的所有binlog备份出来、删除/mysqldata/下的内容。

8.进行恢复

#innobackupex --copy-back(--move-back) /quanbei/

copy-back和move-back的区别:
如果备份和数据库所在的是一个文件系统,move-back的时候其实就是给了一个名字,速度非常的快。

9、恢复之后,注意看/mysqldata/下的文件的权限。

# chown -R mysql:mysql /mysqldata/

10、启动mysql

# mysqld_safe --defaults-file=/etc/my.cnf --user=root &

11、登录mysql,看看之前删除的数据有没有回来

12、恢复binlog(此时恢复的是备份期间产生的redo)
①查看备份恢复到具体位置:

# cd /quanbei/
# cat xtrabackup_binlog_info

这里写图片描述
②恢复

#mysqlbinlog --strat-position=686 /mysqlbin/mybin.000002 | mysql -uroot -p123123 -h127.0.0.1

innobackupex 常用参数详解

  • –apply-log :全备完毕后接着进行apply 备份。
  • –compress
  • –compress-threads=NUMBER-OF-THREADS:备份的时候压缩非常消耗CPU,压的时候可以加大cpu的力度
  • –copy-back :恢复
  • –encrypt=ENCRYPTION-ALGORITHM]:备份有加密的需求
  • –no-timestamp:备份完之后不生成时间戳
  • –compact:优化,所有表上的二级索引不备份。只备份表数据。
  • –parallel=NUMBER-OF-FORKS:只支持全备,备份的时候可以用并发(并行)的方式去备份(在带宽足够的条件下,可以大量的减少备份的时间)
  • –throttle=# 阈值, 限流:限制流量,控制他的IO使用量,降低对主库使用的影响,不要对生产产生影响
  • –safe-slave-backup:停止对从库的更新,然后进行备份,这样备份非常快。
  • –incremental :接增量备份的目录
  • –incremental-basedir :第一次接全备的目录,后来接上次增备的目录
  • –log-copy-interval=# :每隔多长时间记录一下日志
  • –kill-long-queries-timeout=#:如果系统里有一个长事务一直未提交,加锁加不上,那么备份的时候就会hang住,等多长时间事务不提交加不上锁的话就把他杀死。
  • –ftwrl-wait-timeout=# :
  • –no-lock:在备份期间不加锁。使用这个参数要保证在备份期间没有DDL(会导致数据不一致) ,没有对myisam表的更新。
  • –redo-only :This is necessary if the backup will have incremental changes applied to it later. 只要后面还有增量就一定要加上redo-only。

MySQL启动流程分析:

1、cat /etc/my.cnf 文件是否存在,文件内容是否正确,主要看datadir
2、看datadir的权限
3、进入datadir,看里面的内容是否齐全:
ibdata1,ib_logfile,mysql,performation_scheme,information_scheme
4、确认一下errorlog,pid文件,sock文件
5、mysql_safe –defaults-file=/etc/my.cnf &
6、ps -ef | grep mysqld
7、tail -100f errorlog
8、登陆mysql -uroot -p -h127.0.0.1 或者mysql -uroot -p -S /…/…sock


数据的导入和导出(如何处理纯文本文件里的行数据)

一般都是基于表的。
导出数据:两种方式
1、select … into outfile
这里写图片描述

options:

select * from t3 into outfile "/data/1.txt" fields terminated by ',' ;    

列和列之间用逗号做分隔符

select * from t3 into outfile "/data/1.txt" fields terminated by ',' lines terminated by '\n' ; 

行和行之间用回车作分隔符

select * from t3 into outfile "/data/1.txt" fields terminated by ',' enclosed by '"' ;

所有的列都加单引号

select * from t3 into outfile "/data/1.txt" fields terminated by ',' optionally enclosed by '"' ;  

只有varchar和char列加单引号

insert into t4 values(1,'\tdasd');      #插入一行数据以tab分隔
select * from t4 into outfile "/data/1.txt" fields terminated by ',' escaped by '\\';' ; 

只在个别的字符类型上加引用符

2、mysqldump -T

mysqldump -u username- T target_ dir dbname tablename [option]

导入数据

1、load data

mysql>LOAD DATA [LOCAL] INFILE 'filename' INTO TABLE tablename [option] 

load比insert into速度要快好多,load属于批量导入。

2、mysqllimport

Shell> mysqlimport -u root -p*** [--LOCAL] dbname order_tab.txt [option]

这里写图片描述


Create By LPeng

posted @ 2017-12-26 20:40  斯言甚善  阅读(184)  评论(0编辑  收藏  举报