一、mysql的主从复制

复制过程需要至少两个mysql服务节点,mysql的主从复制框架一般都为一主多从,从多机房汇总到数据中心的模式,而复制过程只能从主服务器到从服务器实现。

复制过程中,主服务器负责读/写操作,而从服务器只负责读操作

二、主从复制的功能

1、实现数据冗余、异地灾备恢复、备份

2、实现数据的读/写分离

3、实现数据库服务的负载均衡

4、实现高可用与故障切换

5、实现MySQL的升级测试

三、主从复制过程中注意的事项

1、不要混合shi用不同的存储引擎

2、主从服务器的server-id 要保持不同

3、尽力避免修改从服务器的数据库

4、尽可能的使用基于行或基于混合模式的复制,避免使用基于语句的复制

5、主服务器要启动二进制日志,而从节点则是开启中继日志,而且要确保从服务器的复制线程时刻开启着

6、注意因为磁盘及内存的大小不足而导致的复制崩溃

四、主从复制的具体实现过程

mysql主从复制拓扑图mysql的主从复制与半同步复制(一)_第1张图片

1、准备两个安装过mysql服务的节点xz:172.16.200.5,node2:172.16.200.7,修改主机名并同步时间;

[root@xz ~]# hostname master
[root@master ~]# crontab -e
*/1 * * * * /usr/sbin/ntpdate 172.16.0.1 &> /dev/null
[root@node2 ~]# hostname slave
[root@slave ~]# crontab -e
*/1 * * * * /usr/sbin/ntpdate 172.16.0.1 &> /dev/null

2、在主节点上创建有复制权限的用户,于从节点上使用授权用户连接测试;


[root@master ~]# mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.5.33-log MySQL Community Server (GPL)
。。。。。
mysql> grant replication slave,replication client on *.* to 'zly'@'172.16.200.7' identified by 'mypass';
Query OK, 0 rows affected (0.35 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.09 sec)
mysql> show grants for 'zly'@'172.16.200.7';
+-----------------------------------------------------------------------------------------------------------------------------------------------+
| Grants for [email protected]                                                                                                                   |
+-----------------------------------------------------------------------------------------------------------------------------------------------+
| GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'zly'@'172.16.200.7' IDENTIFIED BY PASSWORD '*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4' |
+-----------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.03 sec)
...........
[root@slave ~]# mysql -uzly -pmypass -h 172.16.200.5
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 4
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>

3、修改主从两个节点的配置文件,并重新启动mysql服务;

[root@master ~]# vim /etc/my.cnf
log-bin=mysql-bin
log_bin_index = mysql_bin.index
binlog_format=mixed
server-id       = 5
[root@master ~]# killall mysqld
[root@master ~]# ps aux | grep mysqld
root      7700  0.0  0.1 103244   832 pts/3    S+   09:27   0:00 grep mysqld
[root@master ~]# service mysqld restart
MySQL server PID file could not be found!                  [FAILED]
Starting MySQL...                                          [  OK  ]
[root@master ~]# service mysqld restart
Shutting down MySQL.                                       [  OK  ]
Starting MySQL..                                           [  OK  ]
...............
[root@slave ~]# vim /etc/my.cnf
#log-bin=mysql-bin
# binary logging format - mixed recommended
#binlog_format=mixed
skip_slave_start = 1
read_only = 1
relay_log = relay_log
relay_log_index = relay_log.index
# required unique id between 1 and 2^32 - 1
# defaults to 1 if master-host is not set
# but will not function as a master if omitted
server-id       = 7
[root@slave ~]# killall mysqld
[root@slave ~]# ps aux | grep mysqld
root      8796  0.0  0.1 103244   832 pts/4    S+   23:45   0:00 grep mysqld
[root@slave ~]# service mysqld restart
MySQL server PID file could not be found!                  [FAILED]
Starting MySQL..                                           [  OK  ]
[root@slave ~]# service mysqld restart
Shutting down MySQL.                                       [  OK  ]
Starting MySQL..                                           [  OK  ]

4、查看主节点的二进制日志及其事件位置;

mysql> show master status;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000011 |      107 |              |                  |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)

5、与从节点上复制主节点上的数据;

[root@slave ~]# mysql
mysql> help change master to
Name: 'CHANGE MASTER TO'
Description:
Syntax:
CHANGE MASTER TO option [, option] ...
option:
    MASTER_BIND = 'interface_name'
  | MASTER_HOST = 'host_name'
  | MASTER_USER = 'user_name'
  | MASTER_PASSWORD = 'password'
  | MASTER_PORT = port_num
  | MASTER_CONNECT_RETRY = interval
  | MASTER_HEARTBEAT_PERIOD = interval
  | MASTER_LOG_FILE = 'master_log_name'
  | MASTER_LOG_POS = master_log_pos
  | RELAY_LOG_FILE = 'relay_log_name'
  | RELAY_LOG_POS = relay_log_pos
  | MASTER_SSL = {0|1}
  | MASTER_SSL_CA = 'ca_file_name'
  | MASTER_SSL_CAPATH = 'ca_directory_name'
  | MASTER_SSL_CERT = 'cert_file_name'
  | MASTER_SSL_KEY = 'key_file_name'
  | MASTER_SSL_CIPHER = 'cipher_list'
  | MASTER_SSL_VERIFY_SERVER_CERT = {0|1}
  | IGNORE_SERVER_IDS = (server_id_list)
server_id_list:
    [server_id [, server_id] ... ]
........................................
mysql> change master to
    -> master_host='172.16.200.5',master_user='zly',master_password='mypass
',master_port=3306,master_log_file='mysql-bin.000011',master_log_pos=107;
Query OK, 0 rows affected (0.07 sec)

6、启动从服务器复制线程、查看状态,并查看启动的线程;

mysql> start slave;
Query OK, 0 rows affected (0.01 sec)
mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 172.16.200.5
                  Master_User: zly
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000011
          Read_Master_Log_Pos: 107
               Relay_Log_File: relay_log.000002
                Relay_Log_Pos: 253
        Relay_Master_Log_File: mysql-bin.000011
             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: 403
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
.................................
mysql> show processlist\G
*************************** 1. row ***************************
     Id: 1
   User: root
   Host: localhost
     db: NULL
Command: Query
   Time: 0
  State: NULL
   Info: show processlist
*************************** 2. row ***************************
     Id: 2
   User: system user
   Host:
     db: NULL
Command: Connect
   Time: 276
  State: Waiting for master to send event
   Info: NULL
*************************** 3. row ***************************
     Id: 3
   User: system user
   Host:
     db: NULL
Command: Connect
   Time: 275
  State: Slave has read all relay log; waiting for the slave I/O thread to update it
   Info: NULL
3 rows in set (0.00 sec)

7、在主节点上创建数据库查看从节点是否已经复制;

[root@master ~]# mysql -e "create database classdb;"
[root@master ~]# mysql -e "show databases;"
+--------------------+
| Database           |
+--------------------+
| information_schema |
| classdb            |
| mysql              |
| performance_schema |
| testdb             |
+--------------------+
[root@slave ~]# mysql -e "show databases;"
+--------------------+
| Database           |
+--------------------+
| information_schema |
| classdb            |
| mysql              |
| performance_schema |
+--------------------+

8、与主从节点查看已经更新的状态及二进制日志位置

[root@master ~]# mysql -e "show master status;"
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000011 |      453 |              |                  |
+------------------+----------+--------------+------------------+
[root@slave ~]# mysql -e "show slave status\G"
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 172.16.200.5
                  Master_User: zly
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000011
          Read_Master_Log_Pos: 453
               Relay_Log_File: relay_log.000002
                Relay_Log_Pos: 599
        Relay_Master_Log_File: mysql-bin.000011
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

