You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: doc/mirroring.md
+34-29
Original file line number
Diff line number
Diff line change
@@ -3,7 +3,7 @@
3
3
This is the first implementation of mirroring in ProxySQL, and should be considered experimental:
4
4
* specification can change in the near future
5
5
* 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
7
7
8
8
### Extensions to mysql_query_rules
9
9
@@ -43,8 +43,8 @@ apply INT CHECK(apply IN (0,1)) NOT NULL DEFAULT 0)
43
43
44
44
## Implementation overview
45
45
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.
48
48
If a source queries is matched against multiple query rules, it is possible that `mirror_flagOUT` or `mirror_hostgroup` are changes multiple times.
49
49
The mirroring logic is the follow:
50
50
* 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:
55
55
56
56
## Examples
57
57
58
-
# Mirror selects to same hostgroup
58
+
###Mirror selects to same hostgroup
59
59
60
60
In this very simple example we will just send all `SELECT` statements to hostgroup2, both the original and the mirror ones.
61
61
@@ -97,7 +97,7 @@ mysql> SELECT id FROM sbtest1 LIMIT 3;
97
97
3 rows inset (0.02 sec)
98
98
```
99
99
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:
101
101
```sql
102
102
Admin>select hostgroup,count_star,schemaname,digest_text from stats_mysql_query_digest ORDER BY digest;
Admin>INSERT INTO mysql_query_rules (rule_id,active,match_pattern,destination_hostgroup,mirror_flagOUT,apply) VALUES (5,1,'FROM sbtest1 ',2,100,1);
262
261
Query OK, 1 row affected (0.00 sec)
263
262
```
264
263
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:
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)
314
314
```
315
315
316
316
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` .
* the mirrored query was way slower because ignored the index
366
366
367
-
# Advanced example: use mirroring to test query rewrite
367
+
###Advanced example: use mirroring to test query rewrite
368
368
369
369
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?
370
370
To be more specific, the problem is to understand if the rewrite is correct without affecting live traffic.
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);
381
381
Query OK, 1 row affected (0.00 sec)
382
382
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)
384
385
```
385
386
386
387
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;
430
431
```
431
432
432
433
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:
434
435
```
435
436
re2/re2.cc:881: invalid rewrite pattern: SELECT DISTINCT c FROM sbtest\1 WHERE id = \3 \+ \4 ORDER BY c
436
437
```
@@ -439,7 +440,8 @@ Indeed, it is an incorrect syntax , let fix this:
439
440
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;
440
441
Query OK, 1 row affected (0.00 sec)
441
442
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)
443
445
444
446
Admin>SELECTCOUNT(*) FROM stats_mysql_query_digest_reset;
445
447
```
@@ -469,17 +471,18 @@ Admin> select hostgroup,count_star,sum_time,digest_text from stats_mysql_query_d
469
471
470
472
Well, yes, the query was rewritten correctly, and was also executed :-)
471
473
472
-
# Advanced example: use mirroring to test query rewrite
474
+
###Advanced example: use mirroring and firewall to test query rewrite
473
475
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.
476
478
477
479
Example:
478
480
```sql
479
481
Admin>UPDATE mysql_query_rules SET error_msg="random error, blah blah"WHERE rule_id=10;
480
482
Query OK, 1 row affected (0.00 sec)
481
483
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)
483
486
484
487
Admin>SELECTCOUNT(*) FROM stats_mysql_query_digest_reset;
485
488
```
@@ -516,4 +519,6 @@ Admin> SELECT * from stats_mysql_query_rules;
516
519
2 rows inset (0.00 sec)
517
520
```
518
521
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