MySQL数据备份

MySQL数据备份

  • 全量备份
    • mysqldump
      • 1、全量备份数据库
  • 增量备份
    • mysqlbinlog
      • 2、保证bin-log已开启
        • 查看binlog相关系统参数值
        • binlog的三种格式
      • 3、导出binlog
        • 查看binlog文件的2种方式
    • binlog2sql
      • 3、binlog转化为可执行的sql
      • 4、执行增量备份的sql
  • 参考文档

上周对测试环境的MySQL进行了一次迁移,学习了一些MySQL数据备份相关的知识。主要的操作步骤有4步,使用到了mysqldump、mysqlbinlog和binlog2sql这三个工具。

全量备份

mysqldump

1、全量备份数据库

mysqldump -uroot -proot --lock-all-tables --flush-logs --databases test > /mysqlbackup/test_`date`.sql
 --lock-all-tables:备份时为所有的表加锁
 --flush-logs:备份前刷新日志

以下是mysqldump的常用操作

#导出所有数据库
mysqldump -uroot -proot --all-databases >/tmp/all.sql

#导出指定数据库
mysqldump -uroot -proot --databases db1 db2 >/tmp/user.sql

#导出一个数据库的指定表
mysqldump -uroot -proot --databases db1 --tables a1 a2  >/tmp/db1.sql

#条件导出,如果多个表条件相同可以一次导出多个表
mysqldump -uroot -proot --databases db1 --tables a1 --where='id=1'  >/tmp/a1.sql

#只导出表结构, --no-data 
mysqldump -uroot -proot --no-data --databases db1 >/tmp/db1.sql

#导出其他服务器上的数据
mysqldump --host=h1 -uroot -proot --databases db1 >/tmp/db1.sql
#将h1服务器中的db1数据库的所有数据导入到h2中的db2数据库中,db2的数据库必须存在否则会报错
mysqldump --host=h1 -uroot -proot --databases db1 |mysql --host=h2 -uroot -proot db2

增量备份

mysqlbinlog

2、保证bin-log已开启

修改my.cnf并且将以下参数加入其中,重启mysql实例

server-id=1 #由于bug,所以需要设置该参数.否则无法启动mysql实例 
log-bin = mysql-bin #其中mysql-bin代表的是basename就是生成二进制日志文件的前缀部分,默认的位置在datadir目录下,也可以设置为其他的路径

查看binlog相关系统参数值

mysql> show variables like '%log_bin%';
+---------------------------------+---------------------------------+
| Variable_name                   | Value                           |
+---------------------------------+---------------------------------+
| log_bin                         | ON                              |
| log_bin_basename                | /opt/mysql/data/mysql-bin       |
| log_bin_index                   | /opt/mysql/data/mysql-bin.index |
| log_bin_trust_function_creators | ON                              |
| log_bin_use_v1_row_events       | OFF                             |
| sql_log_bin                     | ON                              |
+---------------------------------+---------------------------------+
log_bin:binlog开启
log_bin_basename:binlog文件的前缀
log_bin_index:该文件记录所有的binlog文件的地址
log_bin_trust_function_creators:默认值为False,只有置为true时,用户才可以创建或修改存储函数
log_bin_use_v1_row_events:控制binlog中Rows_log_event的格式,默认是OFF,即使用v2版本的格式
sql_log_bin:动态变量,可以全局设置也可以针对当前的会话,置为OFF时会关闭binlog


mysql> show variables like '%binlog%';
+-----------------------------------------+----------------------+
| Variable_name                           | Value                |
+-----------------------------------------+----------------------+
| binlog_cache_size                       | 1048576              |
| binlog_checksum                         | CRC32                |
| binlog_direct_non_transactional_updates | OFF                  |
| binlog_error_action                     | IGNORE_ERROR         |
| binlog_format                           | MIXED                |
| binlog_gtid_simple_recovery             | OFF                  |
| binlog_max_flush_queue_time             | 0                    |
| binlog_order_commits                    | ON                   |
| binlog_row_image                        | FULL                 |
| binlog_rows_query_log_events            | OFF                  |
| binlog_stmt_cache_size                  | 32768                |
| binlogging_impossible_mode              | IGNORE_ERROR         |
| innodb_api_enable_binlog                | OFF                  |
| innodb_locks_unsafe_for_binlog          | OFF                  |
| max_binlog_cache_size                   | 18446744073709547520 |
| max_binlog_size                         | 524288000            |
| max_binlog_stmt_cache_size              | 18446744073709547520 |
| simplified_binlog_gtid_recovery         | OFF                  |
| sync_binlog                             | 0                    |
+-----------------------------------------+----------------------+
binlog_cache_size:binlog使用的内存大小
binlog_format:格式
max_binlog_size:binlog的最大值,默认值为1GB
sync_binlog:事务提交后写到binlog文件,不强制刷新到磁盘。性能最好,但风险最高。一旦系统崩溃,在文件系统缓存中的所有Binlog信息都会丢失

binlog的三种格式

binlog有三种格式:Statement、Row以及Mixed。

  • 基于SQL语句的复制(statement-based replication,SBR),

  • 基于行的复制(row-based replication,RBR),

  • 混合模式复制(mixed-based replication,MBR)。

    a. Statement
    每一条会修改数据的sql都会记录在binlog中。
    优点:不需要记录每一行的变化,减少了binlog日志量,节约了IO,提高性能。
    缺点:由于记录的只是执行语句,为了这些语句能在slave上正确运行,因此还必须记录每条语句在执行的时候的一些相关信息,以保证所有语句能在slave得到和在master端执行时候相同 的结果。另外mysql 的复制,像一些特定函数功能,slave可与master上要保持一致会有很多相关问题。

    b. Row
    5.1.5版本的MySQL才开始支持row level的复制,它不记录sql语句上下文相关信息,仅保存哪条记录被修改。
    优点: binlog中可以不记录执行的sql语句的上下文相关的信息,仅需要记录那一条记录被修改成什么了。所以rowlevel的日志内容会非常清楚的记录下每一行数据修改的细节。而且不会出现某些特定情况下的存储过程,或function,以及trigger的调用和触发无法被正确复制的问题.
    缺点:所有的执行的语句当记录到日志中的时候,都将以每行记录的修改来记录,这样可能会产生大量的日志内容。

    c. Mixed
    从5.1.8版本开始,MySQL提供了Mixed格式,实际上就是Statement与Row的结合。
    在Mixed模式下,一般的语句修改使用statment格式保存binlog,如一些函数,statement无法完成主从复制的操作,则采用row格式保存binlog,MySQL会根据执行的每一条具体的sql语句来区分对待记录的日志形式,也就是在Statement和Row之间选择一种。

查看目前的binlog文件信息

mysql> show variables like 'binlog_format';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | MIXED |
+---------------+-------+

3、导出binlog

3.1 查看当前正在写入的binlog文件

mysql> show master status;
+------------------+-----------+--------------+------------------+-------------------+
| File             | Position  | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+-----------+--------------+------------------+-------------------+
| mysql-bin.000034 | 382465243 |              |                  |                   |
+------------------+-----------+--------------+------------------+-------------------+
#当前正在写入的文件为mysql-bin.000034,位置为382465243

3.2 导出binlog

/opt/mysql/bin/mysqlbinlog --no-defaults --base64-output=decode-rows -v  /opt/mysql/data/mysql-bin.000368 > /opt/dump_`date`.sql

查看binlog文件的2种方式

默认情况下binlog日志是二进制格式,无法直接查看。

a. 使用show binlog events

#查看binlog文件内容
SHOW BINLOG EVENTS [IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count]

1、查看一个二进制文件中的全部事务
注:binlog文件实际上是由一连串的event组成的一个组,即事务组。
mysql> show binlog events in 'mysql-bin.000001' \G;
*************************** 1. row ***************************
   Log_name: mysql-bin.000001
        Pos: 4
 Event_type: Format_desc    //事件类型
  Server_id: 1
End_log_pos: 120    //结束pos点
       Info: Server ver: 5.6.29-log, Binlog ver: 4
*************************** 2. row ***************************
   Log_name: mysql-bin.000001
        Pos: 120
 Event_type: Rotate
  Server_id: 1
End_log_pos: 167
       Info: mysql-bin.000002;pos=4

 2、对二进制文件做过滤查询
 #从194节点开始,查找两条事务信息
mysql> SHOW BINLOG EVENTS IN 'mysql-bin.000005' FROM 194 LIMIT 2 \G;  
*************************** 1. row ***************************
   Log_name: mysql-bin.000005
        Pos: 194
 Event_type: Query
  Server_id: 1
End_log_pos: 319
       Info: use `tpcc`; UPDATE warehouse SET w_ytd = w_ytd + 3232 WHERE w_id = 1
*************************** 2. row ***************************
   Log_name: mysql-bin.000005
        Pos: 319
 Event_type: Query
  Server_id: 1
End_log_pos: 458
       Info: use `tpcc`; UPDATE district SET d_ytd = d_ytd + 3232 WHERE d_w_id = 1 AND d_id = 3
2 rows in set (0.00 sec)

b.使用mysqlbinlog查看binlog

1、查看指定的binlog日志
shell> mysqlbinlog mysql-bin-000005

