主从复制的作用
1、做数据的热备,作为后备数据库,主数据库服务器故障后,可切换到从数据库继续工作,避免数据丢失。
2、架构的扩展。业务量越来越大,I/O访问频率过高,单机无法满足,此时做多库的存储,降低磁盘I/O访问的频率,提高单个机器的I/O性能。
3、读写分离,使数据库能支撑更大的并发。在报表中尤其重要。由于部分报表sql语句非常的慢,导致锁表,影响前台服务。如果前台使用master,报表使用slave,那么报表sql将不会造成前台锁,保证了前台速度。
1.搭建主数据库
docker run -d -p 3306:3306 -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql-docker mysql:5.7
mysql主数据库 配置文件配置
docker exec -it mysql-docker /bin/bash
cd /etc/mysql/mysql.conf.d
vim mysqld.cnf
添加以下配置
log-bin=/var/lib/mysql/mysql-bin #开启mysql的binlog日志功能
server-id=1 # 节点ID,确保唯一
binlog_format=MIXED #binlog日志格式,mysql默认采用statement,建议使用mixed
expire_logs_days=30 #binlog过期清理时间
max_binlog_size=100m #binlog每个日志文件大小
max_allowed_packet = 1G
net_buffer_length = 1048576
sync_binlog = 1 #控制数据库的binlog刷到磁盘上去 , 0 不控制,性能最好,1每次事物提交都会刷到日志文件中,性能最差,最安全
binlog-ignore-db=mysql #不生成日志文件的数据库,多个忽略数据库可以用逗号拼接,或者 复制这句话,写多行
slave-skip-errors = all #跳过从库错误
保存退出
2.搭建从数据库
docker run -d -p 3307:3306 -v /home/mysql_slave1/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql_slave1 mysql:5.7
mysql.cnf 配置
server-id = 2
log-bin=/var/lib/mysql/mysql-bin
relay-log = mysql-relay-bin
replicate-wild-ignore-table=mysql.%
replicate-wild-ignore-table=test.%
replicate-wild-ignore-table=information_schema.%
slave_parallel_workers = 4
slave_parallel_type= logical_clock #基于组提交的并行复制方式 DATABASE:默认值,基于库的并行复制方式
master_info_repository=TABLE #是否将主状态和连接信息记录到 FILE(master.info)或a TABLE (mysql.slave_master_info)
relay_log_info_repository=TABLE #取决于服务器的 relay_log_info_repository 设置(FILE或 TABLE)
sync_master_info=1 #若master-info-repository为FILE,当设置为0,则每次sync_master_info事件都会刷新到磁盘,默认为10000次刷新到磁盘;若master-info-repository为TABLE,当设置为0,则表不做任何更新,设置为1,则每次事件会更新表 #默认为10000
sync_relay_log = 1 #默认为10000,即每10000次sync_relay_log事件会刷新到磁盘。为0则表示不刷新,交由OS的cache控制。
sync_relay_log_info = 1 #若relay_log_info_repository为FILE,当设置为0,交由OS刷新磁盘,默认为10000次刷新到磁盘;若relay_log_info_repository为TABLE,且为INNODB存储,则无论为任何值,则都每次evnet都会更新表。
relay_log_recovery=ON #当slave从库宕机后,假如relay-log损坏了,导致一部分中继日志没有处理,则自动放弃所有未执行的relay-log,并且重新从master上获取日志,这样就保证了relay-log的完整性。默认情况下该功能是关闭的
重启两个mysql,让配置生效
3.导出主数据库数据
docker exec -it mysql-docker /bin/bash
mysqldump -uroot -p123456 --all-databases >/all_databases.sql #导出主数据库的数据
4.把数据导入从数据库
docker exec -it mysql_slave1 /bin/bash
mysql -uroot -p123456 </all_databases.sql
5.主从同步配置
1.进入master的数据库,为master创建复制用户
CREATE USER repl_user IDENTIFIED BY 'repl_passwd';
2.赋予该用户复制的权利
grant replication slave on *.* to 'repl_user'@'%' identified by 'repl_passwd';
FLUSH PRIVILEGES;
3.查看master的状态
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000018 | 10306799 | | mysql | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
4.进入slave数据库配置
CHANGE MASTER TO
MASTER_HOST = '192.168.1.107',
MASTER_USER = 'repl_user',
MASTER_PASSWORD = 'repl_passwd',
MASTER_PORT = 3306,
MASTER_LOG_FILE='mysql-bin.000018',
MASTER_LOG_POS=10306799,
MASTER_RETRY_COUNT = 60,
MASTER_HEARTBEAT_PERIOD = 10000;
# MASTER_LOG_FILE='mysql-bin.000018',#与主库File 保持一致
# MASTER_LOG_POS=10306799, #与主库Position 保持一致
启动从库slave进程
mysql> slave start;
Query OK, 0 rows affected (0.04 sec)
查看状态
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.1.107
Master_User: repl_user
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000018
Read_Master_Log_Pos: 10263291
Relay_Log_File: mysql-relay-bin.000004
Relay_Log_Pos: 17258
Relay_Master_Log_File: mysql-bin.000018
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: mysql.%,test.%,information_schema.%
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 10263291
Relay_Log_Space: 17465
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: 1
Master_UUID: e5377b78-2250-11eb-9b38-0242ac110005
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: 60
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:
1 row in set (0.00 sec)
以下状态表示启动成功
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
…
Seconds_Behind_Master: 0
6.Slave_SQL_Running: No mysql同步故障解决方法
解决办法II:
重新进入slave数据库配置
slave stop;
CHANGE MASTER TO
MASTER_HOST = '192.168.1.107',
MASTER_USER = 'repl_user',
MASTER_PASSWORD = 'repl_passwd',
MASTER_PORT = 3306,
MASTER_LOG_FILE='***',
MASTER_LOG_POS=***,
MASTER_RETRY_COUNT = 60,
MASTER_HEARTBEAT_PERIOD = 10000;
start slave;
解决办法II(不建议使用):
mysql> slave stop;
mysql> set GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
mysql>start slave;
7.半同步复制
默认的主从复制方式是异步复制,有可能存在数据丢失的问题(主节点挂了,从节点还没来得及读主节点的binlog)。半同步复制则是来解决该问题,用来保证节点之间的数据一致性。
mysql让master在某一个时间点等待slave节点的ack消息,接收到ack后才进行事务提交,这也是半同步复制的基础,了解半同步之前我们可以先回顾一下主从辅助master节点事务的处理过程。众所周知,mysql的事务是分为两阶段提交,处理流程大概如下:
当master不需要关注slave是否接受到binlog事件时,即为传统的主从复制,当master需要在第三步等待slave返回ack时,即为半同步复制(after-commit)。还有另外一种是增强半同步。
半同步复制配置
master配置
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
Query OK, 0 rows affected (0.20 sec)
mysqld.cnf 配置
# master半同步复制配置
plugin-load="rpl_semi_sync_master=semisync_master.so"
rpl_semi_sync_master_enabled=1
# 半同步超时时间,默认10s,半同步复制发生超时会转为异步复制
rpl_semi_sync_master_timeout=10000
slave配置
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
Query OK, 0 rows affected (0.06 sec)
mysqld.cnf 配置
# slave半同步复制配置
# 半同步复制配置
plugin-load="rpl_semi_sync_slave=semisync_slave.so"
rpl_semi_sync_slave_enabled=1