MySQL 主从复制

MySQL 支持一台主服务器同时向多台从服务器进行复制,从服务器同时也可以作为其他服务器的主服务器,实现链状的复制。

一、异步复制
(1)确保主从服务器上安装了相同版本的数据库。
(2)在主服务器上,设置一个复制使用的账户,并授予REPLICATION SLAVE 权限。这里创建一个复制用户repl:
     mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%' IDENTIFIED BY '123';
(3)修改主数据库服务器的配置文件my.cnf,开启BINLOG,并设置server-id 的值。这两个参数的修改需要重新启动数据库服务才可以生效。
    My.cnf 中修改:
		[mysqld]
		log-bin=mysql-bin
		server-id=1
		
		[root@CentOS 3306]# ./stop.sh
		[root@CentOS 3306]# ./start.sh 
(4)在主服务器上,设置读锁定有效,这个操作是为了确保没有数据库操作,以便获得一个一致性的快照:
		mysql> flush tables with read lock;   ##这个session不要断开
(5)然后得到主服务器上当前的二进制日志名和偏移量值。这个操作的目的是为了在从数据库启动以后,从这个点开始进行数据的恢复。
		mysql> show master status;
		+------------------+----------+--------------+------------------+-------------------+
		| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
		+------------------+----------+--------------+------------------+-------------------+
		| mysql-bin.000001 |      120 |              |                  |                   |
		+------------------+----------+--------------+------------------+-------------------+
		1 row in set (0.00 sec)
(6)现在主数据库服务器已经停止了更新操作,需要生成主数据库的备份,备份的方式有很多种,可以直接在操作系统下cp 全部的数据文件到从数据库服务器上,也可以通过mysqldump 导出数据等。
    方法一:mysqldump -uroot -p -S /mydata/data/3306/mysql_3306.sock -l -F test >test.dmp
    方法二:
		[root@CentOS 3306]# ./stop.sh
		[root@CentOS data]# cp -R 3306 3306_bak
(7)主数据库的备份完毕后,主数据库可以恢复写操作,剩下的操作只需要在从服务器上执行:
    [root@CentOS 3306]# ./start.sh 
		mysql> unlock tables;
(8)将主数据库的一致性备份恢复到从数据库上。如果是使用.tar 打包的文件包,只需要解开到相应的目录即可。
    方法一:mysql -uroot -p -S /mydata/data/3307/mysql_3307.sock test < test.dmp
    ##如果是用mysqldump导入,就需要先做(9)(10)步。
    
    方法二:替换文件包括:
		[root@CentOS 3306]# ll
		总用量 176208
		-rw-rw----. 1 mysql mysql 79691776 12月  5 00:04 ibdata1
		-rw-rw----. 1 mysql mysql 50331648 12月  5 00:04 ib_logfile0
		-rw-rw----. 1 mysql mysql 50331648 11月 19 04:35 ib_logfile1
		drwx------. 2 mysql mysql     4096 11月 19 04:35 mysql
		drwx------. 2 mysql mysql     4096 11月 19 04:35 performance_schema
		drwx------. 2 mysql mysql     4096 12月  4 18:14 test
(9)修改从数据库的配置文件my.cnf,增加server-id 参数。注意server-id 的值必须是唯一的,不能和主数据库的配置相同,如果有多个从数据库服务器,每个从数据库服务器必须有自己唯一的server-id 值。
		my.cnf 中修改:
		[mysqld]
		server-id=2
		log-bin=mysql-bin
		relay-log=mysql-relay-bin
(10)在从服务器上,使用--skip-slave-start 选项启动从数据库,这样不会立即启动从数据库服务上的复制进程,方便我们对从数据库的服务进行进一步的配置:
		[root@CentOS 3307]# mysqld_safe --defaults-file=/mydata/data/3307/my.cnf --skip-slave-start 2>&1 > /dev/null &
(11)对从数据库服务器做相应设置,指定复制使用的用户,主数据库服务器的IP、端口以及开始执行复制的日志文件和位置等,具体语法如下:
		mysql> CHANGE MASTER TO
		-> MASTER_HOST='master_host_name',
		-> MASTER_USER='replication_user_name',
		-> MASTER_PASSWORD='replication_password',
		-> MASTER_LOG_FILE='recorded_log_file_name',
		-> MASTER_LOG_POS=recorded_log_position;
举例说明如下:
		CHANGE MASTER TO
		MASTER_HOST='10.10.10.8',
		MASTER_PORT=3306,
		MASTER_USER='repl',
		MASTER_PASSWORD='123',
		MASTER_LOG_FILE='mysql-bin.000001',
		MASTER_LOG_POS=120;
