MySQL半同步复制

《MySQL半同步复制》要点:
本文介绍了MySQL半同步复制,希望对您有用。如果有疑问,可以联系我们。

简介

一、前言

二、Mysql 根基知识

三、Mysql 复制(Replication)

四、Mysql 复制(Replication)类型

五、Mysql 主从复制基本步调

六、Mysql 主从复制(异步)

七、Mysql 主从复制(半同步)

八、Mysql 复制对象

九、Mysql 复制注意事变

十、Mysql 复制过滤

一、前言

从这一篇博客开始我们就来学习mysql的高档课程,在前面的几篇博客我们讲解了mysql基础知识、mysql日志类型、mysql配置文件、mysql备份策略,这一篇博客中我们来讲解mysql的复制.

二、mysql根基知识

1.mysql日记类型

  • 二进制日记

  • 事务日记

  • 差错日志

  • 一般查询日记

  • 中继日记

  • 慢查询日记

注,有博友对mysql日记不怎么了解,可以参考这篇博客http://freeloda.blog.51cto.com/2033581/1253991

2.mysql二进制日记详解

阐明:默认开启,精确的记录了用户对数据库中的数据进行操作的命令和操作的数据对象.

二进制日记文件的作用:

  • 提供了增量备份的功效

  • 提供了数据基于光阴点的恢复,这个恢复的光阴点可以由用户控制

  • 为mysql的复制架构提供根基,将这主服务器的二进制日志复制到从服务器上并执行同样的操作,就可将数据进行同步

  • 实现数据的高可用

  • 分担当载

二进制日志默认寄存位置:

  • 数据目录下,以mysql-bin.XXXXXX定名的日志

二进制日志格局:

  • 基于语句 statement

  • 基于行 row

  • 混合方式 mixed

二进制日记滚动方式:

  • 重启服务

  • 日志到达最大上限

  • 执行flush logs

二进制日志变乱:

  • position 基于位置,也便是offset(偏移量)

  • datetime 基于光阴

  • timestamp

二进制日记的查看与删除方式:

mysql>show master status; 查看当前正在使用的二进制日志
mysql>show binlog events in'mysql-bin.000001'; 查看二进制日志记录的变乱[from position]
mysql>flush logs; 二进制日志滚动
mysql>show binary logs; 查看所有二进制日志
mysql>purge binary logs to 'mysql-bin.000003'; 删除二进制日志

文件系统中查看二进制日志的命令:

mysqlbinlog相关选项,--start-position #开始位置--stop-position #结束位置
--start-datetime 'yyyy-mm-dd hh:mm:ss'; #开始时间
--stop-datetime ''; #结束时间

配置mysql的主配置文件:

sql_log_bin = {ON|OFF} #用于控制二进制日志信息是否记录进日志文件.默认为ON,表示启用记录功能.用户可以在会话级别修改此变量的值,但其必须具有SUPER权限
binlog_cache_size = 32768 #默认值32768 Binlog Cache 用于在打开了二进制日志(binlog)记录功能的环境,是 MySQL 用来提高binlog的记录效率而设计的一个用于短时间内临时缓存binlog数据的内存区域.一般来说,如果我们的数据库中没有什么大事务,写入也不是特别频繁,2MB~4MB是一个合适的选择.但是如果我们的数据库大事务较多,写入量比较大,可与适当调高binlog_cache_size.同时,我们可以通过binlog_cache_use 以及 binlog_cache_disk_use来分析设置的binlog_cache_size是否足够,是否有大量的binlog_cache由于内存大小不够而使用临时文件(binlog_cache_disk_use)来缓存了
binlog_stmt_cache_size = 32768 #当非事务语句使用二进制日志缓存,但是超出binlog_stmt_cache_size时,使用一个临时文件来存放这些语句
log_bin = mysql-bin #指定binlog的位置,默认在数据目录下
binlog-format= {ROW|STATEMENT|MIXED}#指定二进制日志的类型,默认为MIXED.如果设定了二进制日志的格式,却没有启用二进制日志,则MySQL启动时会产生警告日志信息并记录于错误日志中.
sync_binlog = 10 #设定多久同步一次二进制日志至磁盘文件中,0表示不同步,任何正数值都表示对二进制每多少次写操作之后同步一次.当autocommit的值为1时,每条语句的执行都会引起二进制日志同步,否则,每个事务的提交会引起二进制日志同步
max_binlog_cache_size = {4096 .. 18446744073709547520} #二进定日志缓存空间大小,5.5.9及以后的版本仅应用于事务缓存,其上限由max_binlog_stmt_cache_size决定.
max_binlog_stmt_cache_size = {4096 .. 18446744073709547520} #二进定日志缓存空间大小,5.5.9及以后的版本仅应用于事务缓存expire_log_days = {0..99}
#设定二进制日志的过期天数,超出此天数的二进制日志文件将被自动删除.默认为0,表示不启用过期自动删除功能.如果启用此功能,自动删除工作通常发生在MySQL启动时或FLUSH日志时

