Featured image of post MySQL集群实战(一主多从,两主多从到SpringBoot多数据源实战)

MySQL集群实战(一主多从,两主多从到SpringBoot多数据源实战)

一主多从,两主多从到SpringBoot多数据源实战

MySQL主从复制概述

​ 在实际生产中,数据的重要性不言而喻

​ 如果我们的数据库只有一台服务器,那么很容易产生单点故障的问题,比如这台服务器访问压力过大而没有响应或者奔溃,那么服务就不可用了,再比如这台服务器的硬盘坏了,那么整个数据库的数据就全部丢失了,这是重大的安全事故.

​ 为了避免服务的不可用以及保障数据的安全可靠性,我们至少需要部署两台或两台以上服务器来存储数据库数据,也就是我们需要将数据复制多份部署在多台不同的服务器上,即使有一台服务器出现故障了,其他服务器依然可以继续提供服务.

​ MySQL提供了主从复制功能以提高服务的可用性与数据的安全可靠性.

​ 主从复制是指服务器分为主服务器和从服务器,主服务器负责读和写,从服务器只负责读,主从复制也叫 master/slave,master是主,slave是从,但是并没有强制,也就是说从也可以写,主也可以读,只不过一般我们不这么做。

​ 主从复制可以实现对数据库备份和读写分离

MySQL的主从复制架构

一主多从架构

双主双从结构

MySQL主从复制原理

  • 当主库服务器上的数据发生改变时,则将其改变写入二进制事件日志文件中

  • 从库服务器会在一定时间间隔内对主库服务器上的二进制日志进行探测,探测其是否发生过改变,如果探测到主库服务器的二进制事件日志发生了改变,则开始一个 I/O Thread 请求 master 二进制事件日志

  • 同时主库服务器为每个 I/O Thread 启动一个dump Thread,用于向其发送二进制事件日志

  • 从库服务器将接收到的二进制事件日志保存至自己本地的中继日志文件(relaylog)中

  • 从库服务器将启动 SQL Thread 从中继日志中读取二进制日志,在本地重放,使得其数据和主服务器保持一致;

  • 最后 I/O Thread 和 SQL Thread 将进入睡眠状态,等待下一次被唤醒

主从复制的过程会有很小的延迟,基本没有影响

MySQL多实例搭建

​ MySQL的多实例就是指安装了MySQL之后,在一台Linux机器上启动多个MySQL实例(主要用于学习)。

多实例配置

  • 安装mysql,下载mysql的安装包之后,解压。

  • 创建mysql用户和用户组

    1
    2
    3
    
    groupadd mysql
    useradd -r -g mysql mysql
    chown -R mysql.mysql /usr/local/mysql5.7
    
  • 创建数据目录用于存放mysql多实例数据。

    1
    2
    3
    4
    
    mkdir -p /usr/local/mysql5.7/data/3307
    mkdir -p /usr/local/mysql5.7/data/3308
    mkdir -p /usr/local/mysql5.7/data/3309
    mkdir -p /usr/local/mysql5.7/data/3310
    
  • 在mysql的解压目录下的bin目录下执行命令:

    1
    2
    3
    4
    5
    6
    7
    
    ./mysqld --initialize --console --basedir=/usr/local/mysql5.7 --datadir=/usr/local/mysql5.7/data/3307 --user=mysql
    
    ./mysqld --initialize --console --basedir=/usr/local/mysql5.7 --datadir=/usr/local/mysql5.7/data/3308 --user=mysql
    
    ./mysqld --initialize --console --basedir=/usr/local/mysql5.7 --datadir=/usr/local/mysql5.7/data/3309 --user=mysql
    
    ./mysqld --initialize --console --basedir=/usr/local/mysql5.7 --datadir=/usr/local/mysql5.7/data/33010 --user=mysql
    

    注意:–initialize 会随机生成root用户的密码。–console控制台输出初始化日志。这就可以看到生成的root密码。–user指定运行MySQL实例的用户

  • 在各自的数据目录下创建配置文件

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    
    #================3307端口================
    [client]
    port        = 3307
    socket      = /usr/local/mysql5.7/data/3307/mysql.sock
    default-character-set=utf8
    
    [mysqld]
    port    = 3307
    socket  = /usr/local/mysql5.7/data/3307/mysql.sock
    datadir = /usr/local/mysql5.7/data/3307
    log-error = /usr/local/mysql5.7/data/3307/error.log
    pid-file = /usr/local/mysql5.7/data/3307/mysql.pid
    
    character-set-server=utf8
    lower_case_table_names=1
    autocommit = 1
    
    #================3308端口================
    [client]
    port        = 3308
    socket      = /usr/local/mysql5.7/data/3308/mysql.sock
    default-character-set=utf8
    
    [mysqld]
    port    = 3308
    socket  = /usr/local/mysql5.7/data/3308/mysql.sock
    datadir = /usr/local/mysql5.7/data/3308
    log-error = /usr/local/mysql5.7/data/3308/error.log
    pid-file = /usr/local/mysql5.7/data/3308/mysql.pid
    
    character-set-server=utf8
    lower_case_table_names=1
    autocommit = 1
    
    
    #================3309端口================
    [client]
    port        = 3309
    socket      = /usr/local/mysql5.7/data/3309/mysql.sock
    default-character-set=utf8
    
    [mysqld]
    port    = 3309
    socket  = /usr/local/mysql5.7/data/3309/mysql.sock
    datadir = /usr/local/mysql5.7/data/3309
    log-error = /usr/local/mysql5.7/data/3309/error.log
    pid-file = /usr/local/mysql5.7/data/3309/mysql.pid
    
    character-set-server=utf8
    lower_case_table_names=1
    autocommit = 1
    
    
    #================3310端口================
    [client]
    port        = 3310
    socket      = /usr/local/mysql5.7/data/3310/mysql.sock
    default-character-set=utf8
    
    [mysqld]
    port    = 3310
    socket  = /usr/local/mysql5.7/data/3310/mysql.sock
    datadir = /usr/local/mysql5.7/data/3310
    log-error = /usr/local/mysql5.7/data/3310/error.log
    pid-file = /usr/local/mysql5.7/data/3310/mysql.pid
    
    character-set-server=utf8
    lower_case_table_names=1
    autocommit = 1
    

启动多实例

在MySQL的安装目录下bin目录执行

1
2
3
4
5
6
7
./mysqld_safe --defaults-file=/usr/local/mysql5.7/data/3307/my.cnf &

./mysqld_safe --defaults-file=/usr/local/mysql5.7/data/3308/my.cnf &

./mysqld_safe --defaults-file=/usr/local/mysql5.7/data/3309/my.cnf &

./mysqld_safe --defaults-file=/usr/local/mysql5.7/data/3310/my.cnf &

登录实例

1
2
3
4
./mysql -uroot -p -P3307 -h127.0.0.1
./mysql -uroot -p -P3308 -h127.0.0.1
./mysql -uroot -p -P3309 -h127.0.0.1
./mysql -uroot -p -P3310 -h127.0.0.1

修改密码

alter user 'root'@'localhost' identified by '123456;'

开启远程访问许可

grant all privileges on *.* to root@'%' identified by '123456';

其中*.* 的第一个表示所有数据库名,第二个表示所有的数据库表

root@’%’ 中的root表示用户名

%表示所有ip地址,%也可以指定具体的ip地址,比如root@localhost,root@192.168.10.129。

刷新权限

flush privileges;

多实例关闭

1
2
3
4
./mysqladmin -uroot -p -P3307 -h127.0.0.1 shutdown
./mysqladmin -uroot -p -P3308 -h127.0.0.1 shutdown
./mysqladmin -uroot -p -P3309 -h127.0.0.1 shutdown
./mysqladmin -uroot -p -P3310 -h127.0.0.1 shutdown

MySQL一主多从架构搭建

配置文件

在MySQL主服务器(3307)配置文件my.cnf里面加入

log-bin=mysql-bin #表示启用二进制日志

server-id=3307 #表示server编号,编号要唯一

在MySQL从服务器(3308)配置文件my.cnf里面加入

server-id=3308

在MySQL从服务器(3309)配置文件my.cnf里面加入

server-id=3309

在MySQL从服务器(3310)配置文件my.cnf里面加入

server-id=3310

主库配置

  1. 登录,./mysql -uroot -p -P3307 -h127.0.0.1

  2. 创建复制数据的账户并且授权:grant replication slave on *.* to 'copy'@'%' identified by '123456';

  3. 查看主库状态

    mysql主库状态默认值:File:mysql-bin.000001Position:154。因为执行过授权语句,所以偏移量会变化。所以需要充值一下master的偏移量。

从库配置

  1. 查看从库状态:show slave status \G;结果会是:Empty set (0.00 sec)。从库的初始状态。如果不是需要重置:reset slave;

  2. 设置监听的主库并开始执行复制

    1
    2
    3
    
    change master to master_host='192.168.79.150',master_user='copy',master_port=3307,master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=154;
    
    start slave;
    

    master_host :Master的IP地址

    master_port:Master的端口号,指的是容器的端口号

    master_user:用于数据同步的用户

    master_password:用于同步的用户的密码

    master_log_file:指定 Slave 从哪个日志文件开始复制数据,即上文中提到的 File 字段的值

    master_log_pos:从哪个 Position 开始读,即上文中提到的 Position 字段的值

  3. 查看从库状态:show slave status;

    Slave_IO_RunningSlave_SQL_Running的值为yes说明slave开启成功

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    
    mysql> show slave status \G;
    *************************** 1. row ***************************
                   Slave_IO_State: Waiting for master to send event
                      Master_Host: 192.168.79.150
                      Master_User: copy
                      Master_Port: 3307
                    Connect_Retry: 60
                  Master_Log_File: mysql-bin.000001
              Read_Master_Log_Pos: 154
                   Relay_Log_File: dev1-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: 154
                  Relay_Log_Space: 526
                  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: 3307
                      Master_UUID: be3a5680-8fdd-11eb-897a-000c297b3e36
                 Master_Info_File: /usr/local/mysql5.7/data/3309/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)
    

测试

  1. 连接上主库,在主库创建一个数据库,再在此库里面创建一个表并写入一下数据。

  2. 为了方便可以使用Navicat之类的软件进行操作

  3. 查看在主库创建的表数据库和表及其数据是否存在。数据存在主从模式搭建成功

  4. 查看一下主库的binlong:show binlog events in 'mysql-bin.000001'\G;

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    
    mysql> show binlog events in 'mysql-bin.000001'\G;
    *************************** 1. row ***************************
       Log_name: mysql-bin.000001
            Pos: 4
     Event_type: Format_desc
      Server_id: 3307
    End_log_pos: 123
           Info: Server ver: 5.7.24-log, Binlog ver: 4
    *************************** 2. row ***************************
       Log_name: mysql-bin.000001
            Pos: 123
     Event_type: Previous_gtids
      Server_id: 3307
    End_log_pos: 154
           Info:
    *************************** 3. row ***************************
       Log_name: mysql-bin.000001
            Pos: 154
     Event_type: Anonymous_Gtid
      Server_id: 3307
    End_log_pos: 219
           Info: SET @@SESSION.GTID_NEXT= 'ANONYMOUS'
    *************************** 4. row ***************************
       Log_name: mysql-bin.000001
            Pos: 219
     Event_type: Query
      Server_id: 3307
    End_log_pos: 368
           Info: CREATE DATABASE `shop` CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_general_ci'
    *************************** 5. row ***************************
       Log_name: mysql-bin.000001
            Pos: 368
     Event_type: Anonymous_Gtid
      Server_id: 3307
    End_log_pos: 433
           Info: SET @@SESSION.GTID_NEXT= 'ANONYMOUS'
    *************************** 6. row ***************************
       Log_name: mysql-bin.000001
            Pos: 433
     Event_type: Query
      Server_id: 3307
    End_log_pos: 628
           Info: use `shop`; CREATE TABLE `shop`.`order`  (
      `id` int NOT NULL AUTO_INCREMENT,
      `name` varchar(255) NULL,
      PRIMARY KEY (`id`)
    )
    *************************** 7. row ***************************
       Log_name: mysql-bin.000001
            Pos: 628
     Event_type: Anonymous_Gtid
      Server_id: 3307
    End_log_pos: 693
           Info: SET @@SESSION.GTID_NEXT= 'ANONYMOUS'
    *************************** 8. row ***************************
       Log_name: mysql-bin.000001
            Pos: 693
     Event_type: Query
      Server_id: 3307
    End_log_pos: 765
           Info: BEGIN
    *************************** 9. row ***************************
       Log_name: mysql-bin.000001
            Pos: 765
     Event_type: Table_map
      Server_id: 3307
    End_log_pos: 816
           Info: table_id: 109 (shop.order)
    *************************** 10. row ***************************
       Log_name: mysql-bin.000001
            Pos: 816
     Event_type: Write_rows
      Server_id: 3307
    End_log_pos: 862
           Info: table_id: 109 flags: STMT_END_F
    *************************** 11. row ***************************
       Log_name: mysql-bin.000001
            Pos: 862
     Event_type: Xid
      Server_id: 3307
    End_log_pos: 893
           Info: COMMIT /* xid=94 */
    *************************** 12. row ***************************
       Log_name: mysql-bin.000001
            Pos: 893
     Event_type: Anonymous_Gtid
      Server_id: 3307
    End_log_pos: 958
           Info: SET @@SESSION.GTID_NEXT= 'ANONYMOUS'
    *************************** 13. row ***************************
       Log_name: mysql-bin.000001
            Pos: 958
     Event_type: Query
      Server_id: 3307
    End_log_pos: 1030
           Info: BEGIN
    *************************** 14. row ***************************
       Log_name: mysql-bin.000001
            Pos: 1030
     Event_type: Table_map
      Server_id: 3307
    End_log_pos: 1081
           Info: table_id: 109 (shop.order)
    *************************** 15. row ***************************
       Log_name: mysql-bin.000001
            Pos: 1081
     Event_type: Write_rows
      Server_id: 3307
    End_log_pos: 1126
           Info: table_id: 109 flags: STMT_END_F
    *************************** 16. row ***************************
       Log_name: mysql-bin.000001
            Pos: 1126
     Event_type: Xid
      Server_id: 3307
    End_log_pos: 1157
           Info: COMMIT /* xid=97 */
    16 rows in set (0.00 sec)
    
  5. 查看slave的状态

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    
    mysql> mysql> show slave status \G;
    *************************** 1. row ***************************
                   Slave_IO_State: Waiting for master to send event
                      Master_Host: 192.168.79.150
                      Master_User: copy
                      Master_Port: 3307
                    Connect_Retry: 60
                  Master_Log_File: mysql-bin.000001
              Read_Master_Log_Pos: 1157
                   Relay_Log_File: dev1-relay-bin.000002
                    Relay_Log_Pos: 1323
            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: 1157
                  Relay_Log_Space: 1529
                  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: 3307
                      Master_UUID: be3a5680-8fdd-11eb-897a-000c297b3e36
                 Master_Info_File: /usr/local/mysql5.7/data/3308/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)
    

注意事项

​ 在主库写入数据,数据会同步到从库中,但是当在从库写入一条数据时并不会同步到其他从库和主库中。当一个表的数据的主键是自增的。当主库插入数据时,单独在从库写入的数据和主库同步过来的数据的主键发生冲突时,该从库的数据不会显示主库同步过来的数据。此时从库的状态中:

1
2
3
4
Read_Master_Log_Pos: 1157  # 这一项依旧会随着主库的写入而变化,即同步主库的数据。
Relay_Log_Pos: 1323        # 这一项会停止不动,这是中继日志的操作。数据会无法回放
Slave_IO_Running: Yes
Slave_SQL_Running: NO      # 这一项会变成No。

查看从库的状态。Last_Error字段就会报错。

解决方法:

  1. 删掉从库上与主库冲突的数据。然后停止stop slave;,再重启start slave;。这时候就会重新生成中继文件,重新同步数据。
  2. 删除掉从库上的整个表或数据库,重新添加主库。不过这样的操作会复制很多的数据,毕竟整个表和数据库都被删除了。

MySQL多主多从架构搭建

​ 上面一主多从的架构,如果主库的服务器宕机了,写操作就会完成不了,读操作时可以的(因为一般MySQL的主从架构就是用于读写分离的)。这样一个主库的架构就会出现单点故障了。

3307端口的MySQL为主库,3309端口的MySQL为其从库

3308端口的MySQL为主库,3310端口的MySQL为其从库

3307端口的MySQL和3309端口的MySQL护卫主从

配置文件的配置

在第一台主服务器3307端口的MySQL的my.cnf文件增加如下配置

1
2
3
4
5
6
7
auto_increment_increment=2

auto_increment_offset=1

log-slave-updates

sync_binlog=1

在第二台主服务器3308端口的MySQL的my.cnf文件增加如下配置

1
2
3
4
5
6
7
auto_increment_increment=2

auto_increment_offset=2

log-slave-updates

sync_binlog=1

配置项说明

  1. auto_increment_increment

    控制主键自增的自增步长,用于防止Master与Master之间复制出现重复自增字段值,通常auto_increment_increment=n,有多少台主服务器,n 就设置为多少

  2. auto_increment_offset=1

    设置自增起始值,这里设置为1,这样Master的auto_increment字段产生的数值是:1, 3, 5, 7, …等奇数ID

    auto_increment_offset的设置,不同的master设置不应该一样,否则就容易引起主键冲突,比如master1的offset=1,则master2的offset=2,master3的offset=3

  3. log-slave-updates

    在双主模式中,log-slave-updates 配置项一定要配置,否则在master1(3307端口)上进行了更新数据,在master2(3308端口)和slave1(3309端口)上会更新,但是在slave2(3310端口)上不会更新

  4. sync_binlog

    表示每几次事务提交,MySQL把binlog缓存刷进日志文件中,默认是0,最安全的是设置为1。

    sync_binlog=0,当事务提交之后,MySQL不做fsync之类的磁盘同步指令刷新binlog_cache中的信息到磁盘,而让Filesystem自行决定什么时候来做同步,或者cache满了之后才同步到磁盘

    sync_binlog=n,当每进行n次事务提交之后,MySQL将进行一次fsync之类的磁盘同步指令来将binlog_cache中的数据强制写入磁盘

注意事项

​ 从库只开启log-bin功能,不添加log-slave-updates参数,从库从主库复制的数据不会写入log-bin日志文件里。开启log-slave-updates参数后,从库从主库复制的数据会写入log-bin日志文件里。这也是该参数的功能,直接向从库写入数据时,是会写入log-bin日志的。

​ 在自动生成主键的时候,会在已生成主键的基础上按照规则生成,即比存在的值大。

主从库的配置

  1. 启动分别启动MySQL

    1
    2
    3
    4
    5
    6
    7
    
    ./mysqld_safe --defaults-file=/usr/local/mysql5.7/data/3307/my.cnf &
    
    ./mysqld_safe --defaults-file=/usr/local/mysql5.7/data/3308/my.cnf &
    
    ./mysqld_safe --defaults-file=/usr/local/mysql5.7/data/3309/my.cnf &
    
    ./mysqld_safe --defaults-file=/usr/local/mysql5.7/data/3310/my.cnf &
    
  2. 在3308端口的MySQL里执行:grant replication slave on *.* to 'copy'@'%' identified by '123456';由于3307端口的MySQL已经执行过。

  3. 重置Master:reset master;不重置也可以,再从库监听主库的时候,制定好biglog的名字就好。重置后都是:mysql-bin.000001

  4. 在3308端口的MySQL执行,因为3308端口、3309端口和3310端口在上面设置过主从配置。

    1
    2
    
    stop slave;
    reset salve;
    
  5. 从库监听主库

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    #==============在3307端口和3310端口的MySQL里执行===============
    change master to master_host='192.168.79.150',master_user='copy',master_port=3308,master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=154;
    
    start slave;
    
    #==============在3308端口和3309端口的MySQL里执行===============
    change master to master_host='192.168.79.150',master_user='copy',master_port=3307,master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=154;
    
    start slave;
    

    测试

    跟上一节的一主多从的测试一样。

代码实战:多数据源配置

​ 当我们的MySQL集群搭建好了之后,那就要在代码里面使用了。一般我们在写代码时,数据源都是只设置了一个。现在这么多个数据源,又要怎么使用呢!

​ 有两种情况:1、做读写分离。2、只操作主库,从库只是当作备份。

方案一:MyBatis的Mapper包隔离

核心原理

基于Mapper包的隔离,每个Mapper包操作不同的数据库,每个Mapper包对应一个数据库。

代码实现

pom.xml:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.msr</groupId>
    <artifactId>spring-mybatis-mutil-datasource</artifactId>
    <version>1.0</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <!--Spring相关的依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.1.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.1.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.4.RELEASE</version>
        </dependency>

        <!--Mybatis框架依赖-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.6</version>
        </dependency>
        <!--Mybatis与Spring整合依赖-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.3.2</version>
        </dependency>
        <!--MySQL数据库连接驱动 版本不要过高-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql