近期需要在某单位部署ETL系统,该系统必须要依赖于MySQL库,该单位没有现成的库可以使用,故需要现场部署。
按照该ETL手册中的需要部署MySQL 5.7版本。
【配置半同步需要5.7.17以上,这里以5.7.28为例】
1.安装前准备
1.1 下载对应版本的MySQL
从
官网
下载适用于Linux的Mysql安装包,
因为现场环境为centos7,故我选择RH版本的MySQL,其他版本的MySQL可以选择对应的包。
下载 Compressed TAR Archive 版本的压缩版本安装。
1.2 检查是否已经安装过mysql
执行命令查看是否系统内安装过MySQL的rpm包
[root@localhost /]# rpm -qa | grep mysql
从执行结果,可以看出我们已经安装了mysql-libs-5.1.73-5.el6_6.x86_64,执行删除命令
[root@localhost /]# rpm -e --nodeps mysql-libs-5.1.73-5.el6_6.x86_64
再次执行命令发现已经成功删除
检查依赖的包是否安装
[root@localhost bin]# rpm -qa|grep libaio
[root@localhost bin]#
--安装依赖
[root@localhost bin]# yum install libaio -y
[root@localhost bin]# yum install numactl -y
查询所有Mysql对应的文件夹
[root@localhost /]# whereis mysql
mysql: /usr/bin/mysql /usr/include/mysql
执行命令后删除对应的文件夹,避免后续初始化失败
[root@localhost /]# rm -rf /usr/bin/mysql /usr/include/mysql /data/mysql /data/mysql/mysql
检查mysql用户组和用户是否存在,如果没有,则创建
[root@localhost /]# cat /etc/group | grep mysql
[root@localhost /]# cat /etc/passwd |grep mysql
[root@localhost /]# groupadd mysql
[root@localhost /]# useradd -r -g mysql mysql
[root@localhost /]# passwd mysql
之后将文件上传至服务器
1.3 设置服务器名并配置hosts
设置服务器名
hostnamectl set-hostname bdi01
hostnamectl set-hostname bdi02
hostnamectl set-hostname bdi03
配置hosts
[root@bdi01 sql]$ vim /etc/hosts
2. 安装MySQL程序
因该服务器分给其他目录的空间较少,故决定将MySQL完全部署在/home目录下
2.1 前期操作
执行下列命令,解压MySQL程序并改名;创建data文件夹
[mysql@bdi01 ~]$ pwd
/home/mysql
[mysql@bdi01 ~]$ tar -zxvf mysql-5.7.28-el7-x86_64.tar.gz
[mysql@bdi01 ~]$ ll
总用量 792660
drwxrwxr-x. 9 mysql mysql 129 9月 27 17:21 mysql-5.7.28-el7-x86_64
-rw-r--r--. 1 mysql mysql 811676432 9月 22 10:26 mysql-5.7.28-el7-x86_64.tar.gz
[mysql@bdi01 ~]$ mv mysql-5.7.28-el7-x86_64 mysql-5.7.28
[mysql@bdi01 ~]$ mkdir data
编辑配置文件 /etc/my.cnf
注意: 其中的server_id=每台服务器不能一样
[root@bdi01 ~]$ vim /etc/my.cnf
[mysqld]
datadir=/home/mysql/data
basedir=/home/mysql/mysql-5.7.28
socket=/home/mysql/var/lib/mysql/mysql.sock
user=mysql
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
log_bin_trust_function_creators=1
lower_case_table_names=1
sql_mode=
transaction_isolation=READ-COMMITTED
binlog_format=mixed
max_allowed_packet=104857600
server_id=1
log-bin=mysql-bin
binlog-ignore-db=mysql
log_slave_updates=1
character_set_server=utf8
collation_server=utf8_general_ci
[mysqld_safe]
log-error=/home/mysql/var/log/mysqld.log
pid-file=/home/mysql/var/run/mysqld/mysqld.pid
[client]
port=3306
socket=/home/mysql/var/lib/mysql/mysql.sock
创建其中的尚未建立的文件夹,使用root权限再次赋权
[root@bdi01 ~]$ mkdir -p /home/mysql/var/log/
[root@bdi01 ~]$ mkdir -p /home/mysql/var/run/mysqld/
[root@bdi01 ~]$ mkdir -p /home/mysql/var/lib/mysql/
[root@bdi01 ~]$ chown -R mysql.mysql /home/mysql/
2.2 初始化数据库
[root@bdi01 ~]$ su - mysql
[mysql@bdi01 ~]$ cd mysql-5.7.28/bin/
[mysql@bdi01 ~]$ ./mysqld --initialize --user=mysql --basedir=/home/mysql/mysql-5.7.28 --datadir=/home/mysql/data
...
2020-09-22T06:20:39.503793Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
2020-09-22T06:20:39.925529Z 0 [Warning] InnoDB: New log files created, LSN=45790
2020-09-22T06:20:40.303039Z 0 [Warning] InnoDB: Creating foreign key constraint system tables.
2020-09-22T06:20:40.311645Z 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: bca278ab-fc9b-11ea-8dc5-00505689440b.
2020-09-22T06:20:40.312738Z 0 [Warning] Gtid table is not ready to be used. Table 'mysql.gtid_executed' cannot be opened.
2020-09-22T06:20:41.007238Z 0 [Warning] CA certificate ca.pem is self signed.
2020-09-22T06:20:41.227047Z 1 [Note] A temporary password is generated for root@localhost: llJ;MvAG>5;F
出现上述打印文字即说明初始化成功,需要记住末尾的 root@localhost: llJ;MvAG>5;F 这是等会登陆MySQL的临时root密码
2.3登陆MySQL并进行配置
配置软连接后登陆数据库进行操作
[mysql@bdi01 ~]$ ln -s /home/mysql/mysql-5.7.28/support-files/mysql.server /etc/init.d/mysqld
[mysql@bdi01 ~]$ ln -s /home/mysql/mysql-5.7.28/bin/mysql /usr/bin/mysql
[mysql@bdi01 ~]$ service mysqld start
[mysql@bdi01 ~]$ mysql -uroot -pllJ;MvAG>5;F
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 24
Server version: 5.7.28 MySQL Community Server (GPL)
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
如果报错
[root@bdi02 ~]# service mysqld start
Starting MySQL.2020-10-13T07:31:51.997438Z mysqld_safe error: log-error set to '/home/mysql/var/log/mysqld.log', however file don't exists. Create writable for user 'mysql'.
ERROR! The server quit without updating PID file (/home/mysql/data/bdi02.pid).
可以在root下执行,一般可以解决
[root@bdi02 ~]# touch /home/mysql/var/log/mysqld.log
[root@bdi02 ~]# touch /home/mysql/data/bdi02.pid
[root@bdi02 ~]# chown -R mysql.mysql /home/mysql/
[root@bdi02 ~]# service mysqld start
Starting MySQL. SUCCESS!
到这一步MySQL算是基本完成安装了
接下来开始部分的配置工作
--修改root密码
mysql>set password for 'root'@'localhost'=password('你的密码');
mysql>flush privileges;
--临时赋予root任意ip访问权限
mysql>use mysql;
msyql>update user set user.Host='%' where user.User='root';
mysql>flush privileges;
--创建其他用户
mysql>CREATE USER '你的用户名'@'%' IDENTIFIED BY '你的密码';
mysql>flush privileges;
2.4 添加开机启动
1、赋予可执行权限
[root@localhost /]# chmod +x /etc/init.d/mysqld
2、添加服务
[root@localhost /]# chkconfig --add mysqld
3、显示服务列表
[root@localhost /]# chkconfig --list
3. 配置半同步复制
3.1 半同步复制概念
从MySQL 5.5开始,MySQL 以插件的形式支持半同步复制。如何理解半同步呢?首先我们来看看异步,全同步的概念
3.1.1异步复制(Asynchronous replication)
MySQL 默认的复制即是异步的,主库在执行完客户端提交的事务后会立即将结果返给给客户端,并不关心从库是否已经接收并处理,这样就会有一个问题,主如果crash掉了,此时主上已经提交的事务可能并没有传到从上,如果此时,强行将从提升为主,可能导致新主上的数据不完整。
3.1.2全同步复制(Fully synchronous replication)
指当主库执行完一个事务,所有的从库都执行了该事务才返回给客户端。因为需要等待所有从库执行完该事务才能返回,所以全同步复制的性能必然会收到严重的影响。
3.1.3半同步复制(Semisynchronous replication)
介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收到并写到relay log中才返回给客户端。相对于异步复制,半同步复制提高了数据的安全性,同时它也造成了一定程度的延迟,这个延迟最少是一个TCP/IP往返的时间。所以,半同步复制最好在低延时的网络中使用。
且在MySQL5.7版本之后,支持 Loss-Less半同步复制 新的半同步方案。
3.1.4旧版本半同步复制的潜在问题
上图是旧版本半同步复制原理图,客户端事务在存储引擎层提交后,在得到从库确认的过程中,主库宕机了,此时,可能的情况有两种
3.1.4.1. 事务还没发送到从库上
此时,客户端会收到事务提交失败的信息,客户端会重新提交该事务到新的主上,当宕机的主库重新启动后,以从库的身份重新加入到该主从结构中,会发现,该事务在从库中被提交了两次,一次是之前作为主的时候,一次是被新主同步过来的。
3.1.4.2. 事务已经发送到从库上
此时,从库已经收到并应用了该事务,但是客户端仍然会收到事务提交失败的信息,重新提交该事务到新的主上。
3.1.4.3.无数据丢失的半同步复制
针对上述潜在问题,MySQL 5.7引入了一种新的半同步方案:Loss-Less半同步复制。
针对上面这个图,“Waiting Slave dump”被调整到“Storage Commit”之前。
当然,之前的半同步方案同样支持,MySQL 5.7.2引入了一个新的参数进行控制-rpl_semi_sync_master_wait_point
rpl_semi_sync_master_wait_point有两种取值
AFTER_SYNC
这个即新的半同步方案,Waiting Slave dump在Storage Commit之前。
AFTER_COMMIT
老的半同步方案,如前图所示。
3.2 配置半同步复制
3.2.1 其他服务器节点上部署MySQL,并修改配置文件(前面修改了就不用了)
首先按照前面的步骤,在另外一台服务器上部署 MySQL(不详述)
vim /etc/my.cnf
#主从配置应该设置在[mysqld]下面(1主2从)
server_id=2
log-bin=mysql-bin
binlog-ignore-db=mysql
log_slave_updates=1
3.2.2 加载插件
之后开始加载插件
--主MySQL节点
mysql>install plugin rpl_semi_sync_master soname 'semisync_master.so';
--备MySQL节点
mysql>install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
--如果装错了可以
mysql>UNINSTALL PLUGIN rpl_semi_sync_master;
查看插件是否安装成功并启动
mysql>SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE '%semi%';
mysql>select * from mysql.plugin;
分别设置master(主),slave(备)的全局状态
mysql>set global rpl_semi_sync_master_enabled = 1;
mysql>set global rpl_semi_sync_slave_enabled = 1;
3.2.3 导入主库的数据
导出主库的数据
[root@bdi03 ~]# su - mysql
上一次登录:一 9月 28 11:59:58 CST 2020pts/2 上
[mysql@bdi03 ~]$ ./mysql-5.7.28/bin/mysqldump -uroot -p你的密码 --routines --single_transaction --master-data=2 --databases db_portal>db_portal.sql
然后scp数据到目标服务器
[mysql@bdi03 ~]$ scp db_* mysql@bdi01:/home/mysql/sql
mysql@bdi01's password:
在目标数据库上建库并导入数据
[mysql@bdi01 ~]$ mysql -uroot -p你的密码 -e'
[mysql@bdi01 ~]$ CREATE DATABASE db_portal
[mysql@bdi01 ~]$ DEFAULT CHARACTER SET utf8
[mysql@bdi01 ~]$ DEFAULT COLLATE utf8_general_ci;'
[mysql@bdi01 ~]$ mysql -uroot -p你的密码 db_portal<db_portal.sql
以上需要逐个操作主库上所有的表,请注意
然后查看你你操作的首个库的sql文件,获取日志文件名和log_pos的数据,一般查看前25行
[mysql@bdi01 sql]$ head -25 db_bpm.sql
-- MySQL dump 10.13 Distrib 5.7.28, for el7 (x86_64)
--
-- Host: localhost Database: db_bpm
-- ------------------------------------------------------
-- Server version 5.7.28-log
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Position to start replication or point-in-time recovery from
--
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=8830666;
--
-- Current Database: `db_bpm`
由上可知(后面需要用到):
MASTER_LOG_FILE='mysql-bin.000003'
MASTER_LOG_POS=8830666;
或可通过
mysql>show master status\G
得到上述
3.2.4 在从库(slave)配置主节点
在从库(slave)配置主节点,注意不推荐使用root权限进行同步,推荐创建相应的账户
--主从节点分别创建新用户
mysql>CREATE USER 'user_sync'@'%' IDENTIFIED BY '你的密码';
mysql>flush privileges;
mysql>GRANT ALL ON db_dp.* TO 'user_sync'@'%';
mysql>GRANT ALL ON db_portal.* TO 'user_sync'@'%';
mysql>GRANT ALL ON db_bpm.* TO 'user_sync'@'%';
mysql>flush privileges;
--主节点(master)授予用户REPLICATION SLAVE特权
GRANT REPLICATION SLAVE ON *.* TO 'user_sync'@'%';
flush privileges;
--配置主节点 里面的参数用到上一节从sql导出文件里取得的
mysql>change master to master_host='你的ip',
mysql>master_user='user_sync',
mysql>master_password='你的密码',
mysql>master_port=你的端口,
mysql>master_log_file='mysql-bin.000003',
mysql>master_log_pos=8830666;
3.2.5 启动主从同步
--设置从库只读
mysql>SET @@global.read_only = ON;
--重启从节点上的IO线程:如果没有重启,则默认还是异步复制,重启后,slave会在master上注册为半同步复制的slave角色。
mysql> STOP SLAVE IO_THREAD; START SLAVE IO_THREAD;
--执行以下命令就开始同步
mysql>start slave;
--在Slave端查看主从同步状态
mysql>show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 20.20.xxx.xxxx
Master_User: user_bdi
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000003
Read_Master_Log_Pos: 17572196
Relay_Log_File: bdi01-relay-bin.000002
Relay_Log_Pos: 8741850
Relay_Master_Log_File: mysql-bin.000003
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: 17572196
Relay_Log_Space: 8742057
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: 9ff5e8a6-fca0-11ea-bb37-00505689440b
Master_Info_File: /home/mysql/data/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
1 row in set (0.00 sec)
ERROR:
No query specified
--出错跳过
mysql>stop slave;set global sql_slave_skip_counter=1;start slave;
如果确认 : Slave_IO_Running: Yes Slave_SQL_Running: Yes
这两个的值都为Yes,即为同步成功
3.2.6 Master主节点上查看是否启用了半同步
mysql> show global status like 'rpl%';
现在半同步已经正常工作了,主要看Rpl_semi_sync_master_clients是否不为0,Rpl_semi_sync_master_status是否为ON。如果Rpl_semi_sync_master_status为OFF,说明出现了网络延迟或Slave IO线程延迟。
Rpl_semi_sync_master_clients的数值即为从节点的值,配置两个从节点的情况如下:
3.2.5 测试同步效果
在master端(主)建库和建表:
CREATE DATABASE db_test
DEFAULT CHARACTER SET utf8
DEFAULT COLLATE utf8_general_ci;
CREATE TABLE IF NOT EXISTS `tb_test01`(
`runoob_id` INT UNSIGNED AUTO_INCREMENT,
`runoob_title` VARCHAR(100) NOT NULL,
`runoob_author` VARCHAR(40) NOT NULL,
`submission_date` DATE,
PRIMARY KEY ( `runoob_id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
查看同步效果,如成功同步即为成功 ~
【参考文章】