liuis / leveldb

Automatically exported from code.google.com/p/leveldb
BSD 3-Clause "New" or "Revised" License
0 stars 0 forks source link

leveldb 打不开. MANIFEST文件丢失 #73

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
我在zeroc-ice的两个接口函数里, 
频繁的打开/读写/关闭leveldb数据库.
现在leveldb不能打开了, MANIFEST文件丢失了。
有办法恢复吗?

What is the expected output? What do you see instead?

What version of the product are you using? On what operating system?
leveldb 1.1 on centos6.2

Please provide any additional information below.

Original issue reported on code.google.com by liuhengl...@gmail.com on 7 Mar 2012 at 5:49

GoogleCodeExporter commented 9 years ago
sorry!! leveldb version is:
Release 1.2 2011-05-16

Original comment by liuhengl...@gmail.com on 7 Mar 2012 at 5:51

GoogleCodeExporter commented 9 years ago
// this code damaged leveldb
#include <assert.h>
#include "leveldb/db.h"
#include "iostream"

using namespace std;

void *threada(void *)
{
    char i = 'a';

    while (1) {     
        leveldb::DB* db;
        leveldb::Options options;
        options.create_if_missing = true;
        leveldb::Status status = leveldb::DB::Open(options, "./db", &db);
        if (!status.ok())
            continue;

        string key = "c04e873dabbf66de02";
        key += i;
        i++;

        db->Put(leveldb::WriteOptions(), key, "{\"conf\":5,\"endTime\":\"86400\",\"pushWeek\":\"127\",\"startTime\":\"0\"}");

        delete db;
    }

}

void *threadb(void *)
{
    while (1) {
        leveldb::DB* db;
        leveldb::Options options;
        options.create_if_missing = true;
        leveldb::Status status = leveldb::DB::Open(options, "./db", &db);
        if (!status.ok())
            continue;
//      assert(status.ok());

        leveldb::Iterator* it = db->NewIterator(leveldb::ReadOptions());
        for (it->SeekToFirst(); it->Valid(); it->Next()) {
            cout << it->key().ToString() << ": "  << it->value().ToString() << endl;
        }

        delete it;
        delete db;
    }
}

int main(int argc, char *argv[])
{
    pthread_t ptid = 0;
    pthread_create(&ptid, NULL, threada, NULL);
    pthread_detach(ptid);
    pthread_create(&ptid, NULL, threadb, NULL);
    pthread_detach(ptid);

    sleep(1000);

    return 0;
}

Original comment by liuhengl...@gmail.com on 7 Mar 2012 at 8:45

GoogleCodeExporter commented 9 years ago
干什么要 在两个线程打开同一个db???
直接 一个 全局变量 ,打开一次 db就可以了么。。
leveldb是支持 single进程  multi线程 读写的。

Original comment by anyanmw on 22 Mar 2012 at 6:07

GoogleCodeExporter commented 9 years ago
楼上正解。

一处打开,多线程共用。

Original comment by Allnul...@gmail.com on 22 Mar 2012 at 7:36

GoogleCodeExporter commented 9 years ago
不论怎么个用法, 数据库得稳定,健壮,不能坏。

Original comment by liuhengl...@gmail.com on 22 Mar 2012 at 7:40

GoogleCodeExporter commented 9 years ago
帮你修改了一下。测试 应该还行。就是 什么时候结束 
这个应该你来做一下。。

// this code damaged leveldb
#include <assert.h>
#include "leveldb/db.h"
#include "iostream"
#include <unistd.h>

using namespace std;
    leveldb::DB* db;
    leveldb::Options options;
    leveldb::Status status ;
void *threada(void *)
{
    char i = 'a';

    while (1) {
    if(db){     
        string key = "c04e873dabbf66de02";
        key += i;
        i++;
        db->Put(leveldb::WriteOptions(), key, "{\"conf\":5,\"endTime\":\"86400\",\"pushWeek\":\"127\",\"startTime\":\"0\"}");
    }
        usleep(10);
    }

}

void *threadb(void *)
{
    while (1) {
    if(db){
        leveldb::Iterator* it = db->NewIterator(leveldb::ReadOptions());
        for (it->SeekToFirst(); it->Valid(); it->Next()) {
            cout << it->key().ToString() << ": "  << it->value().ToString() << endl;
        }
        delete it;
        usleep(10);
        }
    }
}

int main(int argc, char *argv[])
{
    options.create_if_missing = true;
    status= leveldb::DB::Open(options, "./db", &db);
    assert(status.ok());

    pthread_t ptid = 0;
    pthread_create(&ptid, NULL, threada, NULL);
//  pthread_detach(ptid);
    pthread_create(&ptid, NULL, threadb, NULL);
//  pthread_detach(ptid);
    std::cout<<"Over!!!!!!!!!\n";

    sleep(1000);
    delete db;
    return 0;
}

Original comment by anyanmw on 22 Mar 2012 at 7:55

GoogleCodeExporter commented 9 years ago
对啊 不过你的程序,我运行起来 提示:
总线错误
两个线程同时打开数据库 肯定是不行的!!!而且还是 
while(1)的循环 这 数据库 伤不起 啊。。。

Original comment by anyanmw on 22 Mar 2012 at 8:00

GoogleCodeExporter commented 9 years ago
又对你的程序 分析了下:
在 continue 前面加一个 printf("Cannot Open DB in threada /b \n");;delete 
db ;sleep(1); while(1){结束前 再加一个 sleep(1);

可以运行一段时间,但是运行一段时间后 
数据库就不行了,就两个线程 都无法打开了。所以 
对leveldb的操作还是一个db的好!! 

Original comment by anyanmw on 22 Mar 2012 at 8:24

GoogleCodeExporter commented 9 years ago
Sorry, but I can't read the text of this report.

It is possible that you are running into a problem reported by somebody else 
(there is corruption if the same db is opened multiple times from the same 
process).  That problem is fixed in 1.6.0.

Please reopen this bug and give an English description of the problem if your 
problem is different.

Original comment by san...@google.com on 12 Oct 2012 at 8:12

GoogleCodeExporter commented 9 years ago
楼上说的都很有道理。学习了

Original comment by boyhail...@gmail.com on 28 Dec 2012 at 4:57