快捷搜索:
来自 网络数据库 2019-11-06 06:47 的文章
当前位置: 67677新澳门手机版 > 网络数据库 > 正文

新京葡娱乐场网址:xtrabackup用法和原理详述,

MariaDB/MySQL备份恢复系列:
备份和恢复(一):mysqldump工具用法详述
备份和恢复(二):导入、导出表数据
备份和恢复(三):xtrabackup用法和原理详述

这里参考了jeanron大师的文章:
经过前边恶心的安装以后,接下来尝试一番xtrabackup的备份功能。
xtrabackup主要是用于热备份innodb,或者是 xtradb表中数据的工具,不能备份其他类型的表,也不能备份数据表结构;
innobackupex是将xtrabackup进行封装的perl脚本,可以备份和恢复MyISAM表以及数据表结构。
**


1、备份的解析

**
从innobackupex –help命令可以看到innobackupex 的参数有很多,下面尝试做一个全备。

[root@cxqtest ~]# cd /data/backup/0408/
[root@cxqtest 0408]# innobackupex -S /data/3306/mysql.sock /data/backup/0408/ --no-timestamp --no-lock --throttle=100
170304 11:00:41 innobackupex: Starting the backup operation

IMPORTANT: Please check that the backup run completes successfully.
           At the end of a successful backup run innobackupex
           prints "completed OK!".

170304 11:00:42  version_check Connecting to MySQL server with DSN 'dbi:mysql:;mysql_read_default_group=xtrabackup;port=3306;mysql_socket=/data/3306/mysql.sock' (using password: NO).
Failed to connect to MySQL server: DBI connect(';mysql_read_default_group=xtrabackup;port=3306;mysql_socket=/data/3306/mysql.sock','',...) failed: Access denied for user 'root'@'localhost' (using password: NO) at - line 1314
170304 11:00:43 Connecting to MySQL server host: localhost, user: not set, password: not set, port: 3306, socket: /data/3306/mysql.sock
Failed to connect to MySQL server: Access denied for user 'root'@'localhost' (using password: NO).
[root@cxqtest 0408]# innobackupex -S /data/3306/mysql.sock /data/backup/0408/ --no-timestamp --no-lock --throttle=100 -uroot -p
innobackupex: [ERROR] innobackupex: option '-p' requires an argument

报错了,原因是没有写上用户名密码

[root@cxqtest 0408]# innobackupex -S /data/3306/mysql.sock /data/backup/0408/ --no-timestamp --no-lock --throttle=100 -uroot -pmysql123
170304 11:01:24 innobackupex: Starting the backup operation

IMPORTANT: Please check that the backup run completes successfully.
           At the end of a successful backup run innobackupex
           prints "completed OK!".

170304 11:01:24  version_check Connecting to MySQL server with DSN 'dbi:mysql:;mysql_read_default_group=xtrabackup;port=3306;mysql_socket=/data/3306/mysql.sock' as 'root'  (using password: YES).
170304 11:01:24  version_check Connected to MySQL server
170304 11:01:24  version_check Executing a version check against the server...
170304 11:01:24  version_check Done.
170304 11:01:24 Connecting to MySQL server host: localhost, user: root, password: set, port: 3306, socket: /data/3306/mysql.sock
Using server version 5.6.30-log
innobackupex version 2.4.6 based on MySQL server 5.7.13 Linux (x86_64) (revision id: 8ec05b7)
xtrabackup: uses posix_fadvise().
xtrabackup: cd to /data/3306/data
xtrabackup: open files limit requested 65535, set to 65535
xtrabackup: using the following InnoDB configuration:
xtrabackup:   innodb_data_home_dir = .
xtrabackup:   innodb_data_file_path = ibdata1:1G:autoextend
xtrabackup:   innodb_log_group_home_dir = ./
xtrabackup:   innodb_log_files_in_group = 3
xtrabackup:   innodb_log_file_size = 524288000
xtrabackup: using O_DIRECT
InnoDB: Number of pools: 1
170304 11:01:25 >> log scanned up to (1626008)
xtrabackup: Generating a list of tablespaces
InnoDB: Allocated tablespace ID 1 for mysql/innodb_table_stats, old maximum was 0
170304 11:01:25 [01] Copying ./ibdata1 to /data/backup/0408/ibdata1
170304 11:01:26 >> log scanned up to (1626008)
170304 11:01:27 >> log scanned up to (1626008)
.....
xtrabackup: The latest check point (for incremental): '1626008'
xtrabackup: Stopping log copying thread.
.170304 11:02:00 >> log scanned up to (1626008)

170304 11:02:01 Backup created in directory '/data/backup/0408/'
MySQL binlog position: filename 'mybinlog.000006', position '191', GTID of the last change '82f3c6ed-007a-11e7-9b50-000c298ee31c:1-7'
170304 11:02:01 [00] Writing backup-my.cnf
170304 11:02:01 [00]        ...done
170304 11:02:01 [00] Writing xtrabackup_info
170304 11:02:01 [00]        ...done
xtrabackup: Transaction log of lsn (1626008) to (1626008) was copied.
170304 11:02:01 completed OK!

经过一段时间的备份,可以看到备份完成了
让我们查看一下备份文件如下:

[root@cxqtest 0408]# du -sh 
1.1G    .
[root@cxqtest 0408]# du -sh ./*
4.0K    ./backup-my.cnf
1.1G    ./ibdata1
1.7M    ./mysql
636K    ./performance_schema
4.0K    ./test
4.0K    ./xtrabackup_binlog_info
4.0K    ./xtrabackup_checkpoints
4.0K    ./xtrabackup_info
4.0K    ./xtrabackup_logfile

可以看到备份了my.cnf,ibdata1,各种数据库,这时候还多出来几个xtrabackup打头的文件
查看这几个文件的内容如下:
–xtrabackup_binlog_info文件记录了对应当下binlog的信息

[root@cxqtest 0408]# more xtrabackup_binlog_info
more xtrabackup_binlog_info
mybinlog.000006 191 82f3c6ed-007a-11e7-9b50-000c298ee31c:1-7

–xtrabackup_checkpoints记录了备份的类型是全备,是从0到1626008的最新的全备

[root@cxqtest 0408]# more xtrabackup_checkpoints
backup_type = full-backupedf
rom_lsn = 0
to_lsn = 1626008
last_lsn = 1626008
compact = 0
recover_binlog_info = 0

–xtrabackup_info记录的是命令的信息

[root@cxqtest 0408]# more xtrabackup_info
uuid = f0083067-0086-11e7-8435-000c298ee31c
name = innobackupextool
command = -S /data/3306/mysql.sock /data/backup/0408/ --no-timestamp --no-lock --throttle=100 -uroot -pmysql123
version = 2.4.6
ibbackup_version = 2.4.6
server_version = 5.6.30
logstart_time = 2017-03-04 11:01:24
end_time = 2017-03-04 11:02:01
lock_time = 1488596521
binlog_pos = filename 'mybinlog.000006', position '191', 
GTID of the last change '82f3c6ed-007a-11e7-9b50-000c298ee31c:1-7'
innodb_from_lsn = 0
innodb_to_lsn = 1626008
partial = N
incremental = N
format = file
compact = N
compressed = N
encrypted = N

–xtrabackup_logfile 看到logfile无法用more查看,是一个二进制日志文件格式,所以使用strings进行查看如下:
记录的是备份的时间

[root@cxqtest 0408]# more xtrabackup_logfile
--More--(88%)

?庰掟栶氿烉︷
[root@cxqtest 0408]# XshellXshellXshellXshellXshellXshellXshellXshellXshellXshell -bash: XshellXshellXshellXshellXshellXshellXshellXshellXshellXshell: command not found
[root@cxqtest 0408]#
 [root@cxqtest 0408]# strings xtrabackup_log
 filextrabkup 170304 11:01:25

xtrabackup是percona团队研发的备份工具,比MySQL官方的ibbackup的功能还要多。支持myisam温全备、innodb热全备和温增备,还可以实现innodb的定时点恢复,而且备份和恢复的速度都较快。在目前MySQL的备份实现上,考虑价格、速度、安全、一致性等角度,xtrabackup是非常合适的工具。

2、全备恢复测试

数据的恢复还是使用innobackupex这个工具
这里的数据恢复分为两个步骤,prepare和还原恢复,prepare意义是如果我们备份数据的时候,存在未提交的事务,但是数据却存在于备份中,这样就是一个数据不一致的状态,在启动数据库的时候需要走一个前滚,然后是一个回滚的操作。这个体现主要就在于logfile和ibdata。是使用apply-log这个选项实现的。
前提需要先将之前的目录删除,停掉mysql服务。

[root@cxqtest 0408]# /etc/init.d/mysqld stop
Shutting down MySQL...                                     [  OK  ]
[root@cxqtest 0408]# 
[root@cxqtest 0408]# cd 
[root@cxqtest ~]# 
[root@cxqtest 3306]# ls
data
[root@cxqtest 3306]# mv data data.bak
[root@cxqtest 3306]# ls
data.bak
[root@cxqtest 3306]# mkdir data

可以使用如下命令进行恢复操作:
第一步:执行innobackupex –defaults-file=/data/backup/0408/backup-my.cnf -uroot -pmysql123 –apply-log /data/backup/0408/

