MySQL主从复制的多种实现

MySQL主从复制

  • 复制的功用:

    • 数据分布
    • 负载均衡读
    • 备份
    • 高可用和故障切换
    • MySQL升级测试
  • MySQL复制架构:

    • Master/Slave 一主一从
    • Master/Master 主主
    • 环状复制
    • 一主多从
    • 从服务器还可以再有从服务器(级联复制)
    • 一从多主:适用于多个不同数据库

主从复制原理:
主节点产生数据的更改,会将更改写入到二进制文件中,从节点启动一个线程,将自己伪装成MySQL的客户端,通过mysql协议向mysql服务器端读取二进制日志中的事件,服务器端会从二进制日志中的指定位置,将事件发送给从节点,从节点先将这些事件保存到本地的中继日志中,并将事件在本地回放

主从复制线程:

  • 主节点:

    • DUMP Thread:用来接收从节点的响应请求,并检查本地的二进制日志中有新的事件,然后将新的事件响应给从节点
  • 从节点:

    • I/O Thread:向master请求二进制日志事件,并保存到中继日志中
    • SQL Thread:从中继日志中读取日志事件,在本地重放

和复制功能相关的文件:

  • master.info:用于保存slave连接至master时的相关的信息,例如账号、密码、服务器地址等
  • relay-log.info:保存在当前slave节点上已复制的当前二进制日志和本地replay log日志的对应关系

主从复制特点:

  • 异步复制
  • 主从数据不一致比较常见

复制需要考虑二进制日志事件的记录格式:

  • STATEMENT(5.0之前):基于语句记录
  • ROW(5.1之后,推荐):基于行记录
  • MIXED:混合模式

复制架构总应该注意的问题:

  • 1.限制从服务器为只读

    • 在从服务器上设置read_only=on

      注:此限制对super用户无效

    • 阻止所有用户, 包括主服务器复制的更新

      mysql> FLUSH TABLES WITH READ LOCK;

  • 2.reset slave

    • 在从服务器清除master.info,relay-log.info,relay log,开始新的relay log

      注意:要先stop slave

    • RESET SLAVE ALL 清除所有从服务器上设置的主服务器同步信息如:PORT, HOST, USER和 PASSWORD 等
  • 3、sql_slave_skip_counter = N 从服务器忽略几个主服务器的复制事件,global变量

  • 4.如何保证主从复制的事务安全

    • 在master节点启用参数:

      sync_binlog=1 每次写后立即同步二进制日志到磁盘,性能差

    • 如果用到的为InnoDB存储引擎:

      innodb_flush_log_at_trx_commit=1 每次事务提交立即同步日志写磁盘
      innodb_support_xa=ON 默认值,分布式事务MariaDB10.3.0废除
      sync_master_info=# #次事件后master.info同步到磁盘

    • 在slave节点启用服务器选项:

      skip_slave_start=ON 不自动启动slave

    • 在slave节点启用参数:

      sync_relay_log=# #次写后同步relay log到磁盘
      sync_relay_log_info=# #次事务后同步relay-log.info到磁盘

配置主从复制:

  • 主节点配置: 172.22.45.131
    1. 启用二进制日志
    [mysqld]  
    log_bin=/path/to/file  
    例:log_bin=mariadb-bin     #那么会在默认的/var/lib/mysql/下生产mariadb-bin.000001 ...等日志文件 
2. 为当前节点设置一个全局的唯一ID  
    [mysqld]  
    server_id=131           #默认为1 主节点和从节点的id不能相同  
    log-basename=master     #可选项,设置datadir中日志名称,确保不依赖主机名  
3. 创建有复制权限的用户账号:  
    grant replication slave on *.* to 'repluser'@'host' identified by 'password';
  • 从节点配置:
  1. 启动中继日志:
    [mysqld]
    server_id=132 	        #为当前节点设置一个全局惟的ID号  
    read_only=ON 	        #设置数据库只读  
    relay_log=relay-log 	#relay log的文件路径,默认值为hostname-relay-bin  
    relay_log_index=relay-log.index     #默认值为hostname-relay-bin.index  
  1. 使用有复制权限的用户账号连接至主服务其,并启动复制线程
    change master to master_host='host',master_user='repluser',master_password='password',master_log_file='mariadb-bin.000001',master_log_pos=245;
    #master_log_file='mariadb-bin.000001' master_log_pos=245:指定从主服务器的哪个二进制日志的哪个事件开始复制
  1. 启动从节点线程:
    start slave [IO_THREAD|SQL_THREAD];	
  1. 查看同步状态:
    show slave status\G;  

如果主节点已经运行了一段时间,且有大量数据时,如何配置并启动slave节点:

  1. 通过备份恢复数据至从服务器
  2. 复制起始位置为本分时,二进制日志文件及其post

配置主主复制:互为主从

容易产生的问题:数据不一致;因此慎用
考虑要点:自动增长id
    配置一个节点使用奇数id
        auto_increment_increment=2 增长幅度
        auto_increment_offset=1 开始点
    另一个节点使用偶数id
        auto_increment_offset=2
        auto_increment_increment=2
  • 主服务器1配置:172.22.45.131
  1. 启用二进制日志
    [mysqld]
    log_bin=/path/to/file
    auto_increment_offset=1 
    auto_increment_increment=2 
  1. 为当前节点设置一个全局的唯一ID
    [mysqld]
    server_id=131 
    log-basename=master 
  1. 创建有复制权限的用户账号:
	grant replication slave on *.* to 'repluser'@'host' identified by 'password';
  • 主服务器2配置:172.22.45.132
  1. 启用二进制日志
    [mysqld]
    log_bin=/path/to/file
    auto_increment_offset=2 
    auto_increment_increment=2 
  1. 为当前节点设置一个全局的唯一ID
    [mysqld]
    server_id=132
    log-basename=master 
  1. 使用有复制权限的用户账号连接至主服务其,并启动复制线程:
    change master to master_host='172.22.45.131',master_user='repluser',master_password='admin123',master_log_file='mariadb-bin.000001',master_log_pos=245;
  1. 启动线程
    start slave;
  • 主服务器1:
  1. 使用有复制权限的用户账号连接至主服务其,并启动复制线程:
    change master to master_host='172.22.45.132',master_user='repluser',master_password='admin123',master_log_file='mariadb-bin.000001',master_log_pos=245;
  1. 启动线程
    start slave;

配置级联复制:

  • 主服务器: 172.22.45.131
  1. 启用二进制日志
    [mysqld]
    log_bin=/path/to/file
  1. 为当前节点设置一个全局的唯一ID
    [mysqld]
    server_id=131 
    log-basename=master 
  1. 创建有复制权限的用户账号:
    grant replication slave on *.* to 'repluser'@'host' identified by 'password';
  • 从节点配置: 172.22.45.132
  1. 启动中继日志:
    [mysqld]
    server_id=132	
    read_only=ON 	
    skip_name_resolve=on
    log_bin
    log_slave_updates   #会把从主节点中继日志复制的内容,也写到自己的二进制日志中
    relay_log=relay-log 	
    relay_log_index=relay-log.index 	
  1. 使用有复制权限的用户账号连接至主服务其,并启动复制线程
    change master to master_host='172.22.45.131',master_user='repluser',master_password='password',master_log_file='mariadb-bin.000001',master_log_pos=245;
  1. 启动从节点线程:
    start slave [IO_THREAD|SQL_THREAD];	
  1. 查看同步状态:
    show slave status\G;  
  • 最后从节点配置:172.22.45.133
  1. 启动中继日志:
    [mysqld]
    server_id=133	
    read_only=ON 	
    relay_log=relay-log 	
    relay_log_index=relay-log.index 	
  1. 使用有复制权限的用户账号连接至主服务其,并启动复制线程
    change master to master_host='172.22.45.132',master_user='repluser',master_password='password',master_log_file='mariadb-bin.000001',master_log_pos=245;
  1. 启动从节点线程:
    start slave [IO_THREAD|SQL_THREAD];		
  1. 查看同步状态:
    show slave status\G;

半同步复制:

默认情况下,mysql的复制功能是异步的,异步复制可以提供最佳的性能,主库把binlog日志发送给从库即结束,并不验证从库是否接收完毕。这意味着当主服务器或从服务器端发生故障时,有可能从服务器没有接收到主服务器发送过来的binlog日志,这就会造成主服务器和从服务器的数据不一致,甚至在恢复时造成数据的丢失

半同步复制能够实现,客户端在主服务器修改数据后,主服务器将日志发送给从服务器,在指定的时间内,如果从服务器完成复制,则返回成功给客户端,如果在指定时间内没有完成复制,也会返回成功给客户端

  • 半同步复制的实现:

    • 依赖于semisync_master.so和semisync_slave.so插件
    • 查看数据库当前加载的插件:

      show plugins;

    • 安装插件

      INSTALL PLUGIN name SONAME ‘plugin_name’;
      name:为在show plugins;中看到的名字

    • 启用插件:

      set global name_enabled=1

  • 主服务器配置:

    1. 安装插件:
        install plugin rpl_semi_sync_master soname ''semisync_master.so';
    
    1. 启用插件:
        set global rpl_semi_sync_master_enabled=1
    
    1. 设置超时时长:
        set global rpl_semi_sync_master_timeout=1000;	超时时长为1s
    
    1. 查看相关的变量:
        SHOW GLOBAL VARIABLES LIKE '%semi%';
    
    1. 查看状态:
        SHOW GLOBAL STATUS LIKE '%semi%';
    
  • 从服务器配置:

    1. 安装插件:
        install plugin rpl_semi_sync_slave soname ''semisync_slave.so';
      2. 启用插件:
        set global rpl_semi_sync_slave_enabled=1

你可能感兴趣的:(Linux运维,mysql,主从复制)