1.拉取镜像
docker pull mysql:8.0
2.创建网络
创建网络,使得容器都在此网络内,容器间可以通过容器名互联
docker network create -d bridge my-net
3.创建容器
docker run -d --net my-net -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql-3307 mysql:8.0
docker run -d --net my-net -p 3308:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql-3308 mysql:8.0
4.修改配置文件
配置文件是:/etc/mysql/my.conf
mysql-3307 是主节点,配置文件为:
[mysqld]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql
secure-file-priv= NULL
# 同一局域网内注意要唯一
server-id=100
# 开启二进制日志功能,可以随便取(关键)
log-bin=mysql-master-bin
# 二级制日志格式,有三种 row,statement,mixed
binlog-format=ROW
# 同步的数据库名称,如果不配置,表示同步所有的库
# binlog-do-db=数据库名
mysql-3308 是从节点,配置文件为:
[mysqld]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql
secure-file-priv= NULL
# 设置server_id,注意要唯一
server-id=101
# 开启二进制日志功能,以备Slave作为其它Slave的Master时使用
log-bin=mysql-slave-bin
# relay_log配置中继日志
relay_log=mysql-relay-bin
# 设置为只读,该项如果不设置,表示slave可读可写
read_only=1
修改完配置文件,重启容器
5.配置用户
进入 mysql-3307,配置用户 repl
create user 'repl'@'%' identified with mysql_native_password by '123456';
grant replication slave on *.* to 'repl'@'%';
6.查看主节点状态
使用 show master status
命令,查看主节点状态
mysql> show master status;
+-------------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------------+----------+--------------+------------------+-------------------+
| mysql-master-bin.000001 | 826 | | | |
+-------------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
7.配置从节点
change master to master_host='172.18.0.2', master_user='repl', master_password='123456', master_port=3306, master_log_file='mysql-master-bin.000001', master_log_pos=826, master_connect_retry=30;
master_host :Master库的地址,指的是容器的独立ip,可以通过
master_port:Master的端口号,指的是容器的端口号
master_user:用于数据同步的用户
master_password:用于同步的用户的密码
master_log_file:指定 Slave 从哪个日志文件开始复制数据,即上文中提到的 File 字段的值
master_log_pos:从哪个 Position 开始读,即上文中提到的 Position 字段的值
master_connect_retry:如果连接失败,重试的时间间隔,单位是秒,默认是60秒
8.查看从节点状态
使用 start slave
,开启主从同步(注意:关闭是stop slave,如果改变同步参数需先关闭)
使用 show slave status
命令,查看从节点状态,当 Slave_IO_Running 和 Slave_SQL_Running 为 Yes 时,表示成功
mysql> show slave status G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.18.0.2
Master_User: repl
Master_Port: 3306
Connect_Retry: 30
Master_Log_File: mysql-master-bin.000001
Read_Master_Log_Pos: 2402
Relay_Log_File: mysql-relay-bin.000002
Relay_Log_Pos: 1907
Relay_Master_Log_File: mysql-master-bin.000001
Slave_IO_Running: Yes
Slave_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_Master_Log_Pos: 2402
Relay_Log_Space: 2116
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: 715bbc9e-9ab9-11ec-8725-0242ac120002
Master_Info_File: mysql.slave_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:
Master_public_key_path:
Get_master_public_key: 0
Network_Namespace:
1 row in set, 1 warning (0.00 sec)
ERROR:
No query specified
Master_Log_File,Read_Master_Log_Pos 记录了IO thread读到的当前master binlog文件和位置, 对应master的binlog文件和位置。
Relay_Log_File,Relay_Log_Pos记录了SQL thread执行到relay log的那个文件和位置,对应的是slave上的relay log文件和位置。
Relay_Master_Log_File,Exec_Master_Log_Pos记录的是SQL thread执行到master binlog的文件和位置,对应的master上binlog的文件和位置。
9.主从复制流程
mysql 的 binlog 日志作用是用来记录 mysql 内部增删等对mysql数据库有更新的内容的记录(对数据的改动),对数据库查询的语句如show,select开头的语句,不会被binlog日志记录。用于数据库的主从复制,以及增量恢复。
MySQL主从复制之前我们需要先启动master数据库然后再启动slave数据库,然后在slave数据库中执行start slave;,执行完成之后,流程就如下了:
执行change master to ...
、stop slave
、达到sync_master_info
的值时,会写入 master.info 文件(或slave_master_info表)
mysql> show variables like '%master%';
+------------------------------------------------+-------+
| Variable_name | Value |
+------------------------------------------------+-------+
| binlog_rotate_encryption_master_key_at_startup | OFF |
| master_info_repository | TABLE |
| master_verify_checksum | OFF |
| sync_master_info | 10000 |
+------------------------------------------------+-------+
4 rows in set (0.00 sec)
master_info_repository 有两个值,分别是file和table,该参数决定了slave记录master的状态,如果参数是file,就会创建master.info文件,如果参数值是table,就在mysql中创建slave_master_info的表。
1)如果master_info_repository=file,sync_master_info=N,其中N>0,那么slave就会在每N个事件后,使用fdatasync()方式同步到master.info文件中。如果sync_master_info=N,其中N=0,那么MySQL就会把状态信息写入到OS Cache中,需要等待操作系统同步。
2)如果master_info_repository=table,sync_master_info=N,如果N>0,那么slave就会在,每N个事件后,更新mysql.slave_master_info表,如果N=0,那么mysql.slave_master_info表将永远不会更新。
主从复制流程:
- slave 的IO线程会读取mastr.info文件(或slave_master_info表)中配置好的主库信息,比如说存放的有:master数据库的用户名、密码、端口、还有master的binlog索引位置;
- 拿到信息之后就带着信息去链接master的主库IO线程
- 当主库的IO线程先检查slave传过来的配置信息是否正确,如果正确,就拿着slave传过来的binlog索引位置和master库的binlog文件中最后一个索引位置进行对比,如果一致就陷入等待状态,等待Master的binlog索引位置更新;
- 如果不一致就把slave传过来的binlog索引位置往后的所有SQL语句包括最后一条SQL语句的索引位置发送个给slave的IO线程;
- slave的IO线程拿到信息之后,先把master传过来的binlog索引在slave的master.info文件(或slave_master_info表)中进行更新;
- 然后再把master传过来的SQL语句写入到relay中继日志文件中,然后继续循环执行第二个步骤;
- slave的SQL线程会一直持续的观察relay中继日志文件中是否有改动,如果没有就继续监听;
- 如果发现relay中继日志文件中有变动,那么就获取变动的内容转换为SQL语句,并且把SQL语句在 slave 的数据库中进行执行