innobackupex 备份/恢复
xtrabackup的好处(在线热备不锁表,即备份过程中不给表加锁 )
有2个备份程序(组件):
xtrabackup: 支持备份innodb/xtradb引擎创建的表
innobackupex: 支持备份innodb/xtradb,还支持myisam引擎创建的表。
安装percona
工作中,需要我们自己从网上下载这些包,都是开源的,从官网下载。
真机:传2个包给主机50 (用scp远程拷贝这个命令)
libev-4.15-1.el6.rf.x86_64.rpm
percona-xtrabackup-24-2.4.7-1.el7.x86_64.rpm
主机50:
# rpm -ivh libev-4.15-1.el6.rf.x86_64.rpm 安装libev这个包
# rpm -ivh percona-xtrabackup-24-2.4.7-1.el7.x86_64.rpm 安装percona包时,它提示需要这2个依赖包!!
页面显示:
警告:percona-xtrabackup-24-2.4.7-1.el7.x86_64.rpm: 头V4 DSA/SHA1 Signature, 密钥 ID cd2efd2a: NOKEY
错误:依赖检测失败:
perl(DBD::mysql) 被 percona-xtrabackup-24-2.4.7-1.el7.x86_64 需要
perl(Digest::MD5) 被 percona-xtrabackup-24-2.4.7-1.el7.x86_64 需要
注意:
把提示中的perl(DBD::mysql) 单词间用-隔开,就是依赖包名perl-DBD-mysql
把提示中的perl(Digest::MD5)单词间用-隔开,就是依赖包名perl-Digest-MD5
# yum -y install perl-DBD-mysql perl-Digest-MD5 安装那2个依赖包!
# yum -y install percona-xtrabackup-24-2.4.7-1.el7.x86_64.rpm 安装percona-xtrabackup这个包
# rpm -ql percona-xtrabackup-24 查看这个包安装在哪里了
/usr/bin/innobackupex 支持备份innodb/xtradb/myisam引擎的表,我们主要学习innobackupex这个命令的使用
/usr/bin/xbcloud
/usr/bin/xbcloud_osenv
/usr/bin/xbcrypt
/usr/bin/xbstream
/usr/bin/xtrabackup 支持备份innodb/xtradb引擎的表
/usr/share/doc/percona-xtrabackup-24-2.4.7
/usr/share/doc/percona-xtrabackup-24-2.4.7/COPYING
/usr/share/man/man1/innobackupex.1.gz
/usr/share/man/man1/xbcrypt.1.gz
/usr/share/man/man1/xbstream.1.gz
/usr/share/man/man1/xtrabackup.1.gz
#######################################################################################
修改存储引擎为innodb (因为我们之前设置把50主机的引擎改为了myisam)
# mysql -uroot -p123456
mysql> show engines; 可以看到默认存储引擎是myisam(字段Support对应值为DEFAULT),Support支持,Comment注释,Transactions事务,Savepoints存储点
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine | Support | Comment | Transactions | XA | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| InnoDB | YES | Supports transactions, row-level locking, and foreign keys | YES | YES | YES |
| MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |
| BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO |
| MyISAM | DEFAULT | MyISAM storage engine | NO | NO | NO |
| CSV | YES | CSV storage engine | NO | NO | NO |
| ARCHIVE | YES | Archive storage engine | NO | NO | NO |
| PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO |
| FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
mysql> show databases; 我们之前创建的库,默认存储引擎都是myisam,所以要删掉它们,但不要删除系统的库
+--------------------+
| Database |
+--------------------+
| information_schema |
| bbsdb |
| db1 |
| db2 |
| db3 |
| db4 |
| gamedb |
| mysql |
| performance_schema |
| studb |
| sys |
+--------------------+
mysql> drop database db1;drop database db2;drop database db3;drop database db4; 用分号; 隔开,可以删除多个库
mysql> drop database bbsdb;drop database gamedb;drop database studb;
mysql> show databases; 恢复到了系统初始的4个库information_schema概要
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
mysql> quit
# systemctl stop mysqld
# vim /etc/my.cnf
... ...
[mysqld]
#skip_grant-tables
secure_file_priv="/mydata"
#default-storage-engine=myisam 注释掉指定存储引擎为myisam这一行,其他不变
validate_password_policy=0
validate_password_length=6
... ...
# systemctl start mysqld
# mysql -uroot -p123456
mysql> create database db5;
mysql> insert into db5.a values(555);
mysql> insert into db5.a values(555);
mysql> insert into db5.a values(555);
mysql> insert into db5.a values(555);
mysql> select * from db5.a;
+------+
| id |
+------+
| 555 |
| 555 |
| 555 |
| 555 |
+------+
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| db5 | 可看到现在一共有5个库,包括我们刚创建的库db5
| mysql |
| performance_schema |
| sys |
+--------------------+
####################################################################################
innobackupex <选项>
# man innobackupex 要学会用man命令查看软件的用法,计算机知识更新很快,工作中只能靠自己不断学习
完全备份与恢复 (好处: 在线热备不锁表)
恢复时,要求/var/lib/mysql数据库目录里必须为空!
如果指定的备份目录不存在时,它会自动创建!!!如果有了,这个目录必须是空的才行!!!
如果只备份某个库,必须指定系统自带的3个库也要备份才行!sys,mysql,performance_schema
选项:
--host 主机名
--user 用户名
--port 端口号
--password 密码
--databases 数据库名
--no-timestamp 不用日期命名备份文件存储的子目录名
--redo-only 日志合并
--apply-log 准备还原(回滚日志)
--copy-back 恢复数据
--incremental 目录名 增量备份
--incremental-basedir=目录名 增量备份时,指定上一次备份数据存储的目录名
--incremental-dir=目录名 准备恢复数据时,指定增量备份数据存储的目录名
--export 导出表信息
import 导入表空间
补充:
--databases="库名" 单个库
--databases="库1 库2" 多个库
--databases="库.表" 单个表
-------------------------------------------------------------------------
完全备份与恢复
案例:将所有库完全备份到/allbak
50主机:
# ls /allbak 想指定的目录/allbak当前是不存在的
ls: 无法访问/allbak: 没有那个文件或目录
-----------------------------------------------------------------------------------
完全备份
备份的目录不需要事先创建。
# innobackupex --user root --password 123456 /allbak --no-timestamp
用户,密码,指定目录为/allbak,不以默认的日期方式来命名要加选项--no-timestamp
常见错误:
# innobackupex --user root -password 123456 /allbak --no-timestamp 选项-password前面少打一个-号都会报错
报错信息如下:
181121 17:43:36 innobackupex: Error: extra argument found /allbak
# ls /allbak 有2部分:有备份的备份数据,还有备份的配置文件(当前目录下备份的所有库的备份信息)
backup-my.cnf ib_buffer_pool mysql sys xtrabackup_info
db5 ibdata1 performance_schema xtrabackup_checkpoints xtrabackup_logfile
backup-my.cnf这个文件存的是:本次备份时的备份参数。是我们用innobackupex这个命令去备份的时候,它的配置信息
# cat /allbak/backup-my.cnf
# This MySQL options file was generated by innobackupex.
# The MySQL server
[mysqld]
innodb_checksum_algorithm=innodb
innodb_log_checksum_algorithm=innodb
innodb_data_file_path=ibdata1:10M:autoextend
innodb_log_files_in_group=2
innodb_log_file_size=5242880
innodb_fast_checksum=false
innodb_page_size=16384
innodb_log_block_size=512
innodb_undo_directory=.
innodb_undo_tablespaces=0
server_id=12
redo_log_version=0
----------------------------------------------------------------------------
完全恢复
1,准备恢复数据
# innobackupex --user root --password 123456 --apply-log /allbak 选项--apply-log是准备恢复(回滚日志)
# cat /allbak/xtrabackup_checkpoints 恢复数据后,这个文件里的内容会发生改变(了解即可)
backup_type = full-prepared backup_type有两种: full-prepared (完全备份)、incremental (增量备份)
from_lsn = 0
to_lsn = 3463884
last_lsn = 3463893
compact = 0
recover_binlog_info = 0
# systemctl stop mysqld
# rm -rf /var/lib/mysql 恢复时要求:目录是空的!
# mkdir /var/lib/mysql
2,拷贝备份文件到数据库目录下
# innobackupex --user root --password 123456 --copy-back /allbak 选项--copy-back是恢复数据
常见报错:
... ...
Original data directory /var/lib/mysql is not empty! 如果目录不是空的,就会报错!
3,修改数据库目录的文件所有者和组用户为mysql
# chown -R mysql:mysql /var/lib/mysql -R递归修改!!!一定要在恢复之后再修改归属!
4,启动数据库服务
# systemctl start mysqld
# mysql -uroot -p123456 登陆数据库查看,发现恢复成功!之前备份的共有5个库!
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| db5 |
| mysql |
| performance_schema |
| sys |
+--------------------+
##################################################################################################
增量备份与恢复
周一 先做完全备份(第1次备份时,要把所有数据全备份)
# innobackupex --user root --password 123456 /fullbak --no-timestamp
周二 向表里写新数据,做增量备份
mysql> insert into db5.a values(666);
mysql> insert into db5.a values(666);
mysql> insert into db5.a values(666);
mysql> insert into db5.a values(666);
mysql> insert into db5.a values(666);
# innobackupex --user root --password 123456 --incremental /new1dir --incremental-basedir=/fullbak --no-timestamp
周三 向表里写新数据,做增量备份
mysql> insert into db5.a values(777);
mysql> insert into db5.a values(777);
mysql> insert into db5.a values(777);
# innobackupex --user root --password 123456 --incremental /new2dir --incremental-basedir=/new1dir --no-timestamp
----------------------------------------------------------------------------------------------------
每个备份目录下都有这个文件!这个是备份的日志文件!
xtrabackup_checkpoints
innodb这个存储引擎创建的表,才支持事务日志文件,支持事务回滚
lsn 日志序列号
xtrabackup_checkpoints 存放本次备份数据的备份信息。这个文件里面有指定了本次备份的日志序列号起始范围
# cat /fullbak/xtrabackup_checkpoints 这个文件主要看前3行!
backup_type = full-backuped 备份类型=完全
from_lsn = 0 from从0开始,lsn是日志序列号
to_lsn = 3464814 to到3464814结束,下一次备份,就会从这个序列号的数字的值开始备份。
last_lsn = 3464823
compact = 0
recover_binlog_info = 0
# cat /new1dir/xtrabackup_checkpoints
backup_type = incremental 备份类型=增量
from_lsn = 3464814 from从3464814开始,就是上一次fullbak完全备份的结束点
to_lsn = 3469631 to到3469631结束
last_lsn = 3469640
compact = 0
recover_binlog_info = 0
# cat /new2dir/xtrabackup_checkpoints
backup_type = incremental 备份类型=增量
from_lsn = 3469631 from从3469631开始,就是上一次new1增量备份的结束点
to_lsn = 3474464 to到3474464结束
last_lsn = 3474473
compact = 0
recover_binlog_info = 0
-----------------------------------------------------------------------------------------------------------------
innobackupex应用案例!(实用)
增量恢复(一定要按顺序恢复!)
模拟数据丢失了
# systemctl stop mysqld
# rm -rf /var/lib/mysql
# mkdir /var/lib/mysql
1,准备恢复数据(它恢复数据和数据库是没关系的,无需连接数据库,因为之前备份过!所以当停止数据库服务后,就不需要提交用户名和密码)
# innobackupex --apply-log --redo-only /fullbak
2,合并日志文件(日志信息合并到/fullbak,同时会把增量备份目录下的数据也拷贝到/fullbak)
# innobackupex --apply-log --redo-only /fullbak --incremental-dir=/new1dir 可观察到fullbak日志文件的结束点变成和new1dir结束点一样了
# innobackupex --apply-log --redo-only /fullbak --incremental-dir=/new2dir 可观察到fullbak日志文件的结束点变成和new2dir结束点一样了
3,把拷贝备份文件到数据库目录下
# innobackupex --copy-back /fullbak
4,修改数据库目录的文件所有者和组用户为mysql(因为拷贝)
# chown -R mysql:mysql /var/lib/mysql
5,启动数据库服务
# systemctl start mysqld
它备份不锁表,单是备份到哪一行,就对哪一行加锁。
------------------------------------------------------------------------------
合并日志,不仅是把日志合在一起了,还把相应的备份的数据也合在一起了。因为合并日志里指定的开始点和结束点这些都定义了对应的表里的数据。
开另一个终端来看,日志文件/fullbak/xtrabackup_checkpoints的变化!
# cat /fullbak/xtrabackup_checkpoints
backup_type = full-backuped
from_lsn = 0
to_lsn = 3464814 此时fullbak备份的结束点是3464814
... ...
# cat /new1dir/xtrabackup_checkpoints
backup_type = incremental
from_lsn = 3464814
to_lsn = 3469631 new1dir备份的结束点是3469631
... ...
# cat /new2dir/xtrabackup_checkpoints
backup_type = incremental
from_lsn = 3469631
to_lsn = 3474464 new1dir备份的结束点是3474464
... ...
# cat /fullbak/xtrabackup_checkpoints
backup_type = log-applied
from_lsn = 0
to_lsn = 3469631 合并后,fullbak备份的结束点是3469631(因为它合并到了new1dir那里的结束点)
... ...
# cat /fullbak/xtrabackup_checkpoints
backup_type = log-applied
from_lsn = 0
to_lsn = 3474464 合并后,fullbak备份的结束点是3474464(因为它合并到了new2dir那里的结束点)
... ...
##########################################################################
恢复完全备份中的1个表
mysql> desc db5.b;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| name | char(10) | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
1 row in set (0.00 sec)
mysql> select * from db5.b;
+-------+
| name |
+-------+
| tom |
| jack |
| harry |
| lili |
| jerry |
+-------+
# ls /db5bak/
backup-my.cnf ib_buffer_pool xtrabackup_binlog_info xtrabackup_info
db5 ibdata1 xtrabackup_checkpoints xtrabackup_logfile
mysql> drop table db5.b;
# ls /var/lib/mysql/db5/
a.frm a.ibd db.opt
-----------------------------------------------------------------------------------------------------
恢复的表结构,一定要和备份时的表结构一模一样!!!表结构一定要记住!要不恢复的时候,回不来。
删除表空间必须要用mysql命令!不能用系统命令硬删
.idb 表空间文件,用来存储数据的文件就是表空间文件。一存储就会占用磁盘的空间。
创建删除的b表
mysql> create table db5.b(name char(10));
mysql> system ls /var/lib/mysql/db5;
a.frm a.ibd b.frm db.opt
删除b表的表空间文件
mysql> alter table db5.b discard tablespace; discard丢弃,tablespace表空间文件
mysql> system ls /var/lib/mysql/db5;
a.frm a.ibd b.frm db.opt
导出表信息
# innobackupex --user root --password 123456 --databases="db5" --apply-log --export /db5bak
把导出的表信息文件拷贝到数据库目录下
# cp /db5bak/db5/b.{cfg,exp,ibd} /var/lib/mysql/db5/
# chown -R mysql.mysql /var/lib/mysql/db1/*
# cd /var/lib/mysql/db5/
# ls b.*
b.cfg b.exp b.frm b.ibd 导出后产生的日志文件b.cfg b.exp
导入表空间(同时要删除多余的文件)
mysql> alter table db5.b import tablespace; import导入,tablespace表空间文件
# rm -rf /var/lib/mysql/db5/b.{cfg,exp} 导入之后,就可以删除日志文件了b.cfg b.exp
# cd /var/lib/mysql/db5/
# ls b.*
a.frm a.ibd b.frm b.ibd db.opt
########################################################
明明是innodb存储引擎创建的表a,可是在对应目录下却没有.idb的对应的表空间文件
MariaDB [db1]> show create table db1.a;
+-------+---------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+---------------------------------------------------------------------------------------+
| a | CREATE TABLE `a` (
`id` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------+---------------------------------------------------------------------------------------+
MariaDB [db1]> system ls /var/lib/mysql/db1;
a.frm db.opt
MariaDB [db1]> show variables like "innodb_file_per_table";
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| innodb_file_per_table | OFF |
+-----------------------+-------+
MariaDB [db1]> set innodb_file_per_table=on;
ERROR 1229 (HY000): Variable 'innodb_file_per_table' is a GLOBAL variable and should be set with SET GLOBAL
MariaDB [db1]> set global innodb_file_per_table=on;
MariaDB [db1]> show variables like "innodb_file_per_table";
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| innodb_file_per_table | ON |
+-----------------------+-------+
innodb系统表空间========================================
1、Innodb使用表空间进行数据存储,根据配置参数innod_file_per_table
的值,如果是ON,则存储在独立表空间--tablename.idb,如果是OFF,则存储
在系统表空间--ibdataX(默认是打开的)--> show variables like 'innodb_file_per_table;'
2、系统表空间和独立表空间要如何选择:
系统表空间无法简单的收缩文件大小
独立表空间可以通过optimize table命令收缩文件系统
系统表空间会产生IO瓶颈
独立表空间可以通过向多个文件刷新数据
3、如果把原来存在系统表空间中的表转移到独立表空间:
使用mysqldump导出所有数据库数据
停止mysql服务,修改参数,并删除innodn相关文件
重启mysql服务,重建innodb系统表空间
重新导入数据
##################################################################################################
报错:备份报错
[root@mysql50 ~]# mysqldump -uroot -p123456 -A > /mydata/alldb.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.
mysqldump: Got error: 1102: Incorrect database name '#mysql50# ' when selecting the database
这个提示它不能识别一个名叫'#mysql50# '的库
[root@mysql50 mysql]# mysql -uroot -p123456
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| #mysql50# | 可以发现这里有一个库#mysql50#
| bbsdb |
| db1 |
| db2 |
| db3 |
| db4 |
| db44 |
| gamedb |
| mysql |
| performance_schema |
| studb |
| sys |
+--------------------+
mysql> drop database #mysql50#; 无法删除这个库#mysql50#
mysql> quit
[root@mysql50 mysql]# pwd
/var/lib/mysql
[root@mysql50 mysql]# ll
总用量 188500
drwxr-x--x. 13 root root 4096 11月 21 09:10 发现这里有一个很奇怪的目录,名字居然是空,而且所有者是root
-rw-r-----. 1 mysql mysql 56 11月 16 10:24 auto.cnf
drwxr-x---. 2 mysql mysql 20 11月 16 14:05 bbsdb
-rw-------. 1 mysql mysql 1679 11月 16 10:24 ca-key.pem
-rw-r--r--. 1 mysql mysql 1074 11月 16 10:24 ca.pem
-rw-r--r--. 1 mysql mysql 1078 11月 16 10:24 client-cert.pem
-rw-------. 1 mysql mysql 1675 11月 16 10:24 client-key.pem
drwxr-x---. 2 mysql mysql 216 11月 16 17:56 db1
drwxr-x---. 2 mysql mysql 4096 11月 17 17:48 db2
drwxr-x---. 2 mysql mysql 90 11月 21 08:32 db3
drwxr-x---. 2 mysql mysql 4096 11月 20 11:39 db4
drwxr-x---. 2 mysql mysql 20 11月 16 12:00 gamedb
-rw-r-----. 1 mysql mysql 525 11月 21 10:53 ib_buffer_pool
-rw-r-----. 1 mysql mysql 79691776 11月 21 10:53 ibdata1
-rw-r-----. 1 mysql mysql 50331648 11月 21 10:53 ib_logfile0
-rw-r-----. 1 mysql mysql 50331648 11月 16 10:24 ib_logfile1
-rw-r-----. 1 mysql mysql 12582912 11月 21 10:53 ibtmp1
drwxr-x---. 2 mysql mysql 4096 11月 16 10:24 mysql
srwxrwxrwx. 1 mysql mysql 0 11月 21 10:53 mysql.sock
-rw-------. 1 mysql mysql 5 11月 21 10:53 mysql.sock.lock
drwxr-x---. 2 mysql mysql 8192 11月 16 10:24 performance_schema
-rw-------. 1 mysql mysql 1679 11月 16 10:24 private_key.pem
-rw-r--r--. 1 mysql mysql 451 11月 16 10:24 public_key.pem
-rw-r--r--. 1 mysql mysql 1078 11月 16 10:24 server-cert.pem
-rw-------. 1 mysql mysql 1675 11月 16 10:24 server-key.pem
drwxr-x---. 2 mysql mysql 20 11月 16 14:39 studb
drwxr-x---. 2 mysql mysql 8192 11月 16 10:24 sys
[root@mysql50 mysql]# rm -rf ' '
[root@mysql50 mysql]# ll 发现已经成功删除了那个很奇怪的目录
总用量 188496
-rw-r-----. 1 mysql mysql 56 11月 16 10:24 auto.cnf
drwxr-x---. 2 mysql mysql 20 11月 16 14:05 bbsdb
-rw-------. 1 mysql mysql 1679 11月 16 10:24 ca-key.pem
-rw-r--r--. 1 mysql mysql 1074 11月 16 10:24 ca.pem
-rw-r--r--. 1 mysql mysql 1078 11月 16 10:24 client-cert.pem
-rw-------. 1 mysql mysql 1675 11月 16 10:24 client-key.pem
drwxr-x---. 2 mysql mysql 216 11月 16 17:56 db1
drwxr-x---. 2 mysql mysql 4096 11月 17 17:48 db2
drwxr-x---. 2 mysql mysql 90 11月 21 08:32 db3
drwxr-x---. 2 mysql mysql 4096 11月 20 11:39 db4
drwxr-x---. 2 mysql mysql 20 11月 16 12:00 gamedb
-rw-r-----. 1 mysql mysql 525 11月 21 10:53 ib_buffer_pool
-rw-r-----. 1 mysql mysql 79691776 11月 21 10:53 ibdata1
-rw-r-----. 1 mysql mysql 50331648 11月 21 10:53 ib_logfile0
-rw-r-----. 1 mysql mysql 50331648 11月 16 10:24 ib_logfile1
-rw-r-----. 1 mysql mysql 12582912 11月 21 10:53 ibtmp1
drwxr-x---. 2 mysql mysql 4096 11月 16 10:24 mysql
srwxrwxrwx. 1 mysql mysql 0 11月 21 10:53 mysql.sock
-rw-------. 1 mysql mysql 5 11月 21 10:53 mysql.sock.lock
drwxr-x---. 2 mysql mysql 8192 11月 16 10:24 performance_schema
-rw-------. 1 mysql mysql 1679 11月 16 10:24 private_key.pem
-rw-r--r--. 1 mysql mysql 451 11月 16 10:24 public_key.pem
-rw-r--r--. 1 mysql mysql 1078 11月 16 10:24 server-cert.pem
-rw-------. 1 mysql mysql 1675 11月 16 10:24 server-key.pem
drwxr-x---. 2 mysql mysql 20 11月 16 14:39 studb
drwxr-x---. 2 mysql mysql 8192 11月 16 10:24 sys
[root@mysql50 mysql]# mysql -uroot -p123456
mysql> show databases; 登陆数据库,发现成功删除那个库
+--------------------+
| Database |
+--------------------+
| information_schema |
| bbsdb |
| db1 |
| db2 |
| db3 |
| db4 |
| gamedb |
| mysql |
| performance_schema |
| studb |
| sys |
+--------------------+