注:一般建议将binlog日志与数据文件分开存放,不但可以提高mysql性能,还可以增加平安性!

三、Mysql 复制(Replication)

1.Mysql 复制造用

  • 负载均衡(load balancing)

  • 备份

  • 高可用性(high availability)和容错

2.Mysql 复制若何工作

主要有三步(如下图):

  • master将改变记录到二进制日志(binary log)中(这些记录叫做二进制日志变乱,binary log events);

  • slave将master的binary log events拷贝到它的中继日记(relay log);

  • slave重做中继日志中的事件,将改变反映它本身的数据.

MySQL半同步复制

具体阐明:

该过程的第一部分便是master记录二进制日志.在每个事务更新数据完成之前,master在二日志记录这些改变.MySQL将事务串行的写入二进制日志,即使事务中的语句都是交叉执行的.在事件写入二进制日志完成后,master通知存储引擎提交事务.

下一步就是slave将master的binary log拷贝到它本身的中继日志.首先,slave开始一个工作线程——I/O线程.I/O线程在master上打开一个普通的连接,然后开始binlog dump process.Binlog dump process从master的二进制日志中读取事件,如果已经跟上master,它会睡眠并等待master产生新的事件.I/O线程将这些事件写入中继日志.

SQL slave thread处理该过程的最后一步.SQL线程从中继日志读取事件,更新slave的数据,使其与master中的数据一致.只要该线程与I/O线程坚持一致,中继日志通常会位于OS的缓存中,所以中继日志的开销很小.

此外,在master中也有一个工作线程:和其它MySQL的连接一样,slave在master中打开一个连接也会使得master开始一个线程.复制过程有一个很重要的限制——复制在slave上是串行化的,也就是说master上的并行更新操作不能在slave上并行操作.所以slave上数据一般要慢于master上数据.即master与slave之间的数据在必定时间内会不同步.

四、Mysql 复制(Replication)类型

1.mysql复制类型有以下一些基来源根基则

  • 每个slave只能有一个master;

  • 每个slave只能有一个独一的服务器ID;

  • 每个master可以有许多slave;

  • 假如你设置log_slave_updates,slave可以是其它slave的master,从而扩散master的更新.

注,MySQL不支持多主服务器复制(Multimaster Replication)——即一个slave可以有多个master.但是,通过一些简单的组合,我们却可以建立灵活而强大的复制体系布局.

2.mysql复制类型

(1).一主多从模式

注,由一个master和一个slave构成复制系统是最简单的情况.Slave之间并不相互通信,只能与master进行通信.

MySQL通过复制(Replication)实现存储系统的高可用.今朝,MySQL支持的复制方式有:

  • 异步复制(Asynchronous Replication):原理最简单,性能最好.但是主备之间数据纷歧致的概率很大.

MySQL半同步复制

MySQL半同步复制

MySQL半同步复制

  • 半同步复制(Semi-synchronous Replication):相比异步复制,半同步复制牺牲了必定的性能,提升了主备之间数据的一致性(有一些情况还是会出现主备数据不一致).

mysql> SHOW GLOBAL STATUS LIKE 'rpl_semi%'; +--------------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients | 1 |
| Rpl_semi_sync_master_net_avg_wait_time | 1560 |
| Rpl_semi_sync_master_net_wait_time | 10920 |
| Rpl_semi_sync_master_net_waits | 7 |
| 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 | 985 |
| Rpl_semi_sync_master_tx_wait_time | 985 |
| 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 | 6 |
+--------------------------------------------+-------+
14 rows in set (0.00 sec)
mysql> STOP SLAVE IO_THREAD;
Query OK,0 rows affected (0.01 sec)
mysql> SHOW GLOBAL STATUS LIKE 'rpl_semi%';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | OFF |
+----------------------------+-------+
1 row in set (0.00 sec)
  • 组复制(Group Replication):基于Paxos算法实现分布式数据复制的强一致性.只要年夜多数机器存活就能保证系统可用.相比半同步复制,Group Replication的数据一致性和系统可用性更高

  • 具体阐明:

  • 主动的Master-Master复制有一些特殊的用处.例如,地理上分布的两个部分都需要本身的可写的数据副本.这种结构最大的问题就是更新冲突.假设一个表只有一行(一列)的数据,其值为1,如果两个服务器分别同时执行如下语句:

mysql> STOP SLAVE IO_THREAD;
Query OK,0 rows affected (0.01 sec)
master:
mysql> create table user1 (id int(10));
Query OK,0 rows affected (1.03 sec)
  • 在第一个服务器上执行:

  • 那么结果是多少呢?一台服务器是4,另一个服务器是3,但是,这并不会产生差错.

