文章目录
提示:以下是本篇文章正文内容,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 主从复制
- 从机连接主机后,一开始不会进行全量复制,所以最好再开始主从之前将数据库的内容保持一致。
- 采用增量复制的方式,MySQL 会在运行的过程中,会记录二进制日志,所有的DML和DDL操作都会被记录进日志中。
- 主库只需要将操作记录复制给从库,让从库也运行一次,那么就可以实现主从复制。
- 即使主库出现故障,从库也能正常提供服务,实现了读写分离。
这里我们就使用两台主机来搭建一主一从的环境,首先确保两台服务器都安装了 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 配置从机
① 从机连接主机的信息:注意后面的 logfile
和 pos
就是我们上面从主库中显示的信息。
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_Running
和 Replica_SQL_Running
必须同时为 Yes 才可以,实际上从库会创建两个线程,一个线程负责与主库进行通信,获取二进制日志,暂时存放到一个中间表(Relay_Log)中,而另一个线程则是将中间表保存的二进制日志的信息进行执行,然后插入到从库中。
🍌2.4 查看同步状态
这样,我们的MySQL主从就搭建完成了,那么如果主机此时挂了会怎么样?
- 可以看到 IO 线程是处于重连状态,会等待主库重新恢复运行。
- 主库重启后,会发现从库会自动连接。如果没有再次连接,可能是偏移量不一致了,需要从机先
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 操作:从机连接主机信息(这里的 logfile
和 pos
就是我们上面从主库中的 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主从结构。之后的学习内容将持续更新!!!