###1.源码编译mysql###
对压缩包进行解压,并对mysql进行源码编译,其中需要下载依赖才能编译成功。
官网: www.mysql.com解压并进入目录
[root@server1 ~]# tar xf mysql-boost-5.7.40.tar.gz
[root@server1 ~]# cd mysql-5.7.40/安装依赖性
[root@server1 mysql-5.7.40]# yum install -y cmake gcc-c++ bsioncmake
[root@server1 mysql-5.7.40]# cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_DATADIR=/data/mysql -DMYSQL_UNIX_ADDR=/data/mysql/mysql.sock -DWITH_INNOBASE_STORAGE_ENGINE=1 -DWITH_EXTRA_CHARSETS=all -DDEFAULT_CHARSET=utf8mb4 -DDEFAULT_COLLATION=utf8mb4_unicode_ci -DWITH_BOOST=/root/mysql-5.7.40/boost/boost_1_59_0[root@server1 mysql-5.7.40]# make
[root@server1 mysql-5.7.40]# make install
[注意] 如果没有一次性cmake成功,则删除CMakeCache.txt,重新cmake
参数含义
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql ##指定软件的安装路径
-DMYSQL_DATADIR=/data/mysql ##指定MySQL数据库数据文件的存储路径,这一选项在MySQL服务启动时可以通过datadir参数进行设置
-DMYSQL_UNIX_ADDR=/data/mysql/mysql.sock ##指定套接字文件的存储路径,默认是在/tmp/mysql.sock目录下,这一选项可以在MySQL服务启动时通过socket参数进行设置
-DWITH_INNOBASE_STORAGE_ENGINE=1 ##静态编译存储引擎
-DSYSCONFDIR=/etc ##指定MySQL参数文件的默认路径,这一选项可以在MySQL服务启动时通过defaults-file参数进行设置
-DENABLED_LOCAL_INFILE=1 ##是否允许从客户端本地加载数据到MySQL服务端,专用于load data infile语句,默认是不允许的
-DWITH_EXTRA_CHARSETS=all ##指定附加支持的字符集,默认是all
-DDEFAULT_CHARSET=utf8mb4 ##指定MySQL服务的默认字符集
-DDEFAULT_COLLATION=utf8mb4_unicode_ci ##指定MySQL服务的默认校对规则
-DWITH_BOOST=/root/mysql-5.7.31/boost/boost_1_59_0 ##安装位置与数据位置
###2.初始化配置mysql###
创建mysql的数据目录,并设定为某一用户的所属人、所属组以保证其执行权限,因此建立该用户。同时拷贝启动脚本,使mysql可全局使用,然后开启服务。
拷贝启动脚本
[root@server1 mysql-5.7.40]# cd /usr/local/mysql/
[root@server1 mysql]# cd support-files/
[root@server1 support-files]# cp mysql.server /etc/init.d/mysqld
修改mysql配置文件
[root@server1 etc]# vim /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# Settings user and group are ignored when systemd is used.
# If you need to run mysqld under a different user or group,
# customize your systemd unit file for mariadb according to the
# instructions in http://fedoraproject.org/wiki/Systemd#[mysqld_safe]
#log-error=/var/log/mariadb/mariadb.log
#pid-file=/var/run/mariadb/mariadb.pid#
# include all files from the config directory
#
!includedir /etc/my.cnf.d
创建mysql的数据目录,并设定为mysql用户的所属人、所属组以保证其执行权限,因此建立mysql用户。
[root@server1 ~]# mkdir /data/mysql -p
[root@server1 ~]# useradd -M -d /data/mysql/ -s /sbin/nologin mysql
[root@server1 ~]# chown mysql.mysql /data/mysql/
修改环境变量使其生效
[root@server1 ~]# vim .bash_profile
# .bash_profile# Get the aliases and functions
if [ -f ~/.bashrc ]; then. ~/.bashrc
fi# User specific environment and startup programsPATH=$PATH:$HOME/bin:/usr/local/php/bin:/usr/local/mysql/binexport PATH[root@server1 ~]# source .bash_profile
初始化触发
[root@server1 ~]# mysqld --initialize --user=mysql
启动服务
[root@server1 ~]# /etc/init.d/mysqld start
Starting MySQL.Logging to '/data/mysql/server1.err'.SUCCESS!
[root@server1 ~]# netstat -antlp|grep :3306
tcp6 0 0 :::3306 :::* LISTEN 13856/mysqld
安全初始化
[root@server1 ~]# 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: #是否激活密码插件,直接回车
Using existing password for root.
Change the password for root ? ((Press y|Y for Yes, any other key for 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.
#是否删除匿名用户,输入 yNormally, 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.
#是否禁用root远程登录,输入 y
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.
#是否删除test数据库,输入 y- 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@server1 ~]# mysql -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 5
Server version: 5.7.40 Source distributionCopyright (c) 2000, 2022, 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> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)
###3.主从复制###
(1)master配置
修改配置文件,设定启用binlog和主库id号,重启服务。在数据目录下,会生成数据库的二进制操作日志和二进制日志的索引文件。
[root@server1 ~]# vim /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# Settings user and group are ignored when systemd is used.
# If you need to run mysqld under a different user or group,
# customize your systemd unit file for mariadb according to the
# instructions in http://fedoraproject.org/wiki/Systemdlog-bin=mysql-bin##表示启用binlog,log-bin决定了msyql 的binlog的名字,⽣成的binlog名字为mysql-bin.000001
server_id=1 ##正整数,可以不是递增,但必须为正#[mysqld_safe]
#log-error=/var/log/mariadb/mariadb.log
#pid-file=/var/run/mariadb/mariadb.pid#
# include all files from the config directory
#
!includedir /etc/my.cnf.d重启服务
[root@server1 ~]# /etc/init.d/mysqld restart
进入数据库,创建复制用户,并且进行授权。slave端可以通过该授权用户进入master端的数据库。
[root@server1 ~]# mysql -pwestos
mysql> CREATE USER 'repl'@'%' IDENTIFIED BY 'westos';
Query OK, 0 rows affected (0.00 sec)mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
Query OK, 0 rows affected (0.00 sec)mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 595 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
(2)slave配置
在server1主机master主库中将mysql的数据目录
以及配置文件
复制到server2主机,即slave从库。
新建数据库实例server2
[root@server1 ~]# scp -r /usr/local/mysql/ server2:/usr/local/
[root@server1 ~]# scp /etc/my.cnf server2:/etc/修改配置文件
[root@server2 ~]# vim /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# Settings user and group are ignored when systemd is used.
# If you need to run mysqld under a different user or group,
# customize your systemd unit file for mariadb according to the
# instructions in http://fedoraproject.org/wiki/Systemdserver-id=2#[mysqld_safe]
#log-error=/var/log/mariadb/mariadb.log
#pid-file=/var/run/mariadb/mariadb.pid#
# include all files from the config directory
#
!includedir /etc/my.cnf.d
修改环境变量,在从库中拷贝启动脚本,使mysql可全局使用,添加变量,创建用户,数据目录,初始化,然后开启服务,修改密码。
修改环境变量
[root@server2 ~]# vim .bash_profile
[root@server2 ~]# source .bash_profile[root@server2 ~]# cd /usr/local/mysql
[root@server2 mysql]# cp support-files/mysql.server /etc/init.d/mysqld
[root@server2 mysql]# useradd -M -d /data/mysql/ -s /sbin/nologin mysql
[root@server2 mysql]# mkdir -p /data/mysql
[root@server2 mysql]# chown mysql.mysql /data/mysql/
用mysql用户初始化触发
[root@server2 mysql]# mysqld --initialize --user=mysql
启动服务
[root@server2 mysql]# /etc/init.d/mysqld start
安全初始化
[root@server2 mysql]# mysql_secure_installation
配置主从同步
登录
[root@server2 mysql]# mysql -pwestos
mysql> CHANGE MASTER TO MASTER_HOST='192.168.76.11', MASTER_USER='repl', MASTER_PASSWORD='westos', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=595;
Query OK, 0 rows affected, 2 warnings (0.01 sec)###########参数#########################
MASTER_HOST='192.168.76.11' #访问的master端地址
MASTER_USER='repl', #访问的用户
MASTER_PASSWORD='westos', #输入密码
MASTER_LOG_FILE='mysql-bin.000001', #要从master中复制的文件
MASTER_LOG_POS=595; #文件Position号
########################################开启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 eventMaster_Host: 192.168.56.11Master_User: replMaster_Port: 3306Connect_Retry: 60Master_Log_File: mysql-bin.000001Read_Master_Log_Pos: 595Relay_Log_File: server2-relay-bin.000002Relay_Log_Pos: 320Relay_Master_Log_File: mysql-bin.000001Slave_IO_Running: YesSlave_SQL_Running: Yes ##两行yes即为成功
...
(3)测试server12数据同步
master创建测试数据库
[root@server1 ~]# mysql -pwestos
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)mysql> create database westos;
Query OK, 1 row affected (0.00 sec)mysql> use westos;mysql> create table user_tb (-> username varchar(25) not null,-> password varchar(50) not null);
Query OK, 0 rows affected (0.00 sec)mysql> desc user_tb;
+----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| username | varchar(25) | NO | | NULL | |
| password | varchar(50) | NO | | NULL | |
+----------+-------------+------+-----+---------+-------+
2 rows in set (0.01 sec)mysql> insert into user_tb values ('user1','123');
Query OK, 1 row affected (0.00 sec)mysql> insert into user_tb values ('user2','456');
Query OK, 1 row affected (0.00 sec)
slave server2:查看测试数据库是否同步
[root@server2 mysql]# mysql -pwestos
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| westos |
+--------------------+
5 rows in set (0.00 sec)
mysql> use westos
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -ADatabase changed
mysql> show tables;
+------------------+
| Tables_in_westos |
+------------------+
| user_tb |
+------------------+
1 row in set (0.00 sec)mysql> select * from user_tb;
+----------+----------+
| username | password |
+----------+----------+
| user1 | 123 |
| user2 | 456 |
+----------+----------+
2 rows in set (0.01 sec)
(4)添加一台新的slave:server3
[root@server1 ~]# scp -r /usr/local/mysql/ server3:/usr/local/
[root@server1 ~]# scp /etc/my.cnf server3:/etc/
[root@server3 ~]# vim .bash_profile
[root@server3 ~]# source .bash_profile
[root@server3 ~]# mkdir -p /data/mysql
[root@server3 ~]# useradd -M -d /data/mysql/ -s /sbin/nologin mysql
[root@server3 ~]# chown mysql.mysql /data/mysql/
[root@server3 ~]# vim /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# Settings user and group are ignored when systemd is used.
# If you need to run mysqld under a different user or group,
# customize your systemd unit file for mariadb according to the
# instructions in http://fedoraproject.org/wiki/Systemdserver-id=3#[mysqld_safe]
#log-error=/var/log/mariadb/mariadb.log
#pid-file=/var/run/mariadb/mariadb.pid#
# include all files from the config directory
#
!includedir /etc/my.cnf.d[root@server3 ~]# mysqld --initialize --user=mysql
[root@server3 ~]# cd /usr/local/mysql/
[root@server3 mysql]# cp support-files/mysql.server /etc/init.d/mysqld
[root@server3 mysql]# /etc/init.d/mysqld start
[root@server3 mysql]# mysql_secure_installation
(5)配置slave3能同步master改变前后的所有数据
新建的slave只能同步从新建这一刻起master生成的新数据,之前的数据会丢失。需要先将master已有的数据备份,传输给新的slave,在建立新的主从复制。
master备份数据库
[root@server1 ~]# mysqldump -pwestos westos > dump.sql #mysqldump用来做备份
[root@server1 ~]# scp dump.sql server3:
注意:
生产环境中备份时需要锁表,保证备份前后的数据一致
mysql> FLUSH TABLES WITH READ LOCK;
备份后再解锁
mysql> UNLOCK TABLES;
注意:
mysqldump命令备份的数据文件,在还原时先DROP TABLE,需要合并数据时需要删除此语句
salve server3还原数据库
[root@server3 ~]# mysqladmin -pwestos create westos #新建一个库
[root@server3 ~]# mysql -pwestos westos < dump.sql #将备份数据传给库
测试是否旧数据同步
[root@server3 ~]# mysql -pwestos
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| westos |
+--------------------+
5 rows in set (0.00 sec)mysql> use westos
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -ADatabase changed
mysql> select * from user_tb;
+----------+----------+
| username | password |
+----------+----------+
| user1 | 123 |
| user2 | 456 |
+----------+----------+
2 rows in set (0.00 sec)
设置主从同步
mysql> CHANGE MASTER TO MASTER_HOST='192.168.56.11', MASTER_USER='repl', MASTER_PASSWORD='westos', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=1534;
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 eventMaster_Host: 192.168.56.11Master_User: replMaster_Port: 3306Connect_Retry: 60Master_Log_File: mysql-bin.000001Read_Master_Log_Pos: 1534Relay_Log_File: server3-relay-bin.000002Relay_Log_Pos: 320Relay_Master_Log_File: mysql-bin.000001Slave_IO_Running: YesSlave_SQL_Running: Yes
...
(6)测试server123数据同步
master server1创建测试文件
[root@server1 ~]# mysql -pwestos
mysql> insert into westos.user_tb values ('user3','666');
Query OK, 1 row affected (0.00 sec)
slave server23查看是否同步
[root@server2 mysql]# mysql -pwestos
mysql> select * from westos.user_tb;
+----------+----------+
| username | password |
+----------+----------+
| user1 | 123 |
| user2 | 456 |
| user3 | 666 |
+----------+----------+
3 rows in set (0.00 sec)[root@server3 mysql]# mysql -pwestos
mysql> select * from westos.user_tb;
+----------+----------+
| username | password |
+----------+----------+
| user1 | 123 |
| user2 | 456 |
| user3 | 666 |
+----------+----------+
3 rows in set (0.00 sec)
###4.主-从(主)-从复制+GTID###
GTID即全局事务ID (global transaction identifier), 其保证为每一个在主上提交的事务在复制集群中可以生成一个唯一的ID。mysql主从结构在一主一从情况下对于GTID来说就没有优势了,而对于2台主以上的结构优势异常明显,可以在数据不丢失的情况下切换新主。
(1)master设置
在server1主机master端mysql配置文件中开启gtid,并重启服务。
master配置:
[root@server1 mysql]# vim /etc/my.cnf
...
log-bin=mysql-bin
server-id=1
gtid_mode=ON
enforce-gtid-consistency=ON重启服务
[root@server1 mysql]# /etc/init.d/mysqld restart
(2)slave设置
在server2主机slave端mysql配置文件中开启gtid,并重启服务。停止slave端,设定以repl用户自动获取master端的事务。开启slave,查看状态,可以看到,IO线程和SQL线程为running状态。 其它slave节点以此类推
slave配置:
[root@server2 ~]# vim /etc/my.cnf
...
server-id=2
gtid_mode=ON
enforce-gtid-consistency=ON重启服务
[root@server2 ~]# /etc/init.d/mysqld restart[root@server2 ~]# mysql -pwestos
#首先停止slave
mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)#重新配置
mysql> CHANGE MASTER TO MASTER_HOST='192.168.56.11', MASTER_USER='repl', MASTER_PASSWORD='westos', MASTER_AUTO_POSITION = 1;
Query OK, 0 rows affected, 2 warnings (0.00 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 eventMaster_Host: 192.168.56.11Master_User: replMaster_Port: 3306Connect_Retry: 60Master_Log_File: mysql-bin.000002Read_Master_Log_Pos: 154Relay_Log_File: server2-relay-bin.000002Relay_Log_Pos: 367Relay_Master_Log_File: mysql-bin.000002Slave_IO_Running: YesSlave_SQL_Running: Yes
(3)测试
在master端插入新内容,slave端的mysql表中的gtid_executed里会生成gtid的标识号。
###5.半同步复制###
异步复制:主库只负责发送,从库只负责接受,主库没有确认复制的过程,如果网络延迟或者设备中断,会导致数据不同步。
show processlist; 可以查看io和sql线程
io延迟:网络延迟
sql延迟:因为主库上多个线程对数据库进行写入,但从库只有一个线程进行回放,不可避免会产生延迟。
当读和写的同步需求很高,异步复制就不能够稳定复制。
AFTER_COMMIT
原理:master将binlog发送给slave端,同时保存本地,进行引擎提交,等待slave端完成操作,返回给master端ack信息,同时返回用户ok信息。
但问题是,进行引擎提交后,salve端没有完成操作,但此时同时登陆的另一个用户已经可以看到提交的信息,如果此时master端挂掉,slave端没有保存信息,而另一用户已经看到的信息也会消失。
AFTER_SYNC(5.7版本后默认使用)
原理:master将binlog发送给slave端,同时保存本地,等待slave端完成操作,返回给master端ack信息,master端才会进行引擎提交,同时返回用户ok信息。
(1)master配置
#安装半同步模块
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)#激活master半同步模式
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 | 2 |
| 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)半同步参数写入配置文件,确保重启后依然生效
[root@server1 mysql]# vim /etc/my.cnf
...
log-bin=mysql-bin
server-id=1
gtid_mode=ON
enforce-gtid-consistency=ON
rpl_semi_sync_master_enabled=1
(2)slave配置
#安装半同步模块
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)#需要重启IO线程,slave端的半同步才能生效
mysql> STOP SLAVE IO_THREAD;
Query OK, 0 rows affected (0.00 sec)mysql> START SLAVE IO_THREAD;
Query OK, 0 rows affected (0.00 sec)mysql> SHOW VARIABLES LIKE 'rpl_semi_sync%';
+---------------------------------+-------+
| Variable_name | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled | ON |
| rpl_semi_sync_slave_trace_level | 32 |
+---------------------------------+-------+
2 rows in set (0.00 sec)mysql> SHOW STATUS LIKE 'Rpl_semi_sync%';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON |
+----------------------------+-------+
1 row in set (0.00 sec)#半同步参数写入配置文件
[root@server2 ~]# vim /etc/my.cnf
server-id=2
gtid_mode=ON
enforce-gtid-consistency=ON
rpl_semi_sync_slave_enabled=1
(3)测试
master写入数据:
mysql> insert into westos.user_tb values ('user6','666');
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 |
| Rpl_semi_sync_master_status | ON |
| Rpl_semi_sync_master_timefunc_failures | 0 |
| Rpl_semi_sync_master_tx_avg_wait_time | 2096 |
| Rpl_semi_sync_master_tx_wait_time | 2096 |
| 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)停止所有slave节点的IO线程:(不会再有任何slave线程回应master)
mysql> STOP SLAVE IO_THREAD;
Query OK, 0 rows affected (0.00 sec)master节点再次写入数据:
mysql> insert into westos.user_tb values ('user7','666');
Query OK, 1 row affected (10.00 sec)
#等待默认超时时间10秒后,mysql自动切换为异步模式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 | 4 |
| Rpl_semi_sync_master_no_times | 1 |
| Rpl_semi_sync_master_no_tx | 1 | #显示未通过半同步模式复制的数据,即异步模式数据
| Rpl_semi_sync_master_status | OFF | #半同步模式关闭
| Rpl_semi_sync_master_timefunc_failures | 0 |
| Rpl_semi_sync_master_tx_avg_wait_time | 2096 |
| Rpl_semi_sync_master_tx_wait_time | 2096 |
| 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.01 sec)所有slave节点再次启动IO线程,mysql会自动切回半同步模式
mysql> START SLAVE IO_THREAD;
Query OK, 0 rows affected (0.00 sec)
###6.并行复制(MTS)###
适用于多线程并发。基于组的并发复制,可以支持在一个database中,并发执行relaylog中的事务。相同的二进制日志组在master上提交并行应用到slave节点上,没有跨数据库的限制,并且不需要把数据分割到多个数据库。
(1)master配置
在master主机中修改配置文件,设定在mysql中创建表,数据会存在数据库中,打开半同步复制。
vim /etc/my.cnf
///
log-bin=mysql-bin
server-id=1
gtid_mode=ON
enforce-gtid-consistency=ON
rpl_semi_sync_master_enabled=1 ##控制打开半同步复制
master_info_repository=TABLE ##在mysql中创建表,数据会存在数据库中
///
(2)slave配置
server2主机
默认slave节点sql单线程回放,会造成数据同步延时较高
slave节点添加以下参数
[root@server2 ~]# vim /etc/my.cnf
...
slave-parallel-type=LOGICAL_CLOCK ##基于组提交的并行复制方式
slave-parallel-workers=16 ##可有16个SQL Thread(coordinator线程)来进行并行复制,不建议设置为1,单线程复制,但是因为要做coordinator协调线程的转发,性能比0还差,效率会更低
master_info_repository=TABLE ##有两个值,分别是file和table,该参数决定了slave记录master的状态,如果参数是file,就会创建master.info文件,磁盘频繁读取文件,会降低执行效率,如果参数值是table,就在mysql中创建slave_master_info的表,数据会存在数据库中,避免影响内存。
relay_log_info_repository=TABLE ##明文存储不安全,把relay.info中的信息记录在table中相对安全
relay_log_recovery=ON ##从库意外宕机后,同时从库的relay log也一起损坏了,而主库的日志已经传到了从库,只是从库还没有来得及应用这些日志时,从库会自动放弃所有未执行的relay log,重新生成一个relay log,并将从库的io线程的position重新指向新的relay log。并将sql线程的position退回到跟io线程的position保持一致,重新开始同步,这样在从库中事务不会丢失。重启服务
[root@server2 ~]# /etc/init.d/mysqld restart
Shutting down MySQL.. SUCCESS!
Starting MySQL. SUCCESS!
(3)测试
进入数据库,查看设定是否生效
[root@server2 ~]# mysql -pwestos
> show variables like 'relay_log%'; ##查看上面的设定是否成功
> use mysql
> show tables; ##slave_master_info
> select * from slave_relay_log_info;
> show processlist;
###7.延迟复制###
1、mysql本身有延迟,测验延迟多少会对实验产生影响
2、如果主库出现问题,有延迟内的时间从从库恢复数据
并不记录IO延迟,只记录SQL的延迟
(1)slave端设置
在server2进入数据库,查看从库状态,当前主从延迟为0,停止从库服务。设定主从复制延迟为60s,重新开启从库服务。查看状态,设定成功。
###server2
mysql -p
> show slave status\G; ##sql_delay=0
> STOP SLAVE SQL_THREAD; ##停止服务
> CHANGE MASTER TO MASTER_DELAY=60; ##设定延迟60s复制
> START SLAVE SQL_THREAD;
> show slave status\G; ##sql_delay=30
(2)测试
此时在server1插入数据。
###server1
mysql -pwestos
> use westos;
> insert into linux values ('user9','999');
在server2查看,seconds_behind_master会从60递减到0,60s后,数据会被同步。
###server2
> show slave status\G; ##seconds_behind_master:30 ~ 0
> select * from westos.linux; ##重复执行,直到30s后才会出现user10
> show slave status\G; ##seconds_behind_master:0
###8.慢查询###
程序中定位一个执行慢的SQL可以根据慢查询日志,默认情况下,慢查询日志禁用,因为开启慢查询日志或多或少的会对mysql的性能产生一些影响。在慢查询日志功能开启时,只有SQL执行时间超过long_query_time参数值的的语句才会在慢查询日志中记录。long_query_time参数,最小值和默认值分别为0 10,单位为秒。
在server1主机中,当前慢查询为关闭状态。设定开启慢查询,慢查询记录会存放在数据目录server1-slow.log文件中。慢查询默认值为10s,设定为5s,执行select sleep(N)语句。
###server1
> show variables like 'slow%'; ##slow_query_log为OFF
> set global slow_query_log=1; ##开启慢查询日志
> show variables like 'slow%'; ##slow_query_log为ON,慢查询记录会存放在数据目录server1-slow.log文件中
> show variables like 'long%'; ##默认10s
> set long_query_time=5;
> show variables like 'long%'; ##5s
> select sleep(10); ##执行select sleep(N)可以让此语句运行N秒钟
> exit
进入mysql数据目录,查看慢查询日志。
cd /data/mysql
ls
cat server1-slow.log
///
query_time:10.000515
select sleep(10);
###9.mysql组复制(多主模式)###
底层逻辑:基于二进制日志的复制
在任何一个节点写入,都会将数据发送到其他所有节点进行校验,当任何一个节点校验失败,其他节点不会执行该操作,只有所有节点都校验成功,才会执行该操作。容错:最起码需要有3个节点,允许一个节点出现即时故障。
组复制(group commit):通过对事务进行分组,优化减少了生成二进制日志所需的操作数。当事务同时提交时,它们将在单个操作中写入到二进制日志中。如果事务能同时提交成功,那么它们就不会共享任何锁,这意味着它们没有冲突,因此可以在Slave上并行执行。所以通过在主机上的二进制日志中添加组提交信息,这些Slave可以并行地安全地运行事务。
(1)server1配置
首先停止数据库
[root@server1 mysql]# /etc/init.d/mysqld stop
Shutting down MySQL............ SUCCESS!清除数据
[root@server1 ~]# cd /data/mysql
[root@server1 mysql]# rm -fr *[root@server1 mysql]# vim /etc/my.cnf
...
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY" ##不需要的引擎server_id=1
gtid_mode=ON ##开启gitd复制
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE ##不支持binlog校验
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" ##UUID号,集群中要一致
group_replication_start_on_boot=off ##不需开机自启
group_replication_local_address= "server1:33061"
group_replication_group_seeds= "server1:33061,server2:33061,server3:33061" ##解析
group_replication_bootstrap_group=off ##默认关闭, 防止自动创建新的Group
group_replication_ip_whitelist="192.168.76.0/24,127.0.0.1/8" ##安全白名单,默认只允许localhost,加入虚拟机网段
group_replication_single_primary_mode=OFF ##单主模式
group_replication_enforce_update_everywhere_checks=ON ##复制
group_replication_allow_local_disjoint_gtids_join=1
#根据实际情况修改主机名和网段初始化
[root@server1 mysql]# mysqld --initialize --user=mysql启动服务
[root@server1 mysql]# /etc/init.d/mysqld start[root@server1 mysql]# mysql -p
#首先修改临时密码
mysql> alter user root@localhost identified by 'westos';
Query OK, 0 rows affected (0.01 sec)mysql> SET SQL_LOG_BIN=0; ##设为0后,在Master数据库上执行的语句都不记录binlog(想在主库上执行一些操作,但不复制到slave库上,可以通过修改参数sql_log_bin来实现)
Query OK, 0 rows affected (0.00 sec)mysql> CREATE USER rpl_user@'%' IDENTIFIED BY 'westos'; ##创建用于组复制的用户,当前语句不纪录binlog
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; 打开binlog记录,以下内容需要记录
Query OK, 0 rows affected (0.00 sec)mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='westos' FOR CHANNEL 'group_replication_recovery'; ##change master to配置和改变slave服务器用于连接master服务器的参数,以便slave服务器读取master服务器的binlog及slave服务器的relay log。同时也更新master info及relay log info信息库。执行该语句前如果从机上slave io及sql线程已经启动,需要先停止(执行stop slave)
Query OK, 0 rows affected, 2 warnings (0.00 sec)mysql> SET GLOBAL group_replication_bootstrap_group=ON; #只在server1上执行,标示以后加入集群的服务器以这台服务器为基准,以后加入的就不需要设置
Query OK, 0 rows affected (0.00 sec)mysql> START GROUP_REPLICATION; ##开启组复制
Query OK, 0 rows affected, 1 warning (2.19 sec)mysql> SET GLOBAL group_replication_bootstrap_group=OFF; #只在server1上执行
Query OK, 0 rows affected (0.00 sec)mysql> SELECT * FROM performance_schema.replication_group_members; ##查看组复制成员
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | 21262bc0-b4e3-11ed-a6a0-000c298f4b2a | server1 | 3306 | ONLINE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
1 row in set (0.00 sec)
(2)server2配置
首先停止数据库
[root@server2 ~]# /etc/init.d/mysqld stop
Shutting down MySQL............ SUCCESS!清除数据
[root@server2 ~]# cd /data/mysql
[root@server2 mysql]# rm -fr *[root@server2 mysql]# vim /etc/my.cnf
...
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"server_id=2
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=ROWplugin_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= "server2:33061"
group_replication_group_seeds= "server1:33061,server2:33061,server3:33061"
group_replication_bootstrap_group=off
group_replication_ip_whitelist="192.168.76.0/24,127.0.0.1/8"
group_replication_single_primary_mode=OFF
group_replication_enforce_update_everywhere_checks=ON
group_replication_allow_local_disjoint_gtids_join=1
#根据实际情况修改主机名和网段初始化
[root@server2 mysql]# mysqld --initialize --user=mysql启动服务
[root@server2 mysql]# /etc/init.d/mysqld start[root@server2 mysql]# mysql -p
#首先修改临时密码
mysql> alter user root@localhost identified by 'westos';
Query OK, 0 rows affected (0.01 sec)mysql> SET SQL_LOG_BIN=0;
Query OK, 0 rows affected (0.00 sec)mysql> CREATE USER rpl_user@'%' IDENTIFIED BY 'westos';
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='westos' FOR CHANNEL 'group_replication_recovery';
Query OK, 0 rows affected, 2 warnings (0.00 sec)mysql> START GROUP_REPLICATION;
Query OK, 0 rows affected, 1 warning (2.19 sec)mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | 21262bc0-b4e3-11ed-a6a0-000c298f4b2a | server1 | 3306 | ONLINE |
| group_replication_applier | e8be5058-b4e3-11ed-8788-000c29f15153 | server2 | 3306 | ONLINE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
2 rows in set (0.00 sec)
(3)server3配置
首先停止数据库
[root@server3 ~]# /etc/init.d/mysqld stop
Shutting down MySQL............ SUCCESS!清楚数据
[root@server3 ~]# cd /data/mysql
[root@server3 mysql]# rm -fr *[root@server3 mysql]# vim /etc/my.cnf
...
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"server_id=3
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=ROWplugin_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= "server3:33061"
group_replication_group_seeds= "server1:33061,server2:33061,server3:33061"
group_replication_bootstrap_group=off
group_replication_ip_whitelist="192.168.76.0/24,127.0.0.1/8"
group_replication_single_primary_mode=OFF
group_replication_enforce_update_everywhere_checks=ON
group_replication_allow_local_disjoint_gtids_join=1
#根据实际情况修改主机名和网段初始化
[root@server3 mysql]# mysqld --initialize --user=mysql启动服务
[root@server3 mysql]# /etc/init.d/mysqld start[root@server3 mysql]# mysql -p
#首先修改临时密码
mysql> alter user root@localhost identified by 'westos';
Query OK, 0 rows affected (0.01 sec)mysql> SET SQL_LOG_BIN=0;
Query OK, 0 rows affected (0.00 sec)mysql> CREATE USER rpl_user@'%' IDENTIFIED BY 'westos';
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='westos' FOR CHANNEL 'group_replication_recovery';
Query OK, 0 rows affected, 2 warnings (0.00 sec)mysql> START GROUP_REPLICATION;
Query OK, 0 rows affected, 1 warning (2.19 sec)mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | 21262bc0-b4e3-11ed-a6a0-000c298f4b2a | server1 | 3306 | ONLINE |
| group_replication_applier | 4c655909-b4e4-11ed-8dcc-000c29259218 | server3 | 3306 | ONLINE |
| group_replication_applier | e8be5058-b4e3-11ed-8788-000c29f15153 | server2 | 3306 | ONLINE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
3 rows in set (0.00 sec)
(4)测试
所有节点都可以读写数据
server1:
mysql> CREATE DATABASE test;
Query OK, 1 row affected (0.00 sec)mysql> USE test;
Database changed
mysql> CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL); ##组复制要求创建表中必须有主键
Query OK, 0 rows affected (0.01 sec)mysql> INSERT INTO t1 VALUES (1, 'Luis');
Query OK, 1 row affected (0.03 sec)mysql> SELECT * FROM t1;
+----+------+
| c1 | c2 |
+----+------+
| 1 | Luis |
+----+------+
1 row in set (0.00 sec)
server2:
mysql> select * from test.t1;
+----+------+
| c1 | c2 |
+----+------+
| 1 | Luis |
+----+------+
1 row in set (0.00 sec)mysql> INSERT INTO test.t1 VALUES (2, 'wxh');
Query OK, 1 row affected (0.00 sec)
server3:
mysql> select * from test.t1;
+----+------+
| c1 | c2 |
+----+------+
| 1 | Luis |
| 2 | wxh |
+----+------+
2 rows in set (0.00 sec)mysql> INSERT INTO test.t1 VALUES (3, 'westos');
Query OK, 1 row affected (0.01 sec)
###10.mysql路由器(读写分离)###
访问mysql路由器,然后由mysql路由器访问后端服务器server主机,确保当某一台主机宕掉后,可以迅速启用其他主机。相当于负载均衡。
基于主从复制或者组复制(多主模式)的集群,通过访问不同端口实现读写分离。
前提:组复制,多主模式三台主机均online,再准备一个server4主机做路由器
(1)路由器server4配置
安装mysql读写分离组件。编辑配置文件,设定只读端口和读写端口,并开启服务。
安装软件
[root@server4 ~]# rpm -ivh mysql-router-community-8.0.21-1.el7.x86_64.rpm配置服务
[root@server4 ~]# cd /etc/mysqlrouter/
[root@server4 mysqlrouter]# vim mysqlrouter.conf
...
[routing:ro]
bind_address = 0.0.0.0
bind_port = 7001
destinations = 192.168.56.11:3306,192.168.56.12:3306,192.168.56.13:3306
routing_strategy = round-robin[routing:rw]
bind_address = 0.0.0.0
bind_port = 7002
destinations = 192.168.56.13:3306,192.168.56.12:3306,192.168.56.11:3306
routing_strategy = first-available启动服务
[root@server4 mysqlrouter]# systemctl enable --now mysqlrouter.service安装mysql客户端工具
[root@server4 ~]# yum install -y mariadb在mysql集群中创建远程测试用户
mysql> grant all on test.* to 'wxh'@'%' identified by 'westos';
(2)测试
路由器连接远程测试用户,访问7001端口,按照配置文件的设置,第一个连接的应该是server1.
连接mysql路由器
[root@server4 ~]# mysql -h 192.168.56.14 -P 7001 -u wxh -pwestosMySQL [(none)]> select * from test.t1;
+----+--------+
| c1 | c2 |
+----+--------+
| 1 | Luis |
| 2 | wxh |
| 3 | westos |
+----+--------+
3 rows in set (0.00 sec)在server1上查看网络连接
[root@server1 mysql]# yum install -y lsof
[root@server1 mysql]# lsof -i :3306
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
mysqld 15184 mysql 22u IPv6 87530 0t0 TCP *:mysql (LISTEN)
mysqld 15184 mysql 83u IPv6 93365 0t0 TCP server1:mysql->server4:55504 (ESTABLISHED)
路由器连接远程测试用户,访问7002端口,按照配置文件的设置,第一个连接的应该是server3.
[root@server4 ~]# mysql -h 192.168.56.14 -P 7002 -u wxh -pwestos[root@server3 mysql]# lsof -i :3306
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
mysqld 30811 mysql 22u IPv6 73360 0t0 TCP *:mysql (LISTEN)
mysqld 30811 mysql 81u IPv6 78061 0t0 TCP server3:mysql->server4:38594 (ESTABLISHED)
###11.mysql MHA高可用###
Master HA,对主节点进行监控,可实现自动故障转移至其它从节点;通过提升某一从节点为新的主节点,基于主从复制实现,还需要客户端配合实现,目前MHA主要支持一主多从的架构,要搭建MHA,要求一个复制集群中必须最少有三台数据库服务器,一主二从,即一台充当master,一台充当备用master,另外一台充当从库。
MHA工作原理
1 从宕机崩溃的master保存二进制日志事件(binlog events)
2 识别含有最新更新的slave
3 应用差异的中继日志(relay log)到其他的slave
4 应用从master保存的二进制日志事件(binlog events)
5 提升一个slave为新的master
6 使其他的slave连接新的master进行复制
(1)创建一主两从集群
①master配置
master配置:
清理数据
[root@server1 ~]# cd /data/mysql
[root@server1 mysql]# rm -fr *修改配置
[root@server1 mysql]# vim /etc/my.cnf
server_id=1
gtid_mode=ON
enforce_gtid_consistency=ON
log_slave_updates=ON
log_bin=binlog初始化
[root@server1 mysql]# mysqld --initialize --user=mysql启动服务
[root@server1 mysql]# /etc/init.d/mysqld start配置master
[root@server1 mysql]# mysql -p
mysql> alter user root@localhost identified by 'westos';
Query OK, 0 rows affected (0.01 sec)mysql> grant replication slave on *.* to repl@'%' identified by 'westos';
Query OK, 0 rows affected, 1 warning (0.01 sec)
②slave配置
slave配置:
[root@server2 ~]# cd /data/mysql/
[root@server2 mysql]# rm -fr *[root@server2 mysql]# vim /etc/my.cnf
server_id=2
gtid_mode=ON
enforce_gtid_consistency=ON
log_slave_updates=ON
log_bin=binlog[root@server2 mysql]# mysqld --initialize --user=mysql[root@server2 mysql]# /etc/init.d/mysqld start[root@server2 mysql]# mysql -p
mysql> alter user root@localhost identified by 'westos';
Query OK, 0 rows affected (0.01 sec)mysql> change master to master_host='192.168.56.11', master_user='repl', master_password='westos', master_auto_position=1;
Query OK, 0 rows affected, 2 warnings (0.02 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 eventMaster_Host: 192.168.56.11Master_User: replMaster_Port: 3306Connect_Retry: 60Master_Log_File: binlog.000002Read_Master_Log_Pos: 681Relay_Log_File: server2-relay-bin.000002Relay_Log_Pos: 888Relay_Master_Log_File: binlog.000002Slave_IO_Running: YesSlave_SQL_Running: Yesserver3节点的配置以此类推
③测试
master端新建内容,slave端同步
master:
mysql> create database westos;
Query OK, 1 row affected (0.00 sec)mysql> use westos
Database changedmysql> create table user_tb (-> username varchar(25) not null,-> password varchar(50) not null);
Query OK, 0 rows affected (0.01 sec)mysql> insert into user_tb values ('user1','111');
Query OK, 1 row affected (0.03 sec)mysql> insert into user_tb values ('user2','222');
Query OK, 1 row affected (0.00 sec)
slave:
mysql> select * from westos.user_tb;
+----------+----------+
| username | password |
+----------+----------+
| user1 | 111 |
| user2 | 222 |
+----------+----------+
2 rows in set (0.00 sec)
(2)MHA环境部署
①四台主机安装软件
• Manager 工具包主要包括以下几个工具:masterha_check_ssh // 检查 MHA 的 SSH 配置状况masterha_check_repl // 检查 MySQL 复制状况masterha_manger //启动 MHAmasterha_check_status // 检测当前 MHA 运行状态masterha_master_monitor //检测 master 是否宕机masterha_master_switch // 控制故障转移(自动或者手动)masterha_conf_host // 添加或删除配置的 server 信息• Node 工具包(由 MHA Manager 的脚本触发,无需人为操作)主要包括以下几个工具:save_binary_logs // 保存和复制 master 的二进制日志apply_diff_relay_logs // 识别差异的中继日志事件并将其差异的事件应用于其他的 slavefilter_mysqlbinlog // 去除不必要的 ROLLBACK 事件( MHA 已不再使用这个工具)purge_relay_logs // 清除中继日志(不会阻塞 SQL 线程)
在server4主机,关闭mysqlrouter服务。安装MHA高可用的masterrpm包及其依赖性。并将MHAnode节点rpm包复制至其他三台主机。在其他三台主机上安装rpm包。
server4上安装管理端软件
[root@server4 ~]# cd MHA-7/
[root@server4 MHA-7]# yum install -y *.rpm管理端配置ssh免密
[root@server4 MHA-7]# ssh-keygen
[root@server4 MHA-7]# ssh-copy-id server4把密钥复制到各节点
[root@server4 ~]# scp -r .ssh/ server1:
[root@server4 ~]# scp -r .ssh/ server2:
[root@server4 ~]# scp -r .ssh/ server3:复制客户端软件
[root@server4 MHA-7]# scp mha4mysql-node-0.58-0.el7.centos.noarch.rpm server1:
[root@server4 MHA-7]# scp mha4mysql-node-0.58-0.el7.centos.noarch.rpm server2:
[root@server4 MHA-7]# scp mha4mysql-node-0.58-0.el7.centos.noarch.rpm server3:server1、server2、server3上安装客户端软件
[root@server1 ~]# yum install -y mha4mysql-node-0.58-0.el7.centos.noarch.rpm
②MHA环境配置
在server4主机建立高可用目录,编辑配置文件。
MHA配置
[root@server4 ~]# mkdir /etc/masterha ##建立高可用目录
[root@server4 ~]# vim /etc/masterha/app1.cnf
[server default]
user=root #mysql管理员
password=westos #mysql管理员密码
ssh_user=root #ssh免密用户
repl_user=repl #mysql主从复制用户
repl_password=westos
master_binlog_dir=/data/mysql #mysql数据库目录
remote_workdir=/tmp #远端mysql在发生切换时binlog的保存位置
secondary_check_script= masterha_secondary_check -s 192.168.76.12 -s 192.168.76.13
ping_interval=3 #发送ping包的时间间隔,默认是3秒,尝试三次没有回应的时候自动进行failover
# master_ip_failover_script= /script/masterha/master_ip_failover
# shutdown_script= /script/masterha/power_manager
# report_script= /script/masterha/send_report
# master_ip_online_change_script= /script/masterha/master_ip_online_change
manager_workdir=/etc/masterha
manager_log=/etc/masterha/manager.log[server1]
hostname=192.168.76.11
candidate_master=1
check_repl_delay=0[server2]
hostname=192.168.76.12
candidate_master=1 #指定failover时此slave会接管master,即使数据不是最新的。
check_repl_delay=0[server3]
hostname=192.168.76.13
no_master=1 #始终不作为master
在server1主机进入数据库,设置mysql管理员权限,slave节点会自动同步
在server1master上设置mysql管理员权限,slave节点会自动同步
mysql> grant all on *.* to root@'%' identified by 'westos';
Query OK, 0 rows affected, 1 warning (0.00 sec)
③测试
检测各节点ssh免密连接
[root@server4 ~]# masterha_check_ssh --conf=/etc/masterha/app1.cnf
检测主从复制集群状态
[root@server4 ~]# masterha_check_repl --conf=/etc/masterha/app1.cnf
(3)故障切换
MHA 的故障切换过程,共包括以下的步骤:1. 配置文件检查阶段,这个阶段会检查整个集群配置文件配置2. 宕机的 master 处理,这个阶段包括虚拟 ip 摘除操作,主机关机操作3. 复制 dead maste 和最新 slave 相差的 relay log ,并保存到 MHA Manger 具体的目录下4. 识别含有最新更新的 slave5. 应用从 master 保存的二进制日志事件( binlog events )6. 提升一个 slave 为新的 master 进行复制7. 使其他的 slave 连接新的 master 进行复制
MHA 在线切换的大概过程:1. 检测复制设置和确定当前主服务器2. 确定新的主服务器3. 阻塞写入到当前主服务器4. 等待所有从服务器赶上复制5. 授予写入到新的主服务器6. 重新设置从服务器
为了保证数据完全一致性,在最快的时间内完成切换, MHA 的在线切换必须满足以下条件才会切换成功,否则会切换失败。1. 所有 slave 的 IO 线程都在运行2. 所有 slave 的 SQL 线程都在运行3. 所有的 show slave status 的输出中 Seconds_Behind_Master 参数小于或者等于running_updates_limit 秒,如果在切换过程中不指定 running_updates_limit, 那么默认情况下 running_updates_limit 为 1 秒。4. 在 master 端,通过 show processlist 输出,没有一个更新花费的时间大于 running_updates_limit秒
①手动切换
master正常
手动切换(master正常)
[root@server4 ~]# masterha_master_switch --conf=/etc/masterha/app1.cnf --master_state=alive --new_master_host=192.168.56.12 --new_master_port=3306 --orig_master_is_new_slave --running_updates_limit=10000
master故障
手动切换(master故障)
手动停止master节点上的msql服务
[root@server2 ~]# /etc/init.d/mysqld stop[root@server4 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故障节点需要手动修复,重新加入主从集群
[root@server2 ~]# /etc/init.d/mysqld start
[root@server2 ~]# mysql -pwestosmysql> change master to master_host='192.168.56.11', master_user='repl', master_password='westos', master_auto_position=1;
Query OK, 0 rows affected, 2 warnings (0.02 sec)mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
②自动切换
自动切换
故障切换后会生成lock文件,需要手动删除
[root@server4 masterha]# rm -f app1.failover.complete启动manger程序,并打入后台运行,完成切换任务后进程会自动退出
[root@server4 masterha]# masterha_manager --conf=/etc/masterha/app1.cnf &在进行自动切换之前,必须保证主从集群正常,一主两从加入故障切换脚本,需要有可执行权限[root@server4 ~]# mv master_ip_failover master_ip_online_change /usr/local/bin/
[root@server4 ~]# chmod +x /usr/local/bin/master_ip_*
[root@server4 ~]# ll /usr/local/bin/
total 8
-rwxr-xr-x 1 root root 2158 Feb 26 11:20 master_ip_failover
-rwxr-xr-x 1 root root 3815 Feb 26 11:21 master_ip_online_change修改故障切换脚本中的vip
[root@server4 ~]# vim /usr/local/bin/master_ip_failover
[root@server4 ~]# vim /usr/local/bin/master_ip_online_change
...
my $vip = '192.168.76.100/24';
...修改配置文件加上故障切换脚本的访问路径
[root@server4 ~]# vim /etc/masterha/app1.cnf
[server default]
user=root
password=westos
ssh_user=root
repl_user=repl
repl_password=westos
master_binlog_dir=/data/mysql
remote_workdir=/tmp
secondary_check_script= masterha_secondary_check -s 192.168.56.12 -s 192.168.56.13
ping_interval=3
master_ip_failover_script= /usr/local/bin/master_ip_failover
# shutdown_script= /script/masterha/power_manager
# report_script= /script/masterha/send_report
master_ip_online_change_script= /usr/local/bin/master_ip_online_change
manager_workdir=/etc/masterha
manager_log=/etc/masterha/manager.log[server1]
hostname=192.168.56.11
candidate_master=1
check_repl_delay=0[server2]
hostname=192.168.56.12
candidate_master=1
check_repl_delay=0[server3]
hostname=192.168.56.13
no_master=1测试
给master端添加一个vip,然后停掉master服务
[root@server1 ~]# ip a a 192.168.76.100/24 dev eth0
[root@server1 ~]# /etc/init.d/mysqld stop
Shutting down MySQL............ SUCCESS!server4的日志里显示server1master挂掉,server2变为master
[root@server4 masterha]# ls
app1.cnf app1.failover.complete manager.log
[root@server4 masterha]# cat manager.log
...
From:
192.168.76.11(192.168.76.11:3306) (current master)+--192.168.76.12(192.168.76.12:3306)+--192.168.76.13(192.168.76.13:3306)To:
192.168.76.12(192.168.76.12:3306) (new master)+--192.168.76.13(192.168.76.13:3306)
...VIP被加到新的master上
[root@server2 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope hostvalid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000link/ether 00:0c:29:61:99:04 brd ff:ff:ff:ff:ff:ffinet 192.168.76.12/24 brd 192.168.76.255 scope global eth0valid_lft forever preferred_lft foreverinet 192.168.76.100/24 scope global secondary eth0valid_lft forever preferred_lft foreverinet6 fe80::20c:29ff:fe61:9904/64 scope linkvalid_lft forever preferred_lft forever