MySQL(4)

文章目录

  • 一、MySQL的主从复制
    • 主从复制原理
    • 【实战】MySQL主从复制
    • 主从复制基本故障处理
      • 处理方法一
      • 处理方法二
      • 处理方法三
    • 延时从库
    • 半同步复制
    • 过滤复制
  • 二、MHA高可用架构
    • 工作流程
    • MHA工具介绍
    • MHA实验环境
    • 基于GTID的主从复制
    • 部署MHA

一、MySQL的主从复制

主从复制原理

  • 复制是MySQL的一项功能,允许服务器将更改从一个实例复制到另一个实例.
    • 主服务器将所有数据和结构更改记录到二进制日志中.
    • 从属服务器从主服务器请求该二进制日志并在本地应用其内容.
    • IO线程:请求主库,获取上一次执行过程的新的事件,并存放到relaylog
    • SQL线程:从relaylog中将sql语句翻译给从库执行
  • 主从复制的前提
    • 两台或两台以上的数据库实例
    • 主库要开启二进制日志
    • 主库要有复制用户
    • 主库的server_id和从库不同
    • 从库需要在开启复制功能前,要获取到主库之前的数据(主库备份,并且记录binlog当时位置)
    • 从库在第一次开启主从复制时,必须获知主库:ip、port、user、password、logfile,pos
    • 从库要开启相关线程:IO、SQL
    • 从库需要记录复制相关用户信息,还应该记录到上次已经从主库请求到哪个二进制日志
    • 从库请求过来的binlog,首先要存下来,并且执行binlog,执行过的信息保存下来
  • 主从复制涉及到的文件和线程
    • 主库
      • 主库binlog:记录主库发生过的修改事件
      • dump thread:给从库传送(TP)二进制日志线程
    • 从库:
      • relay-log(中继日志):存储所有主库TP过来的binlog事件
      • master.info:存储复制用户信息,上次请求到主库binlog位置点
      • IO thread:接收主库发来的binlog日志,也是从库请求主库的线程
      • SQL thread:执行主库TP过来的日志
  • 原理
    • 通过change master to 语句告诉从库主库的ip、port、password、file、pos
    • 从库通过start slave命令开启复制必要的IO线程和SQL线程
    • 从库通过IO线程拿着change master to 用户密码相关信息,连接主库,验证合法性
    • 从库连接成功后,会根据binlog的pos问主库,有没有比这个更新的
    • 主库接收到从库请求后,比较一下binlog信息,如果有就将最新数据通过dump线程给从库IO线程
    • 从库通过IO线程接收到主库发来的binlog事件,存储到TCP/IP缓存中,并返回ACK更新master.info
    • 将TCP/IP缓存中的内容存到relay-log中
    • SQL线程读取relay-log.info,读取到上次已经执行过的relay-log位置点,继续执行后续的relay-log日志,执行完成后,更新relay-log.info
      MySQL(4)_第1张图片

【实战】MySQL主从复制

将实例搭在两个机器上

  • 主库操作
    • 修改配置文件
vim /etc/my.cnf
[mysqld]
server_id=1
# 主库server-id为1,从库不等于1
log_bin=mysql-bin
# 开启binlog日志
  • 导出一份全备数据给从库
mysqldump -uroot -p123456 -A -R -triggers --master-data=2 --single-transaction > /tmp/full.sql
scp /tmp/full.sql [email protected]:/tmp
  • 创建主从复制用户
mysql -uroot -p123456
mysql> grant replication slave on *.* to slave@'192.168.64.%' identified by '123456';
# 创建slave用户
  • 从库操作
    • 修改配置文件导入全备数据
vim /etc/my.cnf
[mysqld]
server_id=5
# 主库server-id为1,从库不等于1
# 从库不需要开二进制日志

systemctl restart mysqld

mysql> source /tmp/full.sql;
mysql> show master status;
# 记录主库binlog及位置点,在主库上看,或者去全备日志里面grep -i ‘change master to’看

mysql -uroot -p123456
mysql> change master to
master_host='192.168.64.129',
master_user='slave',
master_password='123456',
master_log_file='mysql-bin.000001',
master_log_pos=120;
#master_auto_position=1; 自动找位点

