db.cpp 5.2 KB
Newer Older
羽飞's avatar
羽飞 已提交
1 2 3 4 5 6 7 8 9 10 11
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
         http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */

//
12
// Created by Meiyi & Longda & Wangyunlai on 2021/5/12.
羽飞's avatar
羽飞 已提交
13 14
//

羽飞's avatar
羽飞 已提交
15
#include "storage/db/db.h"
羽飞's avatar
羽飞 已提交
16 17 18 19 20 21 22 23

#include <sys/stat.h>
#include <fcntl.h>
#include <vector>

#include "common/log/log.h"
#include "common/os/path.h"
#include "common/lang/string.h"
羽飞's avatar
羽飞 已提交
24 25
#include "storage/table/table_meta.h"
#include "storage/table/table.h"
羽飞's avatar
羽飞 已提交
26
#include "storage/common/meta_util.h"
羽飞's avatar
羽飞 已提交
27 28
#include "storage/trx/trx.h"
#include "storage/clog/clog.h"
羽飞's avatar
羽飞 已提交
29

L
Longda 已提交
30 31
Db::~Db()
{
羽飞's avatar
羽飞 已提交
32 33 34 35 36 37
  for (auto &iter : opened_tables_) {
    delete iter.second;
  }
  LOG_INFO("Db has been closed: %s", name_.c_str());
}

L
Longda 已提交
38 39 40 41
RC Db::init(const char *name, const char *dbpath)
{
  if (common::is_blank(name)) {
    LOG_ERROR("Failed to init DB, name cannot be empty");
羽飞's avatar
羽飞 已提交
42 43 44 45
    return RC::INVALID_ARGUMENT;
  }

  if (!common::is_directory(dbpath)) {
L
Longda 已提交
46
    LOG_ERROR("Failed to init DB, path is not a directory: %s", dbpath);
羽飞's avatar
羽飞 已提交
47
    return RC::INTERNAL;
羽飞's avatar
羽飞 已提交
48 49
  }

50
  clog_manager_.reset(new CLogManager());
羽飞's avatar
羽飞 已提交
51 52
  if (clog_manager_ == nullptr) {
    LOG_ERROR("Failed to init CLogManager.");
53 54 55 56 57 58 59
    return RC::NOMEM;
  }

  RC rc = clog_manager_->init(dbpath);
  if (OB_FAIL(rc)) {
    LOG_WARN("failed to init clog manager. dbpath=%s, rc=%s", dbpath, strrc(rc));
    return rc;
羽飞's avatar
羽飞 已提交
60 61
  }

羽飞's avatar
羽飞 已提交
62 63 64
  name_ = name;
  path_ = dbpath;

65 66 67 68 69 70 71 72 73 74 75 76
  rc = open_all_tables();
  if (OB_FAIL(rc)) {
    LOG_WARN("failed to open all tables. dbpath=%s, rc=%s", dbpath, strrc(rc));
    return rc;
  }

  rc = recover();
  if (OB_FAIL(rc)) {
    LOG_WARN("failed to recover db. dbpath=%s, rc=%s", dbpath, strrc(rc));
    return rc;
  }
  return rc;
羽飞's avatar
羽飞 已提交
77 78
}

L
Longda 已提交
79 80
RC Db::create_table(const char *table_name, int attribute_count, const AttrInfo *attributes)
{
羽飞's avatar
羽飞 已提交
81 82 83
  RC rc = RC::SUCCESS;
  // check table_name
  if (opened_tables_.count(table_name) != 0) {
L
Longda 已提交
84
    LOG_WARN("%s has been opened before.", table_name);
羽飞's avatar
羽飞 已提交
85 86 87
    return RC::SCHEMA_TABLE_EXIST;
  }

L
Longda 已提交
88 89
  // 文件路径可以移到Table模块
  std::string table_file_path = table_meta_file(path_.c_str(), table_name);
羽飞's avatar
羽飞 已提交
90
  Table *table = new Table();
91
  rc = table->create(next_table_id_++, table_file_path.c_str(), table_name, path_.c_str(), attribute_count, attributes);
羽飞's avatar
羽飞 已提交
92
  if (rc != RC::SUCCESS) {
L
Longda 已提交
93
    LOG_ERROR("Failed to create table %s.", table_name);
羽飞's avatar
羽飞 已提交
94 95 96 97 98 99 100 101 102
    delete table;
    return rc;
  }

  opened_tables_[table_name] = table;
  LOG_INFO("Create table success. table name=%s", table_name);
  return RC::SUCCESS;
}

L
Longda 已提交
103 104
Table *Db::find_table(const char *table_name) const
{
羽飞's avatar
羽飞 已提交
105 106 107 108 109 110 111
  std::unordered_map<std::string, Table *>::const_iterator iter = opened_tables_.find(table_name);
  if (iter != opened_tables_.end()) {
    return iter->second;
  }
  return nullptr;
}

112 113 114 115 116 117 118 119 120 121
Table *Db::find_table(int32_t table_id) const
{
  for (auto pair : opened_tables_) {
    if (pair.second->table_id() == table_id) {
      return pair.second;
    }
  }
  return nullptr;
}

L
Longda 已提交
122 123
RC Db::open_all_tables()
{
羽飞's avatar
羽飞 已提交
124 125 126 127
  std::vector<std::string> table_meta_files;
  int ret = common::list_file(path_.c_str(), TABLE_META_FILE_PATTERN, table_meta_files);
  if (ret < 0) {
    LOG_ERROR("Failed to list table meta files under %s.", path_.c_str());
羽飞's avatar
羽飞 已提交
128
    return RC::IOERR_READ;
羽飞's avatar
羽飞 已提交
129 130 131 132 133
  }

  RC rc = RC::SUCCESS;
  for (const std::string &filename : table_meta_files) {
    Table *table = new Table();
羽飞's avatar
羽飞 已提交
134
    rc = table->open(filename.c_str(), path_.c_str());
羽飞's avatar
羽飞 已提交
135 136 137 138 139 140 141 142
    if (rc != RC::SUCCESS) {
      delete table;
      LOG_ERROR("Failed to open table. filename=%s", filename.c_str());
      return rc;
    }

    if (opened_tables_.count(table->name()) != 0) {
      delete table;
L
Longda 已提交
143 144 145
      LOG_ERROR("Duplicate table with difference file name. table=%s, the other filename=%s",
          table->name(),
          filename.c_str());
羽飞's avatar
羽飞 已提交
146
      return RC::INTERNAL;
羽飞's avatar
羽飞 已提交
147 148
    }

149 150 151
    if (table->table_id() >= next_table_id_) {
      next_table_id_ = table->table_id();
    }
羽飞's avatar
羽飞 已提交
152 153 154 155 156 157 158 159
    opened_tables_[table->name()] = table;
    LOG_INFO("Open table: %s, file: %s", table->name(), filename.c_str());
  }

  LOG_INFO("All table have been opened. num=%d", opened_tables_.size());
  return rc;
}

L
Longda 已提交
160 161
const char *Db::name() const
{
羽飞's avatar
羽飞 已提交
162 163 164
  return name_.c_str();
}

L
Longda 已提交
165 166 167
void Db::all_tables(std::vector<std::string> &table_names) const
{
  for (const auto &table_item : opened_tables_) {
羽飞's avatar
羽飞 已提交
168 169 170 171
    table_names.emplace_back(table_item.first);
  }
}

L
Longda 已提交
172 173
RC Db::sync()
{
羽飞's avatar
羽飞 已提交
174
  RC rc = RC::SUCCESS;
L
Longda 已提交
175
  for (const auto &table_pair : opened_tables_) {
羽飞's avatar
羽飞 已提交
176 177 178 179 180 181
    Table *table = table_pair.second;
    rc = table->sync();
    if (rc != RC::SUCCESS) {
      LOG_ERROR("Failed to flush table. table=%s.%s, rc=%d:%s", name_.c_str(), table->name(), rc, strrc(rc));
      return rc;
    }
L
Longda 已提交
182
    LOG_INFO("Successfully sync table db:%s, table:%s.", name_.c_str(), table->name());
羽飞's avatar
羽飞 已提交
183
  }
L
Longda 已提交
184
  LOG_INFO("Successfully sync db. db=%s", name_.c_str());
羽飞's avatar
羽飞 已提交
185
  return rc;
羽飞's avatar
羽飞 已提交
186 187 188 189
}

RC Db::recover()
{
190
  return clog_manager_->recover(this);
羽飞's avatar
羽飞 已提交
191 192
}

193
CLogManager *Db::clog_manager()
L
Longda Feng 已提交
194
{
195
  return clog_manager_.get();
羽飞's avatar
羽飞 已提交
196
}