[tracker/sqlite-batch-locking] libtracker-db: Add experimental SQLite VFS wrapper
- From: Jürg Billeter <juergbi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker/sqlite-batch-locking] libtracker-db: Add experimental SQLite VFS wrapper
- Date: Tue, 11 May 2010 10:19:01 +0000 (UTC)
commit 8173a3c516c405e56cf1f78c558301d427b102c1
Author: Jürg Billeter <j bitron ch>
Date: Tue May 11 12:15:19 2010 +0200
libtracker-db: Add experimental SQLite VFS wrapper
The SQLite VFS wrapper tracks database locking to dynamically adjust
batch transaction size. This only works without shared cache as
table-level locking does not use locks on the VFS level.
src/libtracker-db/tracker-db-interface-sqlite.c | 66 ++++++++++++++++++++++-
src/libtracker-db/tracker-db-interface-sqlite.h | 3 +
src/libtracker-db/tracker-db-manager.c | 6 --
src/tracker-store/tracker-store.c | 16 ++----
4 files changed, 74 insertions(+), 17 deletions(-)
---
diff --git a/src/libtracker-db/tracker-db-interface-sqlite.c b/src/libtracker-db/tracker-db-interface-sqlite.c
index c290d16..d209923 100644
--- a/src/libtracker-db/tracker-db-interface-sqlite.c
+++ b/src/libtracker-db/tracker-db-interface-sqlite.c
@@ -137,11 +137,75 @@ G_DEFINE_TYPE_WITH_CODE (TrackerDBCursorSqlite, tracker_db_cursor_sqlite, G_TYPE
G_IMPLEMENT_INTERFACE (TRACKER_TYPE_DB_CURSOR,
tracker_db_cursor_sqlite_iface_init))
+/* from GLib */
+#define STRUCT_ALIGNMENT (2 * sizeof (gsize))
+#define ALIGN_STRUCT(offset) \
+ ((offset + (STRUCT_ALIGNMENT - 1)) & -STRUCT_ALIGNMENT)
+
+static sqlite3_vfs *default_vfs = NULL;
+
+#define DEFAULT_METHODS(file) (*((const sqlite3_io_methods **) ((gchar *) file + ALIGN_STRUCT(default_vfs->szOsFile))))
+
+static gboolean db_locked = FALSE;
+
+static int
+my_lock (sqlite3_file* file, int locktype)
+{
+ gint rc;
+ if (locktype >= SQLITE_LOCK_PENDING) {
+ db_locked = TRUE;
+ }
+ rc = DEFAULT_METHODS(file)->xLock (file, locktype);
+ return rc;
+}
+
+static int
+my_open (sqlite3_vfs *vfs, const char *zName, sqlite3_file* file, int flags, int *pOutFlags)
+{
+ int rc = default_vfs->xOpen (vfs, zName, file, flags, pOutFlags);
+ if ((flags & SQLITE_OPEN_MAIN_DB) && file->pMethods) {
+ sqlite3_io_methods *my_methods = g_memdup (file->pMethods, sizeof (sqlite3_io_methods));
+ my_methods->xLock = my_lock;
+
+ DEFAULT_METHODS(file) = file->pMethods;
+ file->pMethods = my_methods;
+ }
+ return rc;
+}
+
+gboolean
+tracker_db_manager_pending_lock (void)
+{
+ if (db_locked) {
+ db_locked = FALSE;
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+static gboolean initialized = FALSE;
+
void
tracker_db_interface_sqlite_enable_shared_cache (void)
{
+ sqlite3_vfs *wrapper;
+
+ if (initialized) {
+ return;
+ }
+
+ initialized = TRUE;
+
+ default_vfs = sqlite3_vfs_find (NULL);
+ wrapper = g_memdup (default_vfs, sizeof (sqlite3_vfs));
+ wrapper->szOsFile = ALIGN_STRUCT(default_vfs->szOsFile) + sizeof (gpointer);
+ wrapper->xOpen = my_open;
+
+ sqlite3_vfs_register (wrapper, TRUE);
+
sqlite3_config (SQLITE_CONFIG_MULTITHREAD);
- sqlite3_enable_shared_cache (1);
+ sqlite3_enable_shared_cache (0);
}
static void
diff --git a/src/libtracker-db/tracker-db-interface-sqlite.h b/src/libtracker-db/tracker-db-interface-sqlite.h
index 042d62c..aaa74e8 100644
--- a/src/libtracker-db/tracker-db-interface-sqlite.h
+++ b/src/libtracker-db/tracker-db-interface-sqlite.h
@@ -65,6 +65,9 @@ void tracker_db_interface_sqlite_enable_shared_cache (void);
void tracker_db_interface_sqlite_fts_init (TrackerDBInterfaceSqlite *interface,
gboolean create);
+gboolean
+tracker_db_manager_pending_lock (void);
+
G_END_DECLS
#endif /* __LIBTRACKER_DB_INTERFACE_SQLITE_H__ */
diff --git a/src/libtracker-db/tracker-db-manager.c b/src/libtracker-db/tracker-db-manager.c
index 66efc03..fb3ea94 100644
--- a/src/libtracker-db/tracker-db-manager.c
+++ b/src/libtracker-db/tracker-db-manager.c
@@ -267,12 +267,6 @@ db_set_params (TrackerDBInterface *iface,
tracker_db_interface_execute_query (iface, NULL, "PRAGMA encoding = \"UTF-8\"");
tracker_db_interface_execute_query (iface, NULL, "PRAGMA auto_vacuum = 0;");
- /* if we add direct access library (or enable running queries in parallel with updates,
- we need to disable read_uncommitted again
- however, when read_uncommitted is disabled, we need the custom page cache (wrapper)
- to avoid locking issues between long running batch transactions and queries */
- tracker_db_interface_execute_query (iface, NULL, "PRAGMA read_uncommitted = True;");
-
if (page_size != TRACKER_DB_PAGE_SIZE_DONT_SET) {
g_message (" Setting page size to %d", page_size);
tracker_db_interface_execute_query (iface, NULL, "PRAGMA page_size = %d", page_size);
diff --git a/src/tracker-store/tracker-store.c b/src/tracker-store/tracker-store.c
index bb55c55..5ec04c7 100644
--- a/src/tracker-store/tracker-store.c
+++ b/src/tracker-store/tracker-store.c
@@ -35,7 +35,6 @@
#include "tracker-store.h"
-#define TRACKER_STORE_TRANSACTION_MAX 4000
#define TRACKER_STORE_MAX_CONCURRENT_QUERIES 2
#define TRACKER_STORE_QUERY_WATCHDOG_TIMEOUT 10
@@ -44,7 +43,6 @@
typedef struct {
gboolean have_handler, have_sync_handler;
gboolean batch_mode, start_log;
- guint batch_count;
GQueue *queues[TRACKER_STORE_N_PRIORITIES];
guint handler, sync_handler;
guint n_queries_running;
@@ -209,7 +207,6 @@ begin_batch (TrackerStorePrivate *private)
delays database commits to improve performance */
tracker_data_begin_db_transaction ();
private->batch_mode = TRUE;
- private->batch_count = 0;
}
}
@@ -221,8 +218,10 @@ end_batch (TrackerStorePrivate *private)
tracker_data_commit_db_transaction ();
tracker_data_notify_db_transaction ();
+ /* the above commit will trigger a lock again, reset it */
+ tracker_db_manager_pending_lock ();
+
private->batch_mode = FALSE;
- private->batch_count = 0;
}
}
@@ -447,8 +446,7 @@ pool_dispatch_cb (gpointer data,
if (task->data.update.batch) {
if (!task->error) {
- private->batch_count++;
- if (private->batch_count >= TRACKER_STORE_TRANSACTION_MAX) {
+ if (tracker_db_manager_pending_lock ()) {
end_batch (private);
}
}
@@ -467,8 +465,7 @@ pool_dispatch_cb (gpointer data,
if (task->data.update.batch) {
if (!task->error) {
- private->batch_count++;
- if (private->batch_count >= TRACKER_STORE_TRANSACTION_MAX) {
+ if (tracker_db_manager_pending_lock ()) {
end_batch (private);
}
}
@@ -560,8 +557,7 @@ queue_idle_handler (gpointer user_data)
if (process_turtle_file_part (turtle_reader, &error)) {
/* import still in progress */
- private->batch_count++;
- if (private->batch_count >= TRACKER_STORE_TRANSACTION_MAX) {
+ if (tracker_db_manager_pending_lock ()) {
end_batch (private);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]