diff options
author | Carlos Garnacho <carlosg@gnome.org> | 2019-07-31 02:24:43 +0200 |
---|---|---|
committer | Carlos Garnacho <carlosg@gnome.org> | 2019-08-08 00:39:18 +0200 |
commit | c304915724d32d98f4d274ebf6a1a12ddd9009c2 (patch) | |
tree | 8fd2d50a43997abf87c2e49bd676bed5149c090e | |
parent | 3f131901feed51023ef0a49a2ba7adb6bd31ec82 (diff) | |
download | tracker-c304915724d32d98f4d274ebf6a1a12ddd9009c2.tar.gz |
libtracker-data: Add consistency check
The dreaded database refcounting issue is still rampaging in some
users. We can't detect all databases that are potentially broken,
(eg. refcounting still "correct", but off), but we can detect the
fact that it already broke in a more elegant way than a myriad
seemingly unrelated breaks.
If we have something in the rdfs:Resource table that is not in the
Resource table, that's a clear indication the database is already
irremediably broken. Just drop the database and reindex from scratch
in that case.
-rw-r--r-- | src/libtracker-data/tracker-data-manager.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/src/libtracker-data/tracker-data-manager.c b/src/libtracker-data/tracker-data-manager.c index 116b1d4a9..010c4755c 100644 --- a/src/libtracker-data/tracker-data-manager.c +++ b/src/libtracker-data/tracker-data-manager.c @@ -4150,6 +4150,30 @@ update_ontology_last_modified (TrackerDataManager *manager, } static gboolean +check_db_consistency (TrackerDBInterface *iface) +{ + TrackerDBStatement *stmt; + TrackerDBCursor *cursor = NULL; + gboolean is_inconsistent = FALSE; + + stmt = tracker_db_interface_create_statement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_SELECT, NULL, + "SELECT ID FROM \"rdfs:Resource\" " + "LEFT OUTER JOIN Resource ON ID LIMIT 1"); + + if (stmt) { + cursor = tracker_db_statement_start_cursor (stmt, NULL); + g_object_unref (stmt); + } + + if (cursor) { + is_inconsistent = tracker_db_cursor_iter_next (cursor, NULL, NULL); + g_object_unref (cursor); + } + + return !is_inconsistent; +} + +static gboolean tracker_data_manager_initable_init (GInitable *initable, GCancellable *cancellable, GError **error) @@ -4214,6 +4238,16 @@ tracker_data_manager_initable_init (GInitable *initable, iface = tracker_db_manager_get_writable_db_interface (manager->db_manager); + if (!read_only && !check_db_consistency (iface)) { + g_set_error (error, + TRACKER_DATA_ONTOLOGY_ERROR, + TRACKER_DATA_UNSUPPORTED_LOCATION, + "Database is inconsistent, reindexing from scratch"); + + tracker_db_manager_remove_all (manager->db_manager); + return FALSE; + } + #ifndef DISABLE_JOURNAL if (manager->journal_check && is_first_time_index) { TrackerDBJournalReader *journal_reader; |