mysql> start slave;
mysql> show slave status;
需要保证io线程和sql线程同时为yes才表示主从复制开启成功
如果是mysql装好之后直接克隆过来的,会出现uuid一致的情况
uuidgen命令生成uuid,替换掉原来文件中的uuid即可

主从复制基本故障处理

  • IO线程报错
    • user passoword ip port
    • 网络:不同,延迟高,防火墙
    • 没有跳过反向解析[mysqld]里面加入skip-name-resolve
  • 请求binlog
    • binlog不存在或者损坏
  • 更新relay-log和master.info
    • SQL线程
    • relay-log出现问题
    • 从库做写入了,一般从库只用来读,不会在上面进行写操作,因为主库同步不了从库上面的内容
  • 操作对象已经存在(create)
  • 操作对象不存在(insert update delete drop truncate alter)
  • 约束问题、数据类型、列属性

处理方法一

处理SQL线程出现的问题

mysql> stop slave;
# 临时停止同步
mysql> set global sql_slave_skip_counter=1;
# 将同步指针向下移动一个(可重复操作)
mysql> start slave;
# 开启同步

处理方法二

vim /etc/my.cnf
# 编辑配置文件
[mysqld]
slave-skip-errors=1032,1062,1007
# 跳过的错误代码

但是以上操作都是有风险存在的

处理方法三

限制其不能修改从库

set gobal read_only=1
# 在命令行临时设置
vim /etc/my.cnf
# 编辑配置文件
[mysqld]
read_only=1

延时从库

  • 普通的主从复制可能存在不足
    • 逻辑损坏怎么办?
    • 不能保证主库的操作,从库一定能做
    • 高可用?自动failover?
    • 过滤复制
  • 企业中一般会延时3-6个小时
  • 延时从库配置方法
mysql> stop slave;
# 临时停止同步
mysql> CHANGE MASTER TO MASTER_DELAY = 60;
# 设置延时为60秒
mysql> start slave;
mysql> show slave status\G;
SQL_Delay: 60
# 查看状态

mysql> stop slave;
mysql> CHANGE MASTER TO MASTER_DELAY = 0;
mysql> start slave;
  • 恢复数据
    • 停止主从
    • 导出从库数据
    • 主库导入数据

半同步复制

从MySQL5.5开始,支持半同步复制。之前版本的MySQL Replication都是异步(asynchronous)的,主库在执行完一些事务后,是不会关注备库的进度的。如果备库不幸落后,而更不幸的是主库此时又出现Crash(例如宕机),这时备库中的数据就是不完整的。简而言之,在主库发生故障的时候,我们无法使用备库来继续提供数据一致的服务了。

半同步复制(Semi synchronous Replication)则一定程度上保证提交的事务已经传给了至少一个备库。

出发点是保证主从数据一致性问题,安全的考虑

  • 半同步复制开启方法
    • 安装(主库)
mysql -uroot -p123456
mysql> show global variables like 'have_dynamic_loading';
# 查看是否有动态支持
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME'semisync_master.so';
# 安装自带插件
mysql> SET GLOBAL rpl_semi_sync_master_enabled = 1;
# 启动插件
mysql> SET GLOBAL rpl_semi_sync_master_timeout = 1000;
# 设置超时

vim /etc/my.cnf
[mysqld]
rpl_semi_sync_master_enabled = 1
rpl_semi_sync_master_timeout = 1000

mysql> show global variables like 'repl%';
mysql> show global status like 'rpl_semi%';
# 检查安装
  • 安装(从库)
mysql -uroot -p123456
mysql> show global variables like 'have_dynamic_loading';
# 查看是否有动态支持
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME'semisync_master.so';
# 安装自带插件
mysql> SET GLOBAL rpl_semi_sync_master_enabled = 1;
# 启动插件
mysql> stop slave io_thread;
mysql> start slave io_thread;
# 重启io线程使其生效

vim /etc/my.cnf
[mysqld]
rpl_semi_sync_master_enabled = 1
  • 注:相关参数说明
    • rpl_semi_sync_master_timeout=milliseconds
      • 设置此参数值(ms),为了防止半同步复制在没有收到确认的情况下发生堵塞,如果Master在超时之前没有收到任何确认,将恢复到正常的异步复制,并继续执行没有半同步的复制操作。
    • rpl_semi_sync_master_wait_no_slave={ON|OFF}
      • 如果一个事务被提交,但Master没有任何slave连接,这时不可能将事务发送到其他地方保存起来。默认情况下,Master会在时间限制范围内继续等待Slave的连接,并确认该事务已经被正确的写到磁盘上。
      • 可以使用此参数选项关闭这种行为,在这种情况下,如果没有Slave连接,Master就会恢复到异步复制。

过滤复制

  • 主库
    • 白名单:只记录白名单列出的库的二进制日志
      • binlog-do-db
    • 黑名单:不记录黑名单列出的库的二进制日志
      • binlog-ignore-db
  • 从库
    • 白名单:只执行白名单中列出的库或者表的中继日志
      • –replication-do-db=test
      • –replication-do-table=test.t1
      • –replication-wild-do-table=test.t*
    • 黑名单:不执行黑名单中列出的库或者表的中继日志
      • –replication-ignore-db
      • –replication-ignore-table
      • –replication-wild-ignore-table
  • 复制过滤配置
修改从库的配置文件
vim /etc/my.cnf
[mysqld]
--replication-do-db=test1

systemctl restart mysqld
mysql -uroot -p
mysql> start slave;
  • 第一次测试:
    • 主库
mysql> use test1;
mysql> create table t1(id int);
    • 从库查看结果
mysql> use test1;
mysql> show tables;
# 同步过来了
  • 第二次测试:
    • 主库
mysql> use test2;
mysql> create table th1(id int);
    • 从库查看结果
mysql> show databases;
# 查看不到test2表

二、MHA高可用架构

MHA(Master High Availability)目前在MySQL高可用方面是一个相对成熟的解决方案,它由日本DeNA公司youshimaton(现就职于Facebook公司)开发,是一套优秀的作为MySQL高可用性环境下故障切换和主从提升的高可用软件。在MySQL故障切换过程中,MHA能做到在0-30秒之内自动完成数据库的故障切换操作,并且在进行故障切换的过程中,MHA能在最大程度上保证数据的一致性,以达到真正意义上的高可用。

MHA能够在较短的时间内实现自动故障检测和故障转移,通常在10-30秒以内;在复制框架中,MHA能够很好地解决复制过程中的数据一致性问题,由于不需要再现有的replication中添加额外的服务器,仅需要一个manager节点,而一个manager能管理多套复制,所以能大大地节约服务器的数量;另外,安装简单,无性能损耗,以及不需要修改现有的复制部署也是它的优势之处。

MHA还提供在线主库切换的功能,能够安全地切换当前运行的主库到一个新的主库中(通过将从库提升为主库),大概0.5-2秒内即可完成。

MHA由两部分组成:MHA Manager(管理节点)和MHA Node(数据节点)。MHA Manager可以独立部署在一台独立的机器上管理多个Master-Slave集群,也可以部署再一台SLave上。当Master出现故障时,它可以自动将最新数据的Slave提升为新的Master,然后将所有其他的Slave重新指向新的Master。整个故障转移过程对应用程序是完全透明的
MySQL(4)_第2张图片

工作流程

  1. 把宕机的master二进制日志保存下来。
  2. 找到binlog位置点最新的slave。
  3. 在binlog位置点最新的slave上用relay log(差异日志)修复其它slave。
  4. 将宕机的master上保存下来的二进制日志恢复到含有最新位置点的slave上。
  5. 将含有最新位置点binlog所在的slave提升为master。
  6. 将其它slave重新指向新提升的master,并开启主从复制。

MHA工具介绍

  • MHA软件由两部分组成,Manager工具包和Node工具包
  • Manager工具包主要包括以下几个工具
masterha_check_ssh 检测MHA的ssh-key
masterha_check_repl 检查主从复制情况
masterha_manager 启动MHA
masterha_check_status 检测MHA的运行状态
masterha_master_monitor 检测master是否宕机
masterha_master_switch 手动故障转移
masterha_conf_host 手动添加server信息
masterha_secondary_check 建立TCP连接从远程服务器
masterha_stop 停止MHA
  • Node工具包主要包括以下几个工具
