MySQL Cluster
MySQL Cluster
MySQL 主从复制原理
参考:https://zhuanlan.zhihu.com/p/96212530
MySQL 主从同步
环境(MySQL5.7):
角色 | IP |
---|---|
Master | 172.16.1.128 |
Slave | 172.16.1.136 |
在默认安装的test
数据库中建一个测试表:
mariadb root@172.16.1.128:test> SHOW CREATE TABLE test\G***************************[ 1. row ]***************************Table | testCreate Table | CREATE TABLE `test` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(32) NOT NULL COMMENT '姓名', PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='测试表'
1 row in setTime: 0.004s
在 Master 主服务上
在主服务器上为从服务器建立一个连接帐户,并授予REPLICATION SLAVE
权限。
mysql> grant replication slave on *.* to 'backup'@'172.16.1.136' identified by '123';mysql> flush privileges;
创建好用户之后,在从服务器进行登录测试:
mysql -ubackup -p123 -h172.16.1.128
修改 mysql 配置文件,/etc/my.cnf
:
# 在[mysqld]配置段添加以下内容server-id=1 # mysql主从里,id必须唯一,范围:1~255log-bin=master-bin # 其中这两行是本来就有的,可以不用动,添加下面两行即可.指定日志文件binlog_format="mixed"binlog-do-db=test # 记录日志的数据库binlog-ignore-db=mysql # 不记录日志的数据库
修改完保存退出,然后重启服务,systemctl restart mariadb
查看主服务器状态:
mysql> flush tables with read lock;mysql> show master status\G*************************** 1. row *************************** File: master-bin.000003 Position: 2007 Binlog_Do_DB:Binlog_Ignore_DB:1 row in set (0.00 sec)
锁表,为了产生环境中不让进新的数据,好让从服务器定位同步位置,初次同步完成后,记得解锁。
mysql> unlock tables;
在 Slave 从服务器上
编辑配置文件my.cnf
:
# 在[mysqld]配置段添加以下内容server-id=2log-bin=master-binreplicate-do-db=testreplicate-ignore-db=mysql,information_schema,performance_schema
修改完保存退出,然后重启服务,systemctl restart mariadb
使用change master
命令指定同步位置:
mysql> stop slave;# 如果发生错误,需要使用 `reset slave;` 来进行重置mysql> change master to master_host='172.16.1.128',master_user='backup',master_password='123', master_log_file='master-bin.000003',master_log_pos=2007;
:warning:注意:上面的master_log_file
和master_log_pos
值要与 Master 主机一致。
查看 Slave 状态:
mysql> show slave status\G;*************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 172.16.1.128 Master_User: backup Master_Port: 3306 Connect_Retry: 60 Master_Log_File: master-bin.000003 Read_Master_Log_Pos: 1024 Relay_Log_File: mariadb-relay-bin.000002 Relay_Log_Pos: 783 Relay_Master_Log_File: master-bin.000003 Slave_IO_Running: Yes # 如果看到这一项和下面一项均为 Yes,则表明从服务器配置完成 Slave_SQL_Running: Yes Replicate_Do_DB: test Replicate_Ignore_DB: mysql,information_schema,performance_schema Replicate_Do_Table: ...
测试同步
在 Master 服务器中向之前创建好的test
空表插入数据:
mysql> insert into test.test(id,name) value(2,'suofeiya');
在 Slave 端进行查看:
mysql> select * from test.test;+----+-----------+| id | name |+----+-----------+| 2 | suofeiya |+----+-----------+
MySQL 双主同步
角色 | IP |
---|---|
Master/Slave(server1) | 172.16.1.128 |
Slave/Master(server2) | 172.16.1.136 |
同时在主服务器上建立一个连接用户,并授予REPLIATION SLAVE
权限,这里服务器1和服务器2都互为主从,所以需要分别建立。
# 在 server1 上mysql> grant replication slave on *.* to 'backup'@'172.16.1.136' identified by '123';mysql> flush privileges;# 在 server2 上mysql> grant replication slave on *.* to 'backup'@'172.16.1.128' identified by '123';mysql> flush privileges;
双方测试连接,确保同步能够正常进行
修改配置文件/etc/my.cnf
的[mysqld]
配置段(仅作为参考):
# --------- server1 ---------server-id=1log-bin=mysql-binbinlog-do-db=testbinlog-ignore-db=mysql# 主-主形式需要多添加的部分log-slave-updatessync_binlog=1auto_increment_offset=1auto_increment_increment=2replicate-do-db=testreplicate-ignore-db=mysql,information_schema
# --------- server2 ---------server-id=2log-bin=mysql-binreplicate-do-db=testreplicate-ignore-db=mysql,information_schema,performance_schema# 主-主形式需要多添加的部分binlog-do-db=testbinlog-ignore-db=mysqllog-slave-updatessync_binlog=1auto_increment_offset=2auto_increment_increment=2
修改完保存退出,随后重启 server1 和server2 的服务,systemctl restart mariadb
查看 server1 和 server2 两主机作为主服务器的状态:
-- server1mysql> show master status\G*************************** 1. row *************************** File: mysql-bin.000001 Position: 245 Binlog_Do_DB: testBinlog_Ignore_DB: mysql1 row in set (0.00 sec)
-- server2mysql> show master status\G*************************** 1. row *************************** File: mysql-bin.000001 Position: 245 Binlog_Do_DB: testBinlog_Ignore_DB: mysql1 row in set (0.00 sec)
分别在两主机上使用change master to
指定同步位置:
-- server1mysql> change master to master_host='172.16.1.136',master_user='backup',master_password='123', master_log_file='mysql-bin.000001',master_log_pos=245;-- server2mysql> change master to master_host='172.16.1.128',master_user='backup',master_password='123', master_log_file='mysql-bin.000001',master_log_pos=245;
然后,分别在两主机上启动从服务器线程并查看其状态:
-- server1mysql> start slave;mysql> show slave status\G;*************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 172.16.1.136 Master_User: backup Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000001 Read_Master_Log_Pos: 245 Relay_Log_File: mariadb-relay-bin.000002 Relay_Log_Pos: 529 Relay_Master_Log_File: mysql-bin.000001 Slave_IO_Running:` Yes` # 看到这两个Yes即表示成功启动 Slave_SQL_Running:` Yes` Replicate_Do_DB: test Replicate_Ignore_DB: mysql,information_schema...-- server2mysql>start slave;mysql> show slave status\G;*************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 172.16.1.128 Master_User: backup Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000001 Read_Master_Log_Pos: 245 Relay_Log_File: mariadb-relay-bin.000002 Relay_Log_Pos: 529 Relay_Master_Log_File: mysql-bin.000001 Slave_IO_Running: `Yes` Slave_SQL_Running: `Yes` Replicate_Do_DB: test Replicate_Ignore_DB: mysql,information_schema,performance_schema Replicate_Do_Table:...
测试双主同步:
-- 在 server1 上插入一条数据,看 server2 是否成功同步mysql> insert into test.test(id,name) value(3,'agou-ops');-- 在 server2 上进行查看mysql> select * from test.test;+----+-----------+| id | name |+----+-----------+| 2 | suofeiya |`| 3 | agou-ops | `+----+-----------+
-- 在 server2 上创建一张测试数据表xxx,看 server1 是否成功同步mysql> create table test.xxx(id INT(10),name VARCHAR(25));-- 在 server1 上进行查看mysql> show tables;+----------------+| Tables_in_test |+----------------+| test || xxx |+----------------+
至此,双主同步已经成功搭建。
基于 SSL 加密传输(主从)
由于 mysql 在复制过程中是明文的,所以就大大降低了安全性,因此需要借助于ssl加密来增加其复制的安全性。
预先准备
在配置 ssl 前我们先看下一下 ssl 的状态信息:
mysql> show variables like '%ssl%';+---------------+----------+| Variable_name | Value |+---------------+----------+| have_openssl | DISABLED || have_ssl | DISABLED || ssl_ca | || ssl_capath | || ssl_cert | || ssl_cipher | || ssl_key | |+---------------+----------+7 rows in set (0.01 sec)
可以看到 SSL 处于 DISABLED
状态,表示未开启。
要开启 SSL 只需要在配置文件/etc/my.cnf
中加入 ssl 即可:
# 在 [mysqld] 配置段ssl
随后保存退出,重启服务即可,systemctl restart mariadb
查看确认:
mysql> show variables like '%ssl%';+---------------+-------+| Variable_name | Value |+---------------+-------+| have_openssl | YES || have_ssl | YES || ssl_ca | || ssl_capath | || ssl_cert | || ssl_cipher | || ssl_key | |+---------------+-------+7 rows in set (0.00 sec)
配置主从服务的 SSL 功能
配置 CA 和颁发证书
在Master
主机上,配置 CA
服务器:
cd /etc/pki/CAtouch index.txtecho 01 > serial(umask 077;openssl genrsa -out private/cakey.pem 1024)openssl req -x509 -new -key private/cakey.pem -out cacert.pem -days 365
为Master
准备私钥并颁发证书:
# 创建存放证书的目录mkdir /usr/local/mysql/ssl -pvcd /usr/local/mysql/ssl
# 创建所需要的证书(umask 077;openssl genrsa 1024 > master.key)openssl req -new -key master.key -out master.csropenssl ca -in master.csr -out master.crt -days 365cp /etc/pki/CA/cacert.pem /usr/local/mysql/sslchown -R mysql:mysql /usr/local/mysql/ssl
在Slave
主机上,准备私钥并申请证书:
# 创建存放证书的目录mkdir /usr/local/mysql/ssl -pvcd /usr/local/mysql/ssl
# 创建所需要的证书(umask 077;openssl genrsa 1024 > slave.key)openssl req -new -key slave.key -out slave.csr scp ./slave.csr 172.16.1.128:/root
在 Master
(主服务器)上为 Slave (从服务器)签发证书:
openssl ca -in slave.csr -out slave.crtscp slave.crt /etc/pki/CA/cacert.pem 172.16.1.136:/usr/local/mysql/ssl
到此为止证书已经准备完成,请确保Master
和Slave
主机上有如下文件,并且属主和属组为mysql:
# master 主机上[root@stor1 ssl]\# lltotal 16-rw-r--r-- 1 mysql mysql 960 May 12 00:05 cacert.pem-rw-r--r-- 1 mysql mysql 3065 May 12 00:05 master.crt-rw-r--r-- 1 mysql mysql 647 May 12 00:05 master.csr-rw------- 1 mysql mysql 887 May 12 00:04 master.key# slave 主机上[root@stor2 ssl]\# lltotal 12-rw-r--r-- 1 mysql mysql 960 May 12 00:10 cacert.pem-rw-r--r-- 1 mysql mysql 0 May 12 00:10 slave.crt-rw-r--r-- 1 mysql mysql 647 May 12 00:09 slave.csr-rw------- 1 mysql mysql 891 May 12 00:06 slave.key
修改配置文件
修改Master
和Slave
主机配置文件:
# 在 [mysqld] 段添加以下内容# ------------ Master 主机 ------------server-id=1log-bin=mysql-binbinlog-do-db=testbinlog-ignore-db=mysqlrelay-log=mysql-relayauto-increment-increment=2auto-increment-offset=1
sslssl-ca=/usr/local/mysql/ssl/cacert.pemssl-cert=/usr/local/mysql/ssl/master.crtssl-key=/usr/local/mysql/ssl/master.key
# ------------ Slave 主机 ------------server-id=2log-bin=mysql-binrelay-log=mysql-relayskip-slave-start=1ssl
完成后保存退出,然后都重启服务,systemctl restart mariadb
在Master
主机进行查看:
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/master.crt || ssl_cipher | || ssl_key | /usr/local/mysql/ssl/master.key |+---------------+---------------------------------+7 rows in set (0.01 sec)
在Master
主机上创建具有复制权限的用户并授权给从服务器,参考上面的主从,这里就不再赘述。
查看Master
主机状态信息并记录下来:
mysql> show master status\G*************************** 1. row *************************** File: mysql-bin.000005 Position: 245 Binlog_Do_DB: testBinlog_Ignore_DB: mysql1 row in set (0.00 sec)
配置Slave
端:
mysql> CHANGE MASTER TO MASTER_HOST='172.16.1.128',MASTER_USER='backup',MASTER_PASSWORD='123',MASTER_LOG_FILE='mysql-bin.000005',MASTER_LOG_POS=245,MASTER_SSL=1,MASTER_SSL_CA='/usr/local/mysql/ssl/cacert.pem',MASTER_SSL_CERT='/usr/local/mysql/ssl/slave.crt',MASTER_SSL_KEY='/usr/local/mysql/ssl/slave.key';
:warning:注意:如果之前已经启动过slave
和配置过slave
需要将其停掉,并重置:
mysql> stop slave;Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> reset slave;Query OK, 0 rows affected (0.03 sec)
在slave
客户端使用 SSL 进行测试连接:
[root@stor2 ssl]\# mysql --ssl-ca=/usr/local/mysql/ssl/cacert.pem --ssl-cert=/usr/local/mysql/ssl/slave.crt --ssl-key=/usr/local/mysql/ssl/slave.key -ubackup -h172.16.1.128 -p123...mysql> \s--------------mysql Ver 15.1 Distrib 5.5.65-MariaDB, for Linux (x86_64) using readline 5.1
Connection id: 5Current database:Current user: backup@172.16.1.136SSL: Cipher in use is DHE-RSA-AES256-GCM-SHA384Current pager: stdoutUsing outfile: ''Using delimiter: ;Server: MariaDBServer version: 5.5.65-MariaDB MariaDB ServerProtocol version: 10Connection: 172.16.1.128 via TCP/IPServer characterset: latin1Db characterset: latin1Client characterset: utf8Conn. characterset: utf8TCP port: 3306Uptime: 3 min 40 sec
Threads: 2 Questions: 16 Slow queries: 0 Opens: 0 Flush tables: 2 Open tables: 26 Queries per second avg: 0.072--------------
启动slave
并查看状态信息:
mysql> start slave;mysql> show slave status\G*************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 172.16.1.128 Master_User: backup Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000006 Read_Master_Log_Pos: 245 Relay_Log_File: mysql-relay.000003 Relay_Log_Pos: 529 Relay_Master_Log_File: mysql-bin.000006 Slave_IO_Running: Yes Slave_SQL_Running: Yes...
测试主从同步:
-- 在 Master 主机上创建一个测试表yyymysql> create table test.yyy(id INT(12),name VARCHAR(25));-- 在 Slave 端进行查看mysql> show tables;+----------------+| Tables_in_test |+----------------+| tb_mobile || test || xxx || `yyy` |+----------------+4 rows in set (0.00 sec)
基于 SSL 加密传输(双主)
参考[基于 SSL 加密传输(主从)](#基于 SSL 加密传输(主从))