gnunet-svn
[Top][All Lists]
Advanced

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

[taler-anastasis] branch master updated: expose DB garbage collection, R


From: gnunet
Subject: [taler-anastasis] branch master updated: expose DB garbage collection, ROLLBACK instead of committing if preflight check fails
Date: Fri, 17 Sep 2021 00:35:08 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository anastasis.

The following commit(s) were added to refs/heads/master by this push:
     new 75b3065  expose DB garbage collection, ROLLBACK instead of committing 
if preflight check fails
75b3065 is described below

commit 75b3065db390c1c631accd03b68f162953597733
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Fri Sep 17 00:34:52 2021 +0200

    expose DB garbage collection, ROLLBACK instead of committing if preflight 
check fails
---
 src/include/anastasis_database_plugin.h |  7 ++-
 src/stasis/anastasis-dbinit.c           | 46 ++++++++++++++++---
 src/stasis/plugin_anastasis_postgres.c  | 78 ++++++++++++++++++++++++++++++---
 3 files changed, 119 insertions(+), 12 deletions(-)

diff --git a/src/include/anastasis_database_plugin.h 
b/src/include/anastasis_database_plugin.h
index bc4b0e6..7bf91a2 100644
--- a/src/include/anastasis_database_plugin.h
+++ b/src/include/anastasis_database_plugin.h
@@ -232,9 +232,12 @@ struct ANASTASIS_DatabasePlugin
   * Does not return anything, as we will continue regardless of the outcome.
   *
   * @param cls the `struct PostgresClosure` with the plugin-specific state
+  * @return #GNUNET_OK if everything is fine
+  *         #GNUNET_NO if a transaction was rolled back
+  *         #GNUNET_SYSERR on hard errors
   */
-  void
-  (*preflight) (void *cls);
+  enum GNUNET_GenericReturnValue
+  (*preflight)(void *cls);
 
   /**
   * Check that the database connection is still up.
diff --git a/src/stasis/anastasis-dbinit.c b/src/stasis/anastasis-dbinit.c
index 17b3c56..a0e17db 100644
--- a/src/stasis/anastasis-dbinit.c
+++ b/src/stasis/anastasis-dbinit.c
@@ -33,6 +33,11 @@ static int global_ret;
  */
 static int reset_db;
 
+/**
+ * -g option: do garbate collection
+ */
+static int gc_db;
+
 /**
  * Main function that will be run.
  *
@@ -54,21 +59,49 @@ run (void *cls,
   {
     fprintf (stderr,
              "Failed to initialize database plugin.\n");
-    global_ret = EXIT_FAILURE;
+    global_ret = EXIT_NOTINSTALLED;
     return;
   }
   if (reset_db)
   {
-    (void) plugin->drop_tables (plugin->cls);
-    ANASTASIS_DB_plugin_unload (plugin);
-    plugin = ANASTASIS_DB_plugin_load (cfg);
+    if (GNUNET_OK != plugin->drop_tables (plugin->cls))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Could not drop tables as requested. Either database was not 
yet initialized, or permission denied. Consult the logs. Will still try to 
create new tables.\n");
+    }
   }
   if (GNUNET_OK !=
       plugin->create_tables (plugin->cls))
   {
     global_ret = EXIT_FAILURE;
+    ANASTASIS_DB_plugin_unload (plugin);
     return;
   }
+  if (gc_db)
+  {
+    struct GNUNET_TIME_Absolute expire_backups;
+    struct GNUNET_TIME_Absolute expire_payments;
+    struct GNUNET_TIME_Absolute now;
+
+    now = GNUNET_TIME_absolute_get ();
+    expire_backups = GNUNET_TIME_absolute_subtract (
+      now,
+      GNUNET_TIME_relative_multiply (
+        GNUNET_TIME_UNIT_MONTHS,
+        6));
+    expire_payments = GNUNET_TIME_absolute_subtract (
+      now,
+      GNUNET_TIME_relative_multiply (
+        GNUNET_TIME_UNIT_YEARS,
+        10));
+    if (0 > plugin->gc (plugin->cls,
+                        expire_backups,
+                        expire_payments))
+    {
+      fprintf (stderr,
+               "Garbage collection failed!\n");
+    }
+  }
   ANASTASIS_DB_plugin_unload (plugin);
 }
 
@@ -86,7 +119,10 @@ main (int argc,
       char *const *argv)
 {
   struct GNUNET_GETOPT_CommandLineOption options[] = {
-
+    GNUNET_GETOPT_option_flag ('g',
+                               "garbagecollect",
+                               "remove state data from database",
+                               &gc_db),
     GNUNET_GETOPT_option_flag ('r',
                                "reset",
                                "reset database (DANGEROUS: all existing data 
is lost!)",
diff --git a/src/stasis/plugin_anastasis_postgres.c 
b/src/stasis/plugin_anastasis_postgres.c
index b78dbdb..b1be081 100644
--- a/src/stasis/plugin_anastasis_postgres.c
+++ b/src/stasis/plugin_anastasis_postgres.c
@@ -72,6 +72,10 @@ struct PostgresClosure
    */
   char *currency;
 
