01 原理
MySQL的主从复制是一种数据同步机制,它允许将主数据库(Master)的DDL和DML操作通过二进制日志(Binary Log)传输到一个或多个从数据库(Slave),以保证数据的一致性。主从复制是建立一个与主数据库数据完全一致的从数据库环境,并将主数据库的操作行为复制到从数据库上的过程。这包括将主数据库的DDL和DML操作日志同步到从数据库,然后在从数据库上重新执行这些日志来保持数据一致性。
动机:主从复制可以提高数据库的可用性、扩展性,实现读写分离,减轻主数据库的负担,以及提供数据的热备份 。
原理:主从复制依赖于二进制日志,主数据库在事务提交时将数据变更记录在二进制日志中。从数据库通过I/O线程连接主数据库,请求并接收主数据库的二进制日志事件,然后将这些事件记录在中继日志(Relay Log)中。从数据库的SQL线程读取中继日志中的事件,并在本地执行,以保持数据的一致性 。
过程:如下图:(1)主数据库在每个事务更新数据后,将操作记录到二进制日志(Binary Log)。(2)从数据库的I/O线程连接到主数据库,请求并接收二进制日志事件,并将这些事件写入中继日志(Relay Log)。(3)从数据库的SQL线程读取中继日志中的事件,并顺序执行这些事件,以确保数据的一致性 。
架构:主从复制架构可以非常灵活,如一主一从、一主多从或双主热备等。其中,双主热备架构中,两个节点互为主从,读写压力平分。
02 实验
2.1 启动容器
# image: https://hub.docker.com/r/ubuntu/mysql
docker pull ubuntu/mysql
# master
docker run -p 3307:3306 --name master -e MYSQL_ROOT_PASSWORD=123456 -d ubuntu/mysql
# slave-1
docker run -p 3308:3306 --name slave -e MYSQL_ROOT_PASSWORD=123456 -d ubuntu/mysql
# slave-2
docker run -p 3309:3306 --name slave2 -e MYSQL_ROOT_PASSWORD=123456 -d ubuntu/mysql
2.2 修改配置
2.2.1 修改主库
修改my.cnf(vim /etc/mysql/my.cnf),新增以下配置,然后重启MySQL服务。
[mysqld]
default_authentication_plugin=mysql_native_password
server_id=3307
binlog-ignore-db=mysql
log-bin=test-mysql-bin
binlog_cache_size=1024
binlog_format=mixed
expire_logs_days=7
slave_skip_errors=1062
新建用于主从复制的用户并授权。
-- mysql -uroot -p123456
CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
ALTER USER 'slave'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
查看MySQL状态。
SHOW master status \G;
2.2.2 修改从库
修改my.cnf(vim /etc/mysql/my.cnf),新增以下配置,然后重启MySQL服务。
[mysqld]
default_authentication_plugin=mysql_native_password
server_id=3308
binlog-ignore-db=mysql
log-bin=test-mysql-slave1-bin
binlog_cache_size=1024
binlog_format=mixed
expire_logs_days=7
slave_skip_errors=1062
relay_log=edu-mysql-relay-bin
log_slave_updates=1
read_only=1
2.3 开启复制
查看MySQL主库和从库容器的ip.
docker inspect --format='{{.NetworkSettings.IPAddress}}' master
docker inspect --format='{{.NetworkSettings.IPAddress}}' slave
docker inspect --format='{{.NetworkSettings.IPAddress}}' slave2
在从库中配置复制的主库信息,一主多从情况下,分别在不同的从库中执行以下语句。
change master to master_host='172.17.0.2', master_user='slave', master_password='123456', master_port=3306, master_log_file='test-mysql-bin.000001', master_log_pos=1247, master_connect_retry=30;
启动主从复制,查看从库状态,Slave_IO_Running和Slave_SQL_Running均为Yes则正常启动。
start slave;
show slave status;
2.4 结果验证
2.4.1 DDL,DML
库表和数据已经同步。
2.4.2 主库bin-log
使用mysqlbinlog查看bin-log日志内容。
mysqlbinlog --base64-output=DECODE-ROWS test-mysql-bin.000001 | grep "INSERT"
2.4.3 从库relay-log
使用mysqlbinlog查看relay-log日志内容。
mysqlbinlog --base64-output=DECODE-ROWS edu-mysql-relay-bin.000002 | grep "INSERT"
封面故事
2024年7月,新疆s101公路。