? mysql主从复制的原理将主数据库的增删改查等操作记录到二进制日志文件中,从库接收主库日志文件,根据最后一次更新的
起始位置,同步复制到从数据库中,使得主从数据库保持一致。
Binary log:主数据库的二进制日志;Relay log:从服务器的中继日志。
复制过程:
1,主数据库在每次事务完成前,将该操作记录到binlog日志文件中;
2,从数据库中有一个I/O线程,负责连接主数据库服务,并读取binlog日志变化,如果发现有新的变动,则将变动写入到relay-log,否则进入休眠状态;
3,从数据库中的SQL Thread读取中继日志,并串行执行SQL事件,使得从数据库与主数据库始,终保持一致。注意事项:涉及时间函数时,会出现数据不一致。原因是,复制过程的两次IO操作和网络、磁盘效率等问题势必导致时间戳不一致;涉及系统函数时,会出现不一致。
准备两台机器:
ip | 作用 |
---|---|
192.168.43.107 | master |
192.168.43.108 | slave |
? 登录到192.168.43.107服务器,并执行下面指令:
[root@localhost ~]# mkdir -p /data/mysql/master
[root@localhost ~]# vim my.cnf
[root@localhost ~]# vim Dockerfile
? my.cnf文件的内容如下:
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
init_connect='SET collation_connection = utf8_unicode_ci'
init_connect='SET NAMES utf8'
character-set-server=utf8
#collection-server=utf8_unicode_ci
collation-server=utf8_general_ci
skip-character-set-client-handshake
skip-name-resolve
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
lower_case_table_names=1
#[必须]启用二进制日志
log-bin=mysql-bin
#[必须]服务器唯一ID一般取IP最后一段,这里看情况分配
server-id=107
~
? Dockerfile文件的内容如下:
FROM mysql:5.7.31
# 作者信息
MAINTAINER mysql from date UTC by Asia/Shanghai "dream21th@dream21th.com"
ENV TZ Asia/Shanghai
COPY my.cnf /etc/mysql/
~
? 构建镜像:
[root@localhost ~]# docker build --rm -t dream21th/mysqlmaster:5.7.31 .
? 启动容器:
[root@localhost mysql]# docker run -p 3306:3306 --name dream21th-mysql-master -v /data/mysql/logs:/logs -v /data/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD='!QAZ@WSX#EDC' -d dream21th/mysqlmaster:5.7.31
? 将my.cnf,Dockerfile两个文件复制到108服务器:
[root@localhost master]# scp my.cnf Dockerfile root:192.168.43.108/data/mysql/slave
? 编辑my.cnf,将server-id改成108,然后执行构建镜像和启动容器:
构建镜像:
[root@localhost ~]# docker build --rm -t dream21th/mysqlmaster:5.7.31 .
? 启动容器:
[root@localhost mysql]# docker run -p 3306:3306 --name dream21th-mysql-slave -v /data/mysql/logs:/logs -v /data/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD='!QAZ@WSX#EDC' -d dream21th/mysqlmaster:5.7.31
? 在107服务器上面执行下面指令进到容器:
[root@localhost master]# docker exec -it dream21th-mysql-master bash
? 进入容器后通过下面指令登录mysql:
root@3c4f257fb608:/# mysql -uroot -p
#创建一个数据同步用户
mysql> create user 'admin'@'%' identified by 'admin';
Query OK, 0 rows affected (0.00 sec)
# 授权
mysql> grant replication slave on *.* to 'admin'@'%';
Query OK, 0 rows affected (0.00 sec)
# 刷新权限
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
# 查看master状态 file和position在做slave同步时要使用
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 749 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
#查看binlog的参数
mysql> show global variables like 'binlog%';
+--------------------------------------------+--------------+
| Variable_name | Value |
+--------------------------------------------+--------------+
| binlog_cache_size | 32768 |
| binlog_checksum | CRC32 |
| binlog_direct_non_transactional_updates | OFF |
| binlog_error_action | ABORT_SERVER |
| binlog_format | ROW |
| binlog_group_commit_sync_delay | 0 |
| binlog_group_commit_sync_no_delay_count | 0 |
| binlog_gtid_simple_recovery | ON |
| 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 |
| binlog_transaction_dependency_history_size | 25000 |
| binlog_transaction_dependency_tracking | COMMIT_ORDER |
+--------------------------------------------+--------------+
15 rows in set (0.00 sec)
#查看服务的参数 107是我们设置的id
mysql> show global variables like 'server%';
+----------------+--------------------------------------+
| Variable_name | Value |
+----------------+--------------------------------------+
| server_id | 107 |
| server_id_bits | 32 |
| server_uuid | 1547eebe-f676-11ec-81e0-0242ac110002 |
+----------------+--------------------------------------+
3 rows in set (0.00 sec)
? 执行完成上述的操作之后,在108服务器上进入到容器操作:
[root@localhost slave]# docker exec -it dream21th-mysql-slave bash
root@1da4bb80398e:/# mysql -uroot -p
# 设置同步数据
mysql> CHANGE MASTER TO master_host='192.168.43.107', master_user='admin', master_password='admin', master_port=3306, master_log_file='mysql-bin.000001', master_log_pos=749;
Query OK, 0 rows affected, 2 warnings (0.01 sec)
#开启slave
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
# 查看slave的状态
mysql> show slave status;
? 用navicat登录107在上面建一个库和一张表,并插入一条数据:
? 登录108,找到一样的数据,代表主从成功: