Mysql主从级联、半同步复制和加密

Mysql主从级联复制

配置主从级联复制时,作为中间节点的那个服务器需要额外做如下配置,以确保从服务器从主服务器哪里复制来的数据能记录二进制日志。
[mysqld]
log_bin
log_slave_updates

余下的从服务器需要指定该中间节点为主服务器。

复制架构中应该注意的问题

限制从服务器为只读

  • 在从服务器上设置read-only=ON
    注意:此限制对拥有super权限的用户均无效。
  • 阻止所有用户,包括主服务器复制的更新
    mysql> flush tables with read lock;

RESET SLAVE
在从服务器清除master.info,relay-log.info,relay log,开始新的relaylog,注意,需要先stop slave;
reset slave all 清除所有从服务器上设置的主服务器同步信息如:port,host,user,password等

sql_slave_skip_counter=N
从服务器忽略几个主服务器的复制时间,global变量。

如何保证主从复制的事务安全
在master节点启用参数

  • sync_binlog=1 每次写后立即同步二进制日知道磁盘,性能差
    如果用到的是innodb存储引擎
  • innodb_fush_log_at_trx_commit=1 每次事务提交立即同步日志写磁盘
  • innodb_support_xa=ON 默认值,分布式事务mariadb10.3.0废除
  • sync_master_info=# #次事件后master.info同步到磁盘

在slave节点启用服务器选项

  • skip_slave_start=ON 不自动启动slave

在slave节点启用参数

  • sync_relay_log=# #次写后同步relay log到磁盘
  • sync_relay_log_info=# #次事务后同步relay-log.info到磁盘

半同步复制

默认情况下,MySQL的复制功能是异步的,异步复制可以提供最佳的性能,主
库把binlog日志发送给从库即结束,并不验证从库是否接收完毕。这意味着当
主服务器或从服务器端发生故障时,有可能从服务器没有接收到主服务器发送
过来的binlog日志,这就会造成主服务器和从服务器的数据不一致,甚至在恢
复时造成数据的丢失

半同步复制的实现

主服务器配置:
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME ‘semisync_master.so’; #安装插件
mysql>SET GLOBAL rpl_semi_sync_master_enabled=1; #启用插件
mysql>SET GLOBAL rpl_semi_sync_master_timeout = 1000;超时长为1s
mysql>SHOW GLOBAL VARIABLES LIKE ‘%semi%’;
mysql>SHOW GLOBAL STATUS LIKE ‘%semi%‘;

从服务器配置:
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME ‘semisync_slave.so’;
mysql> SET GLOBAL rpl_semi_sync_slave_enabled=1;

如果要永久使用半同步复制功能,需要将启用插件写入配置文件
主服务器:

1
2
3
~]#vi /etc/my.cnf.d/server.cnf
[mysqld]
rpl_semi_sync_master_enabled

从服务器

1
2
3
~]#vi /etc/my.cnf.d/server.cnf
[mysqld]
rpl_semi_sync_slave_enabled

配置好主从服务器后,需要重启从服务器的线程

  • stop slave
  • start slave

复制过滤器

让从节点仅复制指定的数据库,或指定数据库的指定表。
实现方式有两种:
第一种实现方式
服务器选项:主服务器仅向二进制日志中记录与特定数据库相关的事件
注意:此项和binlog_format相关
参看:https://mariadb.com/kb/en/library/mysqld-options/#-binlogignore-db

  • binlog_do_db = 数据库白名单列表,多个数据库需多行实现
  • binlog_ignore_db = 数据库黑名单列表
    问题:基于二进制还原将无法实现;不建议使用

第二种是实现方式
从服务器SQL_THREAD在replay中继日志中的事件时,仅读取与特定数
据库(特定表)相关的事件并应用于本地
问题:会造成网络及磁盘IO浪费
从服务器上的复制过滤器相关变量

  • replicate_do_db= 指定复制库的白名单
  • replicate_ignore_db= 指定复制库黑名单
  • replicate_do_table= 指定复制表的白名单
  • replicate_ignore_table= 指定复制表的黑名单
  • replicate_wild_do_table= foo%.bar% 支持通配符
  • replicate_wild_ignore_table=

写入配置文件永久生效

1
2
3
4
5
~]#vi /etc/my.cnf.d/server.cnf
replicate_do_db=db1
replicate_do_db=db2
replicate_do_db=db3
...

Mysql复制加密

基于SSL复制:
在默认的主从复制过程或远程连接到MySQL/MariaDB所有的链接通信中的数据都是明文的,外网里访问数据或则复制,存在安全隐患。通过SSL/TLS加密的方式进行复制的方法,来进一步提高数据的安全性
配置实现:
参看:https://mariadb.com/kb/en/library/replication-with-secureconnections/

  • 主服务器开启SSL:[mysqld] 加一行ssl
  • 主服务器配置证书和私钥;并且创建一个要求必须使用SSL连接的复制账号
  • 从服务器使用CHANGER MASTER TO 命令时指明ssl相关选项

主服务器配置

1
2
3
4
5
6
7
8
~]#vi /etc/my.cnf.d/server.cnf
[mysqld]
log-bin
server_id=1
ssl
ssl-ca=/etc/my.cnf.d/ssl/cacert.pem
ssl-cert=/etc/my.cnf.d/ssl/master.crt
ssl-key=/etc/my.cnf.d/ssl/master.key

从服务器配置

1
2
3
4
5
6
7
8
9
10
11
mysql>
CHANGE MASTER TO
MASTER_HOST='MASTERIP',
MASTER_USER='rep',
MASTER_PASSWORD='centos',
MASTER_LOG_FILE='mariadb-bin.000001',
MASTER_LOG_POS=245,
MASTER_SSL=1,
MASTER_SSL_CA = '/etc/my.cnf.d/ssl/cacert.pem',
MASTER_SSL_CERT = '/etc/my.cnf.d/ssl/slave.crt',
MASTER_SSL_KEY = '/etc/my.cnf.d/ssl/slave.key';

证书申请过程
(umask 066;openssl genrsa 2048 > cakey.pem)
openssl req -new -x509 -key cakey.pem -out cacert.pem -days 3650
openssl req -newkey rsa:2048 -days 365 -nodes -keyout master.key > master.csr
openssl req -newkey rsa:2048 -days 365 -nodes -keyout slave.key > slave.csr
openssl x509 -req -in master.csr -CA cacert.pem -CAkey cakey.pem -set_serial 01 > master.crt
openssl x509 -in master.crt -noout -text
openssl x509 -req -in slave.csr -CA cacert.pem -CAkey cakey.pem -set_serial 02 > slave.crt

复制的监控和维护