导读:html
在以前,咱们搭建了MySQL组复制集群环境,MySQL组复制集群环境解决了MySQL集群内部的自动故障转移,可是,组复制并无解决外部业务的故障转移。举个例子,在A、B、C 3台机器上搭建了组复制环境,且运行在单主模式下,这里假设A为主节点,应用程序链接A写数据,若是A节点发生宕机,主节点切换到B机器上,此时,应用程序是不会自动链接到B服务器上的,须要人工进行切换。node
在这篇文章中,咱们要介绍的ProxySQL就可以解决上面的问题,ProxySQL可以实现业务层面故障转移、读写分离功能,固然ProxySQL不只仅只有这两项功能,还有更多的其它功能。其架构以下:mysql
咱们不妨来了解一下。git
ProxySQL是一款MySQL代理软件,其核心特色为读写分离、故障转移,详细其功能以下:github
这里,咱们使用ProxySQL来对MySQL组复制环境实现读写分离以及故障转移。个人环境以下:sql
IP地址 | 主机名 | 用途 |
192.168.10.11 | mgr-node1 | MySQL组复制成员 |
192.168.10.12 | mgr-node2 | MySQL组复制成员 |
192.168.10.13 | mgr-node3 | MySQL组复制成员 |
192.168.10.10 | proxysql | ProxySQL代理服务器 |
MySQL采用多主模式,搭建过程见文档:《MySQL组复制MGR(二)-- 组复制搭建》,本文把重点放在ProxySQL的搭建与配置上。shell
(二)安装ProxySQL数据库
安装ProxySQL,有2种方法,若是有网络,能够直接使用yum安装,若是没有网络,能够下载ProxySQL发行包安装,下载地址为:https://github.com/sysown/proxysql/releases。这里为了方便,直接使用yum在线安装。
添加yum源,使用Linux root用户执行以下配置:后端
cat <<EOF | tee /etc/yum.repos.d/proxysql.repo [proxysql_repo] name= ProxySQL YUM repository baseurl=https://repo.proxysql.com/ProxySQL/proxysql-2.0.x/centos/\$releasever gpgcheck=1 gpgkey=https://repo.proxysql.com/ProxySQL/repo_pub_key EOF
安装proxysql:centos
yum install -y proxysql OR yum install proxysql-version
若是要查看安装的文件在哪,可使用以下命令:
[root@proxysql yum.repos.d]# rpm -ql proxysql /etc/logrotate.d/proxysql /etc/proxysql.cnf /etc/systemd/system/proxysql-initial.service /etc/systemd/system/proxysql.service /usr/bin/proxysql /usr/share/proxysql/tools/proxysql_galera_checker.sh /usr/share/proxysql/tools/proxysql_galera_writer.pl
查看ProxySQL进程:
[root@proxysql yum.repos.d]# ps -ef|grep proxy avahi 740 1 0 15:52 ? 00:00:00 avahi-daemon: registering [proxysql-65.local] root 761 1 0 15:52 ? 00:00:00 /usr/sbin/gssproxy -D proxysql 2058 1 0 16:09 ? 00:00:00 /usr/bin/proxysql --idle-threads -c /etc/proxysql.cnf proxysql 2059 2058 1 16:09 ? 00:00:00 /usr/bin/proxysql --idle-threads -c /etc/proxysql.cnf root 2087 1589 0 16:09 pts/0 00:00:00 grep --color=auto proxy
查看端口,6032是proxysql的管理端口,6033是对外服务端口
[root@proxysql yum.repos.d]# netstat -anlp | grep proxysql tcp 0 0 0.0.0.0:6032 0.0.0.0:* LISTEN 2059/proxysql tcp 0 0 0.0.0.0:6033 0.0.0.0:* LISTEN 2059/proxysql
(三)启动关闭ProxySQL
启动ProxySQL
service proxysql start
关闭ProxySQL
service proxysql stop
重启ProxySQL
service proxysql restart
查看ProxySQL的状态
service proxysql status
(四)ProxySQL基础知识了解
ProxySQL的配置,相对而言仍是比较复杂的。所以,在配置ProxySQL以前,咱们须要对其架构有一些了解,这样在配置的时候,才不会一脸懵逼。
(4.1)ProxySQL多层配置系统
前面咱们说到ProxySQL具备“零停机时间变动”功能,它是经过3层配置来实现的,3层配置包括:Runtime、Memory、Disk & Configuration File。
3个层面的信息有什么区别呢?我我的的理解是:3个层面保存的都是ProxySQL的配置信息,若是管理员未做修改,那么3个层面的配置信息是相同的。若是管理员要修改配置信息,首先须要修改Memory层,要让修改的信息马上生效,则须要把Memory层的变动信息推到Runtime层;要让修改的配置信息在ProxySQL重启后还能保存下来,则须要把Memory层的信息推到Disk层。Runtime层是ProxySQL正在使用的配置信息,Memory层是用户能够编辑的信息,Disk层能够把配置信息永久保存在磁盘上。
各层之间数据如何同步呢?咱们能够看上图的箭头部分,经过load/save命令来实现同步。具体命令以下:
[1] LOAD <item> FROM MEMORY/LOAD <item> TO RUNTIME 将配置项从内存数据库加载到运行时数据结构 [2] SAVE <item> TO MEMORY/SAVE <item> FROM RUNTIME 将配置项从运行时保存到内存数据库中 [3] LOAD <item> TO MEMORY/LOAD <item> FROM DISK 将持久性配置项目从磁盘数据库加载到内存数据库 [4] SAVE <item> FROM MEMORY/SAVE <item> TO DISK 将配置项从内存数据库保存到磁盘数据库 [5] LOAD <item> FROM CONFIG 将配置项从配置文件加载到内存数据库中
经常使用的配置有:
# 激活用户配置到RUNTIME LOAD MYSQL USERS TO RUNTIME; # 保存用户信息到磁盘上 SAVE MYSQL USERS TO DISK; --------------------------------- # 激活MySQL服务器信息到RUNTIME LOAD MYSQL SERVERS TO RUNTIME; # 保存MySQL服务器信息到磁盘 SAVE MYSQL SERVERS TO DISK; --------------------------------- # 激活查询路由规则到RUNTIME LOAD MYSQL QUERY RULES TO RUNTIME; # 保存查询路由规则到磁盘 SAVE MYSQL QUERY RULES TO DISK; ---------------------------------- # 激活MySQL变量到RUNTIME LOAD MYSQL VARIABLES TO RUNTIME; # 保存MySQL变量到磁盘 SAVE MYSQL VARIABLES TO DISK; ---------------------------------- # 激活proxySQL admin变量到RUNTIME LOAD ADMIN VARIABLES TO RUNTIME; # 保存proxySQL admin变量到磁盘 SAVE ADMIN VARIABLES TO DISK;
(4.2)ProxySQL的配置管理接口
ProxySQL有2种配置方式:
一般使用第一种方法进行配置,这里咱们只了解第1种方法。
ProxySQL管理界面使用的是MySQL协议的界面,经过使用mysql客户端链接到SQLite3进行配置的查询、管理。可使用默认的admin用户链接到proxySQL数据库。
[root@proxysql ~]# mysql -uadmin -padmin -h127.0.0.1 -P6032 mysql> show databases; +-----+---------------+-------------------------------------+ | seq | name | file | +-----+---------------+-------------------------------------+ | 0 | main | | | 2 | disk | /var/lib/proxysql/proxysql.db | | 3 | stats | | | 4 | monitor | | | 5 | stats_history | /var/lib/proxysql/proxysql_stats.db | +-----+---------------+-------------------------------------+
这些数据库做用以下:
ProxySQL设定了2个用户来管理配置数据库:
(五)一步一步配置ProxySQL--基础配置
(5.1)检查配置信息
查看相关配置表是否存在信息,由于还没开始配置,因此是不存在信息的,若是已经配置过了,能够先删除信息。
mysql> select * from mysql_servers; Empty set (0.00 sec) mysql> select * from mysql_users; Empty set (0.01 sec) mysql> select * from mysql_query_rules; Empty set (0.00 sec) mysql> select * from mysql_group_replication_hostgroups; Empty set (0.00 sec)
(5.2)组的配置
所谓组的配置,即定义读组、写组等,可使用以下两个表来定义读写组:
由于咱们这里是使用proxySQL来实现MGR集群业务层面的实现故障转移以及读写分离的,因此配置mysql_group_replication_hostgroups表便可,该表定义以下:
show create table mysql_group_replication_hostgroups; ------------------------------------------------------------ CREATE TABLE mysql_group_replication_hostgroups ( writer_hostgroup INT CHECK (writer_hostgroup>=0) NOT NULL PRIMARY KEY, backup_writer_hostgroup INT CHECK (backup_writer_hostgroup>=0 AND backup_writer_hostgroup<>writer_hostgroup) NOT NULL, reader_hostgroup INT NOT NULL CHECK (reader_hostgroup<>writer_hostgroup AND backup_writer_hostgroup<>reader_hostgroup AND reader_hostgroup>0), offline_hostgroup INT NOT NULL CHECK (offline_hostgroup<>writer_hostgroup AND offline_hostgroup<>reader_hostgroup AND backup_writer_hostgroup<>offline_hostgroup AND offline_hostgroup>=0), active INT CHECK (active IN (0,1)) NOT NULL DEFAULT 1, max_writers INT NOT NULL CHECK (max_writers >= 0) DEFAULT 1, writer_is_also_reader INT CHECK (writer_is_also_reader IN (0,1,2)) NOT NULL DEFAULT 0, max_transactions_behind INT CHECK (max_transactions_behind>=0) NOT NULL DEFAULT 0, comment VARCHAR, UNIQUE (reader_hostgroup), UNIQUE (offline_hostgroup), UNIQUE (backup_writer_hostgroup))
这些字段含义以下:
咱们对该表进行以下配置:
mysql> select * from mysql_group_replication_hostgroups; +------------------+-------------------------+------------------+-------------------+--------+-------------+-----------------------+-------------------------+---------+ | writer_hostgroup | backup_writer_hostgroup | reader_hostgroup | offline_hostgroup | active | max_writers | writer_is_also_reader | max_transactions_behind | comment | +------------------+-------------------------+------------------+-------------------+--------+-------------+-----------------------+-------------------------+---------+ | 1 | 2 | 3 | 4 | 1 | 1 | 0 | 100 | NULL | +------------------+-------------------------+------------------+-------------------+--------+-------------+-----------------------+-------------------------+---------+
(5.3)视图添加
若是ProxySQL是与组复制MGR一块儿使用的,那么还须要在MGR集群添加以下视图:
USE sys; DELIMITER $$ CREATE FUNCTION IFZERO(a INT, b INT) RETURNS INT DETERMINISTIC RETURN IF(a = 0, b, a)$$ CREATE FUNCTION LOCATE2(needle TEXT(10000), haystack TEXT(10000), offset INT) RETURNS INT DETERMINISTIC RETURN IFZERO(LOCATE(needle, haystack, offset), LENGTH(haystack) + 1)$$ CREATE FUNCTION GTID_NORMALIZE(g TEXT(10000)) RETURNS TEXT(10000) DETERMINISTIC RETURN GTID_SUBTRACT(g, '')$$ CREATE FUNCTION GTID_COUNT(gtid_set TEXT(10000)) RETURNS INT DETERMINISTIC BEGIN DECLARE result BIGINT DEFAULT 0; DECLARE colon_pos INT; DECLARE next_dash_pos INT; DECLARE next_colon_pos INT; DECLARE next_comma_pos INT; SET gtid_set = GTID_NORMALIZE(gtid_set); SET colon_pos = LOCATE2(':', gtid_set, 1); WHILE colon_pos != LENGTH(gtid_set) + 1 DO SET next_dash_pos = LOCATE2('-', gtid_set, colon_pos + 1); SET next_colon_pos = LOCATE2(':', gtid_set, colon_pos + 1); SET next_comma_pos = LOCATE2(',', gtid_set, colon_pos + 1); IF next_dash_pos < next_colon_pos AND next_dash_pos < next_comma_pos THEN SET result = result + SUBSTR(gtid_set, next_dash_pos + 1, LEAST(next_colon_pos, next_comma_pos) - (next_dash_pos + 1)) - SUBSTR(gtid_set, colon_pos + 1, next_dash_pos - (colon_pos + 1)) + 1; ELSE SET result = result + 1; END IF; SET colon_pos = next_colon_pos; END WHILE; RETURN result; END$$ CREATE FUNCTION gr_applier_queue_length() RETURNS INT DETERMINISTIC BEGIN RETURN (SELECT sys.gtid_count( GTID_SUBTRACT( (SELECT Received_transaction_set FROM performance_schema.replication_connection_status WHERE Channel_name = 'group_replication_applier' ), (SELECT @@global.GTID_EXECUTED) ))); END$$ CREATE FUNCTION gr_member_in_primary_partition() RETURNS VARCHAR(3) DETERMINISTIC BEGIN RETURN (SELECT IF( MEMBER_STATE='ONLINE' AND ((SELECT COUNT(*) FROM performance_schema.replication_group_members WHERE MEMBER_STATE != 'ONLINE') >= ((SELECT COUNT(*) FROM performance_schema.replication_group_members)/2) = 0), 'YES', 'NO' ) FROM performance_schema.replication_group_members JOIN performance_schema.replication_group_member_stats USING(member_id)); END$$ CREATE VIEW gr_member_routing_candidate_status AS SELECT sys.gr_member_in_primary_partition() as viable_candidate, IF( (SELECT (SELECT GROUP_CONCAT(variable_value) FROM performance_schema.global_variables WHERE variable_name IN ('read_only', 'super_read_only')) != 'OFF,OFF'), 'YES', 'NO') as read_only, sys.gr_applier_queue_length() as transactions_behind, Count_Transactions_in_queue as 'transactions_to_cert' from performance_schema.replication_group_member_stats;$$ DELIMITER ;
而后受权给监控用户,这里须要特别注意,个人监控用户在5.5.1步才建立,所以这一步须要放到5.5.1后执行:
grant select on sys.* to monitoring_user;
(5.4)MySQL服务器添加
mysql_server表是用来存储ProxySQL路由转换的MySQL节点的信息。
mysql> insert into mysql_servers (hostgroup_id, hostname, port) values(1,'192.168.10.11',3306); mysql> insert into mysql_servers (hostgroup_id, hostname, port) values(1,'192.168.10.12',3306); mysql> insert into mysql_servers (hostgroup_id, hostname, port) values(1,'192.168.10.13',3306); mysql> select * from mysql_servers; +--------------+---------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+ | hostgroup_id | hostname | port | gtid_port | status | weight | compression | max_connections | max_replication_lag | use_ssl | max_latency_ms | comment | +--------------+---------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+ | 1 | 192.168.10.11 | 3306 | 0 | ONLINE | 1 | 0 | 1000 | 0 | 0 | 0 | | | 1 | 192.168.10.12 | 3306 | 0 | ONLINE | 1 | 0 | 1000 | 0 | 0 | 0 | | | 1 | 192.168.10.13 | 3306 | 0 | ONLINE | 1 | 0 | 1000 | 0 | 0 | 0 | | +--------------+---------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+
而后执行下面的命令生效:
LOAD MYSQL SERVERS TO RUNTIME; SAVE MYSQL SERVERS TO DISK;
(5.5)监控配置及检查
这里配置监控信息,用来监控ProxySQL与后端的MySQL通讯是否正常。
(5.5.1)监控用户配置
在ProxySQL的变量表里面设定监控用户密码,用于ProxySQL监控后端MySQL服务器的用户信息
mysql> UPDATE global_variables SET variable_value='monitor' WHERE variable_name='mysql-monitor_username'; Query OK, 1 row affected (0.00 sec) mysql> UPDATE global_variables SET variable_value='monitor' WHERE variable_name='mysql-monitor_password'; Query OK, 1 row affected (0.00 sec) mysql> select variable_name,variable_value from global_variables where variable_name in ('mysql-monitor_username','mysql-monitor_password'); +------------------------+----------------+ | variable_name | variable_value | +------------------------+----------------+ | mysql-monitor_password | monitor | | mysql-monitor_username | monitor | +------------------------+----------------+
须要注意,既然使用该用户监控后台MySQL数据库,那么后台MySQL数据库也须要建立该用户并受权,monitor用户须要有usage权限去链接、ping和检查read_only信息,若是要检测复制延迟,还须要具备replication client权限。特别注意,不能使用mysql_users里面的用户来作监控用户。
-- 在MySQL服务器上建立监控用户 -- 须要注意,这里MySQL使用的是MGR,因此只须要在一台节点建立用户便可,其它节点会自动同步用户信息 create user monitor@'%' identified by 'monitor'; grant usage,replication client on *.* to monitor@'%'; flush privileges;
注意:由于ProxySQL+组复制添加了新的视图,见”5.3 视图添加”,所以还需受权:
grant select on sys.* to monitor;
(5.5.2)配置监控间隔
这里把链接、ping、read_only监控间隔改成2s,也能够根据须要改为其它,也能够不作修改
mysql> update global_variables set variable_value='2000' -> where variable_name in('mysql-monitor_connect_interval','mysql-monitor_ping_interval','mysql-monitor_read_only_interval'); Query OK, 3 rows affected (0.00 sec) mysql> select * from global_variables where variable_name like 'mysql-monitor%'; +--------------------------------------------------------------+----------------+ | variable_name | variable_value | +--------------------------------------------------------------+----------------+ | mysql-monitor_enabled | true | | mysql-monitor_connect_timeout | 600 | | mysql-monitor_ping_max_failures | 3 | | mysql-monitor_ping_timeout | 1000 | | mysql-monitor_read_only_max_timeout_count | 3 | | mysql-monitor_replication_lag_interval | 10000 | | mysql-monitor_replication_lag_timeout | 1000 | | mysql-monitor_groupreplication_healthcheck_interval | 5000 | | mysql-monitor_groupreplication_healthcheck_timeout | 800 | | mysql-monitor_groupreplication_healthcheck_max_timeout_count | 3 | | mysql-monitor_groupreplication_max_transactions_behind_count | 3 | | mysql-monitor_galera_healthcheck_interval | 5000 | | mysql-monitor_galera_healthcheck_timeout | 800 | | mysql-monitor_galera_healthcheck_max_timeout_count | 3 | | mysql-monitor_replication_lag_use_percona_heartbeat | | | mysql-monitor_query_interval | 60000 | | mysql-monitor_query_timeout | 100 | | mysql-monitor_slave_lag_when_null | 60 | | mysql-monitor_threads_min | 8 | | mysql-monitor_threads_max | 128 | | mysql-monitor_threads_queue_maxsize | 128 | | mysql-monitor_wait_timeout | true | | mysql-monitor_writer_is_also_reader | true | | mysql-monitor_username | monitor | | mysql-monitor_password | monitor | | mysql-monitor_history | 600000 | | mysql-monitor_connect_interval | 2000 | | mysql-monitor_ping_interval | 2000 | | mysql-monitor_read_only_interval | 2000 | | mysql-monitor_read_only_timeout | 500 | +--------------------------------------------------------------+----------------+ 30 rows in set (0.01 sec)
在修改完变量以后,必定要加载到内存中生效以及永久保存到磁盘中:
LOAD MYSQL VARIABLES TO RUNTIME; SAVE MYSQL VARIABLES TO DISK;
(5.5.3)检查监控信息是否存在异常
监控配置完成后,咱们须要检查ProxySQL与后端MySQL通讯是否有异常,monitor数据库中的表用于存储监视信息,须要注意的是,这些表并不是都已经被使用。
mysql> show tables from monitor; +--------------------------------------+ | tables | +--------------------------------------+ | mysql_server_aws_aurora_check_status | | mysql_server_aws_aurora_failovers | | mysql_server_aws_aurora_log | | mysql_server_connect_log | | mysql_server_galera_log | | mysql_server_group_replication_log | | mysql_server_ping_log | | mysql_server_read_only_log | | mysql_server_replication_lag_log | +--------------------------------------+
查看ProxySQL与后台服务器链接是否正常:
mysql> select * from monitor.mysql_server_connect_log order by time_start_us desc limit 10; +---------------+------+------------------+-------------------------+---------------+ | hostname | port | time_start_us | connect_success_time_us | connect_error | +---------------+------+------------------+-------------------------+---------------+ | 192.168.10.13 | 3306 | 1596263409501584 | 2191 | NULL | | 192.168.10.11 | 3306 | 1596263409480641 | 1911 | NULL | | 192.168.10.12 | 3306 | 1596263409459524 | 3671 | NULL | | 192.168.10.13 | 3306 | 1596263407504677 | 1451 | NULL | | 192.168.10.11 | 3306 | 1596263407481776 | 1398 | NULL | | 192.168.10.12 | 3306 | 1596263407458859 | 1378 | NULL | | 192.168.10.12 | 3306 | 1596263405490389 | 3480 | NULL | | 192.168.10.13 | 3306 | 1596263405474367 | 2804 | NULL | | 192.168.10.11 | 3306 | 1596263405458569 | 1612 | NULL | | 192.168.10.13 | 3306 | 1596263403497485 | 2132 | NULL | +---------------+------+------------------+-------------------------+---------------+ 10 rows in set (0.00 sec)
查看组复制是否正常,检查节点是否只读和交易滞后时间:
mysql> select * from mysql_server_group_replication_log order by time_start_us desc limit 10; +---------------+------+------------------+-----------------+------------------+-----------+---------------------+-------+ | hostname | port | time_start_us | success_time_us | viable_candidate | read_only | transactions_behind | error | +---------------+------+------------------+-----------------+------------------+-----------+---------------------+-------+ | 192.168.10.13 | 3306 | 1596263494597039 | 5671 | YES | NO | 0 | NULL | | 192.168.10.12 | 3306 | 1596263494596052 | 3231 | YES | NO | 0 | NULL | | 192.168.10.11 | 3306 | 1596263494595139 | 3245 | YES | NO | 0 | NULL | | 192.168.10.13 | 3306 | 1596263489596357 | 3027 | YES | NO | 0 | NULL | | 192.168.10.12 | 3306 | 1596263489595491 | 3306 | YES | NO | 0 | NULL | | 192.168.10.11 | 3306 | 1596263489594645 | 3110 | YES | NO | 0 | NULL | | 192.168.10.13 | 3306 | 1596263484595710 | 3680 | YES | NO | 0 | NULL | | 192.168.10.12 | 3306 | 1596263484594839 | 3618 | YES | NO | 0 | NULL | | 192.168.10.11 | 3306 | 1596263484594114 | 3214 | YES | NO | 0 | NULL | | 192.168.10.13 | 3306 | 1596263479595072 | 1887 | YES | NO | 0 | NULL | +---------------+------+------------------+-----------------+------------------+-----------+---------------------+-------+ 10 rows in set (0.01 sec)
查看ProxySQL ping后端MySQL服务器是否正常:
mysql> select * from mysql_server_ping_log order by time_start_us desc limit 10; +---------------+------+------------------+----------------------+------------+ | hostname | port | time_start_us | ping_success_time_us | ping_error | +---------------+------+------------------+----------------------+------------+ | 192.168.10.12 | 3306 | 1596263541810631 | 496 | NULL | | 192.168.10.11 | 3306 | 1596263541786903 | 612 | NULL | | 192.168.10.13 | 3306 | 1596263541762973 | 749 | NULL | | 192.168.10.12 | 3306 | 1596263539796079 | 565 | NULL | | 192.168.10.13 | 3306 | 1596263539779040 | 403 | NULL | | 192.168.10.11 | 3306 | 1596263539762769 | 1141 | NULL | | 192.168.10.12 | 3306 | 1596263537797512 | 848 | NULL | | 192.168.10.11 | 3306 | 1596263537779520 | 845 | NULL | | 192.168.10.13 | 3306 | 1596263537761840 | 742 | NULL | | 192.168.10.12 | 3306 | 1596263535814945 | 843 | NULL | +---------------+------+------------------+----------------------+------------+ 10 rows in set (0.00 sec)
经过监控信息,咱们能够得出结论,全部配置都是健康的,继续下一步。
(5.6)用户配置
(5.6.1)ProxySQL的双层用户认证机制
若是使用了ProxySQL来作中间路由,那么与咱们平时登陆数据库有一些区别:平时咱们直接使用数据库的用户密码,便可访问到数据库,若是使用了ProxySQL,则要先使用帐号密码访问到ProxySQL的数据库,而后再由ProxySQL进行用户请求的转发,那么,ProxySQL中的用户与数据库层的用户有什么关联呢?很奇怪,这部分ProxySQL竟然没在文档里面给出来。
只能本身测试了,通过我的测试,发现:当中间件用户与数据库用户以及密码一致时,才能正常访问数据库。测试结果以下:
MySQL数据库用户(mysql.user表) | ProxySQL用户(main.mysql_users表) | 使用ProxySQL的6033端口访问数据库 |
usera | usera | 正常访问 |
userb | 没法登入proxysql | |
userc | 能够登入proxysql,可是没法读写 |
这里是个人测试过程:
在MySQL数据库上建立用户:usera和userb
create user `usera`@`%` identified by '123456'; grant all privileges on *.* to `usera`@`%`; create user `userb`@`%` identified by '123456'; grant all privileges on *.* to `userb`@`%`; flush privileges;
在ProxySQL上建立用户:usera和userc
insert into mysql_users(username,password,default_hostgroup) values('usera','123456',1); insert into mysql_users(username,password,default_hostgroup) values('userc','123456',1); load mysql users to runtime; save mysql users to disk;
登入测试(分为2步:先登入,再查询):
(1)usera用户登入无问题,查询无问题
[root@proxysql ~]# mysql -uusera -p123456 -P6033 -h192.168.10.10 mysql> select count(*) from lijiamandb.test03; +----------+ | count(*) | +----------+ | 1 | +----------+ 1 row in set (0.01 sec)
(2)userb没法登入,提示用户名密码错误
[root@proxysql ~]# mysql -uuserb -p123456 -P6033 -h192.168.10.10 mysql: [Warning] Using a password on the command line interface can be insecure. ERROR 1045 (28000): ProxySQL Error: Access denied for user 'userb'@'192.168.10.10' (using password: YES)
(3)userc能够正常登入,可是查询的时候提示密码不对
[root@proxysql ~]# mysql -uuserc -p123456 -P6033 -h192.168.10.10 mysql> mysql> select count(*) from lijiamandb.test03; ERROR 1045 (28000): Access denied for user 'userc'@'192.168.10.10' (using password: YES)
用户认证小结:只有ProxySQL中的用户名密码与MySQL中的用户名密码相同时,才能正常访问底层MySQL数据库。所以,若是要使用ProxySQL访问数据库,须要在MySQL和ProxySQL中都要建立相同的帐号,而且密码也要保持一致。
(5.6.2)ProxySQL用户建立
ProxySQL的用户保存在mysql_users表中,用户建立直接执行insert插入便可。如建立一个用户名为“lijiaman”,密码为“123456”,默认用户组为1的用户:
insert into mysql_users(username,password,default_hostgroup) values('lijiaman','123456',1);
load mysql users to runtime; save mysql users to disk;
mysql_users表最重要的字段为:
(六)故障转移(failover)测试
在上一节,咱们已经配置了:
此时,ProxySQL已经具有故障转移的能力了,咱们进行测试一下。
STEP1:如今的配置以下,192.168.10.13主机是写节点,其它2个节点是备用写节点:
-- mysql_serve在memory层r的配置信息 mysql> select * from mysql_servers; +--------------+---------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+ | hostgroup_id | hostname | port | gtid_port | status | weight | compression | max_connections | max_replication_lag | use_ssl | max_latency_ms | comment | +--------------+---------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+ | 1 | 192.168.10.11 | 3306 | 0 | ONLINE | 1 | 0 | 1000 | 0 | 0 | 0 | | | 1 | 192.168.10.12 | 3306 | 0 | ONLINE | 1 | 0 | 1000 | 0 | 0 | 0 | | | 1 | 192.168.10.13 | 3306 | 0 | ONLINE | 1 | 0 | 1000 | 0 | 0 | 0 | | +--------------+---------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+ 3 rows in set (0.00 sec) --加载到RUNTIME后,因为组定义中最多只有1个写节点,其他的主节点移动到备用写组里面 mysql> select * from runtime_mysql_servers; +--------------+---------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+ | hostgroup_id | hostname | port | gtid_port | status | weight | compression | max_connections | max_replication_lag | use_ssl | max_latency_ms | comment | +--------------+---------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+ | 2 | 192.168.10.11 | 3306 | 0 | ONLINE | 1 | 0 | 1000 | 0 | 0 | 0 | | | 1 | 192.168.10.13 | 3306 | 0 | ONLINE | 1 | 0 | 1000 | 0 | 0 | 0 | | | 2 | 192.168.10.12 | 3306 | 0 | ONLINE | 1 | 0 | 1000 | 0 | 0 | 0 | | +--------------+---------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+ 3 rows in set (0.01 sec)
使用ProxySQL来访问MyQSL集群,发现能够支持读写
-- 使用ProxySQL 6033端口访问MySQL数据库 [root@proxysql ~]# mysql -uusera -p123456 -P6033 -h192.168.10.10 mysql> use testdb -- 经过主机名,额能够看到,咱们访问到的是写节点 mysql> select @@hostname; +------------+ | @@hostname | +------------+ | mgr-node3 | +------------+ 1 row in set (0.00 sec) -- 能够此次插入、查询数据 mysql> insert into test01 values(1,'a'); Query OK, 1 row affected (0.00 sec) mysql> select * from test01; +----+------+ | id | name | +----+------+ | 1 | a | +----+------+ 1 row in set (0.00 sec)
STEP2:关闭写节点
# 直接关闭主机 [root@mgr-node3 ~]# reboot
Connection closed by foreign host. Disconnected from remote host(mgr-node3) at 19:00:31. Type `help' to learn how to use Xshell prompt.
[c:\~]$ -- 须要注意的是,之前链接在主节点上的会话会断开,不会转移到新的主节点,很正常,Oracle也不会 mysql> select * from test01; ERROR 2013 (HY000): Lost connection to MySQL server during query
STEP3:查看是否会有备用写节点转为写节点,能够看到192.168.10.12服务器已经转为写节点,而已经关闭的192.168.10.13服务器已经进入离线组。
mysql> select * from runtime_mysql_servers; +--------------+---------------+------+-----------+---------+--------+-------------+-----------------+---------------------+---------+----------------+---------+ | hostgroup_id | hostname | port | gtid_port | status | weight | compression | max_connections | max_replication_lag | use_ssl | max_latency_ms | comment | +--------------+---------------+------+-----------+---------+--------+-------------+-----------------+---------------------+---------+----------------+---------+ | 2 | 192.168.10.11 | 3306 | 0 | ONLINE | 1 | 0 | 1000 | 0 | 0 | 0 | | | 1 | 192.168.10.12 | 3306 | 0 | ONLINE | 1 | 0 | 1000 | 0 | 0 | 0 | | | 4 | 192.168.10.13 | 3306 | 0 | SHUNNED | 1 | 0 | 1000 | 0 | 0 | 0 | | +--------------+---------------+------+-----------+---------+--------+-------------+-----------------+---------------------+---------+----------------+---------+ 3 rows in set (0.00 sec)
STEP4:再次使用ProxySQL来访问MyQSL集群,发现能够支持读写,业务不会因主节点的改变而受影响。
-- 使用ProxySQL 6033端口访问MySQL数据库 [root@proxysql ~]# mysql -uusera -p123456 -P6033 -h192.168.10.10 mysql> use testdb -- 经过主机名,额能够看到,咱们访问到的是新的写节点 mysql> select @@hostname; +------------+ | @@hostname | +------------+ | mgr-node2 | +------------+ 1 row in set (0.00 sec) -- 能够此次插入、查询数据 mysql> insert into test01 values(2,'b'); Query OK, 1 row affected (0.00 sec)
经过上面的测试,能够看到,MGR结合ProxySQL已经能够实现业务的自动故障转移。
接下来,咱们开始研究ProxySQL的读写分离功能。