preaction / Minion-Backend-mysql

MySQL backend for the 🐙 Minion job runner
Other
7 stars 14 forks source link

This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration... #27

Closed yahermann closed 4 years ago

yahermann commented 4 years ago

Using MySQL 8, and while trying to setup Minion as a standalone job queue (for use with Dancer), I got the following error:

DBD::mysql::st execute failed: This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable) at /home/hermann/perl5/perlbrew/perls/perl-5.26.2/lib/site_perl/5.26.2/Mojo/mysql/Migrations.pm line 125.

Here's a reference to what is meant by binary logging and why functions have to be specified as DETERMINISTIC, NO SQL, or READS SQL DATA: https://dev.mysql.com/doc/refman/8.0/en/stored-programs-logging.html

Looking at https://metacpan.org/source/PREACTION/Minion-Backend-mysql-0.19/lib/Minion/Backend/mysql.pm, line 1553, none of the above appear to be specified in the created function.

This fixes it: SET GLOBAL log_bin_trust_function_creators = 1;

Not sure if setting this is required if using MySQL 5. May be new for MySQL 8.

For more background, here's my test code:

use Minion;
use Minion::Backend::mysql;

# Connect to backend
my $minion = Minion->new(
    mysql => 'mysql://my_user:my_password@/my_minion_db'
);

# Add tasks
$minion->add_task(something_slow => sub {
  my ($job, @args) = @_;
  sleep 5;
  print "This is a background worker process.\n";
});

# Enqueue jobs
$minion->enqueue(something_slow => ['foo', 'bar']);
$minion->enqueue(something_slow => [1, 2, 3] => {priority => 5});

# Perform jobs for testing
$minion->enqueue(something_slow => ['foo', 'bar']);
$minion->perform_jobs;

# Start a worker to perform up to 12 jobs concurrently
my $worker = $minion->worker;
$worker->status->{jobs} = 12;
$worker->run;
preaction commented 4 years ago

I don't feel it is appropriate to bypass security restrictions like this, so I instead annotated the function to add the right declarations (NOT DETERMINISTIC, MODIFIES SQL DATA, SQL SECURITY INVOKER). If your server's binary logging is set up correctly (mixed or row-based), it will be fine. If your binlog is statement based, it won't work with Minion and I don't know of any way to make it work.

yahermann commented 4 years ago

I completely agree.

SET GLOBAL log_bin_trust_function_creators = 1; is a workaround. The correct fix is to add the required declaration to the schema, as you have done.

Thank you!

And to the extent Minion is not compatible with a given server's binary logging setup, I think a good descriptive error message would be helpful.