MySQL主从复制、主从复制(异步)、半同步复制、SSL复制

概述

    复制通常用来创建主节点的副本,通过添加冗余节点来保证高可用性,当然复制也可以用于其他 用途,例如在从节点上进行数据读、分析等等。在横向扩展的业务中,复制很容易实施,主要表现在在利用主节点进行写操作,多个从节点进行读操作,在mysql5.5中默认为异步复制。

    mysql 复制的异步性是指:事物首先在主节点上提交,然后复制给从节点并在从节点上应用,这样意味着在同一个时间点主从上的数据可能不一致,异步复制的好处在于它 比同步复制要快,如果对数据的一致性要求很高,还是采用同步复制较好。

    mysql-5.5 开始支持semi-synchronous的复制,也叫半同步复制,目的在于事务环境下保持主从一致

    mysql-5.6 开始支持延时复制。

    mysql复制的原理现阶段都是一样的,master将操作记录到bin-log中,slave的一个线程去master读取bin-log,并将他们保存到relay-log中,slave的另外一个线程去重放relay-log中的操作来实现和master数据同步。


    wKioL1OWgmrSKROTAAEnELMIXRI329.jpg

    该过程的第一部分就是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从线程)处理该过程的最后一步。SQL线程从中继日志读取事件,并重放其中的事件而更新slave的数据,使其与master中的数 据一致。只要该线程与I/O线程保持一致,中继日志通常会位于OS的缓存中,所以中继日志的开销很小。
    此外,在master中也有一个工作线程:和其它MySQL的连接一样,slave在master中打开一个连接也会使得master开始一个线程。复制 过程有一个很重要的限制——复制在slave上是串行化的,也就是说master上的并行更新操作不能在slave上并行操作。


异步主从复制配置

准备:

    OS:rhel5.8_i386

    SoftWare: mysql-5.5.28-linux2.6-i686.tar.gz


1、主从安装mysql

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    tar  xf mysql-5.5.28-linux2.6-i686. tar .gz -C  /usr/local/
    # cd /usr/local/
    # ln -s mysql-5.5.28-linux2.6-i686/ mysql
    # groupadd -r mysql
    # useradd -r -g mysql -s /sbin/nologin mysql
    # mkdir /mydata/data -p
    # chown -R mysql.mysql /mydata/data/
    # chown -R root.mysql /usr/local/mysql/*
    # cp support-files/my-large.cnf /etc/my.cnf
    # cp support-files/mysql.server  /etc/init.d/mysqld
        [mysqld]
        innodb_file_per_table = 1
        datadir =  /mydata/data  #由于是二进制安装的mysql所以必须指定数据库目录位置
    # vim /etc/profile.d/mysqld.sh
        export  PAHT=$PATH: /usr/local/mysql/bin
    # . /etc/profile.d/mysqld.sh

2、主服务器配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
     # vim /etc/my.cnf
         [mysqld]
         log-bin = master-bin
         log-bin-index = master-bin.index
         
         server- id  = 1
     # scripts/mysql_install_db --user=mysql --datadir=/mydata/data/
     # service mysqld start
     # mysql
     mysql> grant replication slave on *.* to repl@ '192.168.100.12'  identified by  'asdasd' ;
     mysql> flush privileges;
     mysql> flush logs;
     mysql> show master logs;
     +-------------------+-----------+
     | Log_name          | File_size |
     +-------------------+-----------+
     | master-bin.000001 |     27326 |
     | master-bin.000002 |   1038693 |
     | master-bin.000003 |       379 |
     | master-bin.000004 |       107 |
     +-------------------+-----------+
     mysql> purge binary logs to  'master-bin.000004' ;

3、从服务器配置

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
     # vim /etc/my.cnf
         [mysqld]
         relay-log = relay-log
         relay-log-index = relay-log.index
         read -only = 1
         #innodb_file_per_table = 1
         #binlog_format=mixed
         server- id  = 10
     # scripts/mysql_install_db --user=mysql --datadir=/mydata/data/
     # service mysqld start
     mysql> change master to master_host= '192.168.100.11' ,master_user= 'repl' ,master_password= 'asdasd' ,master_log_file= 'master-bin.000004' ,master_log_pos=107;
     mysql> show slave status\G
     *************************** 1. row ***************************
                    Slave_IO_State: 
                       Master_Host: 192.168.100.11
                       Master_User: repl
                       Master_Port: 3306
                     Connect_Retry: 60
                   Master_Log_File: master-bin.000004
               Read_Master_Log_Pos: 107
                    Relay_Log_File: relay-log.000001
                     Relay_Log_Pos: 4
             Relay_Master_Log_File: master-bin.000004
                  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;
     mysql> show slave status\G
              Slave_IO_Running: Yes
             Slave_SQL_Running: Yes
             ..............

    至此主从异步复制就完成了

    说明:

        slave_id 必须是唯一的

        slave没有必要开启二进制日志,但在有些情况下必须设置,如mysql级联. slave为其它slave的master,所以要设置bin_log,默认为hostname,但如果hostname改变则会出问题。

        有些人可能开启了slave二进制日志,却没有设置log_slave_updates,然后查看slave的数据是否改变,这是错误的配置。所以尽量使用read_only = 1 ,防止改变数据(除了sql_thread进程)。

        start slave :启动从服务器IO_Thread和SQL_Thread线程,这里也可以单独对它们进行启动

        在主服务器上需设置sync-binlog = 1 ,用于事务安全

        重置change master参数:

