当前位置:数据库 > > 正文

mysql主从同步原理详解(MySQL双主主主架构配置方案)

时间:2021-10-21 07:17:29类别:数据库

mysql主从同步原理详解

MySQL双主主主架构配置方案

在企业中,数据库高可用一直是企业的重中之重,中小企业很多都是使用mysql主从方案,一主多从,读写分离等,但是单主存在单点故障,从库切换成主库需要作改动。因此,如果是双主或者多主,就会增加mysql入口,增加高可用。不过多主需要考虑自增长id问题,这个需要特别设置配置文件,比如双主,可以使用奇偶,总之,主之间设置自增长id相互不冲突就能完美解决自增长id冲突问题。

主从同步复制原理

在开始之前,我们先来了解主从同步复制原理。

复制分成三步:

1. master将改变记录到二进制日志(binary log)中(这些记录叫做二进制日志事件,binary log events);
2. slave将master的binary log events拷贝到它的中继日志(relay log);
3. slave重做中继日志中的事件,将改变反映它自己的数据。

下图描述了这一过程:

mysql主从同步原理详解(MySQL双主主主架构配置方案)

该过程的第一部分就是master记录二进制日志。在每个事务更新数据完成之前,master在二日志记录这些改变。mysql将事务串行的写入二进制日志,即使事务中的语句都是交叉执行的。在事件写入二进制日志完成后,master通知存储引擎提交事务。

下一步就是slave将master的binary log拷贝到它自己的中继日志。首先,slave开始一个工作线程——i/o线程。i/o线程在master上打开一个普通的连接,然后开始binlog dump process。binlog dump process从master的二进制日志中读取事件,如果已经跟上master,它会睡眠并等待master产生新的事件。i/o线程将这些事件写入中继日志。

sql slave thread处理该过程的最后一步。sql线程从中继日志读取事件,更新slave的数据,使其与master中的数据一致。只要该线程与i/o线程保持一致,中继日志通常会位于os的缓存中,所以中继日志的开销很小。

此外,在master中也有一个工作线程:和其它mysql的连接一样,slave在master中打开一个连接也会使得master开始一个线程。

mysql5.6以前的版本复制过程有一个很重要的限制——复制在slave上是串行化的,也就是说master上的并行更新操作不能在slave上并行操作。 mysql5.6版本参数slave-parallel-workers=1 表示启用多线程功能。

mysql5.6开始,增加了一个新特性,是加入了全局事务 id (gtid) 来强化数据库的主备一致性,故障恢复,以及容错能力。

官方文档:http://dev.mysql.com/doc/refman/5.6/en/replication-gtids.html

mysql双主(主主)架构方案思路是:

1.两台mysql都可读写,互为主备,默认只使用一台(mastera)负责数据的写入,另一台(masterb)备用;
2.mastera是masterb的主库,masterb又是mastera的主库,它们互为主从;
3.两台主库之间做高可用,可以采用keepalived等方案(使用vip对外提供服务);
4.所有提供服务的从服务器与masterb进行主从同步(双主多从);
5.建议采用高可用策略的时候,mastera或masterb均不因宕机恢复后而抢占vip(非抢占模式);
这样做可以在一定程度上保证主库的高可用,在一台主库down掉之后,可以在极短的时间内切换到另一台主库上(尽可能减少主库宕机对业务造成的影响),减少了主从同步给线上主库带来的压力;

但是也有几个不足的地方:

1.masterb可能会一直处于空闲状态(可以用它当从库,负责部分查询);
2.主库后面提供服务的从库要等masterb先同步完了数据后才能去masterb上去同步数据,这样可能会造成一定程度的同步延时;
架构的简易图如下:

mysql主从同步原理详解(MySQL双主主主架构配置方案)

主主环境(这里只介绍2台主的配置方案):

1.centos 6.8 64位 2台:mastera(192.168.10.11),masterb(192.168.10.12)

2.官方mysql5.6版本

搭建过程:

1.安装mysql服务(建议源码安装)

1.1 yum安装依赖包

  • ?
  • 1
  • yum -y install make gcc gcc-c++ ncurses-devel bison openssl-devel
  • 1.2 添加mysql所需要的用户和组

  • ?
  • 1
  • 2
  • groupadd -g 27 mysql
  • adduser -u 27 -g mysql -s /sbin/nologin mysql
  • 1.3 下载mysql源码包

  • ?
  • 1
  • 2
  • 3
  • 4
  • mkdir -p /data/packages/src
  • cd /data/packages/
  • wget http://distfiles.macports.org/cmake/cmake-3.2.3.tar.gz
  • wget http://dev.mysql.com/get/downloads/mysql-5.6/mysql-5.6.34.tar.gz
  • 1.4 创建mysql数据目录

  • ?
  • 1
  • mkdir -p /usr/local/mysql/data
  • 1.5 解压编译安装cmake、mysql

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • cd /data/packages/src
  • tar -zxvf ../cmake-3.2.3.tar.gz
  • cd cmake-3.2.3/
  • ./bootstrap
  • gmake
  • make install
  • cd ../
  • tar xf mysql-5.6.34.tar.gz
  • cd mysql-5.6.34
  • cmake . -dcmake_install_prefix=/usr/local/mysql -dsysconfdir=/etc \
  • -dwith_ssl=bundled -ddefault_charset=utf8 -ddefault_collation=utf8_general_ci \
  • -dwith_innobase_storage_engine=1 -dwith_myisam_storage_engine=1 \
  • -dmysql_tcp_port=3306 -dmysql_unix_addr=/tmp/mysql.sock \
  • -dmysql_datadir=/usr/local/mysql/data
  • make && make install
  • 1.6 添加开机启动脚本

  • ?
  • 1
  • cp support-files/mysql.server /etc/rc.d/init.d/mysqld
  • 1.7 添加mastera配置文件/etc/my.cnf

  • ?
  • 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
  • [client]
  • port = 3306
  • socket = /tmp/mysql.sock
  •  
  • [mysqld]
  • basedir = /usr/local/mysql
  • port = 3306
  • socket = /tmp/mysql.sock
  • datadir = /usr/local/mysql/data
  • pid-file = /usr/local/mysql/data/mysql.pid
  • log-error = /usr/local/mysql/data/mysql.err
  •  
  • server-id = 1
  • auto_increment_offset = 1
  • auto_increment_increment = 2                      #奇数id
  •  
  • log-bin = mysql-bin                           #打开二进制功能,master主服务器必须打开此项
  • binlog-format=row
  • binlog-row-p_w_picpath=minimal
  • log-slave-updates=true
  • gtid-mode=on
  • enforce-gtid-consistency=true
  • master-info-repository=table
  • relay-log-info-repository=table
  • sync-master-info=1
  • slave-parallel-workers=0
  • sync_binlog=0
  • binlog-checksum=crc32
  • master-verify-checksum=1
  • slave-sql-verify-checksum=1
  • binlog-rows-query-log_events=1
  • #expire_logs_days=5
  • max_binlog_size=1024m                          #binlog单文件最大值
  •  
  • replicate-ignore-db = mysql                       #忽略不同步主从的数据库
  • replicate-ignore-db = information_schema
  • replicate-ignore-db = performance_schema
  • replicate-ignore-db = test
  • replicate-ignore-db = zabbix
  •  
  • max_connections = 3000
  • max_connect_errors = 30
  •  
  • skip-character-set-client-handshake                   #忽略应用程序想要设置的其他字符集
  • init-connect='set names utf8'                      #连接时执行的sql
  • character-set-server=utf8                        #服务端默认字符集
  • wait_timeout=1800                            #请求的最大连接时间
  • interactive_timeout=1800                        #和上一参数同时修改才会生效
  • sql_mode=no_engine_substitution,strict_trans_tables           #sql模式
  • max_allowed_packet = 10m
  • bulk_insert_buffer_size = 8m
  • query_cache_type = 1
  • query_cache_size = 128m
  • query_cache_limit = 4m
  • key_buffer_size = 256m
  • read_buffer_size = 16k
  •  
  • skip-name-resolve
  • slow_query_log=1
  • long_query_time = 6
  • slow_query_log_file=slow-query.log
  • innodb_flush_log_at_trx_commit = 2
  • innodb_log_buffer_size = 16m
  •  
  • [mysql]
  • no-auto-rehash
  •  
  • [myisamchk]
  • key_buffer_size = 20m
  • sort_buffer_size = 20m
  • read_buffer = 2m
  • write_buffer = 2m
  •  
  • [mysqlhotcopy]
  • interactive-timeout
  •  
  • [mysqldump]
  • quick
  • max_allowed_packet = 16m
  •  
  • [mysqld_safe]
  • 1.8 特别参数说明

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • log-slave-updates = true   #将复制事件写入binlog,一台服务器既做主库又做从库此选项必须要开启
  • #mastera自增长id
  • auto_increment_offset = 1
  • auto_increment_increment = 2                      #奇数id
  • #masterb自增加id
  • auto_increment_offset = 2
  • auto_increment_increment = 2                      #偶数id
  • 1.9 添加masterb配置文件/etc/my.cnf

  • ?
  • 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
  • [client]
  • port = 3306
  • socket = /tmp/mysql.sock
  •  
  • [mysqld]
  • basedir = /usr/local/mysql
  • port = 3306
  • socket = /tmp/mysql.sock
  • datadir = /usr/local/mysql/data
  • pid-file = /usr/local/mysql/data/mysql.pid
  • log-error = /usr/local/mysql/data/mysql.err
  •  
  • server-id = 2
  • auto_increment_offset = 2
  • auto_increment_increment = 2                      #偶数id
  •  
  • log-bin = mysql-bin                           #打开二进制功能,master主服务器必须打开此项
  • binlog-format=row
  • binlog-row-p_w_picpath=minimal
  • log-slave-updates=true
  • gtid-mode=on
  • enforce-gtid-consistency=true
  • master-info-repository=table
  • relay-log-info-repository=table
  • sync-master-info=1
  • slave-parallel-workers=0
  • sync_binlog=0
  • binlog-checksum=crc32
  • master-verify-checksum=1
  • slave-sql-verify-checksum=1
  • binlog-rows-query-log_events=1
  • #expire_logs_days=5
  • max_binlog_size=1024m                          #binlog单文件最大值
  •  
  • replicate-ignore-db = mysql                       #忽略不同步主从的数据库
  • replicate-ignore-db = information_schema
  • replicate-ignore-db = performance_schema
  • replicate-ignore-db = test
  • replicate-ignore-db = zabbix
  •  
  • max_connections = 3000
  • max_connect_errors = 30
  •  
  • skip-character-set-client-handshake                   #忽略应用程序想要设置的其他字符集
  • init-connect='set names utf8'                      #连接时执行的sql
  • character-set-server=utf8                        #服务端默认字符集
  • wait_timeout=1800                            #请求的最大连接时间
  • interactive_timeout=1800                        #和上一参数同时修改才会生效
  • sql_mode=no_engine_substitution,strict_trans_tables           #sql模式
  • max_allowed_packet = 10m
  • bulk_insert_buffer_size = 8m
  • query_cache_type = 1
  • query_cache_size = 128m
  • query_cache_limit = 4m
  • key_buffer_size = 256m
  • read_buffer_size = 16k
  •  
  • skip-name-resolve
  • slow_query_log=1
  • long_query_time = 6
  • slow_query_log_file=slow-query.log
  • innodb_flush_log_at_trx_commit = 2
  • innodb_log_buffer_size = 16m
  •  
  • [mysql]
  • no-auto-rehash
  •  
  • [myisamchk]
  • key_buffer_size = 20m
  • sort_buffer_size = 20m
  • read_buffer = 2m
  • write_buffer = 2m
  •  
  • [mysqlhotcopy]
  • interactive-timeout
  •  
  • [mysqldump]
  • quick
  • max_allowed_packet = 16m
  •  
  • [mysqld_safe]
  • 1.10 初始化mysql

  • ?
  • 1
  • 2
  • cd /usr/local/mysql
  • scripts/mysql_install_db --user=mysql
  • 1.11 为启动脚本赋予可执行权限并启动mysql

  • ?
  • 1
  • 2
  • chmod +x /etc/rc.d/init.d/mysqld
  • /etc/init.d/mysqld start
  • 2. 配置主从同步

    2.1 添加主从同步账户
    mastera上:

  • ?
  • 1
  • 2
  • mysql> grant replication slave on *.* to 'repl'@'192.168.10.12' identified by '123456';
  • mysql> flush privileges;
  • masterb上:

  • ?
  • 1
  • 2
  • mysql> grant replication slave on *.* to 'repl'@'192.168.10.11' identified by '123456';
  • mysql> flush privileges;
  • 2.2 查看主库的状态
    mastera上:

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • mysql> show master status;
  •  
  • +------------------+----------+--------------+------------------+-------------------+
  •  
  • | file       | position | binlog_do_db | binlog_ignore_db | executed_gtid_set |
  •  
  • +------------------+----------+--------------+------------------+-------------------+
  •  
  • | mysql-bin.000003 |   120 |       |         |          |
  •  
  • +------------------+----------+--------------+------------------+-------------------+
  •  
  • 1 row in set (0.00 sec)
  • masterb上

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • mysql> show master status;
  •  
  • +------------------+----------+--------------+------------------+-------------------+
  •  
  • | file       | position | binlog_do_db | binlog_ignore_db | executed_gtid_set |
  •  
  • +------------------+----------+--------------+------------------+-------------------+
  •  
  • | mysql-bin.000003 |   437 |       |         |          |
  •  
  • +------------------+----------+--------------+------------------+-------------------+
  •  
  • 1 row in set (0.00 sec)
  • 2.3 配置同步信息:

    mastera上:

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • mysql> change master to master_host='192.168.10.12',master_port=3306,master_user='repl',master_password='123456',master_log_file='mysql-bin.000003',master_log_pos=437;
  •  
  • mysql> start slave;
  •  
  • mysql> show slave status\g;
  • 显示有如下状态则正常:

  • ?
  • 1
  • 2
  • 3
  • slave_io_running: yes
  •  
  • slave_sql_running: yes
  • masterb上:

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • #本人是测试环境,可以保证没数据写入,否则需要的步骤是:先mastera锁表-->mastera备份数据-->mastera解锁表 -->masterb导入数据-->masterb设置主从-->查看主从
  •  
  • mysql> change master to master_host='192.168.10.11',master_port=3306,master_user='repl',master_password='123456',master_log_file='mysql-bin.000003',master_log_pos=120;
  •  
  • start slave;
  •  
  • mysql> show slave status\g;
  • 显示有如下状态则正常:

  • ?
  • 1
  • 2
  • 标签:

    猜您喜欢