MySQL 主从搭建(binlog) 小记
MySQL 主从搭建(binlog)
原理
MySQL
中有一个 binary_log
的功能,会把对数据的操作都记录下来,写到文件中。这个功能非常有用,我们可以订阅这个文件的变更,来获取 MySQL
中的数据变更,比如解析变更并同步到其它服务中(Elasticsearch
)。现在这个主从,也是同样的原理,让从节点订阅这个 binlog
就行了。
此示例只做了 master > slave 的数据同步,要求 slave 那这不能有数据改动,否则两边数据不一致了就无法正常工作了,最好直接在 slave 节点配置为 readonly + 不要用 root 账户
操作步骤
本样例以 MySQL 8.0.30
为实验对象,操作步骤参考官方文档
$ mysql --version
mysql Ver 8.0.30-0ubuntu0.20.04.2 for Linux on x86_64 ((Ubuntu))
主服务器配置调整
# 其它配置忽略
# 监听指定的网卡,可以填 0.0.0.0
bind-address = 192.168.199.201
mysqlx-bind-address = 192.168.199.201
# 给当前服务取一个 id,master 是 1
server-id = 1
log_bin = /var/log/mysql/mysql-bin.log
binlog_expire_logs_seconds = 2592000
max_binlog_size = 100M
transaction_isolation = READ-COMMITTED
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
从服务器配置调整
# 其它配置忽略
# 监听指定的网卡,可以填 0.0.0.0
bind-address = 192.168.199.202
mysqlx-bind-address = 192.168.199.202
# 给当前服务取一个 id,此处是 2
server-id = 2
# 从节点不必开 binlog,但是要开 read_only 防止从节点修改数据导致两边数据不一致
# ps: 开启后,root 账号(及其它分配了super privilege 的账号)依然能够修改数据,导致同步出错,所以不要用 root 账号
read_only = 1
transaction_isolation = READ-COMMITTED
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
创建同步用户(主服务器)
CREATE USER repl_u@'192.168.%' identified by '666888';
GRANT REPLICATION SLAVE ON *.* TO repl_u@'192.168.%';
创建同步点(主服务器)
# 先把数制写入一下
mysql > FLUSH TABLES WITH READ LOCK;
# 查询出 bin offset 等
mysql > SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000004 | 702 | test | manual,mysql |
+------------------+----------+--------------+------------------+
记录完了上述信息,再把主服务器的数据导出一份。
$> mysqldump --all-databases --master-data > dbdump.db
导完了,把锁恢复一下
mysql> UNLOCK TABLES;
导入同步点数据(从服务器)
# 把主服务器的文件复制过来,然后执行
$> mysql < dbdump.db
然后在 MySQL Cli
中执行
CHANGE REPLICATION SOURCE TO
SOURCE_HOST='192.168.199.201',
SOURCE_USER='repl_u',
SOURCE_PASSWORD='666888',
SOURCE_LOG_FILE='mysql-bin.000004',
SOURCE_LOG_POS=702;
查看 replica 状态
mysql> show replica status\G
*************************** 1. row ***************************
Replica_IO_State: Waiting for source to send event
Source_Host: 192.168.199.201
Source_User: repl_u
Source_Port: 3306
Connect_Retry: 60
Source_Log_File: mysql-bin.000004
Read_Source_Log_Pos: 4635
Relay_Log_File: k8s-node2-relay-bin.000002
Relay_Log_Pos: 4259
Relay_Source_Log_File: mysql-bin.000004
Replica_IO_Running: Yes
Replica_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Source_Log_Pos: 4635
Relay_Log_Space: 4473
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Source_SSL_Allowed: No
Source_SSL_CA_File:
Source_SSL_CA_Path:
Source_SSL_Cert:
Source_SSL_Cipher:
Source_SSL_Key:
Seconds_Behind_Source: 0
Source_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Source_Server_Id: 1
Source_UUID: 46a516e3-12d6-11ed-bf12-000c293c4280
Source_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Replica_SQL_Running_State: Replica has read all relay log; waiting for more updates
Source_Retry_Count: 86400
Source_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Source_SSL_Crl:
Source_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name:
Source_TLS_Version:
Source_public_key_path:
Get_Source_public_key: 0
Network_Namespace:
1 row in set (0.00 sec)
测试数据
当然是从主那里创建个库、表,写几条数据,看看能否同步过来。
其它
如果操作过程中不小心在从库改了、删除数据怎么办?
把库删除了,MySQL 会重新同步过来,不建议生产环境这样操作
经历比结果更重要