struct MDB_oldpages *mo_next;
/** The ID of the transaction in which these pages were freed. */
txnid_t mo_txnid;
- /** An #IDL of the pages */
+ /** An #MDB_IDL of the pages */
pgno_t mo_pages[1]; /* dynamic */
} MDB_oldpages;
pgno_t pgno = P_INVALID;
MDB_ID2 mid;
- if (txn->mt_txnid > 2) {
+ /* The free list won't have any content at all until txn 2 has
+ * committed. The pages freed by txn 2 will be unreferenced
+ * after txn 3 commits, and so will be safe to re-use in txn 4.
+ */
+ if (txn->mt_txnid > 3) {
if (!txn->mt_env->me_pghead &&
txn->mt_dbs[FREE_DBI].md_root != P_INVALID) {
txn->mt_u.dirty_list[0].mid = 0;
txn->mt_free_pgs = env->me_free_pgs;
txn->mt_free_pgs[0] = 0;
- txn->mt_next_pgno = env->me_metas[txn->mt_toggle]->mm_last_pg+1;
env->me_txn = txn;
}
+ txn->mt_next_pgno = env->me_metas[txn->mt_toggle]->mm_last_pg+1;
/* Copy the DB arrays */
LAZY_RWLOCK_RDLOCK(&env->me_dblock);
}
if ((rc = mdb_env_open2(env, flags)) == MDB_SUCCESS) {
- if (flags & (MDB_RDONLY|MDB_NOSYNC)) {
+ if (flags & (MDB_RDONLY|MDB_NOSYNC|MDB_NOMETASYNC)) {
env->me_mfd = env->me_fd;
} else {
/* synchronous fd for meta writes */
}
}
if (!p) {
- if (pgno <= txn->mt_env->me_metas[txn->mt_toggle]->mm_last_pg)
+ if (pgno < txn->mt_next_pgno)
p = (MDB_page *)(txn->mt_env->me_map + txn->mt_env->me_psize * pgno);
}
*ret = p;
* @param[in] newkey The key for the newly inserted node.
* @param[in] newdata The data for the newly inserted node.
* @param[in] newpgno The page number, if the new node is a branch node.
+ * @param[in] nflags The #NODE_ADD_FLAGS for the new node.
* @return 0 on success, non-zero on failure.
*/
static int
* at runtime. Changing other flags requires closing the environment
* and re-opening it with the new flags.
*/
-#define CHANGEABLE (MDB_NOSYNC)
+#define CHANGEABLE (MDB_NOSYNC|MDB_NOMETASYNC)
int
mdb_env_set_flags(MDB_env *env, unsigned int flag, int onoff)
{
#define MDB_NOSYNC 0x10000
/** read only */
#define MDB_RDONLY 0x20000
+ /** don't fsync metapage after commit */
+#define MDB_NOMETASYNC 0x40000
/** @} */
/** @defgroup mdb_open Database Flags
* at risk is governed by how often the system flushes dirty buffers to disk
* and how often #mdb_env_sync() is called. This flag may be changed
* at any time using #mdb_env_set_flags().
+ * <li>#MDB_NOMETASYNC
+ * Don't perform a synchronous flush of the meta page after committing
+ * a transaction. This is similar to the #MDB_NOSYNC case, but safer
+ * because the transaction data is still flushed. The meta page for any
+ * transaction N will be flushed by the data flush of transaction N+1.
+ * In case of a system crash, the last committed transaction may be
+ * lost. This flag may be changed at any time using #mdb_env_set_flags().
* <li>#MDB_RDONLY
* Open the environment in read-only mode. No write operations will be allowed.
* </ul>
/** @brief Set environment flags.
*
* This may be used to set some flags that weren't already set during
- * #mdb_env_open(), or to unset these flags. Currently only the
- * #MDB_NOSYNC flag setting may be changed with this function.
+ * #mdb_env_open(), or to unset these flags.
* @param[in] env An environment handle returned by #mdb_env_create()
* @param[in] flags The flags to change, bitwise OR'ed together
* @param[in] onoff A non-zero value sets the flags, zero clears them.