mysql备份和恢复
根据服务器是否在线,备份可以分为:
1.热备:读写不受影响.
2.温备:能读不能写.
3.冷备:读写均不能进行.
按照备份数据的方式,可以分为:
1.物理备份:速度快
2.逻辑备份:速度慢,丢失浮点数精度,方便使用文本处理工具对备份文件进行处理,可移植能力强.
根据备份数据集的数据范围,可以分为:
1.完全备份.
2.增量备份.
3.差异备份.
备份工具:
1.mysqldump:逻辑备份工具,对myisam可以实现温备,对innodb可以实现热备.
2.mysqlhostcopy:物理备份工具
3.cp
4.lv
5.ibbackup(商业工具)
6.xtrabackup(开源工具)
7.select into outputfile
8.pt-parallel-backup
温备的主要步骤:
1.flush tables;
2.lock tables;
3.备份或创建快照.(对innodb数据引擎的表来讲,还需要确定是否已经将内存中的数据写入到了硬盘中)
4.release locks;
mysqldump命令主要参数:
1. --master-data[=#]
0表示不记录二进制日志及事件位置.
1表示以change master to的方式记录二进制事件位置,可用于恢复后直接启动从服务器进程.
2表示以change master to的方式记录二进制事件位置,但默认被注释掉
2. -x, --lock-all-tables
锁定所有表
3.--flush-logs
执行日志flush.
4.--single-transaction
如果数据库中的所有表均为innodb类型的,则启用该参数可以执行热备,该参数不能和--lock-all-tables一块使用.
5. --all-databases
备份所有数据库.
6.--databases
备份指定数据库.
7.--events
备份数据库事件.
8.--routines
备份存储过程和函数.
9.--triggers
备份触发器
使用mysqldump执行数据库全备与单库备份
[root@idc131 ~]# mysqldump --all-databases --lock-all-tables --flush-logs --master-data=2 --events --routines --triggers >/tmp/mytest_all.txt
[root@idc131 ~]# mysqldump --databases mydb --lock-all-tables --flush-logs --master-data=2 --events --routines --triggers >/tmp/mytest_mydb.txt
[root@idc131 ~]# mysqldump mydb --lock-all-tables --flush-logs --master-data=2 --events --routines --triggers >/tmp/mytest_mydb_1.txt
//该方式不包含创建数据库的语句.
在使用mysql的逻辑备份进行恢复时,需要关闭mysql的二进制日志功能,恢复后,再次打开二进制日志功能.
mysql> show variables like 'sql_log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| sql_log_bin | ON |
+---------------+-------+
1 row in set (0.00 sec)
mysql> set sql_log_bin=off;
Query OK, 0 rows affected (0.00 sec)
mysql> show variables like 'sql_log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| sql_log_bin | OFF |
+---------------+-------+
1 row in set (0.00 sec)
逻辑备份特点:
1.浮点数丢失精度.
2.备份出的数据较大,压缩后大大节省空间.
3.不适合对大数据库做备份.
查看innodb引擎的状态:
mysql> show engine innodb status\G;
使用select * into outfile '' from table_name备份表:
mysql> select * into outfile '/tmp/mytab1_1.txt' from mytab1;
Query OK, 12 rows affected (0.00 sec)
[root@idc131 ~]# cat /tmp/mytab1_1.txt
1 AAA A1 1
2 BBB B1 2
3 CCB C1 3
4 DDD D2 4
5 EEE E1 5
7 FFF F5 6
8 BBB B1 2
9 CCB C1 3
11 EEE E1 5
12 FFF F5 6
14 UU U1 8
15 OO U2 88
mysql> truncate table mytab1;
Query OK, 0 rows affected (0.13 sec)
mysql> load data infile '/tmp/mytab1_1.txt' into table mytab1;
Query OK, 12 rows affected (0.03 sec)
Records: 12 Deleted: 0 Skipped: 0 Warnings: 0
mysql> select * from mytab1;
+----+------+-------+-----+
| id | name | class | age |
+----+------+-------+-----+
| 1 | AAA | A1 | 1 |
| 2 | BBB | B1 | 2 |
| 3 | CCB | C1 | 3 |
| 4 | DDD | D2 | 4 |
| 5 | EEE | E1 | 5 |
| 7 | FFF | F5 | 6 |
| 8 | BBB | B1 | 2 |
| 9 | CCB | C1 | 3 |
| 11 | EEE | E1 | 5 |
| 12 | FFF | F5 | 6 |
| 14 | UU | U1 | 8 |
| 15 | OO | U2 | 88 |
+----+------+-------+-----+
12 rows in set (0.00 sec)
取消表的自动增长主键:
mysql> show create table mytab1;
+--------+------------------------
| Table | Create Table |
+--------+------------------------
| mytab1 | CREATE TABLE `mytab1` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL,
`class` varchar(20) NOT NULL,
`age` tinyint(4) NOT NULL,
PRIMARY KEY (`id`),
KEY `age` (`age`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8 |
mysql> alter table mytab1 change id id int(10) unsigned;
Query OK, 12 rows affected (0.08 sec)
Records: 12 Duplicates: 0 Warnings: 0
mysql> show create table mytab1;
+--------+----------------------
| Table | Create Table |
+--------+---------------------
| mytab1 | CREATE TABLE `mytab1` (
`id` int(10) unsigned NOT NULL DEFAULT '0',
`name` varchar(20) NOT NULL,
`class` varchar(20) NOT NULL,
`age` tinyint(4) NOT NULL,
PRIMARY KEY (`id`),
KEY `age` (`age`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+--------+-----------------------
1 row in set (0.00 sec)
删除表主键:
mysql> alter table mytab1 DROP PRIMARY KEY;
Query OK, 12 rows affected (0.12 sec)
Records: 12 Duplicates: 0 Warnings: 0
对load data的日志分析:
mysql> show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000041 | 25095 | | |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
mysql> show binlog events in 'mysql-bin.000041';
| mysql-bin.000041 | 24765 | Query | 1 | 24833 | BEGIN
| mysql-bin.000041 | 24833 | Table_map | 1 | 24885 | table_id: 335 (mydb.mytab1)
| mysql-bin.000041 | 24885 | Write_rows | 1 | 25068 | table_id: 335 flags: STMT_END_F
| mysql-bin.000041 | 25068 | Xid | 1 | 25095 | COMMIT /* xid=4154 */
分析日志发现从24765到25068处有一段语句,使用sqlbinlog导出语句.
[root@idc131 data]# mysqlbinlog --start-position=24765 mysql-bin.000041 >/tmp/mytab1_2.txt
将该段日志重新导入数据库
[root@idc131 data]# mysql </tmp/mytab1_2.txt
检查结果:
mysql> select * from mytab1;
+----+------+-------+-----+
| id | name | class | age |
+----+------+-------+-----+
| 1 | AAA | A1 | 1 |
| 2 | BBB | B1 | 2 |
| 3 | CCB | C1 | 3 |
| 4 | DDD | D2 | 4 |
| 5 | EEE | E1 | 5 |
| 7 | FFF | F5 | 6 |
| 8 | BBB | B1 | 2 |
| 9 | CCB | C1 | 3 |
| 11 | EEE | E1 | 5 |
| 12 | FFF | F5 | 6 |
| 14 | UU | U1 | 8 |
| 15 | OO | U2 | 88 |
| 1 | AAA | A1 | 1 |
| 2 | BBB | B1 | 2 |
| 3 | CCB | C1 | 3 |
| 4 | DDD | D2 | 4 |
| 5 | EEE | E1 | 5 |
| 7 | FFF | F5 | 6 |
| 8 | BBB | B1 | 2 |
| 9 | CCB | C1 | 3 |
| 11 | EEE | E1 | 5 |
| 12 | FFF | F5 | 6 |
| 14 | UU | U1 | 8 |
| 15 | OO | U2 | 88 |
+----+------+-------+-----+
24 rows in set (0.00 sec)
发现数据被重新又装载了一遍.
使用快照进行备份的前提条件:
1.数据文件要在逻辑卷上.
2.数据文件要和事务日志在同一个逻辑卷上.
3.逻辑卷所在的卷组必须有足够的空间使用快照卷.
使用快照进行备份:
1.施加读锁,锁定所有表.
mysql> flush tables with read lock;
Query OK, 0 rows affected (0.00 sec)
2.切换日志.
mysql> flush logs;
Query OK, 0 rows affected (0.05 sec)
3.显示当前日志信息:
mysql> show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000042 | 107 | | |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
4.创建快照卷.
lvcreate -L 50m -s -p r -n mydata_snap /dev/myvg/myvgdata
5.释放锁.
mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)
6.挂载快照卷.
mount -o ro /dev/myvg/mydata_snap /mnt/temp
7.拷贝数据文件及事务日志.
cp -a /mnt/temp/data /backup/
8.删除快照卷.
lvremove -n mydata_snap
9.增量备份产生的新的二进制日志文件.
如果要生成多个二进制日志文件的sql脚本,则可以使用时间格式来处理,如下:
[root@idc131 data]# mysqlbinlog --start-datetime='2014-08-09 08:08:00' mysql-bin.[0-9]* > /tmp/mysql_data_`date +%F-%H-%M-%S`.sql
注意:如果是innodb存储引擎的话,需要再备份ibdata1,防止innodb的file_per_table未打开,导致数据仍然存储在默认的表空间中.
如果进行恢复的话,切记恢复前关闭sql_log_bin,恢复后,再次打开sql_log_bin.
二进制日志相关的选项:
mysql> show variables like 'innodb_support_xa';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| innodb_support_xa | ON |默认支持分布式事务,两段式提交.
+-------------------+-------+
1 row in set (0.00 sec)
mysql> show variables like 'sync_binlog';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| sync_binlog | 0 |执行备份过程中,建议将该值设置为1.
+---------------+-------+
1 row in set (0.00 sec)
xtrabackup:Percona公司开发的软件.
xtradb是innodb的改进版
支持innodb的在线物理备份,全备和增量备份.
支持myisam的温备及完全备份.
xtrabackup备份:
1.创建最小权限的备份用户:
mysql> create user backupuser@localhost identified by 'backupuser';
Query OK, 0 rows affected (0.00 sec)
mysql> revoke all privileges,grant option from backupuser@localhost;
Query OK, 0 rows affected (0.00 sec)
mysql> grant reload,lock tables,replication client on *.* to backupuser@localhost;
Query OK, 0 rows affected (0.02 sec)
2.执行完全备份或增量备份
[root@idc131 bak]# innobackupex --user=backupuser --password=backupuser /tmp/bak/fullbk
[root@idc131 bak]# innobackupex --user=backupuser --password=backupuser --incremental /tmp/bak/incbk --incremental-basedir=/tmp/bak/fullbk/2014-08-10_11-02-03
[root@idc131 bak]# innobackupex --user=backupuser --password=backupuser --incremental /tmp/bak/incbk --incremental-basedir=/tmp/bak/incbk/2014-08-10_11-03-56
[root@idc131 bak]# innobackupex --user=backupuser --password=backupuser --incremental /tmp/bak/incbk --incremental-basedir=/tmp/bak/incbk/2014-08-10_11-31-56
3.如果需要使用完全备份进行恢复,则需要先对备份文件应用日志进行recover,如下:
[root@idc131 ~]# innobackupex --apply-log /tmp/bak/2014-08-10_08-07-48/
如果需要使用完全备份+增量备份进行恢复,则需要执行如下操作:
[root@idc131 bak]# innobackupex --apply-log --redo-only /tmp/bak/fullbk/2014-08-10_11-02-03/
[root@idc131 bak]# innobackupex --apply-log --redo-only /tmp/bak/fullbk/2014-08-10_11-02-03/ --incremental-dir=/tmp/bak/incbk/2014-08-10_11-03-56
[root@idc131 bak]# innobackupex --apply-log --redo-only /tmp/bak/fullbk/2014-08-10_11-02-03/ --incremental-dir=/tmp/bak/incbk/2014-08-10_11-31-56
[root@idc131 bak]# innobackupex --apply-log --redo-only /tmp/bak/fullbk/2014-08-10_11-02-03/ --incremental-dir=/tmp/bak/incbk/2014-08-10_11-33-40
注意:执行增量备份时使用的参数是--increment-basedir,执行增量恢复的时候,使用的是--incrmental-dir.
检查全备份中的xtrabackup_checkpoints中的lsn号已经和最后一次增量备份的lsn号相等了.
#####模拟故障
mv /usr/local/mysql/data /usr/local/mysql/data_del
mkdir /usr/local/mysql/data
4.restore数据并修改权限
[root@idc131 mysql]# innobackupex --copy-back /tmp/bak/2014-08-10_08-07-48/
[root@idc131 mysql]# chown -R mysql.root data
5.启动mysql数据库
[root@idc131 data]# service mysqld start
Starting MySQL.. SUCCESS!
6.使用对增量的binlog日志进行恢复.
[root@idc131 data_del]# mysqlbinlog --start-datetime='2014-08-10 08:07:53' mysql-bin.00004[3-5] >/tmp/mysql.txt
mysql> set sql_log_bin=off;
Query OK, 0 rows affected (0.00 sec)
mysql> source /tmp/mysql.txt
mysql> set sql_log_bin=on;
Query OK, 0 rows affected (0.00 sec)
[root@idc131 data_del]# mysql </tmp/mysql.txt
7.验证数据.
使用innobackupex导出导入单张表
1.确保要导出innodb数据引擎所在的数据库的innodb_file_per_table是打开的.
2.确保要导入的innodb数据引擎的innodb_file_per_table和innodb_expand_import是打开的.
3.导出表
[root@idc131 ~]# innobackupex --apply-log --export /tmp/bak/fullbk/2014-08-10_11-02-03/
4.在要导入的数据库中创建一个与要导入的表的结构一致的表.
mysql> create table mytabexp select * from mytab1 where 1=2;
5.删除新建表的表空间.
mysql> alter table mytabexp discard tablespace;
6.将导出文件拷贝至新建表所在的数据目录,并将文件名修改为与表名一直后缀名为exp的文件,确保权限正确.
[root@idc131 mydb]# mv mytab1.exp mytabexp.exp
7.导入表.
mysql> alter table mytabexp import tablespace;