MySQL与分布式:主从复制


提示:以下是本篇文章正文内容,mysql 系列学习将会持续更新

MySQL与分布式

前面我讲解了 Redis 在分布式场景的下的相关应用,接着我们来看看 MySQL 数据库在分布式场景下的应用。

一、Linux下载 MySQL

方案一MariaDB (CentOS8 自带 mariadb 下载源)

PS: 如果当前系统中已经安装有 MySQL 数据库,安装将失败。mariadb 与 MySQL 数据库冲突.

参考文章Linux之部署Web项目到云服务器

方案二MySQL

①下载并安装MySQL官方的 Yum Repository

wget -i -c http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm

②可以直接yum安装MySQL源

yum -y install mysql57-community-release-el7-10.noarch.rpm

③开始安装MySQL服务器。

yum -y install mysql-community-server

# 安装报错:提示公钥尚未安装,执行下面指令安装密钥后,再次安装 mysql
rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022

这步可能会花些时间,安装完成后就会覆盖掉之前的 mariadb。

④查看是否安装成功

yum list installed mysql-*

⑤启动 MySQL

# 启动msql服务
systemctl start mysqld
# 开机自启mysql服务
systemctl enable mysqld
# 查看mysql服务状态
systemctl status mysqld

⑥查阅临时密码

# 查看文件内容
cat /var/log/mysqld.log

# 查看文件内容中包含password的行信息
cat /var/log/mysqld.log | grep password

⑦登录mysql

mysql -uroot -p

# 设置密码长度最低位数
set global validate_password_length=6;
# 设置密码安全等级低,便于密码可以修改成123456
set global validate_password_policy=LOW;
# 设置密码
set password = password('123456');

⑧开启访问权限

# *.*表示允许访问的数据库名称.表名称
# root代表远程登录使用的用户名,可以自定义
# %代表允许任意ip登录,如果你想指定特定的IP,可以把%替换掉就可以了
# password代表远程登录时使用的密码,可以自定义
grant all privileges on *.* to 'root' @'%' identified by '123456';
# 让权限立即生效
flush privileges;

回到目录…

二、MySQL 主从复制

  1. 从机连接主机后,一开始不会进行全量复制,所以最好再开始主从之前将数据库的内容保持一致。
  2. 采用增量复制的方式,MySQL 会在运行的过程中,会记录二进制日志,所有的DML和DDL操作都会被记录进日志中。
  3. 主库只需要将操作记录复制给从库,让从库也运行一次,那么就可以实现主从复制。
  4. 即使主库出现故障,从库也能正常提供服务,实现了读写分离

这里我们就使用两台主机来搭建一主一从的环境,首先确保两台服务器都安装了 MySQL 数据库并且都已经正常运行了:
在这里插入图片描述

🍌2.1 修改配置文件

① 修改两个 mysql 服务器的配置文件:

sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf
# 先给两个服务器开启一下外网访问
bind-address           = 0.0.0.0    # 这样改,或者注释掉
# server-id 默认是 1,所有 Mysql 主从实例的 id 必须唯一,不能冲突,否则启动失败
server-id              = 2

② 最后重启两个服务器:

sudo systemctl restart mysql.service 

🍌2.2 配置主机

① 我们在主服务器需要创建一个账号,一会儿方便从库进行访问的用户:

CREATE USER test identified with mysql_native_password by '123456';

② 再来配置主库,主库只需要为我们刚刚创建好的用户分配一个主从复制的权限即可:

grant replication slave on *.* to test;
flush privileges;

③ 然后我们可以输入命令来查看主库的相关情况:

show master status;

在这里插入图片描述

🍌2.3 配置从机

从机连接主机的信息:注意后面的 logfilepos 就是我们上面从主库中显示的信息。

change replication source to SOURCE_HOST='192.168.0.8',SOURCE_USER='test',SOURCE_PASSWORD='123456',SOURCE_LOG_FILE='binlog.000004',SOURCE_LOG_POS=591;

② 开始连接主库

start replica;

③ 查看从机的连接状态

show replica status\G;

查看当前从机状态,可以看到:
在这里插入图片描述
最关键的是下面的 Replica_IO_RunningReplica_SQL_Running 必须同时为 Yes 才可以,实际上从库会创建两个线程,一个线程负责与主库进行通信,获取二进制日志,暂时存放到一个中间表(Relay_Log)中,而另一个线程则是将中间表保存的二进制日志的信息进行执行,然后插入到从库中。

回到目录…

🍌2.4 查看同步状态

在这里插入图片描述

这样,我们的MySQL主从就搭建完成了,那么如果主机此时挂了会怎么样?

  1. 可以看到 IO 线程是处于重连状态,会等待主库重新恢复运行。
    在这里插入图片描述
  2. 主库重启后,会发现从库会自动连接。如果没有再次连接,可能是偏移量不一致了,需要从机先 stop replica; ,再根据主库的情况重新 change replication source to ...

回到目录…

三、Docker 实现 MySQL 主从复制

正常情况下,MySQL 集群是部署到不同服务器上,实现高可用的。但是我们学习阶段,没有两个服务器,而 MySQL 又不像 Redis 一样允许在同一个服务器上开启多个服务器。

