一.安装mysql
yum install wget
wget http://repo.mysql.com/mysql57-community-release-el7-8.noarch.rpm
yum localinstall mysql57-community-release-el7-8.noarch.rpm
yum install mysql-server
启动服务
service mysqld start
刚刚安装好的mysql其实会有默认的数据库密码
cat /var/log/mysqld.log |grep password
获取密码之后,进入数据库
mysql -uroot -p
修改密码
set password = password('你要设置的密码')
在设置密码的过程很中有可能遇到一下设置密码错误的问题
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
遇到这种问题的原因是mysql会对你设置的密码有些要求,类似于要多少位啊,大小写啊这些。这个其实与validate_password_policy的值有关。详细的设置请参考(https://www.cnblogs.com/ivict...)
设置好密码之后就可以开始神奇的mysql之旅啦!
二:了解mysql复制,是实现高可用的基础
复制解决了什么问题
- 实现了在不同服务器上的数据分布
- 实现了数据读取的负载均衡
- 增强了数据安全性
- 实现了数据库高可用和故障切换
- 实现了数据库的在线升级
在了解mysql复制之前,我们还是先了解下什么叫做二进制日志,他是mysql复制的关键
- 二进制日志是存储在mysql的服务层中,它记录了所有对mysql数据库的修改事件,包括对数据库的增删改查事件和对表结构的修改事件
记录二进制日志有几种模式
我们先了解一下如何确定二进制日志的模式
show variables like 'binlog_format';
该命令可以设置当前mysql使用的二进制日志模式
set session binlog_format='statement';
该命令是设置mysql的模式,该命令是把二进制日志设置成了statement模式
插曲一
我在查找我的二进制日志的时候发现 ERROR 1381 (HY000): You are not using binary logging
目测是我的二进制日志的设置没有开启,需要找到mysql.ini文件
在mysqld配置项下面加上log_bin=mysql_bin以及server_id = 1(举个例子,在集群中该值不能重复)
一开始我就是只设置了log_bin参数,没有设置server_id的参数,搞了半天还不行,渣渣伤不起
插曲二
找不到mysql的配置文件,数据保存的文件,日志文件等,如果是通过上述所说的步骤安装的话,前面提到的文件都会默认的在以下路径中
/etc/my.cnf #mysql的主配置文件
/var/lib/mysql #mysql数据库的数据库文件存放位置
/var/log #mysql数据库的日志输出存放位置
二进制日志记录模式的类型以及优缺点
- satement
- row
- 它会记录下所有的行,比如
update t set name = 'mm' where id in (2,3,4,5)
。 他会在日志中记录update t set name = 'mm' where id = 2
..... - 这个模式先会让日志文件变得很大,所有会有额外的参数帮忙来解决这个问题
binlog_row_image = [FULL|MINIMAL|NOBLOB]
- 一张表有20列,如果只修改一个列的数据,
FULL
参数表示还是会记录所有列的数据 - 一张表有20列,如果只修改一个列的数据,
MINIMAL
参数表示只会记录修改列的数据(建议) - 一张表有20列,如果只修改了一个不是blob属性列的数据,
NOBLOB
参数表示会记录所有除了blob属性列之外的所有数据
- mixed
- 这种模式是混合的statement和row类型,储蓄的方式完全靠SQL自身去确定
mysql复制的原理
- 主数据库将变更写入二进制日志中
- 从数据库将读取主数据库的二进制日志并写入到relay_log(中继日志)中
- 在从数据库上将重现relay_log中的日志
- 基于SQL段(statement)的日志是在从库上重新执行记录的SQL语句
- 基于行(row)的日志则是在从库上直接应用对数据库行的修改
mysql复制之基于日志点复制
步骤:
在主数据库上建立复制账号
CREATE USER 'repl' @ 'IP段' IDENTIFIED BY 'password';
对账号进行授权,使该账号可以有复制的权利
GRANT REPLICATION SLAVE ON *.* TO 'repl' @ 'IP 段 '
对主数据库进行配置,在my.cnf文件中(前面有介绍)
log_bin=mysql-bin
server_id=XXX
#这个值在整个集群中必须唯一
在从数据库中进行配置,也是在my.cnf文件中
log_bin=mysql-bin
server_id=XXX
#这个值在整个集群中必须唯一
relay_log=mysql-bin
#中继日志的名称
log_slave_update=on
#[可选]意思是,是否将中继日志的内容也存放在本机的二进制日志中,如果该从库也要对另外一个集群作为主库的话,这个参数必须打开
read_only = on
#[可选]
初始化从数据库的数据,其实就是数据备份,需要在主数据中执行一下命令
mysqldump --all-databases -uroot -p >all.sql
注:更多参数以后在补充
把备份好的数据库发送给从库所在的服务器上,如果主从的数据库数据已经一致,可以忽略这一步
scp all.sql(发送的文件) root@对方服务器:目标目录
在从库上启动复制链路
change master to master_host = 'master_host_ip',master_user = 'repl', master_password = 'xx', master_log_file = '主库的日志文件',master_log_pos='偏移量';
注意:
主库的日志文件名称和偏移量是在哪里找呢?可以在主库中使用
show master status;
开启slave
start slave;
查看slave状态
show slave status;
插曲:
我在启动slave的过程中,发现并没有连接成功,在show slave status
中看到一下错误
分析了一下会发现主数据的服务器并没有给3306开放对外的端口
firewall-cmd --list-port
#查看现在开放的端口有哪些
firewall-cmd --add-port=3306/tcp --permanent
#添加3306为开放的端口
firewall-cmd --reload
#重新刷新服务器开放的端口
mysql复制之基于GTID复制(版本>=5.6)
原理:
- 从库会告诉主库他已经执行完成的GTID值
- 主库会发送从库未执行事务的GTID值
- 这能保证同一个事务只在指定的从库执行一次
什么是GTID
- GTID即全局事务ID,其保证为每一个在主库提交的事务在复制集群中都可以生成一个唯一的ID。
步骤:
在主数据库上建立复制账号,该步骤和基于日志点复制是一样的。所以不多做介绍
在主数据库中的配置,在基于日志点配置的基础上加上了
gtid-mode = on
enforce-gtid-consistency=on
log-slave-updates=on
#mysql 5.7之后就不需要了
注意:在使用了enforce-gtid-consistency
参数之后会对mysql有一些限制
- 不能使用create table ....select 来创建表
- 在事务中使用create temporary table建立临时表时,不能使用关联更新事务表和非事务表(我没试过,看文档时这么写的)
在从库中的配置,同样也是在基于日志点的复制配置基础上
gtid-mode = on
enforce-gtid-consistency=on
log-slave-updates=on
#mysql 5.7之后就不需要了
read_only=read
#[建议]
master_info_repository=table
#[建议]
relay_log_info_repository=table
#[建议]
最后的命令我们完成之后再补充
初始化从数据库,该过程和基于日志点的复制语句是一样的
启动基于GTID的复制
CHANGE MASTER TO MASTER_HOST=master_host_ip, MASTER_USER='repl', MASTER_PASSWORD='13659787422tt', MASTER_AUTO_POSITION=1;
剩下的步骤是和基于日志点的步骤是一样的
GTID 的优缺点
- 优点:
- 可以很方便地进行故障转移
- 从库不会丢失主库的任何数据
- 缺点:
- 故障处理比较复杂
- 对执行的SQL有一些限制
三.mysql复制性能优化
影响主从延迟的因素
- 主库写入二进制日志的时间(解决办法:控制主库的事务大小,分割大事务)
- 二进制日志传输时间,主要是二进制文件的大小(解决办法:二进制文件格式可以设为
mixed
,或者使用row
的话,要记得设置set binlog_raw_image=minimal
) -
默认情况下从库只有一个SQL线程,主库上并发的修改在从库上变成了串行(解决办法:使用多线程复制,以下是启动多线程的步骤,适用于版本>=5.7)
-
stop slave
(停止链路复制) -
set global slave_parallel_type='logical_clock'
(确认以逻辑时钟方式启动多线程复制,我也暂时不同什么叫做逻辑时钟,以后再去讨论) -
set global slave_parallel_workers = 4
(确认并发处理的线程数) -
start slave
(开启链路复制)
-
四.利用MHA工具实现mysql高可用
MHA主从切换的过程
- 尝试从出现故障的主数据库保存二进制文件
- 从多个备选从服务器中选举出新的备选主服务器
- 在备选主服务器和其他从服务器之间同步差异二进制数据
- 应用从原来主数据库服务器上保存二进制日志,但是在这一步如果出现了主键的重复,将会导致故障转移的出错
- 提升备选主数据库服务器为新的数据库服务器
- 迁移集群中的其他从数据库服务器作为新的主数据库的从服务器
配置步骤
- 首先说明的是MHA工具是可以支持基于GTID的复制和基于日志点的复制。在本次的练习中,我们也是基于GTID。
配置集群内所有主机的SSH免认证登陆
ssh-keygen
使用 ssh-keygen 命令之后,可以一直按回车键,当然,也可以根据个人需求来输入相关内容。最终,会生成 id_rsa 和 id_rsa.pub 两个文件。
然后,把本地的公钥添加到对方服务器的 /.ssh/authorized_keys 文件里。
ssh [email protected] 'mkdir -p .ssh && cat >> ~/.ssh/authorized_keys' < ~/.ssh/id_rsa.pub
这样设置之后,每次登录都不再需要输入密码了。
其他问题
可能因为某些操作之后,突然发现登录需要输入密码,但登录配置并没有任何修改的,通过检查发现 .ssh 目录的权限问题。最后,只需要重新修改权限就解决了。
chmod -R 700 .ssh
安装MHA-node软件包和MHA-manager软件包
安装MHA的依赖包,
在所有的服务器上
yum install perl-DBD-MySQL ncftp
在作为监控的服务器上,要需额外安装
yum -y install perl_Config_Tiny.noarch perl-Time-HiRes.x86_64 perl-Parallel-ForkManager perl-Log-Dispatch-perl.noarch perl-DBD-MySQL ncftp
注意:我是通过yum安装的,但是在yum的仓库并没有所有的安装包。其实,CentOS还有一个源叫做 EPEL (Extra Packages for Enterprise Linux),为“红帽系”的操作系统提供额外的软件包,适用于RHEL、CentOS等,里面有1万多个软件,强烈建议安装。命令如下
yum install epel-release
yum update -y
安装好之后,再重新执行yum安装之前没有安装好的依赖包
建立主从复制集群
配置MHA管理节点,创建好一个专门存放MHA配置的文件夹,只需要在监管的服务器上设置即可
mkdir -p /etc/mha
#我实践过程中mha配置文件存放的位置
mkdir -p /home/mysql_mha
#mha工作目录,例如主库宕机了,用来存放主库的二进制文件
添加MHA所用到的账号,可以直接在主库上去添加,因为这样就可以同时同步到其他数据库上
grant all privileges on *.* to mha@'%' identified by '13659787422tt';
在MHA配置文件中进行配置
[server_default]
user = mha
password = 13659787422tt
manager_workdir = /home/mysql_mha
manager_log = /home/mysql_mha/manager.log
remote_workdir = /home/mysql_mha
#需要在集群中的其他节点设置一样路径的目录
ssh_user = root
#ssh免认证的用户,前面有设置好了,忘记了可以回头看看哦
repl_user = repl
#用于数据库复制的账号和密码
repl_password = 13659787422tt
ping_interval = 1
#是用于监控服务器对master服务器检测是否正常的事件间隔,这里设置了1秒
master_binlog_dir = /var/lib/mysql
#告诉监控服务器要去主数据库哪里获取二进制文件
secondary_check_script =
#[可选]在安装好MHA时已经下载好的脚本,可以用于监控服务器多方面对master服务器进行连接检测,避免了一些网络的抖动引起主从切换
[server 1]
hostname = 192.168.239.129
candidate_master = 1
#该服务器是否用于作为主数据进行选举
[server 2]...
#集群中有多少的服务器就相应设置多少
no_master = 1
#不参与主数据的选举
使用masterha_check_ssh和masterha_check_repl对配置进行检验
启动并检验MHA
masterha_check_ssh --conf=/etc/mha/mha.cnf
出现以下的显示,证明ssh检测成功
masterha_check_repl --conf=/etc/mha/mha.cnf
出现以下的显示,证明MHA的配置成功
现在就可以启动MHA了
nohup masterha_manager --conf=/etc/mha/mha.cnf
#nohup是可以让程序后台运行
查看MHA的进程是否已经启动
ps -ef |grep masterha_manager
因为MHA是不能为主库创建虚拟IP的,所以需要收到到主库去创建虚拟IP,在之后的迁移中,虚拟IP就会主动得转移到新的主库中
因为我现在的主库是192.168.239.129,用以下命令创建虚拟IP
ifconfig ens33:1 192.168.239.90/24
ens33是对应的网卡(我理解的),根据自己的机器做相应的改动
配置到这里MHA算是配置完成了。(未完)