summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2019-07-31 02:24:43 +0200
committerCarlos Garnacho <carlosg@gnome.org>2019-08-08 00:39:18 +0200
commitc304915724d32d98f4d274ebf6a1a12ddd9009c2 (patch)
tree8fd2d50a43997abf87c2e49bd676bed5149c090e
parent3f131901feed51023ef0a49a2ba7adb6bd31ec82 (diff)
downloadtracker-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.c34
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;