From a89cd6738094703dd5b78a7312a55bfc20cd11c3 Mon Sep 17 00:00:00 2001 From: Valentin Lorentz <vlorentz@softwareheritage.org> Date: Mon, 19 Dec 2022 12:39:39 +0100 Subject: [PATCH] storage_checker: Retry on postgresql errors from swh-storage This should avoid pointless reports to Sentry and Icinga on AdminShutdown exceptions. --- requirements.txt | 2 ++ swh/scrubber/storage_checker.py | 36 ++++++++++++++++++++++++--------- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/requirements.txt b/requirements.txt index e35fb35..a5f4288 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,3 +3,5 @@ # dependency lines, see https://pip.readthedocs.org/en/1.1/requirements.html dulwich +psycopg2 +tenacity diff --git a/swh/scrubber/storage_checker.py b/swh/scrubber/storage_checker.py index c29a903..69ef8a3 100644 --- a/swh/scrubber/storage_checker.py +++ b/swh/scrubber/storage_checker.py @@ -12,6 +12,9 @@ import datetime import logging from typing import Iterable, Optional, Tuple, Union +import psycopg2 +import tenacity + from swh.core.statsd import Statsd from swh.journal.serializers import value_to_kafka from swh.model import swhids @@ -128,14 +131,13 @@ class StorageChecker: ``start_object`` and ``end_object``. """ if isinstance(self.storage, PostgresqlStorage): - with storage_db(self.storage) as db: - return self._check_postgresql(db) + return self._check_postgresql() else: raise NotImplementedError( f"StorageChecker(storage={self.storage!r}).check_storage()" ) - def _check_postgresql(self, db): + def _check_postgresql(self): object_type = getattr(swhids.ObjectType, self.object_type.upper()) for range_start, range_end in backfill.RANGE_GENERATORS[self.object_type]( self.start_object, self.end_object @@ -172,6 +174,27 @@ class StorageChecker: backfill._format_range_bound(range_end), ) + self._check_postgresql_range(object_type, range_start, range_end) + + self.db.checked_range_upsert( + self.datastore_info(), + range_start_swhid, + range_end_swhid, + start_time, + ) + + @tenacity.retry( + retry=tenacity.retry_if_exception_type(psycopg2.OperationalError), + wait=tenacity.wait_random_exponential(min=10, max=180), + ) + def _check_postgresql_range( + self, object_type: swhids.ObjectType, range_start, range_end + ) -> None: + assert isinstance( + self.storage, PostgresqlStorage + ), f"_check_postgresql_range called with self.storage={self.storage!r}" + + with storage_db(self.storage) as db: objects = backfill.fetch( db, self.object_type, start=range_start, end=range_end ) @@ -186,13 +209,6 @@ class StorageChecker: ): self.check_object_references(objects) - self.db.checked_range_upsert( - self.datastore_info(), - range_start_swhid, - range_end_swhid, - start_time, - ) - def check_object_hashes(self, objects: Iterable[ScrubbableObject]): """Recomputes hashes, and reports mismatches.""" count = 0 -- GitLab