Skip to content

Commit 184cea9

Browse files
committed
Updating mirroring documentation
1 parent 5f8a5d9 commit 184cea9

File tree

1 file changed

+34
-29
lines changed

1 file changed

+34
-29
lines changed

doc/mirroring.md

+34-29
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
This is the first implementation of mirroring in ProxySQL, and should be considered experimental:
44
* specification can change in the near future
55
* isn't extensively tested
6-
* upgrade from previous version that do not support mirroring will lose any previously defined query rules
6+
* upgrades from previous versions that do not support mirroring will lose any previously defined query rules
77

88
### Extensions to mysql_query_rules
99

@@ -43,8 +43,8 @@ apply INT CHECK(apply IN (0,1)) NOT NULL DEFAULT 0)
4343

4444
## Implementation overview
4545

46-
When either `mirror_flagOUT` or `mirror_hostgroup` are set for a matching query, real time query mirroring is automatically enabled.
47-
Note that mirroring is enabled for the the final query, if it was rewritten: if the query was rewritten along the way, the mirroring logic applies to the rewritten query. Although, the mirrored query can be rewritten and modified again. Details below.
46+
When either `mirror_flagOUT` or `mirror_hostgroup` are set for a matching query, real time query mirroring is automatically enabled.
47+
Note that mirroring is enabled for the the final query, if the original was rewritten: if the query was rewritten along the way, the mirroring logic applies to the rewritten query. Although, the mirrored query can be rewritten and modified again. Details below.
4848
If a source queries is matched against multiple query rules, it is possible that `mirror_flagOUT` or `mirror_hostgroup` are changes multiple times.
4949
The mirroring logic is the follow:
5050
* if `mirror_flagOUT` or `mirror_hostgroup` are set while processing the source query, a new mysql session is created
@@ -55,7 +55,7 @@ The mirroring logic is the follow:
5555

5656
## Examples
5757

58-
# Mirror selects to same hostgroup
58+
### Mirror selects to same hostgroup
5959

6060
In this very simple example we will just send all `SELECT` statements to hostgroup2, both the original and the mirror ones.
6161

@@ -97,7 +97,7 @@ mysql> SELECT id FROM sbtest1 LIMIT 3;
9797
3 rows in set (0.02 sec)
9898
```
9999

100-
Back to the admin interface, we can see that the SELECT statements was executed twice:
100+
Back to the admin interface, we can see that the SELECT statement was executed twice:
101101
``` sql
102102
Admin> select hostgroup,count_star,schemaname,digest_text from stats_mysql_query_digest ORDER BY digest;
103103
+-----------+------------+--------------------+----------------------------------+
@@ -140,7 +140,7 @@ Admin> select hostgroup,count_star,schemaname,digest_text from stats_mysql_query
140140
It is important to note that ProxySQL collect metrics both for the original query and the mirrored one.
141141

142142

143-
# Mirror SELECT to different hostgroup
143+
### Mirror SELECT to different hostgroup
144144

145145
In this example, we will re-configure proxysql to send all the `SELECT` statements to hostgroup1, but to mirror them on hostgroup2 :
146146
``` sql
@@ -153,7 +153,7 @@ Query OK, 1 row affected (0.00 sec)
153153
Admin> LOAD MYSQL QUERY RULES TO RUNTIME; Query OK, 0 rows affected (0.00 sec)
154154
```
155155

156-
We also empty `stats_mysql_query_digest` to have a fresh start:
156+
We also empty `stats_mysql_query_digest` to have a fresh stats:
157157
``` sql
158158
Admin> SELECT COUNT(*) FROM stats_mysql_query_digest_reset;
159159
+----------+
@@ -193,26 +193,24 @@ Admin> select hostgroup,count_star,sum_time,digest_text from stats_mysql_query_d
193193
```
194194
The same identical query was sent to both hostgroup1 and hostgroup2!
195195

196-
# rewrite both source query and mirror
196+
### rewrite both source query and mirror
197197

198198
In this example, we will rewrite the original query, and then mirror it:
199199
For semplicity, we will rewrite `sbtest[0-9]+` to `sbtest3` :
200200
``` sql
201-
Admin> DELETE FROM mysql_query_rules; Query OK, 1 row affected (0.00 sec)
201+
Admin> DELETE FROM mysql_query_rules;
202+
Query OK, 1 row affected (0.00 sec)
202203

203204
Admin> INSERT INTO mysql_query_rules (rule_id,active,match_pattern,destination_hostgroup,replace_pattern,mirror_hostgroup,apply) VALUES (5,1,'sbtest[0-9]+',1,'sbtest3',2,1);
204205
Query OK, 1 row affected (0.00 sec)
205206

206-
Admin> LOAD MYSQL QUERY RULES TO RUNTIME; Query OK, 0 rows affected (0.00 sec)
207+
Admin> LOAD MYSQL QUERY RULES TO RUNTIME;
208+
Query OK, 0 rows affected (0.00 sec)
207209
```
208210

