MySQL主从复制理论+实验(上篇)

文章目录

        • 前言:
        • 一、案例概述
          • 1.1 背景
          • 1.2 解决方法
          • 1.3 更高级解决方法
          • 1.4 MySQL主从复制类型
          • 1.5 主从复制工作过程图
        • 二、主从复制实验
          • 2.1 环境部署
            • 2.1.1 实验拓扑
          • 2.2 实验过程
            • 2.2.1 主从服务器时间同步
            • 2.2.2 MySQL手工编译安装
            • 2.2.3 配置主从同步
          • 2.3 测试
        • 小结:

前言:

主从复制(也称 AB 复制)允许将来自一个MySQL数据库服务器(主服务器)的数据复制到一个或多个MySQL数据库服务器(从服务器)。

一、案例概述

1.1 背景
  • 在企业网站中,后端的MySQL数据库只有一台时,会有以下问题
    • ① 单点故障,服务不可用
    • ② 无法处理大量的并发数据请求
    • ③ 数据丢失

MySQL主从复制理论+实验(上篇)_第1张图片

1.2 解决方法
  • 改造办法
    • ① 增加MySQL数据库服务器,对数据进行备份,形成主备
    • ② 确保主备MySQL数据库是一样的
    • ③ 主服务器宕机,备份服务器继续工作,数据有保障
  • MySQL主从复制与读写分离是密切相关的

MySQL主从复制理论+实验(上篇)_第2张图片

选举出主服务器,其他的都是从服务器,从服务器向主服务器看齐

1.3 更高级解决方法
  • 通过主从复制的方式来同步数据,再通过读写分离来提升数据库的并发负载能力
    MySQL主从复制理论+实验(上篇)_第3张图片

  • Amoeba:是一个以MySql为底层数据存储,并对应提供MySQL协议接口的proxy(代理),外号变形虫

    读取请求发送给从服务器是,采用轮询调度算法

  • amoeba使用的java语言编写,配置文件为xml

  • amoeba主要负责对外的一个代理IP

    访问这个IP时,发送的请求为“写”请求,则会转给主服务器

    当发送的请求为“读”时,会通过调度转发给从服务器,使用轮询算法,轮流分配给两台从服务器

    amoeba可以视为调度器,如果主服务器挂掉,则会有MHA解决中国问题

  • 本篇博客实验使用到的账号权限为以下几个

    • 主从同步账号
    • 节点服务器开放调度账号
    • Amoeba代理账号
1.4 MySQL主从复制类型
  • 基于语句的复制

    再主服务器上执行的语句,从服务器执行相同的语句

  • 基于行的复制

    把改变的内容复制到从服务器

  • 混合类型的复制

    一旦发现基于语句无法精确复制时,就会采用基于行的复制

1.5 主从复制工作过程图

MySQL主从复制理论+实验(上篇)_第4张图片

MySQL主从复制理论+实验(上篇)_第5张图片

二、主从复制实验

2.1 环境部署
  • ① 五台centos7虚拟机
  • ② 一台做为client(后续实验读写分离使用)
  • ③ 三台做为mysql服务器(其中一台为master服务器)
  • ④ 一台作为amoeba服务器(后续实验读写分离使用)
2.1.1 实验拓扑

MySQL主从复制理论+实验(上篇)_第6张图片

2.2 实验过程
2.2.1 主从服务器时间同步
  • master服务器配置
  • ① 安装ntp、修改配置文件
[root@master ~]# yum install ntp -y
[root@master ~]# vim /etc/ntp.conf
#在第25行插入以下内容
#前2个127代表的是(192.168) 
server 127.127.226.0
#允许226段的主机与本机同步,时间环数为8个
fudge 127.127.226.0 stratum 8  
-------》wq
  • ② 开启NTP服务、关闭防火墙和增强性安全功能
[root@master ~]# systemctl start ntpd
[root@master ~]# systemctl stop firewalld.service 
[root@master ~]# setenforce 0
  • 两台SLAVE服务器配置
  • ① 安装ntp、ntpdate服务
[root@localhost ~]# yum install ntp ntpdate -y
  • ② 开启ntp服务,关闭防火墙、增强性安全功能
[root@localhost ~]# systemctl start ntpd
[root@localhost ~]# systemctl stop firewalld.service 
[root@localhost ~]# setenforce 0
  • ③ 时间同步master服务器
