[Date Prev][Date Next] [Chronological] [Thread] [Top]

Re: two phase commit for cache failure (ITS#1575)



Committed with some changes.  I note that GID needs
to be globally unique.  This likely can be created
from a UUID created at startup + connection id + operation id.

Kurt

At 02:17 PM 2002-02-01, jongchoi@us.ibm.com wrote:
>Full_Name: Jong Hyuk Choi
>Version: HEAD as of Jan 31
>OS: Redhat 7.1
>URL: ftp://ftp.openldap.org/incoming/
>Submission from: (NULL) (198.81.209.17)
>
>
>A patch for a better interaction of caches and transactions.
>If cache add or update fails after txn_commit, 
>there is no way of aborting the transaction in the current HEAD.
>The patch first prepares the transaction commit by txn_prepare,
>complete the cache add or update, and if they succeed, do txn_commit.
>
>The following is the diff :
>=========================================================================
>diff -Naur ldap-head-Jan31/servers/slapd/back-bdb/add.c
>ldap-head-Jan31new/servers/slapd/back-bdb/add.c
>--- ldap-head-Jan31/servers/slapd/back-bdb/add.c        Tue Jan 29 03:53:47 2002
>+++ ldap-head-Jan31new/servers/slapd/back-bdb/add.c     Fri Feb  1 21:34:24 2002
>@@ -13,6 +13,8 @@
> #include "back-bdb.h"
> #include "external.h"
> 
>+static char bdb_gid[DB_XIDDATASIZE];
>+
> int
> bdb_add(
>        BackendDB       *be,
>@@ -351,40 +353,51 @@
>        }
> 
>        if( op->o_noop ) {
>-               rc = txn_abort( ltid );
>-       } else {
>-               rc = txn_commit( ltid, 0 );
>+               if ((rc=txn_abort( ltid )) != 0)
>+                       text = "txn_abort (no-op) failed";
>+               else
>+                       rc = LDAP_SUCCESS;
>+       }
>+       else {
>+#if DB_VERSION_MAJOR < 4
>+               if ((rc=txn_prepare( ltid, bdb_gid )) != 0)
>+#else
>+               if ((rc=ltid->prepare( ltid, bdb_gid )) != 0)
>+#endif
>+                       text = "txn_prepare failed";
>+               else {
>+                       if (bdb_cache_add_entry_rw(&bdb->bi_cache,
>+                                               e, CACHE_WRITE_LOCK) != 0) {
>+                               if ((rc=txn_abort ( ltid )) != 0)
>+                                       text = "cache add & txn_abort failed";
>+                               else {
>+                                       rc = LDAP_OTHER;
>+                                       text = "cache add failed";
>+                               }
>+                       }
>+                       else {
>+                               if ((rc=txn_commit ( ltid, 0 )) != 0)
>+                                       text = "txn_commit failed";
>+                               else
>+                                       rc = LDAP_SUCCESS;
>+                       }
>+               }
>        }
>+
>        ltid = NULL;
>        op->o_private = NULL;
> 
>-       if( rc != 0 ) {
>-               Debug( LDAP_DEBUG_TRACE,
>-                       "bdb_add: txn_%s failed: %s (%d)\n",
>-                       op->o_noop ? "abort (no-op)" : "commit",
>-                       db_strerror(rc), rc );
>-               rc = LDAP_OTHER;
>-               text = "commit failed";
>-
>-       } else {
>-               /* add the entry to the entry cache */
>-               /* we should add to cache only upon free of txn-abort */
>-               if (!op->o_noop &&
>-                       bdb_cache_add_entry_rw(&bdb->bi_cache, e, CACHE_WRITE_LOCK) != 0)
>-               {
>-                       text = "cache add failed";
>-                       goto return_results;
>-               }
>- 
>-               Debug( LDAP_DEBUG_TRACE,
>-                       "bdb_add: added%s id=%08lx dn=\"%s\"\n",
>-                       op->o_noop ? " (no-op)" : "",
>-                       e->e_id, e->e_dn );
>-               rc = LDAP_SUCCESS;
>+       if (rc == LDAP_SUCCESS) {
>+               Debug(LDAP_DEBUG_TRACE, "bdb_add: added%s id=%08lx dn=\"%s\"\n",
>+                       op->o_noop ? " (no-op)" : "", e->e_id, e->e_dn );
>                text = NULL;
>+               bdb_cache_entry_commit( e );
>+       }
>+       else {
>+               Debug( LDAP_DEBUG_TRACE, "bdb_add: %s : %s (%d)\n",
>+                       text, db_strerror(rc), rc );
>+               rc = LDAP_OTHER;
>        }
>-
>-       bdb_cache_entry_commit( e );
> 
> return_results:
>        send_ldap_result( conn, op, rc,
>diff -Naur ldap-head-Jan31/servers/slapd/back-bdb/modrdn.c
>ldap-head-Jan31new/servers/slapd/back-bdb/modrdn.c
>--- ldap-head-Jan31/servers/slapd/back-bdb/modrdn.c     Tue Jan 29 03:53:48 2002
>+++ ldap-head-Jan31new/servers/slapd/back-bdb/modrdn.c  Fri Feb  1 21:34:33 2002
>@@ -13,6 +13,8 @@
> #include "back-bdb.h"
> #include "external.h"
> 
>+static char bdb_gid[DB_XIDDATASIZE];
>+
> int
> bdb_modrdn(
>     Backend    *be,
>@@ -623,30 +625,50 @@
>        }
> 
>        if( op->o_noop ) {
>-               rc = txn_abort( ltid );
>-       } else {
>-               rc = txn_commit( ltid, 0 );
>-       }
>+               if ((rc=txn_abort( ltid )) != 0)
>+                       text = "txn_abort (no-op) failed";
>+               else
>+                       rc = LDAP_SUCCESS;
>+       }
>+       else {
>+#if DB_VERSION_MAJOR < 4
>+                if ((rc=txn_prepare( ltid, bdb_gid )) != 0)
>+#else
>+               if ((rc=ltid->prepare( ltid, bdb_gid )) != 0)
>+#endif
>+                       text = "txn_prepare failed";
>+               else {
>+                       if (bdb_cache_update_entry(&bdb->bi_cache, e) == -1) {
>+                               if ((rc=txn_abort ( ltid )) != 0)
>+                                       text ="cache update & txn_abort failed";
>+                               else {
>+                                       rc = LDAP_OTHER;
>+                                       text = "cache update failed";
>+                               }
>+                       }
>+                       else {
>+                               if ((rc=txn_commit ( ltid, 0 )) != 0)
>+                                       text = "txn_commit failed";
>+                               else
>+                                       rc = LDAP_SUCCESS;
>+                       }
>+               }
>+        }
>+ 
>        ltid = NULL;
>        op->o_private = NULL;
>-
>-       if( rc != 0 ) {
>-               Debug( LDAP_DEBUG_TRACE,
>-                       "bdb_modrdn: txn_%s failed: %s (%d)\n",
>-                       op->o_noop ? "abort (no-op)" : "commit",
>-                       db_strerror(rc), rc );
>-               rc = LDAP_OTHER;
>-               text = "commit failed";
>-
>-       } else {
>-               (void) bdb_cache_update_entry(&bdb->bi_cache, e);
>-               Debug( LDAP_DEBUG_TRACE,
>-                       "bdb_modrdn: added%s id=%08lx dn=\"%s\"\n",
>-                       op->o_noop ? " (no-op)" : "",
>-                       e->e_id, e->e_dn );
>-               rc = LDAP_SUCCESS;
>+ 
>+       if (rc == LDAP_SUCCESS) {
>+               Debug(LDAP_DEBUG_TRACE,
>+                       "bdb_modrdn: rdn modified%s id=%08lx dn=\"%s\"\n",
>+                       op->o_noop ? " (no-op)" : "", e->e_id, e->e_dn );
>                text = NULL;
>                bdb_cache_entry_commit( e );
>+       }
>+       else {
>+               Debug( LDAP_DEBUG_TRACE, "bdb_add: %s : %s (%d)\n",
>+                       text, db_strerror(rc), rc );
>+               rc = LDAP_OTHER;
>        }
> 
> return_results: