Skip to content

Commit

Permalink
Properly avoid advisory Yugabyte lock erorrs
Browse files Browse the repository at this point in the history
The `try_lock` method was not properly checking for Yugabyte before
attempting to acquire an adivosory lock. Likely it used to be a warning,
but now is an error that cannot be avoided. So have `try_lock` check for
Yugabyte before attempting to take an advisory lock. This requires
fetching the database handle, first, as the database is not identified
until it connects. So also fetch the handle earlier in `wait_lock`, just
to be careful.

While at it, on Yugabyte set the
`yb_silence_advisory_locks_not_supported_error` GUC to avoid the whole
issue whenever possible.

Fixes #841.
  • Loading branch information
theory committed Dec 30, 2024
1 parent 91f1999 commit 0893114
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 3 deletions.
5 changes: 5 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
14 changes: 11 additions & 3 deletions lib/App/Sqitch/Engine/pg.pm
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,11 @@ has dbh => (
my $v = $dbh->selectcol_arrayref(
q{SELECT split_part(version(), ' ', 2)}
)->[0] // '';
$self->_provider('yugabyte') if $v =~ /-YB-/;
if ($v =~ /-YB-/) {
$dbh->do('SET yb_silence_advisory_locks_not_supported_error = true');
$self->_provider('yugabyte')
}

return;
},
},
Expand Down Expand Up @@ -287,7 +291,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]
}
Expand All @@ -296,6 +304,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
Expand All @@ -304,7 +313,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() },
Expand Down

0 comments on commit 0893114

Please sign in to comment.