mysql> UPDATE tbl SET col=col + 1;
在第二个服务器上执行:
mysql> UPDATE tbl SET col=col * 2;
mysql> create table user (id int(10));
Query OK,0 rows affected (0.42 sec)
mysql> show tables;
+----------------+
| Tables_in_mydb |
+----------------+
| user |
+----------------+
1 row in set (0.00 sec)
mysql> insert user value (1);
Query OK,1 row affected (0.34 sec)
  • 实际上,MySQL并不支持其它一些DBMS支持的多主服务器复制(Multimaster Replication),这是MySQL的复制功能很大的一个限制(多主服务器的难点在于办理更新冲突),如果你实在有这种需求,你可以采用MySQL Cluster,以及将Cluster和Replication结合起来,可以建立强大的高性能的数据库平台.但是,可以通过其它一些方式来模拟这种多主服务器的复制.

  • (3).主从模式

  • 注,这是master-master结构变化而来的,它避免了M-M的缺点,实际上,这是一种具有容错和高可用性的系统.它的分歧点在于其中一个服务只能进行只读操作.

mysql> SHOW GLOBAL STATUS LIKE 'rpl_semi%';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON |
+----------------------------+-------+
1 row in set (0.01 sec)
  • (4).带从服务器的Master-Master布局(Master-Master with Slaves)

  • 注,这种结构的优点就是提供了冗余.在地理上分布的复制结构,它不存在单一节点故障问题,而且还可以将读密集型的哀求放到slave上.

mysql> SHOW GLOBAL STATUS LIKE 'rpl_semi%';
+--------------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients | 1 |
| Rpl_semi_sync_master_net_avg_wait_time | 0 |
| Rpl_semi_sync_master_net_wait_time | 0 |
| Rpl_semi_sync_master_net_waits | 0 |
| 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 | 0 |
| Rpl_semi_sync_master_tx_wait_time | 0 |
| Rpl_semi_sync_master_tx_waits | 0 |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0 |
| Rpl_semi_sync_master_wait_sessions | 0 |
| Rpl_semi_sync_master_yes_tx | 0 |
+--------------------------------------------+-------+
14 rows in set (0.00 sec)
  • 总结:一般常用的两种复制类型一种是主从模式,另一种是一主多从模式.在这一篇博客中我们主要讲授主从模式复制.

  • 五、Mysql 主从复制基本步调

[root@node2 ~]# service mysqld restart
Shutting down MySQL. SUCCESS!
Starting MySQL.. SUCCESS!
  • 1.master 设置装备摆设


  • 启用二进制日记

  • 设置装备摆设一个唯一的server-id

[root@node2 ~]# vim /etc/my.cnf
[mysqld]
rpl_semi_sync_slave_enabled=1 #启用半同步复制
  • 创立具有复制权限的用户

  • 2.slave 设置装备摆设

  • 启用中继日记

mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
Query OK,0 rows affected (0.38 sec)
mysql> SET GLOBAL rpl_semi_sync_slave_enabled = 1;
Query OK,0 rows affected (0.00 sec)
mysql> STOP SLAVE IO_THREAD;
Query OK,0 rows affected (0.00 sec)
mysql> START SLAVE IO_THREAD;
Query OK,0 rows affected (0.01 sec)
  • 设置装备摆设一个唯一的server-id

  • 连接主服务器,并开端复制数据

  • 启动数据复制

[root@node1 ~]# service mysqld restart
Shutting down MySQL... SUCCESS!
Starting MySQL.. SUCCESS!
  • 注,基本步调我们就说到这里,下面我们来具体演示一下主从复制.

  • 六、Mysql 主从复制(异步)

  • 1.mysql异步复制

[root@node1 ~]# vim /etc/my.cnf
[mysqld]
rpl_semi_sync_master_enabled=1 #启用半同步
rpl_semi_sync_master_timeout=1000 #超时时间为1s
  • 异步复制:MySQL自己支持单向的、异步的复制.异步复制意味着在把数据从一台机器拷贝到另一台机器时有一个延时,最重要的是这意味着当应用系统的事务在主服务器上提交并确认时数据并不能在同一时刻拷贝或应用到从服务器上.通常这个延时是由网络带宽、资源可用性和系统负载决定的.然而,使用正确的组件并且调优,复制能做到接近瞬时完成.

  • 当主库有更新的时候,主库会把更新操作的SQL写入二进制日志(Bin log),并维护一个二进制日志文件的索引,以便于日志文件轮回(Rotate).在从库启动异步复制的时候,从库会开启两个I/O线程,其中一个线程连接主库,要求主库把二进制日志的变化部分传给从库,并把传回的日志写入当地磁盘.另一个线程则负责读取当地写入的二进制日志,并在当地执行,以反映出这种变化.较老的版本在复制的时候只启用一个I/O线程,实现这两部分的功能.下面我们来具体演示一下mysql的异步复制.

  • 2.试验拓扑

mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
Query OK,0 rows affected (0.39 sec)
mysql> SET GLOBAL rpl_semi_sync_master_enabled = 1;
Query OK,0 rows affected (0.00 sec)
mysql> SET GLOBAL rpl_semi_sync_master_timeout = 1000;
Query OK,0 rows affected (0.00 sec)
  • 注,Active (master,node1) 192.168.1.201,Passive (slave,node2)192.168.1.202

  • 3.情况配置

mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mydb |
| mysql |
| performance_schema |
| test |
+--------------------+
5 rows in set (0.03 sec)
  • 光阴同步

  • 4.操作体系