[root@cxqtest 0408]# innobackupex --defaults-file=/data/backup/0408/backup-my.cnf -uroot -pmysql123 --apply-log /data/backup/0408/
170304 12:31:01 innobackupex: Starting the apply-log operation

IMPORTANT: Please check that the apply-log run completes successfully.
           At the end of a successful apply-log run innobackupex
           prints "completed OK!".

innobackupex version 2.4.6 based on MySQL server 5.7.13 Linux (x86_64) (revision id: 8ec05b7)
xtrabackup: cd to /data/backup/0408/
xtrabackup: This target seems to be not prepared yet.
InnoDB: Number of pools: 1
xtrabackup: xtrabackup_logfile detected: size=8388608, start_lsn=(1626008)
xtrabackup: using the following InnoDB configuration for recovery:
xtrabackup:   innodb_data_home_dir = .
xtrabackup:   innodb_data_file_path = ibdata1:1G:autoextend
xtrabackup:   innodb_log_group_home_dir = .
xtrabackup:   innodb_log_files_in_group = 1
xtrabackup:   innodb_log_file_size = 8388608
xtrabackup: using the following InnoDB configuration for recovery:
xtrabackup:   innodb_data_home_dir = .
xtrabackup:   innodb_data_file_path = ibdata1:1G:autoextend
xtrabackup:   innodb_log_group_home_dir = .
xtrabackup:   innodb_log_files_in_group = 1
xtrabackup:   innodb_log_file_size = 8388608
xtrabackup: Starting InnoDB instance for recovery.
xtrabackup: Using 104857600 bytes for buffer pool (set by --use-memory parameter)
InnoDB: PUNCH HOLE support available
InnoDB: Mutexes and rw_locks use GCC atomic builtins
InnoDB: Uses event mutexes
InnoDB: GCC builtin __sync_synchronize() is used for memory barrier
InnoDB: Compressed tables use zlib 1.2.3
InnoDB: Number of pools: 1
InnoDB: Using CPU crc32 instructions
InnoDB: Initializing buffer pool, total size = 100M, instances = 1, chunk size = 100M
InnoDB: Completed initialization of buffer pool
InnoDB: page_cleaner coordinator priority: -20
InnoDB: Highest supported file format is Barracuda.
InnoDB: The log sequence number 1625998 in the system tablespace does not match the log sequence number 1626008 in the ib_logfiles!
InnoDB: Database was not shutdown normally!
InnoDB: Starting crash recovery.
InnoDB: Doing recovery: scanned up to log sequence number 1626008 (0%)
InnoDB: Creating shared tablespace for temporary tables
InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
InnoDB: File './ibtmp1' size is now 12 MB.
InnoDB: 96 redo rollback segment(s) found. 1 redo rollback segment(s) are active.
InnoDB: 32 non-redo rollback segment(s) are active.
InnoDB: Waiting for purge to start
InnoDB: 5.7.13 started; log sequence number 1626008

xtrabackup: starting shutdown with innodb_fast_shutdown = 1
InnoDB: FTS optimize thread exiting.
InnoDB: Starting shutdown...
InnoDB: Shutdown completed; log sequence number 1626027
InnoDB: Number of pools: 1
xtrabackup: using the following InnoDB configuration for recovery:
xtrabackup:   innodb_data_home_dir = .
xtrabackup:   innodb_data_file_path = ibdata1:1G:autoextend
xtrabackup:   innodb_log_group_home_dir = .
xtrabackup:   innodb_log_files_in_group = 3
xtrabackup:   innodb_log_file_size = 524288000
InnoDB: PUNCH HOLE support available
InnoDB: Mutexes and rw_locks use GCC atomic builtins
InnoDB: Uses event mutexes
InnoDB: GCC builtin __sync_synchronize() is used for memory barrier
InnoDB: Compressed tables use zlib 1.2.3
InnoDB: Number of pools: 1
InnoDB: Using CPU crc32 instructions
InnoDB: Initializing buffer pool, total size = 100M, instances = 1, chunk size = 100M
InnoDB: Completed initialization of buffer pool
InnoDB: page_cleaner coordinator priority: -20
InnoDB: Setting log file ./ib_logfile101 size to 500 MB
InnoDB: Progress in MB:
 100 200 300 400 500
InnoDB: Setting log file ./ib_logfile1 size to 500 MB
InnoDB: Progress in MB:
 100 200 300 400 500
InnoDB: Setting log file ./ib_logfile2 size to 500 MB
InnoDB: Progress in MB:
 100 200 300 400 500
InnoDB: Renaming log file ./ib_logfile101 to ./ib_logfile0
InnoDB: New log files created, LSN=1626027
InnoDB: Highest supported file format is Barracuda.
InnoDB: Log scan progressed past the checkpoint lsn 1626124
InnoDB: Doing recovery: scanned up to log sequence number 1626133 (0%)
InnoDB: Doing recovery: scanned up to log sequence number 1626133 (0%)
InnoDB: Database was not shutdown normally!
InnoDB: Starting crash recovery.
InnoDB: Removed temporary tablespace data file: "ibtmp1"
InnoDB: Creating shared tablespace for temporary tables
InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
InnoDB: File './ibtmp1' size is now 12 MB.
InnoDB: 96 redo rollback segment(s) found. 1 redo rollback segment(s) are active.
InnoDB: 32 non-redo rollback segment(s) are active.
InnoDB: Waiting for purge to start
InnoDB: page_cleaner: 1000ms intended loop took 54592ms. The settings might not be optimal. (flushed=0 and evicted=0, during the time.)
InnoDB: 5.7.13 started; log sequence number 1626133
xtrabackup: starting shutdown with innodb_fast_shutdown = 1
InnoDB: FTS optimize thread exiting.
InnoDB: Starting shutdown...
InnoDB: Shutdown completed; log sequence number 1626152
170304 12:32:00 completed OK!

然后执行如下:

[root@cxqtest 0408]# innobackupex --defaults-file=/data/backup/0408/backup-my.cnf -uroot -pmysql123 --copy-back /data/backup/0408/
170304 12:32:42 innobackupex: Starting the copy-back operation

IMPORTANT: Please check that the copy-back run completes successfully.
           At the end of a successful copy-back run innobackupex
           prints "completed OK!".

innobackupex version 2.4.6 based on MySQL server 5.7.13 Linux (x86_64) (revision id: 8ec05b7)
Error: datadir must be specified.

报错要执行datadir,原因是我指定的参数文件是备份的backup-my.cnf内容如下:

[root@cxqtest 0408]# cat backup-my.cnf 

[mysqld]
innodb_checksum_algorithm=innodb
innodb_log_checksum_algorithm=innodb
innodb_data_file_path=ibdata1:1G:autoextend
innodb_log_files_in_group=3
innodb_log_file_size=524288000
innodb_fast_checksum=false
innodb_page_size=16384
innodb_log_block_size=512
innodb_undo_directory=.
innodb_undo_tablespaces=0
server_id=3306

redo_log_version=0

由于没有指定datadir导致报错,所以报错,这里直接指定原来的/etc/my.cnf

[root@cxqtest 3306]# innobackupex --defaults-file=/etc/my.cnf  -uroot -pmysql123 --copy-back /data/backup/0408/
170304 12:47:01 innobackupex: Starting the copy-back operation

IMPORTANT: Please check that the copy-back run completes successfully.
           At the end of a successful copy-back run innobackupex
           prints "completed OK!".

innobackupex version 2.4.6 based on MySQL server 5.7.13 Linux (x86_64) (revision id: 8ec05b7)
170304 12:47:01 [01] Copying ib_logfile0 to /data/3306/data/ib_logfile0
170304 12:47:22 [01]        ...done
170304 12:47:22 [01] Copying ib_logfile1 to /data/3306/data/ib_logfile1
170304 12:47:54 [01]        ...done
170304 12:47:55 [01] Copying ib_logfile2 to /data/3306/data/ib_logfile2
innobackupex: Error writing file '/data/3306/data/ib_logfile2' (Errcode: 28 - No space left on device)
[01] Error: copy_file() failed.

再一次报错:不过这次报错很明显
innobackupex: Error writing file ‘/data/3306/data/ib_logfile2’ (Errcode: 28 - No space left on device)
然后查看df -h:空间满了,无奈删除了一些其他的文件

[root@cxqtest 3306]# df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda2        36G   36G     0 100% /
tmpfs           1.2G   68K  1.2G   1% /dev/shm
/dev/sda1       194M   34M  150M  19% /boot
[root@cxqtest 0408]# df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda2        36G   28G  5.6G  84% /
tmpfs           1.2G   68K  1.2G   1% /dev/shm
/dev/sda1       194M   34M  150M  19% /boot

然后继续如上的步骤:

[root@cxqtest 3306]# innobackupex --defaults-file=/etc/my.cnf  -uroot -pmysql123 --copy-back /data/backup/0408/
170304 12:50:52 innobackupex: Starting the copy-back operation


IMPORTANT: Please check that the copy-back run completes successfully.
           At the end of a successful copy-back run innobackupex
           prints "completed OK!".


innobackupex version 2.4.6 based on MySQL server 5.7.13 Linux (x86_64) (revision id: 8ec05b7)
Original data directory /data/3306/data is not empty!

又报错!!!原因是第一次copyback回去了部分数据,目录不为空导致无法进行,然后将对应目录清空,继续进行如上copy-back操作

[root@cxqtest data]# innobackupex --defaults-file=/etc/my.cnf  -uroot -pmysql123 --copy-back /data/backup/0408/
170304 12:51:57 innobackupex: Starting the copy-back operation

IMPORTANT: Please check that the copy-back run completes successfully.
           At the end of a successful copy-back run innobackupex
           prints "completed OK!".

innobackupex version 2.4.6 based on MySQL server 5.7.13 Linux (x86_64) (revision id: 8ec05b7)
170304 12:51:57 [01] Copying ib_logfile0 to /data/3306/data/ib_logfile0
170304 12:52:18 [01]        ...done
170304 12:52:18 [01] Copying ib_logfile1 to /data/3306/data/ib_logfile1
170304 12:52:42 [01]        ...done
170304 12:52:42 [01] Copying ib_logfile2 to /data/3306/data/ib_logfile2
170304 12:53:06 [01]        ...done
170304 12:53:07 [01] Copying ibdata1 to /data/3306/data/ibdata1
170304 12:53:54 [01]        ...done
.......省略一堆的copy输出日志
170304 12:53:56 [01] Copying ./xtrabackup_info to /data/3306/data/xtrabackup_info
170304 12:53:56 [01]        ...done
170304 12:53:56 completed OK!
[root@cxqtest data]# 
[root@cxqtest data]# 
[root@cxqtest data]# ls
ibdata1  ib_logfile0  ib_logfile1  ib_logfile2  ibtmp1  mysql  performance_schema  test  xtrabackup_info
[root@cxqtest data]# pwd
/data/3306/data

终于将3306恢复回来了
然后将对应的属组修改回MySQL,默认是root。启动MySQL服务登陆正常

[root@cxqtest data]# ll
total 2596892
-rw-r----- 1 root root 1073741824 Mar  4 12:53 ibdata1
-rw-r----- 1 root root  524288000 Mar  4 12:52 ib_logfile0
-rw-r----- 1 root root  524288000 Mar  4 12:52 ib_logfile1
-rw-r----- 1 root root  524288000 Mar  4 12:53 ib_logfile2
-rw-r----- 1 root root   12582912 Mar  4 12:53 ibtmp1
drwxr-x--- 2 root root       4096 Mar  4 12:53 mysql
drwxr-x--- 2 root root       4096 Mar  4 12:53 performance_schema
drwxr-x--- 2 root root       4096 Mar  4 12:53 test
-rw-r----- 1 root root        606 Mar  4 12:53 xtrabackup_info
[root@cxqtest data]# chown -R mysql.mysql /data/3306/data
[root@cxqtest data]# ll
total 2596892
-rw-r----- 1 mysql mysql 1073741824 Mar  4 12:53 ibdata1
-rw-r----- 1 mysql mysql  524288000 Mar  4 12:52 ib_logfile0
-rw-r----- 1 mysql mysql  524288000 Mar  4 12:52 ib_logfile1
-rw-r----- 1 mysql mysql  524288000 Mar  4 12:53 ib_logfile2
-rw-r----- 1 mysql mysql   12582912 Mar  4 12:53 ibtmp1
drwxr-x--- 2 mysql mysql       4096 Mar  4 12:53 mysql
drwxr-x--- 2 mysql mysql       4096 Mar  4 12:53 performance_schema
drwxr-x--- 2 mysql mysql       4096 Mar  4 12:53 test
-rw-r----- 1 mysql mysql        606 Mar  4 12:53 xtrabackup_info
[root@cxqtest data]# /etc/init.d/mysqld start
Starting MySQL................                             [  OK  ]
[root@cxqtest data]# 
[root@cxqtest data]# 
[root@cxqtest data]# mysql -uroot -p
mysEnter password: 
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
[root@cxqtest data]# mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or g.
Your MySQL connection id is 2
Server version: 5.6.30-log Source distribution

Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.

root@localhost:mysql.sock  12:56:04 [(none)]>
root@localhost:mysql.sock  12:56:05 [(none)]>
root@localhost:mysql.sock  12:56:05 [(none)]>
root@localhost:mysql.sock  12:56:05 [(none)]>show databases;
 -------------------- 
| Database           |
 -------------------- 
| information_schema |
| mysql              |
| performance_schema |
| test               |
 -------------------- 
4 rows in set (0.14 sec)

root@localhost:mysql.sock  12:56:08 [(none)]>
root@localhost:mysql.sock  12:56:09 [(none)]>
root@localhost:mysql.sock  12:56:09 [(none)]>exit

MariaDB也可以使用percona xtrabackup进行备份,不过MariaDB基于percona xtrabackup开发了它自己的备份工具:MariaDB Backup。它基于xtrabackup开发,所以所用方法基本和xtrabackup相同,只是有些自己的特性。详细内容见MariaDB Backup官方手册:https://mariadb.com/kb/en/library/mariadb-backup/

3、增量的备份恢复操作

然后进行一下增量备份恢复的测试工作:
首先在test数据库下创建一张测试表:

root@localhost:mysql.sock  13:15:47 [(none)]>use test;
Database changed
root@localhost:mysql.sock  13:15:49 [test]>
root@localhost:mysql.sock  13:15:49 [test]>
root@localhost:mysql.sock  13:15:49 [test]>
root@localhost:mysql.sock  13:15:49 [test]>show tables;
Empty set (0.05 sec)

root@localhost:mysql.sock  13:15:56 [test]>
root@localhost:mysql.sock  13:15:57 [test]>
root@localhost:mysql.sock  13:15:57 [test]>create table t(id int ,name varchar(10));
Query OK, 0 rows affected (0.80 sec)

root@localhost:mysql.sock  13:16:28 [test]>insert into t values(1,'a'),(2,'b'),(3,'c'),(4,'d');
Query OK, 4 rows affected (0.07 sec)
Records: 4  Duplicates: 0  Warnings: 0

root@localhost:mysql.sock  13:17:52 [test]>select * from t;
 ------ ------ 
| id   | name |
 ------ ------ 
|    1 | a    |
|    2 | b    |
|    3 | c    |
|    4 | d    |
 ------ ------ 
4 rows in set (0.00 sec)

由于之前已经做过了全备了,所以这里就直接可以做增量备份。
使用如下命令进行增量备份:

innobackupex --defaults-file=/etc/my.cnf -uroot -pmysql123 --incremental-basedir=/data/backup/0408/incr --incremental /data/backup/0408/incr

很不幸失败了:

[root@cxqtest incr]# innobackupex --defaults-file=/etc/my.cnf -uroot -pmysql123 --incremental-basedir=/data/backup/0408/incr --incremental /data/backup/0408/incr
170304 13:21:17 innobackupex: Starting the backup operation

IMPORTANT: Please check that the backup run completes successfully.
           At the end of a successful backup run innobackupex
           prints "completed OK!".

xtrabackup: Error: cannot open /data/backup/0408/incr//xtrabackup_checkpoints
xtrabackup: error: failed to read metadata from /data/backup/0408/incr//xtrabackup_checkpoints

原因嘛,也给出来了

error: failed to read metadata from /data/backup/0408/incr//xtrabackup_checkpoints

当然,这个错误很明显,就是要找到之前全备的一个基点,也就是增量备的起始点lsn,这样才能进行增量备份,但是这里我直接指定了增量备份的basedir目录/data/backup/0408/incr,所以导致报了错,然后修改回来就没有问题了。这里引用jeanron大师的总结,很精辟:
原因就在于里面的一个关键文件 _checkpoints
使用增备得有一个参考点,从哪里开始,即从哪个LSN开始,这个LSN在指定的参数–incremental-basedir=/data/backup/0408/incr下不存在,因为这个是一个新目录,所以需要指向全库备份的目录。
然后修复后备份就没问题了,英为有了这个参考点LSN,所以需要要说明的是这个备份其实有累计增量和差异增量了。
这个怎么理解呢,比如周日做一个全备,周一做一个增备,周二做一个周日全备到周二的一个增备,这就是一个累计增量备份,而周三的时候做一个周二至周三数据变化的备份,就是一个差异增量备份。

[root@cxqtest incr]# innobackupex --defaults-file=/etc/my.cnf -uroot -pmysql123 --incremental-basedir=/data/backup/0408/ --incremental /data/backup/0408/incr
170304 13:21:52 innobackupex: Starting the backup operation

IMPORTANT: Please check that the backup run completes successfully.
           At the end of a successful backup run innobackupex
           prints "completed OK!".