[root@localhost ~]# /usr/sbin/ntpdate 192.168.226.132
29 Feb 14:48:00 ntpdate[83952]: the NTP socket is in use, exiting
  • 两台slave服务器配置相同
2.2.2 MySQL手工编译安装
  • ① 三台MySQL服务器同时安装
[root@master ~]# mount.cifs //192.168.226.1/LAMP-C7 /mnt
Password for root@//192.168.226.1/LAMP-C7:  
[root@master ~]# cd /mnt
[root@master mnt]# ls
amoeba-mysql-binary-2.2.0.tar.gz  LNMP-C7
apr-1.6.2.tar.gz                  LNMP-C7.rar
apr-util-1.6.0.tar.gz             mha
awstats-7.6.tar.gz                mha.rar
cat.jpg                           mw.jpg
CentOS-7-x86_64-DVD-1708.iso      mysql-5.6.26.tar.gz
cronolog-1.6.2-14.el7.x86_64.rpm  php-5.6.11.tar.bz2
Discuz_X2.5_SC_UTF8.zip           shuita.jpg
dog.jpg                           yum
error.png                         yum.repos.d.zip
httpd-2.4.29.tar.bz2
[root@master mnt]# tar zxvf mysql-5.5.22.tar.gz -C /opt
.......省略部分内容
  • ② 安装环境依赖包
[root@master mnt]# yum -y install gcc gcc-c++ make pcre-devel expat-devel perl ncurses-devel autoconf cmake
  • ③ 创建程序性用户
[root@master opt]# useradd -s /sbin/nologin mysql
#-s 不让此用户从控制台登录
  • ④ 编译
[root@master opt]# cd mysql-5.6.26/
[root@master mysql-5.6.26]# ls
BUILD           config.h.cmake       extra               libmysqld    packaging  sql-bench      unittest
BUILD-CMAKE     configure.cmake      include             libservices  plugin     sql-common     VERSION
client          COPYING              INSTALL-SOURCE      man          README     storage        vio
cmake           dbug                 INSTALL-WIN-SOURCE  mysql-test   regex      strings        win
CMakeLists.txt  Docs                 libevent            mysys        scripts    support-files  zlib
cmd-line-utils  Doxyfile-perfschema  libmysql            mysys_ssl    sql        tests
[root@master mysql-5.6.26]# cmake  \
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
-DDEFAULT_CHARSET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci \
-DEXTRA_CHARSETS=all \
-DSYSCONFIDIR=/etc \
-DMYSQL_DATADIR=/home/mysql/ \
-DMYSQL_UNIX_ADDR=/home/mysql/mysql.sock
........省略部分内容
    
[root@master mysql-5.6.26]# make && make install
#把源码包编译成二进制可执行文件
........省略部分内容
  • ⑤ 给MySQL程序用户配置权限
[root@master mysql-5.6.26]# chown -R mysql.mysql /usr/local/mysql/
  • ⑥ 优化MySQL自带命令(支持其环境变量)
[root@master mysql-5.6.26]# echo "PATH=$PATH:/usr/local/mysql/bin" >> /etc/profile
[root@master mysql-5.6.26]# source /etc/profile
  • ⑦ 将默认启动脚本复制到/etc/init.d中,给与755权限,添加到service中,便于service管理
[root@master mysql-5.6.26]# cp support-files/mysql.server /etc/init.d/mysqld
[root@master mysql-5.6.26]# chmod 755 /etc/init.d/mysqld
[root@master mysql-5.6.26]# chkconfig --add /etc/init.d/mysqld
[root@master mysql-5.6.26]# chkconfig  mysqld --level 35 on
  • ⑧ 将解压包中的默认配置文件复制到/etc下,覆盖原配置文件
[root@master ~]# cd /opt/mysql-5.6.26/
[root@master mysql-5.6.26]# cp support-files/my-default.cnf /etc/my.cnf
cp: overwrite ‘/etc/my.cnf’? y
  • ⑨ 初始化数据库
[root@master mysql-5.6.26]# /usr/local/mysql/scripts/mysql_install_db \
--user=mysql \
--ldata=/var/lib/mysql \
--basedir=/usr/local/mysql \
--datadir=/home/mysql
........省略部分内容
  • ⑩ 在启动脚本添加工作目录和数据目录