1
2
3
             mysql> slave stop;
             mysql> reset slave;
             mysql> change master to master_host= '192.168.100.11' ,master_user= 'repl' ,master_password= 'asdasd' ,master_log_file= 'master-bin.000005' ,master_log_pos=107;

        由于slave都会自动连接上master,当我们有时需要手动调整时可以在启动前移动slave数据目录下的master.ino和relay.info文件,或者查看variables中有无“skip-slave-start”变量,有就设置为ON



半同步复制

    /usr/local/mysql/lib/plugin/semisync_master.so
    /usr/local/mysql/lib/plugin/semisync_slave.so

    1、主服务器配置

1
2
3
4
5
6
7
8
9
10
11
12
     mysql> install plugin rpl_semi_sync_master soname  'semisync_master.so' ;
     mysql> show variables like  '%semi%' ;
     +------------------------------------+-------+
     | Variable_name                      | Value |
     +------------------------------------+-------+
     | rpl_semi_sync_master_enabled       | OFF   |
     | rpl_semi_sync_master_timeout       | 10000 |
     | rpl_semi_sync_master_trace_level   | 32    |
     | rpl_semi_sync_master_wait_no_slave | ON    |
     +------------------------------------+-------+
     mysql> set global rpl_semi_sync_master_enabled=1;
     mysql> set global rpl_semi_sync_master_timeout=1000;

    2、Slave上配置

1
2
3
4
5
6
7
8
9
     mysql> install plugin rpl_semi_sync_slave soname  'semisync_slave.so' ;
     mysql> show variables like  '%semi%' ;
     +---------------------------------+-------+
     | Variable_name                   | Value |
     +---------------------------------+-------+
     | rpl_semi_sync_slave_enabled     | OFF   |
     | rpl_semi_sync_slave_trace_level | 32    |
     +---------------------------------+-------+
     mysql> set global rpl_semi_sync_slave_enabled=1;

    如果需要永久生效,请将上面几个变量分别写入master与slave中mysqld字段中。


MySQL复制过滤

    MySQL复制过滤可以在Master,也可以在Slave
    由于基于Master的过滤操作为影响到二进制日志的完整性,对于我们以后做及时点还原会有影响,所以我们一般不建议在Maser上做复制过滤。

    1、基于数据库

1
2
     binlog- do -db            //binlog-do-db 表示和哪个数据库相关的写入类、修改类指令会被写入
     binlog-ignore-db         //binlog-ignore-db 表示忽略(黑名单)


    2、基于表
    replicate-do-table=
    replicate-ignore-table=


    3、对于表,还可以用通配符配置过滤
    replicate-wild-do-table=
    replicate-wild-ignore-table=





SSL复制

    要求主从服务器各自都要有证书和私钥;默认情况下主从服务器的SSL功能是没有启用的,需要先启用。

1
2
3
4
5
6
7
8
9
10
11
12
     mysql> show variables like  '%ssl%' ;
     +---------------+----------+
     | Variable_name | Value    |
     +---------------+----------+
     | have_openssl  | DISABLED |
     | have_ssl      | DISABLED |
     | ssl_ca        |          |
     | ssl_capath    |          |
     | ssl_cert      |          |
     | ssl_cipher    |          |
     | ssl_key       |          |
     +---------------+----------+

1、配置Master为CA证书服务器

