mariadb-10实现半同步复制及SSL安全复制
一、关于复制的相关问题
1、异步复制解决了那些问题
复制解决的基本问题是让一台服务器的数据和另外的服务器保持同步,可以位于不同的网络拓扑中,对整台服务器的特定的数据库,甚至特定的表进行复制。
基于语句复制和基于行复制,都是通过记录主服务器的二进制日志,并在从服务器上进行重放(replay)完成复制,它们都是异步进行的。
mariadb或mysql复制大部分都是向后兼容的。这意味着版本较新的服务器可以是版本老的服务器的从服务器。复制通常不会大幅增加服务器的开销,它需要主服务器启用二进制日志。复制对扩展读取有好处,可以将读指向到到从服务器上.
2、有了异步为什么还要用半同步复制
MySQL5.5之前版本的MySQL Replication都是异步(asynchronous)的,主库在执行完一些事务后,是不会管备库的进度的。如果备库不幸落后,而更不幸的是主库此时又出现Crash(例如宕机),这时备库中的数据就是不完整的。简而言之,在主库发生故障的时候,我们无法使用备库来继续提供数据一致的服务了。Semisynchronous Replication则一定程度上保证提交的事务已经传给了至少一个备库。
3. 为什么不是完全同步
Semi_synchronous中,仅仅保证事务的已经传递到备库上,但是并不确保已经在备库上执行完成了。
此外,还有一种情况会导致主备数据不一致。在某个session中,主库上提交一个事务后,会等待事务传递给至少一个备库,如果在这个等待过程中主库Crash,那么也可能备库和主库不一致,这是很致命的。(在主库恢复后,可以通过参数Rpl_semi_sync_master_no_tx观察)
4. 如果主备之间连接出现故障,主库是否会一直等待?
如果主备网络故障或者备库挂了,主库在事务提交后等待10秒(rpl_semi_sync_master_timeout的默认值)后,就会继续。这时,主库就会变回原来的异步状态
二、编译安装MariaDB
实验环境:
mysql服务器 | ip地址 | 软件版本 |
master | 172.16.8.7 | mariadb-10.0.10 |
slave | 172.16.8.9 | mariadb-10.0.10 |
下载地址:
由于mysql是基于 cmake编译的,所以要先安装cmake
[root@node3 local]# yum -y install cmake
主从服务器上分别安装MariaDB
# tar xf mariadb-10.0.10.tar.gz # cd mariadb-10.0.10 # cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_DATADIR=/mydata/data/ -DSYSCONFDIR=/etc -DWITH_INNOBASE_STORAGE_ENGINE=1 -DWITH_ARCHIVE_STPRAGE_ENGINE=1 -DWITH_BLACKHOLE_STORAGE_ENGINE=1 -DWIYH_READLINE=1 -DWIYH_SSL=system -DVITH_ZLIB=system -DWITH_LOBWRAP=0 -DMYSQL_UNIX_ADDR=/tmp/mysql.sock -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci # make && make install
初始化数据库。
# cd /usr/local/mysql/ # chown mysql.root * -R # ./scripts/mysql_install_db --user=mysql --datadir=/mydata/data/
提供配置文件
# cp support-files/my-large.cnf /etc/my.cnf //修改此的文件 thread_concurrency = 2 datadir=/mydata/data
准备启动脚本
# cp support-files/mysql.server /etc/rc.d/init.d/mysqld # chkconfig --add mysqld # chkconfig mysqld on
导出二进制文件
vim /etc/profile.d/mysql.sh
export PATH=/usr/local/mysql/bin:$PATH
三、半同步的实现过程
1、要想实现半同步复制,先得配置主从复制。
主服务器
修改配置文件
# vim /etc/my.cnf server-id = 1 //服务器通过server-id来判断是否是本机已经执行过的命令 log-bin= /mydata/logs/master-bin //建议将二进制文件不要和数据文件放在同一个目录中 innodb_file_per_table = ON //将innodb的表分开存放 sync_binlog = 1 //确保主从复制时的事务安全
创建二进制日志目录
[root@node4 mysql]# mkdir -p /mydata/logs/ [root@node4 mysql]# chown -R mysql.mysql /mydata/logs/
创建有复制权限的账号
MariaDB [(none)]> grant replication slave,replication client on *.* to ‘admin‘@‘172.16.8.9‘ identified by ‘admin‘; 授权用户复制权限 MariaDB [(none)]> flush privileges; 通知数据库重读授权库
从服务器
修改配置文件
# vim /etc/my.cnf #log-bin=mysql-bin //注释掉从服务器上的二进制文件日志,因为从服务器不会发生写操作,所有不需要开启二进制文件日志 server-id = 12 //修改从服务器上的server-id,一定不要跟主服务器一样 innodb_file_per_table = ON //将innodb的表分开存放 relay_log = /mydata/logs/slave-bin //开启中继日志, read-only=ON //仅能复制那也不具有super权限的用户无法执行写操作 sync_binlog = 1 //确保主从复制时的事务安全
创建中继日志目录:
[root@node4 mysql]# mkdir -p /mydata/logs/ [root@node4 mysql]# chown -R mysql.mysql /mydata/logs/
连接主服务器
MariaDB [(none)]> change master to master_host=‘172.16.8.7‘,master_user=‘admin‘,master_password=‘admin‘;
启动复制线程
MariaDB [(none)]> start slave; MariaDB [(none)]> show slave status\G;查看状态
2、半同步复制
半同步插件是由谷歌提供,具体位置/usr/local/mysql/lib/plugin/下,一个是master用的semisync_master.so,一个是slave用的semisync_slave.so
在master端上执行如下命令:
MariaDB [(none)]> install plugin rpl_semi_sync_master soname ‘semisync_master.so‘;
打开半同步复制功能semi_sync:
MariaDB [(none)]> set global rpl_semi_sync_master_enabled=1;
在slave端执行如下命令:
MariaDB [(none)]> install plugin rpl_semi_sync_slave soname ‘semisync_slave.so‘;
打开semi_sync功能:
MariaDB [(none)]>set global rpl_semi_sync_slave_enabled=1;
注:想要semi_sync功能永久生效,可以在配置文件中修改,添加这条语句:
rpl_semi_sync_slave_enabled=1
在master查看一下状态:
MariaDB [(none)]> 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)
注解:
Rpl_semi_sync_master_clients
记录支持半同步的slave的个数。
Rpl_semi_sync_master_net_avg_wait_time
master 等待slave 回复的平均等待时间。 单位毫秒.
Rpl_semi_sync_master_net_wait_time
master 总的等待时间。
Rpl_semi_sync_master_net_waits
master 等待slave 回复的的总的等待次数。
Rpl_semi_sync_master_no_times
master 关闭半同步复制的次数。
Rpl_semi_sync_master_no_tx
master 没有收到slave的回复而提交的次数,(应该可以理解为master 等待超时的次
数)
Rpl_semi_sync_master_status
标记master现在是否是半同步复制状态。
Rpl_semi_sync_master_tx_avg_wait_time
master 花在每个事务上的平均等待时间。
Rpl_semi_sync_master_tx_wait_time
master 总的等待次数。
Rpl_semi_sync_master_wait_sessions
当前有多少个session 因为sl ave 的回复而造成等待。
Rpl_semi_sync_master_yes_tx
master 成功接收到slave的回复的次数。
Rpl_semi_sync_slave_status
标记slave 是否在半同步状态。
在slave查看一下状态:
半同步复制已经启用!
四、基于安全(SSL)复制
注:
1、安全模式的复制数据库的版本是mariadb-10.0.10源码安装,并不是之前使用的通用二进制格式的,因为二进制格式不支持SSL,所以只能源码编译安装了
2、源码安装完成后,此处复制是基于主从复制的异步模式。
为什么要用到ssl,因为在主从复制过程或远程连接到mariadb所有的链接通信中的数据都是明文的,也就变得不安全了,所以要用到SSL,虽然SSL在前几天曝出高危漏洞,如果没有采取安全措施,一定会出损失,如果增加了安全措施一定会减小损失。所以说还是尽可能的增加安全意识,来保证我们的信息数据的安全。
4.1、在master做自签CA为所用的连接验证。
[root@node3 ~]# cd /etc/pki/CA [root@node3 CA]# (umask 077; openssl genrsa 1024 > private/cakey.pem) Generating RSA private key, 1024 bit long modulus ...................................................++++++ .......++++++ e is 65537 (0x10001) [root@node3 CA]# openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 3655 You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter ‘.‘, the field will be left blank. ----- Country Name (2 letter code) [XX]:cn State or Province Name (full name) []:henan Locality Name (eg, city) [Default City]:zz Organization Name (eg, company) [Default Company Ltd]:gulong Organizational Unit Name (eg, section) []:mysql Common Name (eg, your name or your server‘s hostname) []:ca.gulong.com Email Address []:admin@gulong.com [root@node3 CA]# mkdir newcerts/ crl/ certs/ [root@node3 CA]# touch index.txt serial [root@node3 CA]# echo 01 >serial
CA的自签证书到此建立完毕.
4.2、建立master的证书
[root@node3 CA]# mkdir /etc/master/ [root@node3 CA]# cd /etc/master/ [root@node3 master]# (umask 077;openssl genrsa 1024 >master.key) Generating RSA private key, 1024 bit long modulus ............................................................................++++++ .......................................................++++++ e is 65537 (0x10001) [root@node3 master]# openssl req -new -key master.key -out master.csr You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter ‘.‘, the field will be left blank. ----- Country Name (2 letter code) [XX]:cn State or Province Name (full name) []:henan Locality Name (eg, city) [Default City]:zz Organization Name (eg, company) [Default Company Ltd]:gulong Organizational Unit Name (eg, section) []:mysql Common Name (eg, your name or your server‘s hostname) []:master.gulong.com Email Address []: Please enter the following ‘extra‘ attributes to be sent with your certificate request A challenge password []: An optional company name []: [root@node3 master]# ls master.csr master.key [root@node3 master]# openssl ca -in master.csr -out master.crt -days 3655 [root@node3 master]# cp /etc/pki/CA/cacert.pem . [root@node3 master]# chown mysql.mysql master.crt master.key cacert.pem [root@node3 master]# ll total 16 -rw-r--r-- 1 mysql mysql 1046 May 2 16:10 cacert.pem -rw-r--r-- 1 mysql mysql 3221 May 2 16:09 master.crt -rw-r--r-- 1 root root 696 May 2 16:07 master.csr -rw------- 1 mysql mysql 887 May 2 16:05 master.key [root@node3 master]#
修改/etc/my.cnf开启支持SSL
//添加如下内容: [client] ssl_cipher = DHE-RSA-AES256-SHA [mysqld] ssl ssl_ca= /etc/master/cacert.pem ssl_cert = /etc/master/master.crt ssl_key = /etc/master/master.key
在master上看一下变量:
现在就可以有ssl登录了:
4.3、建立slave的证书
[root@node4 ~]# mkdir /etc/slave [root@node4 ~]# cd /etc/slave/ [root@node4 slave]# (umask 077;openssl genrsa 1024 > mysql.key) Generating RSA private key, 1024 bit long modulus ..............++++++ .........++++++ e is 65537 (0x10001) [root@node4 slave]# openssl req -new -key mysql.key -out mysql.csr You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter ‘.‘, the field will be left blank. ----- Country Name (2 letter code) [XX]:cn State or Province Name (full name) []:henan Locality Name (eg, city) [Default City]:zz Organization Name (eg, company) [Default Company Ltd]:gulong Organizational Unit Name (eg, section) []:mysql Common Name (eg, your name or your server‘s hostname) []:slave.gulong.com Email Address []: Please enter the following ‘extra‘ attributes to be sent with your certificate request A challenge password []: An optional company name []: [root@node4 slave]# scp mysql.csr 172.16.8.7:/tmp [root@node3 tmp]# openssl ca -in mysql.csr -out mysql.crt -days 3655 [root@node3 tmp]# scp mysql.crt 172.16.8.9:/etc/slave [root@node3 tmp]# scp /etc/pki/CA/cacert.pem 172.16.8.9:/etc/slave [root@node4 slave]# ls cacert.pem mysql.crt mysql.csr mysql.key [root@node4 slave]# chown mysql.mysql * [root@node4 slave]# ll total 16 -rw-r--r-- 1 mysql mysql 1046 May 3 00:45 cacert.pem -rw-r--r-- 1 mysql mysql 3142 May 3 00:42 mysql.crt -rw-r--r-- 1 mysql mysql 647 May 3 00:39 mysql.csr -rw------- 1 mysql mysql 887 May 3 00:38 mysql.key
连接master服务器
MariaDB [wow]> change master to master_host=‘172.16.8.7‘,master_user=‘admin‘,master_password=‘admin‘,master_ssl=1,master_ssl_ca=‘/etc/slave/cacert.pem‘,master_ssl_cert=‘/etc/slave/mysql.crt‘,master_ssl_key=‘/etc/slave/mysql.key‘;
查看状态:
MariaDB [wow]> show slave status\G;
至此,基于ssl的主从复制,已经演示完成,不足之处,请多加指点!