mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-03-07 14:18:15 +08:00
Add mdb_copy for backing up a DB environment
This commit is contained in:
parent
756ce8e10c
commit
ebb6859ea5
@ -5,7 +5,7 @@ CFLAGS = -pthread $(OPT) $(W) $(XCFLAGS)
|
||||
LDLIBS =
|
||||
SOLIBS =
|
||||
|
||||
PROGS = mdb_stat mtest mtest2 mtest3 mtest4 mtest5
|
||||
PROGS = mdb_stat mdb_copy mtest mtest2 mtest3 mtest4 mtest5
|
||||
all: libmdb.a libmdb.so $(PROGS)
|
||||
|
||||
clean:
|
||||
@ -22,6 +22,7 @@ libmdb.so: mdb.o midl.o
|
||||
gcc -pthread -shared -o $@ mdb.o midl.o $(SOLIBS)
|
||||
|
||||
mdb_stat: mdb_stat.o libmdb.a
|
||||
mdb_copy: mdb_copy.o libmdb.a
|
||||
mtest: mtest.o libmdb.a
|
||||
mtest2: mtest2.o libmdb.a
|
||||
mtest3: mtest3.o libmdb.a
|
||||
|
@ -32,6 +32,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#define _GNU_SOURCE
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/param.h>
|
||||
@ -3280,6 +3281,101 @@ mdb_env_close0(MDB_env *env, int excl)
|
||||
env->me_lfd = INVALID_HANDLE_VALUE; /* Mark env as reset */
|
||||
}
|
||||
|
||||
int
|
||||
mdb_env_copy(MDB_env *env, const char *path)
|
||||
{
|
||||
MDB_txn *txn = NULL;
|
||||
int rc, len, oflags;
|
||||
size_t wsize;
|
||||
char *lpath, *ptr;
|
||||
HANDLE newfd = INVALID_HANDLE_VALUE;
|
||||
|
||||
if (env->me_flags & MDB_NOSUBDIR) {
|
||||
lpath = path;
|
||||
} else {
|
||||
len = strlen(path);
|
||||
len += sizeof(DATANAME);
|
||||
lpath = malloc(len);
|
||||
if (!lpath)
|
||||
return ENOMEM;
|
||||
sprintf(lpath, "%s" DATANAME, path);
|
||||
}
|
||||
|
||||
/* The destination path must exist, but the destination file must not.
|
||||
* We don't want the OS to cache the writes, since the source data is
|
||||
* already in the OS cache.
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
newfd = CreateFile(lpath, GENERIC_WRITE, 0, NULL, CREATE_NEW,
|
||||
FILE_FLAG_NO_BUFFERING|FILE_FLAG_WRITE_THROUGH, NULL);
|
||||
#else
|
||||
newfd = open(lpath, O_WRONLY|O_CREAT|O_EXCL
|
||||
#ifdef O_DIRECT
|
||||
|O_DIRECT
|
||||
#endif
|
||||
, 0666);
|
||||
#endif
|
||||
if (!(env->me_flags & MDB_NOSUBDIR))
|
||||
free(lpath);
|
||||
if (newfd == INVALID_HANDLE_VALUE) {
|
||||
rc = ErrCode();
|
||||
goto leave;
|
||||
}
|
||||
|
||||
#ifdef F_NOCACHE /* __APPLE__ */
|
||||
rc = fcntl(newfd, F_NOCACHE, 1);
|
||||
if (rc) {
|
||||
rc = ErrCode();
|
||||
goto leave;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Temporarily block writers until we snapshot the meta pages */
|
||||
LOCK_MUTEX_W(env);
|
||||
|
||||
rc = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn);
|
||||
if (rc) {
|
||||
UNLOCK_MUTEX_W(env);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
wsize = env->me_psize * 2;
|
||||
#ifdef _WIN32
|
||||
{
|
||||
DWORD len;
|
||||
rc = WriteFile(newfd, env->me_map, wsize, &len, NULL);
|
||||
rc = (len == wsize) ? MDB_SUCCESS : ErrCode();
|
||||
}
|
||||
#else
|
||||
rc = write(newfd, env->me_map, wsize);
|
||||
rc = (rc == (int)wsize) ? MDB_SUCCESS : ErrCode();
|
||||
#endif
|
||||
UNLOCK_MUTEX_W(env);
|
||||
|
||||
if (rc)
|
||||
goto leave;
|
||||
|
||||
ptr = env->me_map + wsize;
|
||||
wsize = txn->mt_next_pgno * env->me_psize - wsize;
|
||||
#ifdef _WIN32
|
||||
{
|
||||
DWORD len;
|
||||
rc = WriteFile(newfd, ptr, wsize, &len, NULL);
|
||||
rc = (len == wsize) ? MDB_SUCCESS : ErrCode();
|
||||
}
|
||||
#else
|
||||
rc = write(newfd, ptr, wsize);
|
||||
rc = (rc == (int)wsize) ? MDB_SUCCESS : ErrCode();
|
||||
#endif
|
||||
mdb_txn_abort(txn);
|
||||
|
||||
leave:
|
||||
if (newfd != INVALID_HANDLE_VALUE)
|
||||
close(newfd);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void
|
||||
mdb_env_close(MDB_env *env)
|
||||
{
|
||||
|
@ -450,6 +450,18 @@ int mdb_env_create(MDB_env **env);
|
||||
*/
|
||||
int mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mode_t mode);
|
||||
|
||||
/** @brief Copy an MDB environment to the specified path.
|
||||
*
|
||||
* This function may be used to make a backup of an existing environment.
|
||||
* @param[in] env An environment handle returned by #mdb_env_create(). It
|
||||
* must have already been opened successfully.
|
||||
* @param[in] path The directory in which the copy will reside. This
|
||||
* directory must already exist and be writable but must otherwise be
|
||||
* empty.
|
||||
* @return A non-zero error value on failure and 0 on success.
|
||||
*/
|
||||
int mdb_env_copy(MDB_env *env, const char *path);
|
||||
|
||||
/** @brief Return statistics about the MDB environment.
|
||||
*
|
||||
* @param[in] env An environment handle returned by #mdb_env_create()
|
||||
|
43
libraries/libmdb/mdb_copy.c
Normal file
43
libraries/libmdb/mdb_copy.c
Normal file
@ -0,0 +1,43 @@
|
||||
/* mdb_copy.c - memory-mapped database backup tool */
|
||||
/*
|
||||
* Copyright 2012 Howard Chu, Symas Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted only as authorized by the OpenLDAP
|
||||
* Public License.
|
||||
*
|
||||
* A copy of this license is available in the file LICENSE in the
|
||||
* top-level directory of the distribution or, alternatively, at
|
||||
* <http://www.OpenLDAP.org/license.html>.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include "mdb.h"
|
||||
|
||||
int main(int argc,char * argv[])
|
||||
{
|
||||
int rc;
|
||||
MDB_env *env;
|
||||
char *envname = argv[1];
|
||||
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "usage: %s srcpath dstpath\n", argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
rc = mdb_env_create(&env);
|
||||
|
||||
rc = mdb_env_open(env, envname, MDB_RDONLY, 0);
|
||||
if (rc) {
|
||||
printf("mdb_env_open failed, error %d %s\n", rc, mdb_strerror(rc));
|
||||
} else {
|
||||
rc = mdb_env_copy(env, argv[2]);
|
||||
if (rc)
|
||||
printf("mdb_env_copy failed, error %d %s\n", rc, mdb_strerror(rc));
|
||||
}
|
||||
mdb_env_close(env);
|
||||
|
||||
return rc ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
}
|
Loading…
Reference in New Issue
Block a user