[tracker/binary-log-2: 46/50] Truncate the journal to the last correct entry in case of corruption



commit 4c56793c7cb61a16df9d03f1f8ed3203cf196d27
Author: Philip Van Hoof <philip codeminded be>
Date:   Fri Jan 8 15:00:58 2010 +0100

    Truncate the journal to the last correct entry in case of corruption

 src/libtracker-data/tracker-data-manager.c |   20 ++++++++++++++++++--
 src/libtracker-db/tracker-db-journal.c     |   26 +++++++++++++++++++++++++-
 src/libtracker-db/tracker-db-journal.h     |    1 +
 3 files changed, 44 insertions(+), 3 deletions(-)
---
diff --git a/src/libtracker-data/tracker-data-manager.c b/src/libtracker-data/tracker-data-manager.c
index 6bcc46a..99e865d 100644
--- a/src/libtracker-data/tracker-data-manager.c
+++ b/src/libtracker-data/tracker-data-manager.c
@@ -404,9 +404,11 @@ query_resource_by_id (guint32 id)
 static void
 replay_journal (void)
 {
+	GError *journal_error = NULL;
+
 	tracker_db_journal_reader_init (NULL);
 
-	while (tracker_db_journal_reader_next (NULL)) {
+	while (tracker_db_journal_reader_next (&journal_error)) {
 		GError *error = NULL;
 		TrackerDBJournalEntryType type;
 		const gchar *subject, *predicate, *object;
@@ -470,7 +472,21 @@ replay_journal (void)
 		}
 	}
 
-	tracker_db_journal_reader_shutdown ();
+
+	if (journal_error) {
+		gsize size;
+
+		size = tracker_db_journal_reader_get_size_of_correct ();
+		tracker_db_journal_reader_shutdown ();
+
+		tracker_db_journal_init (NULL);
+		tracker_db_journal_truncate (size);
+		tracker_db_journal_shutdown ();
+
+		g_clear_error (&journal_error);
+	} else {
+		tracker_db_journal_reader_shutdown ();
+	}
 }
 
 static void
diff --git a/src/libtracker-db/tracker-db-journal.c b/src/libtracker-db/tracker-db-journal.c
index 69227f7..34f2345 100644
--- a/src/libtracker-db/tracker-db-journal.c
+++ b/src/libtracker-db/tracker-db-journal.c
@@ -62,6 +62,8 @@ static struct {
 	const gchar *end;
 	const gchar *entry_begin;
 	const gchar *entry_end;
+	const gchar *last_success;
+	const gchar *start;
 	guint32 amount_of_triples;
 	gint64 time;
 	TrackerDBJournalEntryType type;
@@ -481,6 +483,14 @@ tracker_db_journal_rollback_transaction (void)
 }
 
 gboolean
+tracker_db_journal_truncate (gsize new_size)
+{
+	g_return_val_if_fail (writer.journal > 0, FALSE);
+
+	return (ftruncate (writer.journal, new_size) != -1);
+}
+
+gboolean
 tracker_db_journal_commit_transaction (void)
 {
 	guint32 crc;
@@ -576,7 +586,9 @@ tracker_db_journal_reader_init (const gchar *filename)
 		return FALSE;
 	}
 
-	reader.current = g_mapped_file_get_contents (reader.file);
+	reader.last_success = reader.start = reader.current = 
+		g_mapped_file_get_contents (reader.file);
+
 	reader.end = reader.current + g_mapped_file_get_length (reader.file);
 
 	/* verify journal file header */
@@ -596,6 +608,14 @@ tracker_db_journal_reader_init (const gchar *filename)
 	return TRUE;
 }
 
+gsize
+tracker_db_journal_reader_get_size_of_correct (void)
+{
+	g_return_val_if_fail (reader.file != NULL, FALSE);
+
+	return (gsize) (reader.last_success - reader.start);
+}
+
 gboolean
 tracker_db_journal_reader_shutdown (void)
 {
@@ -612,6 +632,8 @@ tracker_db_journal_reader_shutdown (void)
 	g_free (reader.filename);
 	reader.filename = NULL;
 
+	reader.last_success = NULL;
+	reader.start = NULL;
 	reader.current = NULL;
 	reader.end = NULL;
 	reader.entry_begin = NULL;
@@ -765,6 +787,8 @@ tracker_db_journal_reader_next (GError **error)
 		}
 
 		reader.type = TRACKER_DB_JOURNAL_END_TRANSACTION;
+		reader.last_success = reader.current;
+
 		return TRUE;
 	} else {
 		DataFormat df;
diff --git a/src/libtracker-db/tracker-db-journal.h b/src/libtracker-db/tracker-db-journal.h
index 568f556..3326de9 100644
--- a/src/libtracker-db/tracker-db-journal.h
+++ b/src/libtracker-db/tracker-db-journal.h
@@ -91,6 +91,7 @@ gboolean     tracker_db_journal_reader_get_statement         (guint32      *s_id
 gboolean     tracker_db_journal_reader_get_statement_id      (guint32      *s_id,
                                                               guint32      *p_id,
                                                               guint32      *o_id);
+gsize        tracker_db_journal_reader_get_size_of_correct   (void);
 
 G_END_DECLS
 



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