上述命令可以会报一些异常:
a.

ERROR: Error in Log_event::read_log_event(): ‘Sanity check failed’, data_len: 171, event_type: 30

这是当前环境变量下的mysqlbinlog的版本和当前MySQL的版本不一样导致的。加上全局路径就可以。
如:/opt/mysql/bin/mysqlbinlog mysql-bin-000005
b.

mysqlbinlog: unknown variable ‘default-character-set=utf8’

原因是mysqlbinlog这个工具无法识别binlog中的配置中的default-character-set=utf8这个指令。有两种方法可以解决:
一是my.cnf中将default-character-set=utf8 修改为 character-set-server = utf8,这需要重启MySQL
二是加上–no-defaults参数,如:mysqlbinlog --no-defaults mysql-bin.000004,注意–no-defaults参数要放在其余参数之前

2、提取指定position位置的binlog日志
shell> mysqlbinlog --start-position="120" --stop-position="332" mysql-bin-000005

3、提取指定时间段的binlog日志
shell> mysqlbinlog --start-datetime="2014-12-15 20:15:23"  --stop-datetime="2014-12-15 22:15:23" mysql-bin-000005

4、提取binlog后直接导入mysql数据库
shell> mysqlbinlog mysql-bin-000005 | mysql -uroot -p

5、提取binlog并输出到日志文件
shell> mysqlbinlog mysql-bin-000005 > /opt/dump.sql

6、远程提取binlog并输出到文件
shell> mysqlbinlog -h192.168.1.116 -uroot -p mysql-bin-000005 > /opt/dump.sql

c. mysqlbinlog解析binlog

# row格式的binlog直接输出完全看不懂
shell> mysqlbinlog mysql-bin-000005
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#190122  0:10:26 server id 1  end_log_pos 120 CRC32 0x47610ace 	Start: binlog v 4, server v 5.6.29-log created 190122  0:10:26 at startup
ROLLBACK/*!*/;
BINLOG '
8u5FXA8BAAAAdAAAAHgAAAAAAAQANS42LjI5LWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAADy7kVcEzgNAAgAEgAEBAQEEgAAXAAEGggAAAAICAgCAAAACgoKGRkAAc4K
YUc=
'/*!*/;
# at 120
#700101  8:00:00 server id 1  end_log_pos 167 CRC32 0x1b09d2ba 	Rotate to mysql-bin.000002  pos: 4
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;

这时候需要添加参数:
–base64-output=DECODE-ROWS: 解析row模式的sql
-v :显示statement模式的sql语句

shell> mysqlbinlog --base64-output=DECODE-ROWS -v mysql-bin-000005
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 467789453
#190122  0:30:00 server id 1  end_log_pos 467789541 CRC32 0xbd79c3d0    Table_map: `test`.`test_table` mapped to number 2026876
# at 467789541
#190122  0:30:00 server id 1  end_log_pos 467789726 CRC32 0x64e584b7    Delete_rows: table id 2026876 flags: STMT_END_F
### DELETE FROM `test`.`test_table` 
### WHERE
###   @1=37455
###   @2=127365882
###   @3='20180911002167430018010000053'
###   @4=1
###   @5=1548002434542
###   @6='2019-01-21 00:30:04'
###   @7=63
###   @8='1'
###   @9='20180911002167430018010000053'
###   @10='20180911002167430018010000053'
###   @11='2019-01-21 00:30:04'
###   @12='2019-01-21 00:30:04'
# at 467789726
#190122  0:30:00 server id 1  end_log_pos 467789757 CRC32 0x88070c7f    Xid = 596669085
COMMIT/*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;

binlog2sql

3、binlog转化为可执行的sql

在上述操作中,我们可以看到,打印出来的binlog信息是被注释掉的,无法直接执行。

有非常多针对binlog的开源工具,我找到的是 binlog2sql。它提供的功能很多,根据不同的选项,可以得到原始SQL、回滚SQL、去除主键的INSERT SQL等。
首先要安装python环境:centos安装python2.7 。然后下载服务并安装依赖

shell> git clone https://github.com/danfengcao/binlog2sql.git && cd binlog2sql
shell> pip install -r requirements.txt

解析出标准sql

python binlog2sql.py -h192.168.150.151 -P3306 -uroot -p'root' --start-file='/opt/mysql/data/mysql-bin.000368'  --start-position="467789453" --stop-position="467789757" > binlog.sql

4、执行增量备份的sql

mysql> souce binlog.sql;

参考文档

  • 查看binlog文件的2种方式
  • mysql binlog系列(一)----binlog介绍、日志格式、数据查看等

你可能感兴趣的:(数据库)