MySQL的异步复制和半同步复制

SHFFlorenci 8年前
   <h3>实验拓扑</h3>    <p style="text-align:center"><img src="https://simg.open-open.com/show/e7795c17a1704e39151d2dc50b1ead80.jpg"></p>    <p>MySQL主从复制</p>    <table>     <thead>      <tr>       <th>主机名</th>       <th>主机地址</th>       <th>角色</th>      </tr>     </thead>     <tbody>      <tr>       <td>node1</td>       <td>192.168.2.201</td>       <td>Master</td>      </tr>      <tr>       <td>node2</td>       <td>192.168.2.202</td>       <td>Slave</td>      </tr>      <tr>       <td>node3</td>       <td>192.168.2.203</td>       <td>Slave</td>      </tr>     </tbody>    </table>    <p>本文使用CentOS7.1,数据库:MariaDB-5.5.50<br> 注意:本文关闭了selinux,以及iptables。</p>    <p>一、异步复制:</p>    <p>相关知识点:</p>    <ul>     <li>MySQL的异步复制是MySQL自带的数据同步功能,在公司里面也是也就最为常见的。</li>     <li>Master服务器中需要开启二进制日志 binlog ,从服务器需要开启中继日志 relay-log 。</li>     <li>二进制日志 binlog 的主要功能是:记录令数据库内容产生改变的语句,如 insert 语句;二进制日志在备份还原的时候至关重要。</li>     <li>中继日志 relay-log 则是从服务器中开启,作用是从主服务器的二进制日志中复制,并在在从服务器本地执行一次,达到与主服务器内容一致的效果。</li>     <li>一般MySQL复制是放在内网中进行的,因为MySQL的同步并没有进行加密。而且相比较于在公网传输,在内网中丢包的概率较低,带宽也高。</li>    </ul>    <p>Master节点:Node1</p>    <pre>  <code class="language-sql">(1) 启动二进制日志;      [mysqld]      log_bin=mysql-bin  (2) 为当前节点设置一个全局唯一的ID号;      [mysqld]      server_id=1  (3) 授权创建仅有复制权限的用户账号;      mysql> GRANT REPLCATION SLAVE, REPLICATION CLIENT ON *.* TO 'repuser'@'192.168.2.%' IDENTIFIED BY 'repuser';    (4)查看Master端的二进制日志记录到哪里,用于决定Slave复制的起始位置      MariaDB [(none)]> show master status;      +-------------------+----------+--------------+------------------+      | File              | Position | Binlog_Do_DB | Binlog_Ignore_DB |      +-------------------+----------+--------------+------------------+      | Master-log.000001 |     245 |              |                  |      +-------------------+----------+--------------+------------------+       #Slave服务器如果是一个空的数据库而主服务器不为空:       #在同步之前可以先用Master的全量备份,恢复到Slave数据库中。       #然后再从备份那一刻记录的Position开始复制。       #假设Master和Slave都为空,上面的情况就表示Slave从二进制日志Master-log.000001的245开始复制</code></pre>    <p>从节点:Node2设置</p>    <pre>  <code class="language-sql">(1) 启动中继日志;      [mysqld]      relay_log=relay-log      relay_log_index=relay-log.index  (2) 为当前节点设置一个全局惟的ID号;      [mysqld]      server_id=2      #node3把这里改为3  (3) Slave服务器打开只读模式;      [mysqld]      read_only = 1  (4) 使用有复制权限的用户账号连接至主服务器,并启动复制线程;       #注意:上面的是在/etc/my.cnf的配置文件中添加,下面mysql>的则是在mysql服务器中运行的命令      mysql> CHANGE MASTER TO       MASTER_HOST='192.168.2.201',       MASTER_USER='repuser',       MASTER_PASSWORD='repuser',       MASTER_LOG_FILE='Master-log.000001',       MASTER_LOG_POS=245;    (5)在从服务器中开启复制线程     mysql> START SLAVE;</code></pre>    <p>查看从服务器的状态信息</p>    <pre>  <code class="language-sql">mysql> show slave status\G  *************************** 1. row ***************************                 Slave_IO_State: Waiting for master to send event                    Master_Host: 192.168.2.201                    Master_User: repuser                    Master_Port: 3306                  Connect_Retry: 60                Master_Log_File: Master-log.000003            Read_Master_Log_Pos: 1379                 Relay_Log_File: relay-log.000002                  Relay_Log_Pos: 1414          Relay_Master_Log_File: Master-log.000003               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: 1379                Relay_Log_Space: 1702                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 in set (0.00 sec)</code></pre>    <p>插入几条命令之后,从以上的状态信息中可以看得到我们的Master服务器是192.168.2.201<br> 拥有复制功能的账号是repuser,现在复制到Master-log.000003的Position 1379这个位置;<br> 上面的输出结果中,我在复制完成之后使用了flush logs手动地滚动了二进制日志,所以二进制去到000003</p>    <p>二、半同步复制</p>    <p>相关知识点:</p>    <ul>     <li>半同步复制是由谷歌研发的一种数据库主从复制方式。</li>     <li>与传统的异步复制相比,半同步复制在多个Slave节点中会选取一个节点进行半同步复制。也就是说,当Master提交一个事务的时候,在这个半同步复制的Slave端返回一个同步完成的Ack包之后,服务器才会向用户返回事务提交成功,而其他的节点则是采用传统的异步复制方式进行同步。</li>     <li>半同步是复制是基于异步复制之上进行的,也就是说配置半同步复制之前需要先配置到异步复制。</li>     <li>半同步复制可以保证在主节点发生故障的时候,总有一个节点的数据与主节点一样。这样在进行切换的时候,可以更加快速地把这个Slave节点设置成主节点来使用。 <p>Master节点:Node1</p> 由于上面已经进行了异步复制的配置,下面仅进行半同步复制的操作。<br> (1)Master安装插件并修改变量: <pre>  <code class="language-sql">mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';</code></pre> 插件的文件名字和路径一般在rpm -ql mariadb-server那里查看。<br> 这个插件的库文件是安装好之后就直接有的,只是没有默认安装。<br> (2)启用选项 <pre>  <code class="language-sql">mysql> SET GLOBAL VARIABLES rpl_semi_sync_master_enabled=1;</code></pre> </li>    </ul>    <p>Slave节点:Node2</p>    <p>(1)slave安装插件并修改变量:</p>    <pre>  <code class="language-sql">mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';  mysql> SET GLOBAL VARIABLES rpl_semi_sync_slave_enabled=1;</code></pre>    <p>这里需要注意的是,node1作为主节点使用的是master模块。node2,node3作为从节点使用slave模块</p>    <p>(2)查看半同步复制的全局变量</p>    <pre>  <code class="language-sql">mysql> SHOW GLOBAL VARIABLES LIKE '%semi%';  +------------------------------------+-------+  | 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_no_slave | ON    |  +------------------------------------+-------+</code></pre>    <p>设置rpl_semi_sync_master_enabled=1的效果<br> 第一行是ON则表示半同步复制已经开启。</p>    <p>(3)查看半同步复制的全局变量</p>    <pre>  <code class="language-sql">mysql> SHOW GLOBAL STATUS LIKE '%semi%';  +--------------------------------------------+-------+  | Variable_name                              | Value |  +--------------------------------------------+-------+  | Rpl_semi_sync_master_clients               | 1     |  | Rpl_semi_sync_master_net_avg_wait_time     | 645   |  | Rpl_semi_sync_master_net_wait_time         | 645   |  | Rpl_semi_sync_master_net_waits             | 1     |  | Rpl_semi_sync_master_no_times              | 1     |  | Rpl_semi_sync_master_no_tx                 | 5     |  | Rpl_semi_sync_master_status                | ON    |  | Rpl_semi_sync_master_timefunc_failures     | 0     |  | Rpl_semi_sync_master_tx_avg_wait_time      | 783   |  | Rpl_semi_sync_master_tx_wait_time          | 783   |  | 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     |  +--------------------------------------------+-------+</code></pre>    <p>第一行Rpl_semi_sync_master_clients显示1,表示有一台主机是半同步复制的状态。</p>    <p>最后需要说明的是,semi复制的MySQL5.7中性能有明显的改善。</p>    <p>假如真的需要使用半同步复制,建议使用5.7的版本。</p>    <p>下一篇文章,我们将会讲怎么使用MHA配合半同步复制高可用MariaDB</p>    <p> </p>    <p>来自:http://www.jianshu.com/p/d877cbe9f0f0</p>    <p> </p>