[root@node1 ~]# ntpdate 202.120.2.101
[root@node2 ~]# ntpdate 202.120.2.101
mysql> create database mydb;
Query OK,1 row affected (0.00 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mydb |
| mysql |
| performance_schema |
| test |
+--------------------+
5 rows in set (0.00 sec)
  • CentOS 6.4 X86_64

  • 5.软件版本

  • Mysql 5.5.33 (注,这里用的是mysql 5.5.33二进制通用安装包,解压就能用)

查看master上二进制日志
mysql> show master status;
+-------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-------------------+----------+--------------+------------------+
| master-bin.000001 | 107 | | |
+-------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
衔接master服务器
mysql> change master to master_host='192.168.1.201',master_user='repluser',master_password='replpass',master_log_file='master-bin.000001',master_log_pos=107;
Query OK,0 rows affected (0.07 sec)
查看一下slave状态
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State:
Master_Host: 192.168.1.201
Master_User: repluser
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: master-bin.000001
Read_Master_Log_Pos: 107
Relay_Log_File: relay-log.000001
Relay_Log_Pos: 4
Relay_Master_Log_File: master-bin.000001
Slave_IO_Running: No
Slave_SQL_Running: No
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 107
Relay_Log_Space: 107
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 0
1 row in set (0.00 sec)
启动复制并查看状态
mysql> start slave;
Query OK,0 rows affected (0.00 sec)
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.1.201
Master_User: repluser
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: master-bin.000001
Read_Master_Log_Pos: 107
Relay_Log_File: relay-log.000002
Relay_Log_Pos: 254
Relay_Master_Log_File: master-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 107
Relay_Log_Space: 404
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
1 row inset (0.00 sec)
  • 6.安装并配置mysql


  • master:

  • (1).解压并链接

[root@node2 ~]# service mysqld restart
Shutting down MySQL..... SUCCESS!
Starting MySQL........... SUCCESS!

[root@node1 src]# tar xf mysql-5.5.33-linux2.6-x86_64.tar.gz -C /usr/local/
[root@node1 src]# cd /usr/local/
[root@node1 local]# ln -sv /usr/local/mysql-5.5.33-linux2.6-x86_64 mysql
"mysql" -> "/usr/local/mysql-5.5.33-linux2.6-x86_64"
[root@node1 local]# cd mysql
[root@node1 mysql]# ll
总用量 200
drwxr-xr-x 2 root root 4096 8月 24 17:58 bin
-rw-r--r-- 1 7161 wheel 17987 7月 15 20:01 COPYING
drwxr-xr-x 3 root root 4096 8月 24 17:58 data
drwxr-xr-x 2 root root 4096 8月 24 17:58 docs
drwxr-xr-x 3 root root 4096 8月 24 17:58 include
-rw-r--r-- 1 7161 wheel 134493 7月 15 20:01 INSTALL-BINARY
drwxr-xr-x 3 root root 4096 8月 24 17:58 lib
drwxr-xr-x 4 root root 4096 8月 24 17:58 man
drwxr-xr-x 10 root root 4096 8月 24 17:58 mysql-test
-rw-r--r-- 1 7161 wheel 2496 7月 15 20:01 README
drwxr-xr-x 2 root root 4096 8月 24 17:58 scripts
drwxr-xr-x 27 root root 4096 8月 24 17:58 share
drwxr-xr-x 4 root root 4096 8月 24 17:58 sql-bench
drwxr-xr-x 3 root root 4096 8月 24 17:58 support-files
1
2
3
  • (2).新建mysql用户

1
2
3
4
[root@node1 mysql]# groupadd -g 3306 mysql
[root@node1 mysql]# useradd -u 3306 -g mysql -s /sbin/nologin -M mysql
[root@node1 mysql]# id mysql
uid=3306(mysql) gid=3306(mysql) 组=3306(mysql)
[root@node2 ~]# vim /etc/my.cnf
#增加下面几行
[mysqld]
relay-log = relay-log
relay-log-index = relay-log.index
server-id = 10
  • (3).改动mysql安装目录所有者与所属组

  • (4).为mysql提供配置文件并改动

[root@node1 mysql]# chown -R root.mysql /usr/local/mysql/*
[root@node1 mysql]# ll
总用量 200
drwxr-xr-x 2 root mysql 4096 8月 24 17:58 bin
-rw-r--r-- 1 root mysql 17987 7月 15 20:01 COPYING
drwxr-xr-x 3 root mysql 4096 8月 24 17:58 data
drwxr-xr-x 2 root mysql 4096 8月 24 17:58 docs
drwxr-xr-x 3 root mysql 4096 8月 24 17:58 include
-rw-r--r-- 1 root mysql 134493 7月 15 20:01 INSTALL-BINARY
drwxr-xr-x 3 root mysql 4096 8月 24 17:58 lib
drwxr-xr-x 4 root mysql 4096 8月 24 17:58 man
drwxr-xr-x 10 root mysql 4096 8月 24 17:58 mysql-test
-rw-r--r-- 1 root mysql 2496 7月 15 20:01 README
drwxr-xr-x 2 root mysql 4096 8月 24 17:58 scripts
drwxr-xr-x 27 root mysql 4096 8月 24 17:58 share
drwxr-xr-x 4 root mysql 4096 8月 24 17:58 sql-bench
drwxr-xr-x 3 root mysql 4096 8月 24 17:58 support-files
[root@node1 ~]# service mysqld restart
Shutting down MySQL....... SUCCESS!
Starting MySQL............. SUCCESS!
[root@node1 mysql]# cp support-files/my-large.cnf /etc/my.cnf
[root@node1 mysql]# vim /etc/my.cnf
[mysqld]
#增加一行
datadir = /mydata/data
1
2
3
  • (5).为mysql提供启动剧本

1
2
[root@node1 mysql]# cp support-files/mysql.server /etc/init.d/mysqld
[root@node1 mysql]# chmod +x /etc/init.d/mysqld
mysql> grant replication slave on *.* to 'repluser'@'192.168.1.%' identified by 'replpass';
Query OK,0 rows affected (0.61 sec)
mysql> flush privileges;
Query OK,0 rows affected (0.41 sec)
  • (6).初始化mysql数据库

  • (7).启动并测试

[root@node1 ~]# mkdir -pv /mydata/data
mkdir: 已创建目录 "/mydata"
mkdir: 已创建目录 "/mydata/data"
[root@node1 ~]# chown -R mysql.mysql /mydata/data/
[root@node1 ~]# /usr/local/mysql/scripts/mysql_install_db --datadir=/mydata/data/ --basedir=/usr/local/mysql --user=mysql
Installing MySQL system tables...
/usr/local/mysql/bin/mysqld: error while loading shared libraries: libaio.so.1: cannot open shared object file: No such file or directory
Installation of system tables failed! Examine the logs in
/mydata/data/ for more information.
You can try to start the mysqld daemon with:
shell> /usr/local/mysql/bin/mysqld --skip-grant &
and use the commandline tool /usr/local/mysql/bin/mysql
to connect to the mysql database and lookat the grant tables:
shell> /usr/local/mysql/bin/mysql -u root mysql
mysql> show tables
Try 'mysqld --help' ifyou have problems with paths. Using --log
gives you a log in /mydata/data/ that may be helpful.
Please consult the MySQL manual section
'Problems running mysql_install_db',and the manual section that
describes problems on your OS. Another information source are the
MySQL email archives available at http://lists.mysql.com/.
Please check all of the above before mailing us! And remember,if
you do mail us,you MUST use the /usr/local/mysql/scripts/mysqlbug script!
[root@node1 ~]# cd /mydata/data/
[root@node1 data]# ll
总用量 8
drwx------ 2 mysql root 4096 8月 24 18:21 mysql
drwx------ 2 mysql root 4096 8月 24 18:21 test
[root@node1 ~]# vim /etc/my.cnf
#增加下面几行
[mysqld]
log-bin=master-bin
log-bin-index=master-bin.index
server-id = 1
innodb_file_per_table = 1
启动报错
[root@node1 data]# service mysqld start
Starting MySQL. ERROR! The server quit without updating PID file (/mydata/data/node1.test.com.pid).
查看一下差错日志
[root@node1 data]# vim node1.test.com.err
130824 18:21:44 mysqld_safe Starting mysqld daemon with databases from /mydata/data
/usr/local/mysql/bin/mysqld: error while loading shared libraries: libaio.so.1: cannot open shared object file: No such file or directory
130824 18:21:44 mysqld_safe mysqld from pid file /mydata/data/node1.test.com.pid ended
注,从差错日志中我们看到差一个库文件libaio,我们用yum安装一下即可.
[root@node1 data]# yum install -y libaio
重新初始化mysql
[root@node1 data]# /usr/local/mysql/scripts/mysql_install_db --datadir=/mydata/data/ --basedir=/usr/local/mysql --user=mysql
启动mysql
[root@node1 data]# service mysqld start
Starting MySQL... SUCCESS!
环境变量配置
[root@node1 data]# vim /etc/profile.d/mysql.sh
export PATH=$PATH:/usr/local/mysql/bin
[root@node1 data]# source /etc/profile
测试一下
[root@node1 data]# mysql
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.5.33-log MySQL Community Server (GPL)
Copyright (c) 2000,2013,Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
4 rows in set (0.03 sec)
mysql>
1
2
3
4
5
6
7
  • 好了,到这里master的mysql配置完成,下面我们进行slave的mysql配置.

  • slave:

启动mysql
[root@node2 data]# service mysqld start
Starting MySQL... SUCCESS!
情况变量配置
[root@node2 data]# vim /etc/profile.d/mysql.sh
export PATH=$PATH:/usr/local/mysql/bin
[root@node1 data]# source /etc/profile
测试一下
[root@node2 data]# mysql
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.5.33-log MySQL Community Server (GPL)
Copyright (c) 2000,Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
4 rows in set (0.06 sec)
mysql>
  • (1).解压并链接

  • (2).新建mysql用户

[root@node2 ~]# tar xf mysql-5.5.33-linux2.6-x86_64.tar.gz -C /usr/local/
[root@node2 ~]# cd /usr/local/
[root@node2 local]# ln -sv /usr/local/mysql-5.5.33-linux2.6-x86_64 mysql
"mysql"-> "/usr/local/mysql-5.5.33-linux2.6-x86_64"
[root@node2 local]# cd mysql
[root@node2 mysql]# ll
总用量 200
drwxr-xr-x 2 root root 4096 8月 24 18:41 bin
-rw-r--r-- 1 7161 wheel 17987 7月 15 20:01 COPYING
drwxr-xr-x 3 root root 4096 8月 24 18:41 data
drwxr-xr-x 2 root root 4096 8月 24 18:41 docs
drwxr-xr-x 3 root root 4096 8月 24 18:41 include
-rw-r--r-- 1 7161 wheel 134493 7月 15 20:01 INSTALL-BINARY
drwxr-xr-x 3 root root 4096 8月 24 18:41 lib
drwxr-xr-x 4 root root 4096 8月 24 18:41 man
drwxr-xr-x 10 root root 4096 8月 24 18:41 mysql-test
-rw-r--r-- 1 7161 wheel 2496 7月 15 20:01 README
drwxr-xr-x 2 root root 4096 8月 24 18:41 scripts
drwxr-xr-x 27 root root 4096 8月 24 18:41 share
drwxr-xr-x 4 root root 4096 8月 24 18:41 sql-bench
drwxr-xr-x 3 root root 4096 8月 24 18:41 support-files
先安装libaio库文件
[root@node2 mysql]# yum install -y libaio
[root@node2 mysql]# mkdir -pv /mydata/data
mkdir: 已创立目录 "/mydata"
mkdir: 已创立目录 "/mydata/data"
[root@node2 mysql]# cd /mydata/data
[root@node2 data]# chown -R mysql.mysql /mydata/data/
[root@node2 data]# /usr/local/mysql/scripts/mysql_install_db --datadir=/mydata/data/ --basedir=/usr/local/mysql --user=mysql
[root@node2 data]# ll
总用量 1084
drwx------ 2 mysql root 4096 8月 24 18:49 mysql
-rw-rw---- 1 mysql mysql 27698 8月 24 18:49 mysql-bin.000001
-rw-rw---- 1 mysql mysql 1061358 8月 24 18:49 mysql-bin.000002
-rw-rw---- 1 mysql mysql 38 8月 24 18:49 mysql-bin.index
drwx------ 2 mysql mysql 4096 8月 24 18:49 performance_schema
drwx------ 2 mysql root 4096 8月 24 18:49 test
1
2
3
4
[root@node2 mysql]# groupadd -g 3306 mysql
[root@node2 mysql]# useradd -u 3306 -g mysql -s /sbin/nologin -M mysql
[root@node2 mysql]# id mysql
uid=3306(mysql) gid=3306(mysql) 组=3306(mysql)
  • (3).修改mysql安装目录所有者与所属组

[root@node2 mysql]# chown -R root.mysql /usr/local/mysql/*
[root@node2 mysql]# ll
总用量 200
drwxr-xr-x 2 root mysql 4096 8月 24 18:41 bin
-rw-r--r-- 1 root mysql 17987 7月 15 20:01 COPYING
drwxr-xr-x 3 root mysql 4096 8月 24 18:41 data
drwxr-xr-x 2 root mysql 4096 8月 24 18:41 docs
drwxr-xr-x 3 root mysql 4096 8月 24 18:41 include
-rw-r--r-- 1 root mysql 134493 7月 15 20:01 INSTALL-BINARY
drwxr-xr-x 3 root mysql 4096 8月 24 18:41 lib
drwxr-xr-x 4 root mysql 4096 8月 24 18:41 man
drwxr-xr-x 10 root mysql 4096 8月 24 18:41 mysql-test
-rw-r--r-- 1 root mysql 2496 7月 15 20:01 README
drwxr-xr-x 2 root mysql 4096 8月 24 18:41 scripts
drwxr-xr-x 27 root mysql 4096 8月 24 18:41 share
drwxr-xr-x 4 root mysql 4096 8月 24 18:41 sql-bench
drwxr-xr-x 3 root mysql 4096 8月 24 18:41 support-files
[root@node2 mysql]# cp support-files/mysql.server /etc/init.d/mysqld
[root@node2 mysql]# chmod +x /etc/init.d/mysqld
  • (4).为mysql提供配置文件并改动

1
2
1
2
3
4
  • (5).为mysql提供启动剧本

[root@node2 mysql]# cp support-files/my-large.cnf /etc/my.cnf
[root@node2 mysql]# vim /etc/my.cnf
[mysqld]
datadir = /mydata/data
  • (6).初始化mysql数据库

  • (7).启动并测试

  • 好了,slave的mysql也设置装备摆设完成了,下面我们来设置装备摆设主从复制.

  • 7.设置装备摆设master

  • (1).改动配置文件

  • (2).授权复制用户

  • (3).重启一下mysql服务

  • 8.设置装备摆设slave

  • (1).改动配置文件

  • (2).重启mysql服务

  • (3).衔接主服务器并复制

  • 9.主从复制测试

  • master:

  • slave:

  • 好了,到这里异步的主从复制到这里设置装备摆设完成.下面我们来说一下什么是半同步复制(或说是同步也行).

  • 七、Mysql 主从复制(半同步)

  • 1.半同步复制

  • 在说明半同步复制之前我们先来了解一下,什么是同步复制?同步复制:同步复制可以定义为数据在同一时刻被提交到一台或多台机器,通常这是通过众所周知的“两阶段提交”做到的.虽然这确实给你在多系统中坚持一致性,但也由于增加了额外的消息交换而造成性能下降.使用MyISAM或者InnoDB存储引擎的MySQL本身并不支持同步复制,然而有些技术,例如分布式复制块设备(简称DRBD),可以在下层的文件系统提供同步复制,允许第二个MySQL服务器在主服务器丢失的情况下接管(使用第二服务器的复本).了解了同步复制我们正下面来说一下,什么是半同步复制?

  • MYSQL 5.5开始,支持半自动复制.之前版本的MySQL Replication都是异步(asynchronous)的,主库在执行完一些事务后,是不会管备库的进度的.如果备库不幸落后,而更不幸的是主库此时又出现Crash(例如宕机),这时备库中的数据就是不完整的.简而言之,在主库发生故障的时候,我们无法使用备库来继续提供数据一致的服务了.Semisynchronous Replication(半同步复制)则必定程度上保证提交的事务已经传给了至少一个备库.Semi synchronous中,仅仅保证事务的已经传递到备库上,但是并不确保已经在备库上执行完成了.

  • 此外,还有一种情况会导致主备数据不一致.在某个session中,主库上提交一个事务后,会等待事务传递给至少一个备库,如果在这个等待过程中主库Crash,那么也可能备库和主库不一致,这是很致命的.如果主备网络故障或者备库挂了,主库在事务提交后等待10秒(rpl_semi_sync_master_timeout的默认值)后,就会继续.这时,主库就会变回本来的异步状态.

  • MySQL在加载并开启Semi-sync插件后,每一个事务需期待备库接收日志后才返回给客户端.如果做的是小事务,两台主机的延迟又较小,则Semi-sync可以实现在性能很小损失的情况下的零数据丢失.

  • 2.异步与半同步异同

  • 默认情况下MySQL的复制是异步的,Master上所有的更新操作写入Binlog之后并不确保所有的更新都被复制到Slave之上.异步操作虽然效率高,但是在Master/Slave出现问题的时候,存在很高数据分歧步的风险,甚至可能丢失数据.

  • MySQL5.5引入半同步复制功效的目的是为了保证在master出问题的时候,至少有一台Slave的数据是完整的.在超时的情况下也可以临时转入异步复制,保障业务的正常使用,直到一台salve追赶上之后,继续切换到半同步模式.

  • 3.具体设置装备摆设

  • 注,mysql5.5半同步插件是由谷歌提供,具体地位/usr/local/mysql/lib/plugin/下,一个是master用的semisync_master.so,一个是slave用的semisync_slave.so,下面我们就来具体配置一下.

  • master:

  • (1).安装插件

  • (2).改动配置文件

  • (3).从新启动服务

  • slave:

  • (1).安装插件

  • (2).改动配置文件

  • (3).从新启动服务

  • 4.查看一下状况

  • master:

  • slave:

  • 5.测试一下

  • master:

  • 注,大家可以看到创建一个表的插入一个数据的时间都很长,阐明半同步配置完成.

  • 6.模拟一下故障

  • slave:

  • 注,年夜家可以看到主服务器会卡1s,我们超时时间设置的为1s.

  • 7.查看一下状况

  • 好了,到这里我们就配置完成了半同步复制.希望年夜家有所收获.下面我们来简单说一下mysql复制的工具.

  • 八、Mysql 复制对象

  • 1.percona-toolkit简介

  • percona-toolkit是一组高级命令行工具的集合,用来执行各种通过手工执行非常复杂和麻烦的mysql和系统任务,这些任务包含:

  • 反省master和slave数据的一致性

  • 有效地对记载进行归档

  • 查找反复的索引

  • 对服务器信息进行汇总

  • 阐发来自日志和tcpdump的查询

  • 当系统出问题的时候收集紧张的系统信息

半同步复制的基本流程

MySQL半同步复制的实现是建立在MySQL异步复制的基础上的.MySQL支持两种略有分歧的半同步复制:AFTER_SYNCAFTER_COMMIT(受rpl_semi_sync_master_wait_wait_point控制).

开启半同步复制时,Master在返回之前会期待Slave的响应或超时.当Slave超时时,半同步复制退化成异步复制.这也是MySQL半同步复制存在的一个问题.本文不讨论Salve超时的情形(不讨论异步复制).

半同步复制AFTER_SYNC模式的根本流程

AFTER_SYNC模式是MySQL 5.7才支撑的半同步复制方式,也是MySQL5.7默认的半同步复制方式:

  1. Prepare the transaction in the storage engine(s).

  2. Write the transaction to the binlog,flush the binlog to disk.

  3. Wait for at least one slave to acknowledge the reception for the binlog events for the transaction.

  4. Commit the transaction to the storage engine(s).

半同步复制AFTER_COMMIT模式的根本流程

MySQL 5.5和5.6的半同步复制只支撑AFTER_COMMIT

  1. Prepare the transaction in the storage engine(s).

  2. Write the transaction to the binlog,flush the binlog to disk.

  3. Commit the transaction to the storage engine(s).

  4. Wait for at least one slave to acknowledge the reception for the binlog events for the transaction.

AFTER_SYNC和AFTER_COMMIT两种方式的小结

  • AFTER_SYNC: 日记复制到Slave之后,Master再commit.

  • 所有在master上commit的事务都曾经复制到slave.

  • 所有已经复制到slave的事务在master不一定commit了(好比,master将日志复制到slave之后,在commit之前宕机了)

  • AFTER_COMMIT:Master commit之后再将日记复制到Slave.

  • 所有master上commit的事务不一定复制到slave.(好比,master commit之后,还没来得及将日志复制到slave就宕机了)

  • 所有已经复制到slave的事务在master上必定commit了.

  • 很明显,AFTER_COMMIT在master宕机的环境下,无法保证数据的一致性(master commit之后,还没来得及将日志复制到slave就宕机了).本文接下来只讨论AFTER_SYNC模式.

  • MySQL5.7.3开始支持配置半同步复制期待Slave应答的个数:rpl_semi_sync_master_wait_slave_count .

AFTER_SYNC模式下的异常情况阐发

  • 非常情况1:master宕机后,主备切换.

  • master执行事务T,在将事务T的binlog刷到硬盘之前,master产生宕机.slave升级为master.master重启后,crash recovery会对事务T进行回滚.主备数据一致.

  • master执行事务T,在将事务T的binlog刷到硬盘之后,收到slave的ACK之前,master产生宕机(存在pendinglog).slave升级为master.

    2.1 slave还没有收到事务T的binlog,master重启后,crash recovery会直接提交pendinglog.主备数据纷歧致.

    2.2 slave已经收到事务T的binlog.主备数据同等.

  • 非常情况2:master宕机后,不切换主机.只需考虑非常情况1中的2.1.

master重启后,直接提交pendinglog,此时,主备数据纷歧致:

  1. slave连接上master,通过异步复制的方式得到事务T的binlog.主备数据一致.

  2. slave还没来得及复制事务T的binlog,如果master又发生宕机,磁盘损坏.主备数据纷歧致,事务T的数据丢失.

异常情况处置

从上面异常情况的简单分析我们得知,半同步复制必要处理master宕机后重启存在pendinglog(slave没有应答的binlog)的特殊情况.

  • 针对master宕机后,不进行主备切换的情形:

在crash recovery之后,master比及slave的连接和复制,直到至少有一个slave复制了所有已提交的事务的binlog.(SHOW MASTER STATUS on master and SELECT master_pos_wait() on slave).

  • 针对master宕机后,进行主备切换的情形:

旧master重启后,在crash recovery时,对pendinglog进行回滚.(人工截断master的binlog未复制的部门?)

思虑

为什么master重启之后,crash recovery的过程中,是直接commit pendinglog,而不是重试哀求slave的应答呢?

MySQL的异步复制和半同步复制都是由slave触发的,slave主动去衔接master同步binlog.

  1. 没有产生主备切换,机器重启后无法知道哪台机器是slave.

  2. 如果产生主备切换,它已经不是master了,则不会再有slave连上来.如果继续等待,则无法正常运行.

总结

MySQL半同步复制存在以下问题:

  1. 当Slave超不时,会退化成异步复制.

  2. 当Master宕机时,数据一致性无法保证,必要人工处理.

  3. 复制是串行的.

正因为MySQL在主备数据一致性存在着这些问题,影响了互联网业务7*24的高可用服务,因此各大公司纷纷祭出本身的“补丁”:腾讯的TDSQL、微信的PhxSQL、阿里的AliSQL、网易的InnoSQL.

MySQL官方曾经在MySQL5.7推出新的复制模式——MySQL Group Replication.

欢迎参与《MySQL半同步复制》讨论,分享您的想法,编程之家PHP学院为您提供专业教程。

相关文章

在正式开始之前,我们先来看下 MySQL 服务器的配置和版本号信...
> [合辑地址:MySQL全面瓦解](https://www.cnblogs.c...
物理服务机的CPU、内存、存储设备、连接数等资源有限,某个时...
1 回顾 上一节我们详细讲解了如何对数据库进行分区操作,包括...
navicat查看某个表的所有字段的详细信息 navicat设计表只能一...
文章浏览阅读4.3k次。转载请把头部出处链接和尾部二维码一起...