所以我们想演示 MySQL 主从复制,就只能用到 Docker,我们可以用 Docker 创建两个容器部署同样版本的 MySQL,两个 MySQL 服务器 3306 端口映射到宿主机的不同端口,从而进行主从复制
在这里插入图片描述

🍬3.1 准备工作:创建目录映射

① 创建工作目录

mkdir master-slave
# 此后就在此目录开启容器
cd master-slave

② 配置数据卷(创建容器目录映射)

mkdir -p master/conf
cd master/conf
vim my.cnf
mkdir -p slave/conf
cd slave/conf
vim my.cnf

③ 两个 MySQL 服务器的 my.cnf 如下:①两个server-id不同即可;②开启 log-bin 才能记录偏移量。

[mysqld]
user=mysql
character-set-server=utf8
default_authentication_plugin=mysql_native_password
secure_file_priv=/var/lib/mysql
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
max_connections=1000

default-time-zone='+08:00'
innodb_buffer_pool_size = 128M
port = 3306
datadir=/var/lib/mysql
socket=/var/run/mysqld/mysqld.sock
pid-file=/var/run/mysqld/mysqld.pid

# 允许连接失败的次数。
max_connect_errors=10

#引擎
default-storage-engine=INNODB

log-bin = mysql-bin
# #设置保存时间
expire_logs_days=7

# #注意5.7以及更高版本需要配置本项:server-id=123454(自定义,保证唯一性); server-id 一般去ip后三位
server-id=1
# #binlog格式,有3种statement,row,mixed
binlog-format=ROW
# #表示每1次执行写入就与硬盘同步,会影响性能,为0时表示,事务提交时mysql不做刷盘操作,由系统决定
sync-binlog=1

# ##开启慢sql
slow_query_log=on
slow_query_log_file=/var/lib/mysql/slow-query.log
long_query_time=1

[client]
default-character-set=utf8

[mysql]
default-character-set=utf8

回到目录…

🍬3.2 配置 Master

① 创建并开启 Master 容器

docker run -id \
--name mysql-master \
-p 3301:3306 \
-v $PWD/master/conf/my.cnf:/etc/mysql/my.cnf \
-v $PWD/master/conf/conf.d:/etc/mysql/conf.d \
-v $PWD/master/logs:/var/log/mysql \
-v $PWD/master/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:5.7

② 进入容器

docker exec -it mysql-master /bin/bash
mysql -uroot -p123456

③SQL 操作:创建一个新用户,用于从机访问主机

-- 创建一个新用户,用户名为 test,密码为 123456
CREATE USER test identified with mysql_native_password by '123456';
-- 为新用户分配一个主从复制的权限
grant replication slave on *.* to test;
-- 刷新权限池
flush privileges;

④SQL 操作:查看主库情况

show master status;

在这里插入图片描述

如果出现 status 为空的情况,是因为没有开启日志,应该像我上面一样,自定义配置文件做映射。
在这里插入图片描述

回到目录…

🍬3.3 配置 Slave

① 创建并开启 Slave 容器

docker run -id \
--name mysql-slave \
-p 3302:3306 \
-v $PWD/slave/conf/my.cnf:/etc/mysql/my.cnf \
-v $PWD/slave/conf/conf.d:/etc/mysql/conf.d \
-v $PWD/slave/logs:/var/log/mysql \
-v $PWD/slave/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:5.7

② 进入容器

docker exec -it mysql-slave /bin/bash
mysql -uroot -p123456

③ SQL 操作:从机连接主机信息(这里的 logfilepos 就是我们上面从主库中的 status 信息)

change master to master_host='1.15.76.95', master_user='test', master_password='123456', master_port=3301, master_log_file='mysql-bin.000001', master_log_pos=502, master_connect_retry=30;

④ SQL 操作:开始连接主库

start slave;

⑤ SQL 操作:查看从机的连接状态

show slave status\G;

在这里插入图片描述

mysql> show slave status \G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 1.15.76.95
                  Master_User: test
                  Master_Port: 3301
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 502
               Relay_Log_File: 9b169d4502f9-relay-bin.000002
                Relay_Log_Pos: 320
        Relay_Master_Log_File: mysql-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: 502
              Relay_Log_Space: 534
              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: 1
                  Master_UUID: dcb6e016-caf4-11ed-b59e-0242ac110002
             Master_Info_File: /var/lib/mysql/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           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
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
1 row in set (0.00 sec)

ERROR: 
No query specified

回到目录…

🍬3.4 查看同步状态

① 我们在 Master 中插入数据:

create database test_db;
use test_db;
CREATE TABLE users (
	id       int         not null primary key,
	name     varchar(30), 
	age      int
);
insert into users values (1, 'zhangsan', 20);

② 我们在 Slave 中查看数据同步情况:
在这里插入图片描述

③ 当 Master 宕机后,从机状态会变为 Slave_IO_Running: Connecting,此时我们只需要再次启动主机,从机就可以自动连接成功。

docker start mysql-master

回到目录…


总结:
提示:这里对文章进行总结:
本文是对MySQL的学习,先学会了在云服务器上安装MySQL,又学习了MySQL的主从复制,并且基于两台服务器实现了一主一从的结构,又学会了在Docker中开启两个容器实现MySQL主从结构。之后的学习内容将持续更新!!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只咸鱼。。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值