1
2
3
4
5
6
7
8
9
10
11
12
13
# vim /etc/pki/tls/openssl.cnf
# cd /etc/pki/CA/
# (umask 077; openssl genrsa 1024 >private/cakey.pem)
# openssl req -new -x509 -key private/cakey.pem -out cacert.pem
     Country Name (2 letter code) [GB]:CN 
     State or Province Name (full name) [Berkshire]:GD
     Locality Name (eg, city) [Newbury]:ZS
     Organization Name (eg, company) [My Company Ltd]:NEO
     Organizational Unit Name (eg, section) []:tech
     Common Name (eg, your name or your server's  hostname ) []:station01.neo.com
# mkdir newcerts certs crl
# touch index.txt
# echo 01 >serial

2、为Master上的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
# mkdir /usr/local/mysql/ssl
# cd /usr/local/mysql/ssl/
#(umask 077; openssl genrsa 1024 > mysql.key)
# openssl req -new -key mysql.key -out mysql.csr -days 3650
     Country Name (2 letter code) [GB]:CN
     State or Province Name (full name) [Berkshire]:GD
     Locality Name (eg, city) [Newbury]:ZS
     Organization Name (eg, company) [My Company Ltd]:NEO
     Organizational Unit Name (eg, section) []:tech
     Common Name (eg, your name or your server's  hostname ) []:station01.neo.com
     Email Address []:
     
     Please enter the following  'extra'  attributes
     to be sent with your certificate request
     A challenge password []:
     An optional company name []:
# openssl ca -in mysql.csr -out mysql.crt
Using configuration from  /etc/pki/tls/openssl .cnf
Check that the request matches the signature
Signature ok
Certificate Details:
         Serial Number: 1 (0x1)
         Validity
             Not Before: May 28 02:26:17 2014 GMT
             Not After : May 28 02:26:17 2015 GMT
         Subject:
             countryName               = CN
             stateOrProvinceName       = GD
             organizationName          = NEO
             organizationalUnitName    = tech
             commonName                = station01.neo.com
         X509v3 extensions:
             X509v3 Basic Constraints: 
                 CA:FALSE
             Netscape Comment: 
                 OpenSSL Generated Certificate
             X509v3 Subject Key Identifier: 
                 A4:B7:A6:98:9F:60:08:BE:86:87:65:5F:B6:13:BC:4A:5B:D4:44:3A
             X509v3 Authority Key Identifier: 
                 keyid:4F:D8:57:42:D9:39:17:7D:39:44:91:01:A4:01:DE:32:92:D6:F9:DF
 
Certificate is to be certified  until  May 28 02:26:17 2015 GMT (365 days)
Sign the certificate? [y /n ]:y
 
 
1 out of 1 certificate requests certified, commit? [y /n ]y
Write out database with 1 new entries
Data Base Updated
# chown mysql.mysql *

3、Slave上申请证书

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# mkdir /usr/local/mysql/ssl
# (umask 077; openssl genrsa 1024 >mysql.key)
# openssl req -new -key mysql.key -out mysql.csr -days 3650
     Country Name (2 letter code) [GB]:CN
     State or Province Name (full name) [Berkshire]:GD
     Locality Name (eg, city) [Newbury]:ZS
     Organization Name (eg, company) [My Company Ltd]:NEO
     Organizational Unit Name (eg, section) []:tech
     Common Name (eg, your name or your server's  hostname ) []:station02.neo.com
     Email Address []:
     
     Please enter the following  'extra'  attributes
     to be sent with your certificate request
     A challenge password []:
     An optional company name []:
# scp mysql.csr 192.168.100.11:/root/

4、Master上为Slave签发证书

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
# openssl ca -in mysql.csr -out mysql.crt
Using configuration from  /etc/pki/tls/openssl .cnf
Check that the request matches the signature
Signature ok
Certificate Details:
         Serial Number: 2 (0x2)
         Validity
             Not Before: May 28 02:36:24 2014 GMT
             Not After : May 28 02:36:24 2015 GMT
         Subject:
             countryName               = CN
             stateOrProvinceName       = GD
             organizationName          = NEO
             organizationalUnitName    = tech
             commonName                = station02.neo.com
         X509v3 extensions:
             X509v3 Basic Constraints: 
                 CA:FALSE
             Netscape Comment: 
                 OpenSSL Generated Certificate
             X509v3 Subject Key Identifier: 
                 81:9F:5B:E7:06:D0:64:B7:E6:81:3F:98:95:71:D4:DF:C6:B8:CE:3D
             X509v3 Authority Key Identifier: 
                 keyid:4F:D8:57:42:D9:39:17:7D:39:44:91:01:A4:01:DE:32:92:D6:F9:DF
 
Certificate is to be certified  until  May 28 02:36:24 2015 GMT (365 days)
Sign the certificate? [y /n ]: yes
 
 
1 out of 1 certificate requests certified, commit? [y /n ] yes
Write out database with 1 new entries
Data Base Updated
# scp mysql.crt 192.168.100.12:/usr/local/mysql/ssl/
# scp /etc/pki/CA/cacert.pem 192.168.100.12:/usr/local/mysql/ssl/


5、Master上编缉/etc/my.cnf启用ssl,并设置主从


1
2
3
4
5
6
7
8
9
10
# vim /etc/my.cnf
[mysqld] 
log-bin=mysql-bin 
sync_binlog = 1                           ##二进制日志 
server- id  = 1                             ##此id必须全局唯一 
innodb_flush_log_at_trx_commit=1          ##每秒将事务日志立刻刷写到磁盘 
ssl                                       ##启用ssl默认是不开启的,mysql中show variables like '%ssl%'查看 
ssl_ca = /usr/local/mysql/ssl/cacert .pem       ##ca文件的位置 
ssl_cert=  /usr/local/mysql/ssl/mysql .crt      ##证书文件的位置 
ssl_key =  /usr/local/mysql/ssl/mysql .key      ##私钥文件的位置







6、启动mysql,并查看ssl信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# service mysqld start 
# mysql 
mysql> show variables like  '%ssl%'
+---------------+---------------------------------+ 
| Variable_name | Value                           | 
+---------------+---------------------------------+ 
| have_openssl  | YES                             | 
| have_ssl      | YES                             | 
| ssl_ca        |  /usr/local/mysql/ssl/cacert .pem | 
| ssl_capath    |                                 | 
| ssl_cert      |  /usr/local/mysql/ssl/mysql .crt  | 
| ssl_cipher    |                                 | 
| ssl_key       |  /usr/local/mysql/ssl/mysql .key  | 
+---------------+---------------------------------+



7、为同步建立一最小权限账户,并要求ssl

1
2
3
4
5
mysql> create user  'backup_ssl' @ '192.168.100.12'  identified by  'redhat'
mysql> revoke all privileges,grant option from  'backup_ssl' @ '192.168.100.12'
mysql> grant replication slave,replication client on *.* to  'backup_ssl' @ '192.168.100.12'  require ssl; 
mysql> flush privileges;
mysql> flush logs;


8、Slave上编缉/etc/my.cnf,启用ssl,并设置主从

1
2
3
4
5
6
7
8
9
10
11
# vim /etc/my.cnf
[mysqld] 
server- id  = 2                         ##此id必须全局唯一 
##log-bin = mysql-bin                ##注释掉,从服务器不需要二进制日志
relay-log = mysql-relay               ##中继日志 
relay-log-index = mysql-ralay.index   ##中继目录 
read -only = 1                         ##从服务器只读
ssl                                   ##启用ssl默认是不开启的,mysql中show variables like '%ssl%'查看 
ssl_ca = /usr/local/mysql/ssl/cacert .pem   ##ca文件的位置 
ssl_cert=  /usr/local/mysql/ssl/mysql .crt  ##证书文件的位置 
ssl_key =  /usr/local/mysql/ssl/mysql .key  ##私钥文件的位置



   


9、启用mysqld并查看ssl相关信息

1
2
3
4
5
6
7
8
9
10
11
12
13
# servie mysqld start 
mysql> show variables like  '%ssl%'
+---------------+---------------------------------+ 
| Variable_name | Value                           | 
+---------------+---------------------------------+ 
| have_openssl  | YES                             | 
| have_ssl      | YES                             | 
| ssl_ca        |  /usr/local/mysql/ssl/cacert .pem | 
| ssl_capath    |                                 | 
| ssl_cert      |  /usr/local/mysql/ssl/mysql .crt  | 
| ssl_cipher    |                                 | 
| ssl_key       |  /usr/local/mysql/ssl/mysql .key  | 
+---------------+---------------------------------+

10、启动slave同步进程,连接主服务器

1
2
3
4
5
6
7
8
9
10
11
mysql> change master to  
     -> master_host= '192.168.100.11'
     -> master_user= 'backup_ssl'
     -> master_password= 'redhat'
     -> master_log_file= 'mysql-bin.000004'
     -> master_ssl=1, 
     -> master_ssl_ca= '/usr/local/mysql/ssl/cacert.pem'
     -> master_ssl_cert= '/usr/local/mysql/ssl/mysql.crt'
     -> master_ssl_key= '/usr/local/mysql/ssl/mysql.key'
mysql> start slave 
mysql> show slave status\G;  ##查看slave状态



   


11、关注以下参数:

1
2
3
4
5
6
7
8
Slave_IO_Running: Yes                                   ##IOthread是否运行,如果为No代表slave运行不正常 
Slave_SQL_Running: Yes                                  ##SQLthread是否运行,如果为No代表slave运行不正常 
Master_SSL_CA_File:  /usr/local/mysql/ssl/cacert .pem     ##是否启用了ssl 
Master_SSL_Cert:  /usr/local/mysql/ssl/mysql .crt 
Master_SSL_Key:  /usr/local/mysql/ssl/mysql .key 
Master_Log_File: mysql-bin.00005                        ##最后接收的主服务器的二进制 
Exec_Master_Log_Pos: 338                                ##最后执行的位置,查看master中是不是该位置 
Last_IO_Errno: 0                                        ##最后一次IOthread有没有报错
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值