170304 13:21:53  version_check Connecting to MySQL server with DSN 'dbi:mysql:;mysql_read_default_group=xtrabackup;port=3306;mysql_socket=/data/3306/mysql.sock' as 'root'  (using password: YES).
170304 13:21:53  version_check Connected to MySQL server
170304 13:21:53  version_check Executing a version check against the server...
170304 13:21:53  version_check Done.
170304 13:21:53 Connecting to MySQL server host: localhost, user: root, password: set, port: 3306, socket: /data/3306/mysql.sock
Using server version 5.6.30-log
innobackupex version 2.4.6 based on MySQL server 5.7.13 Linux (x86_64) (revision id: 8ec05b7)
incremental backup from 1626008 is enabled.
xtrabackup: uses posix_fadvise().
xtrabackup: cd to /data/3306/data
xtrabackup: open files limit requested 65535, set to 65535
xtrabackup: using the following InnoDB configuration:
xtrabackup:   innodb_data_home_dir = .
xtrabackup:   innodb_data_file_path = ibdata1:1G:autoextend
xtrabackup:   innodb_log_group_home_dir = ./
xtrabackup:   innodb_log_files_in_group = 3
xtrabackup:   innodb_log_file_size = 524288000
xtrabackup: using O_DIRECT
InnoDB: Number of pools: 1
170304 13:21:53 >> log scanned up to (1634925)
xtrabackup: Generating a list of tablespaces
InnoDB: Allocated tablespace ID 1 for mysql/innodb_table_stats, old maximum was 0
xtrabackup: using the full scan for incremental backup
170304 13:21:54 >> log scanned up to (1634925)
170304 13:21:55 [01] Copying ./ibdata1 to /data/backup/0408/incr/2017-03-04_13-21-52/ibdata1.delta
170304 13:21:55 >> log scanned up to (1634925)
.....
170304 13:22:14 [01]        ...done
......
170304 13:22:18 Finished backing up non-InnoDB tables and files
170304 13:22:18 [00] Writing xtrabackup_binlog_info
170304 13:22:18 [00]        ...done
170304 13:22:18 Executing FLUSH NO_WRITE_TO_BINLOG ENGINE LOGS...
xtrabackup: The latest check point (for incremental): '1634925'
xtrabackup: Stopping log copying thread.
.170304 13:22:18 >> log scanned up to (1634925)

170304 13:22:18 Executing UNLOCK TABLES
170304 13:22:18 All tables unlocked
170304 13:22:18 Backup created in directory '/data/backup/0408/incr/2017-03-04_13-21-52/'
MySQL binlog position: filename 'mybinlog.000001', position '574', GTID of the last change 'd26bc1be-0096-11e7-9c08-000c298ee31c:1-2'
170304 13:22:18 [00] Writing backup-my.cnf
170304 13:22:18 [00]        ...done
170304 13:22:18 [00] Writing xtrabackup_info
170304 13:22:18 [00]        ...done
xtrabackup: Transaction log of lsn (1634925) to (1634925) was copied.
170304 13:22:18 completed OK!
[root@cxqtest incr]# ls
2017-03-04_13-21-17  2017-03-04_13-21-52

为了区别两次增量的不同,继续插入

root@localhost:mysql.sock  13:31:16 [test]>insert into t values(5,'e'),(6,'f');
Query OK, 2 rows affected (0.03 sec)
Records: 2  Duplicates: 0  Warnings: 0

root@localhost:mysql.sock  13:31:36 [test]>select * from t;
 ------ ------ 
| id   | name |
 ------ ------ 
|    1 | a    |
|    2 | b    |
|    3 | c    |
|    4 | d    |
|    5 | e    |
|    6 | f    |
 ------ ------ 
6 rows in set (0.00 sec)

再次进行基于上一次增量备份的增量备份:

[root@cxqtest incr]# innobackupex --defaults-file=/etc/my.cnf -uroot -pmysql123 --incremental-basedir=/data/backup/0408/incr/2017-03-04_13-21-52 --incremental /data/backup/0408/incr
170304 13:35:29 innobackupex: Starting the backup operation

IMPORTANT: Please check that the backup run completes successfully.
           At the end of a successful backup run innobackupex
           prints "completed OK!".

170304 13:35:29  version_check Connecting to MySQL server with DSN 'dbi:mysql:;mysql_read_default_group=xtrabackup;port=3306;mysql_socket=/data/3306/mysql.sock' as 'root'  (using password: YES).
170304 13:35:29  version_check Connected to MySQL server
170304 13:35:29  version_check Executing a version check against the server...
170304 13:35:29  version_check Done.
170304 13:35:29 Connecting to MySQL server host: localhost, user: root, password: set, port: 3306, socket: /data/3306/mysql.sock
Using server version 5.6.30-log
innobackupex version 2.4.6 based on MySQL server 5.7.13 Linux (x86_64) (revision id: 8ec05b7)
incremental backup from 1634925 is enabled.
xtrabackup: uses posix_fadvise().
xtrabackup: cd to /data/3306/data
xtrabackup: open files limit requested 65535, set to 65535
xtrabackup: using the following InnoDB configuration:
xtrabackup:   innodb_data_home_dir = .
xtrabackup:   innodb_data_file_path = ibdata1:1G:autoextend
xtrabackup:   innodb_log_group_home_dir = ./
xtrabackup:   innodb_log_files_in_group = 3
xtrabackup:   innodb_log_file_size = 524288000
xtrabackup: using O_DIRECT
InnoDB: Number of pools: 1
170304 13:35:29 >> log scanned up to (1639553)
......
170304 13:35:49 Executing FLUSH NO_WRITE_TO_BINLOG ENGINE LOGS...
xtrabackup: The latest check point (for incremental): '1639553'
xtrabackup: Stopping log copying thread.
.170304 13:35:49 >> log scanned up to (1639553)

170304 13:35:49 Executing UNLOCK TABLES
170304 13:35:49 All tables unlocked
170304 13:35:49 Backup created in directory '/data/backup/0408/incr/2017-03-04_13-35-29/'
MySQL binlog position: filename 'mybinlog.000001', position '821', GTID of the last change 'd26bc1be-0096-11e7-9c08-000c298ee31c:1-3'
170304 13:35:49 [00] Writing backup-my.cnf
170304 13:35:49 [00]        ...done
170304 13:35:49 [00] Writing xtrabackup_info
170304 13:35:49 [00]        ...done
xtrabackup: Transaction log of lsn (1639553) to (1639553) was copied.
170304 13:35:50 completed OK!
[root@cxqtest incr]# 
[root@cxqtest incr]# ls
2017-03-04_13-21-17  2017-03-04_13-21-52  2017-03-04_13-35-29

然后删除test数据库中的表t

root@localhost:mysql.sock  13:37:48 [(none)]>use test;
Database changed
root@localhost:mysql.sock  13:37:50 [test]>
root@localhost:mysql.sock  13:37:50 [test]>
root@localhost:mysql.sock  13:37:50 [test]>show tables;
 ---------------- 
| Tables_in_test |
 ---------------- 
| t              |
 ---------------- 
1 row in set (0.00 sec)

root@localhost:mysql.sock  13:37:53 [test]>drop table t;
Query OK, 0 rows affected (0.13 sec)

然后我们对比一下全备,第一次增备,第二次增备的checkpoints文件内容:

[root@cxqtest incr]# cat ../xtrabackup_checkpoints  ---全备
backup_type = full-prepared
from_lsn = 0
to_lsn = 1626008
last_lsn = 1626008
compact = 0
recover_binlog_info = 0
[root@cxqtest incr]# cat 2017-03-04_13-21-52/xtrabackup_checkpoints  --第一次增备
backup_type = incremental
from_lsn = 1626008
to_lsn = 1634925
last_lsn = 1634925
compact = 0
recover_binlog_info = 0
[root@cxqtest incr]# cat 2017-03-04_13-35-29/xtrabackup_checkpoints  --第二次增备
backup_type = incremental
from_lsn = 1634925
to_lsn = 1639553
last_lsn = 1639553
compact = 0
recover_binlog_info = 0

lsn值逐渐递增。
增量还原分为两个步骤
a.prepare

innobackupex –apply-log /path/to/BACKUP-DIR

此时数据可以被程序访问使用;可使用—use-memory选项指定所用内存以加快进度,默认100M;
b.recover

innobackupex –copy-back /path/to/BACKUP-DIR

从my.cnf读取datadir/innodb_data_home_dir/innodb_data_file_path等变量

先复制MyISAM表,然后是innodb表,最后为logfile;

开始合并操做:
第一次是全备的redo apply

[root@cxqtest incr]# innobackupex --defaults-file=/etc/my.cnf -uroot -pmysql123 --apply-log --redo-only /data/backup/0408/
170304 13:46:27 innobackupex: Starting the apply-log operation

IMPORTANT: Please check that the apply-log run completes successfully.
           At the end of a successful apply-log run innobackupex
           prints "completed OK!".

innobackupex version 2.4.6 based on MySQL server 5.7.13 Linux (x86_64) (revision id: 8ec05b7)
xtrabackup: cd to /data/backup/0408/
xtrabackup: This target seems to be already prepared.
InnoDB: Number of pools: 1
xtrabackup: notice: xtrabackup_logfile was already used to '--prepare'.
xtrabackup: using the following InnoDB configuration for recovery:
xtrabackup:   innodb_data_home_dir = .
xtrabackup:   innodb_data_file_path = ibdata1:1G:autoextend
xtrabackup:   innodb_log_group_home_dir = .
xtrabackup:   innodb_log_files_in_group = 3
xtrabackup:   innodb_log_file_size = 524288000
xtrabackup: using the following InnoDB configuration for recovery:
xtrabackup:   innodb_data_home_dir = .
xtrabackup:   innodb_data_file_path = ibdata1:1G:autoextend
xtrabackup:   innodb_log_group_home_dir = .
xtrabackup:   innodb_log_files_in_group = 3
xtrabackup:   innodb_log_file_size = 524288000
xtrabackup: Starting InnoDB instance for recovery.
xtrabackup: Using 104857600 bytes for buffer pool (set by --use-memory parameter)
InnoDB: PUNCH HOLE support available
InnoDB: Mutexes and rw_locks use GCC atomic builtins
InnoDB: Uses event mutexes
InnoDB: GCC builtin __sync_synchronize() is used for memory barrier
InnoDB: Compressed tables use zlib 1.2.3
InnoDB: Number of pools: 1
InnoDB: Using CPU crc32 instructions
InnoDB: Initializing buffer pool, total size = 100M, instances = 1, chunk size = 100M
InnoDB: Completed initialization of buffer pool
InnoDB: page_cleaner coordinator priority: -20
InnoDB: Highest supported file format is Barracuda.

