MySQL 主从复制是指数据可以从一个MySQL数据库服务器主节点复制到一个或多个从节点。MySQL 默认采用异步复制方式,这样从节点不用一直访问主服务器来更新自己的数据,数据的更新可以在远程连接上进行,从节点可以复制主数据库中的所有数据库或者特定的数据库,或者特定的表。
主从复制是MySQL最重要的功能之一。对于多级复制,数据库服务器即可充当主机,也可充当从机。MySQL主从复制的基础是主服务器对数据库修改记录二进制日志,从服务器通过主服务器的二进制日志自动执行更新。
binlog
主库中可以设置binlog,binlog是主库中保存更新事件日志的二进制文件。
主节点 binary log dump 线程
如上图所示:当从节点连接主节点时,主节点会创建一个log dump 线程,用于发送bin-log的内容。在读取bin-log中的操作时,此线程会对主节点上的bin-log加锁,当读取完成,甚至在发动给从节点之前,锁会被释放。
从节点I/O线程
当从节点上执行start slave
命令之后,从节点会创建一个I/O线程用来连接主节点,请求主库中更新的bin-log。I/O线程接收到主节点binlog dump 进程发来的更新之后,保存在本地relay-log中。
从节点SQL线程
SQL线程负责读取relay log中的内容,解析成具体的操作并执行,最终保证主从数据的一致性。
对于每一个主从连接,都需要三个进程来完成。当主节点有多个从节点时,主节点会为每一个当前连接的从节点建一个binary log dump 进程,而每个从节点都有自己的I/O进程,SQL进程。从节点用两个线程将从主库拉取更新和执行分成独立的任务,这样在执行同步数据任务的时候,不会降低读操作的性能。比如,如果从节点没有运行,此时I/O进程可以很快从主节点获取更新,尽管SQL进程还没有执行。如果在SQL进程执行之前从节点服务停止,至少I/O进程已经从主节点拉取到了最新的变更并且保存在本地relay日志中,当服务再次起来之后,就可以完成数据的同步。
主从复制过程说明
首先必须打开Master 端的binary log(bin-log)功能,否则无法实现。
因为整个复制过程实际上就是Slave 从Master 端获取该日志然后再在自己身上完全顺序的执行日志中所记录的各种操作。如下图所示:
一、 主库配置
1、修改主库配置文件my.cnf
[mysqld]
basedir=/usr/local/mysql
datadir=/data/mysql
socket=/tmp/mysql.sock
user=mysql
port=3306
character-set-server=utf8mb4
# cancle password
skip-grant-tables
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# 配置主从,注意一定要在[mysqld]节点下
server-id=1
log-bin=/data/mysql/mysqlbin
binlog-ignore-db=mysql
binlog-do-db=aemm
binlog-do-db=aoss
read_only = 0
expire_logs_days = 15
[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
主要参数说明:
server-id=1
:配置server-id,不能和从库重复log-bin=/data/mysql/mysqlbin
:配置log-bin文件名binlog-ignore-db=mysql
:配置不复制的库binlog-do-db=testdb1
:配置要复制的库binlog-do-db=testdb2
:可配置多个要复制的库read_only
:0表示可读可写,1表示只读(也可写成on)其他配置参数说明:
expire_logs_days
:通过此来实现master自动删除binlog
innodb_flush_log_at_trx_commit=1
:
此参数表示在事务提交时,处理重做日志的方式;此变量有三个可选值0,1,2:
0:当事务提交时,并不将事务的重做日志写入日志文件,而是等待每秒刷新一次
1:当事务提交时,将重做日志缓存的内容同步写到磁盘日志文件,为了保证数据一致性,在replication环境中使用此值。
2:当事务提交时,将重做日志缓存的内容异步写到磁盘日志文件(写到文件系统缓存中)
建议必须设置innodb_flush_log_at_trx_commit=1
sync_binlog=1
<1>此参数表示每写缓冲多少次就同步到磁盘;
<2>sync_binlog=1表示同步写缓冲和磁盘二进制日志文件,不使用文件系统缓存;
<3>在使用innodb事务引擎时,在复制环境中,为了保证最大的可用性,都设置为“1”,但会对影响io的性能。
<4>即使设置为“1”,也会有问题发生:假如当二进制日志写入磁盘,但事务还没有commit,这个时候宕机,当服务再次起来恢复的时候,无法回滚以及记录到二进制日志的未提交的内容;
这个时候就会造成master和slave数据不一致
<5>解决方案:
需要参数innodb_support_xa=1来保证。建议必须设置。
innodb_support_xa=1
此参数与XA事务有关,它保证了二进制日志和innodb数据文件的同步,保证复制环境中数据一致性。建议必须设置。
binlog-do-table=skate_tab
只记录指定表的更新到二进制日志中
log_slave_updates=1
此参数控制slave数据库是否把从master接受到的log并在本slave执行的内容记录到slave的二进制日志中
在级联复制环境中(包括双master环境),这个参数是必须的
binlog_format=statement|row|mixed
控制以什么格式记录二进制日志的内容,默认是mixed
max_binlog_size
master的每个二进制日志文件的大小,默认1G
binlog_cache_size
1、所有未提交的事务都会被记录到一个缓存或临时文件中,待提交时,统一同步到二进制日志中,
2、此变量是基于session的,每个会话开启一个binlog_cache_size大小的缓存。
3、通过变量“Binlog_cache_disk_use”和“Binlog_cache_use”来设置binlog_cache_size的大小。
说明:
Binlog_cache_disk_use
: 使用临时文件写二进制日志的次数
Binlog_cache_use
: 使用缓冲记写二进制的次数
auto_increment_increment=2
//增长的步长
auto_increment_offset=1 //起始位置
在双master环境下可以防止键值冲突
2、重启数据库,并授权给从库
授权给从库
grant replication slave on *.* to 'root'@'11.10.11.10' identified by '123456';
刷新配置
flush privileges;
查看主库状态
show master status;
主要参数说明:
1.File
:logbin文件;
2.Position
:指主库当前复制的起始位置;
3.Binlog_Do_DB
:要复制的数据库;
4.Binlog_Ignore_DB
:不被复制的数据库。
查看mysqlbin.000003文件,存储在数据库存储目录中,在my.cnf中可以查看
datadir=/data/mysql
二、 从库配置
1、修改从库配置文件my.cnf
[mysqld]
basedir=/usr/local/mysql
datadir=/data/mysql
socket=/tmp/mysql.sock
user=mysql
port=3306
character-set-server=utf8mb4
# cancle password
#skip-grant-tables
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# skip-grant-tables
# 从库配置
server-id=2
log-bin=/data/mysql/mysqlbin
binlog-ignore-db=mysql
binlog-do-db=aemm
binlog-do-db=aoss
skip_slave_start
#relay-log=slave-relay-bin
#relay-log-index=slave-relay-bin.index
#read_only = 1
#log_slave_updates=1
#sync_master_info=1
#sync_relay_log=1
#sync_relay_log_info=1
[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
主要参数说明:
server-id=2
:配置server-id,不能和主库或其他从库重复log-bin=/data/mysql/mysqlbin
:配置log-bin文件名binlog-ignore-db=mysql
:配置不复制的库binlog-do-db=testdb1
:配置要复制的库binlog-do-db=testdb2
:可配置多个要复制的库skip_slave_start
:复制进程就不会随着数据库的启动而启动,避免主从数据不一致其他配置参数说明:
log-bin=mysql-bin
和master的含义一样,开启二进制
relay-log=relay-bin
中继日志文件的路径名称
relay-log-index=relay-bin
中继日志索引文件的路径名称
log_slave_updates=1
和master的含义一样,如上
read_only=1
1、使数据库只读,此参数在slave的复制环境和具有super权限的用户不起作用,
2、对于复制环境设置read_only=1非常有用,它可以保证slave只接受master的更新,而不接受client的更新。
3、客户端设置:
mysq> show global variables like “%read_only%”;
mysq> set global read_only=1
skip_slave_start
使slave在mysql启动时不启动复制进程,mysql起来之后使用 start slave启动,建议必须
replicate-do-db
只复制指定db
replicate-do-table
只复制指定表
replicate-ingore-table
忽略指定表
replicate_wild_do_table=skatedb.%
模糊匹配复制指定db
auto_increment_increment=2
auto_increment_offset=1
和master含义一样,参考如上
log_slow_slave_statements
在slave上开启慢查询日志,在query的时间大于long_query_time时,记录在慢查询日志里
max_relay_log_size
slave上的relay log的大小,默认是1G
relay_log_info_file
中继日志状态信息文件的路径名称
relay_log_purge
当relay log不被需要时就删除,默认是on
SET GLOBAL relay_log_purge=1
`replicate-rewrite-db=from_name->to_name
数据库的重定向,可以把分库汇总到主库便于统计分析
2、配置主数据库
配置主数据库地址和logbin
change master to master_host='11.18.22.32', master_user='root', master_password='123456', master_log_file='mysqlbin.000003', master_log_pos=707;
启动从数据库服务
start slave;
停止命令是:
stop slave;
查看从数据库状态,启动IO和SQL线程
show slave status \G;
注:图中显示的配置参数都是配过的,红框中IO线程和SQL线程状态都是Yes,表示从库配置启动成功。
MySQL 主从复制默认是异步的模式。MySQL增删改操作会全部记录在binary log中,当slave节点连接master时,会主动从master处获取最新的bin log文件。并把bin log中的sql relay。
一、异步模式(mysql async-mode)
异步模式如下图所示,这种模式下,主节点不会主动push bin log到从节点,这样有可能导致failover的情况下,也许从节点没有即时地将最新的bin log同步到本地。
二、半同步模式(mysql semi-sync)
这种模式下主节点只需要接收到其中一台从节点的返回信息,就会commit;否则需要等待直到超时时间然后切换成异步模式再提交;这样做的目的可以使主从数据库的数据延迟缩小,可以提高数据安全性,确保了事务提交后,binlog至少传输到了一个从节点上,不能保证从节点将此事务更新到db中。性能上会有一定的降低,响应时间会变长。如下图所示:
半同步模式不是mysql内置的,从mysql 5.5开始集成,需要master 和slave 安装插件开启半同步模式。
三、全同步模式
全同步模式是指主节点和从节点全部执行了commit并确认才会向客户端返回成功。
Statement-base Replication(SBR)
就是记录sql语句在bin log中,Mysql 5.1.4 及之前的版本都是使用的这种复制格式。优点是只需要记录会修改数据的sql语句到binlog中,减少了binlog日质量,节约I/O,提高性能。缺点是在某些情况下,会导致主从节点中数据不一致(比如sleep(),now()等)。
Row-based Relication(RBR)
是mysql master将SQL语句分解为基于Row更改的语句并记录在bin log中,也就是只记录哪条数据被修改了,修改成什么样。优点是不会出现某些特定情况下的存储过程、或者函数、或者trigger的调用或者触发无法被正确复制的问题。缺点是会产生大量的日志,尤其是修改table的时候会让日志暴增,同时增加bin log同步时间。也不能通过bin log解析获取执行过的sql语句,只能看到发生的data变更。
Mixed-format Replication(MBR)
,MySQL NDB cluster 7.3 和7.4 使用的MBR。是以上两种模式的混合,对于一般的复制使用STATEMENT模式保存到binlog,对于STATEMENT模式无法复制的操作则使用ROW模式来保存,MySQL会根据执行的SQL语句选择日志保存方式。
四、GTID复制模式
在传统的复制里面,当发生故障,需要主从切换,需要找到binlog和pos点,然后将主节点指向新的主节点,相对来说比较麻烦,也容易出错。在MySQL 5.6里面,不用再找binlog和pos点,我们只需要知道主节点的ip,端口,以及账号密码就行,因为复制是自动的,MySQL会通过内部机制GTID自动找点同步。
多线程复制(基于库),在MySQL 5.6以前的版本,slave的复制是单线程的。一个事件一个事件的读取应用。而master是并发写入的,所以延时是避免不了的。唯一有效的方法是把多个库放在多台slave,这样又有点浪费服务器。在MySQL 5.6里面,我们可以把多个表放在多个库,这样就可以使用多线程复制。
基于GTID复制实现的工作原理
本文只为整理学习笔记,所以摘录和参考了很多博客,原文链接如下所示: