diff --git a/Changes b/Changes index 94449a84..324fe7da 100644 --- a/Changes +++ b/Changes @@ -10,6 +10,11 @@ Revision history for Perl extension App::Sqitch exception objects rather than strings, for more consistent error handling throughout. - Removed duplicate DBI error handling code from engines and tests. + - Fixed an order of operation issue that prevented Sqitch from detecting + Yugabyte before attempting to create an advisory lock, which results in + an error for more recent Yugabyte releases. Also set a GUC to avoid the + advisory lock errors altogether. Thanks to Stefano Ricciardi for the + report and to Franck Pachot for the GUC suggestion (#841). 1.4.1 2024-02-04T16:35:32Z - Removed the quoting of the role and warehouse identifiers that was diff --git a/lib/App/Sqitch/Engine/pg.pm b/lib/App/Sqitch/Engine/pg.pm index 312ac1bc..7f1d502e 100644 --- a/lib/App/Sqitch/Engine/pg.pm +++ b/lib/App/Sqitch/Engine/pg.pm @@ -144,7 +144,16 @@ has dbh => ( my $v = $dbh->selectcol_arrayref( q{SELECT split_part(version(), ' ', 2)} )->[0] // ''; - $self->_provider('yugabyte') if $v =~ /-YB-/; + + # Detect Yugabyte. + if ($v =~ /-YB-/) { + $self->_provider('yugabyte'); + # Disable advisory lock errors, if supported. + try { + $dbh->do('SET yb_silence_advisory_locks_not_supported_error = true') + }; + } + return; }, }, @@ -287,7 +296,11 @@ sub begin_work { # Override to try to acquire a lock on a constant number without waiting. sub try_lock { - shift->dbh->selectcol_arrayref( + my $self = shift; + # _provider not set till we fetch dbh. + my $dbh = $self->dbh; + return 1 if $self->_provider ne 'postgres'; + $dbh->selectcol_arrayref( 'SELECT pg_try_advisory_lock(75474063)' )->[0] } @@ -296,6 +309,7 @@ sub try_lock { # until timeout. sub wait_lock { my $self = shift; + my $dbh = $self->dbh; # Yugabyte does not support advisory locks. # https://github.com/yugabyte/yugabyte-db/issues/3642 @@ -304,7 +318,6 @@ sub wait_lock { return 1 if $self->_provider ne 'postgres'; # Asynchronously request a lock with an indefinite wait. - my $dbh = $self->dbh; $dbh->do( 'SELECT pg_advisory_lock(75474063)', { pg_async => DBD::Pg::PG_ASYNC() },