Skip to content

Commit

Permalink
Meta converter (baidu#743)
Browse files Browse the repository at this point in the history
* Small fix on Makefile

* Add meta converter baidu#742

(baidu#742)
  • Loading branch information
lylei authored and Yang Ce committed Jan 3, 2017
1 parent c7391e3 commit 3932abc
Show file tree
Hide file tree
Showing 4 changed files with 188 additions and 4 deletions.
9 changes: 5 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -144,15 +144,16 @@ location_provider_test: src/nameserver/test/location_provider_test.o src/nameser

chunkserver_impl_test: src/chunkserver/test/chunkserver_impl_test.o \
src/chunkserver/chunkserver_impl.o src/chunkserver/data_block.o src/chunkserver/block_manager.o \
src/chunkserver/counter_manager.o src/chunkserver/file_cache.o src/chunkserver/disk.o
src/chunkserver/counter_manager.o src/chunkserver/file_cache.o src/chunkserver/disk.o \
src/utils/meta_converter.o
$(CXX) $^ $(OBJS) -o $@ $(LDFLAGS)

file_cache_test: src/chunkserver/test/file_cache_test.o
$(CXX) src/chunkserver/file_cache.o src/chunkserver/test/file_cache_test.o $(OBJS) -o $@ $(LDFLAGS)

block_manager_test: src/chunkserver/test/block_manager_test.o src/chunkserver/block_manager.o \
src/chunkserver/disk.o src/chunkserver/data_block.o src/chunkserver/counter_manager.o \
src/chunkserver/file_cache.o
src/chunkserver/file_cache.o src/utils/meta_converter.o
$(CXX) $^ $(OBJS) -o $@ $(LDFLAGS)

data_block_test: src/chunkserver/test/data_block_test.o \
Expand All @@ -170,8 +171,8 @@ metaserver: $(METASERVER_OBJ) $(OBJS) src/nameserver/block_mapping_manager.o \
src/nameserver/chunkserver_manager.o src/nameserver/block_mapping.o \
src/nameserver/namespace.o src/nameserver/location_provider.o -o $@ $(LDFLAGS)

chunkserver: $(CHUNKSERVER_OBJ) $(OBJS)
$(CXX) $(CHUNKSERVER_OBJ) $(OBJS) -o $@ $(LDFLAGS)
chunkserver: $(CHUNKSERVER_OBJ) $(OBJS) src/utils/meta_converter.o
$(CXX) $(CHUNKSERVER_OBJ) $(OBJS) src/utils/meta_converter.o -o $@ $(LDFLAGS)

libbfs.a: $(SDK_OBJ) $(OBJS) $(PROTO_HEADER)
$(AR) -rs $@ $(SDK_OBJ) $(OBJS)
Expand Down
2 changes: 2 additions & 0 deletions src/chunkserver/block_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "chunkserver/disk.h"
#include "chunkserver/data_block.h"
#include "chunkserver/file_cache.h"
#include "utils/meta_converter.h"

DECLARE_int32(chunkserver_file_cache_size);
DECLARE_int32(chunkserver_use_root_partition);
Expand Down Expand Up @@ -153,6 +154,7 @@ void BlockManager::CheckStorePath(const std::string& store_path) {
}
LOG(INFO, "%lu store path used.", store_path_list.size());
assert(store_path_list.size() > 0);
CheckChunkserverMeta(store_path_list);
}

int64_t BlockManager::DiskQuota() const {
Expand Down
155 changes: 155 additions & 0 deletions src/utils/meta_converter.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
// Copyright (c) 2016, Baidu.com, Inc. All Rights Reserved
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

#include <string>
#include <map>

#include <gflags/gflags.h>
#include <leveldb/db.h>

#include <common/string_util.h>
#include <common/logging.h>

#include "proto/block.pb.h"

#include "utils/meta_converter.h"

namespace baidu {
namespace bfs {

const int CHUNKSERVER_META_VERSION = 1;

const int EMPTY_META = -1;

void CheckChunkserverMeta(const std::vector<std::string>& store_path_list) {
std::map<std::string, leveldb::DB*> meta_dbs;
int meta_version = EMPTY_META;
for (size_t i = 0; i < store_path_list.size(); ++i) {
const std::string& path = store_path_list[i];
leveldb::Options options;
options.create_if_missing = true;
leveldb::DB* metadb;
leveldb::Status s = leveldb::DB::Open(options, path + "/meta/", &metadb);
if (!s.ok()) {
LOG(ERROR, "[MetaCheck] Open meta on %s failed: %s", path.c_str(), s.ToString().c_str());
exit(EXIT_FAILURE);
return;
}

std::string version_key(8, '\0');
version_key.append("version");
std::string version_str;
s = metadb->Get(leveldb::ReadOptions(), version_key, &version_str);
if (s.IsNotFound()) {
LOG(INFO, "[MetaCheck] Load empty meta %s", path.c_str());
} else {
std::string meta_key(8, '\0');
meta_key.append("meta");
std::string meta_str;
s = metadb->Get(leveldb::ReadOptions(), meta_key, &meta_str);
if (s.ok()) {
int cur_version = *(reinterpret_cast<int*>(&meta_str[0]));
LOG(INFO, "[MetaCheck] %s Load meta version %d", path.c_str(), cur_version);
if (meta_version != EMPTY_META && cur_version != meta_version) {
LOG(ERROR, "Cannot handle this situation!!!");
exit(EXIT_FAILURE);
}
meta_version = cur_version;
} else if (s.IsNotFound()) {
if (meta_version != EMPTY_META && meta_version != 0) {
LOG(ERROR, "Cannot handle this situation!!!");
exit(EXIT_FAILURE);
}
meta_version = 0;
LOG(INFO, "No meta version %s", path.c_str());
}
}
meta_dbs[path] = metadb;
}
if (meta_version == CHUNKSERVER_META_VERSION) {
LOG(INFO, "[MetaCheck] Chunkserver meta check pass");
} else if (meta_version == EMPTY_META) {
LOG(INFO, "[MetaCheck] Chunkserver empty");
SetChunkserverMetaVersion(meta_dbs);
} else if (meta_version == 0) {
ChunkserverMetaV02V1(meta_dbs);
SetChunkserverMetaVersion(meta_dbs);
} else {
LOG(ERROR, "[MetaCheck] Cannot handle this situation!!!");
exit(EXIT_FAILURE);
}
CloseMetaStore(meta_dbs);
}

void ChunkserverMetaV02V1(const std::map<std::string, leveldb::DB*>& meta_dbs) {
LOG(INFO, "[MetaCheck] Start converting chunkserver meta from verion 0");
leveldb::DB* src_meta = NULL;
std::string src_meta_path;
std::string version_key(8, '\0');
std::string version_str;
for (auto it = meta_dbs.begin(); it != meta_dbs.end(); ++it) {
version_key.append("version");
leveldb::Status s = it->second->Get(leveldb::ReadOptions(), version_key, &version_str);
if (s.ok()) {
src_meta = it->second;
src_meta_path = it->first;
break;
}
}
if (!src_meta) {
LOG(ERROR, "[MetaCheck] Cannot find a valid meta store");
exit(EXIT_FAILURE);
}

leveldb::Iterator* it = src_meta->NewIterator(leveldb::ReadOptions());
for (it->Seek(std::string(8, '\0') + "version" + '\0'); it->Valid(); it->Next()) {
BlockMeta meta;
if (!meta.ParseFromArray(it->value().data(), it->value().size())) {
LOG(ERROR, "[MetaCheck] Parse BlockMeta failed: key = %s", it->key().ToString().c_str());
exit(EXIT_FAILURE);
}
const std::string& path = meta.store_path();
auto db_it = meta_dbs.find(path);
if (db_it == meta_dbs.end()) {
LOG(WARNING, "[MetaCheck] Cannot find store_path %s", path.c_str());
continue;
}
leveldb::DB* disk_db = db_it->second;
disk_db->Put(leveldb::WriteOptions(), it->key(), it->value());
if (path != src_meta_path) {
src_meta->Delete(leveldb::WriteOptions(), it->key());
}
}
for (auto it = meta_dbs.begin(); it != meta_dbs.end(); ++it) {
leveldb::DB* ldb = it->second;
ldb->Put(leveldb::WriteOptions(), version_key, version_str);
}
delete it;
}

void SetChunkserverMetaVersion(const std::map<std::string, leveldb::DB*>& meta_dbs) {
for (auto it = meta_dbs.begin(); it != meta_dbs.end(); ++it) {
leveldb::DB* ldb = it->second;
std::string meta_key(8, '\0');
meta_key.append("meta");
std::string meta_str(4, '\0');
*(reinterpret_cast<int*>(&meta_str[0])) = CHUNKSERVER_META_VERSION;
leveldb::Status s = ldb->Put(leveldb::WriteOptions(), meta_key, meta_str);
if (!s.ok()) {
LOG(ERROR, "[MetaCheck] Put meta failed %s", it->first.c_str());
exit(EXIT_FAILURE);
}
LOG(INFO, "[MetaCheck] Set meta version %s = %d", it->first.c_str(), CHUNKSERVER_META_VERSION);
}
}

void CloseMetaStore(const std::map<std::string, leveldb::DB*>& meta_dbs) {
for (auto it = meta_dbs.begin(); it != meta_dbs.end(); ++it) {
delete it->second;
}
}

} // namespace bfs
} // namespace baidu
26 changes: 26 additions & 0 deletions src/utils/meta_converter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (c) 2016, Baidu.com, Inc. All Rights Reserved
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

#ifndef BFS_UTILS_META_CONVERTER_H_
#define BFS_UTILS_META_CONVERTER_H_

namespace baidu {
namespace bfs {

// Check wether the chunkserver meta is in valid format.
// A meta store with an oloder version will be convert into current
// meta version automatically.
void CheckChunkserverMeta(const std::vector<std::string>& store_path_list);
// Convert meta from version 0 to version 1.
void ChunkserverMetaV02V1(const std::map<std::string, leveldb::DB*>& meta_dbs);
// Set current version for all meta store.
void SetChunkserverMetaVersion(const std::map<std::string, leveldb::DB*>& meta_dbs);
// Close all meta store.
void CloseMetaStore(const std::map<std::string, leveldb::DB*>& meta_dbs);

} // namespace bfs
} // namespace baidu

#endif //BFS_UTILS_META_CONVERTER_H_

0 comments on commit 3932abc

Please sign in to comment.