目录
1 MySql主从复制简介
1.1 主从复制的概念
1.2 主从复制的作用
2. 搭建主从复制
2.1 pull mysql 镜像
2.2 新建主服务器容器实例 3307
2.2.1 master创建 my.cnf
2.2.2 重启master
2.2.3 进入mysql 容器,创建同步用户
2.3 新建从服务器容器实例 3308
2.3.1 slave创建 my.cnf
2.3.2 重启slave 实例
2.3.3 在master中查看主从同步状态
2.3.4 在从数据库中配置主从复制
2.3.5 在从数据中开启主从同步
2.3.6 再次查看 slave status
3 主从复制测试
3.1主机添加数据
3.2 从机直接使用
MySQL 主从复制是指数据可以从一个MySQL数据库服务器主节点复制到一个或多个从节点。MySQL 默认采用异步复制方式,这样从节点不用一直访问主服务器来更新自己的数据,数据的更新可以在远程连接上进行,从节点可以复制主数据库中的所有数据库或者特定的数据库,或者特定的表。
数据的热备:作为后备数据库,主数据库服务器故障后,可切换到从数据库继续工作,避免数据丢失。
架构的扩展:业务量越来越大,I/O访问频率过高,单机无法满足,此时做多库的存储,降低磁盘I/O访问的频率,提高单个机器的I/O性能。
读写分离:使数据库能支撑更大的并发。
(1)在从服务器可以执行查询工作(即我们常说的读功能),降低主服务器压力;(主库写,从库读,降压)
(2)在从服务器进行备份,避免备份期间影响主服务器服务;(确保数据安全)
高可用性:数据备份实际上是一种冗余的机制,通过这种冗余的方式可以换取数据库的高可用性,也就是当服务器出现故障或宕机的情况下,可以切换到从服务器上,保证服务的正常运行。
docker pull mysql
先创建文件夹:
mkdir -p /mydocker/mysql-master/log
mkdir -p /mydocker/mysql-master/data
mkdir -p /mydocker/mysql-master/conf
docker run -p 3307:3306 --name=mysql-master -v /mydocker/mysql-master/log:/var/log/mysql -v /mydocker/mysql-master/data:/var/lib/mysql -v /mydocker/mysql-master/conf:/etc/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql
[root@192 mysql-master]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6a298c5defda mysql "docker-entrypoint.s…" 4 seconds ago Up 2 seconds 33060/tcp, 0.0.0.0:3307->3306/tcp, :::3307->3306/tcp mysql-master
#创建容器时出现 找不着/var/lib/mysql-files 的错误
解决办法:在my.cnf 配置文件中加入 secure_file_priv=/var/lib/mysql
在/mydocker/mysql-master/conf 目录下 创建 my.cnf
[mysqld]
#指定此路径限制数据导入导出,不然默认读取/var/lib/mysql-files路径,但是容器中此路径没有会报错
secure_file_priv=/var/lib/mysql
#设置server_id,同一局域网中需要唯一
server_id=101
#指定不需要同步的数据库名称
binlog-ignore-db=mysql
#开启二进制日志功能
log-bin=mall-mysql-bin
#设置二进制日志使用内存大小(事务)
binlog_cache_size=1M
#设置使用的二进制日志格式(mixed,statement,row)
binlog_format=mixed
#二进制日志过期清理时间,默认值为0,表示不自动清理
expire_logs_days=7
#跳过主从复制中遇到的所有错误或指定类型的错误,避免slae端复制终端
#如:1062错误是指一些主键重复,1032错误是因为主从数据库不一致
slave_skip_errors=1062
docker restart 6a298c5defda
docker exec -it mysql-master /bin/bash
mysql -uroot -p
mysql> CREATE USER 'slave'@'%'IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.15 sec)
mysql> GRANT REPLICATION SLAVE,REPLICATION CLIENT ON*.*TO'slave'@'%';
Query OK, 0 rows affected (0.01 sec)
#由于mysql8之后默认使用认证方式为caching_sha2_password,会使主从复制change命令后出现Slave_IO_Running: Connecting
解决办法:
① :在my.cnf 配置文件中加入 default_authentication_plugin=mysql_native_password
② :在master mysql中执行 ALTER USER 'slave'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
[root@192 ~]# docker run -p 3308:3306 --name=mysql-slave -v /mydocker/mysql-slave/log:/var/log/mysql -v /mydocker/mysql-slave/data:/var/lib/mysql -v /mydocker/mysql-slave/conf:/etc/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql
[root@192 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d284702c6992 mysql "docker-entrypoint.s…" 3 seconds ago Up 2 seconds 33060/tcp, 0.0.0.0:3308->3306/tcp, :::3308->3306/tcp mysql-slave
7b510affe5f3 mysql "docker-entrypoint.s…" 12 minutes ago Up 12 minutes 33060/tcp, 0.0.0.0:3307->3306/tcp, :::3307->3306/tcp mysql-master
[root@192 ~]#
#创建容器时出现 找不着/var/lib/mysql-files 的错误
解决办法:在my.cnf 配置文件中加入 secure_file_priv=/var/lib/mysql
[mysqld]
#指定此路径限制数据导入导出,不然默认读取/var/lib/mysql-files路径,但是容器中此路径没有会报错
secure_file_priv=/var/lib/mysql
#设置server_id,同一局域网中需要唯一
server_id=102
#指定不需要同步的数据库名称
binlog-ignore-db=mysql
#开始二进制日志功能,以备slave作为其他数据库实例的Master时使用
log-bin=mall-mysql-slave1-bin
#设置二进制使用内存大小 (事务)
binlog_cache_size=1M
#设置使用二进制日期格式
binlog_format=mixed
#二进制日志过期清理时间。默认为0,表示不自动清理
expire_logs_days=7
#跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制终端。
#如 1062错误是指一些主键重复,1032错误是因为主从数据库不一致
slave_skip_errors=1062
#relay_log 配置中继日志
relay_log=mall-mysql-relay-bin
#表示slave将复制事件写进自己的二进制日志
log_slave_updates=1
#slave设置为只读(具有super权限的用户除外)
read_only=1
docker restart mysql-slave
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d284702c6992 mysql "docker-entrypoint.s…" 12 hours ago Up 5 minutes 33060/tcp, 0.0.0.0:3308->3306/tcp, :::3308->3306/tcp mysql-slave
7b510affe5f3 mysql "docker-entrypoint.s…" 12 hours ago Up 7 seconds 33060/tcp, 0.0.0.0:3307->3306/tcp, :::3307->3306/tcp mysql-master
mysql> show master status;
+-----------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-----------------------+----------+--------------+------------------+-------------------+
| mall-mysql-bin.000006 | 156 | | mysql | |
+-----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.02 sec)
mysql> change master to master_host='192.168.217.145',master_user='slave',master_password='123456',master_port=3307,master_log_file='mall-mysql-bin.000005',master_log_pos=156,master_connect_retry=30;
Query OK, 0 rows affected, 10 warnings (0.18 sec)
master_host: 主数据库的ip地址
master_user: 在主数据库创建的用于同步数据的用户账号
master_password: 在主数据库创建的用于同步数据的用户密码
master_port: 主数据库的运行端口
master_log_file: 指定从数据库要复制数据的日志文件,通过查看主数据库的状态,获取File参数
master_log_pos:指定从数据库从哪个位置开始复制数据,通过查看主数据库的状态,获取Position
master_connect_retry: 连接失败重试的时间间隔,单位为妙
mysql> show slave status \G;
*************************** 1. row ***************************
Slave_IO_State:
Master_Host: 192.168.145.217
Master_User: slave
Master_Port: 3307
Connect_Retry: 30
Master_Log_File: mall-mysql-bin.000005
Read_Master_Log_Pos: 156
Relay_Log_File: mall-mysql-relay-bin.000001
Relay_Log_Pos: 4
Relay_Master_Log_File: mall-mysql-bin.000005
Slave_IO_Running: No
Slave_SQL_Running: No
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: 156
Relay_Log_Space: 156
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: NULL
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: 0
Master_UUID:
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State:
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.03 sec)
mysql> start slave;
mysql> show slave status \G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for source to send event
Master_Host: 192.168.217.145
Master_User: slave
Master_Port: 3307
Connect_Retry: 30
Master_Log_File: mall-mysql-bin.000007
Read_Master_Log_Pos: 156
Relay_Log_File: mall-mysql-relay-bin.000002
Relay_Log_Pos: 329
Relay_Master_Log_File: mall-mysql-bin.000007
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: 156
Relay_Log_Space: 543
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: 101
Master_UUID: 4d815ecc-e845-11ee-aad4-0242ac110003
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Replica 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)
下面2项的状态已经由No 变成 Yes
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
mysql> create database db01;
Query OK, 1 row affected (0.11 sec)
mysql> use db01;
Database changed
mysql> create table t1(id int,name varchar(20));
Query OK, 0 rows affected (1.94 sec)
mysql> insert t1 values(1,'z3');
Query OK, 1 row affected (0.01 sec)
mysql> use db01;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> select * from t1;
+------+------+
| id | name |
+------+------+
| 1 | z3 |
+------+------+
1 row in set (0.00 sec)