-
-
Notifications
You must be signed in to change notification settings - Fork 9.7k
[Doctrine][Messenger] Remove old MySQL special handling that causes deadlocks #61963
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 7.4
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,11 +12,9 @@ | |
namespace Symfony\Component\Messenger\Bridge\Doctrine\Transport; | ||
|
||
use Doctrine\DBAL\Connection as DBALConnection; | ||
use Doctrine\DBAL\Driver\Exception as DriverException; | ||
use Doctrine\DBAL\Exception as DBALException; | ||
use Doctrine\DBAL\Exception\TableNotFoundException; | ||
use Doctrine\DBAL\LockMode; | ||
use Doctrine\DBAL\Platforms\AbstractMySQLPlatform; | ||
use Doctrine\DBAL\Platforms\OraclePlatform; | ||
use Doctrine\DBAL\Platforms\PostgreSQLPlatform; | ||
use Doctrine\DBAL\Query\ForUpdate\ConflictResolutionMode; | ||
|
@@ -59,7 +57,6 @@ class Connection implements ResetInterface | |
protected ?float $queueEmptiedAt = null; | ||
|
||
private bool $autoSetup; | ||
private bool $doMysqlCleanup = false; | ||
|
||
/** | ||
* Constructor. | ||
|
@@ -83,7 +80,6 @@ public function __construct( | |
public function reset(): void | ||
{ | ||
$this->queueEmptiedAt = null; | ||
$this->doMysqlCleanup = false; | ||
} | ||
|
||
public function getConfiguration(): array | ||
|
@@ -161,19 +157,6 @@ public function send(string $body, array $headers, int $delay = 0): string | |
|
||
public function get(): ?array | ||
{ | ||
if ($this->doMysqlCleanup && $this->driverConnection->getDatabasePlatform() instanceof AbstractMySQLPlatform) { | ||
try { | ||
$this->driverConnection->delete($this->configuration['table_name'], ['delivered_at' => '9999-12-31 23:59:59']); | ||
$this->doMysqlCleanup = false; | ||
} catch (DriverException $e) { | ||
// Ignore the exception | ||
} catch (TableNotFoundException $e) { | ||
if ($this->autoSetup) { | ||
$this->setup(); | ||
} | ||
} | ||
} | ||
|
||
get: | ||
$this->driverConnection->beginTransaction(); | ||
try { | ||
|
@@ -261,14 +244,6 @@ public function get(): ?array | |
public function ack(string $id): bool | ||
{ | ||
try { | ||
if ($this->driverConnection->getDatabasePlatform() instanceof AbstractMySQLPlatform) { | ||
if ($updated = $this->driverConnection->update($this->configuration['table_name'], ['delivered_at' => '9999-12-31 23:59:59'], ['id' => $id]) > 0) { | ||
$this->doMysqlCleanup = true; | ||
} | ||
|
||
return $updated; | ||
} | ||
|
||
return $this->driverConnection->delete($this->configuration['table_name'], ['id' => $id]) > 0; | ||
} catch (DBALException $exception) { | ||
throw new TransportException($exception->getMessage(), 0, $exception); | ||
|
@@ -278,14 +253,6 @@ public function ack(string $id): bool | |
public function reject(string $id): bool | ||
{ | ||
try { | ||
if ($this->driverConnection->getDatabasePlatform() instanceof AbstractMySQLPlatform) { | ||
if ($updated = $this->driverConnection->update($this->configuration['table_name'], ['delivered_at' => '9999-12-31 23:59:59'], ['id' => $id]) > 0) { | ||
$this->doMysqlCleanup = true; | ||
} | ||
|
||
return $updated; | ||
} | ||
|
||
return $this->driverConnection->delete($this->configuration['table_name'], ['id' => $id]) > 0; | ||
} catch (DBALException $exception) { | ||
throw new TransportException($exception->getMessage(), 0, $exception); | ||
|
@@ -569,6 +536,7 @@ private function addTableToSchema(Schema $schema): void | |
$table->addIndex(['queue_name']); | ||
$table->addIndex(['available_at']); | ||
$table->addIndex(['delivered_at']); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are those other indexes still necessary ? AFAICT, queries never put conditions on only one of those fields. They put conditions on either the primary key only or on the 3 fields together (which will use the new index covering them all). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
At least for MySQL/MariaDB, yeah. Those indexes are now useless and are not used. |
||
$table->addIndex(['queue_name', 'available_at', 'delivered_at', 'id']); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @psihius are you sure the ID field is needed? The select query doesn't use the ID field in the where condition. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The query does not, but the primary key is used within the index to lock the column, this makes locking more efficient. |
||
|
||
// We need to create a sequence for Oracle and set the id column to get the correct nextval | ||
if ($this->driverConnection->getDatabasePlatform() instanceof OraclePlatform) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This index is now useless as it's covered by the new index. I suggest to remove it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree. Also other 2 indexes are not needed too, since compound index covers it all
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For precision, the new index doesn't covers the other 2.
Index on columns a,b,c will be used on queries which have where condition on (a), on (a+b) or on (a + b + c). So queries with
where b = ?
orwhere c = ?
orwhere b = ? and c = ?
won't use the index on (a,b,c).Now, I still believe we can remove them since there is no queries with condition only on
available_at
ordelivered_at
or on (available_at
+delivered_at
), cf the other comment.#61963 (comment)