MySQL 主从同步
Table of Contents
1 binlog 简介
binlog,即二进制日志,它记录了数据库上的所有改变. 改变数据库的 SQL 语句执行结束 时,将在 binlog 的末尾写入一条记录,同时通知语句解析器,语句执行完毕.
binlog 格式
- 基于语句, 无法保证所有语句都在从库执行成功, 比如
update ... limit 1
- 基于行, 将每一次改动记为 binlog 中的一行.在执行一个特别复杂的 update 或者 delete 操作时,基于行的格式会有优势.
2 查看 binlog event
获取所有 binlog 文件列表
show binary logs;
Log_name | File_size |
---|---|
binlog.000001 | 6370 |
binlog.000002 | 177 |
binlog.000003 | 177 |
binlog.000004 | 177 |
binlog.000005 | 177 |
binlog.000006 | 177 |
binlog.000007 | 177 |
binlog.000008 | 177 |
binlog.000009 | 177 |
binlog.000010 | 177 |
binlog.000011 | 21668 |
binlog.000012 | 177 |
binlog.000013 | 3367 |
binlog.000014 | 31076 |
查看当前正在写入的 binlog
show master status;
File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
---|---|---|---|---|
binlog.000014 | 31076 |
查看第一个 binlog 的内容
show binlog events limit 20;
Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
---|---|---|---|---|---|
binlog.000001 | 4 | Format_desc | 1 | 123 | Server ver: 5.7.31-log, Binlog ver: 4 |
binlog.000001 | 123 | Previous_gtids | 1 | 154 | |
binlog.000001 | 154 | Anonymous_Gtid | 1 | 219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
binlog.000001 | 219 | Query | 1 | 319 | create database test01 |
binlog.000001 | 319 | Anonymous_Gtid | 1 | 384 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
binlog.000001 | 384 | Query | 1 | 517 | use `test01`; create table t1 (id int primary key, name varchar(32) ) |
binlog.000001 | 517 | Anonymous_Gtid | 1 | 582 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
binlog.000001 | 582 | Query | 1 | 701 | use `test01`; DROP TABLE `t1` * generated by server * |
binlog.000001 | 701 | Anonymous_Gtid | 1 | 766 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
binlog.000001 | 766 | Query | 1 | 926 | use `test01`; create table table01(id int not null auto_increment primary key, name varchar(64)) |
binlog.000001 | 926 | Anonymous_Gtid | 1 | 991 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
binlog.000001 | 991 | Query | 1 | 1065 | BEGIN |
binlog.000001 | 1065 | Table_map | 1 | 1120 | table_id: 221 (test01.table01) |
binlog.000001 | 1120 | Write_rows | 1 | 1168 | table_id: 221 flags: STMT_END_F |
binlog.000001 | 1168 | Table_map | 1 | 1223 | table_id: 221 (test01.table01) |
binlog.000001 | 1223 | Write_rows | 1 | 1271 | table_id: 221 flags: STMT_END_F |
binlog.000001 | 1271 | Table_map | 1 | 1326 | table_id: 221 (test01.table01) |
binlog.000001 | 1326 | Write_rows | 1 | 1375 | table_id: 221 flags: STMT_END_F |
binlog.000001 | 1375 | Table_map | 1 | 1430 | table_id: 221 (test01.table01) |
binlog.000001 | 1430 | Update_rows | 1 | 1495 | table_id: 221 flags: STMT_END_F |
查看指定 binlog 内容
show binlog events in 'binlog.000014' limit 10;
Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
---|---|---|---|---|---|
binlog.000014 | 4 | Format_desc | 1 | 123 | Server ver: 5.7.31-log, Binlog ver: 4 |
binlog.000014 | 123 | Previous_gtids | 1 | 154 | |
binlog.000014 | 154 | Anonymous_Gtid | 1 | 219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
binlog.000014 | 219 | Query | 1 | 419 | use `test01`; create table author (\n id int auto_increment primary key,\n name varchar(128) not null,\n age int,\n gender varchar(32)\n) |
binlog.000014 | 419 | Anonymous_Gtid | 1 | 484 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
binlog.000014 | 484 | Query | 1 | 558 | BEGIN |
binlog.000014 | 558 | Table_map | 1 | 616 | table_id: 112 (test01.author) |
binlog.000014 | 616 | Write_rows | 1 | 667 | table_id: 112 flags: STMT_END_F |
binlog.000014 | 667 | Xid | 1 | 698 | COMMIT * xid=13 * |
binlog.000014 | 698 | Anonymous_Gtid | 1 | 763 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
3 一主一从配置
3.1 准备数据库镜像
启动两个 mysql 容器,一个做主节点,一个做从节点
docker run --detach --restart always \ --name mysql-master \ --publish 31100:3306 \ --env 'MYSQL_ROOT_PASSWORD=root' \ --env 'MYSQL_DATABASE=test01' \ --env 'MYSQL_USER=user01' \ --env 'MYSQL_PASSWORD=user01' \ --volume /srv/mysql-master/conf:/etc/mysql/conf.d \ mysql:5.7.26 docker run --detach --restart always \ --name mysql-slave \ --publish 31101:3306 \ --env 'MYSQL_ROOT_PASSWORD=root' \ --env 'MYSQL_DATABASE=test01' \ --env 'MYSQL_USER=user01' \ --env 'MYSQL_PASSWORD=user01' \ --volume /srv/mysql-slave/conf:/etc/mysql/conf.d \ mysql:5.7.26
3.2 主节点配置
[mysqld] server-id = 100 log-bin = binlog binlog-do-db = test01 binlog-ignore-db = information_schema binlog-ignore-db = mysql binlog-ignore-db = performance_schema binlog-ignore-db = sys
3.3 从节点配置
配置 slave 节点启动参数,指定需要同步和复制的数据库
[mysqld] server-id = 101 log-bin = binlog replicate-do-db = test01 replicate-ignore-db = information_schema replicate-ignore-db = mysql replicate-ignore-db = performance_schema replicate-ignore-db = sys
3.4 配置项目
master 上授权给 slave 复制权限
grant replication slave on *.* to 'repl'@'%' identified by 'repl'; flush privileges;
slave 指向 master 的用户名和密码是在 slave 节点中动态配置
-- 配置主库同步的用户信息 change master to master_host='172.17.0.2', master_port=3306, master_user='repl', master_password='repl'; -- 指定 binlog 文件 change master to master_host='172.17.0.2', master_port=3306, master_user='repl', master_password='repl' master_log_file='binlog.000004';
启动 slave 节点中 slave 服务
stop slave;
start slave;
查看 slave 状态,确保参数 Slave_IO_Running: Yes
和 Slave_SQL_Running: Yes
show slave status\G
*************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 172.17.0.2 Master_User: repl Master_Port: 3306 Connect_Retry: 60 Master_Log_File: binlog.000003 Read_Master_Log_Pos: 1099 Relay_Log_File: 76af8d33cb4e-relay-bin.000007 Relay_Log_Pos: 582 Relay_Master_Log_File: binlog.000003 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: test01 Replicate_Ignore_DB: information_schema,mysql,performance_schema,sys Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 1099 Relay_Log_Space: 959 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 100 Master_UUID: c0083b30-dbd5-11eb-a18a-0242ac110002 Master_Info_File: /var/lib/mysql/master.info SQL_Delay: 0 SQL_Remaining_Delay: NULL Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates Master_Retry_Count: 86400 Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: Executed_Gtid_Set: Auto_Position: 0 Replicate_Rewrite_DB: Channel_Name: Master_TLS_Version: