# PXC 单写入节点 ProxySQL 配置说明
 
## 参考
 
1. [ProxySQL Read Write Split (HOWTO)](https://github.com/malongshuai/proxysql/wiki/ProxySQL-Read-Write-Split-(HOWTO))
2. [ProxySQL Configuration](https://github.com/sysown/proxysql/wiki/ProxySQL-Configuration)
3. [详述ProxySQL的路由规则](https://www.cnblogs.com/f-ck-need-u/p/9300829.html)
 
## 进入容器
 
> `docker exec -it pxc_proxysql bash`
 
## 进入管理界面
 
> `mysql -u admin -padmin -h 127.0.0.1 -P6032 --prompt='Admin> '`
 
## 配置只读服务器
 
### 1.将第一个节点(写入节点)设置更新为 `hostgroup_id = 2`
 
```sql
UPDATE mysql_servers SET hostgroup_id = 2 WHERE hostname = '192.168.0.104';
```
 
### 2.添加一条写入规则
 
> 规则说明: [详述ProxySQL的路由规则](https://www.cnblogs.com/f-ck-need-u/p/9300829.html)
 
1. rule_id:规则的id。规则是按照rule_id的顺序进行处理的
2. active:只有该字段值为1的规则才会加载到runtime数据结构,所以只有这些规则才会被查询处理模块处理
3. digest:通过digest进行匹配,digest的值在stats_mysql_query_digest.digest中(digest:将参数化后的语句进行hash运算得到一个hash值digest,可以对这个hash值进行精确匹配。匹配效率最高)
4. match_digest:通过正则表达式匹配digest_text,即参数化后的SQL语句(也是SQL,但参数化了,即将参数用`?`替换)
5. match_pattern:通过正则表达式匹配查询语句的文本内容,即原始SQL
6. apply:当设置为1后,当匹配到该规则后,将立即应用该规则,不会再评估其它的规则(注意:应用之后,将不会评估mysql_query_rules_fast_routing中的规则)
 
```sql
DELETE FROM mysql_query_rules;
INSERT INTO mysql_query_rules (rule_id, active, match_digest, destination_hostgroup,apply)
VALUES
(1,1,'^SELECT.*FOR UPDATE$',2,1),
(2,1,'^SELECT',1,1);
```
 
> 说明:
 
1. 把所有以`^SELECT.*FOR UPDATE$` 会产生一个写锁,对数据查询的实效性要求高,把它分配到编号为 `2` 的写组中,其他所有操作都会**默认路由**到写组中(创建 `mysql_users`记录时设置的`default_hostgroup`)。
2. 把所有以 `SELECT` 开头的语句全部分配到编号为 `1` 的读组中。
 
## 应用设置
 
### 1. 查看服务器
 
```sql
SELECT * FROM mysql_servers;
```
 
### 2. 查看路由规则
 
```sql
SELECT * FROM mysql_query_rules;
```
 
### 3. 应用设置
 
```sql
LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;
LOAD MYSQL QUERY RULES TO RUNTIME;
SAVE MYSQL QUERY RULES TO DISK;
```
 
## 测试
 
```sql
select hostgroup, schemaname, username, digest, digest_text, count_star from stats_mysql_query_digest;
```
 
## 其它命令
 
### 1. 重置查询统计
 
> Querying stats_mysql_query_digest_reset allows to atomically get the content of the stats_mysql_query_digest table , and truncate it!
 
```sql
SELECT * FROM stats_mysql_query_digest_reset LIMIT 1;
```
 
### 2. 查看路由信息
 
```sql
SELECT hostgroup hg, sum_time, count_star, digest_text FROM stats_mysql_query_digest ORDER BY sum_time DESC;
```
 
### 3. 启用Web管理界面
 
> 启用 `admin-web_enabled='true'` 后,可以通过 `http://ip:6080`来访问Web界面
 
```sql
SET admin-web_enabled='true';
SET admin-stats_credentials='123456';
 
LOAD ADMIN VARIABLES TO RUNTIME;
SAVE ADMIN VARIABLES TO DISK;
```
 
### 4. 查看连接池 `stats_mysql_connection_pool`
 
```sql
SELECT hostgroup hg, srv_host, status, ConnUsed, ConnFree, ConnOK, ConnERR FROM stats_mysql_connection_pool WHERE ConnUsed+ConnFree > 0 ORDER BY hg, srv_host;
 
# 请求总数
SELECT hostgroup hg, srv_host, Queries, Bytes_data_sent, Bytes_data_recv, Latency_us FROM stats_mysql_connection_pool WHERE ConnUsed+ConnFree > 0 ORDER BY hg, srv_host;
```
 
### 5. 查看计数器 `stats_mysql_commands_counters`
 
```sql
SELECT * FROM stats_mysql_commands_counters ORDER BY Total_cnt DESC LIMIT 1\G
```
 
### 6. 分析
 
- 查找出总执行时间排在前5的查询:
 
```sql
SELECT digest,SUBSTR(digest_text,0,200),count_star,sum_time,schemaname FROM stats_mysql_query_digest WHERE digest_text LIKE 'SELECT%' ORDER BY sum_time DESC LIMIT 5;
```
 
- 查找出执行次数排在前5的查询:
 
```sql
SELECT digest,SUBSTR(digest_text,0,100),count_star,sum_time,schemaname FROM stats_mysql_query_digest WHERE digest_text LIKE 'SELECT%' ORDER BY count_star DESC LIMIT 5;
```
 
- 查找最长执行时间排在前30的查询:
 
```sql
SELECT digest,digest_text,count_star,sum_time,sum_time/count_star avg_time, min_time, max_time,schemaname FROM stats_mysql_query_digest WHERE digest_text LIKE 'SELECT%' ORDER BY max_time DESC LIMIT 30;
```
 
### 7. 创建基于用户的路由
 
1. 在目标数据库服务器上添加用户`user@password`,并设置好相应的数据库权限;
 
2. 添加`mysql_users`用户:
 
```sql
INSERT INTO mysql_users(username,password,default_hostgroup,default_schema) VALUES ('user','password',2,'proxy_server');
 
LOAD MYSQL USERS TO RUNTIME;
SAVE MYSQL USERS TO DISK;
```