签到成功

知道了

CNDBA社区CNDBA社区

MariaDB 半同步主从复制 搭建手册

2018-02-11 17:47 3284 0 原创 MySQL
作者: dave

1 背景说明

MySQL 5.5之前版本的MySQL Replication都是异步(asynchronous)的,即主库执行完事务后,不用关心备库的情况。如果备库没有及时同步,而主库此时又Crash,那么这时备库中的数据就是不完整的。即在主库发生故障的时候,无法使用备库来继续提供数据一致的服务。http://www.cndba.cn/dave/article/2661

而半同步机制,master节点只要确认有至少一个slave节点接收到了事物,即可向客户端返回操作成功的信息,master节点甚至不需要等待slave节点也成功执行完这个事物,只要至少有一个slave节点接收到这个事物,并且将之成功写入到本地的中继日志文件(写到relay log),就算成功。

当然Semi_synchronous中,仅仅保证事务的已经传递到备库上,但是并不确保已经在备库上执行完成了。此外,还有一种情况会导致主备数据不一致。在某个session中,主库上提交一个事务后,会等待事务传递给至少一个备库,如果在这个等待过程中主库Crash,那么也可能备库和主库不一致。在主库恢复后,可以通过参数Rpl_semi_sync_master_no_tx观察。

在半同步情况下,如果主备之间连接出现故障,比如主备网络故障或者备库故障,主库在事务提交后等待10秒(rpl_semi_sync_master_timeout的默认值)后,就会继续。这时主库就会变回原来的异步状态。

在Mysql 5.7 和 MariaDB 10.2中,半同步机制变化也有如下2个变化:
1) rpl_semi_sync_master_wait_slave_count参数设置有几个slave接收到了binlog才成功返回客户端请求,缺省是一台,但不可以指定是具体哪台。
2) rpl_semi_sync_master_wait_point 参数,它有两种选择:

AFTER_SYNC(5.7缺省值,5.6中无此选项)
主库把每一个事务写到二进制日志并且发送给从库,主库在等待从库写到自己的relay-log里的确认信息,在接到确认信息后,主数据库把事务写到存储引擎里并把相应结果反馈给客户端。

AFTER_COMMIT(5.6缺省值)
主库把每一个事务写到二进制日志并且发送给从库,然后马上就把事务写到存储引擎里;主库在等待从库写到自己的relay-log里的信息确认后,主库把相应结果反馈给客户端。http://www.cndba.cn/dave/article/2661

这两个参数值的区别:
AFTER_COMMIT模式的弊端在于,虽然主库一直没有告诉提交事务的客户端事务已经成功(在从库成功确认前)但是实际已经提交了,其它客户端此时已经可以看到事务的结果了。
也就是对于事务提交者自身,的确保证了只要收到成功就一定成功了,但是其它客户端却可能存在发现事务成功了,但最后却没成功,因为数据已经到了存储引擎层。

http://www.cndba.cn/dave/article/2661
http://www.cndba.cn/dave/article/2661

2 搭建主从复制环境

半同步复制,是在主从复制的基础上搭建的。关于主从复制的搭建参考:
MariaDB 主从复制 搭建手册
http://www.cndba.cn/dave/article/2659

3 半同步复制配置

这里假设MariaDB的主从复制已经完成,并正常工作。 我们看半同步的配置。

3.1 安装插件

半同步复制依赖2个插件:semisync_master.so 和 semisync_slave.so。

查看现有插件:

http://www.cndba.cn/dave/article/2661

MariaDB [cndba]> show plugins;
+-------------------------------+----------+--------------------+---------+---------+
| Name                          | Status   | Type               | Library | License |
+-------------------------------+----------+--------------------+---------+---------+
| binlog                        | ACTIVE   | STORAGE ENGINE     | NULL    | GPL     |
| mysql_native_password         | ACTIVE   | AUTHENTICATION     | NULL    | GPL     |
| mysql_old_password            | ACTIVE   | AUTHENTICATION     | NULL    | GPL     |
| wsrep                         | ACTIVE   | STORAGE ENGINE     | NULL    | GPL     |
| MRG_MyISAM                    | ACTIVE   | STORAGE ENGINE     | NULL    | GPL     |
| MEMORY                        | ACTIVE   | STORAGE ENGINE     | NULL    | GPL     |
| CSV                           | ACTIVE   | STORAGE ENGINE     | NULL    | GPL     |
| MyISAM                        | ACTIVE   | STORAGE ENGINE     | NULL    | GPL     |
| CLIENT_STATISTICS             | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| INDEX_STATISTICS              | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| TABLE_STATISTICS              | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| USER_STATISTICS               | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| PERFORMANCE_SCHEMA            | 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     |
……

MariaDB [cndba]> show variables like 'plugin_dir';
+---------------+------------------------------+
| Variable_name | Value                        |
+---------------+------------------------------+
| plugin_dir    | /usr/local/mysql/lib/plugin/ |
+---------------+------------------------------+
1 row in set (0.00 sec)

MariaDB [cndba]> system ls -l /usr/local/mysql/lib/plugin/semisync*
-rwxr-xr-x 1 1021 1004 587252 Jan  3 22:52 /usr/local/mysql/lib/plugin/semisync_master.so
-rwxr-xr-x 1 1021 1004 471765 Jan  3 22:53 /usr/local/mysql/lib/plugin/semisync_slave.so
MariaDB [cndba]>

在master库安装semisync_master.so,在slave端安装semisync_slave.so:

MariaDB [cndba]>  install plugin rpl_semi_sync_master SONAME 'semisync_master.so' ;
Query OK, 0 rows affected (0.01 sec)
MariaDB [cndba]>  install plugin rpl_semi_sync_slave SONAME 'semisync_slave.so';
Query OK, 0 rows affected (0.02 sec)

安装完后就可以通过show plugins命令查看到该插件,当然也可以两个插件都装上,已防止以后主从库的切换:http://www.cndba.cn/dave/article/2661

MariaDB [cndba]> show plugins;
……
| rpl_semi_sync_master          | ACTIVE   | REPLICATION        | semisync_master.so | GPL     |
| rpl_semi_sync_slave           | ACTIVE   | REPLICATION        | semisync_slave.so  | GPL     |
+-------------------------------+----------+--------------------+--------------------+---------+
54 rows in set (0.00 sec)
3.2 修改Master端半同步相关参数
MariaDB [cndba]>  show variables like '%rpl_semi_sync%';
+------------------------------------+--------------+
| Variable_name                      | Value        |
+------------------------------------+--------------+
| rpl_semi_sync_master_enabled       | OFF          |
| rpl_semi_sync_master_timeout       | 10000        |
| rpl_semi_sync_master_trace_level   | 32           |
| rpl_semi_sync_master_wait_no_slave | ON           |
| rpl_semi_sync_master_wait_point    | AFTER_COMMIT |
| rpl_semi_sync_slave_enabled        | OFF          |
| rpl_semi_sync_slave_trace_level    | 32           |
+------------------------------------+--------------+
7 rows in set (0.00 sec)

控制是否在主端启用半同步复制:

MariaDB [cndba]> set global rpl_semi_sync_master_enabled=1;
Query OK, 0 rows affected (0.00 sec)

指定主端等待slave响应的时间,单位是毫秒,这里设为10秒http://www.cndba.cn/dave/article/2661

http://www.cndba.cn/dave/article/2661

MariaDB [cndba]> set global rpl_semi_sync_master_timeout=10000;  
Query OK, 0 rows affected (0.00 sec)
3.3 修改slave端半同步相关参数
MariaDB [cndba]> show variables like '%rpl_semi_sync%';
+------------------------------------+--------------+
| Variable_name                      | Value        |
+------------------------------------+--------------+
| rpl_semi_sync_master_enabled       | OFF          |
| rpl_semi_sync_master_timeout       | 10000        |
| rpl_semi_sync_master_trace_level   | 32           |
| rpl_semi_sync_master_wait_no_slave | ON           |
| rpl_semi_sync_master_wait_point    | AFTER_COMMIT |
| rpl_semi_sync_slave_enabled        | OFF          |
| rpl_semi_sync_slave_trace_level    | 32           |
+------------------------------------+--------------+
7 rows in set (0.00 sec)

控制是否在slave端启用半同步复制:

MariaDB [cndba]> set global rpl_semi_sync_slave_enabled=1;
Query OK, 0 rows affected (0.00 sec)

MariaDB [cndba]> show variables like '%rpl_semi_sync%';
+------------------------------------+--------------+
| Variable_name                      | Value        |
+------------------------------------+--------------+
| rpl_semi_sync_master_enabled       | OFF          |
| rpl_semi_sync_master_timeout       | 10000        |
| rpl_semi_sync_master_trace_level   | 32           |
| rpl_semi_sync_master_wait_no_slave | ON           |
| rpl_semi_sync_master_wait_point    | AFTER_COMMIT |
| rpl_semi_sync_slave_enabled        | ON           |
| rpl_semi_sync_slave_trace_level    | 32           |
+------------------------------------+--------------+
7 rows in set (0.00 sec)
3.4 重启slave节点的io_thread线程

通过重启让slave重新连接master,注册成为半同步的slave身份。

MariaDB [cndba]> stop slave io_thread;
Query OK, 0 rows affected (0.01 sec)

MariaDB [cndba]> start slave io_thread;
Query OK, 0 rows affected (0.00 sec)
3.5 查看master相关变量
MariaDB [cndba]>  show status like 'rpl_semi_sync%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 1     |
| Rpl_semi_sync_master_net_avg_wait_time     | 432   |
| Rpl_semi_sync_master_net_wait_time         | 432   |
| Rpl_semi_sync_master_net_waits             | 1     |
| Rpl_semi_sync_master_no_times              | 0     |
| Rpl_semi_sync_master_no_tx                 | 0     |
| Rpl_semi_sync_master_status                | ON    |
| Rpl_semi_sync_master_timefunc_failures     | 0     |
| Rpl_semi_sync_master_tx_avg_wait_time      | 468   |
| Rpl_semi_sync_master_tx_wait_time          | 468   |
| Rpl_semi_sync_master_tx_waits              | 1     |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
| Rpl_semi_sync_master_wait_sessions         | 0     |
| Rpl_semi_sync_master_yes_tx                | 1     |
| Rpl_semi_sync_slave_status                 | OFF   |
+--------------------------------------------+-------+
15 rows in set (0.00 sec)

主要关注四个参数:
Rpl_semi_sync_master_status —-表示当前master节点是否启用了半同步模式
Rpl_semi_sync_master_no_tx —-表示当前未成功发送到slave节点的事物数量
Rpl_semi_sync_master_yes_tx —-表示当前已成功发送到slave节点的事物数量
Rpl_semi_sync_master_clients —-表示当前处于半同步模式的slave节点数量

http://www.cndba.cn/dave/article/2661
http://www.cndba.cn/dave/article/2661

3.6 测试

主库:

MariaDB [(www.cndba.cn/dave)]> use cndba
Database changed
MariaDB [cndba]> select * from dave;
+------+-------------------+
| id   | name              |
+------+-------------------+
|    1 | www.cndba.cn/dave |
|    2 | www.zhixintech.cc |
+------+-------------------+
2 rows in set (0.00 sec)

MariaDB [cndba]> insert into dave values(1,'dave');
Query OK, 1 row affected (0.04 sec)

从库:

MariaDB [(www.cndba.cn/dave)]> use cndba
Database changed
MariaDB [cndba]> select * from dave;
+------+-------------------+
| id   | name              |
+------+-------------------+
|    1 | www.cndba.cn/dave |
|    2 | www.zhixintech.cc |
|    1 | dave              |
+------+-------------------+
3 rows in set (0.00 sec)

同步正常,进一步测试:
停掉从库:

[root@MariaDB ~]# service mysql stop
Shutting down MySQL.                                       [  OK  ]
[root@MariaDB ~]#

主库操作:

MariaDB [cndba]> insert into dave values(1,'dave');
Query OK, 1 row affected (10.01 sec)
注意:这里会hang 10秒钟

MariaDB [cndba]> show status like 'rpl_semi_sync%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 0     |
| Rpl_semi_sync_master_net_avg_wait_time     | 263   |
| Rpl_semi_sync_master_net_wait_time         | 526   |
| Rpl_semi_sync_master_net_waits             | 2     |
| Rpl_semi_sync_master_no_times              | 1     |
| Rpl_semi_sync_master_no_tx                 | 1     |
| Rpl_semi_sync_master_status                | OFF   |
| Rpl_semi_sync_master_timefunc_failures     | 0     |
| Rpl_semi_sync_master_tx_avg_wait_time      | 468   |
| Rpl_semi_sync_master_tx_wait_time          | 468   |
| Rpl_semi_sync_master_tx_waits              | 1     |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
| Rpl_semi_sync_master_wait_sessions         | 0     |
| Rpl_semi_sync_master_yes_tx                | 1     |
| Rpl_semi_sync_slave_status                 | OFF   |
+--------------------------------------------+-------+
15 rows in set (0.00 sec)

版权声明:本文为博主原创文章,未经博主允许不得转载。

用户评论
* 以下用户言论只代表其个人观点,不代表CNDBA社区的观点或立场
dave

dave

关注

人的一生应该是这样度过的:当他回首往事的时候,他不会因为虚度年华而悔恨,也不会因为碌碌无为而羞耻;这样,在临死的时候,他就能够说:“我的整个生命和全部精力,都已经献给世界上最壮丽的事业....."

  • 2262
    原创
  • 3
    翻译
  • 579
    转载
  • 192
    评论
  • 访问:8089720次
  • 积分:4350
  • 等级:核心会员
  • 排名:第1名
精华文章
    最新问题
    查看更多+
    热门文章
      热门用户
      推荐用户
        Copyright © 2016 All Rights Reserved. Powered by CNDBA · 皖ICP备2022006297号-1·

        QQ交流群

        注册联系QQ