diff --git a/libraries/liblmdb/CHANGES b/libraries/liblmdb/CHANGES index 20babf3db5..857a08e14c 100644 --- a/libraries/liblmdb/CHANGES +++ b/libraries/liblmdb/CHANGES @@ -1,5 +1,13 @@ LMDB 0.9 Change Log +LMDB 0.9.34 Engineering + ITS#10222 - Update mdb_dump(1) and mdb_load(1) man pages for append (-a) option + ITS#10275 - mdb_load: add -Q option to use NOSYNC + ITS#10296 - fix fdatasync on MacOS + ITS#10342 - fix memleak in mdb_txn_begin for nested txns + ITS#10346 - fix mdb_env_copy2 with values > (2GB-16) + ITS#10355 - fix mplay build on musl + LMDB 0.9.33 Release (2024/05/21) ITS#9037 mdb_page_search: fix error code when DBI record is missing ITS#10198 For win32, stop passing ignored parameter diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c index 668f9660f2..7a52945c3b 100644 --- a/libraries/liblmdb/mdb.c +++ b/libraries/liblmdb/mdb.c @@ -128,7 +128,11 @@ typedef SSIZE_T ssize_t; # define MDB_USE_ROBUST 1 #elif defined(__APPLE__) || defined (BSD) || defined(__FreeBSD_kernel__) # define MDB_USE_POSIX_SEM 1 -# define MDB_FDATASYNC fsync +# if defined(__APPLE__) +# define MDB_FDATASYNC fcntl(fd, F_FULLFSYNC) +# else +# define MDB_FDATASYNC fsync +# endif #elif defined(ANDROID) # define MDB_FDATASYNC fsync #endif @@ -2573,7 +2577,7 @@ mdb_env_sync(MDB_env *env, int force) ? MS_ASYNC : MS_SYNC; if (MDB_MSYNC(env->me_map, env->me_mapsize, flags)) rc = ErrCode(); -#ifdef _WIN32 +#if defined(_WIN32) || defined(__APPLE__) else if (flags == MS_SYNC && MDB_FDATASYNC(env->me_fd)) rc = ErrCode(); #endif @@ -2970,8 +2974,10 @@ renew: rc = mdb_txn_renew0(txn); } if (rc) { - if (txn != env->me_txn0) + if (txn != env->me_txn0) { + free(txn->mt_u.dirty_list); free(txn); + } } else { txn->mt_flags |= flags; /* could not change txn=me_txn0 earlier */ *ret = txn; @@ -9170,8 +9176,8 @@ typedef struct mdb_copy { pthread_cond_t mc_cond; /**< Condition variable for #mc_new */ char *mc_wbuf[2]; char *mc_over[2]; - int mc_wlen[2]; - int mc_olen[2]; + size_t mc_wlen[2]; + size_t mc_olen[2]; pgno_t mc_next_pgno; HANDLE mc_fd; int mc_toggle; /**< Buffer number in provider */ @@ -9188,7 +9194,8 @@ mdb_env_copythr(void *arg) { mdb_copy *my = arg; char *ptr; - int toggle = 0, wsize, rc; + int toggle = 0, rc; + size_t wsize; #ifdef _WIN32 DWORD len; #define DO_WRITE(rc, fd, ptr, w2, len) rc = WriteFile(fd, ptr, w2, &len, NULL) diff --git a/libraries/liblmdb/mdb_dump.1 b/libraries/liblmdb/mdb_dump.1 index 5f2d771b58..9674c29f7b 100644 --- a/libraries/liblmdb/mdb_dump.1 +++ b/libraries/liblmdb/mdb_dump.1 @@ -61,14 +61,14 @@ Exit status is zero if no errors occur. Errors result in a non-zero exit status and a diagnostic message being written to standard error. -Dumping and reloading databases that use user-defined comparison functions -will result in new databases that use the default comparison functions. -\fBIn this case it is quite likely that the reloaded database will be -damaged beyond repair permitting neither record storage nor retrieval.\fP +Dumping databases that use user-defined comparison functions will output +records with the ordering imposed by those comparison functions. If +.B mdb_load +is invoked without including the +.B -a +option when reloading those records, the new databases will likely be +damaged beyond repair, permitting neither record storage nor retrieval. -The only available workaround is to modify the source for the -.BR mdb_load (1) -utility to load the database using the correct comparison functions. .SH "SEE ALSO" .BR mdb_load (1) .SH AUTHOR diff --git a/libraries/liblmdb/mdb_load.1 b/libraries/liblmdb/mdb_load.1 index 78439a14da..741555f87c 100644 --- a/libraries/liblmdb/mdb_load.1 +++ b/libraries/liblmdb/mdb_load.1 @@ -8,6 +8,8 @@ mdb_load \- LMDB environment import tool [\c .BR \-V ] [\c +.BR \-a ] +[\c .BI \-f \ file\fR] [\c .BR \-n ] @@ -16,6 +18,8 @@ mdb_load \- LMDB environment import tool [\c .BR \-N ] [\c +.BR \-Q ] +[\c .BR \-T ] .BR \ envpath .SH DESCRIPTION @@ -56,6 +60,9 @@ Load a specific subdatabase. If no database is specified, data is loaded into th .BR \-N Don't overwrite existing records when loading into an already existing database; just skip them. .TP +.BR \-Q +Quick mode, uses MDB_NOSYNC for faster loading. Forces sync with mdb_env_sync() before exiting. +.TP .BR \-T Load data from simple text files. The input must be paired lines of text, where the first line of the pair is the key item, and the second line of the pair is its corresponding diff --git a/libraries/liblmdb/mdb_load.c b/libraries/liblmdb/mdb_load.c index cba6c06003..d266b4f6e1 100644 --- a/libraries/liblmdb/mdb_load.c +++ b/libraries/liblmdb/mdb_load.c @@ -311,10 +311,11 @@ int main(int argc, char *argv[]) * -n: use NOSUBDIR flag on env_open * -s: load into named subDB * -N: use NOOVERWRITE on puts + * -Q: quick mode using NOSYNC * -T: read plaintext * -V: print version and exit */ - while ((i = getopt(argc, argv, "af:ns:NTV")) != EOF) { + while ((i = getopt(argc, argv, "af:ns:NQTV")) != EOF) { switch(i) { case 'V': printf("%s\n", MDB_VERSION_STRING); @@ -339,6 +340,9 @@ int main(int argc, char *argv[]) case 'N': putflags = MDB_NOOVERWRITE|MDB_NODUPDATA; break; + case 'Q': + envflags |= MDB_NOSYNC; + break; case 'T': mode |= NOHDR | PRINT; break; @@ -403,9 +407,9 @@ int main(int argc, char *argv[]) goto env_close; } - rc = mdb_open(txn, subname, flags|MDB_CREATE, &dbi); + rc = mdb_dbi_open(txn, subname, flags|MDB_CREATE, &dbi); if (rc) { - fprintf(stderr, "mdb_open failed, error %d %s\n", rc, mdb_strerror(rc)); + fprintf(stderr, "mdb_dbi_open failed, error %d %s\n", rc, mdb_strerror(rc)); goto txn_abort; } prevk.mv_size = 0; @@ -486,6 +490,13 @@ int main(int argc, char *argv[]) prog, lineno, mdb_strerror(rc)); goto env_close; } + if (envflags & MDB_NOSYNC) { + rc = mdb_env_sync(env, 1); + if (rc) { + fprintf(stderr, "mdb_env_sync failed, error %d %s\n", rc, mdb_strerror(rc)); + goto env_close; + } + } mdb_dbi_close(env, dbi); } diff --git a/libraries/liblmdb/mplay.c b/libraries/liblmdb/mplay.c index 0fef74f67e..4673036774 100644 --- a/libraries/liblmdb/mplay.c +++ b/libraries/liblmdb/mplay.c @@ -483,12 +483,10 @@ static pidpair *addpid(int tpid) pipe(fdin); if ((pid = fork()) == 0) { /* child */ - fclose(stdin); - fclose(stdout); + fflush(stdin); + fflush(stdout); dup2(fdout[0], 0); dup2(fdin[1], 1); - stdin = fdopen(0, "r"); - stdout = fdopen(1, "w"); child(); return 0; /* NOTREACHED */ } else {