MySQL主从复制:半同步、异步
2016-04-28 15:00
966 查看
MySQL主从复制:半同步、异步
大纲前言
如何对MySQL进行扩展?
MySQL Replication WorkFlow
MySQL主从复制模式
实战演练MySQL异步复制实现
MySQL半同步复制实现
实验中的思考
总结
前言
本篇我们介绍MySQL Replication的相关内容, 我们首先介绍
MySQL CLuster的实现原理和如何一步步构建一个
MySQL Replication Cluster看懂本文需要了解:
MySQL基本操作,
MySQL日志类型及其作用
如何对MySQL进行扩展?
大家之前应该了解; 在单台服务器性能不足时, 有两种方式进行扩展Scale Up ; 垂直扩展Scale Out ; 水平扩展垂直扩展: 指的是提升单台服务器的性能(硬件)来提升服务的性能
水平扩展: 指的是添加服务器通过负载均衡的方式来分担单台服务器的负载, 从而提升服务的性能
我们可以通过LVS, HAProxy, Nginx等软件实现一些服务的负载均衡, 但是如果要用到
MySQL上就会有一些问题, 如下如何保证多台
MySQL服务器数据的一致性
如何保证多台服务器同时提交事务导致数据的完整性
如何保证一台服务器宕机时, 其的事务能够正常提交或ROLLBACK
…
我们需要考虑的问题比扩展
WEB服务多太多了, 毕竟大家都知道,
数据无价, 在很多重要场景中, 数据不能有半点闪失, 但是
MySQL对这方面做得并不是很好, 而
Oracle数据库在这方面特别的厉害, 所以众多的银行都采用
Oracle数据库存储客户的账户信息等, 这么说, 难道我们就不用
MySQL了么? 这显然不可能, 我们首先来介绍一下
MySQL Replication Cluster的几种同步数据方式Synchronous Replication 同步复制
Asynchronous Replication 异步复制
Semisynchronous Replication 半同步复制同步复制: 指的是客户端连接到
MySQL主服务器写入一段数据,
MySQL主服务器同步给
MySQL从服务器需要等待从服务器发出同步完成的响应才返回客户端OK, 这其中等待同步的过程是阻塞的, 如果有N台从服务器, 效率极低
异步复制: 指的是客户端连接到
MySQL主服务器写入一段数据,
MySQL主服务器将写入的数据发送给
MySQL从服务器, 然后直接返回客户端OK, 可能从服务器的数据会和主服务不一致
半同步复制:指的是客户端连接到
MySQL主服务器写入一段数据,
MySQL主服务器只将数据同步复制给其中一台从服务器, 半同步复制给其他的从服务器, 来达到其中一台从服务器完全同步的效果
MySQL Replication WorkFlow
Master/Slave工作流程建立主从关系后, 主服务器如果有数据修改之后,
BINLOG会更新, 从服务通过
IO-Thread读取主服务器的
BINLOG到本地的
Relay Log, 再通过
SQL-Thread对其进行重放(replay), 从而同步到本地
MySQL主从复制模式
在不同的业务模型中我们可以采用不同的MySQL主从复制架构, 一般分为以下两种Master/Slave
Master/MasterMaster/Slave: 指的是一主多从模式, 这种模式下可以有效的分担读请求, 但是写请求并不能完成负载分担、从节点可能数据不一致, 并且如果
Master宕机了客户端就无法进行写操作了, 还是有很多问题的
Master/Master: 指的是多主模式, 这种模式中的多台
MySQL服务器都是
Master, 也就意味着都可以进行读写操作, 但是有着更为严重的问题, 多个客户端同时写入数据时由于复制延迟可能到导致数据冲突等严重问题
常用的架构图我们可以使用keepalived实现Master高可用, 并且使用半同步模式实现数据的完全同步
上面那种方式太占用Master的带宽, 我们可以让一台Slave扮演为Master, 为其他Slave同步数据
实战演练
MySQL异步复制实现
实验拓扑环境部署我们需要在各台服务器上安装
MySQL, 这里使用的是rpm包安装, 版本为5.1
[root@node1 ~]# yum install mysql-server -y [root@node2 ~]# yum install mysql-server -y [root@node3 ~]# yum install mysql-server -y配置文件
node1配置文件(master) [mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock user=mysql # Disabling symbolic-links is recommended to prevent assorted security risks symbolic-links=0 innodb_file_per_table = 1 log_bin=master-log #开启二进制日志 log_bin_index=1 server_id=1 #设置serverid [mysqld_safe] log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid node2配置文件(slave1) [mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock user=mysql # Disabling symbolic-links is recommended to prevent assorted security risks symbolic-links=0 relay-log=relay-log #开启relay日志 innodb_file_per_table = 1 read-only = 1 #设置只读 server_id = 2 #设置serverid [mysqld_safe] log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid node3配置文件(slave2) [mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock user=mysql # Disabling symbolic-links is recommended to prevent assorted security risks symbolic-links=0 relay-log=relay-log innodb_file_per_table = 1 read-only = 1 server_id = 3 [mysqld_safe] log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid ##启动mysql ##注意: serverid一定不能相同配置MasterSlave节点进行同步需要通过一个特定的用户进行, 所以我们需要创建一个用户并赋予
REPLICATION SLAVE, REPLICATION CLIENT权限
mysql> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'rpuser'@'%' IDENTIFIED BY 'passwd'; Query OK, 0 rows affected (0.00 sec) mysql> FLUSH PRIVILEGES; Query OK, 0 rows affected (0.00 sec) mysql> SHOW MASTER STATUS; 我们要记录下pos的数值 +-------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +-------------------+----------+--------------+------------------+ | master-log.000005 | 523 | | | +-------------------+----------+--------------+------------------+ 1 row in set (0.00 sec)配置Slave(1)
mysql> CHANGE MASTER TO -> MASTER_HOST='172.16.1.2', -> MASTER_USER='rpuser', -> MASTER_PASSWORD='passwd', -> MASTER_LOG_FILE='master-log.000005', -> MASTER_LOG_POS=523; Query OK, 0 rows affected (0.01 sec mysql> SHOW SLAVE STATUS\G; #查看相应信息 #########省略################## Master_Log_File: master-log.000005 Read_Master_Log_Pos: 523 Relay_Log_File: relay-log.000001 Relay_Log_Pos: 4 Relay_Master_Log_File: master-log.000005 Slave_IO_Running: No #IO-thread没有启动 Slave_SQL_Running: No #SQL-thread没有启动 #########省略################## mysql> START SLAVE; #启动sql-thread和io-thred mysql> SHOW SLAVE STATUS\G; #查看相应信息 Query OK, 0 rows affected (0.00 sec) #########省略################## Master_Log_File: master-log.000005 Read_Master_Log_Pos: 523 Relay_Log_File: relay-log.000002 Relay_Log_Pos: 252 Relay_Master_Log_File: master-log.000005 Slave_IO_Running: Yes #IO-thread启动 Slave_SQL_Running: Yes #SQL-thread启动 #########省略##################配置slave(2)过程和配置slave(1)相同, 不做演示测试主从复制
##在主服务器上创建数据库和表 [root@node1 ~]# mysql mysql> SHOW DATABASES; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | test | +--------------------+ 3 rows in set (0.00 sec) mysql> CREATE DATABASE replication; Query OK, 1 row affected (0.00 sec) mysql> USE replication; Database changed mysql> CREATE TABLE t1 (id int unsigned auto_increment primary key, name char(30)); Query OK, 0 rows affected (0.01 sec) mysql> DESC t1; +-------+------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+------------------+------+-----+---------+----------------+ | id | int(10) unsigned | NO | PRI | NULL | auto_increment | | name | char(30) | YES | | NULL | | +-------+------------------+------+-----+---------+----------------+ 2 rows in set (0.00 sec) mysql> SHOW MASTER STATUS; +-------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +-------------------+----------+--------------+------------------+ | master-log.000005 | 765 | | | +-------------------+----------+--------------+------------------+ 1 row in set (0.00 sec)
##在slave服务器测试 [root@node2 ~]# mysql mysql> SHOW DATABASES; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | replication | | test | +--------------------+ 4 rows in set (0.00 sec) mysql> use replication; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> DESC t1; +-------+------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+------------------+------+-----+---------+----------------+ | id | int(10) unsigned | NO | PRI | NULL | auto_increment | | name | char(30) | YES | | NULL | | +-------+------------------+------+-----+---------+----------------+ 2 rows in set (0.00 sec) mysql> SHOW SLAVE STATUS\G; #########省略################## Master_Log_File: master-log.000005 Read_Master_Log_Pos: 765 #已经同步 Relay_Log_File: relay-log.000002 Relay_Log_Pos: 494 Relay_Master_Log_File: master-log.000005 Slave_IO_Running: Yes Slave_SQL_Running: Yes #########省略##################
MySQL半同步复制实现
由于MySQL半同步复制在
MySQL5.5以后才以插件的形式进行提供, 所以这里我们的
MySQL要换成5.5版本的
MariaDB由于很多步骤和上面重复,我就不写出来了,先配置成M/S然后再按照我下面操作实验拓扑
配置master
半同步的插件在/usr/lib64/mysql/plugin下, master用的semisync_master.so,slave用的semisync_slave.so, MariaDB [(none)]> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; Query OK, 0 rows affected (0.00 sec) MariaDB [(none)]> SET GLOBAL rpl_semi_sync_master_enabled = 1; Query OK, 0 rows affected (0.00 sec) MariaDB [(none)]> SET GLOBAL rpl_semi_sync_master_timeout = 2000; #设置超时时间为2S Query OK, 0 rows affected (0.00 sec)配置slave
MariaDB [(none)]> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so'; Query OK, 0 rows affected (0.00 sec) MariaDB [(none)]> SET GLOBAL rpl_semi_sync_slave_enabled=1; Query OK, 0 rows affected (0.00 sec)验证
因为在我的环境中,即使是半同步复制,也是直接就完成,看不出效果,所以我们故意将slave节点关闭 [root@node2 ~]# service mysql stop ##master创建数据库 MariaDB [(none)]> CREATE DATABASE TEST3; Query OK, 1 row affected (2.00 sec) #等待2s, 超时不再等待,直接创建 MariaDB [(none)]> CREATE DATABASE TEST4; Query OK, 1 row affected (0.00 sec) ##完成,这个可能不是特别直观,但是由于我这边环境实在做不出效果,望大家理解
实验中的思考
如果主从服务器数据相差较大, 最好先使用主服务器的二进制日志在从服务器上replay一篇, 然后再进行同步总结
这篇其实还打算写SSL复制的,但是因为时间比较紧,就没有写了,总体来说不是特别的满意,有很多地方没有说明白,还望大家谅解。作者水平很低, 如果有错误及时指出, 如果你觉得本文写的好请点一波赞~(≧▽≦)/~作者: AnyISaIln QQ: 1449472454
感谢: MageEdu
相关文章推荐
- MySQL中的integer 数据类型
- MySQL存储过程
- mysql中int、bigint、smallint 和 tinyint的区别与长度
- mysql load data 导出、导入 csv
- source命令执行SQL脚本文件
- MySQL创建用户及权限控制
- MySQL管理数据表
- linux下mysql添加用户
- mysql procedure
- mysql触发器
- MySQL 备份和恢复策略
- mac下安装mysql(转载)
- mysql 修改编码 Linux/Mac/Unix/通用(杜绝修改后无法启动的情况!)
- MySQL数据的导出、导入(mysql内部命令:mysqldump、mysql)
- mysql数据行转列
- Linux下修改MySQL编码的方法
- MySQL Server 日志
- MySQL 安全事宜
- MySQL 备份与恢复