+  /**
+   * Prepared statements have been initialized.
+   */
+  bool init;
 };
 
 
@@ -523,39 +527,103 @@ check_connection (void *cls)
 }
 
 
+/**
+ * Connect to the database if the connection does not exist yet.
+ *
+ * @param pg the plugin-specific state
+ * @param skip_prepare true if we should skip prepared statement setup
+ * @return #GNUNET_OK on success
+ */
+static enum GNUNET_GenericReturnValue
+internal_setup (struct PostgresClosure *pg,
+                bool skip_prepare)
+{
+  if (NULL == pg->conn)
+  {
+#if AUTO_EXPLAIN
+    /* Enable verbose logging to see where queries do not
+       properly use indices */
+    struct GNUNET_PQ_ExecuteStatement es[] = {
+      GNUNET_PQ_make_try_execute ("LOAD 'auto_explain';"),
+      GNUNET_PQ_make_try_execute ("SET auto_explain.log_min_duration=50;"),
+      GNUNET_PQ_make_try_execute ("SET auto_explain.log_timing=TRUE;"),
+      GNUNET_PQ_make_try_execute ("SET auto_explain.log_analyze=TRUE;"),
+      /* https://wiki.postgresql.org/wiki/Serializable suggests to really
+         force the default to 'serializable' if SSI is to be used. */
+      GNUNET_PQ_make_try_execute (
+        "SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL 
SERIALIZABLE;"),
+      GNUNET_PQ_make_try_execute ("SET enable_sort=OFF;"),
+      GNUNET_PQ_make_try_execute ("SET enable_seqscan=OFF;"),
+      GNUNET_PQ_EXECUTE_STATEMENT_END
+    };
+#else
+    struct GNUNET_PQ_ExecuteStatement *es = NULL;
+#endif
+    struct GNUNET_PQ_Context *db_conn;
+
+    db_conn = GNUNET_PQ_connect_with_cfg (pg->cfg,
+                                          "exchangedb-postgres",
+                                          NULL,
+                                          es,
+                                          NULL);
+    if (NULL == db_conn)
+      return GNUNET_SYSERR;
+    pg->conn = db_conn;
+  }
+  if (NULL == pg->transaction_name)
+    GNUNET_PQ_reconnect_if_down (pg->conn);
+  if (pg->init)
+    return GNUNET_OK;
+  if (skip_prepare)
+    return GNUNET_OK;
+  return postgres_connect (pg);
+}
+
+
 /**
  * Do a pre-flight check that we are not in an uncommitted transaction.
  * If we are, try to commit the previous transaction and output a warning.
  * Does not return anything, as we will continue regardless of the outcome.
  *
  * @param cls the `struct PostgresClosure` with the plugin-specific state
+ * @return #GNUNET_OK if everything is fine
+ *         #GNUNET_NO if a transaction was rolled back
+ *         #GNUNET_SYSERR on hard errors
  */
-static void
+static enum GNUNET_GenericReturnValue
 postgres_preflight (void *cls)
 {
   struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_ExecuteStatement es[] = {
-    GNUNET_PQ_make_execute ("COMMIT"),
+    GNUNET_PQ_make_execute ("ROLLBACK"),
     GNUNET_PQ_EXECUTE_STATEMENT_END
   };
 
+  if (! pg->init)
+  {
+    if (GNUNET_OK !=
+        internal_setup (pg,
+                        false))
+      return GNUNET_SYSERR;
+  }
   if (NULL == pg->transaction_name)
-    return; /* all good */
+    return GNUNET_OK;  /* all good */
   if (GNUNET_OK ==
       GNUNET_PQ_exec_statements (pg->conn,
                                  es))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "BUG: Preflight check committed transaction `%s'!\n",
+                "BUG: Preflight check rolled back transaction `%s'!\n",
                 pg->transaction_name);
   }
   else
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "BUG: Preflight check failed to commit transaction `%s'!\n",
+                "BUG: Preflight check failed to rollback transaction `%s'!\n",
                 pg->transaction_name);
   }
   pg->transaction_name = NULL;
+  return GNUNET_NO;
 }
 
 

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]