一 背景简介

1.1背景:为什么需要主从复制?

想象一下,你运营着一个网站,最开始所有用户都访问同一个数据库。这个数据库就像公司里唯一的“数据管理员”,所有数据的“读”(查信息)和“写”(增、删、改信息)请求都找他一个人。

一开始业务量小,他还能应付。但随着公司发展(网站用户量增加),问题就来了:

  1. “管理员”压力太大,性能瓶颈:成千上万的用户同时来查询和修改数据,这个唯一的数据库服务器CPU、内存、磁盘IO压力暴增,导致网站响应变慢,甚至卡死。
  2. 单点故障风险:如果这台唯一的服务器硬件坏了、机房断电或者数据库本身崩溃了,整个网站就彻底无法访问了,直接“崩掉”。这是致命的。
  3. 维护困难:你想给数据库做备份、数据迁移或者版本升级,必须暂停服务,这就会导致网站在一段时间内不可用,影响用户体验。
  4. 读写操作互相影响:大量的数据分析报表查询(复杂的读操作)可能会长时间占用资源,影响到用户下单、支付等核心的写操作,导致业务阻塞。

为了解决这些问题,我们就需要找“帮手”,也就是搭建“主从复制”。

1.2 什么是MySQL主从复制?

简单来说,就是把一台MySQL数据库服务器(称为主库,Master)的数据,复制到一台或多台其他的MySQL服务器(称为从库,Slave)上

  • 主库(Master):负责处理所有的写操作(INSERT, UPDATE, DELETE)。它是数据的源头。
  • 从库(Slave):负责复制主库的数据,并主要处理读操作(SELECT)。它是主库的“镜像”或“备份”。

这个复制过程是异步的,意思是主库执行完写操作后,会立刻给客户端返回成功,然后再“悄悄地”将数据的变更同步给从库。所以从库的数据和主库的数据之间存在一个微小的延迟。接下来我们详细介绍搭建过程。

二 部署mysql

这一章节需要主从两台机器都安装mysql

2.1 部署清单

序号 主机名 主机IP 角色
1 es1 192.168.56.107 master主库
2 es2 192.168.56.108 slave从库

2.2 安装JDK

下载jdk

网址:https://www.oracle.com/java/technologies/downloads/archive/

解压缩

# 进入安装包所在路径
cd /usr/local/app_install
# 解压安装包至对应目录
tar -zxvf jdk-8u371-linux-x64.tar.gz -C /usr/local/

添加环境变量

# 将以下内容添加至/etc/profile
vim /etc/profile

# java环境变量
export JAVA_HOME=/usr/local/jdk1.8.0_371
export CLASSPATH=$:CLASSPATH:$JAVA_HOME/lib/    
export PATH=$PATH:$JAVA_HOME/bin
# 刷新配置
source /etc/profile
# 验证jdk环境变量是否配置成功
java -version

2.3 安装mysql

下载mysql

网址:https://downloads.mysql.com/archives/community

部署安装

#1 解压缩
[root@es1][~/package]
$ll
total 557212
-rw-r--r-- 1 root root 570583040 Aug  2 17:38 mysql-5.7.43-1.el7.x86_64.rpm-bundle.tar

[root@es1][~/package]
$tar -xvf mysql-5.7.43-1.el7.x86_64.rpm-bundle.tar 
mysql-community-client-5.7.43-1.el7.x86_64.rpm
mysql-community-common-5.7.43-1.el7.x86_64.rpm
mysql-community-devel-5.7.43-1.el7.x86_64.rpm
mysql-community-embedded-5.7.43-1.el7.x86_64.rpm
mysql-community-embedded-compat-5.7.43-1.el7.x86_64.rpm
mysql-community-embedded-devel-5.7.43-1.el7.x86_64.rpm
mysql-community-libs-5.7.43-1.el7.x86_64.rpm
mysql-community-libs-compat-5.7.43-1.el7.x86_64.rpm
mysql-community-server-5.7.43-1.el7.x86_64.rpm
mysql-community-test-5.7.43-1.el7.x86_64.rpm

