Over a million developers have joined DZone.

Orchestrator and ProxySQL

DZone 's Guide to

Orchestrator and ProxySQL

Learn how can you use Orchestrator and ProxySQL together and a few tips for your configuration and failover prep.

· Database Zone ·
Free Resource

In this blog post, I am going to show you how can you use Orchestrator and ProxySQL together.

In my previous blog post, I showed how to use bash scripts and move virtual IPs with Orchestrator. As in that post, I assume you already have Orchestrator working. If not, you can find the installation steps here.

In the case of a failover, Orchestrator changes the MySQL topology and promotes a new master. But who lets the application know about this change? This is where ProxySQL helps us.


You can find the ProxySQL install steps here. In our test, we use the following topology:


For this topology we need the next rules in “ProxySQL”:

INSERT INTO mysql_servers(hostname,hostgroup_id,port,weight,max_replication_lag)VALUES('',601,3306,1000,10);

INSERT INTO mysql_servers(hostname,hostgroup_id,port,weight,max_replication_lag)VALUES('',601,3306,1000,10);

INSERT INTO mysql_servers(hostname,hostgroup_id,port,weight,max_replication_lag)VALUES('',601,3306,1000,0);

INSERT INTO mysql_servers(hostname,hostgroup_id,port,weight,max_replication_lag)VALUES('',600,3306,1000,0);

INSERT INTO mysql_replication_hostgroups VALUES(600,601,'');


insert into mysql_query_rules(username,destination_hostgroup,active)values('testuser_w',600,1);

insert into mysql_query_rules(username,destination_hostgroup,active)values('testuser_r',601,1);

insert into mysql_query_rules(username,destination_hostgroup,active,retries,match_digest)values('testuser_rw',601,1,3,'^SELECT');


insert into mysql_users(username,password,active,default_hostgroup,default_schema,transaction_persistent)values('testuser_w','Testpass1.',1,600,'test',1);

insert into mysql_users(username,password,active,default_hostgroup,default_schema,transaction_persistent)values('testuser_r','Testpass1.',1,601,'test',1);

insert into mysql_users(username,password,active,default_hostgroup,default_schema,transaction_persistent)values('testuser_rw','Testpass1.',1,600,'test',1);


Choosing the New Master

ProxySQL does not know what the topology looks like, which is really important. ProxySQL is monitoring the “read_only” variables on the MySQL servers, and the server where read_only=off is going to get the writes. If the old master went down and we changed our topology, we have to change the read_only variables on the new master. Of course, applications like MHA or Orchestrator can do that for us.

We have two possibilities here: the master went down, or we want to promote a new master.

Master Is Down

If the master goes down, Orchestrator is going to change the topology and set the read_only=OFF on the promoted master. ProxySQL is going to realize the master went down and send the write traffic to the server where read_only=OFF.

Let’s do a test. After we stopped MySQL on “”, Orchestrator promoted “” as the new master. ProxySQL is using it now as a master:

mysql>select*fromstats_mysql_connection_poolwherehostgroupbetween600and601order byhostgroup,srv_hostdesc;










Promoting a New Master

When we perform a graceful-master-takeover with Orchestrator, it promotes a slave as a new master, removes the old master from the replicaset and sets read_only=ON.

From Orchestrator’s point of view, this is great. It promoted a slave as a new master, and old master is not part of the replicaset anymore. But as I mentioned earlier, ProxySQL does not know what the replicaset looks like.

It only knows we changed the read_only variables on some servers. It is going to send reads to the old master, but it does not have up-to-date data anymore. This is not good at all.

We have two options to avoid this.

Remove a Master From a Read Hostgroup

If the master is not part of the read hostgroup, ProxySQL won’t send any traffic there after we promote a new master. But in this case, if we lose the slaves, ProxySQL cannot redirect the reads to the master. If we have a lot of slaves, and the replication stopped on the saves because of an error or mistake, the master probably won’t be able to handle all the read traffic. But if we only have a few slaves, it would be good if the master can also handle reads if there is an issue on the slaves.

Using a Scheduler

In this great blog post from Marco Tusa, we can see that ProxySQL can use “Schedulers”. We can use the same idea here as well. I wrote a script based on Marco’s that can recognize if the old master is no longer a part of the replicaset.

The script checks the followings:

  • read_only=ON – the server is read-only (on the slave servers, this has to be ON)
  • repl_lag  is NULL – on the master, this should be NULL (if the seconds_behind_master is not defined, ProxySQL will report repl_lag is NULL)

If the read_only=ON, it means the server is not the master at the moment. But if the repl_lag is NULL, it means the server is not replicating from anywhere, and it probably was a master. It has to be removed from the Hostgroup.

Adding a Scheduler

INSERTINTOscheduler(id,interval_ms,filename,arg1)values(10,2000,"/var/lib/proxysql/server_monitor.pl","-u=admin -p=admin -h= -G=601 -P=6032 --debug=0  --log=/var/lib/proxysql/server_check");


The script has parameters like username, password or port. But we also have to define the read Hostgroup (-G).

Let’s see what happens with ProsySQL after we run the command orchestrator-cgraceful-master-takeover-irep1-drep2 :

mysql>select*from stats_mysql_connection_pool where hostgroup between600and601order by hostgroup,srv_host desc;









4rows inset(0.00sec)


Because ProxySQL redirects the traffic based on the read_only  variables, it is important to start the servers with read_only=ON (even on the master). In that case, we can avoid getting writes on many servers at the same time.

If we want to use graceful-master-takeover with Orchestrator, we have to use a scheduler that can remove the old master from the read Hostgroup.

proxysql ,orchestrator ,database ,failover

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}