MySQL主从复制与读写分离

achiverhai 2019-12-02

MySQL主从复制的类型

基于语句的复制(默认)

在主服务器上执行的语句,从服务器执行同样的语句

基于行的复制

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

混合类型的复制

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

主从复制的工作过程

MySQL主从复制与读写分离

MySQL读写分离原理

读写分离就是只在主服务器上写,只在从服务器上读
主数据库处理事务性查询,从而数据库处理select查询
数据库复制被用来把事务性查询导致的变更同步到集群中的从数据库

MySQL主从复制与读写分离

实验环境

amoeba服务器(192.168.142.160)
master服务器(192.168.142.151)
slave1服务器 (192.168.142.163)
slave2服务器 (192.168.142.145)
client客户端 (192.168.142.143)

1,在master服务器上安装ntp时间服务器

[ ~]# yum install ntp -y   ##安装时间服务器
[ ~]# vim /etc/ntp.conf 
##在server下添加
server 127.127.13.0      ##本地是时间源
fudge 127.127.13.0 stratum 8   ##设置时间层级为8

[ ~]# systemctl start ntpd    ##启动时间服务
[ ~]# systemctl stop firewalld   ##关闭防火墙
[ ~]# setenforce 0

2,在slave1上安装ntp,ntpdate服务

[ ~]# yum install ntp ntpdate -y
[ ~]# systemctl start ntpd
[ ~]# systemctl stop firewalld
[ ~]# setenforce 0
[ ~]# /usr/sbin/ntpdate 192.168.142.151    ##同步主服务器时间
29 Nov 16:58:43 ntpdate[4932]: the NTP socket is in use, exiting

3,在slave2上安装ntp,ntpdate服务

[ ~]# yum install ntp ntpdate -y
[ ~]# systemctl start ntpd
[ ~]# systemctl stop firewalld
[ ~]# setenforce 0
[ ~]# /usr/sbin/ntpdate 192.168.142.151
29 Nov 17:02:08 ntpdate[4850]: the NTP socket is in use, exiting

4,在master,slave1,slave2上分别安装MySQL

[ ~]# mkdir /abc   ##创建挂载点
    [ ~]# mount.cifs //192.168.100.1/LNMP-C7 /abc/   ##远程挂载
    Password for //192.168.100.1/LNMP-C7:  
    [ ~]# cd /abc/
    [ abc]# ls
    mysql-5.5.24
    [ abc]# tar zxvf mysql-5.5.24.tar.gz -C /opt/   ##解压
    [ opt]# yum install -y     > gcc gcc-c++     > ncurses     > ncurese-devel \    ##控制终端屏幕显示的库
    > bison \                 ##语法分析
    > make
    > cmake                 ##cmake工具
    > libaio-devel         ##系统调用来实现异步IO

    [ opt]# useradd -s /sbin/nologin mysql   ##添加不可登录的mysql用户
    [ opt]# cd /opt/mysql-5.5.24/
    [ mysql-5.5.24]# mkdir /usr/local/mysql   ##创建安装目录
    [ mysql-5.5.24]# cmake \      ##配置
    > -DCMAKE_INSTALL_PREFIX=/usr/local/mysql \    ##安装路径
    > -DMYSQL_UNIX_ADDR=/home/mysql/mysql.sock \   ##sock文件路径
    > -DDEFAULT_CHARSET=utf8 \      ##字符集
    > -DDEFAULT_COLLATION=utf8_general_ci     > -DWITH_EXTRA_CHARSETS=all     > -DWITH_MYISAM_STORAGE_ENGINE=1 \     ##存储引擎
    > -DWITH_INNOBASE_STORAGE_ENGINE=1     > -DWITH_MEMORY_STORAGE_ENGINE=1     > -DWITH_READLINE=1     > -DENABLED_LOCAL_INFILE=1     > -DMYSQL_DATADIR=/home/mysql \     ##数据文件路径
    > -DMYSQL_USER=mysql \      ##用户
    > -DMYSQL_TCP_PORT=3306    ##端口

    [ mysql-5.5.24]# make && make install   ##编译及安装
    [ mysql-5.5.24]# chown -R mysql.mysql /usr/local/mysql   ##设置mysql属主属组
    [ mysql-5.5.24]# vim /etc/profile   ##配置环境变量便于系统识别
    export PATH=$PATH:/usr/local/mysql/bin/
    [ mysql-5.5.24]# source /etc/profile   ##刷新配置文件
    [ mysql-5.5.24]# cp support-files/my-medium.cnf /etc/my.cnf   ##主配置文件
    cp:是否覆盖"/etc/my.cnf"? yes
    [ mysql-5.5.24]# cp support-files/mysql.server /etc/init.d/mysqld   ##启动文件
    [ mysql-5.5.24]# chmod 755 /etc/init.d/mysqld    ##设置权限
    [ mysql-5.5.24]# chkconfig --add /etc/init.d/mysqld    ##添加到service管理中
    [ mysql-5.5.24]# chkconfig mysqld --level 35 on   ##开机自启动
    [ mysql-5.5.24]# /usr/local/mysql/scripts/mysql_install_db \   ##初始化数据库
    > --user=mysql     > --ldata=/var/lib/mysql     > --basedir=/usr/local/mysql     > --datadir=/home/mysql

    [ mysql-5.5.24]# vim /etc/init.d/mysqld    ##编辑启动脚本文件
    basedir=/usr/local/mysql   ##找到此处添加路径
    datadir=/home/mysql
    [ mysql-5.5.24]# service mysqld start    ##启动MySQL
    Starting MySQL.. SUCCESS! 
    [ mysql-5.5.24]# mysqladmin -u root password ‘abc123‘  ##设置密码

