一 MySQL 的三种复制方式

1.1 简介

asynchronous 异步复制

fully synchronous 全同步复制

Semisynchronous 半同步复制

从MySQL5.5 开始,MySQL 以插件的形式支持半同步复制。

1.2 异步复制(Asynchronous replication)

MySQL 默认的复制是异步的,主库在执行完客户端提交的事务后会立即将结果返给给客户端,并不关心从库是否已经接收并处理,这样就会有一个问题,主如果crash 掉了,此时主上已经提交的事务可能并没有传到从上,如果此时,将从提升为主,可能导致新主上的数据不完整。

原理:在异步复制中,master 写数据到binlog 且sync,slave request binlog 后写入relay‐log 并flush disk

优点:复制的性能最好

缺点:master 挂掉后,slave 可能会丢失数据

1.3 全同步复制(Fully synchronous replication)

指当主库执行完一个事务,所有的从库都执行了该事务才返回给客户端。因为需要等待所有从库执行完该事务才能返回,所以全同步复制的性能必然会收到严重的影响。

优点:数据不会丢失

缺点:会阻塞master session,性能太差,非常依赖网络

1.4 半同步复制(Semisynchronous replication)

介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收到并写到relay log 中才返回给客户端。相对于异步复制,半同步复制提高了数据的安全性,同时它也造成了一定程度的延迟,这个延迟最少是一个TCP/IP 往返的时间。所以,半同步复制最好在低延时的网络中使用。

优点:会有数据丢失风险(低)

缺点:会阻塞master session,性能差,非常依赖网络,由于master 是在三段提交的最后commit 阶段完成后才等待,所以master 的其他session 是可以看到这个提交事务的,所以这时候master 上的数据和slave 不一致,master crash 后,slave 数据丢失。

1.5 增强版的半同步复制(lossless replication)

原理: 在半同步复制中,master 写数据到binlog 且sync,然后一直等待ACK. 当至少一个slave request bilog 后写入到relay‐log 并flush disk,就返回ack(不需要回放完日志)

优点:数据零丢失(前提是让其一直是lossless replication),

性能好

缺点:会阻塞master session,非常依赖网络由于master 是在三段提交的第二阶段sync binlog 完成后才等待, 所以master 的其他session 是看不见这个提交事务的,所以这时候master 上的数据和slave 一致,master crash 后,slave 没有丢失数据

二 实验

2.1 查看plugins

mysql> show plugins;
+----------------------------+----------+--------------------+---------+---------+
| Name | Status | Type | Library | License |
+----------------------------+----------+--------------------+---------+---------+
| binlog | ACTIVE | STORAGE ENGINE | NULL | GPL |
| mysql_native_password | ACTIVE | AUTHENTICATION | NULL | GPL |
| sha256_password | ACTIVE | AUTHENTICATION | NULL | GPL |
| CSV | ACTIVE | STORAGE ENGINE | NULL | GPL |
| MEMORY | ACTIVE | STORAGE ENGINE | NULL | GPL |
| InnoDB | ACTIVE | STORAGE ENGINE | NULL | GPL |
| INNODB_TRX | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_LOCKS | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_LOCK_WAITS | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_CMP | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_CMP_RESET | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_CMPMEM | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_CMPMEM_RESET | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_CMP_PER_INDEX | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_CMP_PER_INDEX_RESET | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_BUFFER_PAGE | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_BUFFER_PAGE_LRU | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_BUFFER_POOL_STATS | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_TEMP_TABLE_INFO | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_METRICS | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_FT_DEFAULT_STOPWORD | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_FT_DELETED | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_FT_BEING_DELETED | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_FT_CONFIG | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_FT_INDEX_CACHE | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_FT_INDEX_TABLE | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_SYS_TABLES | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_SYS_TABLESTATS | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_SYS_INDEXES | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_SYS_COLUMNS | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_SYS_FIELDS | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_SYS_FOREIGN | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_SYS_FOREIGN_COLS | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_SYS_TABLESPACES | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_SYS_DATAFILES | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_SYS_VIRTUAL | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| MyISAM | ACTIVE | STORAGE ENGINE | NULL | GPL |
| MRG_MYISAM | ACTIVE | STORAGE ENGINE | NULL | GPL |
| PERFORMANCE_SCHEMA | ACTIVE | STORAGE ENGINE | NULL | GPL |
| ARCHIVE | ACTIVE | STORAGE ENGINE | NULL | GPL |
| BLACKHOLE | ACTIVE | STORAGE ENGINE | NULL | GPL |
| FEDERATED | DISABLED | STORAGE ENGINE | NULL | GPL |
| partition | ACTIVE | STORAGE ENGINE | NULL | GPL |
| ngram | ACTIVE | FTPARSER | NULL | GPL |
+----------------------------+----------+--------------------+---------+---------+

或者查询INFORMATION_SCHEMA.PLUGINS 表

[root@master1 ~]# cd /usr/lib64/mysql/plugin/

[root@master1 plugin]# ll

-rwxr-xr-x.  root root    Apr  : adt_null.so
-rwxr-xr-x. root root Apr : authentication_ldap_sasl_client.so
-rwxr-xr-x. root root Apr : auth_socket.so
-rwxr-xr-x. root root Apr : connection_control.so
drwxr-xr-x. root root Jul : debug
-rwxr-xr-x. root root Apr : group_replication.so
-rwxr-xr-x. root root Apr : ha_example.so
-rwxr-xr-x. root root Apr : innodb_engine.so
-rwxr-xr-x. root root Apr : keyring_file.so
-rwxr-xr-x. root root Apr : keyring_udf.so
-rwxr-xr-x. root root Apr : libmemcached.so
-rwxr-xr-x. root root Apr : libpluginmecab.so
-rwxr-xr-x. root root Apr : locking_service.so
-rwxr-xr-x. root root Apr : mypluglib.so
-rwxr-xr-x. root root Apr : mysql_no_login.so
-rwxr-xr-x. root root Apr : mysqlx.so
-rwxr-xr-x. root root Apr : rewrite_example.so
-rwxr-xr-x. root root Apr : rewriter.so
-rwxr-xr-x. root root Apr : semisync_master.so #主库安装
-rwxr-xr-x. root root Apr : semisync_slave.so #备库安装
-rwxr-xr-x. root root Apr : validate_password.so
-rwxr-xr-x. root root Apr : version_token.so

2.2 主库配置

查看是否支持动态加载的MySQL 服务器

mysql> show variables like '%dynamic%';
+----------------------+-------+
| Variable_name | Value |
+----------------------+-------+
| have_dynamic_loading | YES |
+----------------------+-------+
row in set (0.00 sec) mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so'; #安装库
Query OK, rows affected (0.00 sec) mysql> show variables like '%rpl_semi%';
+-------------------------------------------+------------+
| Variable_name | Value |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled | OFF | #修改为on状态
| rpl_semi_sync_master_timeout | | #修改为1s
| rpl_semi_sync_master_trace_level | |
| rpl_semi_sync_master_wait_for_slave_count | |
| rpl_semi_sync_master_wait_no_slave | ON |
| rpl_semi_sync_master_wait_point | AFTER_SYNC |
+-------------------------------------------+------------+

修改my.cnf

[root@master1 ~]# vim /etc/my.cnf

rpl_semi_sync_master_enabled =
rpl_semi_sync_master_timeout =

[root@master1 ~]# systemctl restart mysqld

mysql> show variables like '%rpl_semi%';
+-------------------------------------------+------------+
| Variable_name | Value |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled | ON |
| rpl_semi_sync_master_timeout | |
| rpl_semi_sync_master_trace_level | |
| rpl_semi_sync_master_wait_for_slave_count | |
| rpl_semi_sync_master_wait_no_slave | ON |
| rpl_semi_sync_master_wait_point | AFTER_SYNC |
+-------------------------------------------+------------+
mysql> show status like '%semi%';
+--------------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients | |
| Rpl_semi_sync_master_net_avg_wait_time | |
| Rpl_semi_sync_master_net_wait_time | |
| Rpl_semi_sync_master_net_waits | |
| Rpl_semi_sync_master_no_times | |
| Rpl_semi_sync_master_no_tx | |
| Rpl_semi_sync_master_status | ON |
| Rpl_semi_sync_master_timefunc_failures | |
| Rpl_semi_sync_master_tx_avg_wait_time | |
| Rpl_semi_sync_master_tx_wait_time | |
| Rpl_semi_sync_master_tx_waits | |
| Rpl_semi_sync_master_wait_pos_backtraverse | |
| Rpl_semi_sync_master_wait_sessions | |
| Rpl_semi_sync_master_yes_tx | |
+--------------------------------------------+-------+

rpl_semi_sync_master_timeout

一个以毫秒为单位的值,用于控制主服务器等待来自从服务器的确认提交并恢复到异步复制的时间,超过这个值就是超时。 默认值是10000(10 秒)。超时之后,就从半同步复制,返回到异步复制。

Rpl_semi_sync_master_yes_tx:从库成功确认的提交数量。

Rpl_semi_sync_master_no_tx:从库未成功确认的提交数量。

2.3 备份服务器配置

mysql> show variables like '%dynamic%';
+----------------------+-------+
| Variable_name | Value |
+----------------------+-------+
| have_dynamic_loading | YES |
+----------------------+-------+
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
mysql> show variables like '%rpl_semi%';
+---------------------------------+-------+
| Variable_name | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled | OFF | #打开为on
| rpl_semi_sync_slave_trace_level | |
+---------------------------------+-------+

修改my.cnf

[root@slave ~]# vim  /etc/my.cnf

rpl_semi_sync_slave_enabled = 

[root@slave ~]# systemctl restart mysqld

mysql> show variables like '%rpl_semi%';
+---------------------------------+-------+
| Variable_name | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled | ON |
| rpl_semi_sync_slave_trace_level | |
+---------------------------------+-------+
mysql> show status like '%semi%';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON |
+----------------------------+-------+

2.4 主库验证

mysql> show status like '%semi%';
+--------------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients | |
| Rpl_semi_sync_master_net_avg_wait_time | |
| Rpl_semi_sync_master_net_wait_time | |
| Rpl_semi_sync_master_net_waits | |
| Rpl_semi_sync_master_no_times | |
| Rpl_semi_sync_master_no_tx | |
| Rpl_semi_sync_master_status | ON |
| Rpl_semi_sync_master_timefunc_failures | |
| Rpl_semi_sync_master_tx_avg_wait_time | |
| Rpl_semi_sync_master_tx_wait_time | |
| Rpl_semi_sync_master_tx_waits | |
| Rpl_semi_sync_master_wait_pos_backtraverse | |
| Rpl_semi_sync_master_wait_sessions | |
| Rpl_semi_sync_master_yes_tx | |
+--------------------------------------------+-------+
mysql> insert into test values ();
mysql> insert into test values ();
mysql> insert into test values ();
mysql> show status like '%semi%';
+--------------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients | |
| Rpl_semi_sync_master_net_avg_wait_time | |
| Rpl_semi_sync_master_net_wait_time | |
| Rpl_semi_sync_master_net_waits | |
| Rpl_semi_sync_master_no_times | |
| Rpl_semi_sync_master_no_tx | |
| Rpl_semi_sync_master_status | ON |
| Rpl_semi_sync_master_timefunc_failures | |
| Rpl_semi_sync_master_tx_avg_wait_time | |
| Rpl_semi_sync_master_tx_wait_time | |
| Rpl_semi_sync_master_tx_waits | |
| Rpl_semi_sync_master_wait_pos_backtraverse | |
| Rpl_semi_sync_master_wait_sessions | |
| Rpl_semi_sync_master_yes_tx | | #增加数据.这个之会增加
+--------------------------------------------+-------+

从端数据已经同步

mysql> select * from master1.test;
+------+
| id |
+------+
| |
| |
| |
| |
+------+

2.5 测试AFTER_SYNC 和AFTER_COMMIT

主库设置超时时间为1000 秒,备库停掉复制,模拟timeout

mysql> set global rpl_semi_sync_master_timeout=;
mysql> stop slave;
mysql> insert into test values (); #会一直卡住 mysql> select * from master1.test;
+------+
| id |
+------+
| |
| |
| |
| |
+------+

重启主库数据库,模拟主库宕机,从看数据记录

[root@master1 ~]# systemctl start mysqld
[root@master1 ~]# mysql -uroot -p123456
mysql> select * from master1.test;
+------+
| id |
+------+
| |
| |
| |
| |
| | #主库有记录
+------+

备库开启slave

mysql> start slave;
Query OK, rows affected (0.00 sec) mysql> select * from master1.test;
+------+
| id |
+------+
| |
| |
| |
| |
| | #数据已经同步,没有丢失
+------+

无损的半同步复制是在write binlog 之后。需要得到备库的确认。所以这时候主库宕机,不会发生丢数据。当主库启动后,插入的数据重新可见。

将rpl_semi_sync_master_wait_point 设置为AFTER_COMMIT,

再次测试:

主库设置超时时间为1000 秒,备库停掉复制,模拟timeout

mysql> set global rpl_semi_sync_master_wait_point=AFTER_COMMIT;
mysql> set global rpl_semi_sync_master_timeout=;
mysql> show variables like '%semi%';
+-------------------------------------------+--------------+
| Variable_name | Value |
+-------------------------------------------+--------------+
| rpl_semi_sync_master_enabled | ON |
| rpl_semi_sync_master_timeout | |
| rpl_semi_sync_master_trace_level | |
| rpl_semi_sync_master_wait_for_slave_count | |
| rpl_semi_sync_master_wait_no_slave | ON |
| rpl_semi_sync_master_wait_point | AFTER_COMMIT |
+-------------------------------------------+--------------+
mysql> insert into master1.test values (12); #一直卡住
[root@master1 ~]# mysql -uroot -p123456 #另开一个窗口,发现已经有12这个数据
mysql> select * from master1.test;
+------+
| id |
+------+
| |
| |
| |
| |
| |
| |
+------+

这样当从库起来之后,数据已经提交,从库就会缺少这个数据

再开一个窗口查询这条数据,发现可以查询到。这时候主库宕机,会发生数据丢失。

主库重新启动,备库启动slave 会同步到备库。

