Enhanced Master-Slave Connection #313

Closed
wants to merge 1 commit into
from

Conversation

Projects
None yet
4 participants
Q A
Bug fix? no
New feature? yes
BC breaks? no?
Deprecations? no
Tests pass? yes
Fixed tickets -
License MIT

Current implementation of MasterSlaveConnection is very restrictive. The slave is picked up only when executeQuery is used. If appliacation uses prepare method in queries, every SELECT is done on master and this is bad for performance of master.

This PR changes how and when it picks the slave or master:

  1. Slave if master was never picked before and ONLY if getWrappedConnection, query, prepare, or executeQuery is used and the query begins with SELECT (case insensitive) string.
  2. Master picked when exec, executeUpdate, insert, delete, update, createSavepoint, releaseSavepoint, beginTransaction, rollback, commit is called.
  3. Master picked when query, prepare or executeQuery is called and the query doesn't begin with SELECT (case insensitive) string.
  4. If master was picked once during the lifetime of the connection it will always get picked afterwards.
  5. One slave connection is randomly picked ONCE during a request.

@stof stof commented on the diff Apr 26, 2013

lib/Doctrine/DBAL/Connections/MasterSlaveConnection.php
/**
* {@inheritDoc}
*/
public function executeUpdate($query, array $params = array(), array $types = array())
{
- $this->connect('master');
+ $connectionName = 'master';
+
+ $this->connect($connectionName);
@stof

stof Apr 26, 2013

Member

This change is not needed

Owner

beberlei commented Apr 27, 2013

The way we designed MasterSlaveConnection was to be as robust as possible, i don't want to change this even if it seems restrictive to you. Please use your own MasterSlaveConnection in your project in this case.

beberlei closed this Apr 27, 2013

@Koc Koc commented on the diff Apr 27, 2013

lib/Doctrine/DBAL/Connections/MasterSlaveConnection.php
@@ -222,12 +219,19 @@ protected function chooseConnectionConfiguration($connectionName, $params)
return $params['slaves'][array_rand($params['slaves'])];
}
+ protected function getConnectionTypeByStatement($statement)
+ {
+ return (preg_match('/^\s*SELECT\s+/i', $statement)) ? 'slave' : 'master';
@Koc

Koc Apr 27, 2013

Contributor

What about INSERT SELECT?

@andrejhudec

andrejhudec Apr 27, 2013

@Koc INSERT SELECT is sent to master, becuase this type of query doesn't begin with SELECT.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment