-
Notifications
You must be signed in to change notification settings - Fork 30
/
Copy pathmdbaux.c
148 lines (126 loc) · 3.85 KB
/
mdbaux.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
* Copyright 2012 Howard Chu. All rights reserved.
*
* Use and distribution licensed under the BSD license. See
* the LICENSE file for full text.
*
* Authors:
* Howard Chu <[email protected]>
*/
#include "memcachedb.h"
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <signal.h>
#include <lmdb.h>
static void *mdb_chkpoint_thread __P((void *));
static pthread_t chk_ptid;
void mdb_settings_init(void)
{
mdb_settings.env_home = DBHOME;
mdb_settings.cache_size = 1 * 1024 * 1024 * 1024; /* default is 1GB */
mdb_settings.txn_nosync = 0; /* default DB_TXN_NOSYNC is off */
mdb_settings.chkpoint_val = 60 * 5;
mdb_settings.env_flags = MDB_WRITEMAP;
}
void mdb_setup(void){
int ret;
unsigned int readers;
MDB_txn *txn;
/* db env init */
if ((ret = mdb_env_create(&env)) != 0) {
fprintf(stderr, "mdb_env_create: %s\n", mdb_strerror(ret));
exit(EXIT_FAILURE);
}
/* set map size */
if (sizeof(void *) == 4 && mdb_settings.cache_size > (1024uLL * 1024uLL * 1024uLL * 2uLL)) {
fprintf(stderr, "32bit box only max 2GB memory pool allowed\n");
exit(EXIT_FAILURE);
}
ret = mdb_env_set_mapsize(env, mdb_settings.cache_size);
/* check readers */
mdb_env_get_maxreaders(env, &readers);
if (settings.num_threads > readers) {
readers = settings.num_threads;
ret = mdb_env_set_maxreaders(env, readers);
}
/* if no home dir existed, we create it */
if (0 != access(mdb_settings.env_home, F_OK)) {
if (0 != mkdir(mdb_settings.env_home, 0750)) {
fprintf(stderr, "mkdir env_home error:[%s]\n", mdb_settings.env_home);
exit(EXIT_FAILURE);
}
}
if ((ret = mdb_env_open(env, mdb_settings.env_home, mdb_settings.env_flags, 0640)) != 0) {
fprintf(stderr, "mdb_env_open: %s\n", mdb_strerror(ret));
exit(EXIT_FAILURE);
}
/* set DB_TXN_NOSYNC flag */
if (mdb_settings.txn_nosync){
mdb_env_set_flags(env, MDB_NOSYNC, 1);
}
if ((ret = mdb_txn_begin(env, NULL, 0, &txn)) != 0) {
fprintf(stderr, "mdb_txn_begin: %s\n", mdb_strerror(ret));
exit(EXIT_FAILURE);
}
if ((ret = mdb_open(txn, NULL, 0, &dbi)) != 0) {
fprintf(stderr, "mdb_open: %s\n", mdb_strerror(ret));
exit(EXIT_FAILURE);
}
mdb_txn_commit(txn);
}
void start_chkpoint_thread(void){
if (mdb_settings.chkpoint_val > 0){
/* Start a checkpoint thread. */
if ((errno = pthread_create(
&chk_ptid, NULL, mdb_chkpoint_thread, (void *)env)) != 0) {
fprintf(stderr,
"failed spawning checkpoint thread: %s\n",
strerror(errno));
exit(EXIT_FAILURE);
}
}
}
static void *mdb_chkpoint_thread(void *arg)
{
MDB_env *dbenv;
int ret;
dbenv = arg;
if (settings.verbose > 1) {
fprintf(stderr, "checkpoint thread created: %lu, every %d seconds\n",
(u_long)pthread_self(), mdb_settings.chkpoint_val);
}
for (;; sleep(mdb_settings.chkpoint_val)) {
if ((ret = mdb_env_sync(dbenv, 1)) != 0) {
fprintf(stderr, "checkpoint thread: %s\n", mdb_strerror(ret));
}
fprintf(stderr, "checkpoint thread: a checkpoint is done\n");
}
return (NULL);
}
/* for atexit cleanup */
void mdb_shutdown(void){
if (env != NULL) {
mdb_env_close(env);
env = NULL;
}
}
/* for atexit cleanup */
void mdb_chkpoint(void)
{
int ret = 0;
if (env != NULL){
ret = mdb_env_sync(env, 1);
if (0 != ret){
fprintf(stderr, "mdb_env_sync: %s\n", mdb_strerror(ret));
}else{
fprintf(stderr, "mdb_env_sync: OK\n");
}
}
}