读写分离
复制:每个节点都有相同的数据集
向外扩展
二进制日志
单向
复制的功用:
数据分布
负载均衡读
备份
高可用和故障切换
MySQL升级测试
主从复制:主节点将数据同步到多个从节点
级联复制:主节点将数据同步到一个从节点,其他的从节点在向从节点复制数据
同步复制:将数据从主节点全部同步到从节点时才返回给用户的复制策略叫同步复制
异步复制:只要数据写入到主节点就立即返回给用户同步完成
读写分离:在前端加一个调度器,负责将改变数据的语句和查询数据的语句分开调度,把写操作调度到主节点,读操作调度到从节点
主节点:
dump Thread:为每个Slave的I/O Thread启动一个dump线程,用于向其发送binary log events
从节点:
I/O Thread:向Master请求二进制日志事件,并保存于中继日志中
SQL Thread:从中继日志中读取日志事件,在本地完成重放
跟复制功能相关的文件:
master.info:用于保存slave连接至master时的相关信息,例如账号、密码、服务器地址等
relay-log.info(中继日志):保存在当前slave节点上已经复制的当前二进制日志和本地replay log日志的对应关系
复制架构:
一主一从
一主多从
主主复制
环状复制
级联复制
多主一从
主服务器配置
~]# vim /etc/my.cnf [mysqld] log_bin binlog_format=ROW server_id=1~]# systemctl restart mariadb~]# mysqlMariaDB [(none)]> grant replication slave on *.* to lv(从服务接收的用户)@‘192.168.130.%‘ identified by ‘centos‘; #授权同步账号Query OK, 0 rows affected (0.01 sec)MariaDB [(none)]> show master logs;+--------------------+-----------+| Log_name | File_size |+--------------------+-----------+| mariadb-bin.000001 | 19578633 || mariadb-bin.000002 | 395 | #记录此位置,从服务器从这里开始同步+--------------------+-----------+2 rows in set (0.00 sec)
? 2)从服务器配置
~]# vim /etc/my.cnf [mysqld] server_id=2 #服务器ID唯一 relay_log=relay-log #relay log的文件路径,默认值hostname-relay-bin relay_log_index=relay-log.index #默认值hostname-relay-bin.index read_only=ON~]# systemctl restart mariadb #重启服务~]# mysqlMariaDB [(none)]> CHANGE MASTER TO -> MASTER_HOST=‘192.168.130.8‘, #指定主节点IP -> MASTER_USER=‘lv‘, #同步用户的用户名 -> MASTER_PASSWORD=‘centos‘, #同步用户的密码 -> MASTER_PORT=3306, #数据库的端口号 -> MASTER_LOG_FILE=‘mariadb-bin.000002‘, #以上记录的文件
-> MASTER_LOG_POS=395, #位置
-> MASTER_CONNECT_RETRY=10; #重试时间10秒
MariaDB [(none)]> START SLAVE; #开始主从复制
? 3)测试
在主节点上生成一些数据:MariaDB [(none)]> CREATE DATABASE testdb;MariaDB [(none)]> use testdbMariaDB [testdb]> create table testlog (id int auto_increment primary key,name char(20),age int default 20);MariaDB [testdb]> delimiter $$MariaDB [testdb]> create procedure pro_testlog() -> begin -> declare i int; -> set i = 1; -> while i < 100000 -> do insert into testlog(name,age) values (concat(‘testuser‘,i),i); -> set i = i +1; -> end while; -> end$$MariaDB [testdb]> delimiter ;MariaDB [testdb]> START TRANSACTION;MariaDB [testdb]> CALL pro_testlog;MariaDB [testdb]> COMMIT;
在从节点上查看同步情况:MariaDB [(none)]> SELECT COUNT(*) FROM testdb.testlog;+----------+| COUNT(*) |+----------+| 99999 | #同步成功+----------+MariaDB [(none)]> SHOW SLAVE STATUS\G*************************** 1. row **************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.130.8 Master_User: lv Master_Port: 3306 Connect_Retry: 10 Master_Log_File: mariadb-bin.000002 Read_Master_Log_Pos: 10389814 Relay_Log_File: relay-log.000002 Relay_Log_Pos: 10389944 Relay_Master_Log_File: master1-bin.000002 Slave_IO_Running: Yes #IO线程已启动 Slave_SQL_Running: Yes #SQL线程已启动 Seconds_Behind_Master: 0 #主从复制的时间差 Master_Server_Id: 1
? 1)主服务器配置
~]# vim /etc/my.cnf [mysqld] log_bin binlog_format=ROW log-basename=master1 server_id=1 #为当前节点设置一个全局惟的ID号~]# systemctl restart mariadb~]# mysqldump -uroot -pcentos -A -F --single-transaction --master-data=1 > full.sql~]# scp full.sql root@192.168.130.7:/root/~]#mysqlMariaDB [(none)]> GRANT REPLICATION SLAVE ON *.* TO testuser(从服务接收的用户)@‘192.168.130.7‘ IDENTIFIED BY ‘centos‘;
? 2)从服务器配置~]# vim /etc/my.cnf
[mysqld] server_id=2 #为当前节点设置一个全局惟的ID号 relay_log=relay-log read_only=ON~]# systemctl restart mariadb~]# vim full.sql #在备份的SQL文件中加入以下信息CHANGE MASTERTO MASTER_HOST=‘192.168.130.8‘,MASTER_USER=‘testuser‘,MASTER_PASSWORD=‘centos‘,MASTER_PORT=3306,MASTER_LOG_FILE=‘mariadb-bin.000003‘,# 已默认的MASTER_LOG_POS=245, #已默认的MASTER_CONNECT_RETRY=10;~]# mysql < full.sql #导入SQL的同时配置已经完成MariaDB [(none)]> SELECT COUNT(*) FROM testdb.testlog;+----------+| COUNT(*) |+----------+| 99999 |+----------+MariaDB [(none)]> START SLAVE; #启动同步复制MariaDB [(none)]> show slave status\G;*************************** 1. row ***************************Slave_IO_State: Waiting for master to send eventMaster_Host: 192.168.130.8Master_User: testuserMaster_Port: 3306Connect_Retry: 10Master_Log_File: mariadb-bin.000003Read_Master_Log_Pos: 401Relay_Log_File: relay-log.024649Relay_Log_Pos: 531Relay_Master_Log_File: mariadb-bin.000003Slave_IO_Running: Yes #IO线程已启动
Slave_SQL_Running: Yes #SQL线程已启动Seconds_Behind_Master: 0 #主从复制的时间差Master_Server_Id: 1
1)主节点
[root@master ~]# vim /etc/my.cnf[mysqld]log_binbinlog_format=ROWserver_id=1[root@master ~]# systemctl restart mariadbMariaDB [(none)]> GRANT REPLICATION SLAVE ON *.* TO testuser@‘192.168.130.%‘ IDENTIFIED BY ‘centos‘;MariaDB [(none)]> SHOW MASTER LOGS;
+--------------------+-----------+
| Log_name | File_size |
+--------------------+-----------+
| mariadb-bin.000001 | 19578756 |
| mariadb-bin.000002 | 401 |
+--------------------+-----------+
2 rows in set (0.00 sec)
2)从节点
[root@slave1 ~]# vim /etc/my.cnf[mysqld]log_bin #注意,级联架构中中继从节点一定得开二进制日志功能binlog_format=ROWread_only=ONserver_id=2log_slave_updates #这项为关键,作用是将从服务的数据改变记录到二进制日志文件中relay_log=relay-logrelay_log_index=relay-log.index[root@slave1 ~]# systemctl start mariadbMariaDB [(none)]> CHANGE MASTER TO -> MASTER_HOST=‘192.168.130.10‘, -> MASTER_USER=‘testuser‘, -> MASTER_PASSWORD=‘ccentos‘, -> MASTER_PORT=3306, -> MASTER_LOG_FILE=‘mariadb-bin.000002‘, -> MASTER_LOG_POS=401, -> MASTER_CONNECT_RETRY=10;MariaDB [(none)]> START SLAVE;MariaDB [(none)]> show master logs;+--------------------+-----------+| Log_name | File_size |+--------------------+-----------+| mariadb-bin.000001 | 19578633 || mariadb-bin.000002 | 10389327 || mariadb-bin.000003 | 1792 || mariadb-bin.000004 | 264 || mariadb-bin.000005 | 245 |+--------------------+-----------+5 rows in set (0.00 sec)MariaDB [(none)]> GRANT REPLICATION SLAVE ON *.* TO testuser@‘192.168.0.%‘ IDENTIFIED BY ‘centos‘;
3)从节点的从节点
[root@slave2 ~]# vim /etc/my.cnf[mysqld]read_only=ONserver_id=3relay_log=relay-logrelay_log_index=relay-log.index[root@slave2 ~]# systemctl start mariadbMariaDB [(none)]> CHANGE MASTER TO -> MASTER_HOST=‘192.168.130.8‘, -> MASTER_USER=‘testuser‘, -> MASTER_PASSWORD=‘centos‘, -> MASTER_PORT=3306, -> MASTER_LOG_FILE=‘mariadb-bin.000005‘, -> MASTER_LOG_POS=245, -> MASTER_CONNECT_RETRY=10;MariaDB [(none)]> START SLAVE;
4)测试
在主节点上生成一些数据:MariaDB [(none)]> CREATE DATABASE testdb; MariaDB [(none)]> use testdb MariaDB [testdb]> create table testlog (id int auto_increment primary key,name char(20),age int default 20); MariaDB [testdb]> delimiter $$ MariaDB [testdb]> create procedure pro_testlog() -> begin -> declare i int; -> set i = 1; -> while i < 100000 -> do insert into testlog(name,age) values (concat(‘testuser‘,i),i); -> set i = i +1; -> end while; -> end$$ MariaDB [testdb]> delimiter ; MariaDB [testdb]> START TRANSACTION; MariaDB [testdb]> CALL pro_testlog; MariaDB [testdb]> COMMIT;
在从节点上查看同步情况:MariaDB [(none)]> SELECT COUNT(*) FROM testdb.testlog;+----------+| COUNT(*) |+----------+| 99999 | #同步成功+----------+MariaDB [(none)]> SHOW SLAVE STATUS\G*************************** 1. row ***************************Slave_IO_State: Waiting for master to send eventMaster_Host: 192.168.130.10Master_User: testuserMaster_Port: 3306Connect_Retry: 10Master_Log_File: mariadb-bin.000002Read_Master_Log_Pos: 401Relay_Log_File: relay-log.000004Relay_Log_Pos: 531Relay_Master_Log_File: mariadb-bin.000002Slave_IO_Running: Yes #IO线程已启动Slave_SQL_Running: Yes #SQL线程已启动Seconds_Behind_Master: 0 #主从复制的时间差Master_Server_Id: 1
在从节点的从节点上查看同步情况:MariaDB [(none)]> SELECT COUNT(*) FROM testdb.testlog;+----------+| COUNT(*) |+----------+| 99999 | #同步成功+----------+MariaDB [(none)]> SHOW SLAVE STATUS\G*************************** 1. row ***************************Slave_IO_State: Waiting for master to send eventMaster_Host: 192.168.130.8Master_User: testuserMaster_Port: 3306Connect_Retry: 10Master_Log_File: mariadb-bin.000005Read_Master_Log_Pos: 401Relay_Log_File: relay-log.000002Relay_Log_Pos: 687Relay_Master_Log_File: mariadb-bin.000005Slave_IO_Running: Yes #IO线程已启动Slave_SQL_Running: Yes #SQL线程已启动Seconds_Behind_Master: 0 #主从复制的时间差Master_Server_Id: 1
容易产生的问题:数据不一致,因此慎用;考虑要点:自动增长id配置一个节点使用奇数idauto_increment_offset=1 开始点auto_increment_increment=2 增长幅度另一个节点使用偶数idauto_increment_offset=2auto_increment_increment=2
? 默认情况下,MySQL的复制功能是异步的,异步复制可以提供最佳的性能,主库把binlog日志发送给从库即结束,并不验证从库是否接收完毕。这意味着当主服务器或从服务器端发生故障时,有可能从服务器没有接收到主服务器发送过来的binlog日志,这就会造成主服务器和从服务器的数据不一致,甚至在恢复时造成数据的丢失;半同步复制的机制是只有当主节点和从节点同步完成,仅有一台同步完成即可,返回写入完成,这样的机制保证了数据的安全性。

1)主节点
[root@master ~]# vim /etc/my.cnf[mysqld]log_binbinlog_format=ROWlog-basename=masterserver_id=1relay_log=relay-logrelay_log_index=relay-log.index[root@master ~]# systemctl restart mariadbMariaDB [(none)]> GRANT REPLICATION SLAVE ON *.* TO testuser@‘192.168.0.%‘ IDENTIFIED BY ‘centos‘;MariaDB [(none)]> SHOW MASTER LOGS;+--------------------+-----------+| Log_name | File_size |+--------------------+-----------+| mariadb-bin.000001 | 19578756 || mariadb-bin.000002 | 586 || mariadb-bin.000003 | 401 |+--------------------+-----------+MariaDB [(none)]> INSTALL PLUGIN rpl_semi_sync_master SONAME ‘semisync_master.so‘; #安装模块MariaDB [(none)]> SET GLOBAL rpl_semi_sync_master_enabled=1; #开启半同步功能MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE ‘%semi%‘;+------------------------------------+-------+| Variable_name | Value |+------------------------------------+-------+| rpl_semi_sync_master_enabled | ON | #已开启| rpl_semi_sync_master_timeout | 10000 || rpl_semi_sync_master_trace_level | 32 || rpl_semi_sync_master_wait_no_slave | ON |+------------------------------------+-------+MariaDB [(none)]> SHOW GLOBAL STATUS LIKE ‘%semi%‘;+--------------------------------------------+-------+| Variable_name | Value |+--------------------------------------------+-------+| Rpl_semi_sync_master_clients | 0 || 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 |+--------------------------------------------+-------+
2)从节点1
[root@slave1 ~]# vim /etc/my.cnf[mysqld]read_only=ONlog_binbinlog_format=ROWlog-basename=slaveserver_id=2relay_log=relay-logrelay_log_index=relay-log.index[root@slave1 ~]# systemctl restart mariadbMariaDB [(none)]> CHANGE MASTER TO -> MASTER_HOST=‘192.168.130.10‘, -> MASTER_USER=‘testuser‘, -> MASTER_PASSWORD=‘centos‘, -> MASTER_PORT=3306, -> MASTER_LOG_FILE=‘master-bin.000003‘, -> MASTER_LOG_POS=401, -> MASTER_CONNECT_RETRY=10;MariaDB [(none)]> INSTALL PLUGIN rpl_semi_sync_slave SONAME ‘semisync_slave.so‘; #安装模块MariaDB [(none)]> SET GLOBAL rpl_semi_sync_slave_enabled=1; #开启半同步功能MariaDB [(none)]> START SLAVE;MariaDB [(none)]> SHOW MASTER LOGS;+------------------+-----------+| Log_name | File_size |+------------------+-----------+| slave-bin.000001 | 245 |+------------------+-----------+1 row in set (0.00 sec)MariaDB [(none)]> GRANT REPLICATION SLAVE ON *.* TO repluser@‘192.168.0.%‘ IDENTIFIED BY ‘replpass‘;
3)从节点2
[root@slave2 ~]# vim /etc/my.cnf[mysqld]read_only=ONserver_id=3relay_log=relay-logrelay_log_index=relay-log.index[root@slave2 ~]# systemctl restart mariadbMariaDB [(none)]> CHANGE MASTER TO -> MASTER_HOST=‘192.168.130.10‘, -> MASTER_USER=‘testuser‘, -> MASTER_PASSWORD=‘centos‘, -> MASTER_PORT=3306, -> MASTER_LOG_FILE=‘slave-bin.000001‘, -> MASTER_LOG_POS=245, -> MASTER_CONNECT_RETRY=10;MariaDB [(none)]> START SLAVE;当然,从服务器还可以有很多,此处到此为止。再按上面的测试一下就OK!
复制过滤器表示可以指定只复制指定的表或者只复制指定的库,其他的表和库都不进行复制,两种方法可以实现:
主服务器实现:主服务器指定只有指定的表或者库的修改信息才传递到从服务器的中继日志,但是主服务器出现问题之后会丢失未复制表和库的数据;不建议使用 (限定的二进制文件不会同步过来;这样做会使二进制数据造成丢失)
从服务器实现:所有二进制日志都传到从服务器的中继日志,但是sql_thread只执行指定表和库的修改语句,当主服务器出现故障,则不会丢失数据,所有建议采用从服务器的复制过滤;(将所有的二进制日志文件都复制过来,但在同步到自己的数据库时,会选择不同步限制条件的内容)
从服务器配置:SET GLOBAL replicate_do_db=库名 #指定只复制指定的库(相当于库的白名单)SET GLOBAL Replicate_Ignore_DB=库名 #指定不复制指定的库(相当于库的黑名单)SET GLOBAL Replicate_Do_Table=表名 #指定只复制指定表(相当于表的白名单)SET GLOBAL Replicate_Ignore_Table=表名 #指定不复制指定表(相当于表的黑名单)
当指定了复制过滤器后,通过SHOW SLAVE STATUS;命令可以查看到指定的库和表
建议此配置写入配置文件永久生效。
在默认的主从复制过程或远程连接到MySQL/MariaDB所有的链接通信中的数据都是明文的,外网里访问数据或则复制,存在安全隐患。通过SSL/TLS加密的方式进行复制的方法,来进一步提高数据的安全性
主服务器开启SSL:[mysqld] 加一行ssl主服务器配置证书和私钥;并且创建一个要求必须使用SSL连接的复制账号从服务器使用CHANGER MASTER TO 命令时指明ssl相关选项
参看:https://mariadb.com/kb/en/library/replication-with-secureconnections/
MariaDB [(none)]> SHOW VARIABLES LIKE ‘%ssl%‘;+---------------+----------+| Variable_name | Value |+---------------+----------+| have_openssl | DISABLED || have_ssl | DISABLED || ssl_ca | || ssl_capath | || ssl_cert | || ssl_cipher | || ssl_key | |+---------------+----------+
特别提示:在配置之前先检查mysql服务是否支持ssl功能,如果have_ssl的值为‘DISABLED‘则支持;如果为‘NO‘则不支持,需要再重新编译安装或者安装具有ssl功能的版本
1)CA
[root@CA ~]# mkdir /etc/my.cnf.d/ssl/[root@CA ~]# cd /etc/my.cnf.d/ssl/[root@CA ssl]# openssl genrsa 2048 > cakey.pem[root@CA ssl]# openssl req -new -x509 -key cakey.pem -out cacert.pem -days 3650 #自签证书 Country Name (2 letter code) [XX]:CN State or Province Name (full name) []:beijing Locality Name (eg, city) [Default City]:beijing Organization Name (eg, company) [Default Company Ltd]:testmysqlca Organizational Unit Name (eg, section) []:opt Common Name (eg, your name or your server‘s hostname) []:ca.testmysqlca.com[root@CA ssl]# openssl req -newkey rsa:2048 -days 365 -nodes -keyout master.key > master.csr Country Name (2 letter code) [XX]:CN State or Province Name (full name) []:beijing Locality Name (eg, city) [Default City]:beijing Organization Name (eg, company) [Default Company Ltd]:testmysqlca Organizational Unit Name (eg, section) []:opt Common Name (eg, your name or your server‘s hostname) []:master.testmysqlca.com[root@CA ssl]# openssl x509 -req -in master.csr -CA cacert.pem -CAkey cakey.pem -set_serial 01 > master.crt #签署master证书[root@CA ssl]# openssl req -newkey rsa:2048 -days 365 -nodes -keyout slave.key > slave.csr Country Name (2 letter code) [XX]:CN State or Province Name (full name) []:beijing Locality Name (eg, city) [Default City]:beijing Organization Name (eg, company) [Default Company Ltd]:testmysqlca Organizational Unit Name (eg, section) []:opt Common Name (eg, your name or your server‘s hostname) []:slave.testmysqlca.com[root@CA ssl]# openssl x509 -req -in slave.csr -CA cacert.pem -CAkey cakey.pem -set_serial 02 > slave.crt #签署slave证书[root@CA ssl]# openssl req -newkey rsa:2048 -days 365 -nodes -keyout slave2.key > slave2.csrCountry Name (2 letter code) [XX]:CNState or Province Name (full name) []:beijingLocality Name (eg, city) [Default City]:beijingOrganization Name (eg, company) [Default Company Ltd]:testmysqlcaOrganizational Unit Name (eg, section) []:optCommon Name (eg, your name or your server‘s hostname) []:slave2.testmysqlca.com[root@CA ssl]# openssl x509 -req -in slave2.csr -CA cacert.pem -CAkey cakey.pem -set_serial 03 > slave2.crt #签署slave2证书[root@CA ssl]# openssl verify -CAfile cacert.pem master.crt slave.crt slave2.crt #检查证书是否可用master.crt: OKslave.crt: OKslave2.crt: OK先在各个节点上创建/etc/my.cnf.d/ssl/文件夹,将各自的证书,CA的证书和各自的秘钥文件复制过去[root@CA ssl]# scp cacert.pem master.crt master.key root@192.168.0.7:/etc/my.cnf.d/ssl/[root@CA ssl]# scp cacert.pem slave.crt slave.key root@192.168.0.8:/etc/my.cnf.d/ssl/ [root@CA ssl]# scp cacert.pem slave2.crt slave2.key root@192.168.0.9:/etc/my.cnf.d/ssl/
2)master
[root@master ~]# mkdir /etc/my.cnf.d/ssl/[root@master ~]# vim /etc/my.cnf[mysqld]log_binbinlog_format=ROWlog-basename=masterserver_id=1ssl #开启ssl功能ssl-ca=/etc/my.cnf.d/ssl/cacert.pem #指定CA证书的路径ssl-cert=/etc/my.cnf.d/ssl/master.crt #指定自己的证书的路径ssl-key=/etc/my.cnf.d/ssl/master.key #指定自己的秘钥文件路径[root@master ~]# systemctl restart mariadbMariaDB [(none)]> GRANT REPLICATION SLAVE ON *.* TO repluser@‘192.168.0.%‘ IDENTIFIED BY ‘replpass‘ REQUIRE SSL; #授权用户并且强制迫使用户开启ssl登录MariaDB [(none)]> SHOW MASTER LOGS;+-------------------+-----------+| Log_name | File_size |+-------------------+-----------+| master-bin.000001 | 26753 || master-bin.000002 | 921736 || master-bin.000003 | 413 |+-------------------+-----------+
3)slave1
[root@slave1 ~]# mkdir /etc/my.cnf.d/ssl/[root@slave1 ~]# mysql -urepluser -preplpass -h192.168.0.7 --ssl-ca=/etc/my.cnf.d/ssl/cacert.pem --ssl-cert=/etc/my.cnf.d/ssl/slave.crt --ssl-key=/etc/my.cnf.d/ssl/slave.key[root@slave1 ~]# vim /etc/my.cnf[mysqld]read_only=ONserver_id=2relay_log=relay-logrelay_log_index=relay-log.indexsslssl-ca=/etc/my.cnf.d/ssl/cacert.pemssl-cert=/etc/my.cnf.d/ssl/slave.crtssl-key=/etc/my.cnf.d/ssl/slave.key[root@slave1 ~]# systemctl restart mariadbMariaDB [(none)]> CHANGE MASTER TO -> MASTER_HOST=‘192.168.0.7‘, -> MASTER_USER=‘repluser‘, -> MASTER_PASSWORD=‘replpass‘, -> MASTER_PORT=3306, -> MASTER_LOG_FILE=‘master-bin.000003‘, -> MASTER_LOG_POS=413, -> MASTER_CONNECT_RETRY=10, -> MASTER_SSL=1; #注意,需要指明开启ssl链接MariaDB [(none)]> START SLAVE;
4)slave2
[root@slave2 ~]# mkdir /etc/my.cnf.d/ssl/[root@slave2 ~]# mysql -urepluser -preplpass -h192.168.0.7 --ssl-ca=/etc/my.cnf.d/ssl/cacert.pem --ssl-cert=/etc/my.cnf.d/ssl/slave2.crt --ssl-key=/etc/my.cnf.d/ssl/slave2.key[root@slave2 ~]# vim /etc/my.cnf[mysqld]read_only=ONserver_id=3relay_log=relay-logrelay_log_index=relay-log.indexsslssl-ca=/etc/my.cnf.d/ssl/cacert.pemssl-cert=/etc/my.cnf.d/ssl/slave2.crtssl-key=/etc/my.cnf.d/ssl/slave2.key[root@slave2 ~]# systemctl restart mariadbMariaDB [(none)]> CHANGE MASTER TO -> MASTER_HOST=‘192.168.0.7‘, -> MASTER_USER=‘repluser‘, -> MASTER_PASSWORD=‘replpass‘, -> MASTER_PORT=3306, -> MASTER_LOG_FILE=‘master-bin.000003‘, -> MASTER_LOG_POS=413, -> MASTER_CONNECT_RETRY=10, -> MASTER_SSL=1;MariaDB [(none)]> START SLAVE;
选项:
log_bin 启用二进制日志,在主节点或级联复制中间的从节点必须要开启binlog_format=ROW 二进制日志记录方式为基于行的方式记录,强烈建议开启log-basename=master | slave ... 二进制日志的前缀名,不是必须向,但建议标识server_id = # 服务器ID,各个节点的ID必须唯一relay_log = relay-log 开启中继日志,并以relay-log为文件名开头,从节点开启relay_log_index = relay-log.index 中继日志索引文件log_slave_updates 作用是SQL线程重读中继日志时将改变数据的操作记录为二进制日志,在级联复制中使用ssl 开启ssl功能ssl-ca=/etc/my.cnf.d/ssl/cacert.pemssl-cert=/etc/my.cnf.d/ssl/master.crtssl-key=/etc/my.cnf.d/ssl/master.keysync_binlog=1 每次写后立即同步二进制日志到磁盘innodb_flush_log_at_trx_commit=1 每次事务提交立即同步日志写磁盘sync_master_info=# #次事件后master.info同步到磁盘skip_slave_start=ON 不自动启动slavesync_relay_log=# #次写后同步relay log到磁盘sync_relay_log_info=# #次事务后同步relay-log.info到磁盘auto_increment_offset=1 自动增长开始点,在主主复制中使用auto_increment_increment=2 增长幅度
变量:
replicate_do_db= 指定复制库的白名单replicate_ignore_db= 指定复制库黑名单replicate_do_table= 指定复制表的白名单replicate_ignore_table= 指定复制表的黑名单replicate_wild_do_table= foo%.bar% 支持通配符replicate_wild_ignore_table= 指定复制的表,黑名单rpl_semi_sync_slave_enabled=1 开启半同步复制,需要安装模块
指令:
START SLAVE; 启动主从复制STOP SLAVE; 停止复制SHOW SLAVE STATUS; 查看复制状态Seconds_Behind_Master: 0 从服务器是否落后于主服务RESET SLAVE ALL; 重置从服务器的配置MASTER_SSL=1, 配合 CHANGE MASTER TO 使用,开启ssl加密复制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‘;PURGE { BINARY | MASTER } LOGS { TO ‘log_name‘ | BEFORE datetime_expr } 删除二进制日志,谨慎操作SHOW MASTER STATUS 查看二进制日志状态SHOW BINLOG EVENTS 查看二进制日志SHOW BINARY LOGS 查看二进制日志SHOW PROCESSLIST 查看进程
MHA
工作原理
从宕机崩溃的master保存二进制日志事件(binlog events)识别含有最新更新的slave
应用差异的中继日志(relay log)到其他的slave 应用从master保存的二进制日志事件(binlog events) 提升一个slave为新的master 使其他的slave连接新的master进行复制
masterha_check_ssh 检查MHA的SSH配置状况masterha_check_repl 检查MySQL复制状况masterha_manger 启动MHAmasterha_check_status 检测当前MHA运行状态masterha_master_monitor 检测master是否宕机masterha_master_switch 故障转移(自动或手动)masterha_conf_host 添加或删除配置的server信息
Node工具包:这些工具通常由MHA Manager的脚本触发,无需人为操作)主 要包括以下几个工具:
save_binary_logs 保存和复制master的二进制日志
apply_diff_relay_logs 识别差异的中继日志事件并将其差异的事件应用 于其他的slave
purge_relay_logs 清除中继日志(不会阻塞SQL线程)
注意:为了尽可能的减少主库硬件损坏宕机造成的数据丢失,因此在配置MHA 的同时建议配置成MySQL 5.5的半同步复制
实现主从高可用MHA (在主服务器宕机时,自动将从服务器切换成主服务器来使用)
此功能只是一次性的,切换之后,功能就停用了,如果想启用需要再次开启此功能。
结构拓扑图:四台主机;manager,master,slave1,slave2 (管理者,主服务器,两个从服务器)
具体实验步骤:
1). 准备
selinux ,iptables ,time (此实验各台服务器的时间要保持一致)在vim /etc/npt.conf 添加server 172.20.0.1 iburstsystemctl start nptd
2) . 实现主从服务器的搭建
~]#vim /etc/my.cnf[mysqld]server_id=1log_binskip_name_resolve #跳过名字解析~]#systemctl start mariadb #重启服务mysql > grant replication slave on *.* to lv@’192.168.60.%’ identified by ‘centos’; #授权用户账号mysql > show master logs; #查看此时的二进制日志状态为后面从服务器同步时使用
3 ).在slave1服务器上
~]#vim /etc/my.cnf[mysqld]server_id=2log_binread_only=1relay_log_purge=0skip_name_resolve=1~]#systemctl start mariadb #重启服务mysql > CHANGE MASTER TO MASTER_HOST=’192.168.60.20′, MASTER_USER=’lv’, MASTER_PASSWORD=’centos’, MASTER_LOG_FILE=’mariadb-bin.000001′, MASTER_LOG_POS=394; #连接同步mysql > start slave #开启同步mysql > show slave status\G; #查看同步状态
4 ).在slave2服务器上:
~]#vim /etc/my.cnf[mysqld]server_id=3log_binread_only=1relay_log_purge=0skip_name_resolve=1~]#systemctl start mariadb #重启服务mysql > CHANGE MASTER TO MASTER_HOST=’192.168.60.20′, MASTER_USER=’lv’, MASTER_PASSWORD=’centos’, MASTER_LOG_FILE=’mariadb-bin.000001′, MASTER_LOG_POS=394; #连接同步mysql > start slave #开启同步mysql > show slave status\G; #查看同步状态
5 ). 在manager主机上:
实现基于key的验证:~]#ssh-keygen #生成私钥对~]#ssh-copy-id 192.168.60.4 #把自己的公钥复制到自己的机器上~]#cd .ssh #进到此目录下~]#scp -pr .ssh 192.168.60.20:/root/~]#scp -pr .ssh 192.168.60.21:/root/~]#scp -pr .ssh 192.168.60.22:/root/ #将公钥都复制到其他主机的家目录下
6) . 在master服务器上新建授权用户:
grant all on *.* to testuser@’192.168.130.%’ identified by ‘centos’; # 此账号由于是现在建立的他会自动同步到其他两个从服务器上
7 ). 在管理节点上安装两个包: mha4mysql-manager mha4mysql-node #manager服务器上安装
在被管理节点安装: mha4mysql-node #主从服务器上安装mha4mysql-manager-0.56-0.el6.noarch.rpm PublicDocuments mha4mysql-node-0.56-0.el6.noarch.rpm #网上下载两个包~]#yum install mha* #安装两个包,要依赖于epel源
8 ). 在主从的三个服务器上安装mha4mysql-manager-0.56-0.el6.noarch.rpm Public包
9). 在manager服务器上创建一个文件:mkdir /etc/mha
~]#vim /etc/mha/app1.cnf[server default]user=testuser #此为在第6步创建授权的用户password=centosmanager_workdir=/data/mastermha/app1/manager_log=/data/mastermha/app1/manager.logremote_workdir=/data/mastermha/app1/ssh_user=rootrepl_user=lvrepl_password=centosping_interval=1[server1]hostname=192.168.130.10 #主服务器的地址candidate_master=1[server2]hostname=192.168.130.7 #从服务器的地址candidate_master=1 #添加此行代表,主服务器宕机时此为备用的[server3]hostname=192.168.130.8
10). MHA验证和启动 (检查和验证)
~]#masterha_check_ssh –conf=/etc/mha/app1.conf #探测ssh协议能否连接成功~]#masterha_check_repl –conf=/etc/mha/app1.conf #检查复制功能检查复制功能时出现错误,提示lv用户没有复制的权限,添加上权限,在主服务器上:grant all on *.* to lv@’192.168.130.%’; 添加和后再查看一下权限:show grants for lv@’192.168.130.%’;~]#masterha_manager –conf=/etc/mha/app1.conf #开启监控功能此命令为前台运行命令,开启后是不会退出的,以此执行词条命令应该在终端上行,如果在远程上执行,连接断开会造成监控失败
排错日志: /data/mha/app1/manager.log