save_binary_logs 保存宕机的master的binlog
apply_diff_relay_logs 识别relay log的差异
filter_mysqlbinlog 防止回滚时间
purge_relay_logs 清楚中继日志
  • MHA优点总结
    • 自动故障转移快
    • 主库崩溃不存在数据一致性问题
    • 不需要对当前的mysql环境做重大修改
    • 不需要添加额外的服务器(仅一台manager就可管理上百个replication)
    • 性能优秀,可工作在半同步复制和异步复制,当监控mysql状态时,仅需要每隔N秒向master 发送ping包(默认3秒),所以对性能无影响。你可以理解为MHA的性能和简单的主从复制架构性能一样
    • 只要replication支持的存储引擎,MHA都支持,不会局限于innodb

MHA实验环境

  • 搭建三台mysql数据库,一主两从
  • 克隆的另外两台机器需要改一下mysql的uuid, /application/mysql/data/auto.conf
wget https://downloads.mysql.com/archives/get/p/23/file/mysql-5.6.40-linux-glibc2.12-x86_64.tar.gz
tar xzvf mysql-5.6.40-linux-glibc2.12-x86_64.tar.gz
useradd mysql -s /sbin/nologin -M
mkdir /application
mv mysql-5.6.40-linux-glibc2.12-x86_64 /application/mysql-5.6.40
ln -s /application/mysql-5.6.40/ /application/mysql	# 如果版本发生改变,直接重新创建一个软连接,不用修改原来目录的名字
cd /application/mysql/support-files/
cp my-default.cnf /etc/my.cnf	# 后者是linux底下自带的mysql文件
cp:是否覆盖"/etc/my.cnf"? y
cp mysql.server /etc/init.d/mysqld
cd /application/mysql/scripts
yum -y install autoconf
./mysql_install_db --user=mysql --basedir=/application/mysql --datadir=/application/mysql/data/
vim /etc/profile.d/mysql.sh
export PATH="/application/mysql/bin:$PATH"

source /etc/profile

sed -i 's#/usr/local#/application#g' /etc/init.d/mysqld /application/mysqld/bin/mysqld_safe

vim /usr/lib/systemd/system.mysqld.service
[Unit]
Descruption=MySQL Server
Documentation=man:mysqld(8)
Documentation=https://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
After=syslog.target
[Install]
WantedBy=multi-user.target
[Service]
User=mysql
Group=Mysql
ExecStart=/application/mysql/bin/mysqld --defaults-file=/etc/my.cnf
LimitNOFILE = 5000

vim /etc/my.cnf
basedir = /application/mysql
datadir = /application/mysql/data

systemctl daemon-reload
systemctl start mysqld
systemctl enable mysqld
mysqladmin -uroot password '123456'
mysql -uroot -p123456

基于GTID的主从复制

  • 先决条件
  • 主库和从库都要开启binlog
  • 主库和从库server-id不同
  • 要有主从复制用户
  • uuid:tid(事务id)
  • 优势
    • 效率高,速度快,在每一个库都开启一个SQL线程
    • row,节省网络资源,磁盘资源,内存使用率
    • 不需要找pos定位
    • 将主从信息记录在tables中,提高可用性
    • 支持所有复制,包括延时复制

主库操作

  • 修改配置文件
vim /etc/my.cnf
[mysqld]
server_id=1
# 主库server-id为1,从库不等于1
log_bin=mysql-bin
# 开启binlog日志
skip-name-resolv
# 跳过域名解析
  • 创建主从复制用户(所有主机)
mysql -uroot -p123456
mysql> grant replication slave on *.* to slave@'192.168.64.%' identified by '123456';
# 创建slave用户

从库操作

  • 修改配置文件
vim /etc/my.cnf
[mysqld]
server_id=5
# 主库server-id为1,从库不等于1
log_bin=mysql-bin
# 开启binlog日志,因为可能会成为一个主库
重启 systemctl restart mysqld

第二台从库:
vim /etc/my.cnf
[mysqld]
server_id=10
# 主库server-id为1,从库不等于1
log_bin=mysql-bin
# 开启binlog日志
重启 systemctl restart mysqld

注:在以往如果是基于binlog日志的主从复制,则必须要记住主库的master状态信息。

mysql> show master status;

开启GTID

mysql> show global variables like '%gtid%';
# 没开启之前先看一下GTID的状态

