peeringdb / peeringdb-py

PeeringDB python client
BSD 2-Clause "Simplified" License
89 stars 22 forks source link

sync failed due to several DB errors (sqlite3.IntegrityError, django_peeringdb.models.concrete.DoesNotExist, django.db.utils.IntegrityError) #87

Closed rafeurdean closed 6 months ago

rafeurdean commented 7 months ago

Hi,

Not really sure how much is this a peeringdb-py bug or a peeringdb data inconsistency bug.

django-countries==7.5.1 django-handleref==2.0.0 django-inet==1.1.1 django-peeringdb==3.3.0 peeringdb==2.0.0

5-10 minutes after an initial sync:

Syncing to https://www.peeringdb.com/api
[org] Fetching from API
[org] Processing 761 objects
[campus] Fetching from API
[campus] Processing 6 objects
[fac] Fetching from API
[fac] Processing 145 objects
Fetching dangling relationship Campus 82
Fetching dangling relationship Campus 83
Fetching dangling relationship Campus 84
[net] Fetching from API
[net] Processing 1877 objects
[ix] Fetching from API
[ix] Processing 88 objects
[carrier] Fetching from API
[carrier] Processing 19 objects
[carrierfac] Fetching from API
[carrierfac] Processing 32 objects
[ixfac] Fetching from API
[ixfac] Processing 171 objects
[ixlan] Fetching from API
[ixlan] Processing 95 objects
[ixpfx] Fetching from API
[ixpfx] Processing 81 objects
Fetching dangling relationship InternetExchangeLan 4355
Fetching dangling relationship InternetExchange 4355
Traceback (most recent call last):
  File "/srv/peeringdb/lib/python3.9/site-packages/peeringdb/_update.py", line 186, in _handle_incremental_sync
    self.backend.get_object(self.backend.get_concrete(res), row["id"])
  File "/srv/peeringdb/lib/python3.9/site-packages/peeringdb/backend.py", line 27, in wrapped
    return fn(*args, **kwargs)
  File "/srv/peeringdb/lib/python3.9/site-packages/django_peeringdb/client_adaptor/backend.py", line 94, in get_object
    return concrete.objects.get(pk=id)
  File "/srv/peeringdb/lib/python3.9/site-packages/django/db/models/manager.py", line 87, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/srv/peeringdb/lib/python3.9/site-packages/django/db/models/query.py", line 637, in get
    raise self.model.DoesNotExist(
django_peeringdb.models.concrete.DoesNotExist: IXLanPrefix matching query does not exist.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/srv/peeringdb/lib/python3.9/site-packages/django/db/backends/utils.py", line 89, in _execute
    return self.cursor.execute(sql, params)
  File "/srv/peeringdb/lib/python3.9/site-packages/django/db/backends/sqlite3/base.py", line 328, in execute
    return super().execute(query, params)
sqlite3.IntegrityError: NOT NULL constraint failed: peeringdb_ixlan_prefix.prefix

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/srv/peeringdb/bin/peeringdb", line 8, in <module>
    sys.exit(main())
  File "/srv/peeringdb/lib/python3.9/site-packages/peeringdb/cli.py", line 68, in main
    return handler(config=cfg, **vars(options))
  File "/srv/peeringdb/lib/python3.9/site-packages/peeringdb/commands.py", line 20, in _wrapped
    r = func(*a, **k)
  File "/srv/peeringdb/lib/python3.9/site-packages/peeringdb/commands.py", line 262, in handle
    client.updater.update_all(rs, since, fetch_private=kwargs["fetch_private"])
  File "/srv/peeringdb/lib/python3.9/site-packages/peeringdb/_update.py", line 237, in update_all
    self._handle_incremental_sync(entries, res)
  File "/srv/peeringdb/lib/python3.9/site-packages/peeringdb/_update.py", line 191, in _handle_incremental_sync
    self.backend.save(obj)
  File "/srv/peeringdb/lib/python3.9/site-packages/django_peeringdb/client_adaptor/backend.py", line 145, in save
    obj.save()
  File "/srv/peeringdb/lib/python3.9/site-packages/django/db/models/base.py", line 814, in save
    self.save_base(
  File "/srv/peeringdb/lib/python3.9/site-packages/django/db/models/base.py", line 877, in save_base
    updated = self._save_table(
  File "/srv/peeringdb/lib/python3.9/site-packages/django/db/models/base.py", line 1020, in _save_table
    results = self._do_insert(
  File "/srv/peeringdb/lib/python3.9/site-packages/django/db/models/base.py", line 1061, in _do_insert
    return manager._insert(
  File "/srv/peeringdb/lib/python3.9/site-packages/django/db/models/manager.py", line 87, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/srv/peeringdb/lib/python3.9/site-packages/django/db/models/query.py", line 1805, in _insert
    return query.get_compiler(using=using).execute_sql(returning_fields)
  File "/srv/peeringdb/lib/python3.9/site-packages/django/db/models/sql/compiler.py", line 1820, in execute_sql
    cursor.execute(sql, params)
  File "/srv/peeringdb/lib/python3.9/site-packages/django/db/backends/utils.py", line 67, in execute
    return self._execute_with_wrappers(
  File "/srv/peeringdb/lib/python3.9/site-packages/django/db/backends/utils.py", line 80, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "/srv/peeringdb/lib/python3.9/site-packages/django/db/backends/utils.py", line 89, in _execute
    return self.cursor.execute(sql, params)
  File "/srv/peeringdb/lib/python3.9/site-packages/django/db/utils.py", line 91, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/srv/peeringdb/lib/python3.9/site-packages/django/db/backends/utils.py", line 89, in _execute
    return self.cursor.execute(sql, params)
  File "/srv/peeringdb/lib/python3.9/site-packages/django/db/backends/sqlite3/base.py", line 328, in execute
    return super().execute(query, params)
django.db.utils.IntegrityError: NOT NULL constraint failed: peeringdb_ixlan_prefix.prefix
rafeurdean commented 7 months ago

Pretty much at the same time, on another copy, sync initiated several weeks earlier:

django-countries==7.5.1 django-handleref==2.0.0 django-inet==1.1.1 django-peeringdb==3.3.0 peeringdb==2.0.0

[org] Fetching from API
[org] Processing 3 objects
[campus] Fetching from API
[campus] Processing 0 objects
[fac] Fetching from API
[fac] Processing 0 objects
[net] Fetching from API
[net] Processing 14 objects
[ix] Fetching from API
[ix] Processing 0 objects
[carrier] Fetching from API
[carrier] Processing 0 objects
[carrierfac] Fetching from API
[carrierfac] Processing 0 objects
[ixfac] Fetching from API
[ixfac] Processing 0 objects
[ixlan] Fetching from API
[ixlan] Processing 0 objects
[ixpfx] Fetching from API
[ixpfx] Processing 3 objects
Traceback (most recent call last):
  File "/srv/peeringdb/lib/python3.11/site-packages/peeringdb/_update.py", line 186, in _handle_incremental_sync
    self.backend.get_object(self.backend.get_concrete(res), row["id"])
  File "/srv/peeringdb/lib/python3.11/site-packages/peeringdb/backend.py", line 27, in wrapped
    return fn(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^
  File "/srv/peeringdb/lib/python3.11/site-packages/django_peeringdb/client_adaptor/backend.py", line 94, in get_object
    return concrete.objects.get(pk=id)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/srv/peeringdb/lib/python3.11/site-packages/django/db/models/manager.py", line 87, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/srv/peeringdb/lib/python3.11/site-packages/django/db/models/query.py", line 647, in get
    raise self.model.DoesNotExist(
django_peeringdb.models.concrete.IXLanPrefix.DoesNotExist: IXLanPrefix matching query does not exist.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/srv/peeringdb/lib/python3.11/site-packages/django/db/backends/utils.py", line 105, in _execute
    return self.cursor.execute(sql, params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/srv/peeringdb/lib/python3.11/site-packages/django/db/backends/sqlite3/base.py", line 328, in execute
    return super().execute(query, params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
sqlite3.IntegrityError: NOT NULL constraint failed: peeringdb_ixlan_prefix.prefix

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/srv/peeringdb/bin/peeringdb", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/srv/peeringdb/lib/python3.11/site-packages/peeringdb/cli.py", line 68, in main
    return handler(config=cfg, **vars(options))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/srv/peeringdb/lib/python3.11/site-packages/peeringdb/commands.py", line 20, in _wrapped
    r = func(*a, **k)
        ^^^^^^^^^^^^^
  File "/srv/peeringdb/lib/python3.11/site-packages/peeringdb/commands.py", line 262, in handle
    client.updater.update_all(rs, since, fetch_private=kwargs["fetch_private"])
  File "/srv/peeringdb/lib/python3.11/site-packages/peeringdb/_update.py", line 237, in update_all
    self._handle_incremental_sync(entries, res)
  File "/srv/peeringdb/lib/python3.11/site-packages/peeringdb/_update.py", line 191, in _handle_incremental_sync
    self.backend.save(obj)
  File "/srv/peeringdb/lib/python3.11/site-packages/django_peeringdb/client_adaptor/backend.py", line 145, in save
    obj.save()
  File "/srv/peeringdb/lib/python3.11/site-packages/django/db/models/base.py", line 822, in save
    self.save_base(
  File "/srv/peeringdb/lib/python3.11/site-packages/django/db/models/base.py", line 909, in save_base
    updated = self._save_table(
              ^^^^^^^^^^^^^^^^^
  File "/srv/peeringdb/lib/python3.11/site-packages/django/db/models/base.py", line 1067, in _save_table
    results = self._do_insert(
              ^^^^^^^^^^^^^^^^
  File "/srv/peeringdb/lib/python3.11/site-packages/django/db/models/base.py", line 1108, in _do_insert
    return manager._insert(
           ^^^^^^^^^^^^^^^^
  File "/srv/peeringdb/lib/python3.11/site-packages/django/db/models/manager.py", line 87, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/srv/peeringdb/lib/python3.11/site-packages/django/db/models/query.py", line 1845, in _insert
    return query.get_compiler(using=using).execute_sql(returning_fields)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/srv/peeringdb/lib/python3.11/site-packages/django/db/models/sql/compiler.py", line 1823, in execute_sql
    cursor.execute(sql, params)
  File "/srv/peeringdb/lib/python3.11/site-packages/django/db/backends/utils.py", line 79, in execute
    return self._execute_with_wrappers(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/srv/peeringdb/lib/python3.11/site-packages/django/db/backends/utils.py", line 92, in _execute_with_wrappers
    return executor(sql, params, many, context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/srv/peeringdb/lib/python3.11/site-packages/django/db/backends/utils.py", line 100, in _execute
    with self.db.wrap_database_errors:
  File "/srv/peeringdb/lib/python3.11/site-packages/django/db/utils.py", line 91, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/srv/peeringdb/lib/python3.11/site-packages/django/db/backends/utils.py", line 105, in _execute
    return self.cursor.execute(sql, params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/srv/peeringdb/lib/python3.11/site-packages/django/db/backends/sqlite3/base.py", line 328, in execute
    return super().execute(query, params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
django.db.utils.IntegrityError: NOT NULL constraint failed: peeringdb_ixlan_prefix.prefix
MattKobayashi commented 7 months ago

We're experiencing the same issue with our local mirror. I suspect this to be a data integrity issue on PeeringDB's end. A drop-tables followed by a sync seems to work fine, but gives slightly outdated data.

rafeurdean commented 7 months ago

Hi, at htis point I'm not really sure it's a PeeringDB issue. I can do a first sync, it just takes more than 8 minutes. Immediately afterwards, an update-sync fails.:

[#####] $ time /srv/peeringdb/bin/peeringdb -C /srv/peeringdb sync
Syncing to https://www.peeringdb.com/api
[org] Fetching from remote cache
[org] Processing 27267 objects
[campus] Fetching from remote cache
[campus] Processing 40 objects
[fac] Fetching from remote cache
[fac] Processing 5287 objects
Fetching dangling relationship Campus 14
Fetching dangling relationship Campus 60
Fetching dangling relationship Campus 67
Fetching dangling relationship Campus 68
Fetching dangling relationship Campus 64
[net] Fetching from remote cache
[net] Processing 29252 objects
Fetching dangling relationship Organization 30220
Fetching dangling relationship Organization 30281
[ix] Fetching from remote cache
[ix] Processing 1156 objects
[carrier] Fetching from remote cache
[carrier] Processing 138 objects
[carrierfac] Fetching from remote cache
[carrierfac] Processing 1935 objects
Fetching dangling relationship Facility 921
Fetching dangling relationship Facility 471
Fetching dangling relationship Facility 4490
Fetching dangling relationship Facility 10524
Fetching dangling relationship Facility 13740
[ixfac] Fetching from remote cache
[ixfac] Processing 3560 objects
[ixlan] Fetching from remote cache
[ixlan] Processing 1156 objects
[ixpfx] Fetching from remote cache
[ixpfx] Processing 2234 objects
Fetching dangling relationship InternetExchangeLan 3323
Fetching dangling relationship InternetExchange 3323
[netfac] Fetching from remote cache
[netfac] Processing 47811 objects
[netixlan] Fetching from remote cache
[netixlan] Processing 52563 objects
[poc] Fetching from remote cache
[poc] Processing 17057 objects
/srv/peeringdb/bin/peeringdb -C /srv/peeringdb sync  466.52s user 11.07s system 97% cpu 8:09.07 total
[#####] $ cp peeringdb.sqlite3{,.save}
[#####] $ time /srv/peeringdb/bin/peeringdb -C /srv/peeringdb sync
Syncing to https://www.peeringdb.com/api
[org] Fetching from API
[org] Processing 791 objects
[campus] Fetching from API
[campus] Processing 14 objects
[fac] Fetching from API
[fac] Processing 159 objects
Fetching dangling relationship Campus 82
Fetching dangling relationship Campus 83
Fetching dangling relationship Campus 84
[net] Fetching from API
[net] Processing 1941 objects
[ix] Fetching from API
[ix] Processing 90 objects
[carrier] Fetching from API
[carrier] Processing 19 objects
[carrierfac] Fetching from API
[carrierfac] Processing 34 objects
[ixfac] Fetching from API
[ixfac] Processing 171 objects
[ixlan] Fetching from API
[ixlan] Processing 97 objects
[ixpfx] Fetching from API
[ixpfx] Processing 87 objects
Fetching dangling relationship InternetExchangeLan 4355
Fetching dangling relationship InternetExchange 4355
Traceback (most recent call last):
  File "/srv/peeringdb/lib/python3.11/site-packages/peeringdb/_update.py", line 186, in _handle_incremental_sync
    self.backend.get_object(self.backend.get_concrete(res), row["id"])
  File "/srv/peeringdb/lib/python3.11/site-packages/peeringdb/backend.py", line 27, in wrapped
    return fn(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^
  File "/srv/peeringdb/lib/python3.11/site-packages/django_peeringdb/client_adaptor/backend.py", line 94, in get_object
    return concrete.objects.get(pk=id)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/srv/peeringdb/lib/python3.11/site-packages/django/db/models/manager.py", line 87, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/srv/peeringdb/lib/python3.11/site-packages/django/db/models/query.py", line 647, in get
    raise self.model.DoesNotExist(
django_peeringdb.models.concrete.IXLanPrefix.DoesNotExist: IXLanPrefix matching query does not exist.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/srv/peeringdb/lib/python3.11/site-packages/django/db/backends/utils.py", line 105, in _execute
    return self.cursor.execute(sql, params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/srv/peeringdb/lib/python3.11/site-packages/django/db/backends/sqlite3/base.py", line 328, in execute
    return super().execute(query, params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
sqlite3.IntegrityError: NOT NULL constraint failed: peeringdb_ixlan_prefix.prefix

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/srv/peeringdb/bin/peeringdb", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/srv/peeringdb/lib/python3.11/site-packages/peeringdb/cli.py", line 68, in main
    return handler(config=cfg, **vars(options))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/srv/peeringdb/lib/python3.11/site-packages/peeringdb/commands.py", line 20, in _wrapped
    r = func(*a, **k)
        ^^^^^^^^^^^^^
  File "/srv/peeringdb/lib/python3.11/site-packages/peeringdb/commands.py", line 262, in handle
    client.updater.update_all(rs, since, fetch_private=kwargs["fetch_private"])
  File "/srv/peeringdb/lib/python3.11/site-packages/peeringdb/_update.py", line 237, in update_all
    self._handle_incremental_sync(entries, res)
  File "/srv/peeringdb/lib/python3.11/site-packages/peeringdb/_update.py", line 191, in _handle_incremental_sync
    self.backend.save(obj)
  File "/srv/peeringdb/lib/python3.11/site-packages/django_peeringdb/client_adaptor/backend.py", line 145, in save
    obj.save()
  File "/srv/peeringdb/lib/python3.11/site-packages/django/db/models/base.py", line 822, in save
    self.save_base(
  File "/srv/peeringdb/lib/python3.11/site-packages/django/db/models/base.py", line 909, in save_base
    updated = self._save_table(
              ^^^^^^^^^^^^^^^^^
  File "/srv/peeringdb/lib/python3.11/site-packages/django/db/models/base.py", line 1067, in _save_table
    results = self._do_insert(
              ^^^^^^^^^^^^^^^^
  File "/srv/peeringdb/lib/python3.11/site-packages/django/db/models/base.py", line 1108, in _do_insert
    return manager._insert(
           ^^^^^^^^^^^^^^^^
  File "/srv/peeringdb/lib/python3.11/site-packages/django/db/models/manager.py", line 87, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/srv/peeringdb/lib/python3.11/site-packages/django/db/models/query.py", line 1845, in _insert
    return query.get_compiler(using=using).execute_sql(returning_fields)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/srv/peeringdb/lib/python3.11/site-packages/django/db/models/sql/compiler.py", line 1823, in execute_sql
    cursor.execute(sql, params)
  File "/srv/peeringdb/lib/python3.11/site-packages/django/db/backends/utils.py", line 79, in execute
    return self._execute_with_wrappers(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/srv/peeringdb/lib/python3.11/site-packages/django/db/backends/utils.py", line 92, in _execute_with_wrappers
    return executor(sql, params, many, context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/srv/peeringdb/lib/python3.11/site-packages/django/db/backends/utils.py", line 100, in _execute
    with self.db.wrap_database_errors:
  File "/srv/peeringdb/lib/python3.11/site-packages/django/db/utils.py", line 91, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/srv/peeringdb/lib/python3.11/site-packages/django/db/backends/utils.py", line 105, in _execute
    return self.cursor.execute(sql, params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/srv/peeringdb/lib/python3.11/site-packages/django/db/backends/sqlite3/base.py", line 328, in execute
    return super().execute(query, params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
django.db.utils.IntegrityError: NOT NULL constraint failed: peeringdb_ixlan_prefix.prefix
/srv/peeringdb/bin/peeringdb -C /srv/peeringdb sync  16.94s user 1.15s system 58% cpu 30.783 total
[#####] $ date
Mon Feb 26 10:44:35 CET 2024
[#####] $

Basically, since friday (23/02) it is no longer possible to perform an incremental sync.

vegu commented 7 months ago

@rafeurdean i believe this was a data issue and should now be resolved - let us know if not, thanks.

MattKobayashi commented 7 months ago

Hi @vegu, the sync issue has been resolved, however there are some changes that were made to the main PeeringDB instance recently that are not syncing to our local instance. Is there a delay or some kind of issue with the data that's being fed from the API?

vegu commented 7 months ago

@MattKobayashi There can be a delay for changes to appear in the initial sync data (since that has multiple cache layers), incremental sync should pick them up immediately though, what data is it?

MattKobayashi commented 7 months ago

@vegu Specifically in our case, the name of /net/3984 was changed from Western Australian Internet Association to Internet Association of Australia a few days ago, but this change hasn't reflected on our local instance yet.

vegu commented 7 months ago

@MattKobayashi trying to reproduce this i observe the following

Meaning you'd need to run sync at least twice to be fully updated - if you are already doing that and its still having the old name, something else is going on.

rafeurdean commented 7 months ago

I can confirm that since Tuesday morning (probably even monday evening) the update does work as expected, without code update on peeringdb-py/django-peeringdb side.

MattKobayashi commented 7 months ago

@vegu I'm still having issues with our local instance, specifically this error:

django.db.utils.IntegrityError: (1062, "Duplicate entry 'ZYC Network' for key 'peeringdb_network.name'")

Is this an upstream issue or something wrong on my end?

vegu commented 6 months ago

@MattKobayashi am not able to reproduce, although i am seeing some odd behavior when --fetch-private is passed, not sure if it relates (see #85)

Does your error happen off of a fresh sync? Do you make changes to the objects after the sync (other than syncing)?

MattKobayashi commented 6 months ago

@vegu Yes, it happens off a fresh sync. No local changes are being made, we're using this database purely as a read-only reference.

MattKobayashi commented 6 months ago

@vegu I've managed to resolve our issue by changing the way we do things internally, so no need to follow up on this one any further. Thanks for your help!

leovegoda commented 6 months ago

@rafeurdean Are you happy for us to close this issue?

rafeurdean commented 6 months ago

Yes.