5,配置master主服务器

[ mysql-5.5.24]# vim /etc/my.cnf
server-id= 11     ##服务ID号
log-bin=master-bin                         ##主服务器日志文件
log-slave-updates=true                   ##从服务器更新二进制日志
[ mysql-5.5.24]# service mysqld restart   ##重启MySQL服务
Shutting down MySQL. SUCCESS! 
Starting MySQL.. SUCCESS!
[ ~]# mysql -uroot -pabc123   ##进入数据库

mysql> GRANT REPLICATION SLAVE ON *.* TO ‘myslave‘@‘192.168.142.%‘ IDENTIFIED BY ‘123456‘;
##给从服务器提权复制权限,名为myslave密码123456对于13段网段
Query OK, 0 rows affected (0.01 sec)

mysql> FLUSH PRIVILEGES;    ##刷新提权
Query OK, 0 rows affected (0.00 sec)

mysql> show master status;   ##查看主服务器状态
+-------------------+----------+--------------+------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-------------------+----------+--------------+------------------+
| master-bin.000002 |      338 |              |                  |
+-------------------+----------+--------------+------------------+
1 row in set (0.00 sec)

6,配置slave1从服务器

[ mysql-5.5.24]# vim /etc/my.cnf
server-id       = 22              ##另外一台为23

relay-log=relay-log-bin                         ##从主服务器上同步日志文件记录到本地
relay-log-index=slave-relay-bin.index           ##定义relay-log的位置和名称
[ mysql-5.5.24]# service mysqld restart    ##重新服务
Shutting down MySQL. SUCCESS!  
Starting MySQL.. SUCCESS!
[ mysql-5.5.24]# mysql -uroot -pabc123

mysql> change master to master_host=‘192.168.142.151‘,master_user=‘myslave‘,master_password=‘123456‘,master_log_file=‘master-bin.000002‘,master_log_pos=338;
##同步主服务器二进制文件和位置使用授权的账号密码
Query OK, 0 rows affected (0.00 sec)

mysql> start slave;     ##开启同步
Query OK, 0 rows affected (0.01 sec)

mysql> show slave status\G;   ##查看状态
                            Master_Log_File: master-bin.000002
                    Read_Master_Log_Pos: 338
                             Relay_Log_File: relay-log-bin.000001
                                Relay_Log_Pos: 4
                    Relay_Master_Log_File: master-bin.000002
                         Slave_IO_Running: Yes
                            Slave_SQL_Running: Yes

7,配置slave2从服务器

[ mysql-5.5.24]# vim /etc/my.cnf
server-id       = 23              

