How to Fix Memory Leak in Doctrine Migrations
I had to write a Doctrine migration to fix some bad data. Unfortunately there was so much data (~600K records) that the migration leaked. The memory consumption reaches about 12Gb! That’s not really acceptable!
Usually, when there is a leak in Doctrine DBAL (not the ORM), it comes from the SQL logger. When you execute 600K SQL queries, there are 600K log records in the memory!
With Doctrine DBAL 2, we can write the following line of code to avoid the leak:
$this->connection->getConfiguration()->setSQLLogger(null);
However, this doesn’t work anymore with Doctrine DBAL 3! Now they have a middleware system to build the connection. All middlewares wrap the driver to add more capabilities.
So, to fix the migration, I decided to remove all middlewares and create a new connection:
final class Version20230206154337 extends AbstractMigration
{
public function up(Schema $schema): void
{
$this->connection->getConfiguration()->setMiddlewares([]);
$this->connection = DriverManager::getConnection(
$this->connection->getParams(),
$this->connection->getConfiguration(),
);
// regular doctrine migration code
}
Obviously, removing all middlewares can be a bad idea, but in my case only the followings were registered:
Doctrine\DBAL\Logging\MiddlewareDoctrine\Bundle\DoctrineBundle\Middleware\DebugMiddlewareSentry\SentryBundle\Tracing\Doctrine\DBAL\TracingDriverMiddleware
Each middleware brings debug, so it’s safe to remove them all. But some colleagues pushed me to find the culprit, and you may be surprised, but it’s the DebugMiddleware!
If you prefer to remove only this middleware, you can use the following code:
$middlewares = array_filter(
$this->connection->getConfiguration()->getMiddlewares(),
fn ($middleware) => !$middleware instanceof \Doctrine\Bundle\DoctrineBundle\Middleware\DebugMiddleware
);
$this->connection->getConfiguration()->setMiddlewares($middlewares);
I hope this article can help you to reduce memory leak when dealing with a big amount of data.
Commentaires et discussions
Ces clients ont profité de notre expertise
En tant que joaillier 100 % numérique, l’équipe de Courbet Paris a souhaité se doter d’une plateforme eCommerce, capable d’offrir une expérience moderne qui revalorise l’acte d’achat de produits de joaillerie sur internet. JoliCode a accompagné leur équipe en développant une plateforme robuste, mais aussi évolutive, afin de répondre aux enjeux business…
L’application repose sur un socle Symfony robuste, avec une interface d’administration EasyAdmin dédiée à la gestion des utilisateurs et des contenus (import de données depuis des documents excel). Les datavisualisations sont affichées et rendues réactives grâce au framework React. Côté expérience, l’utilisateur peut naviguer entre deux univers métiers…
L’équipe de Finarta a fait appel à JoliCode pour le développement de leur plateforme Web. Basée sur le framework Symfony 2, l’application est un réseau privé de galerie et se veut être une place de communication et de vente d’oeuvres d’art entre ses membres. Pour cela, de nombreuses règles de droits ont été mises en places et une administration poussée…