Add ExecuteInterval to Filter Object. Allow empty sort_field to have the effort of not sorting. Always add FOR SHARE which adds a read-only lock the returned records. Add SKIP LOCKED functionality so that filters can simply skip locked records. This should reduce contention. Also specify FOR UPDATE of the events table, otherwise we also lock Monitors and Storage.

This commit is contained in:
Isaac Connor 2021-12-13 14:58:32 -05:00
parent ef13c84d8b
commit 0382a677df
1 changed files with 16 additions and 10 deletions

View File

@ -56,6 +56,7 @@ $primary_key = 'Id';
%fields = map { $_ => $_ } qw( %fields = map { $_ => $_ } qw(
Id Id
Name Name
ExecuteInterval
Query_json Query_json
AutoArchive AutoArchive
AutoUnarchive AutoUnarchive
@ -106,7 +107,6 @@ sub Execute {
$sql =~ s/zmSystemLoad/$load/g; $sql =~ s/zmSystemLoad/$load/g;
} }
$sql .= ' FOR UPDATE' if $$self{LockRows};
Debug("Filter::Execute SQL ($sql)"); Debug("Filter::Execute SQL ($sql)");
my $sth = $ZoneMinder::Database::dbh->prepare_cached($sql) my $sth = $ZoneMinder::Database::dbh->prepare_cached($sql)
@ -371,10 +371,7 @@ sub Sql {
if ( @auto_terms ) { if ( @auto_terms ) {
$sql .= ' AND ( '.join(' or ', @auto_terms).' )'; $sql .= ' AND ( '.join(' or ', @auto_terms).' )';
} }
if ( !$filter_expr->{sort_field} ) {
$filter_expr->{sort_field} = 'StartDateTime';
$filter_expr->{sort_asc} = 0;
}
my $sort_column = ''; my $sort_column = '';
if ( $filter_expr->{sort_field} eq 'Id' ) { if ( $filter_expr->{sort_field} eq 'Id' ) {
$sort_column = 'E.Id'; $sort_column = 'E.Id';
@ -406,14 +403,23 @@ sub Sql {
$sort_column = 'E.MaxScore'; $sort_column = 'E.MaxScore';
} elsif ( $filter_expr->{sort_field} eq 'DiskSpace' ) { } elsif ( $filter_expr->{sort_field} eq 'DiskSpace' ) {
$sort_column = 'E.DiskSpace'; $sort_column = 'E.DiskSpace';
} else { } elsif ( $filter_expr->{sort_field} ne '' ) {
$sort_column = 'E.StartDateTime'; $sort_column = 'E.'.$filter_expr->{sort_field};
} }
my $sort_order = $filter_expr->{sort_asc} ? 'ASC' : 'DESC'; if ( $sort_column ne '' ) {
$sql .= ' ORDER BY '.$sort_column.' '.$sort_order; $sql .= ' ORDER BY '.$sort_column.' '.($filter_expr->{sort_asc} ? 'ASC' : 'DESC');
if ( $filter_expr->{limit} ) { }
if ($filter_expr->{limit}) {
$sql .= ' LIMIT 0,'.$filter_expr->{limit}; $sql .= ' LIMIT 0,'.$filter_expr->{limit};
} }
if ($$self{LockRows}) {
$sql .= ' FOR UPDATE OF E'
} else {
$sql .= ' FOR SHARE OF E'
}
if ($filter_expr->{skip_locked}) {
$sql .= ' SKIP LOCKED';
}
$self->{Sql} = $sql; $self->{Sql} = $sql;
} # end if has Sql } # end if has Sql
return $self->{Sql}; return $self->{Sql};