diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c
index 3a97f2f..b8e9503 100644
--- a/ldap/servers/slapd/back-ldbm/dblayer.c
+++ b/ldap/servers/slapd/back-ldbm/dblayer.c
@@ -3323,10 +3323,29 @@ int dblayer_txn_init(struct ldbminfo *li __attribute__((unused)), back_txn *txn)
     return 0;
 }
 
-
 int
 dblayer_txn_begin_ext(struct ldbminfo *li, back_txnid parent_txn, back_txn *txn, PRBool use_lock)
 {
+    dblayer_private *priv = NULL;
+    int txn_begin_flags = 0;
+    PR_ASSERT(NULL != li);
+        
+    if ( g_get_shutdown() == SLAPI_SHUTDOWN_DISKFULL ) {
+        return -1;
+    }
+    
+    priv = (dblayer_private*)li->li_dblayer_private;
+    PR_ASSERT(NULL != priv);
+    
+    if (!priv->dblayer_txn_wait) {
+        txn_begin_flags = DB_TXN_NOWAIT;
+    }
+    return dblayer_txn_begin_ext_txnflags(li, parent_txn, txn, use_lock, txn_begin_flags);
+}
+
+int
+dblayer_txn_begin_ext_txnflags(struct ldbminfo *li, back_txnid parent_txn, back_txn *txn, PRBool use_lock, int txn_begin_flags)
+{
     int return_value = -1;
     dblayer_private *priv = NULL;
     back_txn new_txn = {NULL};
@@ -3349,8 +3368,6 @@ dblayer_txn_begin_ext(struct ldbminfo *li, back_txnid parent_txn, back_txn *txn,
 
     if (priv->dblayer_enable_transactions)
     {
-        int txn_begin_flags;
-
         dblayer_private_env *pEnv = priv->dblayer_env;
         if(use_lock) slapi_rwlock_rdlock(pEnv->dblayer_env_lock);
         if (!parent_txn)
@@ -3360,11 +3377,6 @@ dblayer_txn_begin_ext(struct ldbminfo *li, back_txnid parent_txn, back_txn *txn,
             if (par_txn_txn) {
                 parent_txn = par_txn_txn->back_txn_txn;
             }
-                }
-        if (priv->dblayer_txn_wait) {
-                txn_begin_flags = 0;
-        } else {
-                txn_begin_flags = DB_TXN_NOWAIT;
         }
         return_value = TXN_BEGIN(pEnv->dblayer_DB_ENV,
                                  (DB_TXN*)parent_txn,
@@ -3406,6 +3418,13 @@ dblayer_txn_begin_ext(struct ldbminfo *li, back_txnid parent_txn, back_txn *txn,
 }
 
 int
+dblayer_export_txn_begin(backend *be, back_txnid parent_txn, back_txn *txn)
+{
+    struct ldbminfo *li = (struct ldbminfo *)be->be_database->plg_private;
+    return (dblayer_txn_begin_ext_txnflags(li,parent_txn,txn,PR_FALSE,DB_READ_COMMITTED|DB_TXN_NOWAIT));
+}
+
+int
 dblayer_read_txn_begin(backend *be, back_txnid parent_txn, back_txn *txn)
 {
     struct ldbminfo *li = (struct ldbminfo *)be->be_database->plg_private;
@@ -3534,6 +3553,12 @@ int dblayer_txn_commit_ext(struct ldbminfo *li, back_txn *txn, PRBool use_lock)
 }
 
 int
+dblayer_export_txn_commit(backend *be, back_txn *txn)
+{
+    return dblayer_read_txn_commit(be, txn);
+}
+
+int
 dblayer_read_txn_commit(backend *be, back_txn *txn)
 {
     struct ldbminfo *li = (struct ldbminfo *)be->be_database->plg_private;
@@ -3626,6 +3651,12 @@ int dblayer_txn_abort_ext(struct ldbminfo *li, back_txn *txn, PRBool use_lock)
 }
 
 int
+dblayer_export_txn_abort(backend *be, back_txn *txn)
+{
+    return dblayer_read_txn_abort(be, txn);
+}
+
+int
 dblayer_read_txn_abort(backend *be, back_txn *txn)
 {
     struct ldbminfo *li = (struct ldbminfo *)be->be_database->plg_private;
diff --git a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
index 6d897ed..ec87d16 100644
--- a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
+++ b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
@@ -1079,6 +1079,7 @@ ldbm_back_ldbm2ldif( Slapi_PBlock *pb )
     struct ldbminfo  *li = NULL;
     DB               *db = NULL;
     DBC              *dbc = NULL;
+    back_txn         s_txn = {NULL};
     struct backentry *ep;
     DBT              key = {0};
     DBT              data = {0};
@@ -1115,9 +1116,9 @@ ldbm_back_ldbm2ldif( Slapi_PBlock *pb )
     static int       load_dse = 1; /* We'd like to load dse just once. */
     int              server_running;
     export_args      eargs = {0};
-
+    
     slapi_log_err(SLAPI_LOG_TRACE, "ldbm_back_ldbm2ldif", "=>\n");
-
+    
     slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &li );
     slapi_pblock_get( pb, SLAPI_TASK_FLAGS, &task_flags );
     slapi_pblock_get( pb, SLAPI_DB2LDIF_DECRYPT, &decrypt );
@@ -1284,8 +1285,9 @@ ldbm_back_ldbm2ldif( Slapi_PBlock *pb )
     }
 
     /* idl manipulation requires nextid to be init'd now */
-    if (include_suffix && ok_index)
+    if (include_suffix && ok_index) {
         get_ids_from_disk(be);
+    }
 
     if ((( dblayer_get_id2entry( be, &db )) != 0) || (db == NULL)) {
         slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_ldbm2ldif", "Could not open/create id2entry\n");
@@ -1293,6 +1295,21 @@ ldbm_back_ldbm2ldif( Slapi_PBlock *pb )
         goto bye;
     }
 
+    /* Open a TXN so that all our actions across id2entry and entryrdn can be
+     * correlated by the BDB layer.  If we don't group them in a transaction,
+     * we risk deadlocking ourself as we hop around to fill in parents, turn
+     * RDNs into DNs, etc. if it happens that we need to access a page which
+     * has already been locked. (TEL 20180626) */
+    slapi_log_err(SLAPI_LOG_TRACE, "ldbm_back_ldbm2ldif", "Beginning transaction for LDIF export.\n");
+    dblayer_txn_init(li, &s_txn);
+    rc = dblayer_export_txn_begin(be, NULL, &s_txn);
+    if (rc) {
+        slapi_log_err(SLAPI_LOG_ERR,
+                "ldbm_back_ldbm2ldif", "Transaction error: %s (%d)\n",
+                dblayer_strerror(return_value), return_value);
+        goto bye;
+    }
+
     /* if an include_suffix was given (and we're pretty sure the
      * entrydn and ancestorid indexes are valid), we try to
      * assemble an id-list of candidates instead of plowing thru
@@ -1306,7 +1323,7 @@ ldbm_back_ldbm2ldif( Slapi_PBlock *pb )
          * which it is !
          */
         /* get a cursor to we can walk over the table */
-        return_value = db->cursor(db,NULL,&dbc,0);
+        return_value = db->cursor(db, s_txn.back_txn_txn, &dbc, 0);
         if (0 != return_value || NULL == dbc) {
             slapi_log_err(SLAPI_LOG_ERR,
                           "ldbm_back_ldbm2ldif", "Failed to get cursor for db2ldif; %s (%d)\n",
@@ -1400,7 +1417,7 @@ ldbm_back_ldbm2ldif( Slapi_PBlock *pb )
             data.flags = DB_DBT_MALLOC;
 
             for (retry = 0; retry < RETRY_TIMES; retry++) {
-                return_value = db->get(db, NULL, &key, &data, 0);
+                return_value = db->get(db, s_txn.back_txn_txn, &key, &data, 0);
                 if (return_value != DB_LOCK_DEADLOCK) break;
             }
             if (return_value) {
@@ -1481,7 +1498,7 @@ ldbm_back_ldbm2ldif( Slapi_PBlock *pb )
                         eargs.cnt = &cnt;
                         eargs.lastcnt = &lastcnt;
 
-                        rc = _export_or_index_parents(inst, db, NULL, temp_id,
+                        rc = _export_or_index_parents(inst, db, &s_txn, temp_id,
                                             rdn, temp_id, pid, run_from_cmdline,
                                             &eargs, DB2LDIF_ENTRYRDN, &psrdn);
                         if (rc) {
@@ -1501,7 +1518,7 @@ ldbm_back_ldbm2ldif( Slapi_PBlock *pb )
                 } else {
                     int myrc = 0;
                     Slapi_DN *sdn = NULL;
-                    rc = entryrdn_lookup_dn(be, rdn, temp_id, &dn, NULL, NULL);
+                    rc = entryrdn_lookup_dn(be, rdn, temp_id, &dn, NULL, &s_txn);
                     if (rc) {
                         /* We cannot use the entryrdn index;
                          * Compose dn from the entries in id2entry */
@@ -1513,7 +1530,7 @@ ldbm_back_ldbm2ldif( Slapi_PBlock *pb )
                             if (NULL == slapi_rdn_get_rdn(&psrdn)) {
                                 /* This time just to get the parents' rdn
                                  * most likely from dn cache. */
-                                rc = _get_and_add_parent_rdns(be, db, NULL, pid,
+                                rc = _get_and_add_parent_rdns(be, db, &s_txn, pid,
                                                       &psrdn, NULL, 0,
                                                       run_from_cmdline, NULL);
                                 if (rc) {
@@ -1611,6 +1628,13 @@ bye:
     if (dbc) {
         dbc->c_close(dbc);
     }
+    if (s_txn.back_txn_txn) {
+        /* Abort rather than commit the transaction, since we should not be
+         * making any changes to the DB during an export, which this more or
+         * less guarantees. (TEL 20180626) */
+        slapi_log_err(SLAPI_LOG_TRACE, "ldbm_back_ldbm2ldif", "Aborting LDIF export transaction (this is normal).\n");
+        dblayer_export_txn_abort(be, &s_txn);
+    }
 
     dblayer_release_id2entry( be, db );
 
@@ -3283,6 +3307,7 @@ _get_and_add_parent_rdns(backend *be,
     char *pid_str = NULL;
     ID storedid;
     ID temp_pid = NOID;
+    DB_TXN *db_txn = (NULL != txn) ? txn->back_txn_txn : NULL;
 
     if (!entryrdn_get_switch()) { /* entryrdn specific code */
         return rc;
@@ -3347,7 +3372,7 @@ _get_and_add_parent_rdns(backend *be,
 
         memset(&data, 0, sizeof(data));
         data.flags = DB_DBT_MALLOC;
-        rc = db->get(db, NULL, &key, &data, 0);
+        rc = db->get(db, db_txn, &key, &data, 0);
         if (rc) {
             slapi_log_err(SLAPI_LOG_ERR, "_get_and_add_parent_rdns",
                             "Failed to position cursor at ID " ID_FMT "\n", id);
@@ -3511,7 +3536,7 @@ _export_or_index_parents(ldbm_instance *inst,
     }
 
     /* in case the parent is not already exported */
-    rc = entryrdn_get_parent(be, rdn, id, &prdn, &temp_pid, NULL);
+    rc = entryrdn_get_parent(be, rdn, id, &prdn, &temp_pid, txn);
     if (rc) { /* entryrdn is not available. */
         /* get the parent info from the id2entry (no add) */
         rc = _get_and_add_parent_rdns(be, db, txn, pid, psrdn, &ppid, 0,
@@ -3537,7 +3562,7 @@ _export_or_index_parents(ldbm_instance *inst,
             if (!bdn) {
                 /* we put pdn to dn cache, which could be used
                  * in _get_and_add_parent_rdns */
-                rc = entryrdn_lookup_dn(be, prdn, pid, &pdn, NULL, NULL);
+                rc = entryrdn_lookup_dn(be, prdn, pid, &pdn, NULL, txn);
                 if (0 == rc) {
                     int myrc = 0;
                     /* pdn is put in DN cache.  No need to free it here,
@@ -3565,7 +3590,7 @@ _export_or_index_parents(ldbm_instance *inst,
 
     /* check one more upper level */
     if (0 == ppid) {
-        rc = entryrdn_get_parent(be, prdn, pid, &pprdn, &ppid, NULL);
+        rc = entryrdn_get_parent(be, prdn, pid, &pprdn, &ppid, txn);
         slapi_ch_free_string(&pprdn);
         if (rc) { /* entryrdn is not available */
             slapi_log_err(SLAPI_LOG_ERR, "_export_or_index_parents",
diff --git a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
index 86ef5cb..d37737d 100644
--- a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
+++ b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
@@ -98,6 +98,7 @@ int dblayer_release_aux_id2entry(backend *be, DB *pDB, DB_ENV *pEnv);
 int dblayer_txn_init(struct ldbminfo *li, back_txn *txn);
 int dblayer_txn_begin(backend *be,back_txnid parent_txn, back_txn *txn);
 int dblayer_txn_begin_ext(struct ldbminfo *li, back_txnid parent_txn, back_txn *txn, PRBool use_lock);
+int dblayer_txn_begin_ext_txnflags(struct ldbminfo *li, back_txnid parent_txn, back_txn *txn, PRBool use_lock, int txn_begin_flags);
 int dblayer_txn_commit(backend *be, back_txn *txn);
 int dblayer_txn_commit_ext(struct ldbminfo *li, back_txn *txn, PRBool use_lock);
 int dblayer_txn_abort(backend *be, back_txn *txn);
@@ -105,6 +106,9 @@ int dblayer_txn_abort_ext(struct ldbminfo *li, back_txn *txn, PRBool use_lock);
 int dblayer_read_txn_abort(backend *be, back_txn *txn);
 int dblayer_read_txn_begin(backend *be,back_txnid parent_txn, back_txn *txn);
 int dblayer_read_txn_commit(backend *be, back_txn *txn);
+int dblayer_export_txn_abort(backend *be, back_txn *txn);
+int dblayer_export_txn_begin(backend *be,back_txnid parent_txn, back_txn *txn);
+int dblayer_export_txn_commit(backend *be, back_txn *txn);
 int dblayer_txn_begin_all(struct ldbminfo *li,back_txnid parent_txn, back_txn *txn);
 int dblayer_txn_commit_all(struct ldbminfo *li, back_txn *txn);
 int dblayer_txn_abort_all(struct ldbminfo *li, back_txn *txn);
