gerdes's avatar

Check read/write connection in use, how?

Hi,

We're using a single-master db cluster with one read-write node and several read-only nodes. From what I can tell, Laravel does support read and write specific connections (https://laravel.com/docs/8.x/database#read-and-write-connections) including a sticky option.

As explained in the docs, the sticky option forces all queries performed after a write-operation to use the write connection for the rest of the request cycle. However, requests only involving reading from the database will use only the read-only nodes.

Route::get("/write", function() {
	// Should default to using read-only nodes

	// Log connection -> read-only nodes

	// Switch to write-node to perform write operation
	User::create();

	// Log connection -> write node

	// With sticky option enabled, this query should also use the write-node
	$users = User::all();

	// Log connection -> write node

	return $users;
});

Route::get("/read-only", function() {
	// Should default to using read-only nodes

	// Log connection -> read-only nodes

	// This query should use the read-only nodes
	$users = User::all();

	// Log connection -> read-only nodes

	return $users;
});

Now, this is all very nice, but how do we test it? Is it possible to examine which connection was used for each query somehow? We don't want to force the connection using ::connection("mysql:read") etc. We just want to make sure everything is working as expected.

I've added Log connection comments in the above code the simulate the ideal solution to our concern. That would enable us to inspect that the right connection is being used.

I hope someone can help us. Thanks!

0 likes
8 replies
lat4732's avatar

I was trying to examine the same thing literally yesterday. I ended up watching the queries log inside DigitalOcean interface for our nodes so I can catch which node and when is used. Probably the easiest way of examining if its working is to chec kthe queries log for both nodes - in the master node the queries must be only INSERT, UPDATE, DELETE etc... And in the read-only node (slave) the queries must be only SELECT.

Anyways, you could try to listen query events:

https://laravel.com/docs/9.x/database#listening-for-query-events

Check the query object, probably it has the connection information.

gerdes's avatar

@Laralex Well, we want to test it locally. The write node should also have some select statements with the sticky option enabled. Is this really the only way?

lat4732's avatar

@gerdes I haven't tried to listen query events. But I guess it might be an option. I personally think the best way is to watch the query log for each node..

gerdes's avatar

@Laralex I could not make it work by inspecting the queries. I assigning an invalid value for the master node and then made sure everything still worked on endpoints only involving read operations. Not the best approach and I would assume Laravel offers a better solution.

Mavichow's avatar

Hi, was a lil late to the game, I'm in the midst of learning master/slave db.

Decided to post reply here instead of creating a new thread.

May I know how does Laravel know which "Read Only" host to access?

Say we have

  • Read only 1 @ EUROPE region
  • Read only 2 @ ASIA region
  • Write @ ASIA region

Do we need to have any custom setup to configure eg: user to access nearest read only host from the location/ip address? OR Laravel will automatically do the magic for us?

tldr; my question:

If a user from Europe region access the website, Laravel will automatically pull the db from Europe region automatically?

Please or to participate in this conversation.