BerkeleyDB - WindyHana's Solanara

목차

개요

설치

db-*.gz 파일의 다운로드는 Oracle Berkeley DB Downloads에서 받을 수 있다.
root@wl ~/src # tar xvfz db-5.1.25.tar.gz
root@wl ~/src # cd db-5.1.25
root@wl ~/src/db-5.1.25 # cd build_unix
root@wl ~/src/db-5.1.25/build_unix # ../dist/configure --enable-pthread_api --enable-dtrace --enable-dbm
root@wl ~/src/db-5.1.25/build_unix # make
root@wl ~/src/db-5.1.25/build_unix # make install
root@wl ~/src/db-5.1.25/build_unix # cd /usr/local
root@wl /usr/local # ln -s BerkeleyDB.5.1 db 1)
root@wl /usr/local # vi /etc/profile
...
LD_LIBRARY_PATH=/usr/local/db/lib:$LD_LIBRARY_PATH
1) 버클리DB가 버전마다 디렉토리가 다른 관계로, 솔라나라에서는 /usr/local/db 를 사용해 버클리DB와 연동한다.

명령어

C 프로그램 예제

Getting Started with Berkeley DB의 내용을 일부 발췌했다. 대부분의 코드는 매뉴얼에서 가져왔다.
berkeleydb.c
 다운로드 (6,202 바이트)
/*
	BerkeleyDB Sample Code
	WindyHana's Solanara: BerkeleyDB http://www.solanara.net/solanara/berkeleydb
	cc -L/usr/local/db/lib -ldb -I/usr/local/db/include -o berkeleydb berkeleydb.c
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "db.h"
#define  DBFILE "berkeleydb.db"
#define  ENV_DIRECTORY "./"

DB_ENV* dbenv;
DB* dbp;
//DB_MPOOL_STAT* dbmpoolstat;

int putData(char * key, char * val) {
    DBT dbkey, dbval;

    memset(&dbkey, 0, sizeof(dbkey));
    memset(&dbval, 0, sizeof(dbval));
    dbkey.data = key;
    dbkey.size = sizeof(key);
    dbval.data = val;
    dbval.size = sizeof(val);

	return dbp->put(dbp, NULL, &dbkey, &dbval, 0);
}

int genSampleData() {
    putData("apple", "red");
    putData("banana", "yellow");
    putData("grape", "purple");
}

void env_open(DB_ENV **dbenvp) {
	DB_ENV *dbenv;
	int flags;
	int ret;

	/* Create the environment handle. */
	if ((ret = db_env_create(&dbenv, 0)) != 0) {
		fprintf(stderr, "txnapp: db_env_create: %s\n", db_strerror(ret));
		exit (1);
	}

	/* Set up error handling. */
	dbenv->set_errpfx(dbenv, "데이터베이스 정보/오류");

	/* Do deadlock detection internally. */
	if ((ret = dbenv->set_lk_detect(dbenv, DB_LOCK_DEFAULT)) != 0) {
		dbenv->err(dbenv, ret, "set_lk_detect: DB_LOCK_DEFAULT");
		exit (1);
	}

	/* * Open a transactional environment: * create if it doesn't exist * free-threaded handle * run recovery * read/write owner only */
	
	flags = DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN | DB_RECOVER | DB_THREAD;
	if ((ret = dbenv->open(dbenv, ENV_DIRECTORY, flags, S_IRUSR | S_IWUSR)) != 0) {
		dbenv->err(dbenv, ret, "dbenv->open: %s", ENV_DIRECTORY);
		exit (1);
	}

	*dbenvp = dbenv;
}

void * checkpoint_thread(void *arg) {
	DB_ENV *dbenv;
	int ret;
	pthread_t ptid;
	
	dbenv = arg;
	printf("체크포인트 쓰레드(%lu) ", (u_long)pthread_self());

	/* Checkpoint once a minute. */
	for (;; sleep(60)) if ((ret = dbenv->txn_checkpoint(dbenv, 0, 0, 0)) != 0) {
		dbenv->err(dbenv, ret, "checkpoint thread");
		exit (1);
	}
}

/* 필요 없는 로그 파일 삭제 */
void * logfile_thread(void *arg) {
	DB_ENV *dbenv;
	int ret;
	char **begin, **list;
	dbenv = arg;
	printf("로그 삭제 쓰레드(%lu) ", (u_long)pthread_self());

	/* Check once every 5 minutes. */
	for (;; sleep(300)) {
		/* Get the list of log files. */
		if ((ret = dbenv->log_archive(dbenv, &list, DB_ARCH_ABS)) != 0) {
			dbenv->err(dbenv, ret, "DB_ENV->log_archive");
			exit (1);
		}
		/* Remove the log files. */
		if (list != NULL) {
			for (begin = list; *list != NULL; ++list) {
				if ((ret = remove(*list)) != 0) {
					dbenv->err(dbenv, ret, "remove %s", *list);
					exit (1);
				}
			}
			free (begin);
		} 
	}
}