209211
Again, we reset `stats_mysql_query_digest` :
210212
``` sql
211-
Admin> SELECT COUNT(*) FROM stats_mysql_query_digest_reset; +----------+
212-
| COUNT(*) |
213-
+----------+
214-
| 2 |
215-
+----------+
213+
Admin> SELECT COUNT(*) FROM stats_mysql_query_digest_reset;
216214
```
217215

218216
From the mysql client we can run the usual query:
@@ -242,12 +240,12 @@ Admin> select hostgroup,count_star,sum_time,digest_text from stats_mysql_query_d
242240

243241
As expected, the modified query was executed on both hostgroups
244242

245-
# rewrite mirror query only
243+
### rewrite mirror query only
246244

247245
In this example we will rewrite only the mirrored query.
248246
This is very useful if we want, for example, try to understand the performance of a rewritten query, or if a new index can improve performance.
249247
In this specific example we will compare the performance of the same queries with and without the use of indexes.
250-
We will also send the queries to different hostgroups.
248+
We will also send the queries to same hostgroups.
251249

252250
The follow creates a rule (`rule_id=5`) that:
253251
* matches `FROM sbtest1 `
@@ -256,13 +254,14 @@ The follow creates a rule (`rule_id=5`) that:
256254
* does NOT set a `mirror_hostgroup`
257255

258256
``` sql
259-
Admin> DELETE FROM mysql_query_rules; Query OK, 1 row affected (0.00 sec)
257+
Admin> DELETE FROM mysql_query_rules;
258+
Query OK, 1 row affected (0.00 sec)
260259

261260
Admin> INSERT INTO mysql_query_rules (rule_id,active,match_pattern,destination_hostgroup,mirror_flagOUT,apply) VALUES (5,1,'FROM sbtest1 ',2,100,1);
262261
Query OK, 1 row affected (0.00 sec)
263262
```
264263

265-
Because `mirror_flagOUT` is set, a new session will be created to run the same query. Although `mirror_hostgroup` was not set, so the query will be sent to the default hostgroup for the specific user, according to `mysql_users`. Instead, we want to send the mirror query to the same hostgroup as the original. We could do this either setting `mirror_hostgroup` in rule with `rule_id=5` , or create a new rule. We will create a new rule, also to reqrite the query:
264+
Because `mirror_flagOUT` is set, a new session will be created to run the same query. Although `mirror_hostgroup` was not set, so the query will be sent to the default hostgroup for the specific user, according to `mysql_users`. Instead, we want to send the mirror query to the same hostgroup as the original. We could do this either setting `mirror_hostgroup` in rule with `rule_id=5` , or create a new rule. We will create a new rule, also to rewrite the query:
266265
``` sql
267266
Admin> INSERT INTO mysql_query_rules (rule_id,active,flagIN,match_pattern,destination_hostgroup,replace_pattern,apply) VALUES (10,1,100,'FROM sbtest1 ',2,'FROM sbtest1 IGNORE INDEX(k_1) ',1);
268267
Query OK, 1 row affected (0.00 sec)
@@ -310,7 +309,8 @@ destination_hostgroup: 2
310309
apply: 1
311310
2 rows in set (0.00 sec)
312311

313-
Admin> LOAD MYSQL QUERY RULES TO RUNTIME; Query OK, 0 rows affected (0.00 sec)
312+
Admin> LOAD MYSQL QUERY RULES TO RUNTIME;
313+
Query OK, 0 rows affected (0.00 sec)
314314
```
315315

316316
One important thing to note here is that in the rule with `rule_id=10` , the one the mirrored query will match against, we need to set `destination_hostgroup` and not `mirror_hostgroup` : `mirror_hostgroup` should be set only for the original query in order to immediately specify where the mirror query should be sent, without the need of extra rules in `mysql_query_rules` .
@@ -364,7 +364,7 @@ Table `stats_mysql_query_digest` confirms that:
364364
* the mirrored query was rewritten
365365
* the mirrored query was way slower because ignored the index
366366

367-
# Advanced example: use mirroring to test query rewrite
367+
### Advanced example: use mirroring to test query rewrite
368368

369369
While working on mirroring I was asked a completely different question, related to query rewrite: how one could know if the given regex matches given query, and verify that the rewrite pattern is correct?
370370
To be more specific, the problem is to understand if the rewrite is correct without affecting live traffic.
@@ -380,7 +380,8 @@ Query OK, 1 row affected (0.00 sec)
380380
Admin> INSERT INTO mysql_query_rules (rule_id,active,flagIN,match_pattern,destination_hostgroup,replace_pattern,apply) VALUES (10,1,100,'^SELECT DISTINCT c FROM sbtest([0-9]{1,2}) WHERE id BETWEEN ([0-9]+) AND ([0-9]+)\+([0-9]+) ORDER BY c$',2,'SELECT DISTINCT c FROM sbtest\1 WHERE id = \3 \+ \4 ORDER BY c',1);
381381
Query OK, 1 row affected (0.00 sec)
382382

383-
Admin> LOAD MYSQL QUERY RULES TO RUNTIME; Query OK, 0 rows affected (0.00 sec)
383+
Admin> LOAD MYSQL QUERY RULES TO RUNTIME;
384+
Query OK, 0 rows affected (0.00 sec)
384385
```
385386

386387
The regex above are quite complex, and this is why mirroring helps instead of rewriting live traffic.
@@ -430,7 +431,7 @@ Admin> SELECT * from stats_mysql_query_rules;
430431
```
431432

432433
Rule with `rule_id=10` was a match according to `hits` in `stats_mysql_query_rules`.
433-
Why the query wasn't rewritten than? the error log has this information:
434+
Why the query wasn't rewritten than? The error log has this information:
434435
```
435436
re2/re2.cc:881: invalid rewrite pattern: SELECT DISTINCT c FROM sbtest\1 WHERE id = \3 \+ \4 ORDER BY c
436437
```
@@ -439,7 +440,8 @@ Indeed, it is an incorrect syntax , let fix this:
439440
Admin> UPDATE mysql_query_rules SET replace_pattern='SELECT DISTINCT c FROM sbtest\1 WHERE id = \3 + \4 ORDER BY c' WHERE rule_id=10;
440441
Query OK, 1 row affected (0.00 sec)
441442

442-
Admin> LOAD MYSQL QUERY RULES TO RUNTIME; Query OK, 0 rows affected (0.00 sec)
443+
Admin> LOAD MYSQL QUERY RULES TO RUNTIME;
444+
Query OK, 0 rows affected (0.00 sec)
443445

444446
Admin> SELECT COUNT(*) FROM stats_mysql_query_digest_reset;
445447
```
@@ -469,17 +471,18 @@ Admin> select hostgroup,count_star,sum_time,digest_text from stats_mysql_query_d
469471

470472
Well, yes, the query was rewritten correctly, and was also executed :-)
471473

472-
# Advanced example: use mirroring to test query rewrite
474+
### Advanced example: use mirroring and firewall to test query rewrite
473475

474-
Taking the previous example/exercises a bit forward: is it possible to how a query will be rewritten without executing it? YES!
475-
To achieve this, we will set `error_msg` for the mirrored query: in this way ProxySQL will process the query, but it will filter it without sending it to any mysql servers.
476+
Taking the previous example/exercise a bit forward: is it possible to know how a query will be rewritten without executing it? YES!
477+
To achieve this, we will set `error_msg` for the mirrored query: in this way ProxySQL will process the query, but it will filter it without sending it to any mysql servers. As stated in the very beginning, the mirrored query can be modified, and firewall it is an example of modifying the mirrored query.
476478

477479
Example:
478480
``` sql
479481
Admin> UPDATE mysql_query_rules SET error_msg="random error, blah blah" WHERE rule_id=10;
480482
Query OK, 1 row affected (0.00 sec)
481483

482-
Admin> LOAD MYSQL QUERY RULES TO RUNTIME; Query OK, 0 rows affected (0.01 sec)
484+
Admin> LOAD MYSQL QUERY RULES TO RUNTIME;
485+
Query OK, 0 rows affected (0.01 sec)
483486

484487
Admin> SELECT COUNT(*) FROM stats_mysql_query_digest_reset;
485488
```
@@ -516,4 +519,6 @@ Admin> SELECT * from stats_mysql_query_rules;
516519
2 rows in set (0.00 sec)
517520
```
518521

519-
Great! We know that the query was rewritten, but actually not sent anywhere (`sum_time=0` because the response was immediate, and `hostgroup=-1` has the special meaning of "not sent anywhere").
522+
Great! We know that the query was rewritten, but actually not sent anywhere:
523+
* `sum_time=0` because the response was immediate
524+
* `hostgroup=-1` has the special meaning of "not sent anywhere"

0 commit comments

Comments
 (0)