xtrabackup: starting shutdown with innodb_fast_shutdown = 1
InnoDB: Starting shutdown...
InnoDB: Shutdown completed; log sequence number 1626237
InnoDB: Number of pools: 1
170304 13:46:28 completed OK!

第二次是第一次增备的redo apply

[root@cxqtest incr]# innobackupex --defaults-file=/etc/my.cnf -uroot -pmysql123 --apply-log --redo-only /data/backup/0408/ --incremental-dir=/data/backup/0408/incr/2017-03-04_13-21-52
170304 13:51:13 innobackupex: Starting the apply-log operation

IMPORTANT: Please check that the apply-log run completes successfully.
           At the end of a successful apply-log run innobackupex
           prints "completed OK!".

innobackupex version 2.4.6 based on MySQL server 5.7.13 Linux (x86_64) (revision id: 8ec05b7)
incremental backup from 1626008 is enabled.
xtrabackup: cd to /data/backup/0408/
xtrabackup: This target seems to be already prepared with --apply-log-only.
InnoDB: Number of pools: 1
xtrabackup: xtrabackup_logfile detected: size=8388608, start_lsn=(1634925)
.....
xtrabackup: Using 104857600 bytes for buffer pool (set by --use-memory parameter)
InnoDB: PUNCH HOLE support available
InnoDB: Mutexes and rw_locks use GCC atomic builtins
InnoDB: Uses event mutexes
InnoDB: GCC builtin __sync_synchronize() is used for memory barrier
InnoDB: Compressed tables use zlib 1.2.3
InnoDB: Number of pools: 1
InnoDB: Using CPU crc32 instructions
InnoDB: Initializing buffer pool, total size = 100M, instances = 1, chunk size = 100M
InnoDB: Completed initialization of buffer pool
InnoDB: page_cleaner coordinator priority: -20
InnoDB: Highest supported file format is Barracuda.
InnoDB: The log sequence number 1626228 in the system tablespace does not match the log sequence number 1634925 in the ib_logfiles!
InnoDB: Database was not shutdown normally!
InnoDB: Starting crash recovery.
InnoDB: Doing recovery: scanned up to log sequence number 1634925 (0%)
InnoDB: xtrabackup: Last MySQL binlog file position 574, file name mybinlog.000001
InnoDB: xtrabackup: Last MySQL binlog file position 574, file name mybinlog.000001
170304 13:51:17 completed OK!

其实整个过程就是一个merge的过程,可以看到全备的checkpoint中的信息已经发生了变化。

[root@cxqtest 0408]# cat xtrabackup_checkpoints 
backup_type = log-applied
from_lsn = 0
to_lsn = 1634925
last_lsn = 1634925
compact = 0
recover_binlog_info = 0
[root@cxqtest 2017-03-04_13-21-52]# cat xtrabackup_checkpoints 
backup_type = incremental
from_lsn = 1626008
to_lsn = 1634925
last_lsn = 1634925
compact = 0
recover_binlog_info = 0

然后进行第一次还原操作:

[root@cxqtest incr]# innobackupex --defaults-file=/etc/my.cnf -uroot -pmysql123 --copy-back /data/backup/0408/incr/2017-03-04_13-21-52
170304 13:58:13 innobackupex: Starting the copy-back operation

IMPORTANT: Please check that the copy-back run completes successfully.
           At the end of a successful copy-back run innobackupex
           prints "completed OK!".

innobackupex version 2.4.6 based on MySQL server 5.7.13 Linux (x86_64) (revision id: 8ec05b7)
Original data directory /data/3306/data is not empty!

报错了,需要清空对应的数据文件目录,清空目录继续进行操作:

[root@cxqtest incr]# innobackupex --defaults-file=/etc/my.cnf -uroot -pmysql123 --copy-back /data/backup/0408/incr/2017-03-04_13-21-52
170304 14:00:31 innobackupex: Starting the copy-back operation

IMPORTANT: Please check that the copy-back run completes successfully.
           At the end of a successful copy-back run innobackupex
           prints "completed OK!".

innobackupex version 2.4.6 based on MySQL server 5.7.13 Linux (x86_64) (revision id: 8ec05b7)
innobackupex: File 'ibdata1' not found (Errcode: 2 - No such file or directory)
InnoDB: Operating system error number 2 in a file operation.
InnoDB: The error means the system cannot find the path specified.
[01] error: cannot open file ibdata1
[01] Error: copy_file() failed.

又报错,说找不到ibdata1,其实这时候也应该明白了,其实merge合并之后到的是全备的checkpoint文件,所以要恢复的指定的应该是全备的目录才对。
再次修改目录进行恢复,成功:

[root@cxqtest incr]# innobackupex --defaults-file=/etc/my.cnf -uroot -pmysql123 --copy-back /data/backup/0408/
170304 14:02:30 innobackupex: Starting the copy-back operation

IMPORTANT: Please check that the copy-back run completes successfully.
           At the end of a successful copy-back run innobackupex
           prints "completed OK!".

innobackupex version 2.4.6 based on MySQL server 5.7.13 Linux (x86_64) (revision id: 8ec05b7)
.....
170304 14:03:59 completed OK!

然后赋予相应的mysql权限
注意:此次没有关闭mysql服务
登陆:

root@localhost:mysql.sock  14:14:27 [(none)]>use test;
Database changed
root@localhost:mysql.sock  14:14:32 [test]>show tables;
 ---------------- 
| Tables_in_test |
 ---------------- 
| t              |
 ---------------- 
1 row in set (0.00 sec)

root@localhost:mysql.sock  14:14:35 [test]>select * from t;
ERROR 1146 (42S02): Table 'test.t' doesn't exist

竟然报错了,明明显示有表啊,为什么会报表不存在?
重新启动mysql失败

[root@cxqtest incr]# /etc/init.d/mysqld restart
MySQL server PID file could not be found!                  [FAILED]
Starting MySQL......
...................The server quit without updating PID fil[FAILED]/3306/data/mysql.pid).

报错的原因就是找不到pid,幸好,清空目录的时候只是进行了mv操作,所以讲原pid再拷贝到data目录下,启动MySQL服务

[root@cxqtest incr]# /etc/init.d/mysqld start
Starting MySQL                                             [  OK  ]
[root@cxqtest incr]# 
[root@cxqtest incr]# 
[root@cxqtest incr]# mysql -uroot -p
Enter password: 
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/data/3306/mysql.sock' (2)

但是很遗憾,虽然启动成功了,但是找不到sock,登陆不了MySQL数据库,这就尴尬了
然后想着能不能再关闭重启一下是否可以

[root@cxqtest incr]# /etc/init.d/mysqld stop
Shutting down MySQL..                                      [  OK  ]
[root@cxqtest incr]# /etc/init.d/mysqld start
Starting MySQL                                             [  OK  ]
[root@cxqtest incr]# mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or g.
Your MySQL connection id is 1
Server version: 5.6.30-log Source distribution

Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.

root@localhost:mysql.sock  14:20:35 [(none)]>
root@localhost:mysql.sock  14:20:36 [(none)]>
root@localhost:mysql.sock  14:20:36 [(none)]>use test;
Database changed
root@localhost:mysql.sock  14:20:39 [test]>show tables;
 ---------------- 
| Tables_in_test |
 ---------------- 
| t              |
 ---------------- 
1 row in set (0.00 sec)

root@localhost:mysql.sock  14:20:41 [test]>select * from t;
 ------ ------ 
| id   | name |
 ------ ------ 
|    1 | a    |
|    2 | b    |
|    3 | c    |
|    4 | d    |
 ------ ------ 
4 rows in set (0.11 sec)

终于恢复回来了,好不容易!!
TIPS:在进行恢复的过程当中还是需要关闭服务再恢复,再启动服务,不然的话,还是会出现上述的报错,还挺麻烦。
这个过程我们相当于完成了一个全备 一个增备的数据恢复过程。
而我们在一个增备之后又插入了一些数据,这个怎么继续恢复呢,还是prepare的过程。这个路径需要注意,还是merge到全备中。
tips:在prepare阶段,不能关闭MySQL的服务,在copy的阶段再进行关闭MySQL服务的操作

innobackupex --defaults-file=/etc/my.cnf -uroot -pmysql123 --apply-log --redo-only /data/backup/0408/ --incremental-dir=/data/backup/0408/incr/2017-03-04_13-35-29

查看xtrabackup_checkpoints

[root@cxqtest 0408]# cat xtrabackup_checkpoints 
backup_type = log-applied
from_lsn = 0
to_lsn = 1634925
last_lsn = 1634925
compact = 0
recover_binlog_info = 0
[root@cxqtest 0408]# 
[root@cxqtest 0408]# 
[root@cxqtest 0408]# cat xtrabackup_checkpoints 
backup_type = log-applied
from_lsn = 0
to_lsn = 1639553
last_lsn = 1639553
compact = 0
recover_binlog_info = 0

已经更新到了最新的lsn号
如下,进行恢复–ps:这次进行MySQL服务停止尝试一下
同样,清空data目录