relay-log=relay-log-bin                         ##从主服务器上同步日志文件记录到本地
relay-log-index=slave-relay-bin.index           ##定义relay-log的位置和名称
[ mysql-5.5.24]# service mysqld restart    ##重新服务
Shutting down MySQL. SUCCESS!  
Starting MySQL.. SUCCESS!
[ mysql-5.5.24]# mysql -uroot -pabc123

mysql> change master to master_host=‘192.168.142.151‘,master_user=‘myslave‘,master_password=‘123456‘,master_log_file=‘master-bin.000002‘,master_log_pos=338;
##同步主服务器二进制文件和位置使用授权的账号密码
Query OK, 0 rows affected (0.00 sec)

mysql> start slave;    ##开启同步
Query OK, 0 rows affected (0.01 sec)

mysql> show slave status\G;    ##查看状态
                            Master_Log_File: master-bin.000002
                    Read_Master_Log_Pos: 338
                             Relay_Log_File: relay-log-bin.000001
                                Relay_Log_Pos: 4
                Relay_Master_Log_File: master-bin.000002
                         Slave_IO_Running: Yes
                        Slave_SQL_Running: Yes

8,测试主从同步情况

主服务器操作:

mysql> create database school;    ##创建school数据库
Query OK, 1 row affected (0.00 sec)

从服务器1操作:

mysql> show databases;   ##查看数据库
+--------------------+
| Database           |
+--------------------+
| information_schema |
| #mysql50#.mozilla  |
| mysql              |
| performance_schema |
| school             |
| test               |
+--------------------+
6 rows in set (0.01 sec)

从服务器2操作:

mysql> show databases;   ##查看数据库
+--------------------+
| Database           |
+--------------------+
| information_schema |
| #mysql50#.mozilla  |
| mysql              |
| performance_schema |
| school             |
| test               |
+--------------------+
6 rows in set (0.01 sec)

9,配置amoeba服务器

[ ~]# systemctl stop firewalld.service   ##关闭防火墙
    [ ~]# setenforce 0
    [ ~]# mount.cifs //192.168.100.1/LNMP-C7 /mnt/  ##挂载
    Password for //192.168.100.1/LNMP-C7:  
    [ ~]# cd /mnt/
    [ mnt]# ls
    [ mnt]# cp jdk-6u14-linux-x64.bin /usr/local/   ##复制jdk二进制文件到/usr/local下
    [ mnt]# cd /usr/local/
    [ local]# ./jdk-6u14-linux-x64.bin  ##直接执行安装
    Do you agree to the above license terms? [yes or no]
    yes   ##选择yes进行安装
    Press Enter to continue.....
    ##回车继续
    [ local]# mv jdk1.6.0_14/ /usr/local/jdk1.6   ##简化文件名
    [ local]# vim /etc/profile   ##设置环境变量
    ##末行插入
    export JAVA_HOME=/usr/local/jdk1.6  ##家目录
    export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib ##class环境变量
    export PATH=$JAVA_HOME/lib:$JAVA_HOME/jre/bin/:$PATH:$HOME/bin   ##环境变量
    export AMOEBA_HOME=/usr/local/amoeba   ##amoeba家目录
    export PATH=$PATH:$AMOEBA_HOME/bin   ##环境变量
    [ local]# source /etc/profile   ##刷新配置文件
    [ local]# mkdir /usr/local/amoeba   ##创建amoeba目录
    [ local]# cd /mnt/
    [ mnt]# tar zxvf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba   ##解压amoeba
    [ mnt]# chmod -R 755 /usr/local/amoeba/   ##设置权限
    [ mnt]# /usr/local/amoeba/bin/amoeba     ##检查是否安装成功
    amoeba start|stop

10,在master,slave1,slave2上提权amoeba访问权限

grant all on *.* to ‘192.168.142.%‘ identified by ‘123.com‘;
##给amoeba访问权限用户test密码123.com

11,修改amoeba服务器配置文件

