当前位置:Gxlcms > 数据库问题 > sql执行效率,半同步复制

sql执行效率,半同步复制

时间:2021-07-01 10:21:17 帮助过:8人阅读

(1)尽量选择较小的列;

(2)将where中用的比较频繁的字段建立索引;

(3)select中避免使用*;

(4)避免在索引列上使用计算、not in和<>等操作;

(5)当只需要一行数据时候使用limit1;

(6)保证单表数据不超过200w,实时分割表;

针对查询较慢的语句,可以使用explain来分析该语句具体的执行情况。

sql语句应考虑哪些安全性?

(1)少使用root账户,应该为不同的动作分配不同的账户;
(2)sql执行出错后,不能把数据库中显示的出错信息,直接展示给用户。防止泄露服务器和数据库相关信息;
(3)防止sql注入,对特殊字符进行转义、过滤或者使用预编译的sql语句绑定变量

接下来重点说下Mysql半同步复制,从MySQL5.5开始,MySQL以插件的形式支持半同步复制。先来区别下mysql几个同步模式概念:

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

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

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

技术图片

-  对于异步复制,主库将事务Binlog事件写入到Binlog文件中,此时主库只会通知一下Dump线程发送这些新的Binlog,然后主库就会继续处理提交操作,而此时不会保证这些Binlog传到任何一个从库节点上。

-  对于全同步复制,当主库提交事务之后,所有的从库节点必须收到,APPLY并且提交这些事务,然后主库线程才能继续做后续操作。这里面有一个很明显的缺点就是,主库完成一个事务的时间被拉长,性能降低。

-  对于半同步复制,是介于全同步复制和异步复制之间的一种,主库只需要等待至少一个从库节点收到并且Flush Binlog到Relay Log文件即可,主库不需要等待所有从库给主库反馈。同时,这里只是一个收到的反馈,而不是已经完全执行并且提交的反馈,这样就节省了很多时间。

                                                        Mysql半同步复制技术                                                                
一般而言,普通的replication,即MySQL的异步复制,依靠MySQL二进制日志也即binary log进行数据复制。比如两台机器,一台主机(master),另外一台是从机(slave)。
正常的复制为:事务一(t1)写入binlog buffer;dumper线程通知slave有新的事务t1;binlog buffer进行checkpoint;slave的io线程接收到t1并写入到自己的的relay log;slave的sql线程写入到本地数据库。 这时,master和slave都能看到这条新的事务,即使master挂了,slave可以提升为新的master。
异常的复制为:事务一(t1)写入binlog buffer;dumper线程通知slave有新的事务t1;binlog buffer进行checkpoint;slave因为网络不稳定,一直没有收到t1;master挂掉,slave提升为新的master,t1丢失。
很大的问题是:主机和从机事务更新的不同步,就算是没有网络或者其他系统的异常,当业务并发上来时,slave因为要顺序执行master批量事务,导致很大的延迟。

为了弥补以上几种场景的不足,MySQL从5.5开始推出了半同步复制。相比异步复制,半同步复制提高了数据完整性,因为很明确知道,在一个事务提交成功之后,这个事务就至少会存在于两个地方。即在master的dumper线程通知slave后,增加了一个ack(消息确认),即是否成功收到t1的标志码,也就是dumper线程除了发送t1到slave,还承担了接收slave的ack工作。如果出现异常,没有收到ack,那么将自动降级为普通的复制,直到异常修复后又会自动变为半同步复制。 

半同步复制具体特性
-  从库会在连接到主库时告诉主库,它是不是配置了半同步。
-  如果半同步复制在主库端是开启了的,并且至少有一个半同步复制的从库节点,那么此时主库的事务线程在提交时会被阻塞并等待,结果有两种可能,要么至少一个从库节点通知它已经收到了所有这个事务的Binlog事件,要么一直等待直到超过配置的某一个时间点为止,而此时,半同步复制将自动关闭,转换为异步复制。
-  从库节点只有在接收到某一个事务的所有Binlog,将其写入并Flush到Relay Log文件之后,才会通知对应主库上面的等待线程。
-  如果在等待过程中,等待时间已经超过了配置的超时时间,没有任何一个从节点通知当前事务,那么此时主库会自动转换为异步复制,当至少一个半同步从节点赶上来时,主库便会自动转换为半同步方式的复制。
-  半同步复制必须是在主库和从库两端都开启时才行,如果在主库上没打开,或者在主库上开启了而在从库上没有开启,主库都会使用异步方式复制。

下面来看看半同步复制的原理图:

技术图片

半同步复制的意思表示MASTER 只需要接收到其中一台SLAVE的返回信息,就会commit;否则需等待直至达到超时时间然后切换成异步再提交。这个做可以使主从库的数据的延迟较小,可以在损失很小的性能的前提下提高数据的安全性。

主库产生binlog到主库的binlog file,传到从库中继日志,然后从库应用;也就是说传输是异步的,应用也是异步的。半同步复制指的是传输同步,应用还是异步的!
好处:保证数据不丢失(本机和远端都有binlog)
坏处:不能保证应用的同步。

mysql半同步复制模式的流程图

技术图片

即主库忽然崩了时,从库虽然说有延迟,但是延迟过后,可以把从库提升为主库继续服务,事后恢复到主库即可

mysql异步复制模式的流程图

技术图片

半同步复制的潜在问题
客户端事务在存储引擎层提交后,在得到从库确认的过程中,主库宕机了,此时,可能的情况有两种
-  事务还没发送到从库上
此时,客户端会收到事务提交失败的信息,客户端会重新提交该事务到新的主上,当宕机的主库重新启动后,以从库的身份重新加入到该主从结构中,会发现,该事务在从库中被提交了两次,一次是之前作为主的时候,一次是被新主同步过来的。
-  事务已经发送到从库上
此时,从库已经收到并应用了该事务,但是客户端仍然会收到事务提交失败的信息,重新提交该事务到新的主上。

无数据丢失的半同步复制
针对上述潜在问题,MySQL 5.7引入了一种新的半同步方案:Loss-Less半同步复制。针对上面这个图,"Waiting Slave dump"被调整到"Storage Commit"之前。当然,之前的半同步方案同样支持,MySQL 5.7.2引入了一个新的参数进行控制: rpl_semi_sync_master_wait_point, 这个参数有两种取值:1) AFTER_SYNC , 这个是新的半同步方案,Waiting Slave dump在Storage Commit之前。2) AFTER_COMMIT, 这个是老的半同步方案。

来看下面半同步复制原理图,分析下半同步复制潜在问题

技术图片

master将每个事务写入binlog(sync_binlog=1),传递到slave刷新到磁盘(sync_relay=1),同时主库提交事务(commit)。master等待slave反馈收到relay log,只有收到ACK后master才将commit OK结果反馈给客户端。

在MySQL 5.5-5.6使用after_commit的模式下,客户端事务在存储引擎层提交后,在得到从库确认的过程中,主库宕机了。此时,即主库在等待Slave ACK的时候,虽然没有返回当前客户端,但事务已经提交,其他客户端会读取到已提交事务。如果Slave端还没有读到该事务的events,同时主库发生了crash,然后切换到备库。那么之前读到的事务就不见了,出现了幻读。

技术图片

如果主库永远启动不了,那么实际上在主库已经成功提交的事务,在从库上是找不到的,也就是数据丢失了,这是MySQL不愿意看到的。所以在MySQL 5.7版本中增加了after_sync(无损复制)参数,并将其设置为默认半同步方式,解决了数据丢失的问题。

半同步复制的安装部署条件
要想使用半同步复制,必须满足以下几个条件:
1)MySQL 5.5及以上版本
2)变量have_dynamic_loading为YES (查看命令:show variables like "have_dynamic_loading";)
3)主从复制已经存在 (即提前部署mysql主从复制环境,主从同步要配置基于整个数据库的,不要配置基于某个库的同步,即同步时不要过滤库)

-  首先加载插件
因用户需执行INSTALL PLUGIN, SET GLOBAL, STOP SLAVE和START SLAVE操作,所以用户需有SUPER权限。

半同步复制是一个功能模块,库要能支持动态加载才能实现半同步复制! (安装的模块存放路径为/usr/local/mysql/lib/plugin)
主数据库执行:

1 2 3 4 5 6 mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME ‘semisync_master.so‘;   [要保证/usr/local/mysql/lib/plugin/目录下有semisync_master.so文件 (默认编译安装后就有)] --------------------------------------------------------------------------------------- 如果要卸载(前提是要关闭半同步复制功能),就执行 mysql> UNINSTALL PLUGIN rpl_semi_sync_master;

从数据库执行:

1 2 3 4 5 6 mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME ‘semisync_slave.so‘;   [要保证/usr/local/mysql/lib/plugin/目录下有semisync_slave.so文件 (默认编译安装后就有)] --------------------------------------------------------------------------------------- 如果要卸载(前提是要关闭半同步复制功能),就执行 mysql> UNINSTALL PLUGIN rpl_semi_sync_slave;

-  查看插件是否加载成功的两种方式:
1) 方式一

1 2 3 mysql> show plugins; ........ | rpl_semi_sync_master       | ACTIVE   | REPLICATION        | semisync_master.so | GPL     |

2) 方式二

1 2 3 4 5 6 7 mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS  WHERE PLUGIN_NAME LIKE ‘%semi%‘; +----------------------+---------------+ | PLUGIN_NAME          | PLUGIN_STATUS | +----------------------+---------------+ | rpl_semi_sync_master | ACTIVE        | +----------------------+---------------+ 1 row in set (0.00 sec)

-  启动半同步复制
在安装完插件后,半同步复制默认是关闭的,这时需设置参数来开启半同步
主数据库执行:

1 mysql> SET GLOBAL rpl_semi_sync_master_enabled = 1;

从数据库执行:

1 mysql> SET GLOBAL rpl_semi_sync_slave_enabled = 1;

以上的启动方式是在登录mysql后的命令行操作,也可写在my.cnf配置文件中(推荐这种启动方式)。
主数据库的my.cnf配置文件中添加:

1 2 plugin-load=rpl_semi_sync_master=semisync_master.so rpl_semi_sync_master_enabled=1

从数据库的my.cnf配置文件中添加:

1 2 plugin-load=rpl_semi_sync_slave=semisync_slave.so rpl_semi_sync_slave_enabled=1

在个别高可用架构下,master和slave需同时启动,以便在切换后能继续使用半同步复制!即在主从数据库的my.cnf配置文件中都要添加:

1 2 3 plugin-load = "rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so" rpl-semi-sync-master-enabled = 1 rpl-semi-sync-slave-enabled = 1

-  重启从数据库上的IO线程

1 2 mysql> STOP SLAVE IO_THREAD; mysql> START SLAVE IO_THREAD;

特别注意: 如果没有重启,则默认的还是异步复制模式!,重启后,slave会在master上注册为半同步复制的slave角色。这时候,主的error.log中会打印如下信息:

1 2 3 4 2019-01-05T10:03:40.104327Z 5 [Note] While initializing dump thread for slave with UUID <ce9aaf22-5af6-11e6-850b-000c2988bad2>, found a zombie dump thread with the same UUID. Master is killing the zombie dump thread(4). 2019-01-05T10:03:40.111175Z 4 [Note] Stop asynchronous binlog_dump to slave (server_id: 2) 2019-01-05T10:03:40.119037Z 5 [Note] Start binlog_dump to master_thread_id(5) slave_server(2), pos(mysql-bin.000003, 621) 2019-01-05T10:03:40.119099Z 5 [Note] Start semi-sync binlog_dump to slave (server_id: 2), pos(mysql-bin.000003, 621)

-  查看半同步是否在运行
主数据库:

1 2 3 4 5 6 7 mysql> show status like ‘Rpl_semi_sync_master_status‘; +-----------------------------+-------+ | Variable_name               | Value | +-----------------------------+-------+ | Rpl_semi_sync_master_status | ON    | +-----------------------------+-------+ 1 row in set (0.00 sec)

从数据库:

1 2 3 4 5 6 7 mysql> show status like ‘Rpl_semi_sync_slave_status‘; +----------------------------+-------+ | Variable_name              | Value | +----------------------------+-------+ | Rpl_semi_sync_slave_status | ON    | +----------------------------+-------+ 1 row in set (0.20 sec)

这两个变量常用来监控主从是否运行在半同步复制模式下。至此,MySQL半同步复制环境就部署完成了!

                                                                                                                                                                      

