Mysql数据库主从搭建

 1、MySQL 主从复制原理

    主库将变更写入 binlog 日志,然后从库连接到主库之后,从库有一个 IO 线程,将主库的 binlog 日志拷贝到自己本地,写入一个 relay 中继日志中。接着从库中有一个 SQL 线程会从中继日志读取 binlog,然后执行 binlog 日志中的内容,也就是在自己本地再次执行一遍 SQL,这样就可以保证自己跟主库的数据是一样的。

  注意:

  1. 从库同步主库数据的过程是串行化的,也就是说主库上并行的操作,在从库上会串行执行。由于从库从主库拷贝日志以及串行执行 SQL 的特点,在高并发场景下,从库的数据一定会比主库慢一些,是有延时的。所以经常出现,刚写入主库的数据可能是读不到的,要过几十毫秒,甚至几百毫秒才能读取到。

  2. 如果主库突然宕机,然后恰好数据还没同步到从库,那么有些数据可能在从库上是没有的,有些数据可能就丢失了。

    一般来说,如果主从延迟较为严重,有以下解决方案:

    1. 分库,将一个主库拆分为多个主库,每个主库的写并发就减少了几倍,此时主从延迟可以忽略不计。
    2. 打开 MySQL 支持的并行复制,多个库并行复制。如果说某个库的写入并发就是特别高,单库写并发达到了 2000/s,并行复制还是没意义。
    3. 重写代码,写代码的同学,要慎重,插入数据时立马查询可能查不到。
      如果确实是存在必须先插入,立马要求就查询到,然后立马就要反过来执行一些操作,对这个查询设置直连主库。

2、复制流程图

 

 3、复制过程

  1. 主节点必须启用二进制日志,记录任何修改了数据库数据的事件。
  2. 从节点开启一个线程(I/O Thread)把自己扮演成 mysql 的客户端,通过 mysql 协议,请求主节点的二进制日志文件中的事件
  3. 主节点启动一个线程(dump Thread),检查自己二进制日志中的事件,跟对方请求的位置对比,如果不带请求位置参数,则主节点就会从第一个日志文件中的第一个事件一个一个发送给从节点。
  4. 从节点接收到主节点发送过来的数据把它放置到中继日志(Relay log)文件中。并记录该次请求到主节点的具体哪一个二进制日志文件内部的哪一个位置(主节点中的二进制文件会有多个,在后面详细讲解)。
  5. 从节点启动另外一个线程(sql Thread ),把 Relay log 中的事件读取出来,并在本地再执行一次。

     **思考:**从节点需要建立二进制日志文件吗?
      看情况,如果从节点需要作为其他节点的主节点时,是需要开启二进制日志文件的。这种情况叫做级联复制。如果只是作为从节点,则不需要创建二进制文件。

4、主从复制配置过程

主节点:

启用二进制日志。
为当前节点设置一个全局唯一的server_id。
创建有复制权限的用户账号 REPLIACTION SLAVE ,REPLIATION CLIENT。
从节点:

启动中继日志。
为当前节点设置一个全局唯一的server_id。
使用有复制权限的用户账号连接至主节点,并启动复制线程。

5、创建三个虚拟机,mysql 一主两从

       1、192.168.8.162 主

       2、192.168.8.134 从

       3、192.168.8.176 从

6、Mysql的主从配置

    a.配置主库

    192.168.8.162是window10系统,mysql版本是mysql5.7.31,设置成主库

    在E:\Program Files\mysql-5.7.31-winx64\my.ini中添加一下

#server-id给数据库服务的唯一标识
server-id=1
#
##log-bin设置此参数表示启用binlog功能,并指定路径名称
log-bin=E:\Program Files\mysql-5.7.31-winx64\data\mysqlbin
sync_binlog=0
##设置日志的过期天数
expire_logs_days=7
binlog-do-db=test1
binlog-do-db=test2
binlog-ignore-db=information_schema
binlog-ignore-db=sys
binlog-ignore-db=mysql
binlog-ignore-db=performance_schema
  • 这里的server-id用于标识唯一的数据库,在从库必须设置为不同的值。
  • binlog-ignore-db:表示同步的时候忽略的数据库
  • binlog-do-db:指定需要同步的数据库

重启数据库,重启成功后,登录mysql

赋予从库权限账号,允许用户在主库上读取日志,赋予192.168.8.134和192.168.8.176也就是Slave机器有File权限,
只赋予Slave机器有File权限还不行,还要给它REPLICATION SLAVE的权限才可以。

grant FILE on *.* to 'root'@'192.168.8.134' identified by 'root';
grant replication slave on *.* to 'root'@'192.168.8.134' identified by 'root';
flush privileges;
grant FILE on *.* to 'root'@'192.168.8.176' identified by 'root';
grant replication slave on *.* to 'root'@'192.168.8.176' identified by 'root';
flush privileges;

    这里的用户是同步的时候从库使用的用户。

   查看主库信息

     show master status;

 File是同步会使用到的binlog文件,Position是同步的时候也要用到的

   b、在window中配置从库

       192.168.8.176 是window2012R2系统,mysql版本是mysql8.0.18,设置成从库1

        在C:\mysql-8.0.18-winx64\my.ini中添加一下

log-bin=mysqlbin
server-id=3
binlog-ignore-db=information_schema
binlog-ignore-db=sys
binlog-ignore-db=mysql
replicate-ignore-db=mysql
replicate-do-db=test1
replicate-do-db=test2
log-slave-updates
slave-skip-errors=all
slave-net-timeout=60

    注意:两个从库的server-id不一样,需要唯一。小于主库

    修改完my.cnf后,重启一下mysql。重启成功后,登录mysql

stop slave;
change master to master_host='192.168.8.162',master_user='root',master_password='root',master_log_file='mysqlbin.000001', master_log_pos=1580;
start slave;

   

 注意:上面的master_log_file是在主配Master中show master status显示的File,
              而master_log_pos是在主配Master中show master status显示的Position。

然后可以通过show slave status \G查看配置信息

上面的信息有Slave_IO_Running: Yes和Slave_SQL_Running: Yes,证明主从同步成功。

      出错清理掉之前的配置,防止同步已经同步了的数据,执行以下命令

stop slave;
reset slave all;

    c、在linux中配置从库

      192.168.8.134 是centor7系统,mysql版本是mysql5.7.31,设置成从库2

      修改/etc/my.cnf

      vi /etc/my.cnf添加

log-bin=mysqlbin
server-id=2
binlog-ignore-db=information_schema
binlog-ignore-db=sys
binlog-ignore-db=mysql
replicate-ignore-db=mysql
replicate-do-db=test1
replicate-do-db=test2
log-slave-updates
slave-skip-errors=all
slave-net-timeout=60

注意:两个从库的server-id不一样,需要唯一。小于主库。

修改完my.cnf后,重启一下mysql。重启成功后,登录mysql。

service mysql restart

stop slave;
change master to master_host='192.168.8.162',master_user='root',master_password='root',master_log_file='mysqlbin.000001', master_log_pos=1580;
start slave;

 注意:上面的master_log_file是在主配Master中show master status显示的File,
              而master_log_pos是在主配Master中show master status显示的Position。

     然后可以通过show slave status \G查看配置信息

面的信息有Slave_IO_Running: Yes和Slave_SQL_Running: Yes,证明主从同步成功。

      出错清理掉之前的配置,防止同步已经同步了的数据,执行以下命令

stop slave;
reset slave all;

7、验证主从配置

   操作完成后。可以在Master建表插入数据,然后再从2个库中查看,如果2个都有数据,则证明主从数据库同步成功。

8、MYSQL主从配置详解

#master 配置参数

server_id   复制中唯一标示
log-bin     binlog日志路径
log-bin-index   binlog 日志索引文件
binlog_format    binlog格式, Statement ,ROW MIXED
max_binlog_size    binlog日志文件大小 默认大小1G 
sync_binlog   多少个SQL以后调用fdatasync()函数刷新binlog to disk 
#fsync 是完全刷新到磁盘,fdatasync 只刷新数据,不刷新metadata
expire_logs_days    binlog 保留多少天
log_bin_trust_function_creators 开启binlog 时,是否允许创建存储程序(除非有super权限,或者指定deterministic reads sql data,no sql)
auto_increment_increment   #在数字表列auto_increment 每次增长的步长和幅度
auto_increment_offset  #在数字表列auto_increment  起始位置
binlog-do-db          binlog记录的数据库
binlog-ignore-db     binlog 不记录的数据库
log_bin_trust_function_creators  开启binlog 是否允许创建存储程序,除非有supper权限
max_binlog_cache_size    #binlog 最大的写入
binlog_stmt_cache_size   cache事务中非事务表产生SQL语句
max_binlog_stmt_cache_size
back_log   # MYSQL连接过多的时候,会把一些线程短暂的放在线程堆在中。
binlog_direct_non_transactionl_updates  事务中既有事务表和非事务表,发生数据变更,非事务表直接写入binlog,而不是也和事务表一样缓存在buffer中,  这个参数只影响SBR模式,RBR,MBR不影响
 
 
#SLAVE 配置参数
server-id  复制集群中的唯一标示
relay-log   #中继日志
relay-log-index  中继日志的索引文件
read-only # slave 只能读不能写(除非有super,和特权才可以写)
 
#slave 其他的参数
log-slow-slave-statements #开启slave慢查询记录SQL_THREAD线程的SQL语句
log_slave_update #记录Master传过来的数据,再次记录到slave binlog 再中继到其他的节点上
binlog-ignore-db= 忽略DB记录BINLOG
max_relay_log_size  中继日志文件大小
relay-log-info-file   中继文件info信息
relay_log_purge   中继日志的删除 SQL_thread线程回放完,删除中继日志
relay_log_recovery   slave 启动 未应用完的relay log 会被删除 重新从master 请求binlog 再次生成relay log
replicate-same-server-id   slave 复制是否应用和自己相同的server-id的binlog
skip-slave-start    MYSQL启动跳过slave 启动
slave_load_tmpdir    slave 使用load 产生的临时文件的目录
slave_transaction_retries  slave 复制中,应为innodb死锁导致复制线程执行事务的失败重试次数
sync_master_info  多少个事务后调用fdatasync()刷新master.info文件
slave_parallel_workers  多线程复制
 slave_exec_mode     #自动跳过主从SQL线程的错误
slave_parallel_type         
slave_parallel_workers       多线程复制 
sync_binlog=n  #多少SQL语句之后,调用fdatasync()函数刷新binlog到disk  ,fdatasync和fsync  fdatasync只刷新数据,不刷新metadata,fsync 完全刷新到磁盘
sql_log_bin  关闭和开启binlog
replicate-wild-do-table = dba.kian  #采用通配符,是否复制那些表
slave-preserve-commit-order 当启用多线程复制的时候,在从库回放数据顺序不一样,可以启用此参数保持一致
 
fsync() fdatasync() 的区别
fsync() 是完全刷新到磁盘,fdatasync()只刷新数据,不刷新metadata
posted @ 2021-01-14 09:17  hzy_叶子  阅读(791)  评论(0编辑  收藏  举报