[root@cxqtest 3306]# cd data/
[root@cxqtest data]# ls
auto.cnf     ib_logfile1  innodb_status.12062  mysql               test
error.log    ib_logfile2  mybinlog.000001      mysql.pid           xtrabackup_binlog_pos_innodb
ibdata1      ibtmp1       mybinlog.000002      performance_schema  xtrabackup_info
ib_logfile0  incr         mybinlog.index       slow.log
[root@cxqtest data]# /etc/init.d/mysqld stop
Shutting down MySQL..                                      [  OK  ]
[root@cxqtest data]# 
[root@cxqtest data]# mv * ../bak/
[root@cxqtest incr]# innobackupex --defaults-file=/etc/my.cnf -uroot -pmysql123 --copy-back /data/backup/0408/
170304 14:35:05 innobackupex: Starting the copy-back operation

IMPORTANT: Please check that the copy-back run completes successfully.
           At the end of a successful copy-back run innobackupex
           prints "completed OK!".

innobackupex version 2.4.6 based on MySQL server 5.7.13 Linux (x86_64) (revision id: 8ec05b7)
170304 14:35:05 [01] Copying ib_logfile0 to /data/3306/data/ib_logfile0
170304 14:37:00 completed OK!

恢复完成,重复赋予恢复文件的MySQL属组权限,启动MySQL服务:
如果没有服务权限就会报如下的错:

[root@cxqtest data]# /etc/init.d/mysqld start
Starting MySQL..The server quit without updating PID file ([FAILED]06/data/mysql.pid).
[root@cxqtest data]# /etc/init.d/mysqld start
Starting MySQL                                             [  OK  ]
[root@cxqtest data]# 
[root@cxqtest data]# /etc/init.d/mysqld stop
Shutting down MySQL...The server quit without updating PID [FAILED]ata/3306/data/mysql.pid).
[root@cxqtest data]# /etc/init.d/mysqld start
Starting MySQL                                             [  OK  ]
[root@cxqtest data]# /etc/init.d/mysqld stop
MySQL server PID file could not be found!                  [FAILED]
[root@cxqtest data]# 
[root@cxqtest data]# ls
2017-03-04_14-29-25  ib_logfile0  ibtmp1               innodb_status.17127  performance_schema  xtrabackup_binlog_pos_innodb
error.log            ib_logfile1  incr                 mybinlog.index       slow.log            xtrabackup_info
ibdata1              ib_logfile2  innodb_status.14679  mysql                test
[root@cxqtest data]# ll
total 2596920
drwxr-x--- 2 root  root        4096 Mar  4 14:36 2017-03-04_14-29-25
-rw-r----- 1 mysql root       14301 Mar  4 14:43 error.log
-rw-r----- 1 root  root  1073741824 Mar  4 14:36 ibdata1
-rw-r----- 1 root  root   524288000 Mar  4 14:35 ib_logfile0
-rw-r----- 1 root  root   524288000 Mar  4 14:35 ib_logfile1
-rw-r----- 1 root  root   524288000 Mar  4 14:36 ib_logfile2
-rw-r----- 1 root  root    12582912 Mar  4 14:37 ibtmp1
drwxr-x--- 2 root  root        4096 Mar  4 14:36 incr
-rw-rw---- 1 mysql mysql          0 Mar  4 14:39 mybinlog.index
drwxr-x--- 2 root  root        4096 Mar  4 14:36 mysql
drwxr-x--- 2 root  root        4096 Mar  4 14:37 performance_schema
-rw-rw---- 1 mysql mysql        543 Mar  4 14:43 slow.log
drwxr-x--- 2 root  root        4096 Mar  4 14:36 test
-rw-r----- 1 root  root          20 Mar  4 14:37 xtrabackup_binlog_pos_innodb
-rw-r----- 1 root  root         625 Mar  4 14:37 xtrabackup_info
[root@cxqtest data]# pwd
/data/3306/data
[root@cxqtest data]# chown -R mysql.mysql *
[root@cxqtest data]# 
[root@cxqtest data]# 
[root@cxqtest data]# /etc/init.d/mysqld start
Starting MySQL..                                           [  OK  ]
[root@cxqtest data]# 
[root@cxqtest data]# ls
2017-03-04_14-29-25  ib_logfile0  incr                 mysql               test
auto.cnf             ib_logfile1  innodb_status.19581  mysql.pid           xtrabackup_binlog_pos_innodb
error.log            ib_logfile2  mybinlog.000001      performance_schema  xtrabackup_info
ibdata1              ibtmp1       mybinlog.index       slow.log

然后进行还原恢复:

[root@cxqtest incr]# innobackupex --defaults-file=/etc/my.cnf -uroot -pmysql123 --copy-back /data/backup/0408/
170304 15:02:39 innobackupex: Starting the copy-back operation

IMPORTANT: Please check that the copy-back run completes successfully.
           At the end of a successful copy-back run innobackupex
           prints "completed OK!".

innobackupex version 2.4.6 based on MySQL server 5.7.13 Linux (x86_64) (revision id: 8ec05b7)
170304 15:02:39 [01] Copying ib_logfile0 to /data/3306/data/ib_logfile0
170304 15:04:03 [01] Copying ./xtrabackup_info to /data/3306/data/xtrabackup_info
170304 15:04:03 [01]        ...done
170304 15:04:03 completed OK!

恢复完成,然后在data目录下赋予MySQL属组权限,启动MySQL服务:

[root@cxqtest bak]# /etc/init.d/mysqld start
Starting MySQL                                             [  OK  ]
[root@cxqtest bak]# 
[root@cxqtest bak]# 
[root@cxqtest bak]# /etc/init.d/mysqld stop
Shutting down MySQL..                                      [  OK  ]
[root@cxqtest bak]# /etc/init.d/mysqld start
Starting MySQL..                                           [  OK  ]

然后登陆数据库进行查询操作:

root@localhost:mysql.sock  15:11:42 [(none)]>use test;
Database changed
root@localhost:mysql.sock  15:11:44 [test]>
root@localhost:mysql.sock  15:11:44 [test]>
root@localhost:mysql.sock  15:11:45 [test]>
root@localhost:mysql.sock  15:11:45 [test]>show tables;
 ---------------- 
| Tables_in_test |
 ---------------- 
| t              |
 ---------------- 
1 row in set (0.00 sec)

root@localhost:mysql.sock  15:11:48 [test]>select * from t;
 ------ ------ 
| id   | name |
 ------ ------ 
|    1 | a    |
|    2 | b    |
|    3 | c    |
|    4 | d    |
|    5 | e    |
|    6 | f    |
 ------ ------ 
6 rows in set (0.03 sec)

可以看到第二次增量备添加的数据被恢复的回来。

xtrabackup官方手册:https://www.percona.com/doc/percona-xtrabackup/LATEST/index.html

4、备份中的常用选项和场景

innobackupex中的选项很多,常用的比如stream选项,–slave-info选项能够方便搭建从库,生成偏移量的信息,比如并行–parallel等,还可以根据LSN来备份,选项是–incremental-lsn
对于stream选项,默认是打包,可以结合管道来实现压缩,比如:
innobackupex –defaults-file=/etc/my.cnf –user=root –stream=tar /data/backup/0408/ | gzip > /data/backup/0408/0408.tar.gz
很多时候其实我不想备份整个库,我只想备份一个表,那么这个操作如何来实现呢。
innobackupex –defaults-file=/etc/my.cnf –user=root -pn–include=’test.t’ /data/backup/0408
这里有几点需要注意,工具还是会逐个去扫描,只是那些不符合的会被忽略掉,也就意味着备份出来的情况和全备的目录结构是一样的,但是指定的表会备份出ibd,frm文件。

[root@cxqtest bak]# ll
total 1036
-rw-r--r-- 1 mysql mysql    8556 Mar 22 18:34 t.frm
-rw-r--r-- 1 root  root  1048576 Mar 22 19:26 t.ibd
[root@cxqtest bak]# cd ..

而这种情况下,ibdata也会完整备份出来,如果这个文件很大,那就相当不给力了。
不过有一个场景还是很实用的。那就是迁移表。

1.安装xtrabackup

下载地址:https://www.percona.com/downloads/XtraBackup/LATEST/

rpm仓库(实际上是percona的仓库):http://repo.percona.com/release/

清华大学percona源:https://mirrors.tuna.tsinghua.edu.cn/percona/

因为只是一个备份工具,所以没必要编译安装,直接下载它的rpm包即可。但是该rpm包依赖于libev.so.4,该依赖包可以在epel源中找到。

这里安装的是目前最新版的xtrabackup-24-2.4.11。

cat <<eof>>/etc/yum.repos.d/percona.repo
[percona]
name = Percona
baseurl = https://mirrors.tuna.tsinghua.edu.cn/percona/release/$releasever/RPMS/$basearch
enabled = 1
gpgcheck = 0

[epel]
name=epelrepo
baseurl=https://mirrors.aliyun.com/epel/$releasever/$basearch
gpgcheck=0
enable=1
eof

[root@node1 ~]# yum list all| grep xtraback -i
Repository epel is listed more than once in the configuration
holland-xtrabackup.noarch                      1.0.14-3.el6                 epel
percona-xtrabackup.x86_64                      2.3.10-1.el6                 percona
percona-xtrabackup-20.x86_64                   2.0.8-587.rhel6              percona
percona-xtrabackup-20-debuginfo.x86_64         2.0.8-587.rhel6              percona
percona-xtrabackup-20-test.x86_64              2.0.8-587.rhel6              percona
percona-xtrabackup-21.x86_64                   2.1.9-746.rhel6              percona
percona-xtrabackup-21-debuginfo.x86_64         2.1.9-746.rhel6              percona
percona-xtrabackup-22.x86_64                   2.2.13-1.el6                 percona
percona-xtrabackup-22-debuginfo.x86_64         2.2.13-1.el6                 percona
percona-xtrabackup-24.x86_64                   2.4.11-1.el6                 percona
percona-xtrabackup-24-debuginfo.x86_64         2.4.11-1.el6                 percona
percona-xtrabackup-debuginfo.x86_64            2.3.10-1.el6                 percona
percona-xtrabackup-test.x86_64                 2.3.10-1.el6                 percona
percona-xtrabackup-test-21.x86_64              2.1.9-746.rhel6              percona
percona-xtrabackup-test-22.x86_64              2.2.13-1.el6                 percona
percona-xtrabackup-test-24.x86_64              2.4.11-1.el6                 percona

[root@node1 ~]# yum -y install percona-xtrabackup-24

装完xtrabackup后,生成以下几个工具。

[root@node1 ~]# rpm -ql percona-xtrabackup-24 | grep bin | xargs ls -hl
lrwxrwxrwx 1 root root   10 May  8 19:19 /usr/bin/innobackupex -> xtrabackup
-rwxr-xr-x 1 root root 3.5M Apr 19 01:11 /usr/bin/xbcloud
-rwxr-xr-x 1 root root 3.0K Apr 19 01:04 /usr/bin/xbcloud_osenv
-rwxr-xr-x 1 root root 3.5M Apr 19 01:11 /usr/bin/xbcrypt
-rwxr-xr-x 1 root root 3.5M Apr 19 01:11 /usr/bin/xbstream
-rwxr-xr-x 1 root root  21M Apr 19 01:11 /usr/bin/xtrabackup
  • xbcloud和xbcloud_osenv是xtrabackup新的高级特性:云备份;
  • xbcrypt也是新的特性,加密备份集;
  • xbstream是xtrabackup的流数据功能,通过流数据功能,可将备份内容打包并传给管道后的压缩工具进行压缩;
  • xtrabackup是主程序;
  • innobackupex在以前是一个perl脚本,会调用xtrabackup这个二进制工具,从xtrabackup 2.3开始,该工具使用C语言进行了重写,当前它是xtabackup二进制工具的一个软连接,但是实际的使用方法却不同,并且在以后的版本中会删除该工具。

在本文中,会分别对两个主程序innobackupex和xtrabackup的备份恢复方法进行详细的说明,还会在说明过程中尽可能的解释它们是如何工作的,另外还会介绍它们的一些特殊功能的选项,如流备份选项。

5、迁移表实验

如果我们还有一个实例3307的数据库,想把3306库中的test.t表导入到3307的test数据库中我们可以使用Innobackupex来做物理备份,然后还原导入,达到迁移的目的。

[root@cxqtest incr]# innobackupex --defaults-file=/etc/my.cnf --user=root -pmysql123 --include='test.t'  /data/backup/0408
170304 15:21:16 innobackupex: Starting the backup operation

IMPORTANT: Please check that the backup run completes successfully.
           At the end of a successful backup run innobackupex
           prints "completed OK!".

170304 15:21:16  version_check Connecting to MySQL server with DSN 'dbi:mysql:;mysql_read_default_group=xtrabackup;port=3306;mysql_socket=/data/3306/mysql.sock' as 'root'  (using password: YES).
170304 15:21:16  version_check Connected to MySQL server
xtrabackup: Transaction log of lsn (1626267) to (1626267) was copied.
170304 15:21:51 completed OK!
[root@cxqtest 0408]# cd 2017-03-04_15-21-16
[root@cxqtest 2017-03-04_15-21-16]# ls
2017-03-04_14-29-25  2017-03-04_14-56-20  ibdata1  test                    xtrabackup_checkpoints  xtrabackup_logfile
2017-03-04_14-53-36  backup-my.cnf        incr     xtrabackup_binlog_info  xtrabackup_info
[root@cxqtest 2017-03-04_15-21-16]# cat xtrabackup_checkpoints 
backup_type = full-backuped
from_lsn = 0
to_lsn = 1626267
last_lsn = 1626267
compact = 0
recover_binlog_info = 0

下面的命令会声明指定目录下的备份需要导出对象。

[root@cxqtest 2017-03-04_15-21-16]# ls
2017-03-04_14-29-25  2017-03-04_14-56-20  ibdata1  test                    xtrabackup_checkpoints  xtrabackup_logfile
2017-03-04_14-53-36  backup-my.cnf        incr     xtrabackup_binlog_info  xtrabackup_info
[root@cxqtest 2017-03-04_15-21-16]# cd test/
[root@cxqtest test]# ll
total 108
-rw-r----- 1 root root  8586 Mar  4 15:21 t.frm
-rw-r----- 1 root root 98304 Mar  4 15:21 t.ibd
[root@cxqtest incr]# innobackupex --apply-log --export /data/backup/0408/2017-03-04_15-21-16
170304 15:31:06 innobackupex: Starting the apply-log operation

IMPORTANT: Please check that the apply-log run completes successfully.
           At the end of a successful apply-log run innobackupex
           prints "completed OK!".

innobackupex version 2.4.6 based on MySQL server 5.7.13 Linux (x86_64) (revision id: 8ec05b7)
xtrabackup: auto-enabling --innodb-file-per-table due to the --export option
xtrabackup: cd to /data/backup/0408/2017-03-04_15-21-16/
xtrabackup: This target seems to be not prepared yet.
InnoDB: Number of pools: 1
xtrabackup: xtrabackup_logfile detected: size=8388608, start_lsn=(1626267)
.....
InnoDB: Shutdown completed; log sequence number 1626664
170304 15:31:52 completed OK!

直接结果就是多了如下的文件:

[root@cxqtest test]# ll
total 128
-rw-r--r-- 1 root root   420 Mar  4 15:31 t.cfg
-rw-r----- 1 root root 16384 Mar  4 15:31 t.exp
-rw-r----- 1 root root  8586 Mar  4 15:21 t.frm
-rw-r----- 1 root root 98304 Mar  4 15:21 t.ibd

然后在新的3307的test数据库中创建表t,并且对表t信息做截断:

root@localhost:mysql.sock  15:35:24 [(none)]>use test;
Database changed
root@localhost:mysql.sock  15:35:26 [test]>
root@localhost:mysql.sock  15:35:26 [test]>
root@localhost:mysql.sock  15:51:16 [test]>create table t(id int ,name varchar(10));
Query OK, 0 rows affected (0.34 sec)
root@localhost:mysql.sock  15:35:26 [test]>alter table t discard tablespace;
Query OK, 0 rows affected (0.26 sec)

然后将exp和ibd文件拷贝到目标目录然后修改属组导入即可(如是导入到mysql5.6拷贝.cfg,而不是.exp):

[root@cxqtest test]# cp t.exp /data/3307/data/test/
[root@cxqtest test]# cp t.ibd /data/3307/data/test/
[root@cxqtest test]# cp t.cfg /data/3307/data/test/
[root@cxqtest test]# cd /data/3307/data/test/
[root@cxqtest test]# ll
total 128
-rw-r--r-- 1 root root   420 Mar  4 15:47 t.cfg
-rw-r----- 1 root root 16384 Mar 4 15:38 t.exp
-rw-r----- 1 root root 98304 Mar 4 15:39 t.ibd
[root@cxqtest test]# chown mysql.mysql t.*
[root@cxqtest test]# lltotal 128[root@cxqtest test]# ll
total 116
-rw-r--r-- 1 mysql mysql   420 Mar  4 15:47 t.cfg
-rw-r----- 1 mysql mysql 16384 Mar  4 15:38 t.exp
-rw-r----- 1 mysql mysql 98304 Mar  4 15:39 t.ibd

然后再在test数据库中对表t进行导入操作:

root@localhost:mysql.sock  15:53:10 [test]>alter table t import tablespace;
Query OK, 0 rows affected (0.13 sec)
root@localhost:mysql.sock  15:53:41 [test]>show tables;
 ---------------- 
| Tables_in_test |
 ---------------- 
| t              |
 ---------------- 
1 row in set (0.00 sec)

root@localhost:mysql.sock  15:53:46 [test]>select * from t;
 ------ ------ 
| id   | name |
 ------ ------ 
|    1 | a    |
|    2 | b    |
|    3 | c    |
|    4 | d    |
|    5 | e    |
|    6 | f    |
 ------ ------ 
6 rows in set (0.00 sec)

可以看到数据从3306的test数据库中导入到了3307的数据库当中。
如果不是按如上步骤进行操作会报如下的错误:
原因就是,1、在没有对表进行创建和discard之前就将文件拷贝到了test目录下;2、表创建完成以后,没有将对应的文件拷贝到test目录下,导致数据库无法找到对应的文件

root@localhost:mysql.sock  15:49:44 [test]>alter table t import tablespace;
ERROR 1146 (42S02): Table 'test.t' doesn't exist
root@localhost:mysql.sock  15:49:47 [test]>alter table test.t import tablespace;
ERROR 1146 (42S02): Table 'test.t' doesn't exist
root@localhost:mysql.sock  15:49:53 [test]>
root@localhost:mysql.sock  15:49:54 [test]>
root@localhost:mysql.sock  15:49:54 [test]>
root@localhost:mysql.sock  15:50:31 [test]>
root@localhost:mysql.sock  15:50:32 [test]>create table t(id int ,name varchar(10));
ERROR 1813 (HY000): Tablespace for table '`test`.`t`' exists. Please DISCARD the tablespace before IMPORT.
root@localhost:mysql.sock  15:50:44 [test]>alter table test2 discard tablespace;
ERROR 1146 (42S02): Table 'test.test2' doesn't exist
root@localhost:mysql.sock  15:51:07 [test]>alter table t discard tablespace;
ERROR 1146 (42S02): Table 'test.t' doesn't exist

有另外一点值得说的是,这个.exp文件是不是必须的,其实也不是。
我们只拷贝.ibd文件也照样可以。可能在新版本中会有一些警告提示,我们重新来做一下。

root@localhost:mysql.sock  15:50:32 [test]>alter table t discard tablespace;
Query OK, 0 rows affected (0.03 sec)

同时删除刚刚拷贝过来的.exp文件。
然后拷贝ibd文件到指定目录,赋权限
导入表空间信息。

root@localhost:mysql.sock  15:50:32 [test]> alter table t import tablespace; 
Query OK, 0 rows affected (0.00 sec)

2.备份锁

一篇不错的介绍xtrabackup锁的文章:https://www.percona.com/blog/2014/03/11/introducing-backup-locks-percona-server-2/。

percona Server 5.6 支持一种新锁——backup lock(备份锁),这种锁是percona对MySQL的补充,专门为备份而设计。这种锁在percona Server 5.6 有,MariaDB中也有,但是Oracle的MySQL中没有,至少MySQL 5.7中没有。

这种锁用在备份的时候替代 flush tables with read lock 获取全局锁,是一种轻量级的全局锁。它有两种类型的锁:备份表锁和二进制日志锁。为此新增了3种语法:

lock tables for backup   # 申请备份表锁
lock binlog for backup   # 申请二进制日志锁
unlock binlog            # 释放二进制日志锁

备份表锁在全局范围内只对非innodb表加锁,所以持有该锁后无法修改非innodb表,但却不影响innodb表的DML。当然,因为是全局锁,所以也会阻塞DDL操作。

二进制日志锁在全局范围内锁定二进制日志,所以会阻塞其他会话修改二进制日志。这样可以保证能够获取到二进制日志中一致性的位置坐标。 

3.xtrabackup备份原理说明

不管是使用innobackupex还是xtrabackup工具进行备份和恢复,都有3个步骤:备份(backup)、准备(prepare)、恢复(copy back)。

注意,xtrabackup备份过程中,先备份innodb表,再备份非innodb表。

3.1 备份过程(backup阶段)

(1).在启动xtrabackup时记下LSN并将redo log拷贝到备份目标目录下的xtrabackup_logfile文件中。由于拷贝需要一定时间,如果在拷贝时间段内有日志写入,将导致拷贝的日志和MySQL的redo log不一致,所以xtrabackup还有一个后台进程监控着mysql的redo log,每秒监控一次,当MySQL的redo log有变化,该监控进程会立即将变化的内容写入到xtrabackup_logfile文件,这样就能保证拷贝走的redo log中记录了一切变化。但是这也是有风险的,因为redo是轮训式循环写入的,如果某一时刻有非常大量的日志写到redo log中,使得还没开始复制的日志就被新日志覆盖了,这样会日志丢失,并报错。

(2).拷贝完初始版的redo log后,xtrabackup开始拷贝innodb表的数据文件(即表空间文件.ibd文件和ibdata1)。注意,此时不拷贝innodb的frm文件。

(3).当innodb相关表的数据文件拷贝完成后,xtrabackup开始准备拷贝非innodb的文件。但在拷贝它们之前,要先对非innodb表进行加锁防止拷贝时有语句修改这些类型的表数据。

对于不支持backup lock的版本,只能通过flush tables with read lock来获取全局读锁,但这样也同样会锁住innodb表,杀伤力太大。所以使用xtrabackup备份Oracle的MySQL,实质上只能实现innodb表的部分时间热备、部分时间温备。

对于支持backup lock的版本,xtrabackup通过lock tables for backup获取轻量级的backup locks来替代flush tables with read lock,因为它只锁定非innodb表,所以由此实现了innodb表的真正热备。

(4).当获取到非innodb表的锁以后,开始拷贝非innodb表的数据和.frm文件。当这些拷贝完成之后,继续拷贝其他存储引擎类型的文件。(实际上,拷贝非innodb表的数据是在获取backup locks(如果支持)后自动进行的,它们属于同一个过程)

(5).当拷贝阶段完成后,就到了备份的收尾阶段。包括获取二进制日志中一致性位置的坐标点、结束redo log的监控和拷贝、释放锁等。

对于不支持backup lock的版本,收尾阶段的过程是这样的:获取二进制日志的一致性坐标点、结束redo log的监控和拷贝、释放锁。

对于支持backup lock的版本,收尾阶段的过程是这样的:先通过lock binlog for bakcup来获取二进制日志锁,然后结束redo log的监控和拷贝,再unlock tables释放表锁,随后获取二进制日志的一致性位置坐标点,最后unlock binlog释放二进制日志锁。

(6).如果一切都OK,xtrabackup将以状态码0退出。

所以,对是否支持backup lock的版本,xtrabackup备份的时的行为是不一样的。

新京葡娱乐场网址 1

backup阶段的过程具体如下图所示:

新京葡娱乐场网址 2

FTWRL:flush table with read lock;

新京葡娱乐场网址 3

3.2 准备过程(prepare阶段)

由于备份的时候拷贝走的数据文件可能是不一致的,比如监控着MySQL的redo log中在拷贝过程完成后又新的事务提交了,而拷贝走的数据是未提交状态的,那么就需要对该事务前滚;如果监控到的日志中有事务未提交,那么该事务就需要回滚。

但是如果只备份了myisam表或其他非事务表数据,因为备份阶段直接锁定了这些表,所以不会有不一致的状态。

xtrabackup有一个"准备"的阶段。这个阶段的实质就是对备份的innodb数据应用redo log,该回滚的回滚,该前滚的前滚,最终保证xtrabackup_logfile中记录的redo log已经全部应用到备份数据页上,并且实现了一致性。当应用结束后,会重写"xtrabackup_logfile"再次保证该redo log和备份的数据是对应的。

准备过程不需要连接数据库,该过程可以在任意装了xtrabackup软件的机器上进行,之所能实现是因为xtrabackup软件的内部嵌入了一个简化的innodb存储引擎,可以通过它完成日志的应用。

3.3 恢复过程(copy back阶段)

xtrabackup的恢复过程实质是将备份的数据文件和结构定义等文件拷贝回MySQL的datadir。同样可以拷贝到任意机器上。

要求恢复之前MySQL必须是停止运行状态,且datadir是空目录,除非恢复的操作是导入表的操作。具体见后文对应的内容。

4.准备实验环境

创建测试数据库backuptest,并创建myisam表和innodb表,此处简单的使用数值辅助表并分别插入1亿条数据。

DROP DATABASE IF EXISTS backuptest;
CREATE DATABASE backuptest;
USE backuptest;

# 创建myisam类型的数值辅助表和对应插入数据的存储过程
CREATE TABLE num_isam(n INT NOT NULL PRIMARY KEY)ENGINE=MYISAM;
DELIMITER $$
DROP PROCEDURE IF EXISTS proc_num1$$
CREATE PROCEDURE proc_num1(num INT) 
BEGIN
    DECLARE rn INT DEFAULT 1;
    TRUNCATE TABLE backuptest.num_isam;
    INSERT INTO backuptest.num_isam VALUES(1);
    dd: WHILE rn*2 < num DO
        BEGIN
            INSERT INTO backuptest.num_isam SELECT rn n FROM backuptest.num_isam;
            SET rn = rn*2;
        END;
    END WHILE dd;
    INSERT INTO backuptest.num_isam SELECT n rn FROM num_isam WHERE n rn <=num;
END;$$
DELIMITER ;

# 创建innodb类型的数值辅助表和对应插入数据的存储过程
CREATE TABLE num_innodb(n INT NOT NULL PRIMARY KEY)ENGINE=INNODB;
DELIMITER $$
DROP PROCEDURE IF EXISTS proc_num2$$
CREATE PROCEDURE proc_num2(num INT) 
BEGIN
    DECLARE rn INT DEFAULT 1;
    TRUNCATE TABLE backuptest.num_innodb;
    INSERT INTO backuptest.num_innodb VALUES(1);
    dd: WHILE rn*2 < num DO
        BEGIN
            INSERT INTO backuptest.num_innodb SELECT rn n FROM backuptest.num_innodb;
            SET rn = rn*2;
        END;
    END WHILE dd;
    INSERT INTO backuptest.num_innodb SELECT n rn FROM backuptest.num_innodb WHERE n rn <=num;
END;$$
DELIMITER ;

# 分别向两个数值辅助表中插入1亿条数据,
CALL proc_num1(100000000);
CALL proc_num2(100000000);

本文由67677新澳门手机版发布于网络数据库,转载请注明出处:新京葡娱乐场网址:xtrabackup用法和原理详述,

关键词: