快牵着我的袜子

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

一、复制方式 

MySQL支持三种复制方式:

  1)基于语句的复制(也称为逻辑复制)主要是指,在主数据库上执行的SQL语句,在从数据库上会重复执行一遍 。MySQL默认采用的就是这种复制,效率比较高。

  但是也是有一定的问题的,如果SQL中使用uuid()、rand()等函数,那么复制到从库的数据就会有偏差。

  2)基于行的复制,指将更新处理后的数据复制到从数据库,而不是执行一边语句 。从MySQL5.1的版本才被支持。

  3)混合复制,默认采用语句复制,当发现语句不能进行精准复制数据时(例如语句中含有uuid()、rand()等函数),采用基于行的复制 。

二、主从复制流程

  1)第一步:是在主库上记录二进制日志,首先主库要开启binlog日志记录功能,并授权Slave从库可以访问的权限。这里需要注意的一点就是binlog的日志里的顺序

  是按照事务提交的顺序来记录的而非每条语句的执行顺序。

  2)第二步:从库将binLog复制到其本地的RelayLog中。首先从库会启动一个工作线程,称为I/O线程,I/O线程跟主库建立一个普通的客户端连接,然后主库上启动

  一个特殊的二进制转储(binlog dump)线程,此转储线程会读取binlog中的事件。当追赶上主库后,会进行休眠,直到主库通知有新的更新语句时才继续被唤醒。

  3)第三步:从库中启动一个SQL线程,从relaylog中读取事件并在备库中执行,从而实现备库数据的更新。

三、复制模式

  1、异步复制模式

    MySQL的默认复制模式就是异步模式,主要是 指MySQL的主服务器上的I/O线程,将数据写到binlong中就直接返回给客户端数据更新成功,不考虑数据是否传输到

  从服务器,以及是否写入到relaylog中 。在这种模式下,复制数据其实是有风险的,一旦数据只写到了主库的binlog中还没来得及同步到从库时,就会造成数据的丢失。

  2、同步复制模式

    当主库执行完客户端提交的事务后,需要等到所有从库也都执行完这一事务后,才返回给客户端执行成功。因为要等到所有从库都执行完,执行过程中会被阻塞,等待

  返回结果,所以性能上会有很严重的影响。

  3、半同步复制模式

    半同步复制模式,可以说是介于异步和同步之间的一种复制模式,主库在执行完客户端提交的事务后,要等待至少一个从库接收到binlog并将数据写入到relay log中才

  返回给客户端成功结果。半同步复制模式,比异步模式提高了数据的可用性,但是也产生了一定的性能延迟,最少要一个TCP/IP连接的往返时间。主要原理是,在master的

  dump线程去通知从库时,增加了一个ACK机制,也就是会确认从库是否收到事务的标志码,master的dump线程不但要发送binlog到从库,还有负责接收slave的ACK。当出现

  异常时,Slave没有ACK事务,那么将自动降级为异步复制,直到异常修复后再自动变为半同步复制。

 

  4、GTID复制模式

    GTID是由UUID+TransactionID组成的,UUID是单个MySQL实例的唯一标识,在第一次启动MySQL实例时会自动生成一个server_uuid, 并且默认写入到数据目录下的

  auto.cnf(mysql/data/auto.cnf)文件里。TransactionID是该MySQL上执行事务的数量,随着事务数量增加而递增。这样保证了 GTID在一组复制中,全局唯一 。  

  主要数据同步机制可以分为这几步:

    1)master更新数据时,在事务前生产GTID,一同记录到binlog中。

    2)slave端的i/o线程,将变更的binlog写入到relay log中。

    3)sql线程从relay log中获取GTID,然后对比Slave端的binlog是否有记录。

    4)如果有记录,说明该GTID的事务已经执行,slave会忽略该GTID。

    5)如果没有记录,Slave会从relay log中执行该GTID事务,并记录到binlog。

    6)在解析过程中,判断是否有主键,如果没有主键就使用二级索引,再没有二级索引就扫描全表。

四、一些问题

  1、什么是弱一致性、强一致性、最终一致性?

    弱一致性:数据更新后,如果能容忍后续的访问只能访问到部分或者全部访问不到,则是弱一致性。

    强一致:任何一次读都能读到某个数据的最近一次写的数据;系统中的所有进程,看到的操作顺序,都和全局时钟下的顺序一致。

    最终一致性:是弱一致性的特殊形式,存储系统保证在没有新的更新的条件下,最终所有的访问都是最后更新的值,但不完全保证能立即取得已更新的数据。

    对于关系型数据库,要求更新过的数据能被后续的访问都能看到,这是强一致性。如果能容忍后续的部分或者全部访问不到,则是弱一致性。如果经过一段时间后要求能访问到更新后的数据,则是最终一致性

  1、主从数据不一致怎么解决?

    1)忽略错误后,继续同步。该方法适用于主从库数据相差不大,或者要求数据可以不完全统一的情况,数据要求不严格的情况

    2)重新做主从,完全同步。该方法适用于主从库数据相差较大,或者要求数据完全统一的情况

  2、读写分离数据不一致的常见解决方案

    1)强制走主库

    2)判断主备无延迟

    3)等主库位点或 GTID 方案

  3、主从数据库延迟问题怎么解决?

    1)原因:

      1、数据库在业务上读写压力太大,CPU计算负荷大,网卡负荷大,硬盘随机IO太高

      2、读写binlog带来的性能影响,网络传输延迟

    2)判断方法:

      1、可以通过监控show slave statusG命令输出的Seconds_Behind_Master参数的值来判断,是否有发生主从延时。

      2、mk-heartbeat,Maatkit等工具包中的一个工具,被认为可以准确判断复制延时的方法。

    2)解决方案:

      1、硬件方面

        更换好的硬件。

      2、架构方面

        (1)数据库分片技术,而抛弃了由于数据量的越来越多导致复制延迟的问题。按照user_id进行分片,这样必须有一个全局的表来管理用户

        与shard的关系,根据user_id可以得到share_id,然后根据share_id去指定的分片查询指定的数据。

        (2)双MySQL Master+Slave

        (3)当主服务器有数据更新时,立即更新从服务器中的Memcached中的数据,这样即使有延迟,但延迟的时间应该更短了,基本上可以忽略不计了

        (4)需要读取实时数据的时候最好从 Master 直接读取,避免 Slaves 数据滞后现象发生

  4、为什么要分库分表?

    用户就越多,数据量越大,请求量越大,单个数据库一定扛不住。所以要分库分表减缓主库的压力。

  5、什么是垂直拆分和水平拆分?

    水平拆分:就是把一个表的数据给弄到多个库的多个表里去,但是每个库的表结构都一样,只不过每个库表放的数据是不同的,所有库表的数据加起来就是全部数据。

    垂直拆分:就是把一个有很多字段的表给拆分成多个表,或者是多个库上去。每个库表的结构都不一样,每个库表都包含部分字段。

  6、如何设计可以动态扩容缩容的分库分表方案?

    1)预先多建一些逻辑库,分库的时候直接将库

    2)在线双写机制:在原有和新的数据库写数据,然后编写程序将旧数据库的数据迁移到新的数据库上,在迁移的时候检测数据的更新情况,最后做数据校验。

  7、分库分表之后,id 主键如何处理?

    1)基于单库的自增ID,拿到这个ID之后再往分库分表里写入

    2)基于redis实现ID的原子性自增

    3)snowflake (雪花)算法:分布式ID固定是一个long型的数字,符号位、时间戳、机器ID、序列ID。

  8、为什么不建议使用UUID做主键

    UUID太长、占用空间太大、作为主键性能太差、不具有有序性。

posted on 2022-04-27 14:32  快牵着我的袜子  阅读(62)  评论(0编辑  收藏  举报