(12)在从服务器上,启动slave 线程:
		mysql> start slave;
(13)这时slave 上执行show processlist 命令将显示类似如下进程:
mysql> show processlist \G
*************************** 1. row ***************************
     Id: 2
   User: root
   Host: localhost
     db: NULL
Command: Query
   Time: 0
  State: init
   Info: show processlist
*************************** 2. row ***************************
     Id: 3
   User: system user
   Host: 
     db: NULL
Command: Connect
   Time: 74
  State: Waiting for master to send event
   Info: NULL
*************************** 3. row ***************************
     Id: 4
   User: system user
   Host: 
     db: NULL
Command: Connect
   Time: 44         ##从服务器当前执行的SQL 时间戳与系统时间之间的差距,单位是秒。也就是复制延迟多少秒!
  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)

mysql> show slave status \G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event      ##显示slave的当前状态
                  Master_Host: 10.10.10.8
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000005    ##显示当前读取的master节点二进制日志的文件名称
          Read_Master_Log_Pos: 120                 ##显示当前读取的master节点二进制日志位置
               Relay_Log_File: mysql-relay-bin.000008    ##显示当前slave节点正在处理的中继日志的文件名称
                Relay_Log_Pos: 283                       ##显示当前slave节点正在处理的中继日志位置
        Relay_Master_Log_File: mysql-bin.000005
             Slave_IO_Running: Yes     ##Slave_IO_Running:此进程负责从服务器(Slave)从主服务器(Master)上读取BINLOG日志,并写入从服务器上的中继日志中。
            Slave_SQL_Running: Yes     ##Slave_SQL_Running:此进程负责读取并且执行中继日志中的BINLOG 日志。
              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: 120     ##显示当前slave节点正在应用的日志文件位置
              Relay_Log_Space: 503
              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
                  Master_UUID: bc0f7676-9cca-11e5-8bf0-000c29395546
             Master_Info_File: /mydata/data/3307/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
1 row in set (0.00 sec)

主库上:
mysql> show processlist \G
*************************** 1. row ***************************
     Id: 1
   User: root
   Host: localhost
     db: test
Command: Query
   Time: 0
  State: init
   Info: show processlist
*************************** 2. row ***************************
     Id: 4
   User: repl
   Host: 10.10.10.8:36089
     db: NULL
Command: Binlog Dump
   Time: 942
  State: Master has sent all binlog to slave; waiting for binlog to be updated
   Info: NULL
2 rows in set (0.00 sec)

mysql> show slave hosts;
+-----------+------+------+-----------+--------------------------------------+
| Server_id | Host | Port | Master_id | Slave_UUID                           |
+-----------+------+------+-----------+--------------------------------------+
|         2 |      | 3307 |         1 | 3f8e9993-9cc8-11e5-8be0-000c29395546 |
+-----------+------+------+-----------+--------------------------------------+
1 row in set (0.00 sec)

(14)也可以测试复制服务的正确性,在主数据库上执行一个更新操作,观察是否在从数据库上同步。在主数据库上test 数据库创建一个测试表,插入数据:
mysql> delete from t where id in(1,2,3,4,5,6);
Query OK, 18 rows affected (1.06 sec)

mysql> select * from t;
+------+------+
| id   | name |
+------+------+
|  101 | a    |
|  102 | b    |
|  103 | c    |
|  104 | d    |
|  105 | d    |
|  106 | d    |
+------+------+
6 rows in set (0.00 sec)

mysql> insert into t1 values(4,'d');
Query OK, 1 row affected (1.94 sec)

mysql> select * from t1;
+------+------+
| id   | name |
+------+------+
|    1 | a    |
|    2 | b    |
|    3 | c    |
|    4 | d    |
+------+------+
4 rows in set (0.01 sec)
(15)在从数据库上检查新表是否被创建,数据是否同步:
mysql> select * from t;
+------+------+
| id   | name |
+------+------+
|  101 | a    |
|  102 | b    |
|  103 | c    |
|  104 | d    |
|  105 | d    |
|  106 | d    |
+------+------+
6 rows in set (0.00 sec)

mysql> select * from t1;
+------+------+
| id   | name |
+------+------+
|    1 | a    |
|    2 | b    |
|    3 | c    |
|    4 | d    |
+------+------+
4 rows in set (0.00 sec)

可以看到数据可以正确同步到从数据库上,复制服务配置成功完成。MySQL引入sync_binlog参数来控制binlog刷新到磁盘的频率:
mysql> show variables like '%sync_binlog%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| sync_binlog   | 0     |
+---------------+-------+
1 row in set (0.01 sec)

如果sync_binlog>0,则表示sync_binlog次事务提交,MySQL调用文件系统的刷新操作将binlog刷到磁盘。为了更好的保证数据的完整性和安全性,其实就是更好的保证二进制日志binlog的完整性和安全性,MySQL5.5引入了半同步复制部分的解决问题。

二、半同步复制
主库在每次事务成功提交时,并不及时反馈给前端应用用户,而是等待其中一个从库也接收到binlog事务并成功写入中继日志后,主库才返回commit操作成功给客户端。半同步模式是作为MySQL5.5的一个插件来实现的,主库和从库使用不同的插件。在前面异步复制的环境上,安装半同步复制插件即可。
(1)首先,判断MySQL服务器是否支持动态增加插件:
mysql> select @@have_dynamic_loading;
+------------------------+
| @@have_dynamic_loading |
+------------------------+
| YES                    |
+------------------------+
1 row in set (0.00 sec)

(2)检查MySQL的安装目录下是否存在插件,一般在$MYSQL_HOME/lib/plugin目录下 :
mysql> show variables like '%plugin_dir%';
+---------------+------------------------------+
| Variable_name | Value                        |
+---------------+------------------------------+
| plugin_dir    | /usr/local/mysql/lib/plugin/ |
+---------------+------------------------------+
1 row in set (0.00 sec)

[root@CentOS plugin]# pwd
/usr/local/mysql/lib/plugin
[root@CentOS plugin]# ll semisync_*.so
-rwxr-xr-x. 1 mysql mysql 399898 9月  18 23:34 semisync_master.so
-rwxr-xr-x. 1 mysql mysql 244216 9月  18 23:34 semisync_slave.so

在主库上安装插件semisync_master.so:
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
Query OK, 0 rows affected (8.84 sec)

mysql> select * from mysql.plugin;
+----------------------+--------------------+
| name                 | dl                 |
+----------------------+--------------------+
| rpl_semi_sync_master | semisync_master.so |
+----------------------+--------------------+
1 row in set (0.00 sec)

从库上安装semisync_slave.so插件:
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
Query OK, 0 rows affected (1.60 sec)

mysql> select * from mysql.plugin;
+---------------------+-------------------+
| name                | dl                |
+---------------------+-------------------+
| rpl_semi_sync_slave | semisync_slave.so |
+---------------------+-------------------+
1 row in set (0.30 sec)

(3)需要分别在主库和从库上配置参数打开半同步semi-sync:
主库参数:
mysql> set global rpl_semi_sync_master_enabled=1;
Query OK, 0 rows affected (0.53 sec)

mysql> set global rpl_semi_sync_master_timeout=30000;          ##主库在等待rpl_semi_sync_master_timeout毫秒后超时后,自动转成异步复制
Query OK, 0 rows affected (0.01 sec)

从库参数:
mysql> set global rpl_semi_sync_slave_enabled=1;
Query OK, 0 rows affected (0.00 sec)
注意,由于之前配置的复制是异步复制,所以需要重启一下从库上的I/O线程(如果全新配置的半同步复制则不需要):
mysql> stop slave io_thread;
Query OK, 0 rows affected (4.26 sec)

mysql> show slave status \G
*************************** 1. row ***************************
               Slave_IO_State: 
                  Master_Host: 10.10.10.8
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000006
          Read_Master_Log_Pos: 333
               Relay_Log_File: mysql-relay-bin.000011
                Relay_Log_Pos: 496
        Relay_Master_Log_File: mysql-bin.000006
             Slave_IO_Running: No       ##注意这里
            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: 333
              Relay_Log_Space: 832
              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: 1
                  Master_UUID: bc0f7676-9cca-11e5-8bf0-000c29395546
             Master_Info_File: /mydata/data/3307/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
1 row in set (0.00 sec)

mysql> start slave io_thread;
Query OK, 0 rows affected (0.01 sec)

mysql> show slave status \G
*************************** 1. row ***************************
               Slave_IO_State: Connecting to master
                  Master_Host: 10.10.10.8
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000006
          Read_Master_Log_Pos: 333
               Relay_Log_File: mysql-relay-bin.000011
                Relay_Log_Pos: 496
        Relay_Master_Log_File: mysql-bin.000006
             Slave_IO_Running: Connecting    ##注意这里
            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: 333
              Relay_Log_Space: 832
              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: 1
                  Master_UUID: bc0f7676-9cca-11e5-8bf0-000c29395546
             Master_Info_File: /mydata/data/3307/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
1 row in set (0.00 sec)

mysql> show slave status \G
*************************** 1. row ***************************
               Slave_IO_State: Queueing master event to the relay log
                  Master_Host: 10.10.10.8
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000006
          Read_Master_Log_Pos: 333
               Relay_Log_File: mysql-relay-bin.000011
                Relay_Log_Pos: 496
        Relay_Master_Log_File: mysql-bin.000006
             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: 333
              Relay_Log_Space: 716
              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
                  Master_UUID: bc0f7676-9cca-11e5-8bf0-000c29395546
             Master_Info_File: /mydata/data/3307/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
1 row in set (2.70 sec)

(4)到此半同步配置完毕,下面可以来验证一下。
主库:
mysql> show status like '%semi_sync%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 1     |      ##显示当前处于半同步模式的slave节点数量
| 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     |      ##表示当前有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 variables like '%semi_sync%';
+------------------------------------+-------+
| Variable_name                      | Value |
+------------------------------------+-------+
| rpl_semi_sync_master_enabled       | ON    |
| rpl_semi_sync_master_timeout       | 30000 |
| rpl_semi_sync_master_trace_level   | 32    |
| rpl_semi_sync_master_wait_no_slave | ON    |
+------------------------------------+-------+
4 rows in set (0.00 sec)

从库:
mysql> show status like '%semi_sync%';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON    |
+----------------------------+-------+
1 row in set (0.00 sec)

mysql> show variables like '%semi_sync%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled     | ON    |
| rpl_semi_sync_slave_trace_level | 32    |
+---------------------------------+-------+
2 rows in set (0.09 sec)

注意:当从库网络异常时,自动切换为异步复制;当从库网络恢复正常后,会自动切换成为半同步复制。
半同步复制的“半”就体现在:虽然主库和从库的binlog日志是同步的,但是主库并不等待从库应用这部分日志就返回提交结果,这部分操作是异步的,从库的数据并不是和主库实时同步的,所以只能称为半同步,而不是完全的实时同步。

三、主要复制启动选项
log-slave-updates 这个参数用来配置从服务器上的更新操作是否写二进制日志,默认是不打开的。但是,如果这个从服务器同时也要作为其他服务器的主服务器,搭建一个链式的复制,那么就需要打开这个选项,这样它的从服务器将获得它的二进制日志以进行同步操作。这个启动参数需要和--logs-bin 参数一起使用。

master-connect-retry 这个参数用来设置在和主服务器的连接丢失的时候,重试的时间间隔,默认是60 秒,即每60 秒重试一次。

read-only 该参数用来设置从服务器只能接受超级用户的更新操作,从而限制应用程序错误的对从服务器的更新操作。

replicate-do-db、replicate-do-table、replicate-ignore-db、replicate-ignore-table 或replicate-wild-do-table 来指定从主数据库复制到从数据库的数据库或者表。有些时候用户只需要将关键表备份到从服务器上,或者只需要将提供查询操作的表复制到从服务器上,这样就可以通过配置这几个参数来筛选进行同步的数据库和表。从数据库启动的时候指定。

slave-skip-errors 此参数可以定义多个错误号,或者通过定义成all 跳过全部的错误。具体语法如下:--slave-skip-errors=[err_code1,err_code2,... | all]
如果从数据库主要是作为主数据库的备份,那么就不应该使用这个启动参数,设置不当,很可能造成主从数据库的数据不同步。但是,如果从数据库仅仅是为了分担主数据库的查询压力,且对数据的完整性要求不是很严格,那么这个选项的确可以减轻数据库管理员维护从数据库的工作量。

slave_parallel_workers  MySQL5.6提供了基于schema的多线程复制,允许从库并行更新。通过设置参数slave_parallel_workers为2,让MySQL从库在复制时启动两个SQL线程。

SQL_SLAVE_SKIP_COUNTER  跳过来自主服务器的语句的命令为SET GLOBALSQL_SLAVE_SKIP_COUNTER = n,其中n 的取值为1 或者2。如果来自主服务器的更新语句不使用AUTO_INCREMENT 或LAST_INSERT_ID(),n 值应为1,否则,值应为2。原因是使用AUTO_INCREMENT 或LAST_INSERT_ID()的语句需要从二进制日志中取两个事件。

auto_increment_increment 和auto_increment_offset  在某些情况下,可能会需要使用多主复制(多台主服务器对一台从服务器)。这个时候,如果主服务器的表采用自动增长变量,那么复制到从服务器的同一张表后很可能会引起主键冲突,因为系统参数auto_increment_increment 和auto_increment_offset 默认值为1,这样多台主服务器的自增变量列迟早会发生冲突。就需要定制auto_increment_increment 和auto_increment_offset 的设置,保证多主之间复制到从数据库不会有重复冲突。比如,两个master 的情况可以按照以下设置。
? Master1 上:auto_increment_increment = 2,auto_increment_offset = 1;(1,3,5,7…序列)。
? Master2 上:auto_increment_increment = 2,auto_increment_offset = 0;(0,2,4,6…序列)。

四、日常管理维护
##查看从服务器状态
mysql> show slave status \G

##启/停线程
mysql> start slave;
mysql> start slave io_thread;
mysql> start slave sql_thread;
mysql> stop slave;
mysql> stop slave io_thread;
mysql> stop slave sql_thread;

##主从服务器同步维护
在某些繁忙的OLTP(在线事务处理)系统上,由于主服务器更新频繁,而从服务器由于各种原因(比如硬件性能较差)导致更新速度较慢,从而使得主从服务器之间的数据差距越来越大,最终对某些应用产生影响。在这种情况下,我们就需要定期地进行主从服务器的数据同步,使得主从数据差距能够减到最小。常用的方法是:在负载较低的时候暂时阻塞主数据库的更新,强制主从数据库更新同步。具体操作步骤如下。
(1)在主服务器上,执行以下语句(注意,会阻塞主数据库的所有更新操作):
mysql> FLUSH TABLES WITH READ LOCK;
Query OK, 0 rows affected (0.03 sec)

mysql> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000006 |      545 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
##记录SHOW 语句的输出的日志名和偏移量,这些是从服务器复制的目的坐标。

(2)在从服务器上,执行下面语句,其中MASTER_POS_WAIT()函数的参数是前面步骤中得到的复制坐标值:
mysql> select MASTER_POS_WAIT('mysql-bin.000006','545');
+-------------------------------------------+
| MASTER_POS_WAIT('mysql-bin.000006','545') |
+-------------------------------------------+
|                                         0 |
+-------------------------------------------+
1 row in set (0.02 sec)
##这个SELECT 语句会阻塞直到从服务器达到指定的日志文件和偏移量后,返回0,如果返回-1,则表示超时退出。查询返回0 时,则从服务器与主服务器同步。

(3)在主服务器上,执行下面的语句允许主服务器重新开始处理更新:
mysql> UNLOCK TABLES;
Query OK, 0 rows affected (0.02 sec)

##切换主从服务器
假设有一个复制的环境,一个主数据库服务器M,两个从数据库服务器S1、S2 同时指向主数据库服务器M。
(1)首先要确保所有的从数据库都已经执行了relay log 中的全部更新,在每个从服务器上,执行STOP SLAVE IO_THREAD,然后检查SHOW PROCESSLIST 的输出,直到看到状态是Has read all relay log,表示更新都执行完毕。
mysql> STOP SLAVE IO_THREAD;
mysql> SHOW PROCESSLIST \G
(2)在从数据库S1 上,执行STOP SLAVE 停止从服务,然后RESET MASTER 重置成主数据库。
mysql> STOP SLAVE;
mysql> reset master;
mysql> show master status;
(3)在S2 上,执行STOP SLAVE 停止从服务,然后执行CHANGE MASTER TO MASTER_HOST= 'S1'重新设置主数据库,然后再执行START SLAVE 启动复制。
mysql> STOP SLAVE;
mysql> CHANGE MASTER TO MASTER_HOST = '192.168.1.101';
mysql> start slave;
(4)通知所有的客户端将应用指向S1,这样客户端发送的所有的更新语法写入到S1 的二进制日志。
(5)删除新的主数据库服务器上的master.info 和relay-log.info 文件,否则下次重启的时候还会按照从服务器启动。
(6)最后,如果M 服务器可以修复,则可以按照S2 的方法配置成S1 的从服务器。
注意:上面测试的步骤是默认S1 是打开log-bin 选项的,这样重置成主数据库后可以将二进制日志传输到其他从服务器。其次,S1 上没有打开log-slave-updates 参数,否则重置成主数据库后,可能会将已经执行过的二进制日志重复传输给S2,导致S2 的同步错误。

你可能感兴趣的:(MySQL 主从复制)