Mysql 集群技术

目录

[一 Mysql 在服务器中的部署方法](#一 Mysql 在服务器中的部署方法)

[1.1 在Linux下部署mysql](#1.1 在Linux下部署mysql)

[1.1.1 安装依赖性:](#1.1.1 安装依赖性:)

[1.1.2 下载并解压源码包](#1.1.2 下载并解压源码包)

[1.1.3 源码编译安装mysql](#1.1.3 源码编译安装mysql)

[1.1.4 部署mysql](#1.1.4 部署mysql)

[1.1.5 对另一台主机进行源码编译](#1.1.5 对另一台主机进行源码编译)

[二 mysql的组从复制](#二 mysql的组从复制)

[2.1 配置mastesr](#2.1 配置mastesr)

[2.2 配置salve](#2.2 配置salve)

[2.3 当有数据时添加slave2](#2.3 当有数据时添加slave2)

[2.4 延迟复制](#2.4 延迟复制)

[2.5 慢查询日志](#2.5 慢查询日志)

[2.6 mysql的并行复制](#2.6 mysql的并行复制)

[2.7 原理刨析](#2.7 原理刨析)

[2.8 架构缺陷](#2.8 架构缺陷)

[三 半同步模式](#三 半同步模式)

3.1半同步模式原理

[3.2 gtid模式](#3.2 gtid模式)

3.3.启用半同步模式

3.4.测试

[四 mysql高可用之组复制 (MGR)](#四 mysql高可用之组复制 (MGR))

[4.1 组复制流程](#4.1 组复制流程)

[4.2 组复制单主和多主模式](#4.2 组复制单主和多主模式)

4.3.实现mysql组复制

[五 mysql-router(mysql路由)](#五 mysql-router(mysql路由))

[六 mysql高可用之MHA](#六 mysql高可用之MHA)

6.1.MHA概述

[6.2 MHA部署实施](#6.2 MHA部署实施)

[6.2.1 搭建主两从架构](#6.2.1 搭建主两从架构)

6.2.2安装MHA所需要的软件

[6.2.3 配置MHA 的管理环境](#6.2.3 配置MHA 的管理环境)

[6.2.4 MHA的故障切换](#6.2.4 MHA的故障切换)

[6.2.5 为MHA添加VIP功能](#6.2.5 为MHA添加VIP功能)


Mysql在服务器中的部署方法

在企业中 90% 的服务器操作系统均为 Linux
在企业中对于 Mysql 的安装通常用源码编译的方式来进行
官网: http://www.mysql.com

1.1Linux下部署mysql

1.1.1****安装依赖性:

[root@mysql-node ~]# yum install cmake gcc-c++ openssl-devel \> ncurses-devel.x86_64 libtirpc-devel-0.2.4-0.16.el7.x86_64.rpm rpcgen.x86_64 -y

1.1.2****下载并解压源码包

[root@mysql-node ~]# tar zxf mysql-boost-5.7.44.tar.gz

[root@mysql-node ~]# cd /root/mysql-5.7.44/

1.1.3源码编译安装mysql

[root@mysql-node mysql-5.7.44]# cmake \
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql \ #指定安装路径
-DMYSQL_DATADIR=/data/mysql \ #指定数据目录 -DMYSQL_UNIX_ADDR=/data/mysql/mysql.sock \ #指定套接字文件
-DWITH_INNOBASE_STORAGE_ENGINE=1 \#指定启用INNODB存储引擎,默认用myisam
-DWITH_EXTRA_CHARSETS=all \#扩展字符集
-DDEFAULT_CHARSET=utf8mb4 \ #指定默认字符集
-DDEFAULT_COLLATION=utf8mb4_unicode_ci \ #指定默认校验字符集
-DWITH_BOOST=/root/mysql-5.7.44/boost/boost_1_59_0/ #指定c++库依赖

[root@mysql-node mysql-5.7.44]# make -j2 #-j2 表示有几个核心就跑几个进程
[root@mysql-node mysql-5.7.44]# make install

注意:当cmake出错后如果想重新检测,删除 mysql-5.7.44 中 CMakeCache.txt即可

1.1.4部署mysql

#创建用户并给改权限
[root@mysql-node mysql]# useradd -s /sbin/nologin -M mysql
[root@mysql-node ~]# mkdir -p /data/mysql
[root@mysql-node mysql]# chown -R mysql.mysql /data/mysql

生成启动脚本

[root@mysql-node ~]# cd /usr/local/mysql/support-files/
[root@mysql-node support-files]# cp mysql.server /etc/init.d/mysqld

修改环境变量

[root@mysql-node ~]# vim ~/.bash_profile
PATH=PATH:HOME/bin:/usr/local/mysql/bin
[root@mysql-node ~]# source ~/.bash_profile

生成配置文件

[root@mysql-node rhel7]# vim /etc/my.cnf
[mysqld]
datadir=/data/mysql #指定数据目录
socket=/data/mysql/mysql.sock #指定套接字
symbolic-links=0 # 数据只能存放到数据目录中,禁止链接到数据目录

数据库初始化建立 mysql 基本数据

[root@mysql-node ~]# mysqld --initialize --user=mysql

InnoDB 日志文件创建

2024-08-22T01:20:36.084103Z 0 [Warning] InnoDB: New log files created, LSN=45790

外键约束系统表创建

2024-08-22T01:20:36.214263Z 0 [Warning] InnoDB: Creating foreign key constraint system tables.

生成新的 UUID

2024-08-22T01:20:36.284170Z 0 [Warning] No existing UUID has been found, so we assume that this is the first time that this server has been started. Generating a new UUID: bc1c65fc-6024-11ef-8be5-000c2907e18c.

GTID 表未准备好

2024-08-22T01:20:36.285763Z 0 [Warning] Gtid table is not ready to be used. Table 'mysql.gtid_executed' cannot be opened.

TLS 版本警告

2024-08-22T01:20:36.355459Z 0 [Warning] A deprecated TLS version TLSv1 is enabled. Please use TLSv1.2 or higher.
2024-08-22T01:20:36.355476Z 0 [Warning] A deprecated TLS version TLSv1.1 is enabled. Please use TLSv1.2 or higher.
#CA 证书警告
2024-08-22T01:20:36.356188Z 0 [Warning] CA certificate ca.pem is self signed.

临时密码生成

2024-08-22T01:20:36.379701Z 1 [Note] A temporary password is generated for root@localhost: T6.%V!Fw?ldl

[root@mysql-node mysql]# /etc/init.d/mysqld start
Starting MySQL.. SUCCESS!
[root@mysql-node ~]# chkconfig mysqld on #自动启用 MySQL 服务

数据库安全初始化

[root@mysql-node ~]# mysql_secure_installation
Securing the MySQL server deployment.

Enter password for user root: #输入当前密码

The existing password for the user account root has expired. Please set a new password.

New password: #输入新密码

Re-enter new password: #重复密码

VALIDATE PASSWORD PLUGIN can be used to test passwords

and improve security. It checks the strength of password

and allows the users to set only those passwords which are

secure enough. Would you like to setup VALIDATE PASSWORD plugin?

Press y|Y for Yes, any other key for No: no #是否启用密码插件

Using existing password for root.

Change the password for root ? ((Press y|Y for Yes, any other key for No) : no #是否要重置密码

... skipping.

By default, a MySQL installation has an anonymous user,

allowing anyone to log into MySQL without having to have

a user account created for them. This is intended only for

testing, and to make the installation go a bit smoother.

You should remove them before moving into a production

environment.

Remove anonymous users? (Press y|Y for Yes, any other key for No) : y

Success.

Normally, root should only be allowed to connect from

'localhost'. This ensures that someone cannot guess at

the root password from the network.

Disallow root login remotely? (Press y|Y for Yes, any other key for No) : y

Success.

By default, MySQL comes with a database named 'test' that

anyone can access. This is also intended only for testing,

and should be removed before moving into a production

environment.

Remove test database and access to it? (Press y|Y for Yes, any other key for No) : y

  • Dropping test database...

Success.

  • Removing privileges on test database...

Success.

Reloading the privilege tables will ensure that all changes

made so far will take effect immediately.

Reload privilege tables now? (Press y|Y for Yes, any other key for No) : y

Success.

All done!

测试:

[root@mysql-node ~]# mysql -uroot -p123 #注意:这是测试环境下把密码写在命令行中

mysql: [Warning] Using a password on the command line interface can be insecure.

Welcome to the MySQL monitor. Commands end with ; or \g.

Your MySQL connection id is 5

Server version: 5.7.44 Source distribution

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

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>

1.1.5 对另一台主机进行源码编译

[root@mysql-node ~]# rsync -al /usr/local/mysql root@192.168.10.140:/usr/local

[root@mysql ~]# cd /usr/local/

[root@mysql local]# ls

bin etc games include lib lib64 libexec mysql sbin share src

[root@mysql local]#

[root@mysql local]# useradd -s /sbin/nologin -M mysql

[root@mysql local]# mkdir /data/mysql -p

[root@mysql local]# chown -R mysql.mysql /data/mysql/

[root@mysql local]# ll /data/mysql/ -ld

drwxr-xr-x 2 mysql mysql 6 8月 22 14:38 /data/mysql/

[root@mysql ~]# cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld

[root@mysql ~]# vim ~/.bash_profile

PATH=PATH:HOME/bin:/usr/local/mysql/bin

[root@mysql ~]# source ~/.bash_profile

[root@mysql ~]#

[root@mysql ~]# vim /etc/my.cnf

[mysqld]

datadir=/data/mysql

socket=/data/mysql/mysql.sock

symbolic-links=0

[root@mysql ~]# mysqld --initialize --user=mysql

2024-08-22T07:02:19.863874Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).

2024-08-22T07:02:20.751269Z 0 [Warning] InnoDB: New log files created, LSN=45790

2024-08-22T07:02:20.895574Z 0 [Warning] InnoDB: Creating foreign key constraint system tables.

2024-08-22T07:02:20.967020Z 0 [Warning] No existing UUID has been found, so we assume that this is the first time that this server has been started. Generating a new UUID: 79dab3e1-6054-11ef-a6e9-000c2991d455.

2024-08-22T07:02:20.968295Z 0 [Warning] Gtid table is not ready to be used. Table 'mysql.gtid_executed' cannot be opened.

2024-08-22T07:02:21.026969Z 0 [Warning] A deprecated TLS version TLSv1 is enabled. Please use TLSv1.2 or higher.

2024-08-22T07:02:21.026986Z 0 [Warning] A deprecated TLS version TLSv1.1 is enabled. Please use TLSv1.2 or higher.

2024-08-22T07:02:21.030500Z 0 [Warning] CA certificate ca.pem is self signed.

2024-08-22T07:02:21.072374Z 1 [Note] A temporary password is generated for root@localhost: k,F9,ukq?Qd7

[root@mysql ~]# ls /data/mysql/

auto.cnf ibdata1 public_key.pem

ca-key.pem ib_logfile0 server-cert.pem

ca.pem ib_logfile1 server-key.pem

client-cert.pem mysql sys

client-key.pem performance_schema

ib_buffer_pool private_key.pem

[root@mysql ~]# /etc/init.d/mysqld start

Starting MySQL.Logging to '/data/mysql/mysql.node2.com.err'.

SUCCESS!

[root@mysql ~]# chkconfig mysqld on

[root@mysql ~]# mysql_secure_installation

Securing the MySQL server deployment.

Enter password for user root:

The existing password for the user account root has expired. Please set a new password.

New password:

Re-enter new password:

VALIDATE PASSWORD PLUGIN can be used to test passwords

and improve security. It checks the strength of password

and allows the users to set only those passwords which are

secure enough. Would you like to setup VALIDATE PASSWORD plugin?

Press y|Y for Yes, any other key for No: no

Using existing password for root.

Change the password for root ? ((Press y|Y for Yes, any other key for No) : no

... skipping.

By default, a MySQL installation has an anonymous user,

allowing anyone to log into MySQL without having to have

a user account created for them. This is intended only for

testing, and to make the installation go a bit smoother.

You should remove them before moving into a production

environment.

Remove anonymous users? (Press y|Y for Yes, any other key for No) : y

Success.

Normally, root should only be allowed to connect from

'localhost'. This ensures that someone cannot guess at

the root password from the network.

Disallow root login remotely? (Press y|Y for Yes, any other key for No) : y

Success.

By default, MySQL comes with a database named 'test' that

anyone can access. This is also intended only for testing,

and should be removed before moving into a production

environment.

Remove test database and access to it? (Press y|Y for Yes, any other key for No) : y

  • Dropping test database...

Success.

  • Removing privileges on test database...

Success.

Reloading the privilege tables will ensure that all changes

made so far will take effect immediately.

Reload privilege tables now? (Press y|Y for Yes, any other key for No) : y

Success.

All done!

测试:

[root@mysql ~]# mysql -uroot -p123

mysql: [Warning] Using a password on the command line interface can be insecure.

Welcome to the MySQL monitor. Commands end with ; or \g.

Your MySQL connection id is 5

Server version: 5.7.44 Source distribution

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

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>

mysql的组从复制

2.1配置mastesr

[root@mysql-node ~]# vim /etc/my.cnf

[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
symbolic-links=0
log-bin=mysql-bin
server-id=1

[root@mysql-node ~]# /etc/init.d/mysqld restart

进入数据库配置用户权限

[root@mysql-node ~]# mysql -p123
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.44-log Source distribution

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

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> create user 'repl'@'%' identified by 'lee'; ##生成专门用来做复制的用户,此用户是用于slave端做认证用

Query OK, 0 rows affected (0.01 sec)

mysql> grant replication slave on *.* to repl@'%'; ##对这个用户进行授权
Query OK, 0 rows affected (0.00 sec)

mysql> show master status; ##查看master的状态
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 595 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

mysql> quit
Bye

[root@mysql-node ~]# cd /data/mysql/
[root@mysql-node mysql]# mysqlbinlog mysql-bin.000001 -vv ## 查看二进制日志

2.2配置salve

[root@mysql ~]# vim /etc/my.cnf

[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
symbolic-links=0
server-id=2

[root@mysql ~]# /etc/init.d/mysqld restart

[root@mysql ~]# mysql -p123

mysql> CHANGE MASTER TO

-> MASTER_HOST='192.168.10.130',MASTER_USER='repl',MASTERR_PASSWORD='lee',MASTER_LOG_FILE='mysql-bi000001',MASTER_LOG_POS=595;

Query OK, 0 rows affected, 2 warnings (0.01 sec)

mysql> start slave;

Query OK, 0 rows affected (0.00 sec)

#如果想要停止

mysql> STOP SLAVE IO_THREAD;

Query OK, 0 rows affected (0.00 sec)

mysql> SHOW SLAVE STATUS\G;

*************************** 1. row ***************************

Slave_IO_State: Waiting for master to send event

Master_Host: 192.168.10.130

Master_User: repl

Master_Port: 3306

Connect_Retry: 60

Master_Log_File: mysql-bin.000001

Read_Master_Log_Pos: 754

Relay_Log_File: mysql-relay-bin.000004

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: 754

Relay_Log_Space: 852

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: 639d0234-6036-11ef-9994-000c2907e18c

Master_Info_File: /data/mysql/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)

#注意:这里如果出错(即这里的不是yes Slave_IO_Running: Yes)看底下给出的错误信息,也有可能是你的防火墙和selinux没有关

测试:

[root@mysql-node ~]# mysql -p123

mysql> create database haha;

Query OK, 0 rows affected (0.01 sec)

mysql> create table haha.userlist(

-> username varchar(20) not null,

-> password varchar(50) not null

-> );

Query OK, 0 rows affected (0.01 sec)

mysql> insert into haha.userlist value ('xixi','1112');

Query OK, 1 row affected (0.01 sec)

mysql> select * from haha.userlist;

+----------+----------+

| username | password |

+----------+----------+

| xixi | 1112 |

+----------+----------+

1 row in set (0.00 sec)

在slave中查看数据是否有同步过来

[root@mysql ~]# mysql -p123

mysql> select * from haha.userlist;

+----------+----------+

| username | password |

+----------+----------+

| xixi | 1112 |

+----------+----------+

1 row in set (0.00 sec)

注意:

在 slave 阶段中默认情况下是开启了写功能的,但是建议关闭 slave 节点的写功能来保证数据一致性
vim /etc/my.cnf
[mysqld]
super_read_only=on

2.3当有数据时添加slave2

[root@mysql-node3 ~]# vim /etc/my.cnf

[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
symbolic-links=0
erver-id=3

[root@mysql-node3 ~]# /etc/init.d/mysqld restart

从 master 节点备份数据

[root@mysql-node ~]# mysqldump -p haha > haha.sql
Enter password:
[root@mysql-node ~]# cat haha.sql
[root@mysql-node ~]# scp haha.sql root@192.168.10.150:/mnt/
The authenticity of host '192.168.10.150 (192.168.10.150)' can't be established.
ECDSA key fingerprint is SHA256:5flpLOEGakncAmIC/h6XbCsbiqcbt2ejCE7y4dIrCIs.
ECDSA key fingerprint is MD5:30:cf:04:80:d3:6d:48:1c:a8:58:5d:19:f5:45:7a:cc.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.10.150' (ECDSA) to the list of known hosts.
root@192.168.10.150's password:
haha.sql 100% 1946 1.1MB/s 00:00
生产环境中备份时需要锁表,保证备份前后的数据一致
mysql> FLUSH TABLES WITH READ LOCK;
备份后再解锁
mysql> UNLOCK TABLES;
mysqldump 命令备份的数据文件,在还原时先 DROP TABLE ,需要合并数据时需要删除此语句

-- Table structure for table `userlist`

DROP TABLE IF EXISTS `userlist`; # 需要合并数据时需要删除此语句
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
[root@mysql-node3 ~]# mysql -p123 -e "create database haha;"

mysql: [Warning] Using a password on the command line interface can be insecure.

[root@mysql-node3 ~]# mysql -p123 haha < /mnt/haha.sql

mysql: [Warning] Using a password on the command line interface can be insecure.

[root@mysql-node3 ~]# mysql -p123 -e "select * from haha.userlist;"

mysql: [Warning] Using a password on the command line interface can be insecure.

+----------+----------+

| username | password |

+----------+----------+

| xixi | 1112 |

+----------+----------+

配置 slave2 的 slave 功能

在 master 中查询日志 pos

[root@mysql-node ~]# mysql -p123
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 1245 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
[root@mysql-node3 ~]# mysql -p123
mysql> change master to master_host='192.168.10.130',master_user='repl',master_password='lee',master_log_file='mysql-bin.000001',master_log_pos=1245;
Query OK, 0 rows affected, 2 warnings (0.01 sec)
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.10.130
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 1245
Relay_Log_File: mysql-node3-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: 1245
Relay_Log_Space: 533
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: 639d0234-6036-11ef-9994-000c2907e18c
Master_Info_File: /data/mysql/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)

测试:

[root@mysql-node ~]# mysql -p123 -e "insert into haha.userlist values('xixi2',1234);"

[root@mysql ~]# mysql -p123 -e "select * from haha.userlist;"

mysql: [Warning] Using a password on the command line interface can be insecure.

+----------+----------+

| username | password |

+----------+----------+

| xixi | 1112 |

| xixi2 | 1234 |

+----------+----------+

[root@mysql-node3 ~]# mysql -p123 -e "select * from haha.userlist;"

mysql: [Warning] Using a password on the command line interface can be insecure.

+----------+----------+

| username | password |

+----------+----------+

| xixi | 1112 |

| xixi2 | 1234 |

+----------+----------+

注意:

在 slave 阶段中默认情况下是开启了写功能的,但是建议关闭 slave 节点的写功能来保证数据一致性
vim /etc/mysql.cnf
[mysqld]
super_read_only=on

2.4****延迟复制

延迟复制时用来控制 sql 线程的,和 i/o 线程无关
这个延迟复制不是 i/o 线程过段时间来复制, i/o 是正常工作的
是日志已经保存在 slave 端了,那个 sql 要等多久进行回放
当 master 端误操作,可以在 slave 端进行数据备份

在 slave 端

mysql> STOP SLAVE SQL_THREAD;
mysql> CHANGE MASTER TO MASTER_DELAY=60;
mysql> START SLAVE SQL_THREAD;
mysql> SHOW SLAVE STATUS\G;
Master_Server_Id: 1
Master_UUID: 639d0234-6036-11ef-9994-000c2907e18c
Master_Info_File: /data/mysql/master.info
SQL_Delay: 60
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Master_Retry_Count: 86400
测试:
在 master 中写入数据后过了延迟时间才能被查询到

2.5****慢查询日志

  • 慢查询,顾名思义,执行很慢的查询
  • 当执行SQL超过long_query_time参数设定的时间阈值(默认10s)时,就被认为是慢查询,这个
  • SQL语句就是需要优化的
  • 慢查询被记录在慢查询日志里
  • 慢查询日志默认是不开启的
  • 如果需要优化SQL语句,就可以开启这个功能,它可以让你很容易地知道哪些语句是需要优化的。

mysql> SHOW variables like "slow%";

+---------------------+---------------------------------+

| Variable_name | Value |

+---------------------+---------------------------------+

| slow_launch_time | 2 |

| slow_query_log | OFF |

| slow_query_log_file | /data/mysql/mysql-node-slow.log |

+---------------------+---------------------------------+

3 rows in set (0.01 sec)
开启慢查询日志

mysql> SET GLOBAL slow_query_log=ON;

Query OK, 0 rows affected (0.01 sec)

mysql> SET long_query_time=4;

Query OK, 0 rows affected (0.00 sec)

mysql> SHOW VARIABLES like "long%";

+-----------------+----------+

| Variable_name | Value |

+-----------------+----------+

| long_query_time | 4.000000 |

+-----------------+----------+

1 row in set (0.00 sec)

mysql> SHOW VARIABLES like "slow%";

+---------------------+---------------------------------+

| Variable_name | Value |

+---------------------+---------------------------------+

| slow_launch_time | 2 |

| slow_query_log | ON | ##慢查询日志开启

| slow_query_log_file | /data/mysql/mysql-node-slow.log |

+---------------------+---------------------------------+

3 rows in set (0.00 sec)

[root@mysql-node ~]# cat /data/mysql/mysql-node-slow.log

/usr/local/mysql/bin/mysqld, Version: 5.7.44-log (Source distribution). started with:

Tcp port: 3306 Unix socket: /data/mysql/mysql.sock

Time Id Command Argument
测试慢查询

[root@mysql-node ~]# mysql -p123
mysql> select sleep (10);
+------------+
| sleep (10) |
+------------+
| 0 |
+------------+
1 row in set (10.00 sec)

[root@mysql-node ~]# cat /data/mysql/mysql-node-slow.log
/usr/local/mysql/bin/mysqld, Version: 5.7.44-log (Source distribution). started with:
Tcp port: 3306 Unix socket: /data/mysql/mysql.sock
Time Id Command Argument
/usr/local/mysql/bin/mysqld, Version: 5.7.44-log (Source distribution). started with:
Tcp port: 3306 Unix socket: /data/mysql/mysql.sock
Time Id Command Argument

Time: 2024-08-26T07:25:51.228702Z

User@Host: root[root] @ localhost [] Id: 4

Query_time: 10.000570 Lock_time: 0.000000 Rows_sent: 1 Rows_examined: 0

SET timestamp=1724657151;
select sleep (10);

2.6 mysql****的并行复制

查看 slave 中的线程信息


默认情况下 slave 中使用的是 sql 单线程回放
在 master 中时多用户读写,如果使用 sql 单线程回放那么会造成组从延迟严重
开启 MySQL 的多线程回放可以解决上述问题

在 slaves 中设定
[root@mysql ~]# vim /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
symbolic-links=0
server-id=2
super_read_only=on
gtid_mode=ON
enforce-gtid-consistency=ON
slave-parallel-type=LOGICAL_CLOCK # 基于组提交
slave-parallel-workers=16 # 开启线程数量
master_info_repository=TABLE #master 信息在表中记录,默认记录
在 /data/mysql/master.info
relay_log_info_repository=TABLE # 回放日志信息在表中记录,默认记录
在 /data/mysql/relay-log.info

relay_log_recovery=ON #日志回放恢复功能开启

[root@mysql ~]# /etc/init.d/mysqld restart

Shutting down MySQL. SUCCESS!

Starting MySQL. SUCCESS!


此时 sql 线程转化为协调线程, 16 个 worker 负责处理 sql 协调线程发送过来的处理请求

MySQL 组提交( Group commit )是一个性能优化特性,它允许在一个事务日志同步操作中将多个事务的日志记录一起写入。这样做可以减少磁盘I/O 的次数,从而提高数据库的整体性能。

2.7****原理刨析


三个线程

实际上主从同步的原理就是基于 binlog 进行数据同步的。在主从复制过程中,会基于 3 个线程来操作,一个主库线程,两个从库线程。

  • 二进制日志转储线程(Binlog dump thread)是一个主库线程。当从库线程连接的时候, 主库可以将二进制日志发送给从库,当主库读取事件(Event)的时候,会在 Binlog 上加锁,读取完成之后,再将锁释放掉。
  • 从库 I/O 线程会连接到主库,向主库发送请求更新 Binlog。这时从库的 I/O 线程就可以读取到主库的二进制日志转储线程发送的 Binlog 更新部分,并且拷贝到本地的中继日志 (Relay log)。
  • 从库 SQL 线程会读取从库中的中继日志,并且执行日志中的事件,将从库中的数据与主库保持同步。
    复制三步骤

步骤 1 : Master 将写操作记录到二进制日志( binlog )。
步骤 2 : Slave 将 Master 的 binary log events 拷贝到它的中继日志( relay log );
步骤 3 : Slave 重做中继日志中的事件,将改变应用到自己的数据库中。 MySQL 复制是异步的且串行化的,而且重启后从接入点开始复制。
具体操作
1.slaves 端中设置了 master 端的 ip ,用户,日志,和日志的 Position ,通过这些信息取得 master 的认证及
信息
2.master 端在设定好 binlog 启动后会开启 binlog dump 的线程
3.master 端的 binlog dump 把二进制的更新发送到 slave 端的
4.slave 端开启两个线程,一个是 I/O 线程,一个是 sql 线程,

  • i/o线程用于接收master端的二进制日志,此线程会在本地打开relaylog中继日志,并且保存到本地磁盘
  • sql线程读取本地relog中继日志进行回放
  1. 什么时候我们需要多个 slave ?
    当读取的而操作远远高与写操作时。我们采用一主多从架构
    数据库外层接入负载均衡层并搭配高可用机制

2.8****架构缺陷

  • 主从架构采用的是异步机制
  • master更新完成后直接发送二进制日志到slave,但是slaves是否真正保存了数据master端不会检测
  • master端直接保存二进制日志到磁盘
  • 当master端到slave端的网络出现问题时或者master端直接挂掉,二进制日志可能根本没有到达slave
  • master出现问题slave端接管master,这个过程中数据就丢失了
  • 这样的问题出现就无法达到数据的强一致性,零数据丢失

三 半同步模式

3.1****半同步模式原理

  1. 用户线程写入完成后 master 中的 dump 会把日志推送到 slave 端
    2.slave 中的 io 线程接收后保存到 relaylog 中继日志
  2. 保存完成后 slave 向 master 端返回 ack
  3. 在未接受到 slave 的 ack 时 master 端时不做提交的,一直处于等待当收到 ack 后提交到存储引擎
  4. 在 5.6 版本中用到的时 after_commit 模式, after_commit 模式时先提交在等待 ack 返回后输出 ok

3.2 gtid****模式

当为启用 gtid 时我们要考虑的问题
在 master 端的写入时多用户读写,在 slave 端的复制时单线程日志回放,所以 slave 端一定会延迟与master端
这种延迟在 slave 端的延迟可能会不一致,当 master 挂掉后 slave 接管,一般会挑选一个和 master 延迟日志最接近的充当新的master
那么为接管 master 的主机继续充当 slave 角色并会指向到新的 master 上,作为其 slave
这时候按照之前的配置我们需要知道新的 master 上的 pos 的 id ,但是我们无法确定新的 master 和 slave 之间差多少


当激活 GITD 之后
当 master 出现问题后, slave2 和 master 的数据最接近,会被作为新的 master
slave1 指向新的 master ,但是他不会去检测新的 master 的 pos id ,只需要继续读取自己 gtid_next 即可

[root@mysql-node ~]# mysqlbinlog -vv /data/mysql/mysql-bin.000003

/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;

/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;

DELIMITER /*!*/;

at 4

#240826 15:54:11 server id 1 end_log_pos 123 CRC32 0x7b22c786 Start: binlog v 4, server v 5.7.44-log created 240826 15:54:11 at startup

Warning: this binlog is either in use or was not closed properly.

ROLLBACK/*!*/;

BINLOG '

ozTMZg8BAAAAdwAAAHsAAAABAAQANS43LjQ0LWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAACjNMxmEzgNAAgAEgAEBAQEEgAAXwAEGggAAAAICAgCAAAACgoKKioAEjQA

AYbHIns=

'/*!*/;

at 123

#240826 15:54:11 server id 1 end_log_pos 154 CRC32 0x47a3883e Previous-GTIDs

[empty]

SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;

DELIMITER ;

End of log file

/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;

/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/
[root@mysql-node3 ~]# mysql -p123
mysql> select * from mysql.gtid_executed;
+--------------------------------------+----------------+--------------+
| source_uuid | interval_start | interval_end |
+--------------------------------------+----------------+--------------+
| 768c6b91-4c01-11ef-a514-000c299355ea | 1 | 1 |
+--------------------------------------+----------------+--------------+
1 row in set (0.00 sec)

设置gtid

在 master 端和 slave 端开启 gtid 模式

[root@mysql-node ~]# vim /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
symbolic-links=0
log-bin=mysql-bin
server-id=1
gtid_mode=ON
enforce-gtid-consistency=ON

[root@mysql-node ~]# /etc/init.d/mysqld restart
[root@mysql ~]# vim /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
symbolic-links=0
server-id=2
super_read_only=on
gtid_mode=ON
[root@mysql-node ~]# /etc/init.d/mysqld restart

[root@mysql-node3 ~]# cat /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
symbolic-links=0
server-id=3
super_read_only=on
gtid_mode=ON
[root@mysql-node ~]# /etc/init.d/mysqld restart

停止 slave 端

[root@mysql ~]# mysql -p123
mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)
[root@mysql-node3 ~]# mysql -p123
mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)

开启 slave 端的 gtid

mysql> CHANGE MASTER TO MASTER_HOST='192.168.10.130', MASTER__USER='repl',MASTER_PASSWORD='lee', MASTER_AUTO_POSITION=1;
Query OK, 0 rows affected, 2 warnings (0.01 sec)

mysql> start slave;

Query OK, 0 rows affected (0.01 sec)

mysql> show slave status\G;

*************************** 1. row ***************************

Slave_IO_State: Waiting for master to send event

Master_Host: 192.168.10.130

Master_User: repl

Master_Port: 3306

Connect_Retry: 60

Master_Log_File: mysql-bin.000004

Read_Master_Log_Pos: 154

Relay_Log_File: mysql-node3-relay-bin.000002

Relay_Log_Pos: 367

Relay_Master_Log_File: mysql-bin.000004

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: 154

Relay_Log_Space: 580

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: 639d0234-6036-11ef-9994-000c2907e18c

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: 1 #功能开启

Replicate_Rewrite_DB:

Channel_Name:

Master_TLS_Version:

1 row in set (0.00 sec)

**3.3.**启用半同步模式

在 master 端配置启用半同步模式

[root@mysql-node ~]# vim /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
symbolic-links=0
log-bin=mysql-bin
server-id=1
gtid_mode=ON
enforce-gtid-consistency=ON
rpl_semi_sync_master_enabled=1 # 开启半同步功能
[root@mysql-node ~]# mysql -p123

安装半同步插件

mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
Query OK, 0 rows affected (0.01 sec)

查看插件情况

mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS
-> FROM INFORMATION_SCHEMA.PLUGINS
-> WHERE PLUGIN_NAME LIKE '%semi%';
+----------------------+---------------+
| PLUGIN_NAME | PLUGIN_STATUS |
+----------------------+---------------+
| rpl_semi_sync_master | ACTIVE |
+----------------------+---------------+
1 row in set (0.00 sec)

打开半同步功能

mysql> SET GLOBAL rpl_semi_sync_master_enabled = 1;
Query OK, 0 rows affected (0.00 sec)

查看半同步功能状态

mysql> SHOW VARIABLES LIKE 'rpl_semi_sync%';
+-------------------------------------------+------------+
| Variable_name | Value |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled | ON |
| rpl_semi_sync_master_timeout | 10000 |
| rpl_semi_sync_master_trace_level | 32 |
| rpl_semi_sync_master_wait_for_slave_count | 1 |
| rpl_semi_sync_master_wait_no_slave | ON |
| rpl_semi_sync_master_wait_point | AFTER_SYNC |
+-------------------------------------------+------------+
6 rows in set (0.00 sec)
mysql> SHOW STATUS LIKE 'Rpl_semi_sync%';
+--------------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients | 0 |
| Rpl_semi_sync_master_net_avg_wait_time | 0 |
| Rpl_semi_sync_master_net_wait_time | 0 |
| Rpl_semi_sync_master_net_waits | 0 |
| Rpl_semi_sync_master_no_times | 0 |
| Rpl_semi_sync_master_no_tx | 0 |
| Rpl_semi_sync_master_status | ON |
| Rpl_semi_sync_master_timefunc_failures | 0 |
| Rpl_semi_sync_master_tx_avg_wait_time | 0 |
| Rpl_semi_sync_master_tx_wait_time | 0 |
| Rpl_semi_sync_master_tx_waits | 0 |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0 |
| Rpl_semi_sync_master_wait_sessions | 0 |
| Rpl_semi_sync_master_yes_tx | 0 |
+--------------------------------------------+-------+
14 rows in set (0.00 sec)
mysql> show plugins;
在 slave 端开启半同步功能
[root@mysql ~]# vim /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
symbolic-links=0
server-id=2
#super_read_only=on
gtid_mode=ON
enforce-gtid-consistency=ON
rpl_semi_sync_master_enabled=1 # 开启半同步功能
[root@mysql ~]# mysql -p123
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';

Query OK, 0 rows affected (0.00 sec)

mysql> SET GLOBAL rpl_semi_sync_slave_enabled =1;

Query OK, 0 rows affected (0.00 sec)

mysql> STOP SLAVE IO_THREAD; #重启io线程,半同步才能生效

Query OK, 0 rows affected (0.00 sec)
mysql> START SLAVE IO_THREAD; # 重启 io 线程,半同步才能生效
Query OK, 0 rows affected (0.00 sec)
mysql> SHOW VARIABLES LIKE 'rpl_semi_sync%';
+-------------------------------------------+------------+
| Variable_name | Value |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled | ON |
| rpl_semi_sync_master_timeout | 10000 |
| rpl_semi_sync_master_trace_level | 32 |
| rpl_semi_sync_master_wait_for_slave_count | 1 |
| rpl_semi_sync_master_wait_no_slave | ON |
| rpl_semi_sync_master_wait_point | AFTER_SYNC |
| rpl_semi_sync_slave_enabled | ON |
| rpl_semi_sync_slave_trace_level | 32 |
+-------------------------------------------+------------+
8 rows in set (0.00 sec)

mysql> SHOW STATUS LIKE 'Rpl_semi_sync%';
+--------------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients | 0 |
| Rpl_semi_sync_master_net_avg_wait_time | 0 |
| Rpl_semi_sync_master_net_wait_time | 0 |
| Rpl_semi_sync_master_net_waits | 0 |
| Rpl_semi_sync_master_no_times | 0 |
| Rpl_semi_sync_master_no_tx | 0 |
| Rpl_semi_sync_master_status | ON |
| Rpl_semi_sync_master_timefunc_failures | 0 |
| Rpl_semi_sync_master_tx_avg_wait_time | 0 |
| Rpl_semi_sync_master_tx_wait_time | 0 |
| Rpl_semi_sync_master_tx_waits | 0 |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0 |
| Rpl_semi_sync_master_wait_sessions | 0 |
| Rpl_semi_sync_master_yes_tx | 0 |
| Rpl_semi_sync_slave_status | ON |
+--------------------------------------------+-------+
15 rows in set (0.00 sec)

**3.4.**测试

在 master 端写入数据

[root@mysql-node ~]# mysql -p123
mysql> insert into haha.userlist values ('xixi3',122);
Query OK, 1 row affected (0.01 sec)
mysql> SHOW STATUS LIKE 'Rpl_semi_sync%';
+--------------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients | 2 |
| Rpl_semi_sync_master_net_avg_wait_time | 0 |
| Rpl_semi_sync_master_net_wait_time | 0 |
| Rpl_semi_sync_master_net_waits | 2 |
| Rpl_semi_sync_master_no_times | 0 |
| Rpl_semi_sync_master_no_tx | 0 | # 未同步数据 0 笔
| Rpl_semi_sync_master_status | ON |
| Rpl_semi_sync_master_timefunc_failures | 0 |
| Rpl_semi_sync_master_tx_avg_wait_time | 784 |
| Rpl_semi_sync_master_tx_wait_time | 784 |
| Rpl_semi_sync_master_tx_waits | 1 |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0 |
| Rpl_semi_sync_master_wait_sessions | 0 |
| Rpl_semi_sync_master_yes_tx | 1 | # 已同步数据 1 笔
+--------------------------------------------+-------+
14 rows in set (0.00 sec)
模拟故障:

在 slave 端

[root@mysql ~]# mysql -p123
mysql> STOP SLAVE IO_THREAD;
Query OK, 0 rows affected (0.00 sec)

[root@mysql-node3 ~]# mysql -p123
mysql> STOP SLAVE IO_THREAD;
Query OK, 0 rows affected (0.00 sec)

在 master 端插入数据

mysql> insert into haha.userlist values ('xixi4',121);
Query OK, 1 row affected (10.01 sec) #10 秒超时
mysql> SHOW STATUS LIKE 'Rpl_semi%';
+--------------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients | 0 |
| Rpl_semi_sync_master_net_avg_wait_time | 0 |
| Rpl_semi_sync_master_net_wait_time | 0 |
| Rpl_semi_sync_master_net_waits | 2 |
| Rpl_semi_sync_master_no_times | 1 |
| Rpl_semi_sync_master_no_tx | 1 | # 一笔数据为同步
| Rpl_semi_sync_master_status | OFF | # 自动转为异步模式,当
slave 恢复
| Rpl_semi_sync_master_timefunc_failures | 0 | # 会自动恢复
| Rpl_semi_sync_master_tx_avg_wait_time | 784 |
| Rpl_semi_sync_master_tx_wait_time | 784 |
| Rpl_semi_sync_master_tx_waits | 1 |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0 |
| Rpl_semi_sync_master_wait_sessions | 0 |
| Rpl_semi_sync_master_yes_tx | 1 |
+--------------------------------------------+-------+
14 rows in set (0.00 sec)

mysql高可用之组复制**(MGR)**

MySQL Group Replication( 简称 MGR ) 是 MySQL 官方于 2016 年 12 月推出的一个全新的高可用与高扩展的解决方案
组复制是 MySQL 5.7.17 版本出现的新特性,它提供了高可用、高扩展、高可靠的 MySQL 集群服务
MySQL 组复制分单主模式和多主模式,传统的 mysql 复制技术仅解决了数据同步的问题,
MGR 对属于同一组的服务器自动进行协调。对于要提交的事务,组成员必须就全局事务序列中给定事务的顺序达成一致
提交或回滚事务由每个服务器单独完成,但所有服务器都必须做出相同的决定
如果存在网络分区,导致成员无法达成事先定义的分割策略,则在解决此问题之前系统不会继续进行,
这是一种内置的自动裂脑保护机制
MGR 由组通信系统 ( Group Communication System , GCS ) 协议支持
该系统提供故障检测机制、组成员服务以及安全且有序的消息传递

4.1****组复制流程

首先我们将多个节点共同组成一个复制组,在执行读写( RW )事务的时候,需要通过一致性协议层(Consensus 层)的同意,也就是读写事务想要进行提交,必须要经过组里 " 大多数人 " (对应 Node 节点)的同意,大多数指的是同意的节点数量需要大于 (N/2+1 ),这样才可以进行提交,而不是原发起方一个说了算。而针对只读(RO )事务则不需要经过组内同意,直接提交即可

注意:节点数量不能超过9台

4.2****组复制单主和多主模式

single-primary mode(单写或单主模式)

单写模式 group 内只有一台节点可写可读,其他节点只可以读。当主服务器失败时,会自动选择新的主服务器,

multi-primary mode(多写或多主模式)

组内的所有机器都是 primary 节点,同时可以进行读写操作,并且数据是最终一致的。

4.3.实现mysql****组复制

注意:应该全部都是ONLINE,应为我一开始没有在每个虚拟机上手动做地址解析

[root@mysql-node * 2 * 3~]# cat /etc/hosts

127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4

::1 localhost localhost.localdomain localhost6 localhost6.localdomain6

192.168.10.130 mysql-node.com

192.168.10.140 mysql-node2.com

192.168.10.150 mysql-node3.com
为了避免出错,在所有节点中从新生成数据库数据

编辑主配置文件:

#在mysql-node中

[root@mysql-node ~]# rm -rf /data/mysql/

[root@mysql-node ~]# vim /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
symbolic-links=0
server-id=1 # 配置 server 唯一标识号
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY" # 禁用指定存储
引擎
gtid_mode=ON # 启用全局事件标识
enforce_gtid_consistency=ON # 强制 gtid 一致
master_info_repository=TABLE # 复制事件数据到表中而不记录在数据目录中
relay_log_info_repository=TABLE
binlog_checksum=NONE # 禁止对二进制日志校验
log_slave_updates=ON # 打开数据库中继,

当 slave 中 sql 线程读取日志后也会写入到自己的 binlog 中

log_bin=binlog # 重新指定 log 名称
binlog_format=ROW # 使用行日志格式
plugin_load_add='group_replication.so' # 加载组复制插件
transaction_write_set_extraction=XXHASH64 # 把每个事件编码为加密散列
group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" # 通知插件正
式加入

或创建的组

名称为

uuid 格式
group_replication_start_on_boot=off # 在 server 启动时不自动启动组复

group_replication_local_address="192.168.10.130:33061" # 指定插件接受其他成员的信息端

group_replication_group_seeds="192.168.10.130:33061,192.168.10.140:33061,
192.168.10.150:33061" #本地地址允许访
问成员列表
group_replication_ip_whitelist="192.168.10.0/24,127.0.0.1/8" # 主机白名单

不随系统自启而启动,只在初始成员主机中手动开启,

需要在两种情况下做设定: 1. 初始化建组时 2. 关闭并重新启动整个组时

group_replication_bootstrap_group=off
group_replication_single_primary_mode=OFF # 使用多主模式
group_replication_enforce_update_everywhere_checks=ON # 组同步中有任何改变
检测更新
group_replication_allow_local_disjoint_gtids_join=1 # 放弃自己信息以
master 事件为主
[root@mysql-node ~]# mysqld --user=mysql --initialize #这个最后一行会生成一个密码
2024-08-26T09:09:31.862768Z 1 [Note] A temporary password is generated for root@localhost: 2JL>irHt6_eC
[root@mysql-node ~]# /etc/init.d/mysqld start
[root@mysql-node ~]# mysql -uroot -p
Enter password:
mysql> alter user root@localhost identified by '123';
Query OK, 0 rows affected (0.01 sec)

配置 sql

[root@mysql-node ~]# mysql -uroot -p123
mysql> SET SQL_LOG_BIN=0;

Query OK, 0 rows affected (0.00 sec)

mysql> CREATE USER rpl_user@'%' IDENTIFIED BY 'lee';

Query OK, 0 rows affected (0.00 sec)

mysql> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%';

Query OK, 0 rows affected (0.00 sec)

mysql> FLUSH PRIVILEGES;

Query OK, 0 rows affected (0.00 sec)

mysql> SET SQL_LOG_BIN=1;

Query OK, 0 rows affected (0.00 sec)

mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='lee' FOR CHANNEL

-> 'group_replication_recovery';

Query OK, 0 rows affected, 2 warnings (0.01 sec)

mysql> SET GLOBAL group_replication_bootstrap_group=ON; #用以指定初始成员,值在第一台主机中执行

Query OK, 0 rows affected (0.00 sec)

mysql> START GROUP_REPLICATION;

Query OK, 0 rows affected, 1 warning (2.03 sec)

mysql> SET GLOBAL group_replication_bootstrap_group=OFF;

Query OK, 0 rows affected (0.00 sec)

mysql> SELECT * FROM performance_schema.replication_group_members;

#在复制配置文件到myql-node2和mysql-node3

[root@mysql-node ~]# scp /etc/my.cnf root@192.168.10.140:/etc/my.cnf

The authenticity of host '192.168.10.140 (192.168.10.140)' can't be established.

ECDSA key fingerprint is SHA256:5flpLOEGakncAmIC/h6XbCsbiqcbt2ejCE7y4dIrCIs.

ECDSA key fingerprint is MD5:30:cf:04:80:d3:6d:48:1c:a8:58:5d:19:f5:45:7a:cc.

Are you sure you want to continue connecting (yes/no)? yes

Warning: Permanently added '192.168.10.140' (ECDSA) to the list of known hosts.

root@192.168.10.140's password:

my.cnf 100% 916 753.3KB/s 00:00

[root@mysql-node ~]# scp /etc/my.cnf root@192.168.10.150:/etc/my.cnf

root@192.168.10.150's password:

my.cnf 100% 916 671.7KB/s 00:00

修改 mysql---node2 和 mysl-node3 中的配置

[root@mysql ~]# rm -rf /data/mysql/
[root@mysql ~]# vim /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
symbolic-links=0
server-id=2 # 在 3 上写 3
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_slave_updates=ON
log_bin=binlog
binlog_format=ROW
plugin_load_add='group_replication.so'
transaction_write_set_extraction=XXHASH64
group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
group_replication_start_on_boot=off
group_replication_local_address="192.168.10.140:33061" # 在 3 上要写150
group_replication_group_seeds="192.168.10.130:33061,192.168.10.140:33061,192.168.10.150:33061"
group_replication_ip_whitelist="192.168.10.0/24,127.0.0.1/8"
group_replication_bootstrap_group=off
group_replication_single_primary_mode=OFF
group_replication_enforce_update_everywhere_checks=ON
group_replication_allow_local_disjoint_gtids_join=1
[root@mysql ~]# mysqld --user=mysql --initialize
2024-08-26T09:36:43.356205Z 1 [Note] A temporary password is generated for root@localhost: MwW_s47fgJU:
[root@mysql ~]# /etc/init.d/mysqld start

配置 sql

[root@mysql ~]# mysql -pMwW_s47fgJU:
mysql> alter user root@localhost identified by '123';
Query OK, 0 rows affected (0.01 sec)

注意:这里必须全部都是ONLINE才可以进行下面测试

测试:
在每个节点都可以完成读写

[root@mysql-node ~]# mysql -p123

mysql> create database haha;

Query OK, 0 rows affected (0.01 sec)

mysql> create table haha.userlist(

-> username varchar(20) not null,

-> password varchar(50) not null

-> );

Query OK, 0 rows affected (0.01 sec)

mysql> insert into haha.userlist value ('xixi','1112');

Query OK, 1 row affected (0.01 sec)

mysql> select * from haha.userlist;

+----------+----------+

| username | password |

+----------+----------+

| xixi | 1112 |

+----------+----------+

1 row in set (0.00 sec)

在 mysql-node2 中

[root@mysql ~]# mysql -p123 -e "insert into haha.userlist values('xixi2',1234);"

[root@mysql ~]# mysql -p123 -e "select * from haha.userlist;"

| username | password |

+----------+----------+

| xixi | 1112 |

| xixi2 | 1234 |

+----------+----------+
2 rows in set (0.00 sec)
#mysql---node3 中
[root@mysql-node3 ~]# mysql -p123 -e "insert into haha.userlist values('xixi3',1222);"

[root@mysql-node3 ~]# mysql -p123 -e "select * from haha.userlist;"

| username | password |

+----------+----------+

| xixi | 1112 |

| xixi2 | 1234 |

| xixi3 | 1222 |

+----------+----------+
3 rows in set (0.00 sec)

mysql-routermysql路由)

MySQL Router

是一个对应用程序透明的 InnoDB Cluster 连接路由服务,提供负载均衡、应用连接故障转移和客户端路由。
利用路由器的连接路由特性,用户可以编写应用程序来连接到路由器,并令路由器使用相应的路由策略来处理连接,使其连接到正确的MySQL 数据库服务器

Mysql route****的部署方式
我们需要在所有的数据库主机之外再开一台主机 mysql-router

安装 mysql-router

[root@mysql-node ~]# cd rhel7/
[root@mysql-node rhel7]# rpm -ivh mysql-router-community-8.4.0-1.el7.x86_64.rpm

配置 mysql-router

[root@mysql-node rhel7]# vim /etc/mysqlrouter/mysqlrouter.conf

[routing:ro]

bind_address = 0.0.0.0

bind_port = 7001destinations = 192.168.10.130:3306,192.168.10.140:3306,192.168.10.150:3306

routing_strategy = round-robin

[routing:rw]

bind_address = 0.0.0.0

bind_port = 7002

destinations = 192.168.10.150:3306,192.168.10.140:3306,192.168.10.130:3306

routing_strategy = first-available

[root@mysql-node rhel7]# systemctl start mysqlrouter.service

[root@mysql-node rhel7]#

测试:

建立测试用户

mysql> CREATE USER lee@'%' IDENTIFIED BY 'lee';
Query OK, 0 rows affected (0.00 sec)

mysql> GRANT ALL ON lee.* TO lee@'%';
Query OK, 0 rows affected (0.00 sec)
#查看调度效果

[root@mysql-node rhel7]# watch lsof -i :3306

[root@mysql ~]# mysql -ulee -plee -h 192.168.10.130 -P 7001

mysql: [Warning] Using a password on the command line interface can be insecure.

Welcome to the MySQL monitor. Commands end with ; or \g.

Your MySQL connection id is 66

Server version: 5.7.44-log Source distribution

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

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>

注意:mysql router 并不能限制数据库的读写,访问分流

mysql高可用之****MHA

6.1.MHA****概述

为什么要用MHA

Master 的单点故障问题

什么是MHA

  • MHA(Master High Availability)是一套优秀的MySQL高可用环境下故障切换和主从复制的软件。
  • MHA 的出现就是解决MySQL 单点的问题。
  • MySQL故障切换过程中,MHA能做到0-30秒内自动完成故障切换操作。
  • MHA能在故障切换的过程中最大程度上保证数据的一致性,以达到真正意义上的高可用。

MHA****的组成

  • MHA由两部分组成:MHAManager (管理节点) MHA Node (数据库节点),
  • MHA Manager 可以单独部署在一台独立的机器上管理多个master-slave集群,也可以部署在一台slave 节点上。
  • MHA Manager 会定时探测集群中的 master 节点。
  • 当 master 出现故障时,它可以自动将最新数据的 slave 提升为新的 master, 然后将所有其他的slave 重新指向新的 master。

MHA****的特点

  • 自动故障切换过程中,MHA从宕机的主服务器上保存二进制日志,最大程度的保证数据不丢失
  • 使用半同步复制,可以大大降低数据丢失的风险,如果只有一个slave已经收到了最新的二进制日志,MHA可以将最新的二进制日志应用于其他所有的slave服务器上,因此可以保证所有节点的数据一致性
  • 目前MHA支持一主多从架构,最少三台服务,即一主两从

故障切换备选主库的算法

1 .一般判断从库的是从( position/GTID )判断优劣,数据有差异,最接近于 master 的 slave ,成为备选主。
2 .数据一致的情况下,按照配置文件顺序,选择备选主库。
3 .设定有权重( candidate_master=1 ),按照权重强制指定备选主。
( 1 )默认情况下如果一个 slave 落后 master 100M 的 relay logs 的话,即使有权重,也会失效。
( 2 )如果 check_repl_delay=0 的话,即使落后很多日志,也强制选择其为备选主。

MHA****工作原理

  • 目前MHA主要支持一主多从的架构,要搭建MHA,要求一个复制集群必须最少有3台数据库服务器,一主二从,即一台充当Master,台充当备用Master,另一台充当从库。
  • MHA Node 运行在每台 MySQL 服务器上
  • MHAManager 会定时探测集群中的master 节点
  • 当master 出现故障时,它可以自动将最新数据的slave 提升为新的master
  • 然后将所有其他的slave 重新指向新的master,VIP自动漂移到新的master。
  • 整个故障转移过程对应用程序完全透明。

6.2 MHA****部署实施

6.2.1****搭建主两从架构

[root@mysql-node ~]# /etc/init.d/mysqld stop

[root@mysql-node ~]# rm -rf /data/mysql/*

[root@mysql-node data]# vim /etc/my.cnf

[mysqld]

datadir=/data/mysql

socket=/data/mysql/mysql.sock

symbolic-links=0

log-bin=mysql-bin

gtid_mode=ON

log_slave_updates=ON

enforce-gtid-consistency=ON

server-id=1

[root@mysql-node ~]# mysqld --user mysql --initialize

2024-08-26T10:47:39.383052Z 1 [Note] A temporary password is generated for root@localhost: ej!d;usPq6ed

[root@mysql-node ~]# /etc/init.d/mysqld start

[root@mysql-node ~]# mysql_secure_installation

[root@mysql-node ~]# mysql -p123

mysql> CREATE USER 'repl'@'%' IDENTIFIED BY 'lee';

Query OK, 0 rows affected (0.00 sec)

mysql> GRANT REPLICATION SLAVE ON *.* TO repl@'%';

Query OK, 0 rows affected (0.00 sec)

mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';

Query OK, 0 rows affected (0.00 sec)

mysql> SET GLOBAL rpl_semi_sync_master_enabled = 1;

Query OK, 0 rows affected (0.00 sec)
#在slave1和slave2中

[root@mysql & node3 ~]# /etc/init.d/mysqld stop

[root@mysql & node3 ~]# rm -rf /data/mysql/*

[root@mysql & node3 ~]# vim /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
symbolic-links=0
server-id=2 #这里node3改为server-id=3
log-bin=mysql-bin
gtid_mode=ON
log_slave_updates=ON
enforce-gtid-consistency=ON

[root@mysql & node3 ~]# mysqld --user mysql --initialize

2024-08-26T10:55:16.490062Z 1 [Note] A temporary password is generated for root@localhost: Ocneh;oq?8o+
[root@mysql & node3 ~]# /etc/init.d/mysqld start
[root@mysql & node3 ~]# mysql_secure_installation

[root@mysql & node3 ~]# mysql -p123

mysql> CHANGE MASTER TO MASTER_HOST='192.168.10.130', MASTER__USER='repl',MASTER_PASSWORD='lee', MASTER_AUTO_POSITION=1;

Query OK, 0 rows affected, 2 warnings (0.01 sec)

mysql> start slave;

Query OK, 0 rows affected (0.00 sec)

mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';

Query OK, 0 rows affected (0.00 sec)

mysql> SET GLOBAL rpl_semi_sync_slave_enabled =1;

Query OK, 0 rows affected (0.00 sec)

mysql> STOP SLAVE IO_THREAD;

Query OK, 0 rows affected (0.00 sec)

mysql> START SLAVE IO_THREAD;

Query OK, 0 rows affected (0.01 sec)

mysql> SHOW STATUS LIKE 'Rpl_semi_sync%';

+----------------------------+-------+

| Variable_name | Value |

+----------------------------+-------+

| Rpl_semi_sync_slave_status | ON |

+----------------------------+-------+

1 row in set (0.00 sec)

6.2.2安装MHA****所需要的软件

在 MHA 中

[root@mysql-node ~]# cd rhel7/
[root@mysql-node rhel7]# unzip MHA-7
[root@mysql-node rhel7]# cd MHA-7/
[root@mysql-node MHA-7]# ls
mha4mysql-manager-0.58-0.el7.centos.noarch.rpm
mha4mysql-manager-0.58.tar.gz
mha4mysql-node-0.58-0.el7.centos.noarch.rpm
perl-Config-Tiny-2.14-7.el7.noarch.rpm
perl-Email-Date-Format-1.002-15.el7.noarch.rpm
perl-Log-Dispatch-2.41-1.el7.1.noarch.rpm
perl-Mail-Sender-0.8.23-1.el7.noarch.rpm
perl-Mail-Sendmail-0.79-21.el7.noarch.rpm
perl-MIME-Lite-3.030-1.el7.noarch.rpm
perl-MIME-Types-1.38-2.el7.noarch.rpm
perl-Net-Telnet-3.03-19.el7.noarch.rpm
perl-Parallel-ForkManager-1.18-2.el7.noarch.rpm
[root@mysql-node MHA-7]# yum install *.rpm -y

[root@mysql-node MHA-7]# scp mha4mysql-node-0.58-0.el7.centos.noarch.rpm root@192.168.10.140:/mnt
root@192.168.10.140's password:
mha4mysql-node-0.58-0.el7 100% 35KB 19.4MB/s 00:00
[root@mysql-node MHA-7]# scp mha4mysql-node-0.58-0.el7.centos.noarch.rpm root@192.168.10.150:/mnt
root@192.168.10.150's password:
mha4mysql-node-0.58-0.el7 100% 35KB 11.7MB/s 00:00

在 sql-node 中

[root@mysql ~]# yum install /mnt/mha4mysql-node-0.58-0.el7.centos.noarch.rpm -y
[root@mysql-node3 ~]# yum install /mnt/mha4mysql-node-0.58-0.el7.centos.noarch.rpm -y

在软件中包含的工具包介绍
1.Manager 工具包主要包括以下几个工具:

  • masterha_check_ssh #检查MHA的SSH配置状况

  • masterha_check_repl #检查MySQL复制状况

  • masterha_manger #启动MHA

  • masterha_check_status #检测当前MHA运行状态

  • masterha_master_monitor #检测master是否宕机

  • masterha_master_switch #控制故障转移(自动或者手动)

  • masterha_conf_host #添加或删除配置的server信息
    2.Node 工具包 (通常由masterHA 主机直接调用,无需人为执行)

  • save_binary_logs #保存和复制master的二进制日志

  • apply_diff_relay_logs #识别差异的中继日志事件并将其差异的事件应用于其他的slave

  • filter_mysqlbinlog #去除不必要的ROLLBACK事件(MHA已不再使用这个工具)

  • purge_relay_logs #清除中继日志(不会阻塞SQL线程)

6.2.3配置MHA****的管理环境

  1. 生成配置目录和配置文件

[root@mysql-node MHA-7]# masterha_manager --help
Usage:
masterha_manager --global_conf=/etc/masterha_default.cnf #全局配置文件,记录
公共设定
--conf=/usr/local/masterha/conf/app1.cnf # 不同管理配置文件,记录各自配 置

See online reference
(http://code.google.com/p/mysql-master-ha/wiki/masterha_manager) for
details.
因为我们当前只有一套主从,所以我们只需要写一个配置文件即可
rpm 包中没有为我们准备配置文件的模板
可以解压源码包后在 samples 中找到配置文件的模板文件

生成配置文件

[root@mysql-node MHA-7]# mkdir /etc/masterha
[root@mysql-node MHA-7]# tar zxf mha4mysql-manager-0.58.tar.gz
[root@mysql-node MHA-7]# cd mha4mysql-manager-0.58/samples/conf/
[root@mysql-node conf]# cat masterha_default.cnf app1.cnf > /etc/masterha/app1.cnf

编辑配置文件

[root@mysql-node ~]# vim /etc/masterha/app1.cnf
[server default]
user=root #mysql管理员用户,因为需要做自动化配置
password=lee #mysql密码
ssh_user=root #ssh远程登陆用户
repl_user=repl #mysql主从复制中负责认证的用户
repl_password=lee #mysql主从复制中负责认证的用户密码
master_binlog_dir= /data/mysql #二进制日志目录
remote_workdir=/tmp #远程工作目录

#此参数使为了提供冗余检测,方式是mha主机网络自身的问题无法连接数据库节点,应为集群之外的主机
secondary_check_script= masterha_secondary_check -s 127.25.254.10 -s 127.25.254.11
ping_interval=3 #每隔3秒检测一次

#发生故障后调用的脚本,用来迁移vip

master_ip_failover_script= /script/masterha/master_ip_failover

#电源管理脚本

shutdown_script= /script/masterha/power_manager

#当发生故障后用此脚本发邮件或者告警通知

report_script= /script/masterha/send_report

#在线切换时调用的vip迁移脚本,手动

master_ip_online_change_script= /script/masterha/master_ip_online_change

[server default]
manager_workdir=/etc/masterha #mha工作目录
manager_log=/var/etc/masterha/manager.log #mha日志

[server1]
hostname=127.25.254.10
candidate_master=1 #可能作为master的主机
check_repl_delay=0 ##默认情况下如果一个slave落后master 100M的relay logs的话
#MHA将不会选择该slave作为一个新的master
#因为对于这个slave的恢复需要花费很长时间
#通过设置check_repl_delay=0
#MHA触发切换在选择一个新的master的时候将会忽略复制延时
#这个参数对于设置了candidate_master=1的主机非常有用
#因为这个候选主在切换的过程中一定是新的master

[server2]
hostname=127.25.254.20
candidate_master=1
check_repl_delay=0 #可能作为master的主机

[server3]
hostname=127.25.254.30
no_master=1 #不会作为master的主机
2. 检测配置:
a )检测网络及 ssh 免密
[root@mysql-node ~]# masterha_check_ssh --conf=/etc/masterha/app1.cnf
Fri Aug 2 16:57:41 2024 - [warning] Global configuration file
/etc/masterha_default.cnf not found. Skipping.
Fri Aug 2 16:57:41 2024 - [info] Reading application default configuration from
/etc/masterha/app1.cnf..
Fri Aug 2 16:57:41 2024 - [info] Reading server configuration from
/etc/masterha/app1.cnf..
Fri Aug 2 16:57:41 2024 - [info] Starting SSH connection tests..
Fri Aug 2 16:57:42 2024 - [debug]
Fri Aug 2 16:57:41 2024 - [debug] Connecting via SSH from
root@172.25.254.10(172.25.254.10:22) to root@172.25.254.20(172.25.254.20:22)..
Fri Aug 2 16:57:41 2024 - [debug] ok.
Fri Aug 2 16:57:41 2024 - [debug] Connecting via SSH from
root@172.25.254.10(172.25.254.10:22) to root@172.25.254.30(172.25.254.30:22)..
Fri Aug 2 16:57:41 2024 - [debug] ok.
Fri Aug 2 16:57:42 2024 - [debug]
Fri Aug 2 16:57:41 2024 - [debug] Connecting via SSH from
root@172.25.254.20(172.25.254.20:22) to root@172.25.254.10(172.25.254.10:22)..
Warning: Permanently added '172.25.254.10' (ECDSA) to the list of known hosts.
Fri Aug 2 16:57:42 2024 - [debug] ok.
Fri Aug 2 16:57:42 2024 - [debug] Connecting via SSH from
root@172.25.254.20(172.25.254.20:22) to root@172.25.254.30(172.25.254.30:22)..
Warning: Permanently added '172.25.254.30' (ECDSA) to the list of known hosts.
Fri Aug 2 16:57:42 2024 - [debug] ok.
Fri Aug 2 16:57:43 2024 - [debug]
Fri Aug 2 16:57:42 2024 - [debug] Connecting via SSH from
root@172.25.254.30(172.25.254.30:22) to root@172.25.254.10(172.25.254.10:22)..
Warning: Permanently added '172.25.254.10' (ECDSA) to the list of known hosts.
Fri Aug 2 16:57:42 2024 - [debug] ok.
Fri Aug 2 16:57:42 2024 - [debug] Connecting via SSH from
root@172.25.254.30(172.25.254.30:22) to root@172.25.254.20(172.25.254.20:22)..
Warning: Permanently added '172.25.254.20' (ECDSA) to the list of known hosts.
Fri Aug 2 16:57:42 2024 - [debug] ok.
Fri Aug 2 16:57:43 2024 - [info] All SSH connection tests passed successfully.
b )检测数据主从复制情况

在数据节点 master 端

mysql> GRANT ALL ON *.* TO root@'%' identified by 'lee'; # 允许 root 远程登陆

执行检测

[root@mysql-node ~ ]# masterha_check_repl --conf=/etc/masterha/app1.cnf
Fri Aug 2 17:04:20 2024 - [warning] Global configuration file
/etc/masterha_default.cnf not found. Skipping.
Fri Aug 2 17:04:20 2024 - [info] Reading application default configuration from
/etc/masterha/app1.cnf..
Fri Aug 2 17:04:20 2024 - [info] Reading server configuration from
/etc/masterha/app1.cnf..
Fri Aug 2 17:04:20 2024 - [info] MHA::MasterMonitor version 0.58.
Fri Aug 2 17:04:21 2024 - [info] GTID failover mode = 1
Fri Aug 2 17:04:21 2024 - [info] Dead Servers:
Fri Aug 2 17:04:21 2024 - [info] Alive Servers:
Fri Aug 2 17:04:21 2024 - [info] 172.25.254.10(172.25.254.10:3306)
Fri Aug 2 17:04:21 2024 - [info] 172.25.254.20(172.25.254.20:3306)
Fri Aug 2 17:04:21 2024 - [info] 172.25.254.30(172.25.254.30:3306)
Fri Aug 2 17:04:21 2024 - [info] Alive Slaves:
Fri Aug 2 17:04:21 2024 - [info] 172.25.254.20(172.25.254.20:3306)
Version=5.7.44-log (oldest major version between slaves) log-bin:enabled
Fri Aug 2 17:04:21 2024 - [info] GTID ON
Fri Aug 2 17:04:21 2024 - [info] Replicating from
172.25.254.10(172.25.254.10:3306)
Fri Aug 2 17:04:21 2024 - [info] Primary candidate for the new Master
(candidate_master is set)
Fri Aug 2 17:04:21 2024 - [info] 172.25.254.30(172.25.254.30:3306)
Version=5.7.44-log (oldest major version between slaves) log-bin:enabled
Fri Aug 2 17:04:21 2024 - [info] GTID ON
Fri Aug 2 17:04:21 2024 - [info] Replicating from
172.25.254.10(172.25.254.10:3306)
Fri Aug 2 17:04:21 2024 - [info] Not candidate for the new Master (no_master
is set)
Fri Aug 2 17:04:21 2024 - [info] Current Alive Master:
172.25.254.10(172.25.254.10:3306)
Fri Aug 2 17:04:21 2024 - [info] Checking slave configurations..
Fri Aug 2 17:04:21 2024 - [info] read_only=1 is not set on slave
172.25.254.20(172.25.254.20:3306).
Fri Aug 2 17:04:21 2024 - [info] read_only=1 is not set on slave
172.25.254.30(172.25.254.30:3306).
Fri Aug 2 17:04:21 2024 - [info] Checking replication filtering settings..
Fri Aug 2 17:04:21 2024 - [info] binlog_do_db= , binlog_ignore_db=
Fri Aug 2 17:04:21 2024 - [info] Replication filtering check ok.
Fri Aug 2 17:04:21 2024 - [info] GTID (with auto-pos) is supported. Skipping all
SSH and Node package checking.
Fri Aug 2 17:04:21 2024 - [info] Checking SSH publickey authentication settings
on the current master..
Fri Aug 2 17:04:21 2024 - [info] HealthCheck: SSH to 172.25.254.10 is reachable.
Fri Aug 2 17:04:21 2024 - [info]
172.25.254.10(172.25.254.10:3306) (current master)
+--172.25.254.20(172.25.254.20:3306)
+--172.25.254.30(172.25.254.30:3306)
Fri Aug 2 17:04:21 2024 - [info] Checking replication health on 172.25.254.20..
Fri Aug 2 17:04:21 2024 - [info] ok.
Fri Aug 2 17:04:21 2024 - [info] Checking replication health on 172.25.254.30..
Fri Aug 2 17:04:21 2024 - [info] ok.
Fri Aug 2 17:04:21 2024 - [warning] master_ip_failover_script is not defined.
Fri Aug 2 17:04:21 2024 - [warning] shutdown_script is not defined.
Fri Aug 2 17:04:21 2024 - [info] Got exit code 0 (Not master dead).
MySQL Replication Health is OK.

6.2.4 MHA****的故障切换

MHA 的故障切换过程
共包括以下的步骤:

  1. 配置文件检查阶段,这个阶段会检查整个集群配置文件配置
  2. 宕机的 master 处理,这个阶段包括虚拟 ip 摘除操作,主机关机操作
  3. 复制 dead master 和最新 slave 相差的 relay log ,并保存到 MHA Manger 具体的目录下
  4. 识别含有最新更新的 slave
  5. 应用从 master 保存的二进制日志事件( binlog events )
  6. 提升一个 slave 为新的 master 进行复制
  7. 使其他的 slave 连接新的 master 进行复制
    切换方式:
    master 未出现故障手动切换

在 master 数据节点还在正常工作情况下

[root@mysql-node ~ ]# masterha_master_switch \
--conf=/etc/masterha/app1.cnf \ #指定配置文件
--master_state=alive \ #指定 master 节点状态
--new_master_host=172.25.254.20 \ #指定新 master 节点
--new_master_port=3306 \ #执行新 master 节点端口
--orig_master_is_new_slave \ #原始 master 会变成新的 slave
--running_updates_limit=10000 #切换的超时时间

切换过程如下:

[root@mysql-node masterha]# masterha_master_switch --conf=/etc/masterha/app1.cnf -
-master_state=alive --new_master_host=172.25.254.20 --new_master_port=3306 --
orig_master_is_new_slave --running_updates_limit=10000
Fri Aug 2 18:30:38 2024 - [info] MHA::MasterRotate version 0.58.
Fri Aug 2 18:30:38 2024 - [info] Starting online master switch..
Fri Aug 2 18:30:38 2024 - [info]
Fri Aug 2 18:30:38 2024 - [info] * Phase 1: Configuration Check Phase..
Fri Aug 2 18:30:38 2024 - [info]
Fri Aug 2 18:30:38 2024 - [warning] Global configuration file
/etc/masterha_default.cnf not found. Skipping.
Fri Aug 2 18:30:38 2024 - [info] Reading application default configuration from
/etc/masterha/app1.cnf..
Fri Aug 2 18:30:38 2024 - [info] Reading server configuration from
/etc/masterha/app1.cnf..
Fri Aug 2 18:30:39 2024 - [info] GTID failover mode = 1
Fri Aug 2 18:30:39 2024 - [info] Current Alive Master:
172.25.254.10(172.25.254.10:3306)
Fri Aug 2 18:30:39 2024 - [info] Alive Slaves:
Fri Aug 2 18:30:39 2024 - [info] 172.25.254.20(172.25.254.20:3306)
Version=5.7.44-log (oldest major version between slaves) log-bin:enabled
Fri Aug 2 18:30:39 2024 - [info] GTID ON
Fri Aug 2 18:30:39 2024 - [info] Replicating from
172.25.254.10(172.25.254.10:3306)
Fri Aug 2 18:30:39 2024 - [info] Primary candidate for the new Master
(candidate_master is set)
Fri Aug 2 18:30:39 2024 - [info] 172.25.254.30(172.25.254.30:3306)
Version=5.7.44-log (oldest major version between slaves) log-bin:enabled
Fri Aug 2 18:30:39 2024 - [info] GTID ON
Fri Aug 2 18:30:39 2024 - [info] Replicating from
172.25.254.10(172.25.254.10:3306)
Fri Aug 2 18:30:39 2024 - [info] Not candidate for the new Master (no_master
is set)
It is better to execute FLUSH NO_WRITE_TO_BINLOG TABLES on the master before
switching. Is it ok to execute on 172.25.254.10(172.25.254.10:3306)? (YES/no):
yes 《《《《
Fri Aug 2 18:30:40 2024 - [info] Executing FLUSH NO_WRITE_TO_BINLOG TABLES. This
may take long time..
Fri Aug 2 18:30:40 2024 - [info] ok.
Fri Aug 2 18:30:40 2024 - [info] Checking MHA is not monitoring or doing
failover..
Fri Aug 2 18:30:40 2024 - [info] Checking replication health on 172.25.254.20..
Fri Aug 2 18:30:40 2024 - [info] ok.
Fri Aug 2 18:30:40 2024 - [info] Checking replication health on 172.25.254.30..
Fri Aug 2 18:30:40 2024 - [info] ok.
Fri Aug 2 18:30:40 2024 - [info] 172.25.254.20 can be new master.
Fri Aug 2 18:30:40 2024 - [info]
From:
172.25.254.10(172.25.254.10:3306) (current master)
+--172.25.254.20(172.25.254.20:3306)
+--172.25.254.30(172.25.254.30:3306)
To:
172.25.254.20(172.25.254.20:3306) (new master)
+--172.25.254.30(172.25.254.30:3306)
+--172.25.254.10(172.25.254.10:3306)
Starting master switch from 172.25.254.10(172.25.254.10:3306) to
172.25.254.20(172.25.254.20:3306)? (yes/NO): yes
Fri Aug 2 18:30:42 2024 - [info] Checking whether
172.25.254.20(172.25.254.20:3306) is ok for the new master..
Fri Aug 2 18:30:42 2024 - [info] ok.
Fri Aug 2 18:30:42 2024 - [info] 172.25.254.10(172.25.254.10:3306): SHOW SLAVE
STATUS returned empty result. To check replication filtering rules, temporarily
executing CHANGE MASTER to a dummy host.
Fri Aug 2 18:30:42 2024 - [info] 172.25.254.10(172.25.254.10:3306): Resetting
slave pointing to the dummy host.
Fri Aug 2 18:30:42 2024 - [info] ** Phase 1: Configuration Check Phase
completed.
Fri Aug 2 18:30:42 2024 - [info]
Fri Aug 2 18:30:42 2024 - [info] * Phase 2: Rejecting updates Phase..
Fri Aug 2 18:30:42 2024 - [info]
master_ip_online_change_script is not defined. If you do not disable writes on
the current master manually, applications keep writing on the current master. Is
it ok to proceed? (yes/NO): yes
Fri Aug 2 18:30:43 2024 - [info] Locking all tables on the orig master to reject
updates from everybody (including root):
Fri Aug 2 18:30:43 2024 - [info] Executing FLUSH TABLES WITH READ LOCK..
Fri Aug 2 18:30:43 2024 - [info] ok.
Fri Aug 2 18:30:43 2024 - [info] Orig master binlog:pos is mysql
bin.000002:1275.
Fri Aug 2 18:30:43 2024 - [info] Waiting to execute all relay logs on
172.25.254.20(172.25.254.20:3306)..
Fri Aug 2 18:30:43 2024 - [info] master_pos_wait(mysql-bin.000002:1275)
completed on 172.25.254.20(172.25.254.20:3306). Executed 0 events.
Fri Aug 2 18:30:43 2024 - [info] done.
Fri Aug 2 18:30:43 2024 - [info] Getting new master's binlog name and position..
Fri Aug 2 18:30:43 2024 - [info] mysql-bin.000002:1519
Fri Aug 2 18:30:43 2024 - [info] All other slaves should start replication from
here. Statement should be: CHANGE MASTER TO MASTER_HOST='172.25.254.20',
MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl',
MASTER_PASSWORD='xxx';
Fri Aug 2 18:30:43 2024 - [info]
Fri Aug 2 18:30:43 2024 - [info] * Switching slaves in parallel..
Fri Aug 2 18:30:43 2024 - [info]
Fri Aug 2 18:30:43 2024 - [info] -- Slave switch on host
172.25.254.30(172.25.254.30:3306) started, pid: 41941
Fri Aug 2 18:30:43 2024 - [info]
Fri Aug 2 18:30:45 2024 - [info] Log messages from 172.25.254.30 ...
Fri Aug 2 18:30:45 2024 - [info]
Fri Aug 2 18:30:43 2024 - [info] Waiting to execute all relay logs on
172.25.254.30(172.25.254.30:3306)..
Fri Aug 2 18:30:43 2024 - [info] master_pos_wait(mysql-bin.000002:1275)
completed on 172.25.254.30(172.25.254.30:3306). Executed 0 events.
Fri Aug 2 18:30:43 2024 - [info] done.
Fri Aug 2 18:30:43 2024 - [info] Resetting slave
172.25.254.30(172.25.254.30:3306) and starting replication from the new master
172.25.254.20(172.25.254.20:3306)..
Fri Aug 2 18:30:43 2024 - [info] Executed CHANGE MASTER.
Fri Aug 2 18:30:44 2024 - [info] Slave started.
Fri Aug 2 18:30:45 2024 - [info] End of log messages from 172.25.254.30 ...
Fri Aug 2 18:30:45 2024 - [info]
Fri Aug 2 18:30:45 2024 - [info] -- Slave switch on host
172.25.254.30(172.25.254.30:3306) succeeded.
Fri Aug 2 18:30:45 2024 - [info] Unlocking all tables on the orig master:
Fri Aug 2 18:30:45 2024 - [info] Executing UNLOCK TABLES..
Fri Aug 2 18:30:45 2024 - [info] ok.
Fri Aug 2 18:30:45 2024 - [info] Starting orig master as a new slave..
Fri Aug 2 18:30:45 2024 - [info] Resetting slave
172.25.254.10(172.25.254.10:3306) and starting replication from the new master
172.25.254.20(172.25.254.20:3306)..
Fri Aug 2 18:30:45 2024 - [info] Executed CHANGE MASTER.
Fri Aug 2 18:30:46 2024 - [info] Slave started.
Fri Aug 2 18:30:46 2024 - [info] All new slave servers switched successfully.
Fri Aug 2 18:30:46 2024 - [info]
Fri Aug 2 18:30:46 2024 - [info] * Phase 5: New master cleanup phase..
Fri Aug 2 18:30:46 2024 - [info]
Fri Aug 2 18:30:46 2024 - [info] 172.25.254.20: Resetting slave info succeeded.
Fri Aug 2 18:30:46 2024 - [info] Switching master to
172.25.254.20(172.25.254.20:3306) completed successfully.
[root@mysql-node masterha]#
检测:
[root@mysql-node masterha]# masterha_check_repl --conf=/etc/masterha/app1.cnf
Fri Aug 2 18:33:46 2024 - [warning] Global
configuration file /etc/masterha_default.cnf not found. Skipping.
Fri Aug 2 18:33:46 2024 - [info] Reading application default configuration from
/etc/masterha/app1.cnf..
Fri Aug 2 18:33:46 2024 - [info] Reading server configuration from
/etc/masterha/app1.cnf..
Fri Aug 2 18:33:46 2024 - [info] MHA::MasterMonitor version 0.58.
Fri Aug 2 18:33:47 2024 - [info] GTID failover mode = 1
Fri Aug 2 18:33:47 2024 - [info] Dead Servers:
Fri Aug 2 18:33:47 2024 - [info] Alive Servers:
Fri Aug 2 18:33:47 2024 - [info] 172.25.254.10(172.25.254.10:3306)
Fri Aug 2 18:33:47 2024 - [info] 172.25.254.20(172.25.254.20:3306)
Fri Aug 2 18:33:47 2024 - [info] 172.25.254.30(172.25.254.30:3306)
Fri Aug 2 18:33:47 2024 - [info] Alive Slaves:
Fri Aug 2 18:33:47 2024 - [info] 172.25.254.10(172.25.254.10:3306)
Version=5.7.44-log (oldest major version between slaves) log-bin:enabled
Fri Aug 2 18:33:47 2024 - [info] GTID ON
Fri Aug 2 18:33:47 2024 - [info] Replicating from
172.25.254.20(172.25.254.20:3306)
Fri Aug 2 18:33:47 2024 - [info] Primary candidate for the new Master
(candidate_master is set)
Fri Aug 2 18:33:47 2024 - [info] 172.25.254.30(172.25.254.30:3306)
Version=5.7.44-log (oldest major version between slaves) log-bin:enabled
Fri Aug 2 18:33:47 2024 - [info] GTID ON
Fri Aug 2 18:33:47 2024 - [info] Replicating from
172.25.254.20(172.25.254.20:3306)
Fri Aug 2 18:33:47 2024 - [info] Not candidate for the new Master (no_master
is set)
Fri Aug 2 18:33:47 2024 - [info] Current Alive Master:
172.25.254.20(172.25.254.20:3306)
Fri Aug 2 18:33:47 2024 - [info] Checking slave configurations..
Fri Aug 2 18:33:47 2024 - [info] read_only=1 is not set on slave
172.25.254.30(172.25.254.30:3306).
Fri Aug 2 18:33:47 2024 - [info] Checking replication filtering settings..
Fri Aug 2 18:33:47 2024 - [info] binlog_do_db= , binlog_ignore_db=
Fri Aug 2 18:33:47 2024 - [info] Replication filtering check ok.
Fri Aug 2 18:33:47 2024 - [info] GTID (with auto-pos) is supported. Skipping all
SSH and Node package checking.
Fri Aug 2 18:33:47 2024 - [info] Checking SSH publickey authentication settings
on the current master..
Fri Aug 2 18:33:47 2024 - [info] HealthCheck: SSH to 172.25.254.20 is reachable.
Fri Aug 2 18:33:47 2024 - [info]
172.25.254.20(172.25.254.20:3306) (current master)
+--172.25.254.10(172.25.254.10:3306)
+--172.25.254.30(172.25.254.30:3306)
Fri Aug 2 18:33:47 2024 - [info] Checking replication health on 172.25.254.10..
Fri Aug 2 18:33:47 2024 - [info] ok.
Fri Aug 2 18:33:47 2024 - [info] Checking replication health on 172.25.254.30..
Fri Aug 2 18:33:47 2024 - [info] ok.
Fri Aug 2 18:33:47 2024 - [warning] master_ip_failover_script is not defined.
Fri Aug 2 18:33:47 2024 - [warning] shutdown_script is not defined.
Fri Aug 2 18:33:47 2024 - [info] Got exit code 0 (Not master dead).
MySQL Replication Health is OK.
master 故障手动切换

模拟 master 故障

[root@mysql-node20 mysql]# /etc/init.d/mysqld stop

在 MHA-master 中做故障切换

[root@mysql-mha masterha]# masterha_master_switch --master_state=dead --
conf=/etc/masterha/app1.cnf --dead_master_host=192.168.56.12 --
dead_master_port=3306 --new_master_host=192.168.56.11 --new_master_port=3306 --
ignore_last_failover
--ignore_last_failover 表示忽略在 /etc/masterha/ 目录中在切换过程中生成的锁文件
masterha_master_switch --master_state=dead --conf=/etc/masterha/app1.cnf --
dead_master_host=172.25.254.20 --dead_master_port=3306 --
new_master_host=172.25.254.10 --new_master_port=3306 --ignore_last_failover
--dead_master_ip=<dead_master_ip> is not set. Using 172.25.254.20.
Fri Aug 2 19:38:35 2024 - [warning] Global configuration file
/etc/masterha_default.cnf not found. Skipping.
Fri Aug 2 19:38:35 2024 - [info] Reading application default configuration from
/etc/masterha/app1.cnf..
Fri Aug 2 19:38:35 2024 - [info] Reading server configuration from
/etc/masterha/app1.cnf..
Fri Aug 2 19:38:35 2024 - [info] MHA::MasterFailover version 0.58.
Fri Aug 2 19:38:35 2024 - [info] Starting master failover.
Fri Aug 2 19:38:35 2024 - [info]
Fri Aug 2 19:38:35 2024 - [info] * Phase 1: Configuration Check Phase..
Fri Aug 2 19:38:35 2024 - [info]
Fri Aug 2 19:38:36 2024 - [info] GTID failover mode = 1
Fri Aug 2 19:38:36 2024 - [info] Dead Servers:
Fri Aug 2 19:38:36 2024 - [info] 172.25.254.20(172.25.254.20:3306)
Fri Aug 2 19:38:36 2024 - [info] Checking master reachability via MySQL(double
check)...
Fri Aug 2 19:38:36 2024 - [info] ok.
Fri Aug 2 19:38:36 2024 - [info] Alive Servers:
Fri Aug 2 19:38:36 2024 - [info] 172.25.254.10(172.25.254.10:3306)
Fri Aug 2 19:38:36 2024 - [info] 172.25.254.30(172.25.254.30:3306)
Fri Aug 2 19:38:36 2024 - [info] Alive Slaves:
Fri Aug 2 19:38:36 2024 - [info] 172.25.254.10(172.25.254.10:3306)
Version=5.7.44-log (oldest major version between slaves) log-bin:enabled
Fri Aug 2 19:38:36 2024 - [info] GTID ON
Fri Aug 2 19:38:36 2024 - [info] Replicating from
172.25.254.20(172.25.254.20:3306)
Fri Aug 2 19:38:36 2024 - [info] Primary candidate for the new Master
(candidate_master is set)
Fri Aug 2 19:38:36 2024 - [info] 172.25.254.30(172.25.254.30:3306)
Version=5.7.44-log (oldest major version between slaves) log-bin:enabled
Fri Aug 2 19:38:36 2024 - [info] GTID ON
Fri Aug 2 19:38:36 2024 - [info] Replicating from
172.25.254.20(172.25.254.20:3306)
Fri Aug 2 19:38:36 2024 - [info] Not candidate for the new Master (no_master
is set)
Master 172.25.254.20(172.25.254.20:3306) is dead. Proceed? (yes/NO): yes
Fri Aug 2 19:38:39 2024 - [info] Starting GTID based failover.
Fri Aug 2 19:38:39 2024 - [info]
Fri Aug 2 19:38:39 2024 - [info] ** Phase 1: Configuration Check Phase
completed.
Fri Aug 2 19:38:39 2024 - [info]
Fri Aug 2 19:38:39 2024 - [info] * Phase 2: Dead Master Shutdown Phase..
Fri Aug 2 19:38:39 2024 - [info]
Fri Aug 2 19:38:39 2024 - [info] HealthCheck: SSH to 172.25.254.20 is reachable.
Fri Aug 2 19:38:39 2024 - [info] Forcing shutdown so that applications never
connect to the current master..
Fri Aug 2 19:38:39 2024 - [warning] master_ip_failover_script is not set.
Skipping invalidating dead master IP address.
Fri Aug 2 19:38:39 2024 - [warning] shutdown_script is not set. Skipping
explicit shutting down of the dead master.
Fri Aug 2 19:38:39 2024 - [info] * Phase 2: Dead Master Shutdown Phase
completed.
Fri Aug 2 19:38:39 2024 - [info]
Fri Aug 2 19:38:39 2024 - [info] * Phase 3: Master Recovery Phase..
Fri Aug 2 19:38:39 2024 - [info]
Fri Aug 2 19:38:39 2024 - [info] * Phase 3.1: Getting Latest Slaves Phase..
Fri Aug 2 19:38:39 2024 - [info]
Fri Aug 2 19:38:39 2024 - [info] The latest binary log file/position on all
slaves is mysql-bin.000002:1519
Fri Aug 2 19:38:39 2024 - [info] Retrieved Gtid Set: 1a02fc44-4d68-11ef-8dd9-
000c29d8cf7e:1
Fri Aug 2 19:38:39 2024 - [info] Latest slaves (Slaves that received relay log
files to the latest):
Fri Aug 2 19:38:39 2024 - [info] 172.25.254.10(172.25.254.10:3306)
Version=5.7.44-log (oldest major version between slaves) log-bin:enabled
Fri Aug 2 19:38:39 2024 - [info] GTID ON
Fri Aug 2 19:38:39 2024 - [info] Replicating from
172.25.254.20(172.25.254.20:3306)
Fri Aug 2 19:38:39 2024 - [info] Primary candidate for the new Master
(candidate_master is set)
Fri Aug 2 19:38:39 2024 - [info] 172.25.254.30(172.25.254.30:3306)
Version=5.7.44-log (oldest major version between slaves) log-bin:enabled
Fri Aug 2 19:38:39 2024 - [info] GTID ON
Fri Aug 2 19:38:39 2024 - [info] Replicating from
172.25.254.20(172.25.254.20:3306)
Fri Aug 2 19:38:39 2024 - [info] Not candidate for the new Master (no_master
is set)
Fri Aug 2 19:38:39 2024 - [info] The oldest binary log file/position on all
slaves is mysql-bin.000002:1519
Fri Aug 2 19:38:39 2024 - [info] Retrieved Gtid Set: 1a02fc44-4d68-11ef-8dd9-
000c29d8cf7e:1
Fri Aug 2 19:38:39 2024 - [info] Oldest slaves:
Fri Aug 2 19:38:39 2024 - [info] 172.25.254.10(172.25.254.10:3306)
Version=5.7.44-log (oldest major version between slaves) log-bin:enabled
Fri Aug 2 19:38:39 2024 - [info] GTID ON
Fri Aug 2 19:38:39 2024 - [info] Replicating from
172.25.254.20(172.25.254.20:3306)
Fri Aug 2 19:38:39 2024 - [info] Primary candidate for the new Master
(candidate_master is set)
Fri Aug 2 19:38:39 2024 - [info] 172.25.254.30(172.25.254.30:3306)
Version=5.7.44-log (oldest major version between slaves) log-bin:enabled
Fri Aug 2 19:38:39 2024 - [info] GTID ON
Fri Aug 2 19:38:39 2024 - [info] Replicating from
172.25.254.20(172.25.254.20:3306)
Fri Aug 2 19:38:39 2024 - [info] Not candidate for the new Master (no_master
is set)
Fri Aug 2 19:38:39 2024 - [info]
Fri Aug 2 19:38:39 2024 - [info] * Phase 3.3: Determining New Master Phase..
Fri Aug 2 19:38:39 2024 - [info]
Fri Aug 2 19:38:39 2024 - [info] 172.25.254.10 can be new master.
Fri Aug 2 19:38:39 2024 - [info] New master is 172.25.254.10(172.25.254.10:3306)
Fri Aug 2 19:38:39 2024 - [info] Starting master failover..
Fri Aug 2 19:38:39 2024 - [info]
From:
172.25.254.20(172.25.254.20:3306) (current master)
+--172.25.254.10(172.25.254.10:3306)
+--172.25.254.30(172.25.254.30:3306)
To:
172.25.254.10(172.25.254.10:3306) (new master)
+--172.25.254.30(172.25.254.30:3306)
Starting master switch from 172.25.254.20(172.25.254.20:3306) to
172.25.254.10(172.25.254.10:3306)? (yes/NO): yes
Fri Aug 2 19:38:41 2024 - [info] New master decided manually is
172.25.254.10(172.25.254.10:3306)
Fri Aug 2 19:38:41 2024 - [info]
Fri Aug 2 19:38:41 2024 - [info] * Phase 3.3: New Master Recovery Phase..
Fri Aug 2 19:38:41 2024 - [info]
Fri Aug 2 19:38:41 2024 - [info] Waiting all logs to be applied..
Fri Aug 2 19:38:41 2024 - [info] done.
Fri Aug 2 19:38:41 2024 - [info] Getting new master's binlog name and position..
Fri Aug 2 19:38:41 2024 - [info] mysql-bin.000002:1519
Fri Aug 2 19:38:41 2024 - [info] All other slaves should start replication from
here. Statement should be: CHANGE MASTER TO MASTER_HOST='172.25.254.10',
MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl',
MASTER_PASSWORD='xxx';
Fri Aug 2 19:38:41 2024 - [info] Master Recovery succeeded.
File:Pos:Exec_Gtid_Set: mysql-bin.000002, 1519, 1a02fc44-4d68-11ef-8dd9-
000c29d8cf7e:1,
68f3a901-4deb-11ef-8055-000c29cb63ce:1-5
Fri Aug 2 19:38:41 2024 - [warning] master_ip_failover_script is not set.
Skipping taking over new master IP address.
Fri Aug 2 19:38:41 2024 - [info] Setting read_only=0 on
172.25.254.10(172.25.254.10:3306)..
Fri Aug 2 19:38:41 2024 - [info] ok.
Fri Aug 2 19:38:41 2024 - [info] ** Finished master recovery successfully.
Fri Aug 2 19:38:41 2024 - [info] * Phase 3: Master Recovery Phase completed.
Fri Aug 2 19:38:41 2024 - [info]
Fri Aug 2 19:38:41 2024 - [info] * Phase 4: Slaves Recovery Phase..
Fri Aug 2 19:38:41 2024 - [info]
Fri Aug 2 19:38:41 2024 - [info]
Fri Aug 2 19:38:41 2024 - [info] * Phase 4.1: Starting Slaves in parallel..
Fri Aug 2 19:38:41 2024 - [info]
Fri Aug 2 19:38:41 2024 - [info] -- Slave recovery on host
172.25.254.30(172.25.254.30:3306) started, pid: 42023. Check tmp log
/etc/masterha/172.25.254.30_3306_20240802193835.log if it takes time..
Fri Aug 2 19:38:43 2024 - [info]
Fri Aug 2 19:38:43 2024 - [info] Log messages from 172.25.254.30 ...
Fri Aug 2 19:38:43 2024 - [info]
Fri Aug 2 19:38:41 2024 - [info] Resetting slave
172.25.254.30(172.25.254.30:3306) and starting replication from the new master
172.25.254.10(172.25.254.10:3306)..
Fri Aug 2 19:38:41 2024 - [info] Executed CHANGE MASTER.
Fri Aug 2 19:38:42 2024 - [info] Slave started.
Fri Aug 2 19:38:42 2024 - [info] gtid_wait(1a02fc44-4d68-11ef-8dd9-
000c29d8cf7e:1,
68f3a901-4deb-11ef-8055-000c29cb63ce:1-5) completed on
172.25.254.30(172.25.254.30:3306). Executed 0 events.
Fri Aug 2 19:38:43 2024 - [info] End of log messages from 172.25.254.30.
Fri Aug 2 19:38:43 2024 - [info] -- Slave on host
172.25.254.30(172.25.254.30:3306) started.
Fri Aug 2 19:38:43 2024 - [info] All new slave servers recovered successfully.
Fri Aug 2 19:38:43 2024 - [info]
Fri Aug 2 19:38:43 2024 - [info] * Phase 5: New master cleanup phase..
Fri Aug 2 19:38:43 2024 - [info]
Fri Aug 2 19:38:43 2024 - [info] Resetting slave info on the new master..
Fri Aug 2 19:38:43 2024 - [info] 172.25.254.10: Resetting slave info succeeded.
Fri Aug 2 19:38:43 2024 - [info] Master failover to
172.25.254.10(172.25.254.10:3306) completed successfully.
Fri Aug 2 19:38:43 2024 - [info]
----- Failover Report -----
app1: MySQL Master failover 172.25.254.20(172.25.254.20:3306) to
172.25.254.10(172.25.254.10:3306) succeeded
Master 172.25.254.20(172.25.254.20:3306) is down!
Check MHA Manager logs at mysql-mha.timinglee.org for details.
Started manual(interactive) failover.
Selected 172.25.254.10(172.25.254.10:3306) as a new master.
172.25.254.10(172.25.254.10:3306): OK: Applying all logs succeeded.
172.25.254.30(172.25.254.30:3306): OK: Slave started, replicating from
172.25.254.10(172.25.254.10:3306)
172.25.254.10(172.25.254.10:3306): Resetting slave info succeeded.
Master failover to 172.25.254.10(172.25.254.10:3306) completed successfully.
恢复故障 mysql 节点
[root@mysql-node20 tmp]# /etc/init.d/mysqld start
Starting MySQL. SUCCESS!
[root@mysql-node20 tmp]# mysql -p
mysql> CHANGE MASTER TO MASTER_HOST='172.25.254.10', MASTER_USER='repl',
MASTER_PASSWORD='lee', MASTER_AUTO_POSITION=1;
mysql> show slave\G

测试一主两从是否正常

[root@mysql-node masterha]# masterha_check_repl --conf=/etc/masterha/app1.cnf
Fri Aug 2 20:15:29 2024 - [info] Checking replication health on 172.25.254.20..
Fri Aug 2 20:15:29 2024 - [info] ok.
Fri Aug 2 20:15:29 2024 - [info] Checking replication health on 172.25.254.30..
Fri Aug 2 20:15:29 2024 - [info] ok.
Fri Aug 2 20:15:29 2024 - [warning] master_ip_failover_script is not defined.
Fri Aug 2 20:15:29 2024 - [warning] shutdown_script is not defined.
Fri Aug 2 20:15:29 2024 - [info] Got exit code 0 (Not master dead).
MySQL Replication Health is OK.
自动切换
[root@mysql-node masterha]# rm -fr app1.failover.complete # 删掉切换锁文件

监控程序通过指定配置文件监控 master 状态,当 master 出问题后自动切换并退出避免重复做故障切换

[root@mysql-mha masterha]# masterha_manager --conf=/etc/masterha/app1.cnf
[root@mysql-mha masterha]# cat /etc/masterha/manager.log

恢复故障节点

恢复故障节点

[root@mysql-node20 mysql]# /etc/init.d/mysqld start
mysql> CHANGE MASTER TO MASTER_HOST='172.25.254.10', MASTER_USER='repl',
MASTER_PASSWORD='lee', MASTER_AUTO_POSITION=1
清除锁文件
[root@mysql-node masterha]# rm -rf app1.failover.complete manager.log

6.2.5MHA添加VIP****功能

上传在群中发给大家的脚本

[root@mysql-node ~]# ls
master_ip_failover master_ip_online_change MHA-7 MHA-7.zip
[root@mysql-node ~]# cp master_ip_failover master_ip_online_change
/usr/local/bin/
[root@mysql-node ~]# chmod +x /usr/local/bin/master_ip_*

修改脚本在脚本中只需要修改下 vip 即可

[root@mysql-node ~]# vim /usr/local/bin/master_ip_failover
my $vip = '172.25.254.100/24';
my $ssh_start_vip = "/sbin/ip addr add $vip dev eth0";
my $ssh_stop_vip = "/sbin/ip addr del $vip dev eth0";
[root@mysql-mha ~]# vim /usr/local/bin/master_ip_online_change
my $vip = '172.25.254.100/24';
my $ssh_start_vip = "/sbin/ip addr add $vip dev eth0";
my $ssh_stop_vip = "/sbin/ip addr del $vip dev eth0";
my $exit_code = 0;
[root@mysql-node masterha]# masterha_manager --conf=/etc/masterha/app1.cnf & 启动监
控程序
[root@mysql-node10 tmp]# ip a a 172.25.254.100/24 dev eth0 # 在 master 节点添加 VIP
模拟故障
[root@mysql-node10 ~]# /etc/init.d/mysqld stop # 关闭主节点服务
[root@mysql-mha masterha]# cat manager.log
恢复故障主机
[root@mysql-node20 mysql]# /etc/init.d/mysqld start
mysql> CHANGE MASTER TO MASTER_HOST='172.25.254.10', MASTER_USER='repl',
MASTER_PASSWORD='lee', MASTER_AUTO_POSITION=1
[root@mysql-node masterha]# rm -rf app1.failover.complete manager.log
手动切换后查看 vip 变化
[root@mysql-node masterha]# masterha_master_switch --conf=/etc/masterha/app1.cnf
--master_state=alive --new_master_host=172.25.254.10 --new_master_port=3306 --
orig_master_is_new_slave --running_updates_limit=10000
[root@mysql-node10 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP
group default qlen 1000
link/ether 00:0c:29:cb:63:ce brd ff:ff:ff:ff:ff:ff
inet 172.25.254.10/24 brd 172.25.254.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet 172.25.254.100/24 scope global secondary eth0
valid_lft forever preferred_lft forever

相关推荐
申耀的科技观察13 分钟前
【观察】戴尔AI算力加速服务器“焕新上市”,打通AI落地行业“最后一公里”...
大数据·运维·服务器·人工智能
一名在八月份找工作的测试员14 分钟前
数据库的操作:SQL运算符(算法/比较/逻辑/位)
java·数据库·sql
666IDCaaa17 分钟前
选择适合你企业发展的服务器
运维·服务器
程序员佳倩21 分钟前
jsp+sevlet+mysql实验室设备管理系统2.0
java·开发语言·mysql
紫郢剑侠30 分钟前
Linux shell编程学习笔记78:cpio命令——文件和目录归档工具(上)
linux·学习笔记·shell编程·脚本编程·cpio
oulaqiao43 分钟前
项目——负载均衡OJ
运维·服务器·负载均衡
gbase_lmax1 小时前
druid连接gbase8s数据库报错空指针
数据库
知知之之1 小时前
ShardingSphere事务
数据库·mysql
乔以亦1 小时前
python 装饰器
linux·开发语言·python