password:用户名对应的密码。可以是明文密码,也可以是hash密码。如果想使用hash密码,可以先在某个MySQL节点上执行select password(PASSWORD),然后将加密结果复制到该字段。
default_hostgroup:该用户名默认的路由目标。例如,指定root用户的该字段值为10时,则使用root用户发送的SQL语句默认情况下将路由到hostgroup_id=10组中的某个节点。
admin> select * from mysql_users\G *************************** 1. row *************************** username: root password: P@ssword1! active: 1 # 注意本行 use_ssl: 0 default_hostgroup: 10 default_schema: NULL schema_locked: 0 transaction_persistent: 1 # 注意本行 fast_forward: 0 backend: 1 frontend: 1 max_connections: 10000 *************************** 2. row *************************** username: sqlsender password: P@ssword1! active: 1 use_ssl: 0 default_hostgroup: 10 default_schema: NULL schema_locked: 0 transaction_persistent: 1 fast_forward: 0 backend: 1 frontend: 1 max_connections: 10000虽然本文不详细介绍mysql_users表,但上面标注了"注意本行"的两个字段必须要引起注意。
只有active=1的用户才是有效的用户。
至于transaction_persistent字段,当它的值为1时,表示事务持久化:当某连接使用该用户开启了一个事务后,那么在事务提交/回滚之前,所有的语句都路由到同一个组中,避免语句分散到不同组。在以前的版本中,默认值为0,不知道从哪个版本开始,它的默认值为1。我们期望的值为1,所以在继续下面的步骤之前,先查看下这个值,如果为0,则执行下面的语句修改为1。
update mysql_users set transaction_persistent=1 where username='root'; update mysql_users set transaction_persistent=1 where username='sqlsender'; load mysql users to runtime; save mysql users to disk;然后,另开一个终端,分别使用root用户和sqlsender用户测试下它们是否能路由到默认的hostgroup_id=10(它是一个写组)读、写数据。
[root@s1 ~]# mysql -uroot -pP@ssword1! -P6033 -h127.0.0.1 -e "select @@server_id" mysql: [Warning] Using a password on the command line interface can be insecure. +-------------+ | @@server_id | +-------------+ | 110 | +-------------+ [root@s1 ~]# mysql -uroot -pP@ssword1! -P6033 -h127.0.0.1 -e "create database proxysql_test" mysql: [Warning] Using a password on the command line interface can be insecure. [root@s1 ~]# mysql -uroot -pP@ssword1! -P6033 -h127.0.0.1 -e "show databases;" mysql: [Warning] Using a password on the command line interface can be insecure. +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | proxysql_test | | sys | +--------------------+ [root@s1 ~]# mysql -usqlsender -pP@ssword1! -P6033 -h127.0.0.1 -e 'use proxysql_test;create table t(id int);' mysql: [Warning] Using a password on the command line interface can be insecure. [root@s1 ~]# mysql -usqlsender -pP@ssword1! -P6033 -h127.0.0.1 -e "show tables from proxysql_test;" mysql: [Warning] Using a password on the command line interface can be insecure. +-------------------------+ | Tables_in_proxysql_test | +-------------------------+ | t | +-------------------------+ 1.5 读写分离:配置SQL语句的路由规则ProxySQL的路由规则非常灵活,可以基于用户、基于schema以及基于每个语句实现路由规则的定制。
本文作为入门文章,实现一个最简单的语句级路由规则,从而实现读写分离。必须注意,这只是实验,实际的路由规则绝不应该仅根据所谓的读、写操作进行分离,而是从各项指标中找出压力大、执行频繁的语句单独写规则、做缓存等等。
和查询规则有关的表有两个:mysql_query_rules和mysql_query_rules_fast_routing,后者是前者的扩展表,1.4.7之后才支持该快速路由表。本文只介绍第一个表。
插入两个规则,目的是将select语句分离到hostgroup_id=20的读组,但由于select语句中有一个特殊语句SELECT...FOR UPDATE它会申请写锁,所以应该路由到hostgroup_id=10的写组。
insert into mysql_query_rules(rule_id,active,match_digest,destination_hostgroup,apply) VALUES (1,1,'^SELECT.*FOR UPDATE$',10,1), (2,1,'^SELECT',20,1); load mysql query rules to runtime; save mysql query rules to disk;select ... for update规则的rule_id必须要小于普通的select规则的rule_id,因为ProxySQL是根据rule_id的顺序进行规则匹配的。