[ conf]# vim amoeba.xml  ##修改主配置文件
    #第30行

     <property name="user">amoeba</property>    ##从服务器同步主服务器的用户密码
    #第32行
     <property name="password">123456</property>

    #第117行去掉注释
     <property name="defaultPool">master</property>
     <property name="writePool">master</property>
     <property name="readPool">slaves</property>

    [ conf]# vim conf/dbServers.xml   ##配置数据库配置文件

    #第26 至29行去掉注释
     <property name="user">test</property>

     <property name="password">123.com</property>

    #第42行添加主服务器地址
    <dbServer name="master"  parent="abstractServer">
     <property name="ipAddress">192.168.142.151</property>
    第52行添加从服务器slave1地址
    <dbServer name="slave1"  parent="abstractServer">
     <property name="ipAddress">192.168.142.163</property>
     ##复制6行添加服务器slave2地址
     <dbServer name="slave2"  parent="abstractServer">
     <property name="ipAddress">192.168.142.145</property>
    #第65行授权同步
     <dbServer name="slaves" virtual="true">
     <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">

    #末行添加从服务器名称
    <property name="poolNames">slave1,slave2</property>
     </poolConfig>
    [ conf]# /usr/local/amoeba/bin/amoeba start&   ##开启amoeba服务
    [ ~]# netstat -anpt | grep java   ##开启另一个终端查看开启情况
    tcp6       0      0 127.0.0.1:26268         :::*                    LISTEN      40925/java          
    tcp6       0      0 :::8066                 :::*                    LISTEN      40925/java          
    tcp6       0      0 192.168.142.160:34090    192.168.142.151:3306     ESTABLISHED 40925/java          
    tcp6       0      0 192.168.142.160:33866    192.168.142.145:3306     ESTABLISHED 40925/java          
    tcp6       0      0 192.168.142.160:55984    192.168.142.163:3306     ESTABLISHED 40925/java

12,在客户端测试读写分离

[ ~]# yum install mysql -y   ##安装测试数据库

测试机创建表

[ ~]# mysql -u amoeba -p123456 -h 192.168.142.160 -P8066  
##使用amoeba账户密码登录amoeba
MySQL [(none)]> show databases;   ##查看数据库
+--------------------+
| Database           |
+--------------------+
| information_schema |
| #mysql50#.mozilla  |
| mysql              |
| performance_schema |
| school             |
| test               |
+--------------------+
6 rows in set (0.00 sec)

MySQL [(none)]> use school;   ##使用数据库
Database changed
MySQL [school]> create table info (    ##创建表
        -> id int(4) not null primary key,
        -> name varchar(10) not null,
        -> score decimal(4,1) not null);
Query OK, 0 rows affected (0.02 sec)

查看主从服务器上是否有创建的表

mysql> use school;    ##使用数据库
Database changed
mysql> show tables;  ##查看表
+------------------+
| Tables_in_school |
+------------------+
| info             |
+------------------+
1 row in set (0.00 sec)

在两台从服务器上关闭同步slave

mysql> stop slave;
Query OK, 0 rows affected (0.01 sec)
### 在测试机上写入表数据
    MySQL [school]> insert into info (id,name,score) values (1,‘zhangsan‘,88);  ##插入数据内容
    Query OK, 1 row affected (0.03 sec)

在主服务器上查看

mysql> select * from info;
+----+----------+-------+
| id | name     | score |
+----+----------+-------+
|  1 | zhangsan |  88.0 |
+----+----------+-------+
1 row in set (0.00 sec)

在从服务器上查看

mysql> select * from info;  ##从服务器上没有写入
    Empty set (0.00 sec)

在测试机查看

MySQL [school]> select * from info;   ##没有查看到写入的内容
Empty set (0.01 sec)

在slave1写入内容

mysql> insert into info (id,name,score) values (2,‘lisi‘,70);
Query OK, 1 row affected (0.00 sec)

在slave2写入内容

mysql> insert into info (id,name,score) values (3,‘wuwang‘,60);
Query OK, 1 row affected (0.00 sec)

在测试机上查看info表数据(轮询的方式)

MySQL [school]> select * from info;
+----+--------+-------+
| id | name   | score |
+----+--------+-------+
|  3 | wuwang |  60.0 |
+----+--------+-------+
1 row in set (0.00 sec)

MySQL [school]> select * from info;
+----+------+-------+
| id | name | score |
+----+------+-------+
|  2 | lisi |  70.0 |
+----+------+-------+
1 row in set (0.00 sec)

在主服务器上写如数据,在从服务器上读取数据,采用的是轮询机制,从而实现读写分离!

相关推荐