Mysql主从复制与读写分离学习笔记 | 青训营笔记

61 阅读3分钟

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


一.实现原理(摘录)

Mysql的主从复制是一个异步的复制过程,底层是基于Mysql数据库自带的二进制日志功能。就是从库(slave)从主库(master)进行日志复制然后再解析日志并应用到自身那个,最终实现从库的数据和主库的数据保持一致。

Mysql复制过程分成三步:

  1. master将改变记录记录到二进制日志(binary log)
  2. salve将master的binary log拷贝到它的中继日志(relay log)
  3. slave重做中继日志中的事件,将改变应用到自己的数据库中

二.实现配置

1.查看mysql服务是否启动

systemctl status mysql

2.配置主库Master

  • 修改Mysql数据库的配置文件/etc/my.cnf
[mysqld]
log-bin=mysql-bin #[必须]启用二进制日志
server-id=100 #[必须]服务器唯一ID
# 需要同步的数据库,如果不配置则同步全部数据库
binlog-do-db=test_db
# binlog日志保留的天数,清除超过10天的日志
# 防止日志文件过大,导致磁盘空间不足
expire-logs-days=2
  • 可通过show master status\G; 查看当前binlog日志的信息
  • 重启mysql服务
systemctl restart mysqld
  • 登录Mysql数据库,执行下面SQL
GRANT REPLCICATION SLAVE ON *.* TO '<用户名>'@'%'identified by '<密码>';
# 如果是mysql8,则执行下面SQL
//1.创建新用户
CREATE USER <用户名> IDENTIFIED WITH 'mysql_native_password' BY '<密码>';
//2.授权
GRANT REPLICATION SLAVE ON *.* TO <用户名>;
  • 执行show master status; 记录下File和Position的值

3.配置从库Slave

  • 修改Mysql数据库的配置文件/etc/my.cnf
server-id=101 #[必须]服务器唯一ID
  • 重启mysql服务
systemctl restart mysqld
  • 登录,并输入以下命令
CHANGE MASTER TO 
MASTER_HOST='<IP>',//主机IP
MASTER_USER='<username>',//之前创建的用户账号
MASTER_PASSWORD='<password>',//之前创建的用户密码
MASTER_LOG_FILE='<File>',//master主机的binlog日志名称,即File
MASTER_LOG_POS=<Position>,//binlog日志偏移量,即Position
master_port=3306;//端口
  • 启动
# 启动slave服务
start slave;
  • 查看从库状态
    • 执行代码
      show slave status\G;
      
    • 查询结果(简略)
      *************************** 1. row ***************************
             Slave_IO_State: Waiting for master to send event
                Master_Host: 192.168.0.104
                Master_User: root
                Master_Port: 3306
              Connect_Retry: 60
            Master_Log_File: mysql-bin.000001
        Read_Master_Log_Pos: 619
             Relay_Log_File: mysqld-relay-bin.000001
              Relay_Log_Pos: 782
      Relay_Master_Log_File: mysql-bin.000001 //binlog日志文件名称
           Slave_IO_Running: Yes //Slave_IO线程、SQL线程都在运行
          Slave_SQL_Running: Yes
           Master_Server_Id: 104 //master主机的服务id
                Master_UUID: 0ab6b3a6-e21d-11ea-aaa3-080027f8d623
           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 the slave I/O thread to update it
         Master_Retry_Count: 86400
              Auto_Position: 0
      

三.读写分离实现

1.添加sharding-jdbc的maven配置

<!-- sharding-jdbc -->
<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
    <version>4.1.1</version>
</dependency>

2.配置(参考)

# 这是使用druid连接池的配置,其他的连接池配置可能有所不同
spring:
  shardingsphere:
    datasource:
      names: master,slave0,slave1
      # 主数据源
      master:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://192.168.0.108:3306/test_db?useUnicode=true&characterEncoding=utf8&tinyInt1isBit=false&useSSL=false&serverTimezone=GMT
        username: # 用户名
        password: # 密码
      # 从数据源
      slave0:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://192.168.0.109:3306/test_db?useUnicode=true&characterEncoding=utf8&tinyInt1isBit=false&useSSL=false&serverTimezone=GMT
        username: # 用户名
        password: # 密码
      # 从数据源
      slave1:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://192.168.0.110:3306/test_db?useUnicode=true&characterEncoding=utf8&tinyInt1isBit=false&useSSL=false&serverTimezone=GMT
        username: # 用户名
        password: # 密码
    props:
      sql:
	show: true # 开始SQL演示,默认false
    masterslave:
      # 读写分离配置
      # 从库负载均衡策略
      load-balance-algorithm-type: round_robin # 从库轮询
    sharding:
      master-slave-rules:
        master:
	  # 主库数据源名称
          master-data-source-name: master
	  # 从库数据源名称,多个逗号分隔
          slave-data-source-names: slave0,slave1
	# 允许bean定义覆盖配置项
	main:
            allow-bean-definition-overriding: true

以上就是我的一些学习笔记,希望对大家有所帮助:D。