至此mysql的主从复制已经完成

五、mysql的半同步复制的具体实现

半同步复制:主服务器只要收到从服务器中的一台的返回信息,就会提交,否则需等待直至达到超时时间然后切换成异步再提交。可以使主从服务器的数据库数据的延迟较小,可以在损失很小的性能的前提下提高数据的安全性。

要进行半同步复制,只需要在主从服务器上安装上半同步复制的插件,并开启半同步复制功能,便可以进行主从复制了。

1、查看主从节点上的半同步插件,并安装插件;

[root@master ~]# cd /usr/local/mysql/lib/plugin/
[root@master plugin]# ls
adt_null.so          debug                 qa_auth_server.so
auth.so              libdaemon_example.so  semisync_master.so
auth_socket.so       mypluglib.so          semisync_slave.so
auth_test_plugin.so  qa_auth_client.so
daemon_example.ini   qa_auth_interface.so
....................
[root@slave ~]# cd /usr/local/mysql/lib/plugin/
[root@slave plugin]# ls
adt_null.so          debug                 qa_auth_server.so
auth.so              libdaemon_example.so  semisync_master.so
auth_socket.so       mypluglib.so          semisync_slave.so
auth_test_plugin.so  qa_auth_client.so
daemon_example.ini   qa_auth_interface.so
......................
[root@master plugin]# mysql
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
Query OK, 0 rows affected (0.03 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)          
..................................
[root@slave plugin]# mysql
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
Query OK, 0 rows affected (0.04 sec)
mysql> set global rpl_semi_sync_slave_enabled = 1 ;
Query OK, 0 rows affected (0.01 sec)
mysql> stop slave io_thread;
Query OK, 0 rows affected (0.01 sec)
mysql> start slave io_thread;
Query OK, 0 rows affected (0.01 sec)

2、查看半同步开启的状态,并查看从节点的线程启动状态;

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> show global variables like '%rpl%';
+------------------------------------+-------+
| Variable_name                      | Value |
+------------------------------------+-------+
| rpl_recovery_rank                  | 0     |
| rpl_semi_sync_master_enabled       | ON    |
| rpl_semi_sync_master_timeout       | 1000  |
| rpl_semi_sync_master_trace_level   | 32    |
| rpl_semi_sync_master_wait_no_slave | ON    |
+------------------------------------+-------+
5 rows in set (0.00 sec)
...............
mysql> show global status like 'rpl_semi%';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON    |
+----------------------------+-------+
1 row in set (0.00 sec)
mysql> show global variables like '%rpl%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| rpl_recovery_rank               | 0     |
| rpl_semi_sync_slave_enabled     | ON    |
| rpl_semi_sync_slave_trace_level | 32    |
+---------------------------------+-------+
3 rows in set (0.00 sec)
................
[root@slave ~]# mysql -e 'show slave status\G'
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 172.16.200.5
                  Master_User: zly
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000011
          Read_Master_Log_Pos: 453
               Relay_Log_File: relay_log.000003
                Relay_Log_Pos: 253
        Relay_Master_Log_File: mysql-bin.000011
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

3、主从双方节点都存在新建的class数据库,于主服务器上删除该数据库,然后查看从服务器是否也同步删除了;

[root@master ~]# mysql -e 'show databases;'
+--------------------+
| Database           |
+--------------------+
| information_schema |
| classdb            |
| mysql              |
| performance_schema |
| testdb             |
+--------------------+
[root@slave ~]# mysql -e 'show databases;'
+--------------------+
| Database           |
+--------------------+
| information_schema |
| classdb            |
| mysql              |
| performance_schema |
+--------------------+
。。。。。。。。。。。。。
[root@master ~]# mysql -e 'drop database classdb;'
[root@master ~]# mysql -e 'show databases;'
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| testdb             |
+--------------------+
[root@slave ~]# mysql -e 'show databases;'
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
+--------------------+

至此,mysql的半同步复制已经完成。