用binlog恢复数据
MySQL的binlog是数据恢复,主从同步的关键日志;
binlog相关配置:
binlog_format 日志格式
log-bin 日志文件
expire_logs_days 过期清理时间
max_binlog_size 每个日志文件大小
binlog_cache_size 缓存大小
max_binlog_cache_size 最大缓存大小
binlog_do_db 指定要生成binlog的库
binlog_ignore_db 指定不要生成binlog的库
binlog_format 有3种模式:
STATEMENT 每一条会修改数据的sql语句会记录到binlog中;
ROW 不记录每条sql语句的上下文信息,仅需记录哪条数据被修改了,修改成什么样了;
MIXED 以上两种模式的混合使用,一般的复制使用STATEMENT模式保存binlog,对于STATEMENT模式无法复制的操作使用ROW模式保存binlog,MySQL会根据执行的SQL语句选择日志保存方式;
启用binlog之前清空表
mysql> truncate basic_info;
Query OK, 0 rows affected (0.02 sec)
启用binlog
[root@node1 ~]# vim /etc/my.cnf
[root@node1 ~]# cat /etc/my.cnf
...略
server-id=11
log-bin=master-bin
binlog_format=MIXED
[root@node1 ~]# systemctl restart mysqld
确认是否开启
[root@node1 ~]# mysql -u root -p
Enter password:
...略
mysql> show variables like "log_bin";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin | ON |
+---------------+-------+
1 row in set (0.00 sec)
mysql> show master logs;
+-------------------+-----------+
| Log_name | File_size |
+-------------------+-----------+
| master-bin.000001 | 154 |
+-------------------+-----------+
1 row in set (0.00 sec)
写入数据,修改数据,删除数据,清空表,后面恢复修改之前的数据
mysql> insert into basic_info(name,age) values('LiLei',18);
Query OK, 1 row affected (0.01 sec)
mysql> insert into basic_info(name,sex,age) values('HanMM','female',17);
Query OK, 1 row affected (0.01 sec)
mysql> insert into basic_info(name,age,hobby) values('Jhon',17,'basketball');
Query OK, 1 row affected (0.01 sec)
mysql> insert into basic_info(name,sex,age,profession,hobby) values('Sarah','female',19,'student','wrestle');
Query OK, 1 row affected (0.00 sec)
mysql> insert into basic_info(name,age,address) values('Ethan',16,'Woodlands');
Query OK, 1 row affected (0.00 sec)
mysql> update basic_info set profession='student',address='Red Hill' where name='Jhon';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> delete from basic_info where age>18;
Query OK, 1 row affected (0.01 sec)
mysql> truncate basic_info;
Query OK, 0 rows affected (0.12 sec)
查看binlog日志
mysql> show master logs;
+-------------------+-----------+
| Log_name | File_size |
+-------------------+-----------+
| master-bin.000001 | 2835 |
+-------------------+-----------+
1 row in set (0.00 sec)
mysql> show master status;
+-------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master-bin.000001 | 2835 | | | |
+-------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
mysql> show binlog events in 'master-bin.000001';
+-------------------+------+----------------+-----------+-------------+------------------------------------------------------------------------------------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+-------------------+------+----------------+-----------+-------------+------------------------------------------------------------------------------------------------------------------------+
...略
| master-bin.000001 | 340 | Query | 11 | 475 | use `customers`; insert into basic_info(name,age) values('LiLei',18)
...略
| master-bin.000001 | 1829 | Query | 11 | 1984 | use `customers`; insert into basic_info(name,age,address) values('Ethan',16,'Woodlands') |
| master-bin.000001 | 1984 | Xid | 11 | 2015 | COMMIT /* xid=17 */ |
...略
根据position值来恢复数据
[root@node1 ~]# mysqlbinlog --start-position=340 --stop-position=1984 --database=customers /var/lib/mysql/master-bin.000001 | mysql -u root -p customers
Enter password:
查看数据
[root@node1 ~]# mysql -u root -p
Enter password:
...略
mysql> select * from customers.basic_info;
+-----+-------+--------+-----+------------+------------+---------+
| uid | name | sex | age | profession | hobby | address |
+-----+-------+--------+-----+------------+------------+---------+
| 1 | LiLei | male | 18 | NULL | NULL | NULL |
| 2 | HanMM | female | 17 | NULL | NULL | NULL |
| 3 | Jhon | male | 17 | NULL | basketball | NULL |
| 4 | Sarah | female | 19 | student | wrestle | NULL |
+-----+-------+--------+-----+------------+------------+---------+
4 rows in set (0.00 sec)
主从数据库
从库会自动从主库同步数据,使MySQL高可用,数据更不易丢失;
这里用node1作为MySQL主库,node2和node3作为从库;
node1 配置不变,开启binlog即可;
node2 安装配置
[root@node2 ~]# yum install -y mysql-community-server
...略
[root@node2 ~]# systemctl start mysqld
[root@node2 ~]# systemctl enable mysqld
[root@node2 ~]# grep password /var/log/mysqld.log
2020-07-04T00:09:06.627041Z 1 [Note] A temporary password is generated for root@localhost: 7iEtGlgrq3=4
[root@node2 ~]# mysql_secure_installation
...略
[root@node2 ~]# vim /etc/my.cnf
[root@node2 ~]# cat /etc/my.cnf
...略
server-id=12
log_slave_updates=1
relay_log=slave-relay-bin
relay_log_recovery=1
read_only=1
[root@node2 ~]# systemctl restart mysqld
node3 跟 node2 一样安装配置, 除了server-id 改为13
node1 主库设置
[root@node1 ~]# mysql -u root -p
Enter password:
...略
mysql> grant replication slave on *.* to 'replicer'@'10.0.0.%' identified by 'Replica111!';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)
mysql> show master status;
+-------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master-bin.000002 | 895 | | | |
+-------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
node2 和 node3 从库设置
[root@node2 ~]# mysql -u root -p
Enter password:
...略
mysql> change master to master_host='10.0.0.11',master_port=3306,master_user='replicer',master_password='Replica111!',master_log_file='master-bin.000002',master_log_pos=895;
Query OK, 0 rows affected, 2 warnings (0.04 sec)
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 10.0.0.11
Master_User: replicer
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: master-bin.000002
Read_Master_Log_Pos: 895
Relay_Log_File: slave-relay-bin.000002
Relay_Log_Pos: 321
Relay_Master_Log_File: master-bin.000002
Slave_IO_Running: Yes # slave 状态
Slave_SQL_Running: Yes # slave 状态
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: 895
Relay_Log_Space: 528
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: 0 # slave 状态
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: 11
Master_UUID: a739b13a-bc42-11ea-92fb-080027e88dbb
Master_Info_File: /var/lib/mysql/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
1 row in set (0.00 sec)
ERROR:
No query specified
可以通过上面表示的几个状态判定从库状态
主库创建数据库,用于保存网站状态数据
[root@node1 ~]# mysql -u root -p
Enter password:
...略
mysql> create database websites default charset utf8 collate utf8_general_ci;
Query OK, 1 row affected (0.00 sec)
mysql> use websites;
Database changed
mysql> create table site_status( wid int not null auto_increment primary key, name char(30) not null, address char(50) not null, acquired_time datetime not null, status char(10) not null)engine=innodb default charset=utf8;
Query OK, 0 rows affected (0.03 sec)
写入数据
mysql> use websites;
Database changed
mysql> insert into site_status(name,address,acquired_time,status) values("阿里巴巴开源镜像站","https://developer.aliyun.com/mirror/","2020-07-04 10:19:57","online");
Query OK, 1 row affected (0.01 sec)
mysql> insert into site_status(name,address,acquired_time,status) values("网易开源镜像站","http://mirrors.163.com/","2020-07-04 10:19:58","online");
Query OK, 1 row affected (0.01 sec)
mysql> insert into site_status(name,address,acquired_time,status) values("清华大学开源软件镜像站","https://mirrors.tuna.tsinghua.edu.cn/","2020-07-04 10:20:25","online");
Query OK, 1 row affected (0.01 sec)
mysql> select * from site_status;
+-----+-----------------------------------+---------------------------------------+---------------------+--------+
| wid | name | address | acquired_time | status |
+-----+-----------------------------------+---------------------------------------+---------------------+--------+
| 1 | 阿里巴巴开源镜像站 | https://developer.aliyun.com/mirror/ | 2020-07-04 10:19:57 | online |
| 2 | 网易开源镜像站 | http://mirrors.163.com/ | 2020-07-04 10:19:58 | online |
| 3 | 清华大学开源软件镜像站 | https://mirrors.tuna.tsinghua.edu.cn/ | 2020-07-04 10:20:25 | online |
+-----+-----------------------------------+---------------------------------------+---------------------+--------+
3 rows in set (0.00 sec)
查看是否同步到从库
[root@node3 ~]# mysql -u root -p
Enter password:
...略
mysql> select * from websites.site_status;
+-----+-----------------------------------+---------------------------------------+---------------------+--------+
| wid | name | address | acquired_time | status |
+-----+-----------------------------------+---------------------------------------+---------------------+--------+
| 1 | 阿里巴巴开源镜像站 | https://developer.aliyun.com/mirror/ | 2020-07-04 10:19:57 | online |
| 2 | 网易开源镜像站 | http://mirrors.163.com/ | 2020-07-04 10:19:58 | online |
| 3 | 清华大学开源软件镜像站 | https://mirrors.tuna.tsinghua.edu.cn/ | 2020-07-04 10:20:25 | online |
+-----+-----------------------------------+---------------------------------------+---------------------+--------+
3 rows in set (0.00 sec)
成功同步数据。
主从切换
模拟主库故障,将从库升级为主库;
关闭主库
[root@node1 ~]# systemctl stop mysqld
从库(node2和node3)关闭io线程
[root@node2 ~]# mysql -u root -p
Enter password:
...略
mysql> stop slave io_thread;
Query OK, 0 rows affected (0.00 sec)
查看relay log是否被完全读取并执行完毕
mysql> show processlist;
+----+-------------+-----------+------+---------+------+--------------------------------------------------------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+-------------+-----------+------+---------+------+--------------------------------------------------------+------------------+
| 2 | system user | | NULL | Connect | 607 | Slave has read all relay log; waiting for more updates | NULL |
| 4 | root | localhost | NULL | Query | 0 | starting | show processlist |
+----+-------------+-----------+------+---------+------+--------------------------------------------------------+------------------+
2 rows in set (0.00 sec)
对比两个从库的Master_log_pos值,值较大的作为新的主库
[root@node2 ~]# cat /var/lib/mysql/master.info
25
master-bin.000004
3538 # Master_log_pos
10.0.0.11
replicer
Replica111!
3306
60
...略
我这里值是一样的,将node2选为新的主库
将node2切换成主库
[root@node2 ~]# mysql -u root -p
Enter password:
...略
mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)
mysql> drop table mysql.slave_master_info;
Query OK, 0 rows affected (0.01 sec)
mysql> grant replication slave on *.* to 'replicer2'@'10.0.0.%' identified by 'Replica111!';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
mysql> exit
Bye
[root@node2 ~]# rm -f /var/lib/mysql/relay-log.info
[root@node2 ~]# vim /etc/my.cnf
[root@node2 ~]# cat /etc/my.cnf
...略
server-id=12
log-bin=new-master-bin
#log_slave_updates=1
#relay_log=slave-relay-bin
#relay_log_recovery=1
#read_only=1
[root@node2 ~]# systemctl restart mysqld
[root@node2 ~]# mysql -uroot -p
Enter password:
...略
mysql> reset master;
Query OK, 0 rows affected (0.02 sec)
mysql> show master status;
+-----------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-----------------------+----------+--------------+------------------+-------------------+
| new-master-bin.000001 | 601 | | | |
+-----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
修改node3从库的主库信息
[root@node3 ~]# mysql -u root -p
Enter password:
...略
mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)
mysql> change master to master_host='10.0.0.12',master_port=3306,master_user='replicer2',master_password='Replica111!',master_log_file='new-master-bin.000001',master_log_pos=601;
Query OK, 0 rows affected, 2 warnings (0.02 sec)
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 10.0.0.12
Master_User: replicer2
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: new-master-bin.000001
Read_Master_Log_Pos: 601
Relay_Log_File: slave-relay-bin.000002
Relay_Log_Pos: 325
Relay_Master_Log_File: new-master-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
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: 601
Relay_Log_Space: 532
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: 0
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: 12
Master_UUID: 933d7e7d-bd8a-11ea-bd03-080027b7d17f
Master_Info_File: /var/lib/mysql/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
1 row in set (0.00 sec)
ERROR:
No query specified
原本的主库node1此时将其修改为从库
[root@node1 ~]# vim /etc/my.cnf
[root@node1 ~]# cat /etc/my.cnf
..略
server-id=11
#log-bin=master-bin
#binlog_format=MIXED
log_slave_updates=1
relay_log=slave-relay-bin
relay_log_recovery=1
read_only=1
[root@node1 ~]# systemctl start mysqld
[root@node1 ~]# mysql -u root -p
Enter password:
..略
mysql> change master to master_host='10.0.0.12',master_port=3306,master_user='replicer2',master_password='Replica111!',master_log_file='new-master-bin.000001',master_log_pos=601;
Query OK, 0 rows affected, 2 warnings (0.04 sec)
mysql> start slave;
Query OK, 0 rows affected (0.01 sec)
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 10.0.0.12
Master_User: replicer2
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: new-master-bin.000001
Read_Master_Log_Pos: 601
Relay_Log_File: slave-relay-bin.000002
Relay_Log_Pos: 325
Relay_Master_Log_File: new-master-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
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: 601
Relay_Log_Space: 532
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: 0
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: 12
Master_UUID: 933d7e7d-bd8a-11ea-bd03-080027b7d17f
Master_Info_File: /var/lib/mysql/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
1 row in set (0.00 sec)
ERROR:
No query specified
主库写入数据测试
[root@node2 ~]# mysql -uroot -p
Enter password:
...略
mysql> use websites;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> insert into site_status(name,address,acquired_time,status) values("中国科学技术大学开源镜像站","https://mirrors.ustc.edu.cn/","2020-07-04 10:25:34","online");
Query OK, 1 row affected (0.01 sec)
查看是否同步
[root@node1 ~]# mysql -u root -p
Enter password:
...略
mysql> select * from websites.site_status;
+-----+-----------------------------------------+---------------------------------------+---------------------+--------+
| wid | name | address | acquired_time | status |
+-----+-----------------------------------------+---------------------------------------+---------------------+--------+
| 1 | 阿里巴巴开源镜像站 | https://developer.aliyun.com/mirror/ | 2020-07-04 10:19:57 | online |
| 2 | 网易开源镜像站 | http://mirrors.163.com/ | 2020-07-04 10:19:58 | online |
| 3 | 清华大学开源软件镜像站 | https://mirrors.tuna.tsinghua.edu.cn/ | 2020-07-04 10:20:25 | online |
| 4 | 中国科学技术大学开源镜像站 | https://mirrors.ustc.edu.cn/ | 2020-07-04 10:25:34 | online |
+-----+-----------------------------------------+---------------------------------------+---------------------+--------+
4 rows in set (0.00 sec)
读写分离
使用工具MaxScale实现读写分离,把读操作分散到从服务器中,并且对多个从服务器能实现负载均衡;
下载地址:https://downloads.mariadb.com/MaxScale/
[root@node2 ~]# wget https://downloads.mariadb.com/MaxScale/2.4.9/centos/7/x86_64/maxscale-2.4.9-1.centos.7.x86_64.rpm
在 node2 为主库,node1,node3 为从库的基础上实验;
创建用于监控和路由的MySQL用户
[root@node2 ~]# mysql -u root -p
Enter password:
...略
mysql> grant replication slave,replication client on *.* to 'maxmon'@'10.0.0.%' identified by 'Maxscale111!';
Query OK, 0 rows affected, 1 warning (0.01 sec)
mysql> grant select on mysql.* to 'maxrou'@'10.0.0.%' identified by 'Maxscale111!';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
安装配置MaxScale
[root@node2 ~]# rpm -ivh maxscale-2.4.9-1.centos.7.x86_64.rpm
warning: maxscale-2.4.9-1.centos.7.x86_64.rpm: Header V4 RSA/SHA1 Signature, key ID 28c12247: NOKEY
Preparing... ################################# [100%]
Updating / installing...
1:maxscale-2.4.9-1 ################################# [100%]
Created symlink from /etc/systemd/system/multi-user.target.wants/maxscale.service to /usr/lib/systemd/system/maxscale.service.
[root@node2 ~]# cp /etc/maxscale.cnf /etc/maxscale.cnf.bak
[root@node2 ~]# vim /etc/maxscale.cnf
[root@node2 ~]# cat /etc/maxscale.cnf
[maxscale]
threads=auto
[server1]
type=server
address=10.0.0.12
port=3306
protocol=MySQLBackend
[server2]
type=server
address=10.0.0.11
port=3306
protocol=MySQLBackend
[server3]
type=server
address=10.0.0.13
port=3306
protocol=MySQLBackend
[MySQL-Monitor]
type=monitor
module=mysqlmon
servers=server1,server2,server3
user=maxmon
password=Maxscale111!
monitor_interval=2000
detect_replication_lag=1
[Read-Write-Service]
type=service
router=readwritesplit
servers=server1,server2,server3
user=maxrou
password=Maxscale111!
max_slave_replication_lag=60
[Read-Write-Listener]
type=listener
service=Read-Write-Service
protocol=MySQLClient
port=4006
[CLI]
type=service
router=cli
[CLI-Listener]
type=listener
service=CLI
protocol=maxscaled
port=6603
[root@node2 ~]# systemctl start maxscale
[root@node2 ~]# systemctl enable maxscale
查看maxscale集群状态
[root@node2 ~]# maxadmin --user=admin --password=mariadb
MaxScale> list servers
Servers.
-------------------+-----------------+-------+-------------+--------------------
Server | Address | Port | Connections | Status
-------------------+-----------------+-------+-------------+--------------------
server1 | 10.0.0.12 | 3306 | 0 | Master, Running
server2 | 10.0.0.11 | 3306 | 0 | Slave, Running
server3 | 10.0.0.13 | 3306 | 0 | Slave, Running
-------------------+-----------------+-------+-------------+--------------------
MaxScale> show dbusers Read-Write-Service
User names (Read-Write-Listener): mysql.session@localhost mysql.sys@localhost webmonitor@10.0.0.% replicer2@10.0.0.% maxmon@10.0.0.% maxrou@10.0.0.% mysql.session@localhost maxrou@10.0.0.%
MaxScale> exit
测试
[root@node1 ~]# mysql -u webmonitor -h 10.0.0.12 -P 4006 -p
Enter password:
...略
mysql> select @@hostname;
+--------------------+
| @@hostname |
+--------------------+
| node1.newbie.local |
+--------------------+
1 row in set (0.01 sec)
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> select @@hostname;
+--------------------+
| @@hostname |
+--------------------+
| node2.newbie.local |
+--------------------+
1 row in set (0.00 sec)
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
mysql> select @@hostname;
+--------------------+
| @@hostname |
+--------------------+
| node1.newbie.local |
+--------------------+
1 row in set (0.00 sec)
组复制
MySQL Group Replication 是一个高可用与高扩展的解决方案,提供了高可用、高扩展、高可靠的MySQL集群服务;
特点:
高一致性,基于原生复制及paxos协议的组复制技术,并以插件的方式提供,提供一致数据安全保证;
高容错性,只要不是大多数节点坏掉就可以继续工作,有自动检测机制,当不同节点产生资源争用冲突时,不会出现错误,按照先到者优先原则进行处理,并且内置了自动化脑裂防护机制;
高扩展性,节点的新增和移除都是自动的,新节点加入后,会自动从其他节点上同步状态,直到新节点和其他节点保持一致,如果某节点被移除了,其他节点自动更新组信息,自动维护新的组信息;
高灵活性,有单主模式和多主模式,单主模式下,会自动选主,所有更新操作都在主上进行;多主模式下,所有server都可以同时处理更新操作。
恢复初始快照;
node1 node2 node3重新安装,及初始化MySQL;
以单主模式为例,部署MGR
node1 上操作:
配置MySQL服务
[root@node1 ~]# uuidgen
ac2b81bb-09aa-45b3-87b6-65541ed5da4b
[root@node1 ~]# vim /etc/my.cnf
[root@node1 ~]# cat /etc/my.cnf
...略
server_id=11
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_slave_updates=ON
log_bin=binlog
binlog_format=ROW # MGR的binlog只能是ROW格式
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name='ac2b81bb-09aa-45b3-87b6-65541ed5da4b'
loose-group_replication_start_on_boot=off
loose-group_replication_local_address='10.0.0.11:33061'
loose-group_replication_group_seeds='10.0.0.11:33061,10.0.0.12:33062,10.0.0.13:33063'
loose-group_replication_bootstrap_group=off
[root@node1 ~]# systemctl restart mysqld
配置MySQL
[root@node1 ~]# mysql -u root -p
Enter password:
...略
mysql> set SQL_LOG_BIN=0;
Query OK, 0 rows affected (0.00 sec)
mysql> grant replication slave on *.* to 'replicer'@'10.0.0.%' identified by 'Replica111!';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
mysql> set SQL_LOG_BIN=1;
Query OK, 0 rows affected (0.00 sec)
mysql> change master to master_user='replicer',master_password='Replica111!' for channel 'group_replication_recovery';
Query OK, 0 rows affected, 2 warnings (0.04 sec)
mysql> install PLUGIN group_replication SONAME 'group_replication.so';
Query OK, 0 rows affected (0.01 sec)
mysql> show plugins;
+----------------------------+----------+--------------------+----------------------+---------+
| Name | Status | Type | Library | License |
+----------------------------+----------+--------------------+----------------------+---------+
...略
| group_replication | ACTIVE | GROUP REPLICATION | group_replication.so | GPL |
+----------------------------+----------+--------------------+----------------------+---------+
46 rows in set (0.00 sec)
mysql> set global group_replication_bootstrap_group=ON;
Query OK, 0 rows affected (0.00 sec)
mysql> start group_replication;
Query OK, 0 rows affected (2.09 sec)
mysql> set global group_replication_bootstrap_group=OFF;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from performance_schema.replication_group_members;
+---------------------------+--------------------------------------+--------------------+-------------+--------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+--------------------+-------------+--------------+
| group_replication_applier | 675c9ea7-bf4d-11ea-b1db-080027c01ae1 | node1.newbie.local | 3306 | ONLINE |
+---------------------------+--------------------------------------+--------------------+-------------+--------------+
1 row in set (0.00 sec)
node2 上操作:
配置MySQL服务
[root@node2 ~]# vim /etc/my.cnf
[root@node2 ~]# cat /etc/my.cnf
...略
server_id=12
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_slave_updates=ON
log_bin=binlog
binlog_format=ROW
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name='ac2b81bb-09aa-45b3-87b6-65541ed5da4b'
loose-group_replication_start_on_boot=off
loose-group_replication_local_address='10.0.0.12:33062'
loose-group_replication_group_seeds='10.0.0.11:33061,10.0.0.12:33062,10.0.0.13:33063'
loose-group_replication_bootstrap_group=off
[root@node2 ~]# systemctl restart mysqld
配置MySQL
[root@node2 ~]# mysql -u root -p
Enter password:
...略
mysql> set SQL_LOG_BIN=0;
Query OK, 0 rows affected (0.00 sec)
mysql> grant replication slave on *.* to 'replicer'@'10.0.0.%' identified by 'Replica111!';
Query OK, 0 rows affected, 1 warning (0.01 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
mysql> set SQL_LOG_BIN=1;
Query OK, 0 rows affected (0.00 sec)
mysql> change master to master_user='replicer',master_password='Replica111!' for channel 'group_replication_recovery';
Query OK, 0 rows affected, 2 warnings (0.06 sec)
mysql> install PLUGIN group_replication SONAME 'group_replication.so';
Query OK, 0 rows affected (0.02 sec)
mysql> set global group_replication_allow_local_disjoint_gtids_join=ON;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> start group_replication;
Query OK, 0 rows affected, 1 warning (5.71 sec)
在node1上查看mgr状态
mysql> select * from performance_schema.replication_group_members;
+---------------------------+--------------------------------------+--------------------+-------------+--------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+--------------------+-------------+--------------+
| group_replication_applier | 675c9ea7-bf4d-11ea-b1db-080027c01ae1 | node1.newbie.local | 3306 | ONLINE |
| group_replication_applier | 78028e34-bf50-11ea-9a94-0800275623eb | node2.newbie.local | 3306 | ONLINE |
+---------------------------+--------------------------------------+--------------------+-------------+--------------+
2 rows in set (0.00 sec)
node3 操作跟node2差不多,
不一样的就是server_id和loose-group_replication_local_address两个配置的值;
完成node3的配置之后,再在node1上查看mgr状态
mysql> select * from performance_schema.replication_group_members;
+---------------------------+--------------------------------------+--------------------+-------------+--------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+--------------------+-------------+--------------+
| group_replication_applier | 675c9ea7-bf4d-11ea-b1db-080027c01ae1 | node1.newbie.local | 3306 | ONLINE |
| group_replication_applier | 78028e34-bf50-11ea-9a94-0800275623eb | node2.newbie.local | 3306 | ONLINE |
| group_replication_applier | 7a96e212-bf50-11ea-9b0f-08002787181c | node3.newbie.local | 3306 | ONLINE |
+---------------------------+--------------------------------------+--------------------+-------------+--------------+
3 rows in set (0.00 sec)
写入数据
注意单主模式下,只有主节点可以写入数据
[root@node1 ~]# mysql -u root -p
Enter password:
...略
mysql> create database websites default charset utf8 collate utf8_general_ci;
Query OK, 1 row affected (0.00 sec)
mysql> use websites;
Database changed
mysql> create table site_status( wid int not null auto_increment primary key, name char(30) not null, address char(50) not null, acquired_time datetime not null, status char(10) not null)engine=innodb default charset=utf8;
Query OK, 0 rows affected (0.04 sec)
mysql> insert into site_status(name,address,acquired_time,status) values("阿里巴巴开源镜像站","https://developer.aliyun.com/mirror/","2020-07-04 10:19:57","online");
Query OK, 1 row affected (0.01 sec)
mysql> insert into site_status(name,address,acquired_time,status) values("网易开源镜像站","http://mirrors.163.com/","2020-07-04 10:19:58","online");
Query OK, 1 row affected (0.01 sec)
mysql> insert into site_status(name,address,acquired_time,status) values("清华大学开源软件镜像站","https://mirrors.tuna.tsinghua.edu.cn/","2020-07-04 10:20:25","online");
Query OK, 1 row affected (0.01 sec)
mysql> select * from site_status;
+-----+-----------------------------------+---------------------------------------+---------------------+--------+
| wid | name | address | acquired_time | status |
+-----+-----------------------------------+---------------------------------------+---------------------+--------+
| 1 | 阿里巴巴开源镜像站 | https://developer.aliyun.com/mirror/ | 2020-07-04 10:19:57 | online |
| 2 | 网易开源镜像站 | http://mirrors.163.com/ | 2020-07-04 10:19:58 | online |
| 3 | 清华大学开源软件镜像站 | https://mirrors.tuna.tsinghua.edu.cn/ | 2020-07-04 10:20:25 | online |
+-----+-----------------------------------+---------------------------------------+---------------------+--------+
3 rows in set (0.00 sec)
node2 和 node3 查看数据是否同步
mysql> select * from websites.site_status;
+-----+-----------------------------------+---------------------------------------+---------------------+--------+
| wid | name | address | acquired_time | status |
+-----+-----------------------------------+---------------------------------------+---------------------+--------+
| 1 | 阿里巴巴开源镜像站 | https://developer.aliyun.com/mirror/ | 2020-07-04 10:19:57 | online |
| 2 | 网易开源镜像站 | http://mirrors.163.com/ | 2020-07-04 10:19:58 | online |
| 3 | 清华大学开源软件镜像站 | https://mirrors.tuna.tsinghua.edu.cn/ | 2020-07-04 10:20:25 | online |
+-----+-----------------------------------+---------------------------------------+---------------------+--------+
3 rows in set (0.00 sec)