Description:
Hi,
the MySQL-Proxy can be easily fooled to write to the slave.
Here is the output of the mysql-proxy with activated debug:
[connect_server] 127.0.0.1:21675
[1].connected_clients = 0
[1].pool.cur_idle = 2
[1].pool.max_idle = 8
[1].pool.min_idle = 1
[1].type = 1
[1].state = 1
[2].connected_clients = 0
[2].pool.cur_idle = 0
[2].pool.max_idle = 8
[2].pool.min_idle = 1
[2].type = 2
[2].state = 0
[2] idle-conns below min-idle
[read_query] 127.0.0.1:21675
current backend = 0
client default db = test
client username = root
query = show databases
sending to backend : :3306
is_slave : false
server default db: test
server username : root
in_trans : false
in_calc_found : false
COM_QUERY : true
[read_query] 127.0.0.1:21675
current backend = 0
client default db = test
client username = root
query = show tables
sending to backend : :3306
is_slave : false
server default db: test
server username : root
in_trans : false
in_calc_found : false
COM_QUERY : true
[read_query] 127.0.0.1:21675
current backend = 0
client default db = test
client username = root
sending to backend : :3306
is_slave : false
server default db: test
server username : root
in_trans : false
in_calc_found : false
COM_QUERY : false
[read_query] 127.0.0.1:21675
current backend = 0
client default db = test
client username = root
query = select @@version_comment limit 1
sending to backend : 127.0.0.1:3307
is_slave : true
server default db: test
server username : root
in_trans : false
in_calc_found : false
COM_QUERY : true
[read_query] 127.0.0.1:21675
current backend = 0
client default db = test
client username = root
query = select USER()
sending to backend : 127.0.0.1:3307
is_slave : true
server default db: test
server username : root
in_trans : false
in_calc_found : false
COM_QUERY : true
[read_query] 127.0.0.1:21675
current backend = 0
client default db = test
client username = root
query = CREATE TABLE test (test int)
sending to backend : :3306
is_slave : false
server default db: test
server username : root
in_trans : false
in_calc_found : false
COM_QUERY : true
[read_query] 127.0.0.1:21675
current backend = 0
client default db = test
client username = root
query = SELECT * FROM test
sending to backend : 127.0.0.1:3307
is_slave : true
server default db: test
server username : root
in_trans : false
in_calc_found : false
COM_QUERY : true
[read_query] 127.0.0.1:21675
current backend = 0
client default db = test
client username = root
query = SELECT SQL_CALC_FOUND_ROWS * FROM test
sending to backend : 127.0.0.1:3307
is_slave : true
server default db: test
server username : root
in_trans : false
in_calc_found : true
COM_QUERY : true
(read_query_result) staying on the same backend
in_trans : false
in_calc_found : true
have_insert_id : nil
[read_query] 127.0.0.1:21675
current backend = 2
client default db = test
client username = root
query = INSERT INTO test VALUES (1)
sending to backend : 127.0.0.1:3307
is_slave : true
server default db: test
server username : root
in_trans : false
in_calc_found : true
COM_QUERY : true
(read_query_result) staying on the same backend
in_trans : false
in_calc_found : true
have_insert_id : false
How to repeat:
Start a proxy with one master and one slave (I did with)
mysql-proxy \
--pid-file=/var/run/mysqld/mysql-proxy.pid \
--proxy-lua-script=/usr/share/mysql-proxy/rw-splitting.lua \
--proxy-backend-addresses=:3306 \
--proxy-read-only-backend-addresses=127.0.0.1:3307
Create enough connections to the proxy to make the proxy actually connect you to the slave for reads.
Try:
CREATE TABLE test (test int); -- master chosen as expected
SELECT * FROM test; -- slave chosen
SELECT SQL_CALC_FOUND_ROWS * FROM test; -- slave chosen again
INSERT INTO test VALUES (1); -- done on the slave
Suggested fix:
Make the writing statements overrule 'is_in_select_calc_found_rows' in server selection.