REBELinBLUE
4 years ago
288
1
Laravel

STMT_PREPARE error only with mysqlnd

Posted 4 years ago by REBELinBLUE

I have a queue listener which occasionally throws this error.

Next exception 'Illuminate\Database\QueryException' with message 'Error while sending STMT_PREPARE packet. PID=24865 (SQL: select * from `deployments` where `deployments`.`deleted_at` is null and `deployments`.`id` = 45 limit 1)' in /var/www/deployer/releases/20151011222847/vendor/laravel/framework/src/Illuminate/Database/Connection.php:651
Stack trace:
#0 /var/www/deployer/releases/20151011222847/vendor/laravel/framework/src/Illuminate/Database/Connection.php(611): Illuminate\Database\Connection->runQueryCallback('select * from `...', Array, Object(Closure))
#1 /var/www/deployer/releases/20151011222847/vendor/laravel/framework/src/Illuminate/Database/Connection.php(324): Illuminate\Database\Connection->run('select * from `...', Array, Object(Closure))
#2 /var/www/deployer/releases/20151011222847/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php(1398): Illuminate\Database\Connection->select('select * from `...', Array, true)
#3 /var/www/deployer/releases/20151011222847/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php(1388): Illuminate\Database\Query\Builder->runSelect()
#4 /var/www/deployer/releases/20151011222847/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php(1373): Illuminate\Database\Query\Builder->getFresh(Array)
#5 /var/www/deployer/releases/20151011222847/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(409): Illuminate\Database\Query\Builder->get(Array)
#6 /var/www/deployer/releases/20151011222847/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(168): Illuminate\Database\Eloquent\Builder->getModels(Array)
#7 /var/www/deployer/releases/20151011222847/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(140): Illuminate\Database\Eloquent\Builder->get(Array)
#8 /var/www/deployer/releases/20151011222847/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(87): Illuminate\Database\Eloquent\Builder->first(Array)
#9 /var/www/deployer/releases/20151011222847/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(119): Illuminate\Database\Eloquent\Builder->find(45, Array)
#10 [internal function]: Illuminate\Database\Eloquent\Builder->findOrFail(45)
#11 /var/www/deployer/releases/20151011222847/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(3459): call_user_func_array(Array, Array)
#12 /var/www/deployer/releases/20151011222847/vendor/laravel/framework/src/Illuminate/Queue/SerializesModels.php(65): Illuminate\Database\Eloquent\Model->__call('findOrFail', Array)
#13 /var/www/deployer/releases/20151011222847/vendor/laravel/framework/src/Illuminate/Queue/SerializesModels.php(65): REBELinBLUE\Deployer\Deployment->findOrFail(45)
#14 /var/www/deployer/releases/20151011222847/vendor/laravel/framework/src/Illuminate/Queue/SerializesModels.php(40): REBELinBLUE\Deployer\Jobs\DeployProject->getRestoredPropertyValue(Object(Illuminate\Contracts\Database\ModelIdentifier))
#15 [internal function]: REBELinBLUE\Deployer\Jobs\DeployProject->__wakeup()
#16 /var/www/deployer/releases/20151011222847/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(38): unserialize('O:39:"REBELinBL...')
#17 /var/www/deployer/releases/20151011222847/vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(129): Illuminate\Queue\CallQueuedHandler->call(Object(Illuminate\Queue\Jobs\BeanstalkdJob), Array)
#18 /var/www/deployer/releases/20151011222847/vendor/laravel/framework/src/Illuminate/Queue/Jobs/BeanstalkdJob.php(53): Illuminate\Queue\Jobs\Job->resolveAndFire(Array)
#19 /var/www/deployer/releases/20151011222847/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(208): Illuminate\Queue\Jobs\BeanstalkdJob->fire()
#20 /var/www/deployer/releases/20151011222847/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(159): Illuminate\Queue\Worker->process('beanstalkd', Object(Illuminate\Queue\Jobs\BeanstalkdJob), '1', 0)
#21 /var/www/deployer/releases/20151011222847/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(111): Illuminate\Queue\Worker->pop(NULL, 'deployer-high,d...', 0, '3', '1')
#22 /var/www/deployer/releases/20151011222847/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(87): Illuminate\Queue\Worker->runNextJobForDaemon(NULL, 'deployer-high,d...', 0, '3', '1')
#23 /var/www/deployer/releases/20151011222847/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(103): Illuminate\Queue\Worker->daemon(NULL, 'deployer-high,d...', 0, 128, '3', '1')
#24 /var/www/deployer/releases/20151011222847/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(71): Illuminate\Queue\Console\WorkCommand->runWorker(NULL, 'deployer-high,d...', 0, 128, true)
#25 [internal function]: Illuminate\Queue\Console\WorkCommand->fire()
#26 /var/www/deployer/releases/20151011222847/vendor/laravel/framework/src/Illuminate/Container/Container.php(503): call_user_func_array(Array, Array)
#27 /var/www/deployer/releases/20151011222847/vendor/laravel/framework/src/Illuminate/Console/Command.php(150): Illuminate\Container\Container->call(Array)
#28 /var/www/deployer/releases/20151011222847/vendor/symfony/console/Command/Command.php(259): Illuminate\Console\Command->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#29 /var/www/deployer/releases/20151011222847/vendor/laravel/framework/src/Illuminate/Console/Command.php(136): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#30 /var/www/deployer/releases/20151011222847/vendor/symfony/console/Application.php(878): Illuminate\Console\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#31 /var/www/deployer/releases/20151011222847/vendor/symfony/console/Application.php(195): Symfony\Component\Console\Application->doRunCommand(Object(Illuminate\Queue\Console\WorkCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#32 /var/www/deployer/releases/20151011222847/vendor/symfony/console/Application.php(126): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#33 /var/www/deployer/releases/20151011222847/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(100): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#34 /var/www/deployer/releases/20151011222847/artisan(36): Illuminate\Foundation\Console\Kernel->handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#35 {main}

As you can see, it is when laravel is trying to get the model from the queue. It is queued with the following

class DeployProject extends Job implements SelfHandling, ShouldQueue
{
    use InteractsWithQueue, SerializesModels;

    private $deployment;

    public function __construct(Deployment $deployment)
    {
        $this->deployment = $deployment;
    }

    public function handle()
    {
        // Do stuff here
    }
}

So when Laravel tries to recreate the injected model the connection has died. Obviously this is not inside my code

This only happens when using the php5-mysqlnd extension, when using php5-mysql it works fine. I added DB::reconnect() to handle() but obviously it hasn't gotten that far at the stage it fails.

One way around this seems to be to add the following to the Deployment model

public function findOrFail()
{
    if (App::runningInConsole()) {
        DB::reconnect();
    }

    return parent::__call('findOrFail', func_get_args());
}

Which works but seems really hacky. Another way would be to just save the deployment ID in the queue, and have the handle() method load it after reconnecting, but again that seems a bit hacky when laravel should be taking care of this.

Does anyone have any ideas?

Please sign in or create an account to participate in this conversation.