运维实战 Mysql高可用与健康检查
主从复制
主从复制自然是分为Maser端
和Slave端
的.
Master端设置操作
之前已经安装过Mysql
了因此安装步骤在下文会被略过
##创建专门用于主从复制的用户
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%' IDENTIFIED BY 'westos';
##为其设置密码并赋予权限
mysql>CREATE USER 'repl'@'%' IDENTIFIED BY 'westos';
mysql>GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
查看主库目前的状态
mysql> show master status
-> ;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 437 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
配置Server ID
vim /etc/my.cnf
[mysqld]
datadir=/usr/local/mysql/data
socket=/usr/local/mysql/data/mysql.sock
symbolic-links=0
server-id=1
log-bin=mysql-bin
##设置完成后重启MySQL
/etc/init.d/mysqld restart
Slave端设置操作
之前已经安装过Mysql
了因此安装步骤在下文会被略过
- 配置环境变量
[root@Server2 mysql]# vim ~/.bash_profile
PATH=$PATH:$HOME/bin:/usr/local/mysql/bin
[root@Server2 mysql]# source ~/.bash_profile
- 新建数据库所需用户
[root@Server2 mysql]# groupadd -g 1001 mysql
[root@Server2 mysql]# useradd -u 1001 -g mysql -M -d /usr/local/mysql/ -s /sbin/nologin mysql
- 删除数据库内
data
数据,保证环境清洁
同步要保证数据完全一致,如果存在区别则会报错
[root@Server2 ~]# cd /usr/local/mysql/data/
[root@Server2 data]# ls
auto.cnf ib_buffer_pool mysql Server1.err
ca-key.pem ibdata1 mysql.sock.lock Server1.pid
ca.pem ib_logfile0 performance_schema server-cert.pem
client-cert.pem ib_logfile1 private_key.pem server-key.pem
client-key.pem ibtmp1 public_key.pem sys
[root@Server2 data]# rm -rf *
- 配置Server ID
[root@Server2 mysql]# vim /etc/my.cnf
[mysqld]
datadir=/usr/local/mysql/data
socket=/usr/local/mysql/data/mysql.sock
symbolic-links=0
server-id=2
- 数据库安全初始化
[root@Server2 data]# mysqld --initialize --user=mysql
[root@Server2 data]# /etc/init.d/mysqld start
[root@Server2 data]# mysql_secure_installation
- 查看是否能够正确进入
[root@Server2 data]# mysql -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 11
Server version: 5.7.31 Source distribution
Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
同步相关配置
##配置主机信息,注意信息与上文必须做到一字不差
##否则就会出现差异导致失败
mysql> CHANGE MASTER TO MASTER_HOST='172.25.5.1',MASTER_USER='repl',MASTER_PASSWORD='westos',MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=437;
Query OK, 0 rows affected, 2 warnings (0.02 sec)
##启动slave端
mysql> START SLAVE;
Query OK, 0 rows affected (0.00 sec)
##查看slave状态
mysql> SHOW SLAVE STATUS\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.25.5.1
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 437
Relay_Log_File: Server2-relay-bin.000002
Relay_Log_Pos: 320
Relay_Master_Log_File: mysql-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: 437
Relay_Log_Space: 529
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: 7806f80a-9809-11eb-ac50-52540079f81b
Master_Info_File: /usr/local/mysql/data/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:
1 row in set (0.00 sec)
ERROR:
No query specified
注意事项
在查看Slave
状态(SHOW SLAVE STATUS\G
)时,以下两项必须均为YES
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
验证同步情况
- 在
Master
端进行数据库操作
mysql> CREATE DATABASE Test;
Query OK, 1 row affected (0.00 sec)
- 切换到
Slave
端进行查看,能够看到从机出现了刚刚创建的Test
数据库
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| Test |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
不难发现,这种方式费时费力,需要注意Master
的状态,如果mysql-bin.000001
变动或者重启, 都可能导致同步设置出错, 更不要提主从切换等操作了.
这大大增加了运维的难度, 因此也出现了新的方法
GTID复制
GTID工作原理
MASTER
更新数据时, 会在事务前产生GTID
, 一同记录到binlog
日志中.SLAVE
端的IO
线程将变更的binlog
, 写入到本地的relay log
中.sql
线程从relay log
中获取GTID
, 然后对比SLAVE
端的binlog
是否有记录.- 如果有记录, 说明该
GTID
的事务已经执行,SLAVE
会忽略. - 如果没有记录,
SLAVE
就会从relay log
中执行该GTID
的事务, 并记录到binlog
. - 在解析过程中会判断是否有主键, 如果没有就用二级索引, 如果没有就用全部扫描.
GTID优势
- 一个事务对应一个唯一
ID
, 一个GTID
在一个服务器上只会执行一次 GTID
是用来代替传统复制的方法,GTID
复制与普通复制模式的最大不同就是不需要指定二进制文件名和位置- 减少手工干预和降低服务故障时间, 当主机挂了之后通过软件从众多的备机中提升一台备机为主机
默认情况下,整个过程是异步的. 而异步就可能会出现问题, 需要有确认机制.
同时也存在着半同步状态, 默认情况下MASTER
的半同步时间为10s
, 超过10s
就会切为异步, 出现主从不一致.
因此生产环境中这一事件应该尽可能调大.
配置流程
主机
##在数据库主配置文件中增加GTID支持
[root@Server1 ~]# vim /etc/my.cnf
gtid_mode=ON
enforce-gtid-consistency=ON
##重启服务
[root@Server1 ~]# /etc/init.d/mysqld restart
Shutting down MySQL............ SUCCESS!
Starting MySQL.. SUCCESS!
##查看数据库状态
[root@Server1 ~]# mysql -p
mysql> show master status;
从机
##在数据库主配置文件中增加GTID支持
[root@Server2 data]# vim /etc/my.cnf\
gtid_mode=ON
enforce-gtid-consistency=ON
##重启服务
[root@Server2 data]# /etc/init.d/mysqld restart
##查看数据库状态
[root@Server2 data]# mysql -pwestos
mysql> show slave status\G;
##停止当前的slave,修改其配置后重启
mysql> stop slave;
mysql> change master to master_host='172.25.5.1', master_user='repl', master_password='westos', MASTER_AUTO_POSITION = 1;
mysql> start slave;
##假设Server2将Server1当作主机,Server3将Server2当作主机
##则Server3的设置应该如下所示
[root@Server3 ~]# vim /etc/my.cnf
gtid_mode=ON
enforce-gtid-consistency=ON
[root@Server3 ~]# /etc/init.d/mysqld restart
[root@Server3 ~]# mysql -pwestos
MySQL [(none)]> stop slave;
MySQL [(none)]> change master to master_host='192.168.0.12', master_user='repl', master_password='westos',
MASTER_AUTO_POSITION = 1;
MySQL [(none)]> start slave;
半同步复制
传统的复制模式属于异步复制, 主库只管发送二进制日志, 而不关心从库是否收到.
这种复制方式虽然复制速度很快, 但从实现上就无法保证主从数据的一致性.
在生产环境中数据量增大的情况下可能造成极大的危险性.
半同步复制的流程
- 主库发送二进制二进制日志到从库
- 从库接收到数据并存入
relay-log
- 从库发送
ack确认
给主库 - 主库接收到确认, 整个复制流程结束
ACK
确认提交后才作引擎提交, 做了引擎提交之后其他用户才能查看到数据.
不难看出, 这一操作保证了主从数据的一致性.
主机
##启动Mysql并登陆
/etc/init.d/mysqld start
mysql -pwestos
##启用半同步
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
##查看相关信息
SHOW variables like 'rpl%';
##启用半同步服务并设置超时时间
SET GLOBAL rpl_semi_sync_master_enabled = 1;
SET GLOBAL rpl_semi_sync_master_timeout = 1000;
##启用后也可以查看半同步服务的状态
SHOW status like 'rpl%';
从机
##启动Mysql并登陆
/etc/init.d/mysqld start
mysql -pwestos
##查看IO和SQL线程的状态是否为YES
SHOW SLAVE STATUS\G;
##启用半同步插件
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
##启用半同步服务
SET GLOBAL rpl_semi_sync_slave_enabled = 1;
##查看启用情况
SHOW variables like 'rpl%';
##但是如果不重启IO线程,实际上服务并没有运行
mysql> SHOW status like 'rpl%';
+----------------------------+-------+
| Variable_name | Value