Hi,
Background:
Our application has two traffic patterns:
--> Read Transaction is sent as "SET autocommit = 1; SELECT "
--> Write Transaction is sent as "SET autocommit = 0; SELECT|INSERT|UPDATE|DELETE; COMMIT;"
Problem Statement:
I am trying to set up Read/Write Split using ProxySQL's latest version 1.4 using above transaction patterns but I am not able to do so.
ProxySQL Configuration:
mysql> SELECT @@version;
+------------------+
| @@version |
+------------------+
| 1.4.0-0-ge2f0cc4 |
+------------------+
1 row in set (0.00 sec)
mysql> \! uname -a
Linux ip-172-21-35-79.ap-south-1.compute.internal 2.6.32-642.15.1.el6.x86_64 #1 SMP Fri Feb 24 14:31:22 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
mysql> SELECT *
-> FROM runtime_global_variables
-> WHERE variable_name = 'mysql-forward_autocommit';
+--------------------------+----------------+
| variable_name | variable_value |
+--------------------------+----------------+
| mysql-forward_autocommit | true |
+--------------------------+----------------+
1 row in set (0.00 sec)
mysql> SELECT *
-> FROM runtime_mysql_servers;
+--------------+---------------+------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+
| hostgroup_id | hostname | port | status | weight | compression | max_connections | max_replication_lag | use_ssl | max_latency_ms | comment |
+--------------+---------------+------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+
| 601 | 172.21.35.79 | 3310 | ONLINE | 1000 | 0 | 1000 | 10 | 0 | 0 | |
| 600 | 172.21.35.133 | 3310 | ONLINE | 1000 | 0 | 1000 | 10 | 0 | 0 | |
| 601 | 172.21.35.133 | 3310 | ONLINE | 200 | 0 | 1000 | 10 | 0 | 0 | |
| 601 | 172.21.35.94 | 3310 | ONLINE | 1000 | 0 | 1000 | 10 | 0 | 0 | |
+--------------+---------------+------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+
4 rows in set (0.00 sec)
mysql> SELECT *
-> FROM runtime_mysql_replication_hostgroups;
+------------------+------------------+-------------------------+
| writer_hostgroup | reader_hostgroup | comment |
+------------------+------------------+-------------------------+
| 600 | 601 | replication host groups |
+------------------+------------------+-------------------------+
1 row in set (0.00 sec)
mysql> SELECT username,active,use_ssl,default_hostgroup,default_schema,schema_locked,transaction_persistent,fast_forward,backend,frontend,max_connections
-> FROM runtime_mysql_users
-> WHERE username = 'mha_RW';
+----------+--------+---------+-------------------+----------------+---------------+------------------------+--------------+---------+----------+-----------------+
| username | active | use_ssl | default_hostgroup | default_schema | schema_locked | transaction_persistent | fast_forward | backend | frontend | max_connections |
+----------+--------+---------+-------------------+----------------+---------------+------------------------+--------------+---------+----------+-----------------+
| mha_RW | 1 | 0 | 600 | | 0 | 1 | 0 | 1 | 0 | 10000 |
| mha_RW | 1 | 0 | 600 | | 0 | 1 | 0 | 0 | 1 | 10000 |
+----------+--------+---------+-------------------+----------------+---------------+------------------------+--------------+---------+----------+-----------------+
2 rows in set (0.00 sec)
mysql> SELECT *
-> FROM runtime_mysql_query_rules
-> WHERE active = 1\G
*************************** 1. row ***************************
rule_id: 892
active: 1
username: mha_RW
schemaname: NULL
flagIN: 0
client_addr: NULL
proxy_addr: NULL
proxy_port: NULL
digest: NULL
match_digest: NULL
match_pattern: ^SELECT
negate_match_pattern: 0
re_modifiers: CASELESS
flagOUT: NULL
replace_pattern: NULL
destination_hostgroup: 601
cache_ttl: NULL
reconnect: NULL
timeout: NULL
retries: NULL
delay: NULL
next_query_flagIN: NULL
mirror_flagOUT: NULL
mirror_hostgroup: NULL
error_msg: NULL
sticky_conn: NULL
multiplex: NULL
log: NULL
apply: 1
comment: NULL
1 row in set (0.00 sec)
Question:
I have set up the user "mha_RW" with transaction_persistent = 1 which means that commands within a transaction should not be sent on slave.
I have also set up a Query rule which sends the regex pattern '^SELECT' on Read Hostgroup, I am expecting that transaction_persistent=1 will take precedence over the Query rule but it is not happening. SELECTS in the write transaction "SET autocommit = 0; SELECT; COMMIT;" are served from the Read Hostgroup even though they are enclosed within a transaction.
[root@ip-172-21-35-79 ~]# mysql -h 127.0.0.1 --port 6033 --user mha_RW -p'Test@123' -e 'set autocommit=0; select @@hostname; commit';
mysql: [Warning] Using a password on the command line interface can be insecure.
+---------------------------------------------+
| @@hostname |
+---------------------------------------------+
| ip-172-21-35-79.ap-south-1.compute.internal |
+---------------------------------------------+
[root@ip-172-21-35-79 ~]# mysql -h 127.0.0.1 --port 6033 --user mha_RW -p'Test@123' -e 'set autocommit=0; select @@hostname; commit';
mysql: [Warning] Using a password on the command line interface can be insecure.
+---------------------------------------------+
| @@hostname |
+---------------------------------------------+
| ip-172-21-35-94.ap-south-1.compute.internal |
+---------------------------------------------+
[root@ip-172-21-35-79 ~]# mysql -h 127.0.0.1 --port 6033 --user mha_RW -p'Test@123' -e 'set autocommit=0; select @@hostname; commit';
mysql: [Warning] Using a password on the command line interface can be insecure.
+---------------------------------------------+
| @@hostname |
+---------------------------------------------+
| ip-172-21-35-94.ap-south-1.compute.internal |
+---------------------------------------------+
Interesting thing is that if I create transactions using "BEGIN;SELECT;COMMIT" format then SELECT statements are always directed to Write Hostgroup:
[root@ip-172-21-35-79 ~]# mysql -h 127.0.0.1 --port 6033 --user mha_RW -p'Test@123' -e 'BEGIN;SELECT @@hostname;COMMIT;';
mysql: [Warning] Using a password on the command line interface can be insecure.
+----------------------------------------------+
| @@hostname |
+----------------------------------------------+
| ip-172-21-35-133.ap-south-1.compute.internal |
+----------------------------------------------+
[root@ip-172-21-35-79 ~]# mysql -h 127.0.0.1 --port 6033 --user mha_RW -p'Test@123' -e 'BEGIN;SELECT @@hostname;COMMIT;';
mysql: [Warning] Using a password on the command line interface can be insecure.
+----------------------------------------------+
| @@hostname |
+----------------------------------------------+
| ip-172-21-35-133.ap-south-1.compute.internal |
+----------------------------------------------+
[root@ip-172-21-35-79 ~]# mysql -h 127.0.0.1 --port 6033 --user mha_RW -p'Test@123' -e 'BEGIN;SELECT @@hostname;COMMIT;';
mysql: [Warning] Using a password on the command line interface can be insecure.
+----------------------------------------------+
| @@hostname |
+----------------------------------------------+
| ip-172-21-35-133.ap-south-1.compute.internal |
+----------------------------------------------+
Can someone please help me understand why the SELECT statements in former transaction pattern are not routed correctly to Write Hostgroup.
Regards,
Ankit