Remove updating the Storage table in triggers. Do those updates manually because there is frequently too much contention around the Storage table and filters get locked on it.

This commit is contained in:
Isaac Connor
2025-08-07 14:08:45 -04:00
parent 316b68e6bc
commit ed57267258
3 changed files with 32 additions and 16 deletions

View File

@@ -122,20 +122,7 @@ CREATE TRIGGER event_update_trigger AFTER UPDATE ON Events
FOR EACH ROW
BEGIN
declare diff BIGINT default 0;
set diff = COALESCE(NEW.DiskSpace,0) - COALESCE(OLD.DiskSpace,0);
IF ( NEW.StorageId = OLD.StorageID ) THEN
IF ( diff ) THEN
UPDATE Storage SET DiskSpace = GREATEST(COALESCE(DiskSpace,0) + diff,0) WHERE Storage.Id = OLD.StorageId;
END IF;
ELSE
IF ( NEW.DiskSpace ) THEN
UPDATE Storage SET DiskSpace = COALESCE(DiskSpace,0) + NEW.DiskSpace WHERE Storage.Id = NEW.StorageId;
END IF;
IF ( OLD.DiskSpace ) THEN
UPDATE Storage SET DiskSpace = GREATEST(COALESCE(DiskSpace,0) - COALESCE(OLD.DiskSpace,0),0) WHERE Storage.Id = OLD.StorageId;
END IF;
END IF;
UPDATE Events_Hour SET DiskSpace=NEW.DiskSpace WHERE EventId=NEW.Id;
UPDATE Events_Day SET DiskSpace=NEW.DiskSpace WHERE EventId=NEW.Id;
@@ -204,9 +191,6 @@ DROP TRIGGER IF EXISTS event_delete_trigger//
CREATE TRIGGER event_delete_trigger BEFORE DELETE ON Events
FOR EACH ROW
BEGIN
IF ( OLD.DiskSpace ) THEN
UPDATE Storage SET DiskSpace = GREATEST(COALESCE(DiskSpace,0) - COALESCE(OLD.DiskSpace,0),0) WHERE Storage.Id = OLD.StorageId;
END IF;
DELETE FROM Events_Hour WHERE EventId=OLD.Id;
DELETE FROM Events_Day WHERE EventId=OLD.Id;
DELETE FROM Events_Week WHERE EventId=OLD.Id;

View File

@@ -0,0 +1,22 @@
SELECT 'This update may make changes that require SUPER privileges. If you see an error message saying:
ERROR 1419 (HY000) at line 298: You do not have the SUPER privilege and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)
You will have to either run this update as root manually using something like (on ubuntu/debian)
sudo mysql --defaults-file=/etc/mysql/debian.cnf zm < /usr/share/zoneminder/db/zm_update-1.37.69.sql
OR
sudo mysql --defaults-file=/etc/mysql/debian.cnf "set global log_bin_trust_function_creators=1;"
sudo zmupdate.pl
OR
Turn off binary logging in your mysql server by adding this to your mysql config.
[mysqld]
skip-log-bin
';
source @PKGDATADIR@/db/triggers.sql

View File

@@ -417,6 +417,9 @@ sub delete {
# Do it individually to avoid locking up the table for new events
ZoneMinder::Database::zmDbDo('DELETE FROM Events WHERE Id=?', $$event{Id});
$ZoneMinder::Database::dbh->commit() if ! $in_transaction;
my $storage = $self->Storage();
$storage->save({DiskSpace=>$storage->DiskSpace()-$self->DiskSpace()}) if $self->DiskSpace();
}
if ( ( $in_zmaudit or (!$Config{ZM_OPT_FAST_DELETE})) and $event->Storage()->DoDelete() ) {
@@ -765,6 +768,9 @@ sub MoveTo {
}
}
my $old_diskspace = $self->DiskSpace();
my $new_diskspace = $self->DiskSpace(undef);
# Succeeded in copying all files, so we may now update the Event.
$self->Storage($NewStorage);
$error .= $self->save();
@@ -775,6 +781,10 @@ sub MoveTo {
}
$ZoneMinder::Database::dbh->commit() if !$was_in_transaction;
# Update storage diskspace. The triggers no longer do this. This is ... less important so do it outside the transaction
$OldStorage->save({DiskSpace => $OldStorage->DiskSpace()-$old_diskspace}) if $old_diskspace;
$NewStorage->save({DiskSpace => $NewStorage->DiskSpace()+$new_diskspace}) if $new_diskspace;
$self->delete_files($OldStorage);
return $error;
} # end sub MoveTo