#2 安装前置依赖
yum install -y libaio openssl-devel net-tools

#3 删除原先的MySQL和mariadb
rpm -qa | grep mysql | xargs rpm -e --nodeps
rpm -qa | grep mariadb| xargs rpm -e --nodeps


#4 安装mysql的rpm
[root@es1][~/package]
$yum localinstall -y ./*.rpm

#5 查看安装版本
[root@es1][~/package]
$mysql -V
mysql  Ver 14.14 Distrib 5.7.43, for Linux (x86_64) using  EditLine wrapper

服务操作

服务启动之前一定看看端口有没有被占用,相关文件权限的属主属组是否匹配

# 启动
systemctl start mysqld
# 停止
systemctl stop mysqld
# 状态
systemctl status mysqld

密码修改

#1 抓取临时信息
cat /var/log/mysqld.log | grep 'temporary password is generated'

#2 登录mysql修改root密码
mysql -uroot -p
mysql> show databases;
ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement. #首次安装需要修改密码
mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'xxx';
Query OK, 0 rows affected (0.00 sec)

mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

三 mysql主从构建

3.1 前置操作

#1 创建相关文件夹
[root@es1][/var/lib/mysql]
$mkdir mysql-bin

[root@es1][/var/lib/mysql]
$chown mysql.mysql mysql-bin/

[root@es1][/var/lib/mysql/mysql-bin]
$pwd
/var/lib/mysql/mysql-bin

#2 时间同步-一般同步阿里云时间
[root@es2][~]
$ ntpdate ntp1.aliyun.com

3.2 修改master配置文件

[root@es1][~/package]
$cat /etc/my.cnf
# For advice on how to change settings please see
# http://dev.mysql.com/doc/refman/5.7/en/server-configuration-defaults.html

[mysqld]
port=9001
max_connections=1000
max_connect_errors=10
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock

server_id=1                 # server_id 主从机器必须不一致
log-bin=/var/lib/mysql/mysql-bin   # binlog日志存放路径
expire_logs_days = 7  
binlog-ignore-db=mysql  # 忽略mysql这个数据库,不进行同步,也可以采用binlog-do-db=mysql指定同步mysql库

# Disabling symbolic-links is recommended to prevent assorted security risks
#symbolic-links=0
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

3.3 修改slave配置文件

[root@es2][~/package]
$cat /etc/my.cnf
# For advice on how to change settings please see
# http://dev.mysql.com/doc/refman/5.7/en/server-configuration-defaults.html

[mysqld]
port=9001
max_connections=1000
max_connect_errors=10
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock

server_id=2                 # server_id 主从机器必须不一致
#log-bin=/var/lib/mysql/mysql-bin   # binlog日志存放路径
expire_logs_days = 7  
replicate-ignore-db=mysql    # 忽略复制mysql数据库,也可以通过replicate-do-db=test指定复制某test数据库

# Disabling symbolic-links is recommended to prevent assorted security risks
#symbolic-links=0
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

3.4 mysql服务重启

#1 两台服务器都需要重启
systemctl restart mysqld

#2 登录主库:验证binlog是否开启

mysql> show variables like '%log_bin%';
+---------------------------------+--------------------------------+
| Variable_name                   | Value                          |
+---------------------------------+--------------------------------+
| log_bin                         | ON                             |
| log_bin_basename                | /var/lib/mysql/mysql-bin       |
| log_bin_index                   | /var/lib/mysql/mysql-bin.index |
| log_bin_trust_function_creators | OFF                            |
| log_bin_use_v1_row_events       | OFF                            |
| sql_log_bin                     | ON                             |
+---------------------------------+--------------------------------+
6 rows in set (0.01 sec)

3.5 创建同步账户

master库

#1 方便读写分离的时候使用,同时也允许远程使用root权限登录,但是生产环境还是谨慎
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'xxxx' WITH GRANT OPTION;
FLUSH PRIVILEGES;

#2 在主库中创建主从同步用户,并授予复制、同步访问的权限。
mysql> CREATE USER 'slave'@'%' IDENTIFIED BY 'xxx';
Query OK, 0 rows affected (0.01 sec)

mysql> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
Query OK, 0 rows affected (0.00 sec)

mysql>  FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

mysql> show master status \G
*************************** 1. row ***************************
             File: mysql-bin.000049
         Position: 604
     Binlog_Do_DB: 
 Binlog_Ignore_DB: mysql
Executed_Gtid_Set: 
1 row in set (0.00 sec)

slave库

[root@es2][~]
$mysql -uroot -p
Enter password: 
#停掉从库
mysql> stop slave;  
Query OK, 0 rows affected, 1 warning (0.00 sec)

#同步主库,以下的信息是主库的show master status \G命令来的
mysql> change master to master_host='192.168.56.107',MASTER_PORT=9001,master_user='slave',master_password='xxx',master_log_file='mysql-bin.000049',master_log_pos=604;
Query OK, 0 rows affected, 2 warnings (0.03 sec)

#开启从库
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)

# 查看从库状态:在从库中查看主从同步状态。图中显示2个yes证明同步成功。
mysql>  show slave status \G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.56.107
                  Master_User: slave
                  Master_Port: 9001
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000049
          Read_Master_Log_Pos: 604
               Relay_Log_File: es2-relay-bin.000002
                Relay_Log_Pos: 320
        Relay_Master_Log_File: mysql-bin.000049
           ######主要是下面的两个是不是yes这种
             Slave_IO_Running: Yes  
            Slave_SQL_Running: Yes

3.6 创建测试数据

主库

#1 创建数据库
mysql>  CREATE DATABASE employeesdb; 
Query OK, 1 row affected (0.00 sec)

mysql> use employeesdb;
Database changed

#2 创建表
CREATE TABLE employee_table(  
    id int NOT NULL AUTO_INCREMENT,  
    name varchar(45) NOT NULL,  
    occupation varchar(35) NOT NULL,  
    age int NOT NULL,  
    PRIMARY KEY (id)  
); 

#3 查看表
mysql> SHOW TABLES; 

#4 插入数据
INSERT INTO employee_table VALUES  
(101, 'Joseph', 'Developer', 30),  
(102, 'Mike', 'Leader', 28),  
(103, 'Stephen', 'Scientist', 45),
(104, 'john', 'teacher', 22);

mysql> INSERT INTO employee_table VALUES  
    -> (101, 'Joseph', 'Developer', 30),  
    -> (102, 'Mike', 'Leader', 28),  
    -> (103, 'Stephen', 'Scientist', 45),
    -> (104, 'john', 'teacher', 22);
Query OK, 4 rows affected (0.01 sec)
Records: 4  Duplicates: 0  Warnings: 0

从库

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| employeesdb        |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

mysql> use employeesdb;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+-----------------------+
| Tables_in_employeesdb |
+-----------------------+
| employee_table        |
+-----------------------+
1 row in set (0.00 sec)

mysql> select * from employee_table;
+-----+---------+------------+-----+
| id  | name    | occupation | age |
+-----+---------+------------+-----+
| 101 | Joseph  | Developer  |  30 |
| 102 | Mike    | Leader     |  28 |
| 103 | Stephen | Scientist  |  45 |
| 104 | john    | teacher    |  22 |
+-----+---------+------------+-----+
4 rows in set (0.00 sec)

至此,mysq主从搭建完毕,欢迎大家相互交流学习。
本文来源于我的微信公众号Linux运维小白,我会持续更新文章,欢迎大家关注,互相交流学习。
在这里插入图片描述

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