当前端app发送SQL请求时,需要使用这套用户。然后ProxySQL将SQL语句路由给某后端节点,需要使用同一个用户和后端建立连接并将SQL语句发送出去。
需要现在后端MySQL组中创建好这套用户,因为ProxySQL需要连接后端,所以一般授权所有权限,例如root。
通过mysql_users表将这些用户加入到ProxySQL中,每一行对应一个用户。
4.1 添加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用户的默认组。
下面先介绍一下mysql_users表中的密码相关内容,然后再详细介绍mysql_users表。
4.2 mysql_users表中用户的密码管理ProxySQL向mysql_users表添加用户时,支持明文密码和hash加密密码。这个hash密码和mysql的password()的算法是一样的。
但是,ProxySQL内部使用的是SQLite3引擎,不支持password()。所以,想要向ProxySQL中使用hash加密密码,可以先通过mysql的password()函数创建一个hash密码,然后copy到mysql_users表中。
例如:
[root@s4 ~]# mysql -uroot -pP@ssword1! -e 'select password("P@ssword1!");' mysql: [Warning] Using a password on the command line interface can be insecure. +-------------------------------------------+ | password("P@ssword1!") | +-------------------------------------------+ | *50572A5FABC7DA9CEE5EB5977EDDE59E38967422 | +-------------------------------------------+然后插入到ProxySQL的mysql_users表:
insert into mysql_users(username,password,default_hostgroup) values ('root','*50572A5FABC7DA9CEE5EB5977EDDE59E38967422',10);ProxySQL和MySQL对密码的处理方式都是:以"*"开头的密码,表示是hash加密密码。
在MySQL和ProxySQL中,使用SHA1(SHA1('clear_password'))对clear_password进行加密。无法根据加密的hash密码推导回原始的明文密码。
当客户端连接到ProxySQL时,ProxySQL将使用该加密的密码对用户进行认证。如果该客户端是第一次认证,则ProxySQL会推导出一部分的hash密码SHA1('clear_password')。推导出的信息会存储到runtime的内部数据结构中,以便ProxySQL连接后端MySQL时使用。
从1.2.3版本开始,引入了一个布尔类型的全局变量admin-hash_passwords,默认为true。该变量表示,内存数据库的mysql_users表中的明文密码,在load mysql users to runtime时,对明文密码进行hash加密,并保存到runtime数据结构中。有了这个特性,可以以另一种方式保存加密密码:只需将其刷回内存数据库即可。
例如:
Admin> SELECT username,password FROM mysql_users; +----------+-----------+ | username | password | +----------+-----------+ | user1 | password1 | # 明文密码 | user2 | password2 | +----------+-----------+ Admin> LOAD MYSQL USERS TO RUNTIME; # 加载到runtime数据结构 Admin> SELECT username,password FROM mysql_users; +----------+-----------+ | username | password | +----------+-----------+ | user1 | password1 | # 还是明文密码 | user2 | password2 | +----------+-----------+这个时候,runtime数据结构中的密码是加密密码,而内存数据库中的密码是明文密码。
将runtime数据结构数据刷回内存数据库,即可将加密密码保存到内存数据库中,然后还可以将加密的密码持久化到disk。
Admin> save mysql users to memory; Admin> SELECT username,password FROM mysql_users; +----------+-------------------------------------------+ | username | password | +----------+-------------------------------------------+ | user1 | *668425423DB5193AF921380129F465A6425216D0 | | user2 | *DC52755F3C09F5923046BD42AFA76BD1D80DF2E9 | +----------+-------------------------------------------+ Admin> save mysql users to disk;唯一需要注意的是,admin-hash-passwords变量是admin-变量而非mysql-变量,这意味着修改了这个变量后(虽然基本不会去修改),load/save操作的目标是"admin variables",而非"mysql variables"。
load admin variables to runtime; save admin variables to disk; 4.3 mysql_users表详细解释