需要注意下,其实Mysql半同步复制并不是严格意义上的半同步复制。当半同步复制发生超时时(由rpl_semi_sync_master_timeout参数控制,单位是毫秒,默认为10000,即10s),会暂时关闭半同步复制,转而使用异步复制。当master dump线程发送完一个事务的所有事件之后,如果在rpl_semi_sync_master_timeout内,收到了从库的响应,则主从又重新恢复为半同步复制。[一旦有一次超时自动降级为异步].

1 2 3 4 5 6 7 mysql> show variables like "rpl_semi_sync_master_timeout"; +------------------------------+-------+ | Variable_name                | Value | +------------------------------+-------+ | rpl_semi_sync_master_timeout | 10000 | +------------------------------+-------+ 1 row in set (0.01 sec)

 接下来可以测试下:

1) 主数据库 (从数据库在执行"stop slave"之前)

1 2 3 4 5 6 7 8 mysql> create database bobo; Query OK, 1 row affected (0.05 sec)   mysql> create table bobo.ceshi(id int); Query OK, 0 row affected (0.28 sec)   mysql> insert into bobo.ceshi values(1); Query OK, 1 row affected (0.09 sec)

2) 从数据执行"stop slave"

1 mysql> stop slave;

再观察主数据库

1 2 3 4 5 6 7 8 9 10 mysql> insert into bobo.ceshi values(2); Query OK, 1 row affected (10.01 sec)   mysql> show status like ‘Rpl_semi_sync_master_status‘; +-----------------------------+-------+ | Variable_name               | Value | +-----------------------------+-------+ | Rpl_semi_sync_master_status | OFF   | +-----------------------------+-------+ 1 row in set (0.00 sec)

查看从数据库

1 2 3 4 5 6 7 mysql> show status like ‘Rpl_semi_sync_slave_status‘; +-----------------------------+-------+ | Variable_name               | Value | +-----------------------------+-------+ | Rpl_semi_sync_slave_status  | OFF   | +-----------------------------+-------+ 1 row in set (0.01 sec)

3) 接着再在从数据库执行"start slave"

1 mysql> start slave;

再观察主数据

1 2 3 4 5 6 7 8 9 10 mysql> insert into bobo.ceshi values(3); Query OK, 1 row affected (0.00 sec)   mysql> show status like ‘Rpl_semi_sync_master_status‘; +-----------------------------+-------+ | Variable_name               | Value | +-----------------------------+-------+ | Rpl_semi_sync_master_status | ON    | +-----------------------------+-------+ 1 row in set (0.00 sec)

查看从数据库

1 2 3 4 5 6 7 mysql> show status like ‘Rpl_semi_sync_slave_status‘; +-----------------------------+-------+ | Variable_name               | Value | +-----------------------------+-------+ | Rpl_semi_sync_slave_status  | ON   | +-----------------------------+-------+ 1 row in set (0.00 sec)

以上验证分为三个阶段:
1) 在Slave执行stop slave之前,主的insert操作很快就能返回。
2) 在Slave执行stop slave后,主的insert操作需要10.01s才返回,而这与rpl_semi_sync_master_timeout参数的时间相吻合。这时,查看两个状态的值,均为“OFF”了。同时,主的error.log中打印如下信息:

1 2 2019-01-05T11:51:49.855452Z 6 [Warning] Timeout waiting for reply of binlog (file: mysql-bin.000003, pos: 1447), semi-sync up to file mysql-bin.000003, position 1196. 2019-01-05T11:51:49.855742Z 6 [Note] Semi-sync replication switched OFF.

3) 在Slave执行start slave后,主的insert操作很快就能返回,此时,两个状态的值也变为“ON”了。同时,主的error.log中会打印如下信息:

1 2 3 2019-01-05T11:52:40.477098Z 7 [Note] Start binlog_dump to master_thread_id(7) slave_server(2), pos(mysql-bin.000003, 1196) 2019-01-05T11:52:40.477168Z 7 [Note] Start semi-sync binlog_dump to slave (server_id: 2), pos(mysql-bin.000003, 1196) 2019-01-05T11:52:40.523475Z 0 [Note] Semi-sync replication switched ON at (mysql-bin.000003, 1447)

                                                 其他变量说明                                                  

环境变量(show variables like ‘%Rpl%‘;)

1 2 3 4 5 6 7 8 9 10 11 12 13 mysql> show variables like ‘%Rpl%‘; +-------------------------------------------+------------+ | Variable_name                             | Value      | +-------------------------------------------+------------+ | rpl_semi_sync_master_enabled              | ON         | | rpl_semi_sync_master_timeout              | 10000      | | rpl_semi_sync_master_trace_level          | 32         | | rpl_semi_sync_master_wait_for_slave_count | 1          | | rpl_semi_sync_master_wait_no_slave        | ON         | | rpl_semi_sync_master_wait_point           | AFTER_SYNC | | rpl_stop_slave_timeout                    | 31536000   | +-------------------------------------------+------------+ 7 rows in set (0.30 sec)

rpl_semi_sync_master_wait_for_slave_count
MySQL 5.7.3引入的,该变量设置主需要等待多少个slave应答,才能返回给客户端,默认为1。

rpl_semi_sync_master_wait_no_slave
ON
默认值,当状态变量Rpl_semi_sync_master_clients中的值小于rpl_semi_sync_master_wait_for_slave_count时,Rpl_semi_sync_master_status依旧显示为ON。

OFF
当状态变量Rpl_semi_sync_master_clients中的值于rpl_semi_sync_master_wait_for_slave_count时,Rpl_semi_sync_master_status立即显示为OFF,即异步复制。

简单来说,如果mysql架构是1主2从,2个从都采用了半同步复制,且设置的是rpl_semi_sync_master_wait_for_slave_count=2,如果其中一个挂掉了,对于rpl_semi_sync_master_wait_no_slave设置为ON的情况,此时显示的仍然是半同步复制,如果rpl_semi_sync_master_wait_no_slave设置为OFF,则会立刻变成异步复制。

状态变量(show status like ‘%Rpl_semi%‘;)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 mysql> show 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             | 6     | | Rpl_semi_sync_master_no_times              | 1     | | Rpl_semi_sync_master_no_tx                 | 1     | | Rpl_semi_sync_master_status                | ON    | | Rpl_semi_sync_master_timefunc_failures     | 0     | | Rpl_semi_sync_master_tx_avg_wait_time      | 1120  | | Rpl_semi_sync_master_tx_wait_time          | 4483  | | Rpl_semi_sync_master_tx_waits              | 4     | | Rpl_semi_sync_master_wait_pos_backtraverse | 0     | | Rpl_semi_sync_master_wait_sessions         | 0     | | Rpl_semi_sync_master_yes_tx                | 4     | +--------------------------------------------+-------+ 14 rows in set (0.00 sec)

Rpl_semi_sync_master_clients
当前半同步复制从的个数,如果是一主多从的架构,并不包含异步复制从的个数。

Rpl_semi_sync_master_no_tx
The number of commits that were not acknowledged successfully by a slave.
具体到上面的测试中,指的是insert into bobo.ceshi values(2)这个事务。

Rpl_semi_sync_master_yes_tx
The number of commits that were acknowledged successfully by a slave.
具体到上面的测试中,指的是以下四个事务:
mysql> create database bobo;
mysql> create table bobo.ceshi(id int);
mysql> insert into bobo.ceshi values(1);
mysql> insert into bobo.ceshi values(3); 

简单总结:
1) 在一主多从的架构中,如果要开启半同步复制,并不要求所有的从都是半同步复制。
2) MySQL 5.7极大的提升了半同步复制的性能。
    5.6版本的半同步复制,dump thread 承担了两份不同且又十分频繁的任务:传送binlog 给slave ,还需要等待slave反馈信息,而且这两个任务是串行的,dump thread 必须等待 slave 返回之后才会传送下一个 events 事务。dump thread 已然成为整个半同步提高性能的瓶颈。在高并发业务场景下,这样的机制会影响数据库整体的TPS 。
    5.7版本的半同步复制中,独立出一个 ack collector thread ,专门用于接收slave 的反馈信息。这样master 上有两个线程独立工作,可以同时发送binlog 到slave ,和接收slave的反馈。

                                                                           Mysql半同步模式配置示例                                                                           

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 mysql主数据库: 172.16.60.205 mysql从数据库: 172.16.60.206 mysql5.6.39 安装部署,参考:https://www.cnblogs.com/kevingrace/p/6109679.html   主数据库172.16.60.205配置: [root@mysql-master ~]# cat /usr/local/mysql/my.cnf ....... server-id=1 log-bin=mysql-bin sync_binlog = 1 binlog_checksum = none binlog_format = mixed   从数据库172.16.60.206配置: [root@mysql-slave ~]# cat /usr/local/mysql/my.cnf ......... server-id=2 log-bin=mysql-bin slave-skip-errors = all   然后从库同步操作,不需要跟master_log_file 和 master_log_pos=120 mysql> change master to master_host = ‘172.16.60.205‘, master_port = 3306, master_user =‘slave‘, master_password =‘slave@123‘;   其他的配置,参考https://www.cnblogs.com/kevingrace/p/6256603.html 即主从同步配置不过滤库,是基于整个数据库的同步。其他的操作和这个文档中记录的差不多   ======================================================== 主数据库 [root@mysql-master ~]# mysql -p123456 ...... mysql> use kevin; mysql> show tables; +-----------------+ | Tables_in_kevin | +-----------------+ | haha            | +-----------------+ 1 row in set (0.00 sec)     mysql> select * from haha; +----+--------+ id | name   | +----+--------+ |  2 | anxun  | |  3 | huoqiu | |  4 | xihuju | +----+--------+ 3 rows in set (0.00 sec)     从数据库: [root@mysql-slave ~]# mysql -p123456 .......... .......... mysql> show slave status \G; *************************** 1. row ***************************                Slave_IO_State: Waiting for master to send event                   Master_Host: 172.16.60.205                   Master_User: slave                   Master_Port: 3306                 Connect_Retry: 60 ......... .........              Slave_IO_Running: Yes             Slave_SQL_Running: Yes     mysql> select * from kevin.haha; +----+--------+ id | name   | +----+--------+ |  2 | anxun  | |  3 | huoqiu | |  4 | xihuju | +----+--------+ 3 rows in set (0.00 sec)     主数据库插入数据 mysql> insert into haha values(1,"linux"); Query OK, 1 row affected (0.03 sec) mysql> insert into haha values(11,"linux-ops"); Query OK, 1 row affected (0.04 sec)     从数据库查看 mysql> select * from kevin.haha; +----+-----------+ id | name      | +----+-----------+ |  1 | linux     | |  2 | anxun     | |  3 | huoqiu    | |  4 | xihuju    | | 11 | linux-ops | +----+-----------+ 5 rows in set (0.00 sec)     mysql> select version(); +------------+ | version()  | +------------+ | 5.6.39-log | +------------+ 1 row in set (0.00 sec)     mysql> show variables like "have_dynamic_loading"; +----------------------+-------+ | Variable_name        | Value | +----------------------+-------+ | have_dynamic_loading | YES   | +----------------------+-------+ 1 row in set (0.00 sec)     从上面可知,已满足mysql半同步复制功能部署的条件: 1)MySQL 5.5及以上版本! 2)变量have_dynamic_loading为YES 3)主从复制已经存在!     =================================================== 接下来进行mysql半同步复制环境部署:     1)加载mysql半同步复制的插件 主数据库执行: mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME ‘semisync_master.so‘; Query OK, 0 row affected (0.04 sec)     从数据库执行: mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME ‘semisync_slave.so‘; Query OK, 0 row affected (0.04 sec)     2)查看插件是否加载成功的两种方式: 主数据库执行: mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS  WHERE PLUGIN_NAME LIKE ‘%semi%‘; +----------------------+---------------+ | PLUGIN_NAME          | PLUGIN_STATUS | +----------------------+---------------+ | rpl_semi_sync_master | ACTIVE        | +----------------------+---------------+ 1 row in set (0.00 sec)     从数据库执行: mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS  WHERE PLUGIN_NAME LIKE ‘%semi%‘; +----------------------+---------------+ | PLUGIN_NAME          | PLUGIN_STATUS | +----------------------+---------------+ | rpl_semi_sync_slave  | ACTIVE        | +----------------------+---------------+ 2 rows in set (0.01 sec)     3) 启动半同步复制 主数据库执行: mysql> SET GLOBAL rpl_semi_sync_master_enabled = 1; Query OK, 0 rows affected (0.00 sec)     从数据库执行: mysql> SET GLOBAL rpl_semi_sync_slave_enabled = 1; Query OK, 0 rows affected (0.00 sec)     ---------------------------------------------------------------------------------------------------------------------------------------------- 温馨提示: 除了上面的设置方法以外, 还可以以下面方式启动半同步复制,即在my.cnf文件中添加启动配置(推荐这种方式): 主数据库 [root@mysql-master ~]# vim /usr/local/mysql/my.cnf      #在[mysqld]区域添加下面内容 ........ plugin-load=rpl_semi_sync_master=semisync_master.so rpl_semi_sync_master_enabled=ON         #或者设置为"1",即开启半同步复制功能 rpl-semi-sync-master-timeout=1000       #超时时间为1000ms,即1s     [root@mysql-master ~]# /etc/init.d/mysqld restart     主数据库 [root@mysql-slave ~]# vim /usr/local/mysql/my.cnf ........ plugin-load=rpl_semi_sync_slave=semisync_slave.so rpl_semi_sync_slave_enabled=ON     [root@mysql-slave ~]# /etc/init.d/mysqld restart ----------------------------------------------------------------------------------------------------------------------------------------------     4)查看半同步是否在运行 主数据库执行: mysql> show status like ‘Rpl_semi_sync_master_status‘; +-----------------------------+-------+ | Variable_name               | Value | +-----------------------------+-------+ | Rpl_semi_sync_master_status | ON    | +-----------------------------+-------+ 1 row in set (0.00 sec)     从数据库执行(此时可能还是OFF状态,需要在下一步重启IO线程后,从库半同步状态才会为ON): mysql> show status like ‘Rpl_semi_sync_slave_status‘; +----------------------------+-------+ | Variable_name              | Value | +----------------------------+-------+ | Rpl_semi_sync_slave_status | ON    | +----------------------------+-------+ 1 row in set (0.00 sec)    5)重启从数据库上的IO线程 mysql> STOP SLAVE IO_THREAD; Query OK, 0 rows affected (0.04 sec)     mysql> START SLAVE IO_THREAD; Query OK, 0 rows affected (0.00 sec)     重启从数据的IO线程之后,  slave会在master上注册为半同步复制的slave角色 查看主数据库上的error日志,就会发现下面信息: [root@mysql-master ~]# tail -f /data/mysql/data/mysql-error.log 2019-01-06 23:23:34 10436 [Note] Semi-sync replication initialized for transactions. 2019-01-06 23:23:34 10436 [Note] Semi-sync replication enabled on the master. 2019-01-06 23:27:28 10436 [Note] Stop asynchronous binlog_dump to slave (server_id: 2) 2019-01-06 23:27:28 10436 [Note] Start semi-sync binlog_dump to slave (server_id: 2), pos(mysql-bin.000004, 2944) 2019-01-06 23:32:03 10436 [Note] Stop semi-sync binlog_dump to slave (server_id: 2) 2019-01-06 23:32:03 10436 [Note] Start semi-sync binlog_dump to slave (server_id: 2), pos(mysql-bin.000004, 3357)     如上操作,就已经部署了mysql的半同步复制环境     现在往主数据库插入新数据 mysql> insert into kevin.haha values(5,"grace"); Query OK, 1 row affected (0.13 sec)     mysql> insert into kevin.haha values(6,"huihui"); Query OK, 1 row affected (0.11 sec)     到从数据库上查看,正常复制过来了     mysql> show slave status \G; ......... .........              Slave_IO_Running: Yes             Slave_SQL_Running: Yes     mysql> select * from kevin.haha; +----+-----------+ id | name      | +----+-----------+ |  1 | linux     | |  2 | anxun     | |  3 | huoqiu    | |  4 | xihuju    | |  5 | grace     | |  6 | huihui    | | 11 | linux-ops | +----+-----------+ 7 rows in set (0.00 sec)     查看主数据库 mysql> show status like ‘%Rpl_semi%‘; +--------------------------------------------+-------+ | Variable_name                              | Value | +--------------------------------------------+-------+ | Rpl_semi_sync_master_clients               | 1     | | Rpl_semi_sync_master_net_avg_wait_time     | 475   |               #网络等待的平均时间 | Rpl_semi_sync_master_net_wait_time         | 1427  |               #网络等待时间    | Rpl_semi_sync_master_net_waits             | 3     | | Rpl_semi_sync_master_no_times              | 0     | | Rpl_semi_sync_master_no_tx           

人气教程排行