[tracker/wip/carlosg/refcount-dead-man-switch] libtracker-data: Add consistency check



commit b70891827d55b4d498d3d2625e6d58de31ba3a84
Author: Carlos Garnacho <carlosg gnome org>
Date:   Wed Jul 31 02:24:43 2019 +0200

    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 "corrent", 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.

 src/libtracker-data/tracker-data-manager.c | 34 ++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)
---
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
@@ -4149,6 +4149,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,
@@ -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;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]