环境&版本

使用docker hub中的镜像搭建,方便单机搭建demo,另外自己安装了一些基本工具(ping、vim等)
因为要搭一主二从,先把主实例环境弄好后再创建出新的docker镜像,快速搭起从库容器

MySQL版本:5.7

主库

宿主机启动:

  1. docker run --name mysqlMaster -e MYSQL_LOG_CONSOLE=true -e MYSQL_ROOT_PASSWORD=lagou123456 -d mysql:5.7

连接上镜像

  1. echo 'deb http://mirrors.163.com/debian/ buster main non-free contrib' > /etc/apt/sources.list
  2. echo 'deb http://mirrors.163.com/debian/ buster-updates main non-free contrib' >> /etc/apt/sources.list
  3. echo 'deb http://mirrors.163.com/debian/ buster-backports main non-free contrib' >> /etc/apt/sources.list
  4. echo 'deb http://mirrors.163.com/debian-security/ buster/updates main non-free contrib' >> /etc/apt/sources.list
  5. apt-get update
  6. apt-get upgrade
  7. apt-get install vim*

每一台都需要开启binlog并且设置唯一的server-id

  1. [mysqld]
  2. log-bin=mysql-bin
  3. server-id=1

然后登陆进mysql,新建账户并授予权限,注意三台机子都要做,不然没法切换

  1. create user 'repl'@'%' identified by 'lagou123456';
  2. grant REPLICATION SLAVE ON *.* TO 'repl'@'%' identified by 'lagou123456';
  3. flush privileges;

安装半同步复制插件

  1. # 安装插件
  2. INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
  3. # 开启
  4. set global rpl_semi_sync_master_enabled=on;
  5. show variables like '%rpl_semi_sync_master%';
  6. # 验证
  7. show global status like 'rpl%';

最后重启主库容器(docker restart)

从库

复制主库镜像

  1. docker commit <master container id> mine/mysql57:v1
  2. docker run --name slave1 -e MYSQL_LOG_CONSOLE=true -e MYSQL_ROOT_PASSWORD=lagou123456 -d mine/mysql57:v1

设置与主库不同的server-id
登陆进去执行以下指令

  1. # LOG相关值需要在主库中 show master status获取
  2. CHANGE MASTER TO MASTER_HOST='172.17.0.2', MASTER_USER='repl',MASTER_PASSWORD='lagou123456',MASTER_LOG_FILE='mysql-bin.000006',MASTER_LOG_POS=154;
  3. # 开启同步
  4. START SLAVE;
  5. # 查看同步状态
  6. SHOW SLAVE STATUS \G;

安装半同步复制插件

  1. # 安装插件
  2. INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
  3. # 开启
  4. set global rpl_semi_sync_slave_enabled=on;
  5. # 如果之前已经开启同步,需要重启
  6. stop slave;
  7. start slave;
  8. # 验证
  9. show global status like 'rpl%';

MHA搭建

环境安装,三台机器都安装mha node,我这边偷懒就把manager安装在从库上

  1. apt-get install libdbd-mysql-perl
  2. # rpm包需要到网上下载 此命令在宿主机执行
  3. docker cp /Users/canzihou/software/mha bdef0d156e93:/root/
  4. dpkg -i mha4mysql-node_0.54-0_all.deb

安装manager

  1. # apt-get install libdbd-mysql-perl
  2. # apt-get install libconfig-tiny-perl
  3. # apt-get install liblog-dispatch-perl
  4. # apt-get install libparallel-forkmanager-perl

manager配置文件

  1. # /etc/app1.cnf
  2. [server default]
  3. # mysql user and password
  4. user=root
  5. password=lagou123456
  6. ssh_user=root
  7. # working directory on the manager
  8. manager_workdir=/var/log/masterha/app1
  9. # working directory on MySQL servers
  10. remote_workdir=/var/log/masterha/app1
  11. [server1]
  12. hostname=<ip>
  13. [server2]
  14. hostname=<ip>
  15. [server3]
  16. hostname=<ip>

检查ssh连接,每台机器都要

  1. # manager
  2. masterha_check_ssh --conf=/etc/app1.cnf
  1. # 没有ssh 从头安装
  2. apt-get install openssh-server
  3. # 共享公钥
  4. ssh-keygen -t rsa
  5. cat /root/.ssh/id_rsa.pub>> /root/.ssh/authorized_keys
  6. ssh root@172.17.0.2 cat ~/.ssh/id_rsa.pub >> authorized_keys
  7. ssh root@172.17.0.3 cat ~/.ssh/id_rsa.pub >> authorized_keys
  8. ssh root@172.17.0.4 cat ~/.ssh/id_rsa.pub >> authorized_keys
  9. service ssh start

修改配置文件/etc/ssh/sshd_config

  1. PermitRootLogin yes
  2. PubkeyAuthentication yes
  3. UsePAM no

检查主从状态

  1. masterha_check_repl --conf=/etc/app1.cnf

通过后可以开启manager

  1. nohup masterha_manager --conf=/etc/app1.cnf < /dev/null > /var/log/masterha/app1/app1.log 2>&1 &
  2. masterha_manager --conf=/etc/app1.cnf
  3. # 查看manager状态
  4. masterha_check_status --conf=/etc/app1.cnf

模拟主库挂掉

  1. # 禁用主库3306端口
  2. nft add rule iptable1 filter-input-ens33-p0 ip daddr 172.17.0.2 tcp dport 3306 drop

问题

运行以下命令报错,需要修改源码

  1. masterha_check_repl --conf=/etc/app1.cnf
  1. sub parse_mysql_major_version($) {
  2. my $str = shift;
  3. $str =~ /(\d+)\.(\d+)/;
  4. my $strmajor = "$1.$2";
  5. my $result = sprintf( '%03d%03d', $strmajor =~ m/(\d+)/g );
  6. return $result;
  7. }