[root@master mysql-5.6.26]# vim  /etc/init.d/mysqld
basedir=/usr/local/mysql     
datadir=/home/mysql
  • 开启MySQL服务、修改数据库密码
[root@master mysql-5.6.26]# service mysqld start
Starting MySQL. SUCCESS! 
[root@master mysql-5.6.26]# mysqladmin -u root -p password "abc123"
  • 三台MySQL同时手工编译安装
2.2.3 配置主从同步
  • ① master服务器修改配置文件
[root@master ~]# vi /etc/my.cnf
#在mysqld模块下修改一下内容
#开启二进制日志文件(之后生成的日志名为master-bin)
log_bin=master-bin
#开启从服务器日志同步
log_slave=updates=true
#主服务器id为11(不可重复)
server_id = 11
--------》wq
  • 重启服务
[root@master ~]# service mysqld restart
Shutting down MySQL.. SUCCESS! 
Starting MySQL. SUCCESS! 
  • 配置规则
[root@master ~]# mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.

mysql> GRANT REPLICATION SLAVE ON *.* TO 'myslave'@'192.168.226.%' IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.00 sec)

#刷新数据库
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

规则解析:GRANT REPLICATION SLAVE ON . TO ‘myslave’@‘192.168.226.%’ IDENTIFIED BY ‘123456’;

给从服务器提权,允许使用slave的身份复制master的所有数据库的所有表,并指定密码为123456

  • 查看master数据库状态
mysql> show master status;
+-------------------+----------+--------------+------------------+-------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master-bin.000001 |      412 |              |                  |                   |
+-------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

mysql> 
#以上可见产生了master-bin.000001日志文件,定位为412
#从服务器需要定位到此处进行复制
  • ② 从服务器配置
[root@slave1 ~]# vi /etc/my.cnfvi /etc/my.cnf
#开启二进制日志文件
log-bin=mysql-bin
#设置server id为22,slave2 为23
server_id = 22
#从主服务器上同步日志文件记录到本地
relay-log=relay-log-bin
#定义relay-log的位置和名称(index索引) 
relay-log-index=slave-relay-bin.index
--------》wq
  • 开启从服务器功能
[root@slave1 ~]# mysql -uroot -p
...............
mysql> change master to master_host='192.168.226.132',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=412;
Query OK, 0 rows affected, 2 warnings (0.02 sec)

mysql> start slave;
Query OK, 0 rows affected (0.01 sec)
  • 查看从服务器状态
mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.226.132
                  Master_User: myslave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: master-bin.000001
          Read_Master_Log_Pos: 412
               Relay_Log_File: relay-log-bin.000002
                Relay_Log_Pos: 284
        Relay_Master_Log_File: master-bin.000001
             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: 412
              Relay_Log_Space: 455
              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: 11
                  Master_UUID: c59043ec-5ad8-11ea-b895-000c29fe085b
             Master_Info_File: /home/mysql/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
           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
1 row in set (0.00 sec)
  • 同理、开启另一台从服务器同步
2.3 测试
  • 在主服务器上创建一个数据库
mysql> cerate database work;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'cerate database work' at line 1
mysql> create database work;
Query OK, 1 row affected (0.00 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test               |
| work               |
+--------------------+
5 rows in set (0.00 sec)
  • 在两台从服务器上直接查看数据库列表
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test               |
| work               |
+--------------------+
5 rows in set (0.00 sec)

以上,主从同步复制配置完成

小结:

MySQL主从复制与读写分离是密切相关的,本篇博客介绍了MySQL的主从复制(同步),紧接着下一篇会介绍MySQL读写分离

这里简单介绍一下二进制日志

MySQL的二进制日志是一个二进制文件,主要用于记录修改数据或有可能引起数据变更的MySQL语句。

二进制日志中记录了对MySQL数据库执行更改的所有操作,并且记录了语句发生时间、执行时长、操作数据等其他额外信息,但是它不记录SELECT 、SHOW等不修改数据的SQL语句。

二进制日志主要用于数据库恢复(⭐⭐)和主从复制及审计操作。

PS:如果同步失败可使用以下方法尝试解决

  • ① slave数据库中:SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;

    START SLAVE;

  • ② slave数据库中:CHANGE MASTER TO MASTER_LOG_FILE=‘mysql-bin.000001’,MASTER_LOG_POS=0;

你可能感兴趣的:(数据库)