(文章目录)
两个接口
当ProxySQL启动后,将监听两个端口:
- (1).admin管理接口,默认端口为6032。该端口用于查看、配置ProxySQL。
- (2).接收SQL语句的接口,默认端口为6033,这个接口类似于MySQL的3306端口。
ProxySQL的admin管理接口是一个使用MySQL协议的接口,所以,可以直接使用mysql客户端、navicat等工具去连接这个管理接口。
admin-mysql_ifaces
该变量指定admin接口的监听地址,格式为分号分隔的hostname:port
列表。默认监听在0.0.0.0:6032
。
注意,允许使用UNIX的domain socket进行监听,这样本主机内的应用程序就可以直接被处理。
例如:
SET admin-mysql_ifaces='127.0.0.1:6032;/tmp/proxysql_admin.sock'
三层配置系统
从上往下分别是:runtime《——》memory《——》disk、config file
内存数据库需要持久化到disk库才能永久保存配置。但实际上,修改了main库中的配置后,并不会立即生效,它还需要load到runtime的数据结构中才生效,只有在runtime数据结构中的配置才是对ProxySQL当前有效的配置。
ProxySQL的配置系统非常强大,它能在线修改几乎所有配置(仅有的两个需要重启才能生效的变量为mysql-threads
和mysql-stacksize
),并在线生效、持久化保存。这得益于它采用的多层配置系统。
解释下这个3层的配置系统
最底层的是disk库和config file。这里需要注意,这里的config file就是传统的配置文件,默认为/etc/proxysql.cnf,ProxySQL启动时,主要是从disk库中读取配置加载到内存并最终加载到runtime生效,只有极少的几个特定配置内容是从config file中加载的,除非是第一次初始化ProxySQL运行环境(或者disk库为空)。
中间层的是memory,表示的是内存数据库,其实就是main库。通过管理接口修改的所有配置,都保存在内存数据库(main)中。当ProxySQL重启或者崩溃时,这个内存数据库中的数据会丢失,所以需要save到disk库中。
最上层的是runtime,它是ProxySQL有关线程运行时读取的数据结构。换句话说,该数据结构中的配置都是已生效的配置。所以,修改了main库中的配置后,必须load到runtime数据结构中才能使其生效。
在上面的多层配置系统图中,标注了[1]、[2]、[3]、[4]、[5]的序号。每个序号都有两个操作方向from/to b
,其实只是所站角度不同而已。以下是各序号对应的操作:
[1] :将内存数据库中的配置加载到RUNTIME数据结构中
LOAD XXX FROM MEMORY
LOAD XXX TO RUNTIME
[2] :将RUNTIME数据结构中的配置持久化到内存数据库中
SAVE XXX FROM RUNTIME
SAVE XXX TO MEMORY
[3] :将磁盘数据库中的配置加载到内存数据库中
LOAD XXX FROM DISK
LOAD XXX TO MEMORY
[4] :将内存数据库中的配置持久化到磁盘数据库中
SAVE XXX FROM MEMORY
SAVE XXX TO DISK
[5] :从传统配置文件中读取配置加载到内存数据库中
LOAD XXX FROM CONFIG
DISK/MEMORY/RUNTIME/CONFIG可以缩写,只要能识别即可。例如MEMORY
可以缩写为MEM
,runtime
可以缩写为run
。
另外,上面的XXX
是什么?这表示要加载/保存的是哪类配置。目前的ProxySQL支持以下几种:
- [x] mysql users
- [x] mysql servers
- [x] mysql variables
- [x] mysql query rules
- [x] admin variables
- [x] scheduler
- [ ] proxysql_servers:目前ProxySQL集群功能还处于实验阶段,所以该类配置不应该去使用。
这些从main库或disk库中就可以查看到。
admin> show tables from disk;
+------------------------------------+
| tables |
+------------------------------------+
| global_variables | # (1)
| mysql_collations | # (N)
| mysql_group_replication_hostgroups | # (2)
| mysql_query_rules | # (3)
| mysql_query_rules_fast_routing | # (4)
| mysql_replication_hostgroups | # (5)
| mysql_servers | # (6)
| mysql_users | # (7)
| proxysql_servers | # (8)
| scheduler | # (9)
+------------------------------------+
其中:
(1)
中包含两类变量,以amdin-
开头的表示admin variables,以mysql-
开头的表示mysql variables。修改哪类变量,前文的XXX
就代表哪类。(2,5,6)
对应的都是mysql servers。(3,4)
对应的是mysql query rules。(7)
对应的mysql users。(9)
对应的scheduler。(N)
只是一张表,保存的是ProxySQL支持的字符集和排序规则,它是不用修改的。(8)
是ProxySQL的集群配置表,该功能目前还处于实验阶段。如果想要配置该功能,则load/save proxysql_servers to/from ...
。
以下是几个示例:注意,几乎所有配置都是在admin管理接口上修改的,这也是建议的配置方式。
(1).向ProxySQL的mysql_servers
表中添加了一个后端节点。
load mysql servers to runtime; # 加载到runtime使该节点的配置生效
save mysql servers to disk; # 将该节点的配置持久化到磁盘数据库中
上面两句和下面两句是等价的,只是操作方向不同(还使用了缩写):
load mysql servers from mem;
save mysql servers from mem;
(2).向ProxySQL的mysql_users
表中添加了用于发送、处理SQL语句的用户。
load mysql users to runtime;
save mysql users to disk;
(3).修改了以admin-
开头的变量。
load admin variables to runtime;
save admin variables to disk;
四种用户
管理用户、普通用户、前端连接proxysql和proxysql连接后端所使用的用户、监控后端的用户
与管理用户相关的变量为:admin-admin_credentials
与普通用户相关的变量为:admin-stats_credentials
与应用程序连接ProxySQL(默认端口6033),以及ProxySQL连接后端MySQL Servers使用的用户相关的表是:mysql_users
与监控用户相关的变量为:mysql-monitor_username 和 mysql-monitor_password
admin-admin_credentials
该变量控制的是admin管理接口的管理员账户。默认的管理员账户和密码为admin:admin
,但是这个默认的用户只能在本地使用。如果想要远程连接到ProxySQL,例如用windows上的navicat连接Linux上的ProxySQL管理接口,必须自定义一个管理员账户。
例如,添加一个myuser:myuser
的用户密码对。
admin> select @@admin-admin_credentials; # 当前用户名和密码
+---------------------------+
| @@admin-admin_credentials |
+---------------------------+
| admin:admin |
+---------------------------+
admin> set admin-admin_credentials='admin:admin;myuser:myuser';
admin> select @@admin-admin_credentials;
+---------------------------+
| @@admin-admin_credentials |
+---------------------------+
| admin:admin;myuser:myuser |
+---------------------------+
admin> load admin variables to runtime; # 使修改立即生效
admin> save admin variables to disk; # 使修改永久保存到磁盘
修改后,就可以使用该用户名和密码连接管理接口。
mysql -umyuser -pmyuser -P6032 -h127.0.0.1 --prompt 'admin> '
所有的配置操作都是在修改main库中对应的表。
select * from global_variables
where variable_name='admin-admin_credentials';
+-------------------------+---------------------------+
| variable_name | variable_value |
+-------------------------+---------------------------+
| admin-admin_credentials | admin:admin;myuser:myuser |
+-------------------------+---------------------------+
所以,前面的set
语句和下面的update语句是等价的:
update global_variables set variable_value='admin:admin;myuser:myuser'
where variable_name='admin-admin_credentials';
必须要区分admin管理接口的用户名和mysql_users中的用户名。
- admin管理接口的用户是连接到管理接口(默认端口6032)上用来管理、配置ProxySQL的。
- mysql_users表中的用户名是**应用程序连接ProxySQL(默认端口6033),以及ProxySQL连接后端MySQL Servers使用的用户。它的作用是发送、路由SQL语句,类似于MySQL Server的3306端口。**所以,这个表中的用户必须已经在后端MySQL Server上存在且授权了。
目前ProxySQL的mysql_users中的用户既负责ProxySQL前端,又负责ProxySQL后端的连接,未来版本中可能会将这两段连接的用户系统分开,让ProxySQL更加安全。
admin管理接口的用户必须不能存在于mysql_users中,这是出于安全的考虑,防止通过admin管理接口用户猜出mysql_users中的用户。
admin-stats_credentials
该变量控制admin管理接口的普通用户,这个变量中的用户没有超级管理员权限,只能查看monitor库和main库中关于统计的数据,其它库都是不可见的,且没有任何写权限。
默认的普通用户名和密码为stats:stats
。
mysql> select @@admin-stats_credentials;
+---------------------------+
| @@admin-stats_credentials |
+---------------------------+
| stats:stats |
+---------------------------+
mysql> set admin-stats_credentials='stats:stats;mystats:mystats';
[root@s1 ~]# mysql -ustats -pstats -P6032 -h127.0.0.1
mysql> show databases;
+-----+---------------+-------------------------------------+
| seq | name | file |
+-----+---------------+-------------------------------------+
| 0 | main | |
| 2 | monitor | |
| 3 | stats_history | /var/lib/proxysql/proxysql_stats.db |
+-----+---------------+-------------------------------------+
mysql> show tables from main;
+--------------------------------------+
| tables |
+--------------------------------------+
| global_variables |
| stats_memory_metrics |
| stats_mysql_commands_counters |
| stats_mysql_connection_pool |
| stats_mysql_connection_pool_reset |
| stats_mysql_global |
| stats_mysql_prepared_statements_info |
| stats_mysql_processlist |
| stats_mysql_query_digest |
| stats_mysql_query_digest_reset |
| stats_mysql_query_rules |
| stats_mysql_users |
| stats_proxysql_servers_checksums |
| stats_proxysql_servers_metrics |
| stats_proxysql_servers_status |
+--------------------------------------+
同样,这个变量中的用户必须不能存在于mysql_users表中。
mysql_users表详细解释
以下是mysql_users
表的属性。
| 字段名 | 数据类型 | 可为空? | 默认值 |
|-----------------------|---------|----------|-------|
|username (pk,uk) | VARCHAR | NOT NULL | |
|password | VARCHAR | NULL | |
|active | INT | NOT NULL | 1 |
|use_ssl | INT | NOT NULL | 0 |
|default_hostgroup | INT | NOT NULL | 0 |
|default_schema | VARCHAR | NULL | |
|schema_locked | INT | NOT NULL | 0 |
|transaction_persistent | INT | NOT NULL | 1 |
|fast_forward | INT | NOT NULL | 0 |
|backend (pk) | INT | NOT NULL | 1 |
|frontend (uk) | INT | NOT NULL | 1 |
|max_connections | INT | NOT NULL | 10000 |
各字段的意义:
- username, password:前端连接到ProxySQL以及ProxySQL连接到后端时使用的用户凭据。
- active:
active=0
的用户会保留在库中,但不会加载到runtime数据结构中,只有active=1
用户才是有效用户。该字段默认值为1。 - default_hostgroup:如果该用户发送的查询语句无法匹配任何规则,则该查询会路由到该字段指定的默认组中。
- default_schema:建立连接时默认将切换到该schema。
- schema_locked:目前还不支持该功能。
- transaction_persistent:如果正在和ProxySQL建立连接的客户端使用的用户设置了该字段,那么当该用户开启一个事务后,该客户端后续的请求都将路由到同一主机组中(无视查询规则),使得事务在这个组中是持久的,避免同一事务分散到其它组,直到事务结束才可能会路由到其它主机组。注意,有些老版本中,这个字段默认值为0,强烈建议修改为1。
- fast_forward:如果设置了该字段,ProxySQL将绕过查询处理层(重写语句、缓存),直接将原请求语句转发给后端节点。
- frontend:如果设置为1,前端将可以使用该用户(username,password)连接到ProxySQL。
- backend:如果设置为1,ProxySQL将可以使用该用户(username,password)连接到后端节点。
- max_connections:使用该用户"建立到ProxySQL的连接"的最大数量。默认值为10000,所以每个用户最多和ProxySQL建立10000个连接。注意,这是前端到ProxySQL的连接限制,ProxySQL和某个后端节点的最大连接数量是通过
mysql_servers
中的max_connections
字段控制的。
注意,当前版本的ProxySQL要求所有的用户均设置frontend和backend为1(即所有用户都可以进行frontend --> ProxySQL
以及ProxySQL --> backend
的连接认证)。将来版本中,ProxySQL将分离这两部分连接的用户凭据。这样前端将永远不知道后端的用户凭据,它们只能通过中间的ProxySQL发送请求,无法直接和后端节点建立连接,从而提高安全性。
关于快速转发fast_forward:
- 不要求用一个不同的端口:正常的ProxySQL逻辑和"fast forward"的逻辑使用的是完全相同的代码/模块。
- fast forward是基于每用户的:根据连接到ProxySQL用户的设置,决定该用户是否启用、禁用fast forward功能。
- fast forward算法的启用是在用户认证之后:ProxySQL仍然需要先对客户端使用的用户进行认证,尽管客户端的请求会直接原样转发给后端,但ProxySQL仍然会和前端先建立好连接。这意味着,如果前端和ProxySQL的连接发生错误,也会被处理。
- fast forward不支持SSL连接。
- 如果使用压缩功能,必须在两端都启用压缩。
添加MySQL users到ProxySQL
例如,使用root用户来处理SQL请求。先在后端的写节点(如master节点)上授权root,该操作会复制给其它节点。
grant all on *.* to root@'192.168.100.%' identified by 'P@ssword1!';
然后,向ProxySQL的mysql_users
插入这个用户即可。这个表的字段很多,大多数字段都有默认值,以下是大部分使用默认值的插入语句:
insert into mysql_users(username,password,default_hostgroup)
values ('root','P@ssword1!',10);
load mysql users to runtime;
save mysql users to disk;
上面指定了root用户的用户名、密码以及该用户默认的路由目标组。
ProxySQL有多种粒度的路由规则,每个用户都有默认的路由目标组,当使用该用户发送的SQL语句没有能够匹配的语句级路由规则,则会将该SQL语句路由给该用户默认的路由目标组。
例如,navicat工具使用root用户连接到了ProxySQL,发送了一个select语句,如果没有配置select语句的路由规则,那么这个select语句将默认路由给root用户的默认组。
监控用户
Monitor模块监控后端时,需要使用一个MySQL用户连接后端进行监控。
- 需要先在后端MySQL组中创建好这个用户监控的用户。
- 监控connect、ping和read_only时,只需
USAGE
权限,监控replication lag时需要replication client
权限。 - 通过变量
mysql-monitor_username
和mysql-monitor_password
将监控用户加入到ProxySQL中。
五个库
admin> 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 |
+-----+---------------+-------------------------------------+
其中:
- main库是ProxySQL最主要的库,是需要修改配置时使用的库,它其实是一个内存数据库系统。所以,修改main库中的配置后,必须将其持久化到disk上才能永久保存。
- disk库是磁盘数据库,该数据库结构和内存数据库完全一致。当持久化内存数据库中的配置时,其实就是写入到disk库中。磁盘数据库的默认路径为
$DATADIR/proxysql.db
。 - stats库是统计信息库。这个库中的数据一般是在检索其内数据时临时填充的,它保存在内存中。因为没有相关的配置项,所以无需持久化。
- monitor库是监控后端MySQL节点相关的库,该库中只有几个log类的表,监控模块收集到的监控信息全都存放到对应的log表中。
- stats_history库是1.4.4版新增的库,用于存放历史统计数据。默认路径为
$DATADIR/proxysql_stats.db
。
ProxySQL内部使用的是SQLite3数据库,无论是内存数据库还是磁盘数据库,都是通过SQLite3引擎进行解析、操作的。它和MySQL的语法可能稍有不同,但ProxySQL会对不兼容的语法自动进行调整,最大程度上保证MySQL语句的有效率。