vim /etc/my.cnf
[mysqld]
# 主库从库都需要修改
gtid_mode=ON
log_slave_updates
# 开启slave binlog同步
enforce_gtid_consistency
# 不允许任何违反GTID一致性

# 重启数据库
systemctl restart mysqld
mysql> show global variables like '%gtid%';
# 检查GTID的状态

注:主库从库都需要开启GTID否则在主从复制的时候就会报错

mysql -uroot -p123456
mysql> change master to
master_host='192.168.64.129',
master_user='slave',
master_password='123456',
#master_log_file='mysql-bin.000001',
#master_log_pos=120;
master_auto_position=1; #自动找位点

mysql> start slave;
# 开启slave
mysql> show slave status\G;
# 查看状态
  • 从库设置
    不删除从库的relaylog
mysql> set global relay_log_purge = 0;
# 禁用自动删除relay log功能
mysql> set global read_only=1;
# 设置只读
vim /etc/my.cnf
[mysqld]
relay_log_purge = 0

部署MHA

环境准备(所有节点)

工具包下载地址
cd && wget https://download.s21i.faiusr.com/23126342/0/0/ABUIABBPGAAg3OHUiAYolpPt7AQ.zip?f=mysql-master-ha.zip&v=1628778716
yum install perl-DBD-MySQL -y
# 安装依赖包
unzip mysql-master-ha.zip
cd mysql-master-ha
# 进入安装包存放目录
ls
rpm -ivh mha4mysql-node-0.56-0.e16.noarch.rpm
# 安装node包

mysql -uroot -p123456
mysql> grant replication slave on *.* to mha@'192.168.64.%' identified by 'mha';
# 添加mha管理账户
mysql> select user,host from mysql.user;
# 查看是否添加成功
mysql> select user,host from mysql.user;
# 主库上创建,从库上会自动复制,(在从库上查看)
  • 命令软连接(所有节点)
ln -s /application/mysql/bin/mysqlbinlog /usr/bin/mysqlbinlog
ln -s /application/mysql/bin/mysql /usr/bin/mysql
# 如果不创建命令软连接,检测mha复制情况的时候会报错

node节点部署完了

  • 部署管理节点(mha-manager:mysql-db03),一个管理者
yum install -y epel-release
# 使用epel源
yum install -y perl-Config-Tiny epel-release perl-Log-Dispatch perl-Parallel-ForkManger perl-Time-HiRes
# 安装manager依赖包

cd ~/mysql-master-ha && rpm -ivh mha4mysql-manager-0.56-0.e16.noarch.rpm
# 安装manager包
  • 编辑配置文件(manager节点)
mkdir -p /etc/mha
# 创建配置文件目录
mkdir -p /var/log/mha/app1
# 创建日志目录
vim /etc/mha/app1.conf
[server default]
manager_log=/var/log/mha/app1/manager.log
manager_workdir=/var/log/mha/app1
master_binlog_dir=/application/mysql/data
user=mha
password=mha
ping_interval=2
repl_password=123456
repl_user=salve
ssh_user=root
[server1]
hostname=192.168.64.129
port=3306
[server2]
hostname=192.168.64.133
port=3306
candidate_master=1
check_repl_delay=0
[server3]
hostname=192.168.64.135
port=3306
  • 配置ssh信任(所有节点)
ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa > /dev/null 2>&1
ssh-copy-id -i /root/.ssh/id_dsa.pub [email protected]
ssh-copy-id -i /root/.ssh/id_dsa.pub [email protected]
ssh-copy-id -i /root/.ssh/id_dsa.pub [email protected]
  • 启动测试(manage节点)
# masterha_check_ssh --conf=/etc/mha/app1.cnf
# 测试ssh

# masterha_check_repl --conf=/etc/mha/app1.cnf
# 测试复制
  • 启动MHA
nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ingnore_last_failover < /dev/null > /var/log/mha/app1/manager.log 2>&1 &
# 启动
masterha_check_status --conf=/etc/mha/app1.cnf
# 检测状态
  • 切换master测试
mysql> show slave status;

# 停掉主库
systemctl stop mysqld
#在后面两个从库上分别看slave的状态
mysql> show slave status;

你可能感兴趣的:(企业服务,mysql,数据库,服务器)