主库从库理论到实践 | 青训营笔记

112 阅读5分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天

今天和大家分享如何配置主从库。

主库/从库

主从库概念

从库也是一个数据库,它生成两个线程,一个I/O线程,一个SQL线程

I/O线程用来请求主库binlog(执行日志的二进制文件),并将其写道relaylog(中继日志)中;

主库会生成一个log dump线程,用来给从库I/O线程传binlog

SQL线程用来读取中继文件中的日志,并解析成具体操作,来实现主从的操作一致,最终数据一致。

主从库用途

  1. 实时灾备,用于故障切换
  2. 读写分离,提供查询服务(主要功能,一般是主数据库)
  3. 备份,避免影响业务

主从库部署

前提条件

首先,主从库部署需要满足以下条件:

  1. 主库开启binlog日志(设置log-bin参数),从库开启relaylog中继日志(设置relay-log参数)
  2. 主从server-id不同
  3. 从库服务器能连通主库

考虑到主从数据库的版本,配置都有可能不同,我们可以使用docker进行数据库配置:

构建配置目录(数据存放目录)

目录结构如下:

--mysql
  --master
     --data  
     --conf
        --my.cnf    
  --slave
     --data  
     --conf
        --my.cnf

其中my.cng为文件,其他均为目录。(Windows 操作系统中 MySQL 的配置文件 my.ini。Linux 操作系统中 MySQL 的配置文件是 my.cnf

配置my.cnf

配置文件中,我们需要注意以下几点:

  1. 主从服务器的server_id需要不同且唯一,因为他是服务器的标识
  2. 从服务器经常只用作读取服务
  3. 有些文件需要注明忽略同步,例如replicate-ignore-db(忽略某库进行同步)

Master(主数据库) my.cnf 配置文件:

[mysqld]
server_id=1
# 要生成二进制日志文件 主服务器一定要开启
log-bin=mysql-bin
#控制binlog日志文件保留时间,超过保留时间的binlog日志会被自动删除
expire_logs_days=30
# 可读写
read-only=0
# 记录进日志的数据库,不配的话就是记录所有库
binlog-do-db=test
# 不记录进日志的数据库
binlog-ignore-db=mysql
binlog-ignore-db=information_schema
binlog-ignore-db=performation_schema
binlog-ignore-db=sys
# 其他需要的配置位置 无特殊需要不用
# !includedir /etc/mysql/conf.d/
# !includedir /etc/mysql/mysql.conf.d/

Slave(从数据库) my.cnf 配置文件:

[mysqld]
server_id=2
log-bin=mysql-bin
# relay-log配置中继日志
relay-log=mysql-relay-bin
# 只可以读
read-only=1
# 同步的数据库,这里我们不需要,因为主数据库已经指明了需要同步的数据库
replicate-do-db=test
# 不同步的数据库 这里如果主从都没有指明需要同步的数据库,需要使用下面的配置
# replicate-ignore-db=mysql
# replicate-ignore-db=sys
# replicate-ignore-db=information_schema
# replicate-ignore-db=performance_schema

启动docker容器

docker容器,我们选择mysql镜像并且使用已经建好的文件作为容器配置(使用-v命令挂载目录)。

这里,我们为了更好演示,直接使用docker启动两个容器并对外暴露不同的接口。正常做法是两个不同的服务器分别启动一个docker容器。

启动master主数据库容器:

docker run --name mastermysql -d -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123456 -v /home/mysql_test/master/data:/var/lib/mysql -v /home/mysql_test/slave/conf/my.cnf:/etc/mysql/my.cnf mysql:5.7

-e 说明环境变量,即mysql的密码为root;这里 -v 参数,冒号前为宿主机目录,绝对路径,我们可以根据实际情况进行更改; 启动slave从数据库容器。

docker run --name slavemysql -d -p 3308:3306 -e MYSQL_ROOT_PASSWORD=123456 -v /home/mysql_test/slave/data:/var/lib/mysql -v /home/mysql_test/slave/conf/my.cnf:/etc/mysql/my.cnf mysql:5.7

这样两个docker容器就启动了。

配置docker容器

我们建立好了两个数据库,此时它们之间还没有建立好连接,我们需要配置容器。这里可以使用Dockerfile文件配置,也可以进入容器中使用bash命令进行配置:

master设置:

进入容器命令 docker exec -it mastermysql bash。进入容器后逐步执行以下命令:

# 进入数据库
mysql -uroot -p123456
# 这里表示创建一个slaver同步账号slave,允许访问的IP地址为%,%表示通配符,即所有地址
CREATE USER 'slave'@'%' IDENTIFIED BY '123456'; 
# 授予slave主从复制的相关权限。
GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* to 'slave'@'%';
# 刷新权限
FLUSH PRIVILEGES;
# 创建数据库
CREATE DATABASE test;
# 查看当前master的状态
show master status;

****** ****** ****** ****** *** 1. row **** ****** ****** ****** ***** File: mysql-bin.000001 Position: 154 Binlog_Do_DB: Binlog_Ignore_DB: Executed_Gtid_Set: 1 row in set (0.00 sec)

我们需要记住此时的状态表中的File列值(例如mysql-bin.000001)和Position列的值(例如0)之后会用到。

slave设置:

进入容器命令 docker exec -it slavemysql bash。进入容器后逐步执行以下命令:

# 进入数据库
mysql -uroot -p123456
# 创建数据库
CREATE DATABASE test;
# 设置对应主数据库
change master to 
#主数据库ip
master_host='xxx.xxx.xxx.xxx',
#主数据库用户名
master_user='slave', 
#主数据库密码
master_password='123456', 
#主数据库端口号
master_port=3307,
#日志文件开始复制数据
master_log_file='mysql-bin.000001',
#从哪个 Position 开始读,即上文中提到的 Position 字段的值
master_log_pos=0, 
# 如果连接失败,重试的时间间隔,看情况执行
# master_connect_retry=30;

成功执行后,我们进入从Mysql服务器:

#启动slave
start slave;
#查看slave
show slave status;

到此,我们的数据库主从配置就已经完成了。我们可以通过在主test数据库的添加一条记录来,在从数据库查询来验证其有效性。