[tracker/functions] libtracker-db: Check databases for corruption
- From: Mikael Ottela <mottela src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [tracker/functions] libtracker-db: Check databases for corruption
- Date: Thu, 14 Jan 2010 09:12:33 +0000 (UTC)
commit a16a25a95767c853e202ead8cac40d6e151986e8
Author: Philip Van Hoof <philip codeminded be>
Date: Wed Jan 6 18:02:37 2010 +0100
libtracker-db: Check databases for corruption
src/libtracker-data/tracker-data-manager.c | 9 +-
src/libtracker-data/tracker-data-manager.h | 3 +-
src/libtracker-db/tracker-db-manager.c | 183 ++++++++++++++++-----
src/libtracker-db/tracker-db-manager.h | 3 +-
src/tracker-control/tracker-control.c | 2 +-
src/tracker-store/tracker-main.c | 7 +-
tests/libtracker-data/tracker-ontology-test.c | 2 +-
tests/libtracker-data/tracker-sparql-blank-test.c | 2 +-
tests/libtracker-data/tracker-sparql-test.c | 2 +-
tests/libtracker-fts/tracker-fts-test.c | 2 +-
10 files changed, 155 insertions(+), 60 deletions(-)
---
diff --git a/src/libtracker-data/tracker-data-manager.c b/src/libtracker-data/tracker-data-manager.c
index eec1225..6bcc46a 100644
--- a/src/libtracker-data/tracker-data-manager.c
+++ b/src/libtracker-data/tracker-data-manager.c
@@ -997,8 +997,7 @@ import_ontology_into_db (void)
gboolean
tracker_data_manager_init (TrackerDBManagerFlags flags,
const gchar *test_schema,
- gboolean *first_time,
- gboolean *need_journal)
+ gboolean *first_time)
{
TrackerDBInterface *iface;
gboolean is_first_time_index, read_journal;
@@ -1008,17 +1007,13 @@ tracker_data_manager_init (TrackerDBManagerFlags flags,
*first_time = FALSE;
}
- if (need_journal) {
- *need_journal = FALSE;
- }
-
if (initialized) {
return TRUE;
}
read_journal = FALSE;
- tracker_db_manager_init (flags, &is_first_time_index, FALSE, need_journal);
+ tracker_db_manager_init (flags, &is_first_time_index, FALSE);
if (first_time != NULL) {
*first_time = is_first_time_index;
diff --git a/src/libtracker-data/tracker-data-manager.h b/src/libtracker-data/tracker-data-manager.h
index d0ca752..5a976b6 100644
--- a/src/libtracker-data/tracker-data-manager.h
+++ b/src/libtracker-data/tracker-data-manager.h
@@ -39,8 +39,7 @@ G_BEGIN_DECLS
gboolean tracker_data_manager_init (TrackerDBManagerFlags flags,
const gchar *test_schema,
- gboolean *first_time,
- gboolean *need_journal);
+ gboolean *first_time);
void tracker_data_manager_shutdown (void);
gint64 tracker_data_manager_get_db_option_int64 (const gchar *option);
void tracker_data_manager_set_db_option_int64 (const gchar *option,
diff --git a/src/libtracker-db/tracker-db-manager.c b/src/libtracker-db/tracker-db-manager.c
index 6a25c48..d6ef445 100644
--- a/src/libtracker-db/tracker-db-manager.c
+++ b/src/libtracker-db/tracker-db-manager.c
@@ -25,6 +25,10 @@
#include <zlib.h>
#include <locale.h>
#include <time.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <fcntl.h>
#include <glib/gstdio.h>
@@ -52,6 +56,8 @@
#define TRACKER_DB_VERSION_NOW TRACKER_DB_VERSION_8
#define TRACKER_DB_VERSION_FILE "db-version.txt"
+#define IN_USE_FILENAME ".meta.isrunning"
+
typedef enum {
TRACKER_DB_LOCATION_DATA_DIR,
TRACKER_DB_LOCATION_USER_DATA_DIR,
@@ -1012,12 +1018,49 @@ tracker_db_manager_ensure_locale (void)
g_free (stored_locale);
}
+static void
+db_recreate_all (void)
+{
+ guint i;
+
+ /* We call an internal version of this function here
+ * because at the time 'initialized' = FALSE and that
+ * will cause errors and do nothing.
+ */
+ g_message ("Cleaning up database files for reindex");
+
+ db_manager_remove_all (FALSE, FALSE);
+
+ /* In cases where we re-init this module, make sure
+ * we have cleaned up the ontology before we load all
+ * new databases.
+ */
+ tracker_ontology_shutdown ();
+
+ /* Make sure we initialize all other modules we depend on */
+ tracker_ontology_init ();
+
+ /* Now create the databases and close them */
+ g_message ("Creating database files, this may take a few moments...");
+
+ for (i = 1; i < G_N_ELEMENTS (dbs); i++) {
+ dbs[i].iface = db_interface_create (i);
+ }
+
+ /* We don't close the dbs in the same loop as before
+ * becase some databases need other databases
+ * attached to be created correctly.
+ */
+ for (i = 1; i < G_N_ELEMENTS (dbs); i++) {
+ g_object_unref (dbs[i].iface);
+ dbs[i].iface = NULL;
+ }
+}
gboolean
tracker_db_manager_init (TrackerDBManagerFlags flags,
gboolean *first_time,
- gboolean shared_cache,
- gboolean *need_journal)
+ gboolean shared_cache)
{
GType etype;
TrackerDBVersion version;
@@ -1026,16 +1069,14 @@ tracker_db_manager_init (TrackerDBManagerFlags flags,
const gchar *env_path;
gboolean need_reindex, did_copy = FALSE;
guint i;
+ gchar *in_use_filename;
+ int in_use_file;
/* First set defaults for return values */
if (first_time) {
*first_time = FALSE;
}
- if (need_journal) {
- *need_journal = FALSE;
- }
-
if (initialized) {
return TRUE;
}
@@ -1143,6 +1184,12 @@ tracker_db_manager_init (TrackerDBManagerFlags flags,
tracker_db_interface_sqlite_enable_shared_cache ();
}
+ in_use_filename = g_build_filename (g_get_user_data_dir (),
+ "tracker",
+ "data",
+ IN_USE_FILENAME,
+ NULL);
+
/* Should we reindex? If so, just remove all databases files,
* NOT the paths, note, that these paths are also used for
* other things like the nfs lock file.
@@ -1156,54 +1203,103 @@ tracker_db_manager_init (TrackerDBManagerFlags flags,
return FALSE;
}
- /* We call an internal version of this function here
- * because at the time 'initialized' = FALSE and that
- * will cause errors and do nothing.
- */
- g_message ("Cleaning up database files for reindex");
-
- /* Remove all but the meta.db in case of did_copy, else remove
- * all (only in case meta-backup.db was not restored) */
-
- db_manager_remove_all (FALSE, did_copy);
-
- /* In cases where we re-init this module, make sure
- * we have cleaned up the ontology before we load all
- * new databases.
- */
- tracker_ontology_shutdown ();
+ db_recreate_all ();
/* Make sure we initialize all other modules we depend on */
tracker_ontology_init ();
- /* Now create the databases and close them */
- g_message ("Creating database files, this may take a few moments...");
+ /* Load databases */
+ g_message ("Loading databases files...");
for (i = 1; i < G_N_ELEMENTS (dbs); i++) {
dbs[i].iface = db_interface_create (i);
+ dbs[i].mtime = tracker_file_get_mtime (dbs[i].abs_filename);
}
- /* We don't close the dbs in the same loop as before
- * becase some databases need other databases
- * attached to be created correctly.
- */
- for (i = 1; i < G_N_ELEMENTS (dbs); i++) {
- g_object_unref (dbs[i].iface);
- dbs[i].iface = NULL;
- }
} else {
/* Make sure we initialize all other modules we depend on */
tracker_ontology_init ();
- }
- /* Load databases */
- g_message ("Loading databases files...");
+ /* Load databases */
+ g_message ("Loading databases files...");
- for (i = 1; i < G_N_ELEMENTS (dbs); i++) {
- dbs[i].iface = db_interface_create (i);
- dbs[i].mtime = tracker_file_get_mtime (dbs[i].abs_filename);
+ if (g_file_test (in_use_filename, G_FILE_TEST_EXISTS)) {
+ gboolean must_recreate;
+ gsize size = 0;
+
+ must_recreate = FALSE;
+
+ g_message ("Didn't shut down cleanly last time, doing integrity checks");
+
+ for (i = 1; i < G_N_ELEMENTS (dbs) && !must_recreate; i++) {
+ TrackerDBCursor *cursor;
+ TrackerDBStatement *stmt;
+ struct stat st;
+
+ if (g_stat (dbs[i].abs_filename, &st) == 0) {
+ size = st.st_size;
+ }
+
+ /* Size is 1 when using echo > file.db, none of our databases
+ * are only one byte in size even initually. */
+
+ if (size == 0 || size == 1) {
+ must_recreate = TRUE;
+ continue;
+ }
+
+ dbs[i].iface = db_interface_create (i);
+ dbs[i].mtime = tracker_file_get_mtime (dbs[i].abs_filename);
+
+ stmt = tracker_db_interface_create_statement (dbs[i].iface,
+ "PRAGMA integrity_check(1)");
+
+ cursor = tracker_db_statement_start_cursor (stmt, NULL);
+ g_object_unref (stmt);
+
+ if (cursor) {
+ if (tracker_db_cursor_iter_next (cursor)) {
+ if (g_strcmp0 (tracker_db_cursor_get_string (cursor, 0), "ok") != 0) {
+ must_recreate = TRUE;
+ }
+ }
+ g_object_unref (cursor);
+ }
+ }
+
+ if (must_recreate) {
+
+ if (first_time) {
+ *first_time = TRUE;
+ }
+
+ for (i = 1; i < G_N_ELEMENTS (dbs); i++) {
+ if (dbs[i].iface)
+ g_object_unref (dbs[i].iface);
+ }
+
+ db_recreate_all ();
+
+ for (i = 1; i < G_N_ELEMENTS (dbs); i++) {
+ dbs[i].iface = db_interface_create (i);
+ dbs[i].mtime = tracker_file_get_mtime (dbs[i].abs_filename);
+ }
+ }
+ } else {
+ for (i = 1; i < G_N_ELEMENTS (dbs); i++) {
+ dbs[i].iface = db_interface_create (i);
+ dbs[i].mtime = tracker_file_get_mtime (dbs[i].abs_filename);
+ }
+ }
}
+ in_use_file = g_open (in_use_filename,
+ O_WRONLY | O_APPEND | O_CREAT | O_SYNC,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
+ fsync (in_use_file);
+ close (in_use_file);
+ g_free (in_use_filename);
+
tracker_db_manager_ensure_locale ();
initialized = TRUE;
@@ -1273,6 +1369,7 @@ void
tracker_db_manager_shutdown (void)
{
guint i;
+ gchar *in_use_filename;
if (!initialized) {
return;
@@ -1317,6 +1414,16 @@ tracker_db_manager_shutdown (void)
tracker_ontology_shutdown ();
initialized = FALSE;
+
+ in_use_filename = g_build_filename (g_get_user_data_dir (),
+ "tracker",
+ "data",
+ IN_USE_FILENAME,
+ NULL);
+
+ g_unlink (in_use_filename);
+
+ g_free (in_use_filename);
}
void
diff --git a/src/libtracker-db/tracker-db-manager.h b/src/libtracker-db/tracker-db-manager.h
index c46dad6..f7c6636 100644
--- a/src/libtracker-db/tracker-db-manager.h
+++ b/src/libtracker-db/tracker-db-manager.h
@@ -50,8 +50,7 @@ typedef enum {
GType tracker_db_get_type (void) G_GNUC_CONST;
gboolean tracker_db_manager_init (TrackerDBManagerFlags flags,
gboolean *first_time,
- gboolean shared_cache,
- gboolean *need_journal);
+ gboolean shared_cache);
void tracker_db_manager_shutdown (void);
void tracker_db_manager_remove_all (gboolean rm_backup_and_log);
void tracker_db_manager_optimize (void);
diff --git a/src/tracker-control/tracker-control.c b/src/tracker-control/tracker-control.c
index 337fbed..adcebf4 100644
--- a/src/tracker-control/tracker-control.c
+++ b/src/tracker-control/tracker-control.c
@@ -351,7 +351,7 @@ main (int argc, char **argv)
tracker_db_journal_init (NULL);
/* Clean up */
- if (!tracker_db_manager_init (TRACKER_DB_MANAGER_REMOVE_ALL, NULL, FALSE, NULL)) {
+ if (!tracker_db_manager_init (TRACKER_DB_MANAGER_REMOVE_ALL, NULL, FALSE)) {
return EXIT_FAILURE;
}
diff --git a/src/tracker-store/tracker-main.c b/src/tracker-store/tracker-main.c
index 015edc2..d4370b7 100644
--- a/src/tracker-store/tracker-main.c
+++ b/src/tracker-store/tracker-main.c
@@ -342,7 +342,6 @@ main (gint argc, gchar *argv[])
TrackerConfig *config;
TrackerDBManagerFlags flags = 0;
gboolean is_first_time_index;
- gboolean need_journal;
g_type_init ();
@@ -453,14 +452,10 @@ main (gint argc, gchar *argv[])
if (!tracker_data_manager_init (flags,
NULL,
- &is_first_time_index,
- &need_journal)) {
+ &is_first_time_index)) {
return EXIT_FAILURE;
}
- /* TODO binary-log: need_journal might contain whether the db was corrupt
- * or not Do something with that.*/
-
tracker_store_init ();
if (private->shutdown) {
diff --git a/tests/libtracker-data/tracker-ontology-test.c b/tests/libtracker-data/tracker-ontology-test.c
index 2110bd6..31233c8 100644
--- a/tests/libtracker-data/tracker-ontology-test.c
+++ b/tests/libtracker-data/tracker-ontology-test.c
@@ -95,7 +95,7 @@ test_query (gconstpointer test_data)
/* initialization */
tracker_data_manager_init (TRACKER_DB_MANAGER_FORCE_REINDEX,
NULL,
- NULL, NULL);
+ NULL);
/* load data set */
data_filename = g_strconcat (data_prefix, ".ttl", NULL);
diff --git a/tests/libtracker-data/tracker-sparql-blank-test.c b/tests/libtracker-data/tracker-sparql-blank-test.c
index 7788290..bc6a364 100644
--- a/tests/libtracker-data/tracker-sparql-blank-test.c
+++ b/tests/libtracker-data/tracker-sparql-blank-test.c
@@ -43,7 +43,7 @@ test_blank (void)
/* initialization */
tracker_data_manager_init (TRACKER_DB_MANAGER_FORCE_REINDEX,
NULL,
- NULL, NULL);
+ NULL);
/* perform update in transaction */
diff --git a/tests/libtracker-data/tracker-sparql-test.c b/tests/libtracker-data/tracker-sparql-test.c
index 563b671..18d1f88 100644
--- a/tests/libtracker-data/tracker-sparql-test.c
+++ b/tests/libtracker-data/tracker-sparql-test.c
@@ -116,7 +116,7 @@ test_sparql_query (gconstpointer test_data)
tracker_data_manager_init (TRACKER_DB_MANAGER_FORCE_REINDEX,
data_prefix,
- NULL, NULL);
+ NULL);
/* data_path = g_build_path (G_DIR_SEPARATOR_S, TOP_SRCDIR, "tests", "libtracker-data", NULL); */
diff --git a/tests/libtracker-fts/tracker-fts-test.c b/tests/libtracker-fts/tracker-fts-test.c
index a39fabc..777ae6e 100644
--- a/tests/libtracker-fts/tracker-fts-test.c
+++ b/tests/libtracker-fts/tracker-fts-test.c
@@ -70,7 +70,7 @@ test_sparql_query (gconstpointer test_data)
tracker_data_manager_init (TRACKER_DB_MANAGER_FORCE_REINDEX,
data_prefix,
- NULL, NULL);
+ NULL);
/* load data / perform updates */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]