MySQL主从搭建(待完成)

目前我所在公司,申请数据库时,基本都是MySQL主从交付。这篇文章,也主要讲下MySQL主从

基础

MySQL高可用是基于binlog。对binlog的解释,可以参看下官方文档

The binary log is a set of log files that contain information about data modifications made to a MySQL server instance. The log is enabled by starting the server with the --log-bin option

默认binlog是关闭的,可以通过下方语句查询得到Value为OFF

1
show variables like 'log_bin';

要打开binlog,可以通过修改配置文件/etc/my.cnf(Unix like系统下的配置),重启MySQL

1
2
3
4
5
6
7
[mysqld]
#binlog文件的存放目录
log-bin=/usr/local/mysql/mysql-bin/mysql-bin
#binlog文件格式
binlog-format=MIXED
#server id
server-id=1
binlog-format三种格式

假设我们执行SQL

1
delete from t /*comment*/ where c >= 20 and d <= 25 limit 1;
  • STATEMENT格式

binlog文件中记录的是原始的SQL语句,如上方SQL,binlog中记录的是

1
delete from t /*comment*/ where c >= 20 and d <= 25 limit 1;

这种格式可能导致主从数据不一致

  • ROW格式**[推荐]**

binlog文件中记录的是SQL语句影响的所有行,如上方SQL,binlog中可能记录的是

1
2
3
/*所有满足的行都记录下来*/
delete from t where c = 20 and d = 20;
delete from t where c = 21 and d = 20;

如果binlog_row_image配置为FULL,表t还有其他字段,则binlog会把所有字段都记录下来。如上方SQL,binlog中可能记录的是

1
2
delete from t where c = 20 and d = 20 and id = 1;
delete from t where c = 21 and d = 20 and id = 2;

这种格式缺点是可能导致记录的数据特别多,比如满足SQL条件的行有上千行,则binlog会全部记下所有行。优点是避开了statement格式的主从不一致的情况,另外,通过分析binlog,我们也很容易恢复被误修改的数据。生产上推荐这种方式

  • MIXED格式

这种格式是上两种方式的混合,由MySQL判断,如果不会造成主从不一致,则记录原始SQL语句(statement),否则记录所有变更行(row)。

生产上首推ROW格式,易于恢复误修改数据。如果资源不足,可以考虑MIXED格式

binlog文件分析

通过下方语句,可以查看binlog记录内容

1
show binlog events in 'mysql-bin.000001';

结果

http://blog-image-creasylai.oss-cn-shenzhen.aliyuncs.com/blog.images/img/2022/05/article02/01.png

ROW格式下,show binlog只能看到有那些变更,无法看到具体语句

http://blog-image-creasylai.oss-cn-shenzhen.aliyuncs.com/blog.images/img/2022/05/article02/02.png

通过mysqlbinlog工具,可以分析ROW格式下的binlog

1
mysqlbinlog  -vv /usr/local/mysql-5.7.31-macos10.14-x86_64/mysql-bin/mysql-bin.000002 --start-position=544;

http://blog-image-creasylai.oss-cn-shenzhen.aliyuncs.com/blog.images/img/2022/05/article02/03.png

另外,通过mysqlbinlog还可以执行binlog中的SQL

1
mysqlbinlog /usr/local/mysql-5.7.31-macos10.14-x86_64/mysql-bin/mysql-bin.000001  --start-position=544 --stop-position=862 | mysql -u$user -p$password;