• mysql 两主一从环境搭建


    搭建说明

    • 两主一从,从本质上说,只不过是机器 master-a 和 master-b 互为主从机(热备),然后通过 keepalived 进行高可用配置,使得在同一时间内只会有一台对外提供服务,实现单写机制,另一个机器 slave 则作为 master-a 的从机存在(冷备)。
    • 从机 slave 无法直接将虚拟IP(VIP)作为主机:正常运行时,slave 绑定了一个主机 master-a, 一旦绑定之后,在 master-a 不可用的时候,无法自动切换到 master-b,因为需要考虑 二进制日志文件名(master_log_file)及位置(master_log_pos)在 master-a 和 master-b 上是不一致的,此时只有在 master-a 恢复可用时,master-a 从 master-b 同步数据之后,slave 数据最终才会和 master-a 保持一致。

    环境准备

    1. 三台 centos7 的服务器,服务器ip为 192.168.86.124(master-a)、192.168.86.125(master-b)、192.168.86.126(slave)
    2. 一个虚拟IP(VIP):192.168.86.250
    3. mysql-5.7.24-linux-glibc2.12-x86_64 安装包

    数据库安装

    1. 将 mysql 安装包上传到三台服务器上
    2. 解压安装包
      tar -zxvf mysql-5.7.24-linux-glibc2.12-x86_64.tar.gz
      
    3. 创建 mysql 安装路径,然后移动刚才解压的文件夹并重命名
      mkdir /data     #创建安装路径
      mv mysql-5.7.24-linux-glibc2.12-x86_64 /data/mysql  #移动文件并重命名
      
    4. 创建 mysql 用户和组、创建mysql运行需要的文件夹及赋权
      groupadd mysql     #创建用户组 
      useradd -r -g mysql mysql       #创建用户
      cd /data/mysql                   #切换到安装目录
      mkdir data                      #创建数据存放目录
      mkdir mysql-log                 #创建日志存放目录
      mkdir mysql-log/err-log
      mkdir mysql-log/slow-log
      mkdir mysql-log/relay-log
      mkdir mysql-log/bin-log         
      chown -R root:mysql .           #将当前目录以及子目录,所有者改变为 mysql,所属组修改为 mysql
      chown -R mysql:mysql data
      chown -R mysql:mysql mysql-log
      
    5. 设置用户操作系统资源限制
      vi /etc/security/limits.conf
      # 在文件中加入以下内容
      mysql   soft   nproc   2047
      mysql   hard   nproc   16384
      mysql   soft   nofile  1024
      mysql   hard   nofile  65536 
      
    6. 设置链接和服务
      cp /data/mysql/support-files/mysql.server /etc/init.d/mysql  # 可以使用service mysql start
      ln -s  /data/mysql/bin/mysql /usr/bin         #任何路径可以使用 mysql 命令
      
    7. 配置 /etc/my.cnf
      vi /etc/my.cnf
      
      • master-a
        [mysqld]
        port = 3306                             #端口
        basedir = /data/mysql                    #mysql安装路径
        datadir = /data/mysql/data/              #mysql数据存放路径
        
        #日志设置
        log-error = /data/mysql/mysql-log/err-log/db-err.log   #错误日志路径
        slow-query-log-file = /data/mysql/mysql-log/slow-log/db-slow.log  #慢SQL日志路径
        relay-log=/data/mysql/mysql-log/relay-log/relay-log
        long-query-time = 20 #怎样才算是慢sql,单位是秒
        
        #开启 binlog 同步
        server_id = 0001                  #一个集群内的 MySQL 服务器 ID,全局唯一
        log-bin = /data/mysql/mysql-log/bin-log/db-binlog      #开启 Binlog 并写明存放日志的位置
        max-binlog-cache_size = 64M       #binlog 最大能够使用cache的内存大小
        max-binlog-size = 1G              #binlog 日志每达到设定大小后,会使用新的 binlog 日志
        expire_logs_days = 15             #只保留最近15天的bin日志
        binlog-format = mixed             #混合模式复制
        innodb_flush_log_at_trx_commit = 1 #和 sync_binlog 控制MySQL磁盘写入策略以及数据安全性
        sync-binlog = 1                  #控制数据库的binlog刷到磁盘上去
        
        ## 主主同步配置
        replicate-do-db=db_test     #需要从主库-2同步的数据库1
        replicate-do-db=db_dev      #需要从主库-2同步的数据库2
        auto-increment-increment=2
        auto-increment-offset=1
        log-slave-updates=1
        
        #性能调优配置
        innodb_buffer_pool_size = 24576M
        max_connections = 5000
        max_connect_errors = 6000
        external-locking = FALSE
        max_allowed_packet = 64M
        join_buffer_size = 64M
        sort_buffer_size = 2M
        read_rnd_buffer_size = 16M
        
        #SQL模式
        sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
        
      • master-b
        [mysqld]
        port = 3306
        basedir = /data/mysql
        datadir = /data/mysql/data
        
        #日志设置
        slow-query-log-file=/data/mysql/mysql-log/slow-log/db-slow.log
        log-error=/data/mysql/mysql-log/err-log/db-err.log
        relay-log=/data/mysql/mysql-log/relay-log/relay-log
        long-query-time = 20 #怎样才算是慢sql,单位是秒
        
        #开启 binlog 同步
        server_id = 0002                  #一个集群内的 MySQL 服务器 ID,全局唯一
        log-bin = /data/mysql/mysql-log/bin-log/db-binlog      #开启 Binlog 并写明存放日志的位置
        max-binlog-cache_size = 64M       #binlog 最大能够使用cache的内存大小
        max-binlog-size = 1G              #binlog 日志每达到设定大小后,会使用新的 binlog 日志
        expire_logs_days = 15             #只保留最近15天的日志
        binlog-format = mixed             #混合模式复制
        innodb_flush_log_at_trx_commit = 1 #和 sync_binlog 控制MySQL磁盘写入策略以及数据安全性
        sync-binlog = 1                  #控制数据库的binlog刷到磁盘上去
        
        #主主设置
        replicate-do-db=db_test     #需要从主库-1同步的数据库1
        replicate-do-db=db_dev      #需要从主库-1同步的数据库2
        auto-increment-increment=2
        auto-increment-offset=2
        log-slave-updates=1
        
        #性能调优设置
        innodb_buffer_pool_size = 24576M
        max_connections = 5000
        max_connect_errors = 6000
        external-locking = FALSE
        max_allowed_packet = 64M
        join_buffer_size = 64M
        sort_buffer_size = 2M
        read_rnd_buffer_size = 16M
        
        #SQL模式
        sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
        
      • slave
        [mysqld]
        port = 3306
        basedir = /data/mysql
        datadir = /data/mysql/data
        
        #日志设置
        expire_logs_days = 15
        long-query-time = 3
        slow-query-log-file=/data/mysql/mysql-log/slow-log/db-slow.log
        log-error=/data/mysql/mysql-log/err-log/db-err.log
        
        #主从设置
        server_id = 0003 #这里需要在集群中保持唯一
        replicate-do-db=db_test     #需要从主库同步的数据库1
        replicate-do-db=db_dev      #需要从主库同步的数据库2
        read_only=1                 #只读设置
        
        #性能调优设置
        innodb_buffer_pool_size = 24576M
        max_connections = 5000
        max_connect_errors = 6000
        external-locking = FALSE
        max_allowed_packet = 64M
        join_buffer_size = 64M
        sort_buffer_size = 2M
        read_rnd_buffer_size = 16M
        
        #SQL模式
        sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
        
        

    数据库初始化

    1. 初始化数据库
       cd /data/mysql/bin/
       ./mysqld --defaults-file=/etc/my.cnf  --user=mysql --initialize  #初始化
      
    2. 查看密码(初始化数据库之后会生成一个 root 账户的默认密码)
      cat /data/mysql/mysql-log/err-log/db-err.log
      
    3. 启动 mysql
      service mysql start
      
    4. 登录并修改 root 密码
      mysql -u root -p
      set password = password('root');
      flush privileges;
      
      #如果需要使用 root 进行远程连接,执行以下语句
      use mysql;
      update user set host = '%' where user = 'root';
      flush privileges;
      
    5. 创建用户并赋权
      • 主机 master-a、master-b
        #创建一个用于和从机“通信”的用户,具有同步权限 
        grant replication slave on *.* to 'copy'@'%' identified by 'copy'
        flush privileges;
        
        #创建一个用于访问和操作某些特定的库的用户,不应该让应用直接使用 root 用户.
        grant all privileges  on db_test.* to "app_user"@'%' identified by "app_user";
        flush privileges; 
        
      • 从机 slave
        #创建一个用于访问和操作某些特定的库的用户,不应该让应用直接使用 root 用户.
        grant all privileges  on db_test.* to "app_user"@'%' identified by "app_user";
        flush privileges; 
        

    主从同步启动

    1. 主机 master-a
      1. 在 master-b 中获得二进制日志文件名(master_log_file)及位置(master_log_pos)
        show master status
        
        image
      2. 在 master-a 中执行以下命令
        stop slave;     #暂停
        reset slave;    #重置
        change master to master_host="master-b 的IP", master_user="copy",master_password="copy",master_log_file="db-binlog.000002",master_log_pos=2532; #设置和主机同步的用户信息,日志文件信息
        start slave;    #启动
        show slave status G #查看从机状态,主要是看 Slave_IO_Running Slave_SQL_Running 上是否都是 yes
        
        image
    2. 主机 master-b、从机 slave
      1. 在 master-a 中获得二进制日志文件名(master_log_file)及位置(master_log_pos)
        show master status
        
      2. 在 master-b和 slave 中执行以下命令
        stop slave;     #暂停
        reset slave;    #重置
        change master to master_host="master-a 的IP", master_user="copy",master_password="copy",master_log_file="db-binlog.000002",master_log_pos=2532; #设置和主机同步的用户信息,日志文件信息
        start slave;    #启动
        show slave status G #查看从机状态,主要是看 Slave_IO_Running Slave_SQL_Running 上是否都是 yes
        

    keepalived 安装启动(master-a、master-b)

    1. keepalived 安装
      yum install -y keepalived
      
    2. keepalived 配置
      vi /etc/keepalived/keepalived.conf
      
      文件内容为:
      global_defs {
        router_id LVS_DEVEL
      }
      
      vrrp_sync_group VG_1 {
        group {
          VI_1
        }
      }
      
      vrrp_instance VI_1 {
        state BACKUP  #两个机器都是这个值,不要设置为 MASTER,使用下面的 priority 来控制 
        interface ens33  #通过 ifconfig 查看
        virtual_router_id 51
        priority 100 #优先级,另一台机器设置为 90 
        advert_int 1
        nopreempt  # 另一台优先级低的机器不设置此参数!
        authentication {
          auth_type root
          auth_pass root
        }
        virtual_ipaddress {
         192.168.86.250 # 这个是VIP
        }
      }
      
      virtual_server 192.168.86.250 3306 {  # 这个是VIP
        delay_loop 2
        lb_algo rr
        lb_kind DR
        persistence_timeout 50
        protocol TCP
      
        real_server 192.168.86.124 3306 {   # 这是机器的IP地址
          weight 3
          notify_down /data/mysql/bin/mysql.sh
          TCP_CHECK {
            connect_timeout 5
            nb_get_retry 3
            delay_before_retry 3
            connect_port 3306
          }
        }
      }
      
      
    3. 创建一个关闭 keepalived 的脚本,用于在 mysql 无法访问时,关闭 keepalived 以释放 VIP
      vi /data/mysql/bin/mysql.sh
      
      文件内容为:
      #!/bin/sh
      pkill keepalived
      
      将文件设置为可执行文件:
      chmod +x /data/mysql/bin/mysql.sh
      
    4. keepalived 启动
      systemctl start keepalived
      
    5. keepalived 其它相关命令
      systemctl enable keepalived # 开机自启动
      systemctl start keepalived     # 启动
      systemctl stop keepalived     # 暂停
      systemctl restart keepalived  # 重启
      systemctl status keepalived   # 查看状态
      tail -f /var/log/messages
      

    测试

    1. 首先,所有机器、软件都正常运行
      • 通过各个 IP和VIP 连接数据库查看均能正常连接到数据库
        image
      • master-a 获得了 vip
        ip addr
        
        image
    2. 通过 VIP 连接数据库,之后创建一个 db_test 库以及 tb_user表
      • master-a、master-b、slave 均存在创建的库和表
    3. 连接 master-a 的数据库,并新增一条数据
      • master-b、slave 均有新增的数据
    4. 连接 master-b 的数据库,并新增一条数据
      • master-a、slave 均有新增的数据
    5. 关闭 master-a 的mysql
      service  mysql stop  #关闭 mysql
      
      systemctl status keepalived #查看 keepalived 状态
      
      • master-a 的 keepalived 自动关闭了,原因是 mysql 关闭会触发 keepalived 配置的 notify_down 脚本
      • master-b 获得了 vip
    6. 通过 VIP 连接数据库,并插入一条数据
      • master-a(无法连接)
      • master-b (存在新增数据)
      • slave(不存在新增数据,因为 master-a 挂掉了)
    7. 重启 master-a 的 mysql 和 keepalived
      • vip 仍然在 master-b ,因为 master-a keepalived 配置了非抢占模式 nopreempt,因此若是主机故障排除后需要将主机的keepalived重启,然后重启从机的keepalived,需要让主机获取到 VIP
      • master-a、master-b 同步了刚刚新增的数据
    8. 关闭 master-b、slave 的mysql,通过 master-a 新增一条数据,之后重启 master-b、slave 的 mysql,以及 master-b 的 keepalived
      • master-b存在新增数据
      • slave 存在新增数据
      • vip 仍然在 master-a

    常见问题

    -- 整理于网络,加上自己的理解,大家一起学习,进步就好
  • 相关阅读:
    单元测试的必要性
    【C++ STL】Queue
    【C++ STL】Stack
    【C++ STL】容器的选择
    【C++ STL】Map和Multimap
    [Effective JavaScript 笔记]第19条:熟练掌握高阶函数
    [Effective JavaScript 笔记]第18条:理解函数调用、方法调用及构造函数调用之间的不同
    node实现rar格式压缩
    [Effective JavaScript 笔记]第2章:变量作用域--个人总结
    [Effective JavaScript 笔记]第17条:间接调用eval函数优于直接调用
  • 原文地址:https://www.cnblogs.com/shulipeng/p/13937462.html
Copyright © 2020-2023  润新知