0%

复制模式

MySQL主从复制包括异步模式、半同步模式、GTID模式以及多源复制模式,默认是异步模式.

  • 异步复制(Asynchronous replication

所谓异步模式指的是MySQL 主服务器上I/O thread 线程将二进制日志写入binlog文件之后就返回客户端结果,不会考虑二进制日志是否完整传输到从服务器以及是否完整存放到从服务器上的relay log(中继日志)中,这种模式一旦主服务(器)宕机,数据就可能会发生丢失。

  • 全同步复制(Fully synchronous replication

指当主库执行完一个事务,所有的从库都执行了该事务才返回给客户端。因为需要等待所有从库执行完该事务才能返回,所以全同步复制的性能必然会收到严重的影响。

  • 半同步复制(Semisynchronous replication

介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收到并写到relay log中才返回给客户端。相对于异步复制,半同步复制提高了数据的安全性,同时它也造成了一定程度的延迟,这个延迟最少是一个TCP/IP往返的时间。所以,半同步复制最好在低延时的网络中使用。

半同步潜藏问题

mysql5.7版本前,客户端事务在存储引擎层提交后,在得到从库确认的过程中,主库宕机了,客户端会收到事务提交失败的信息,此时,可能的情况有两种:

  • 事务还没发送到从库上
  • 事务已经发送到从库上

此时客户端由于提交失败,再次提交事务,出现问题.

mysql5.7版本引入新的半同步方式,事务提交需要从库同步完成.通过rpl_semi_sync_master_wait_point参数控制:

  • AFTER_SYNC , 这个是新的半同步方案
  • AFTER_COMMIT, 这个是老的半同步方案

开启半同步复制

半同步复制的安装部署条件:

  • MySQL 5.5及以上版本
  • 变量have_dynamic_loadingYES (查看命令:show variables like "have_dynamic_loading";)
  • 主从复制已经配置完成

半同步复制是以插件的形式安装的,默认安装包在/usr/local/mysql/lib/plugin/目录下.可以通过命令查看

-- 查看所有插件
show plugins;

-- 模糊查询
SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS  WHERE PLUGIN_NAME LIKE '%semi%';
  • 启动方式一:通过命令
-- 主库执行安装插件
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
-- 主库执行开启
SET GLOBAL rpl_semi_sync_master_enabled = 1;


-- 从库执行安装插件
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
-- 从库执行开启
SET GLOBAL rpl_semi_sync_master_enabled = 1;


-- 从库重启IO线程
STOP SLAVE IO_THREAD;
START SLAVE IO_THREAD;

-- 主库卸载插件(先关闭半同步复制功能)
UNINSTALL PLUGIN rpl_semi_sync_master;
-- 从库卸载插件(先关闭半同步复制功能)
UNINSTALL PLUGIN rpl_semi_sync_slave;
  • 启动方式二:通过my.cnf,需要重启mysql
# 主库配置
plugin-load=rpl_semi_sync_master=semisync_master.so
rpl_semi_sync_master_enabled=1

# 从库配置
plugin-load=rpl_semi_sync_slave=semisync_slave.so
rpl_semi_sync_slave_enabled=1

# 如果既是主又是从
plugin-load="rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so"
rpl-semi-sync-master-enabled=1
rpl-semi-sync-slave-enabled=1

需要注意,Mysql半同步复制并不是严格意义上的半同步复制。当半同步复制发生超时时(由rpl_semi_sync_master_timeout参数控制,单位是毫秒,默认为10000,即10s),会暂时关闭半同步复制,转而使用异步复制。当master dump线程发送完一个事务的所有事件之后,如果在rpl_semi_sync_master_timeout内,收到了从库的响应,则主从又重新恢复为半同步复制。一旦有一次超时自动降级为异步.

查看半同步复制状态

-- 查看插件
mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS  WHERE PLUGIN_NAME LIKE '%semi%';
+----------------------+---------------+
| PLUGIN_NAME          | PLUGIN_STATUS |
+----------------------+---------------+
| rpl_semi_sync_master | ACTIVE        |
+----------------------+---------------+
1 row in set (0.00 sec)

-- 主库
mysql> show status like 'Rpl_semi_sync_master_status';
+-----------------------------+-------+
| Variable_name               | Value |
+-----------------------------+-------+
| Rpl_semi_sync_master_status | ON    |
+-----------------------------+-------+
1 row in set (0.01 sec)

-- 从库
mysql> show status like 'Rpl_semi_sync_slave_status';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON    |
+----------------------------+-------+
1 row in set (0.00 sec)


-- 查看主库半同步插件运行参数
-- rpl_semi_sync_master_wait_for_slave_count 设置主需要等待多少个slave应答,才能返回给客户端,默认为1
mysql> show variables like '%Rpl%';
+-------------------------------------------+------------+
| Variable_name                             | Value      |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled              | ON         |
| rpl_semi_sync_master_timeout              | 10000      |
| rpl_semi_sync_master_trace_level          | 32         |
| rpl_semi_sync_master_wait_for_slave_count | 1          | 
| rpl_semi_sync_master_wait_no_slave        | ON         |
| rpl_semi_sync_master_wait_point           | AFTER_SYNC |
| rpl_stop_slave_timeout                    | 31536000   |
+-------------------------------------------+------------+

-- 查看从库半同步插件运行参数
mysql> show variables like '%Rpl%';
+---------------------------------+----------+
| Variable_name                   | Value    |
+---------------------------------+----------+
| rpl_semi_sync_slave_enabled     | ON       |
| rpl_semi_sync_slave_trace_level | 32       |
| rpl_stop_slave_timeout          | 31536000 |
+---------------------------------+----------+
3 rows in set (0.00 sec)


-- 查看主库半同步插件运行状态status
mysql> show status like '%Rpl_semi%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 1     |
| Rpl_semi_sync_master_net_avg_wait_time     | 0     |
| Rpl_semi_sync_master_net_wait_time         | 0     |
| Rpl_semi_sync_master_net_waits             | 1     |
| Rpl_semi_sync_master_no_times              | 0     |
| Rpl_semi_sync_master_no_tx                 | 0     |
| Rpl_semi_sync_master_status                | ON    |
| Rpl_semi_sync_master_timefunc_failures     | 0     |
| Rpl_semi_sync_master_tx_avg_wait_time      | 461   |
| Rpl_semi_sync_master_tx_wait_time          | 461   |
| Rpl_semi_sync_master_tx_waits              | 1     |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
| Rpl_semi_sync_master_wait_sessions         | 0     |
| Rpl_semi_sync_master_yes_tx                | 1     |
+--------------------------------------------+-------+
14 rows in set (0.00 sec)

简单测试

-- 正常情况下插入数据
mysql> insert into test.testttt values(1,'22');
Query OK, 1 row affected (0.00 sec)

-- 从库关闭主从复制
mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)

-- 再次插入数据,时间与设置的超时时间吻合
mysql> insert into test.testttt values(1,'222');
Query OK, 1 row affected (10.01 sec)

-- 查看半同步插件状态
mysql> show status like 'Rpl_semi_sync_master_status';
+-----------------------------+-------+
| Variable_name               | Value |
+-----------------------------+-------+
| Rpl_semi_sync_master_status | OFF   |
+-----------------------------+-------+
1 row in set (0.00 sec)

mysql> show status like 'Rpl_semi_sync_slave_status';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | OFF   |
+----------------------------+-------+
1 row in set (0.00 sec)

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

-- 再次插入数据,恢复正常
mysql> insert into test.testttt values(1,'222');
Query OK, 1 row affected (0.00 sec)

-- 查看半同步插件状态也是ON

其它注意参数

  • sync_binlog

默认,sync_binlog=0,表示MySQL不控制binlog的刷新,由文件系统自己控制它的缓存的刷新。这时候的性能是最好的,但是风险也是最大的。因为一旦系统Crash,在binlog_cache中的所有binlog信息都会被丢失。

如果sync_binlog>0,表示每sync_binlog次事务提交,MySQL调用文件系统的刷新操作将缓存刷下去。最安全的就是sync_binlog=1了,表示每次事务提交,MySQL都会把binlog刷下去,是最安全但是性能损耗最大的设置。

  • sync_relay_log

默认为10000,即每10000sync_relay_log事件会刷新到磁盘。为0则表示不刷新,交由系统的cache控制

  • 同步刷盘配置
# my.cnf,最安全配置,牺牲性能
sync_binlog=1
sync_master_info=1
sync_relay_log=1
sync_relay_log_info=1

参考链接

问题

双主之间复制如果网络中断或者其它原因导致不可用,此时在不同主上修改了同一条数据,就会存在数据不一致的情况。

解决办法

  1. 过滤到已知错误
#slave-skip-errors=all # 忽略复制产生的错误
#slave-skip-errors=1062,1032,1060 # 跳过已知错误,主键冲突、表已存在等错误代码如1062,1032,1060等

但是这样数据不一致的问题还是存在.

  1. 不用双主模式,改成主从模式,且从节点只能读不能写
    关闭双向复制,设置单向复制,一主一从
# 从节点设置不能写,设置完需要重启mysql服务
read_only=ON
super_read_only=ON

# SQL
FLUSH TABLES WITH READ LOCK;

非GTID模式下

BIN-LOG里面出现错误导致主从不能同步的时候,

-- 错误状态的部分截图
mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.41.141
             Slave_IO_Running: Yes
            Slave_SQL_Running: No
              Replicate_Do_DB:  
                   Last_Errno: 1032
                   Last_Error: Could not execute Update_rows event on table test.testttt; Can't find record in 'testttt', Error_code: 1032; handler error HA_ERR_END_OF_FILE; the event's master log mysql-bin.000004, end_log_pos 404
                 Skip_Counter: 0
               Last_SQL_Errno: 1032
               Last_SQL_Error: Could not execute Update_rows event on table test.testttt; Can't find record in 'testttt', Error_code: 1032; handler error HA_ERR_END_OF_FILE; the event's master log mysql-bin.000004, end_log_pos 404
  Replicate_Ignore_Server_Ids: 
           Retrieved_Gtid_Set: 69a5d660-cfd9-11ea-8174-00505626c27e:1-5
            Executed_Gtid_Set: 69a5d660-cfd9-11ea-8174-00505626c27e:4,
b3802ae3-cfd8-11ea-85e8-00505630c9f5:1-2
1 row in set (0.00 sec)

可以用下面方法掠过该错误语句行,继续同步:

stop slave;
set global sql_slave_skip_counter=1;
start slave;

set global sql_slave_skip_counter=1;是可能会出现一下错误:不支持GTID_MODE模式运行的数据库

ERROR 1858 (HY000): sql_slave_skip_counter can not be set when the server is running with GTID_MODE = ON. Instead, for each transaction that you want to skip, generate an empty transaction with the same GTID as the transaction

GTID模式下

  1. 找到错误点
show slave status\G
-- 找到这一行
Executed_Gtid_Set: 69a5d660-cfd9-11ea-8174-00505626c27e:1-5
  1. 重置master和slave
reset master;
stop slave;
reset slave;
  1. 设置跳过错误点
-- 1-5 可能出错,ID加1,1-6
set global gtid_purged='69a5d660-cfd9-11ea-8174-00505626c27e:1-6';

set global gtid_purged='xxxxx';要求GTID_EXECUTED为空,所以需要第二部重置操作.

  1. 重启复制
change master to master_host='192.168.41.141',master_port=3306,master_user='slave',master_password='123456',master_auto_position=1;
start slave;
  1. 查看
-- 确认Slave_IO_Running,Slave_SQL_Running,Last_Error,Last_SQL_Error等是否有错
-- 如果还有错但和上面的错误ID不一样,需要重复1~4
show slave status\G

双主模式更麻烦,需要两边都要做1~4操作,确认没有错误.

说明

前文仅仅通过mysql双主 + keepalived实现高可用,这种方式在一台出现问题的时候可以切换,但是正常情况下只有一台服务使用,无法实现负载均衡,本文引入haproxy实现正常情况下也能有负载均衡的效果.

配置

  1. 安装haproxy
yum install haproxy
  1. 修改haproxy配置文件
    默认目录:/etc/haproxy/haproxy.cfg
#---------------------------------------------------------------------
# Example configuration for a possible web application.  See the
# full configuration options online.
#
#   http://haproxy.1wt.eu/download/1.4/doc/configuration.txt
#
#---------------------------------------------------------------------

#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
    # to have these messages end up in /var/log/haproxy.log you will
    # need to:
    #
    # 1) configure syslog to accept network log events.  This is done
    #    by adding the '-r' option to the SYSLOGD_OPTIONS in
    #    /etc/sysconfig/syslog
    #
    # 2) configure local2 events to go to the /var/log/haproxy.log
    #   file. A line like the following can be added to
    #   /etc/sysconfig/syslog
    #
    #    local2.*                       /var/log/haproxy.log
    #
    log         127.0.0.1 local2

    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon

    # turn on stats unix socket
    stats socket /var/lib/haproxy/stats

#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    option forwardfor       except 127.0.0.0/8
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 3000


######## 监控界面配置 #################
listen admin_status
        bind 0.0.0.0:8888
        mode http
        stats refresh 30s
        stats uri /
        stats realm welcome login\ Haproxy
        stats auth admin:123456
        stats hide-version
        stats admin if TRUE
        ########frontend配置##############

######## mysql负载均衡配置 ###############
listen mysql
        bind 0.0.0.0:13306
        mode tcp
        balance roundrobin                  # 负载均衡策略
        #option tcplog                      # tcp日志
        option mysql-check user haproxy     # 在mysql中创建无任何权限用户haproxy,且无密码
        server mysql_1 192.168.41.141:3306 check weight 1 maxconn 2000
        server mysql_2 192.168.41.142:3306 check weight 1 maxconn 2000
        option tcpka                        # 缺少这个配置,可能无法查看到数据库

option mysql-check user haproxy这里是配置健康检查的,需要在mysql中创建无任何权限用户haproxy,且无密码.

  • CREATE USER 'haproxy'@'%' IDENTIFIED BY '';
  1. 修改ulimit配置
    haproxy要求ulimit大于(maxconn*2 + 15 )
#临时修改
ulimit -n 65536

#永久修改,需要修改/etc/security/limits.conf配置文件,文末增加以下内容,然后重新登录就可以生效
* soft nofile 65536
* hard nofile 65536
* soft nproc 65565
* hard nproc 65565
  1. 启动服务并配置自启动

启动后访问8888端口,使用admin/123456登录就可以看到UI界面了。

systemctl start haproxy
systemctl enable haproxy
  1. 修改keepalived配置
    前文配置的keepalived监控的是mysqld进程,需要修改成监控haproxy进程.这样不管哪台机器的mysql或者haproxy或者keepalived出现问题,都不影响使用.
# 修改的配置如下
vrrp_script chk_mysql {
    script "killall -0 haproxy"
    interval 2
    timeout 2
    fall 3
}
  1. 测试
    通过VIP连接数据库,增删改查测试.

说明

mysql双主模式下,在任意一台mysql上写数据都会同步到另一台上,本章通过keepalived VIP实现如果一台服务挂了会自动切换到另一台mysql上.

配置

# 安装keepalived,centos默认安装了
yum install keepalived -y

修改双主机/etc/keepalived/keepalived.conf配置.

global_defs {
   router_id mysql
}

vrrp_script chk_mysql {
    script "killall -0 mysqld"      // 检测mysql进程是否存活
    interval 2
    timeout 2
    fall 3
}

vrrp_instance mysql {
    state MASTER
    interface ens33
    virtual_router_id 51
    priority 100                // 另一台权重可以设置90,防止争抢VIP
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.41.140          // 设置虚拟ip
    }
    track_script {
        chk_mysql
    }
}

测试

# 通过命令可以看到VIP已经在一台机器上了,也可以通过虚拟IP连接上mysql
[root@mysql01 mysql]# ip addr sh ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:50:56:26:c2:7e brd ff:ff:ff:ff:ff:ff
    inet 192.168.41.141/24 brd 192.168.41.255 scope global ens33
       valid_lft forever preferred_lft forever
    inet 192.168.41.140/32 scope global ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::250:56ff:fe26:c27e/64 scope link 
       valid_lft forever preferred_lft forever
# 关掉mysql服务,命令可能根据你安装方式有区别
service mysql stop

# 再次在两台机器上执行命令,可以看到VIP转移了,可以继续通过VIP连接mysql
ip addr sh ens33

前提准备

主机 系统 IP mysql
mysql01 centos7 192.168.41.141 已部署5.7.31
mysql02 centod7 192.168.41.142 已部署5.7.31

原理

MySQL中有一种日志叫做 bin日志(二进制日志),这个日志会记录下所有修改了数据库的SQL语句。主从复制的原理其实就是从服务器主服务器请求这个日志文件,主服务器会把这个 bin日志复制到从服务器上执行一遍,这样从服务器上的数据就和主服务器上的数据相同了。

原理图

  1. 主服务器必须启用二进制日志(log-bin),记录任何修改了数据库数据的事件;
  2. 从服务器开启一个线程(I/O Thread)把自己扮演成 MySQL 的客户端,通过 MySQL 协议,请求主服务器的二进制日志文件中的事件;
  3. 主服务器启动一个线程(Dump Thread),检查自己二进制日志中的事件,跟对方请求的位置对比,如果不带请求位置参数,则主服务器就会从第一个日志文件中的第一个事件一个一个发送给从服务器;
  4. 从服务器接收到主服务器发送过来的数据把它放置到中继日志(relay log)文件中。并记录该次请求到主服务器的具体哪一个二进制日志文件内部的哪一个位置(主服务器中的二进制文件会有多个,其名结尾以6位数递增);
  5. 从服务器启动另外一个线程(SQL Thread),把 relay log 中的事件读取出来,并在本地再执行一次。

双主架构思路

  • 两台mysql都可读写,互为主备
  • 两台主库之间做高可用,可以采用haproxykeepalived等方案

双主配置

主要配置文件/etc/my.cnf

  1. 修改配置
vim /etc/my.cnf

# 添加以下配置
# id 保证唯一
server-id=1
# 开启binlog 日志
log-bin=mysql-bin
# 自增ID保证不冲突, 一主1,3,5 另一主2,4,6
auto-increment-increment=2
auto-increment-offset=1
# 将复制事件写入binlog,一台服务器既做主库又做从库此选项必须要开启
log-slave-updates=true
# 忽略同步的数据库
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema
replicate-ignore-db=mysql
replicate-ignore-db=sys
# binlog文件大小限制
max_binlog_size=1024M
# binlog格式
binlog-format=ROW

另一台配置

server-id=2
log-bin=mysql-bin
auto-increment-increment=2
auto-increment-offset=2
log-slave-updates=true
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema
replicate-ignore-db=mysql
replicate-ignore-db=sys
max_binlog_size=1024M
binlog-format=ROW
#binlog_rows_query_log_events=on # 在row 模式的binlog中包含SQL EVENTS(即SQL语句也会保留)
#master-info-repository=TABLE
#relay-log-info-repository=TABLE
#slave-skip-errors=all # 忽略复制产生的错误
#slave-skip-errors=1062,1032,1060 # 跳过已知错误,主键冲突、表已存在等错误代码如1062,1032,1060等
#relay-log-purge = 1    #是否自动清空不再需要中继日志时。默认值为1(启用)
#expire_logs_days = 30  #超过 30 天的 binlog 删除

slave_skip_errors参数说明:

slave_skip_errors选项有四个可用值,分别为:off,all,ErorCode,ddl_exist_errors, 默认情况下该参数值是off.
mysql5.6及MySQL Cluster NDB 7.3以及后续版本增加了参数ddl_exist_errors,该参数包含一系列error code(1007,1008,1050,1051,1054,1060,1061,1068,1094,1146)
一些error code代表的错误如下:
    1007:数据库已存在,创建数据库失败
    1008:数据库不存在,删除数据库失败
    1050:数据表已存在,创建数据表失败
    1051:数据表不存在,删除数据表失败
    1054:字段不存在,或程序文件跟数据库有冲突
    1060:字段重复,导致无法插入
    1061:重复键名
    1068:定义了多个主键
    1094:位置线程ID
    1146:数据表缺失,请恢复数据库
    1053:复制过程中主服务器宕机
    1062:主键冲突 Duplicate entry '%s' for key %d
  1. 重启mysql
# 根据安装方式选择
service mysql restart
  1. 添加主从同步账户
-- mysql01
grant replication slave on *.* to 'slave'@'192.168.41.142' identified by '123456';
flush privileges;

-- mysql02
grant replication slave on *.* to 'slave'@'192.168.41.141' identified by '123456';
flush privileges;
  1. 查看主库状态
-- 分别在mysql01,mysql02查看, 这里由于都是新安装的,status完全一样,实际可能不一样
-- 记住file的名字和position的值,因为主从同步,从数据库是通过读取主数据库的日志文件来完成同步的,所以需要文件名字和日志的当前位置
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      604 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
  1. 配置同步信息
-- mysql01
change master to master_host='192.168.41.142',master_port=3306,master_user='slave',master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=604;

start slave;

-- mysql02
change master to master_host='192.168.41.141',master_port=3306,master_user='slave',master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=604;

start slave;
  1. 查看同步状态
-- 分别在mysql01,mysql02查看同步状态
mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.41.141
                  Master_User: slave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 604
               Relay_Log_File: mysql02-relay-bin.000002
                Relay_Log_Pos: 320
        Relay_Master_Log_File: mysql-bin.000001
             Slave_IO_Running: Yes      -- 状态正常
            Slave_SQL_Running: Yes      -- 状态正常
  1. 测试
-- 随便在 mysql01 或 mysql02 上创建库、表或者数据都能同步到另一台机器上
create database test;

CREATE TABLE `t_type` (
                            `type_id` INT(2) NOT NULL AUTO_INCREMENT COMMENT '资源类型id',
                            `type_name` VARCHAR(32) NOT NULL COMMENT '资源类型名称',
                            `type_remark` VARCHAR(255) DEFAULT NULL COMMENT '备注',
                            `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
                            `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
                            PRIMARY KEY (`type_id`),
                            UNIQUE KEY (type_name)
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

insert into t_type(type_name, type_remark) VALUES ('菜单资源','用于确定页面菜单资源,分多级菜单');
insert into t_type(type_name, type_remark) VALUES ('按钮资源','用于确定页面按钮资源');
insert into t_type(type_name, type_remark) VALUES ('路由资源','用于确定网关路由资源');
  1. 开启MySQL5.6之后引入的GTID复制功能
vim /etc/my.cnf
# 增加以下配置,开启gtid
gtid-mode=on
enforce-gtid-consistency=on
# 修改完my.cnf需要重启mysql才能生效
-- mysql01,mysql02分别执行以下命令
mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)

mysql> change master to MASTER_AUTO_POSITION=1;
Query OK, 0 rows affected (0.01 sec)

mysql> start slave;
Query OK, 0 rows affected (0.00 sec)

GTID又叫全局事务IDGlobal Transaction ID),是一个已提交事务的编号,并且是一个全局唯一的编号。MySQL5.6版本之后在主从复制类型上新增了GTID复制

双主配置之前数据备份

使用mysqldump命令,MySQL操作mysqldump命令详解

-- 导出主数据库的数据
mysqldump -uroot -p --opt --all-databases >/all_databases.sql

-- 导入数据
mysql -u root -p  < /all_databases.sql

-- 或者使用source导入
-- mysql> source /all_databases.sql;