/* 사용하는 로그 파일 보임 */
void log_archlist(DB_ENV *dbenv)
{
	int ret;
	char **begin, **list;

	/* Get the list of database files. */
	if ((ret = dbenv->log_archive(dbenv, &list, DB_ARCH_ABS | DB_ARCH_DATA)) != 0) {
		dbenv->err(dbenv, ret, "DB_ENV->log_archive: DB_ARCH_DATA");
		exit (1);
	}

	if (list != NULL) {
		for (begin = list; *list != NULL; ++list) printf("database file: %s\n", *list);
		free (begin);
	}

	/* Get the list of log files. */
	if ((ret = dbenv->log_archive(dbenv, &list, DB_ARCH_ABS | DB_ARCH_LOG)) != 0) {
		dbenv->err(dbenv, ret, "DB_ENV->log_archive: DB_ARCH_LOG");
		exit (1);
	}

	if (list != NULL) {
		for (begin = list; *list != NULL; ++list) printf("데이터베이스 로그파일: %s\n", *list);
		free (begin);
	}
}

int main() {
    DBT key, val;
    int ret;
    pthread_t ptid;

    printf("데이터베이스 환경 오픈\n");
	env_open(&dbenv);

    printf("데이터베이스 체크 포인트 쓰레드 시작\n");
	if ((ret = pthread_create(&ptid, NULL, checkpoint_thread, (void *)dbenv)) != 0) {
		fprintf(stderr, "checkpoint: failed spawning checkpoint thread: %s\n", db_strerror(ret));
		exit (1);
	}

    fflush(stdout); printf("데이터베이스 로그 삭제 쓰레드 시작\n");
	if ((ret = pthread_create(&ptid, NULL, logfile_thread, (void *)dbenv)) != 0) {
		fprintf(stderr, "txnapp: failed spawning log file removal thread: %s\n", db_strerror(ret));
		exit (1);
	}

    printf("데이터베이스 생성 (버전: %s)\n", DB_VERSION_STRING);
    if ((ret = db_create(&dbp, dbenv, 0)) != 0) {
        fprintf(stderr, "db_create: %s\n", db_strerror(ret));
        exit(1);
    }

    printf("데이터 베이스 오픈(%s): ", DBFILE);
    if ((ret = dbp->open(dbp, NULL, DBFILE, NULL, DB_BTREE, DB_CREATE, 0664)) != 0) {
        printf("Fail - "); fflush(stdout); dbp->err(dbp, ret, "db->open(%s)", DBFILE);
        goto done;
    }
    printf("성공\n");
    
    memset(&key, 0, sizeof(key));
    memset(&val, 0, sizeof(val));
    key.data = "key1";
    key.size = sizeof("key1");
    val.data = "val1";
    val.size = sizeof("val1");
    printf("데이터 넣기 (%s, %s): ", key.data, val.data);
    if ((ret = dbp->put(dbp, NULL, &key, &val, 0)) != 0) {
        printf("Fail - "); fflush(stdout); dbp->err(dbp, ret, "db->put");
        goto done;
    }
    printf("성공\n");
    
    memset(&val, 0, sizeof(val));
    printf("데이터 얻기 (%s): ", key.data);

    key.flags = DB_DBT_REALLOC;
    val.flags = DB_DBT_REALLOC;
	if ((ret = dbp->get(dbp, NULL, &key, &val, 0)) != 0) {
		printf("Fail - "); fflush(stdout); dbp->err(dbp, ret, "db->get");
		goto done;
	}
	printf("성공 - %s\n", val.data);
                 
	printf("데이터 삭제 (키: %s): ", key.data);
	if ((ret = dbp->del(dbp, NULL, &key, 0)) != 0) {
		printf("Fail - "); fflush(stdout); dbp->err(dbp, ret, "DB->del");
		goto done;
	}
	printf("성공\n");

	printf("삭제된 데이터 얻기(실패해야함): ", key.data);
	if ((ret = dbp->get(dbp, NULL, &key, &val, 0)) != 0) {
		printf("Fail - "); fflush(stdout); dbp->err(dbp, ret, "DB->get");
		goto done;
	}
	printf("성공\n"); // Cannot be reached.

done:
	genSampleData();
	printf("샘플 데이터 삽입됨.\n");
	log_archlist(dbenv);

    if (dbp != NULL) { ret = dbp->close(dbp, 0); }
    if (dbenv != NULL) { ret = dbenv->close(dbenv, 0); }
	printf("데이터 베이스 닫음.\n");
    exit(ret);
}
root@wl ~ # ./berkeleydb
데이터베이스 환경 오픈
데이터베이스 체크 포인트 쓰레드 시작
데이터베이스 로그 삭제 쓰레드 시작
데이터베이스 생성 (버전: Berkeley DB 5.0.26: (June 25, 2010))
데이터 베이스 오픈(berkeleydb.db): 체크포인트 쓰레드(2) 로그 삭제 쓰레드(3) 성공
데이터 넣기 (key1, val1): 성공
데이터 얻기 (key1): 성공 - val1
데이터 삭제 (키: key1): 성공
삭제된 데이터 얻기(실패해야함): Fail - 데이터베이스 정보/오류: DB->get: DB_NOTFOUND: No matching key/data pair found
샘플 데이터 삽입됨.
데이터베이스 로그파일: /export/home/windy/test/bdb/./log.0000000001
데이터 베이스 닫음.
root@wl ~ #
Twitter RSS IconTexto 올바른 XHTML 1.0 Transitional 입니다 올바른 CSS입니다!