mysql主从之半同步复制和lossless无损复制的更多相关文章

  1. mysql基础之mysql主从架构半同步复制

    一.概念 1.异步复制(Asynchronous replication) MySQL默认的复制即是异步的,主库在执行完客户端提交的事务后会立即将结果返给给客户端,并不关心从库是否已经接收并处理,这样 ...

  2. MySQL 5.7半同步复制技术

    一.复制架构衍生史 在谈这个特性之前,我们先来看看MySQL的复制架构衍生史. 在2000年,MySQL 3.23.15版本引入了Replication.Replication作为一种准实时同步方式, ...

  3. MySQL主从复制之半同步模式

    MySQL主从复制之半同步模式 MySQL半同步介绍: 一般情况下MySQL默认复制模式为异步,何为异步?简单的说就是主服务器上的I/O threads 将binlog写入二进制日志中就返回给客户端一 ...

  4. mysql主从复制(半同步方式)

    mysql主从复制(半同步方式) 博客分类: MySQL mysqlreplication复制  一.半同步复制原理介绍 1. 优点 当事务返回客户端成功后,则日志一定在至少两台主机上存在. MySQ ...

  5. 搭建MySQL的主从、半同步、主主复制架构

    复制其最终目的是让一台服务器的数据和另外的服务器的数据保持同步,已达到数据冗余或者服务的负载均衡.一台主服务器可以连接多台从服务器,并且从服务器也可以反过来作为主服务器.主从服务器可以位于不同的网络拓 ...

  6. mysql配置为半同步复制

    mysql 半同步插件是由谷歌提供,具体位置/usr/local/mysql/lib/plugin/下,一个是 master用的 semisync_master.so,一个是 slave 用的 sem ...

  7. Mysql主从复制、半同步复制、并行复制

    MySQL之间数据复制的基础是二进制日志文件(binary log file).一台MySQL数据库一旦启用二进制日志后,其作为master,它的数据库中所有操作都会以"事件"的方 ...

  8. MySQL 5.7半同步复制after sync和after commit详解【转】

    如果你的生产库开启了半同步复制,那么对数据的一致性会要求较高,但在MySQL5.5/5.6里,会存在数据不一致的风险.有这么一个场景,客户端提交了一个事务,master把binlog发送给slave, ...

  9. MySQL主从复制、半同步复制和主主复制

    同步,异步,半同步复制的比较: 同步复制:Master提交事务,直到事务在所有的Slave都已提交,此时才会返回客户端,事务执行完毕.缺点:完成一个事务可能会有很大的延迟. 异步复制:当Slave准备 ...

随机推荐

  1. ios7.1安装提示"无法安装应用程序 由于证书无效"的解决方式二(dropbox被封项目转移到Appharbor上)

    6月18日起dropbox被天朝封了(这个真是无力吐槽),而ios7.1要求使用ssl安全连接,则须要又一次找到一个支持https的免费server. Appharbor是个不错的选择,操作简单.此外 ...

  2. Spring读取mybatis在多个jar包下的的mapper文件

     刚开始的时候我的配置文件在同名目录下都是在/mapper下,导致只能读取一个jar中的mapper文件.先解决如下: 1.将mapper文件放在不能放在同名的目录下.        比如:user. ...

  3. 关于使用JavaMail发送邮件抛出java.lang.NoSuchMethodError: com.sun.mail.util.TraceInputStream.<init>(Ljava异常的解决方法

    我们在使用JavaMail时有可能会如下异常: Exception in thread "main" java.lang.NoSuchMethodError: com.sun.ma ...

  4. saltStack 状态模块(状态间的关系)

    unless onlyif:状态间的条件判断,主要用于cmd状态模块 常用方法:    onlyif:检查的命令,仅当'onlyif'  选项指向的命令返回true时才执行name 定义的命 unle ...

  5. laravel 5.6 请教邮件中的cc,bcc是什么意思,有什么用?

    cc指抄送 bcc指暗送. cc:carbon copy bcc:blind carbon copy

  6. There is no getter for property named 'XXX' in 'class java.lang.String'

    实验环境:spring boot+mybitis 由于采用的不带映射xml文件的模式,因此 方法1: 把#{xxx}修改为 #{_parameter} 即可 select count(*) from ...

  7. 从浏览器的url中获取查询字符串的参数

    正则表达式: function getQuery(name){ var reg = new RegExp("(^|&)" + name + "=([^&] ...

  8. supersockets支持热更新的服务器实例配置选项

    SuperSocket 支持以下配置选项的热更新: * logCommand * idleSessionTimeOut * maxRequestLength * logBasicSessionActi ...

  9. python起个简单web服务器

    在 Linux 服务器上或安装了 Python 的机器上,Python自带了一个WEB服务器 SimpleHTTPServer. 我们可以很简单的使用  python -m SimpleHTTPSer ...

  10. LA 5031 Graph and Queries —— Treap名次树

    离线做法,逆序执行操作,那么原本的删除边的操作变为加入边的操作,用名次树维护每一个连通分量的名次,加边操作即是连通分量合并操作,每次将结点数小的子树向结点数大的子树合并,那么单次合并复杂度O(n1lo ...