MySQLMetaImpl.cpp 76.7 KB
Newer Older
J
jinhai 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

S
starlord 已提交
18
#include "db/meta/MySQLMetaImpl.h"
S
starlord 已提交
19
#include "MetaConsts.h"
S
starlord 已提交
20 21
#include "db/IDGenerator.h"
#include "db/Utils.h"
Z
update  
zhiru 已提交
22
#include "metrics/Metrics.h"
S
starlord 已提交
23 24
#include "utils/Exception.h"
#include "utils/Log.h"
Z
update  
zhiru 已提交
25

S
starlord 已提交
26 27
#include <mysql++/mysql++.h>
#include <string.h>
Z
update  
zhiru 已提交
28
#include <unistd.h>
S
starlord 已提交
29
#include <boost/filesystem.hpp>
Z
update  
zhiru 已提交
30 31
#include <chrono>
#include <fstream>
S
starlord 已提交
32 33 34
#include <iostream>
#include <map>
#include <mutex>
Z
update  
zhiru 已提交
35
#include <regex>
S
starlord 已提交
36 37
#include <set>
#include <sstream>
Z
update  
zhiru 已提交
38
#include <string>
Z
zhiru 已提交
39
#include <thread>
Z
update  
zhiru 已提交
40 41 42 43 44 45

namespace zilliz {
namespace milvus {
namespace engine {
namespace meta {

46
namespace {
Z
update  
zhiru 已提交
47

S
starlord 已提交
48
Status
S
starlord 已提交
49
HandleException(const std::string& desc, const char* what = nullptr) {
S
starlord 已提交
50
    if (what == nullptr) {
S
starlord 已提交
51 52 53 54 55 56 57
        ENGINE_LOG_ERROR << desc;
        return Status(DB_META_TRANSACTION_FAILED, desc);
    } else {
        std::string msg = desc + ":" + what;
        ENGINE_LOG_ERROR << msg;
        return Status(DB_META_TRANSACTION_FAILED, msg);
    }
58
}
Z
update  
zhiru 已提交
59

60
class MetaField {
S
starlord 已提交
61
 public:
S
starlord 已提交
62 63
    MetaField(const std::string& name, const std::string& type, const std::string& setting)
        : name_(name), type_(type), setting_(setting) {
64 65
    }

S
starlord 已提交
66 67
    std::string
    name() const {
68 69 70
        return name_;
    }

S
starlord 已提交
71 72
    std::string
    ToString() const {
73 74 75 76 77
        return name_ + " " + type_ + " " + setting_;
    }

    // mysql field type has additional information. for instance, a filed type is defined as 'BIGINT'
    // we get the type from sql is 'bigint(20)', so we need to ignore the '(20)'
S
starlord 已提交
78 79
    bool
    IsEqual(const MetaField& field) const {
80 81 82
        size_t name_len_min = field.name_.length() > name_.length() ? name_.length() : field.name_.length();
        size_t type_len_min = field.type_.length() > type_.length() ? type_.length() : field.type_.length();
        return strncasecmp(field.name_.c_str(), name_.c_str(), name_len_min) == 0 &&
S
starlord 已提交
83
               strncasecmp(field.type_.c_str(), type_.c_str(), type_len_min) == 0;
84 85
    }

S
starlord 已提交
86
 private:
87 88 89 90 91 92 93
    std::string name_;
    std::string type_;
    std::string setting_;
};

using MetaFields = std::vector<MetaField>;
class MetaSchema {
S
starlord 已提交
94
 public:
S
starlord 已提交
95
    MetaSchema(const std::string& name, const MetaFields& fields) : name_(name), fields_(fields) {
96 97
    }

S
starlord 已提交
98 99
    std::string
    name() const {
100 101 102
        return name_;
    }

S
starlord 已提交
103 104
    std::string
    ToString() const {
105
        std::string result;
S
starlord 已提交
106
        for (auto& field : fields_) {
S
starlord 已提交
107
            if (!result.empty()) {
108 109 110 111 112 113 114
                result += ",";
            }
            result += field.ToString();
        }
        return result;
    }

S
starlord 已提交
115 116 117 118
    // if the outer fields contains all this MetaSchema fields, return true
    // otherwise return false
    bool
    IsEqual(const MetaFields& fields) const {
119
        std::vector<std::string> found_field;
S
starlord 已提交
120 121
        for (const auto& this_field : fields_) {
            for (const auto& outer_field : fields) {
S
starlord 已提交
122
                if (this_field.IsEqual(outer_field)) {
123 124 125 126 127 128 129 130 131
                    found_field.push_back(this_field.name());
                    break;
                }
            }
        }

        return found_field.size() == fields_.size();
    }

S
starlord 已提交
132
 private:
133 134 135 136
    std::string name_;
    MetaFields fields_;
};

S
starlord 已提交
137
// Tables schema
138
static const MetaSchema TABLES_SCHEMA(META_TABLES, {
S
starlord 已提交
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
                                                       MetaField("id", "BIGINT", "PRIMARY KEY AUTO_INCREMENT"),
                                                       MetaField("table_id", "VARCHAR(255)", "UNIQUE NOT NULL"),
                                                       MetaField("state", "INT", "NOT NULL"),
                                                       MetaField("dimension", "SMALLINT", "NOT NULL"),
                                                       MetaField("created_on", "BIGINT", "NOT NULL"),
                                                       MetaField("flag", "BIGINT", "DEFAULT 0 NOT NULL"),
                                                       MetaField("index_file_size", "BIGINT", "DEFAULT 1024 NOT NULL"),
                                                       MetaField("engine_type", "INT", "DEFAULT 1 NOT NULL"),
                                                       MetaField("nlist", "INT", "DEFAULT 16384 NOT NULL"),
                                                       MetaField("metric_type", "INT", "DEFAULT 1 NOT NULL"),
                                                   });

// TableFiles schema
static const MetaSchema TABLEFILES_SCHEMA(
    META_TABLEFILES,
    {
        MetaField("id", "BIGINT", "PRIMARY KEY AUTO_INCREMENT"), MetaField("table_id", "VARCHAR(255)", "NOT NULL"),
        MetaField("engine_type", "INT", "DEFAULT 1 NOT NULL"), MetaField("file_id", "VARCHAR(255)", "NOT NULL"),
        MetaField("file_type", "INT", "DEFAULT 0 NOT NULL"), MetaField("file_size", "BIGINT", "DEFAULT 0 NOT NULL"),
        MetaField("row_count", "BIGINT", "DEFAULT 0 NOT NULL"), MetaField("updated_time", "BIGINT", "NOT NULL"),
        MetaField("created_on", "BIGINT", "NOT NULL"), MetaField("date", "INT", "DEFAULT -1 NOT NULL"),
    });

}  // namespace
163

164
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
S
starlord 已提交
165
MySQLMetaImpl::MySQLMetaImpl(const DBMetaOptions& options, const int& mode) : options_(options), mode_(mode) {
166 167 168 169 170 171
    Initialize();
}

MySQLMetaImpl::~MySQLMetaImpl() {
}

S
starlord 已提交
172
Status
S
starlord 已提交
173
MySQLMetaImpl::NextTableId(std::string& table_id) {
174 175 176 177 178 179 180
    std::stringstream ss;
    SimpleIDGenerator g;
    ss << g.GetNextIDNumber();
    table_id = ss.str();
    return Status::OK();
}

S
starlord 已提交
181
Status
S
starlord 已提交
182
MySQLMetaImpl::NextFileId(std::string& file_id) {
183 184 185 186 187 188 189
    std::stringstream ss;
    SimpleIDGenerator g;
    ss << g.GetNextIDNumber();
    file_id = ss.str();
    return Status::OK();
}

S
starlord 已提交
190 191 192
void
MySQLMetaImpl::ValidateMetaSchema() {
    if (nullptr == mysql_connection_pool_) {
193 194 195
        return;
    }

S
starlord 已提交
196
    mysqlpp::ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab_);
197 198 199 200
    if (connectionPtr == nullptr) {
        return;
    }

S
starlord 已提交
201
    auto validate_func = [&](const MetaSchema& schema) {
S
starlord 已提交
202
        mysqlpp::Query query_statement = connectionPtr->query();
203 204 205 206 207
        query_statement << "DESC " << schema.name() << ";";

        MetaFields exist_fields;

        try {
S
starlord 已提交
208
            mysqlpp::StoreQueryResult res = query_statement.store();
209
            for (size_t i = 0; i < res.num_rows(); i++) {
S
starlord 已提交
210
                const mysqlpp::Row& row = res[i];
211 212 213 214 215 216
                std::string name, type;
                row["Field"].to_string(name);
                row["Type"].to_string(type);

                exist_fields.push_back(MetaField(name, type, ""));
            }
S
starlord 已提交
217
        } catch (std::exception& e) {
218 219 220
            ENGINE_LOG_DEBUG << "Meta table '" << schema.name() << "' not exist and will be created";
        }

S
starlord 已提交
221
        if (exist_fields.empty()) {
222 223 224 225 226 227
            return true;
        }

        return schema.IsEqual(exist_fields);
    };

S
starlord 已提交
228
    // verify Tables
229 230 231 232
    if (!validate_func(TABLES_SCHEMA)) {
        throw Exception(DB_INCOMPATIB_META, "Meta Tables schema is created by Milvus old version");
    }

S
starlord 已提交
233
    // verufy TableFiles
234 235 236 237 238
    if (!validate_func(TABLEFILES_SCHEMA)) {
        throw Exception(DB_INCOMPATIB_META, "Meta TableFiles schema is created by Milvus old version");
    }
}

S
starlord 已提交
239 240
Status
MySQLMetaImpl::Initialize() {
S
starlord 已提交
241
    // step 1: create db root path
S
starlord 已提交
242 243
    if (!boost::filesystem::is_directory(options_.path_)) {
        auto ret = boost::filesystem::create_directory(options_.path_);
244
        if (!ret) {
S
starlord 已提交
245
            std::string msg = "Failed to create db directory " + options_.path_;
S
starlord 已提交
246 247
            ENGINE_LOG_ERROR << msg;
            return Status(DB_META_TRANSACTION_FAILED, msg);
Z
update  
zhiru 已提交
248 249 250
        }
    }

S
starlord 已提交
251
    std::string uri = options_.backend_uri_;
252

S
starlord 已提交
253
    // step 2: parse and check meta uri
254 255
    utils::MetaUriInfo uri_info;
    auto status = utils::ParseMetaUri(uri, uri_info);
S
starlord 已提交
256
    if (!status.ok()) {
257 258 259 260 261 262 263 264 265 266 267
        std::string msg = "Wrong URI format: " + uri;
        ENGINE_LOG_ERROR << msg;
        throw Exception(DB_INVALID_META_URI, msg);
    }

    if (strcasecmp(uri_info.dialect_.c_str(), "mysql") != 0) {
        std::string msg = "URI's dialect is not MySQL";
        ENGINE_LOG_ERROR << msg;
        throw Exception(DB_INVALID_META_URI, msg);
    }

S
starlord 已提交
268
    // step 3: connect mysql
269 270 271 272 273 274 275
    int thread_hint = std::thread::hardware_concurrency();
    int max_pool_size = (thread_hint == 0) ? 8 : thread_hint;
    unsigned int port = 0;
    if (!uri_info.port_.empty()) {
        port = std::stoi(uri_info.port_);
    }

S
starlord 已提交
276 277
    mysql_connection_pool_ = std::make_shared<MySQLConnectionPool>(
        uri_info.db_name_, uri_info.username_, uri_info.password_, uri_info.host_, port, max_pool_size);
278 279
    ENGINE_LOG_DEBUG << "MySQL connection pool: maximum pool size = " << std::to_string(max_pool_size);

S
starlord 已提交
280
    // step 4: validate to avoid open old version schema
281 282
    ValidateMetaSchema();

S
starlord 已提交
283
    // step 5: create meta tables
284
    try {
Y
yudong.cai 已提交
285
        if (mode_ != DBOptions::MODE::CLUSTER_READONLY) {
286
            CleanUp();
287 288
        }

289
        {
S
starlord 已提交
290
            mysqlpp::ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab_);
291

292 293 294
            if (connectionPtr == nullptr) {
                return Status(DB_ERROR, "Failed to connect to database server");
            }
295

296 297 298
            if (!connectionPtr->thread_aware()) {
                ENGINE_LOG_ERROR << "MySQL++ wasn't built with thread awareness! Can't run without it.";
                return Status(DB_ERROR, "MySQL++ wasn't built with thread awareness! Can't run without it.");
299
            }
S
starlord 已提交
300
            mysqlpp::Query InitializeQuery = connectionPtr->query();
301

S
starlord 已提交
302 303
            InitializeQuery << "CREATE TABLE IF NOT EXISTS " << TABLES_SCHEMA.name() << " ("
                            << TABLES_SCHEMA.ToString() + ");";
304

305
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::Initialize: " << InitializeQuery.str();
Z
update  
zhiru 已提交
306

307 308 309
            if (!InitializeQuery.exec()) {
                return HandleException("Initialization Error", InitializeQuery.error());
            }
310

S
starlord 已提交
311 312
            InitializeQuery << "CREATE TABLE IF NOT EXISTS " << TABLEFILES_SCHEMA.name() << " ("
                            << TABLEFILES_SCHEMA.ToString() + ");";
Z
update  
zhiru 已提交
313

314
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::Initialize: " << InitializeQuery.str();
Z
update  
zhiru 已提交
315

316 317 318
            if (!InitializeQuery.exec()) {
                return HandleException("Initialization Error", InitializeQuery.error());
            }
S
starlord 已提交
319 320
        }  // Scoped Connection
    } catch (std::exception& e) {
321
        return HandleException("GENERAL ERROR DURING INITIALIZATION", e.what());
Z
update  
zhiru 已提交
322
    }
S
starlord 已提交
323 324

    return Status::OK();
325 326 327
}

// PXU TODO: Temp solution. Will fix later
S
starlord 已提交
328
Status
S
starlord 已提交
329
MySQLMetaImpl::DropPartitionsByDates(const std::string& table_id, const DatesT& dates) {
330
    if (dates.empty()) {
P
peng.xu 已提交
331 332 333
        return Status::OK();
    }

334 335 336 337 338 339
    TableSchema table_schema;
    table_schema.table_id_ = table_id;
    auto status = DescribeTable(table_schema);
    if (!status.ok()) {
        return status;
    }
Z
zhiru 已提交
340

341 342
    try {
        std::stringstream dateListSS;
S
starlord 已提交
343
        for (auto& date : dates) {
344 345 346
            dateListSS << std::to_string(date) << ", ";
        }
        std::string dateListStr = dateListSS.str();
S
starlord 已提交
347
        dateListStr = dateListStr.substr(0, dateListStr.size() - 2);  // remove the last ", "
Z
update  
zhiru 已提交
348

349
        {
S
starlord 已提交
350
            mysqlpp::ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab_);
Z
update  
zhiru 已提交
351

352
            if (connectionPtr == nullptr) {
S
starlord 已提交
353
                return Status(DB_ERROR, "Failed to connect to database server");
354
            }
Z
update  
zhiru 已提交
355

S
starlord 已提交
356
            mysqlpp::Query dropPartitionsByDatesQuery = connectionPtr->query();
357

S
starlord 已提交
358 359 360 361 362
            dropPartitionsByDatesQuery << "UPDATE " << META_TABLEFILES << " "
                                       << "SET file_type = " << std::to_string(TableFileSchema::TO_DELETE) << ","
                                       << "updated_time = " << utils::GetMicroSecTimeStamp() << " "
                                       << "WHERE table_id = " << mysqlpp::quote << table_id << " AND "
                                       << "date in (" << dateListStr << ");";
Z
update  
zhiru 已提交
363

364
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::DropPartitionsByDates: " << dropPartitionsByDatesQuery.str();
Z
update  
zhiru 已提交
365

366
            if (!dropPartitionsByDatesQuery.exec()) {
S
starlord 已提交
367 368
                return HandleException("QUERY ERROR WHEN DROPPING PARTITIONS BY DATES",
                                       dropPartitionsByDatesQuery.error());
Z
update  
zhiru 已提交
369
            }
S
starlord 已提交
370
        }  // Scoped Connection
371 372

        ENGINE_LOG_DEBUG << "Successfully drop partitions, table id = " << table_schema.table_id_;
S
starlord 已提交
373
    } catch (std::exception& e) {
S
starlord 已提交
374
        return HandleException("GENERAL ERROR WHEN DROPPING PARTITIONS BY DATES", e.what());
Z
update  
zhiru 已提交
375
    }
376 377
    return Status::OK();
}
Z
update  
zhiru 已提交
378

S
starlord 已提交
379
Status
S
starlord 已提交
380
MySQLMetaImpl::CreateTable(TableSchema& table_schema) {
381
    try {
Y
Yu Kun 已提交
382
        server::MetricCollector metric;
383
        {
S
starlord 已提交
384
            mysqlpp::ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab_);
385

386
            if (connectionPtr == nullptr) {
S
starlord 已提交
387
                return Status(DB_ERROR, "Failed to connect to database server");
388
            }
Z
update  
zhiru 已提交
389

S
starlord 已提交
390
            mysqlpp::Query createTableQuery = connectionPtr->query();
Z
update  
zhiru 已提交
391

392 393 394
            if (table_schema.table_id_.empty()) {
                NextTableId(table_schema.table_id_);
            } else {
S
starlord 已提交
395 396
                createTableQuery << "SELECT state FROM " << META_TABLES << " "
                                 << "WHERE table_id = " << mysqlpp::quote << table_schema.table_id_ << ";";
Z
zhiru 已提交
397

398
                ENGINE_LOG_DEBUG << "MySQLMetaImpl::CreateTable: " << createTableQuery.str();
Z
update  
zhiru 已提交
399

S
starlord 已提交
400
                mysqlpp::StoreQueryResult res = createTableQuery.store();
401

402 403 404
                if (res.num_rows() == 1) {
                    int state = res[0]["state"];
                    if (TableSchema::TO_DELETE == state) {
S
starlord 已提交
405
                        return Status(DB_ERROR, "Table already exists and it is in delete state, please wait a second");
406
                    } else {
S
starlord 已提交
407
                        return Status(DB_ALREADY_EXIST, "Table already exists");
408 409 410
                    }
                }
            }
411

412 413
            table_schema.id_ = -1;
            table_schema.created_on_ = utils::GetMicroSecTimeStamp();
Z
update  
zhiru 已提交
414

S
starlord 已提交
415
            std::string id = "NULL";  // auto-increment
416 417 418 419
            std::string table_id = table_schema.table_id_;
            std::string state = std::to_string(table_schema.state_);
            std::string dimension = std::to_string(table_schema.dimension_);
            std::string created_on = std::to_string(table_schema.created_on_);
S
starlord 已提交
420 421
            std::string flag = std::to_string(table_schema.flag_);
            std::string index_file_size = std::to_string(table_schema.index_file_size_);
422
            std::string engine_type = std::to_string(table_schema.engine_type_);
S
starlord 已提交
423 424
            std::string nlist = std::to_string(table_schema.nlist_);
            std::string metric_type = std::to_string(table_schema.metric_type_);
Z
update  
zhiru 已提交
425

S
starlord 已提交
426 427 428 429
            createTableQuery << "INSERT INTO " << META_TABLES << " "
                             << "VALUES(" << id << ", " << mysqlpp::quote << table_id << ", " << state << ", "
                             << dimension << ", " << created_on << ", " << flag << ", " << index_file_size << ", "
                             << engine_type << ", " << nlist << ", " << metric_type << ");";
Z
update  
zhiru 已提交
430

431
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::CreateTable: " << createTableQuery.str();
432

S
starlord 已提交
433
            if (mysqlpp::SimpleResult res = createTableQuery.execute()) {
S
starlord 已提交
434
                table_schema.id_ = res.insert_id();  // Might need to use SELECT LAST_INSERT_ID()?
435

S
starlord 已提交
436
                // Consume all results to avoid "Commands out of sync" error
437
            } else {
S
starlord 已提交
438
                return HandleException("Add Table Error", createTableQuery.error());
439
            }
S
starlord 已提交
440
        }  // Scoped Connection
441

442
        ENGINE_LOG_DEBUG << "Successfully create table: " << table_schema.table_id_;
443
        return utils::CreateTablePath(options_, table_schema.table_id_);
S
starlord 已提交
444
    } catch (std::exception& e) {
S
starlord 已提交
445
        return HandleException("GENERAL ERROR WHEN CREATING TABLE", e.what());
446 447
    }
}
448

S
starlord 已提交
449
Status
S
starlord 已提交
450 451
MySQLMetaImpl::FilesByType(const std::string& table_id, const std::vector<int>& file_types,
                           std::vector<std::string>& file_ids) {
S
starlord 已提交
452
    if (file_types.empty()) {
S
starlord 已提交
453
        return Status(DB_ERROR, "file types array is empty");
454
    }
Z
zhiru 已提交
455 456

    try {
457 458
        file_ids.clear();

S
starlord 已提交
459
        mysqlpp::StoreQueryResult res;
Z
zhiru 已提交
460
        {
S
starlord 已提交
461
            mysqlpp::ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab_);
Z
zhiru 已提交
462 463

            if (connectionPtr == nullptr) {
S
starlord 已提交
464
                return Status(DB_ERROR, "Failed to connect to database server");
Z
zhiru 已提交
465 466
            }

467
            std::string types;
S
starlord 已提交
468 469
            for (auto type : file_types) {
                if (!types.empty()) {
470 471 472 473 474
                    types += ",";
                }
                types += std::to_string(type);
            }

S
starlord 已提交
475
            mysqlpp::Query hasNonIndexFilesQuery = connectionPtr->query();
S
starlord 已提交
476 477 478 479
            // since table_id is a unique column we just need to check whether it exists or not
            hasNonIndexFilesQuery << "SELECT file_id, file_type FROM " << META_TABLEFILES << " "
                                  << "WHERE table_id = " << mysqlpp::quote << table_id << " AND "
                                  << "file_type in (" << types << ");";
Z
zhiru 已提交
480

481
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::FilesByType: " << hasNonIndexFilesQuery.str();
Z
zhiru 已提交
482 483

            res = hasNonIndexFilesQuery.store();
S
starlord 已提交
484
        }  // Scoped Connection
Z
zhiru 已提交
485

486 487 488
        if (res.num_rows() > 0) {
            int raw_count = 0, new_count = 0, new_merge_count = 0, new_index_count = 0;
            int to_index_count = 0, index_count = 0, backup_count = 0;
S
starlord 已提交
489
            for (auto& resRow : res) {
490 491 492 493 494 495
                std::string file_id;
                resRow["file_id"].to_string(file_id);
                file_ids.push_back(file_id);

                int32_t file_type = resRow["file_type"];
                switch (file_type) {
S
starlord 已提交
496 497
                    case (int)TableFileSchema::RAW:
                        raw_count++;
498
                        break;
S
starlord 已提交
499 500
                    case (int)TableFileSchema::NEW:
                        new_count++;
501
                        break;
S
starlord 已提交
502 503
                    case (int)TableFileSchema::NEW_MERGE:
                        new_merge_count++;
504
                        break;
S
starlord 已提交
505 506
                    case (int)TableFileSchema::NEW_INDEX:
                        new_index_count++;
507
                        break;
S
starlord 已提交
508 509
                    case (int)TableFileSchema::TO_INDEX:
                        to_index_count++;
510
                        break;
S
starlord 已提交
511 512
                    case (int)TableFileSchema::INDEX:
                        index_count++;
513
                        break;
S
starlord 已提交
514 515 516 517
                    case (int)TableFileSchema::BACKUP:
                        backup_count++;
                        break;
                    default:
518 519 520 521 522 523 524 525 526
                        break;
                }
            }

            ENGINE_LOG_DEBUG << "Table " << table_id << " currently has raw files:" << raw_count
                             << " new files:" << new_count << " new_merge files:" << new_merge_count
                             << " new_index files:" << new_index_count << " to_index files:" << to_index_count
                             << " index files:" << index_count << " backup files:" << backup_count;
        }
S
starlord 已提交
527
    } catch (std::exception& e) {
S
starlord 已提交
528
        return HandleException("GENERAL ERROR WHEN GET FILE BY TYPE", e.what());
Z
zhiru 已提交
529 530
    }

531 532
    return Status::OK();
}
533

S
starlord 已提交
534
Status
S
starlord 已提交
535
MySQLMetaImpl::UpdateTableIndex(const std::string& table_id, const TableIndex& index) {
S
starlord 已提交
536
    try {
Y
Yu Kun 已提交
537
        server::MetricCollector metric;
S
starlord 已提交
538 539

        {
S
starlord 已提交
540
            mysqlpp::ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab_);
S
starlord 已提交
541 542

            if (connectionPtr == nullptr) {
S
starlord 已提交
543
                return Status(DB_ERROR, "Failed to connect to database server");
S
starlord 已提交
544 545
            }

S
starlord 已提交
546
            mysqlpp::Query updateTableIndexParamQuery = connectionPtr->query();
S
starlord 已提交
547 548 549
            updateTableIndexParamQuery << "SELECT id, state, dimension, created_on FROM " << META_TABLES << " "
                                       << "WHERE table_id = " << mysqlpp::quote << table_id << " AND "
                                       << "state <> " << std::to_string(TableSchema::TO_DELETE) << ";";
S
starlord 已提交
550

S
starlord 已提交
551
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::UpdateTableIndex: " << updateTableIndexParamQuery.str();
S
starlord 已提交
552

S
starlord 已提交
553
            mysqlpp::StoreQueryResult res = updateTableIndexParamQuery.store();
S
starlord 已提交
554 555

            if (res.num_rows() == 1) {
S
starlord 已提交
556
                const mysqlpp::Row& resRow = res[0];
S
starlord 已提交
557 558 559 560 561 562

                size_t id = resRow["id"];
                int32_t state = resRow["state"];
                uint16_t dimension = resRow["dimension"];
                int64_t created_on = resRow["created_on"];

S
starlord 已提交
563 564 565 566 567 568 569 570 571
                updateTableIndexParamQuery << "UPDATE " << META_TABLES << " "
                                           << "SET id = " << id << ", "
                                           << "state = " << state << ", "
                                           << "dimension = " << dimension << ", "
                                           << "created_on = " << created_on << ", "
                                           << "engine_type = " << index.engine_type_ << ", "
                                           << "nlist = " << index.nlist_ << ", "
                                           << "metric_type = " << index.metric_type_ << " "
                                           << "WHERE table_id = " << mysqlpp::quote << table_id << ";";
S
starlord 已提交
572

S
starlord 已提交
573
                ENGINE_LOG_DEBUG << "MySQLMetaImpl::UpdateTableIndex: " << updateTableIndexParamQuery.str();
S
starlord 已提交
574 575

                if (!updateTableIndexParamQuery.exec()) {
S
starlord 已提交
576 577
                    return HandleException("QUERY ERROR WHEN UPDATING TABLE INDEX PARAM",
                                           updateTableIndexParamQuery.error());
S
starlord 已提交
578 579
                }
            } else {
S
starlord 已提交
580
                return Status(DB_NOT_FOUND, "Table " + table_id + " not found");
S
starlord 已提交
581
            }
S
starlord 已提交
582
        }  // Scoped Connection
S
starlord 已提交
583

584
        ENGINE_LOG_DEBUG << "Successfully update table index, table id = " << table_id;
S
starlord 已提交
585
    } catch (std::exception& e) {
S
starlord 已提交
586
        return HandleException("GENERAL ERROR WHEN UPDATING TABLE INDEX PARAM", e.what());
S
starlord 已提交
587 588
    }

589 590 591
    return Status::OK();
}

S
starlord 已提交
592
Status
S
starlord 已提交
593
MySQLMetaImpl::UpdateTableFlag(const std::string& table_id, int64_t flag) {
S
starlord 已提交
594
    try {
Y
Yu Kun 已提交
595
        server::MetricCollector metric;
S
starlord 已提交
596 597

        {
S
starlord 已提交
598
            mysqlpp::ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab_);
S
starlord 已提交
599 600

            if (connectionPtr == nullptr) {
S
starlord 已提交
601
                return Status(DB_ERROR, "Failed to connect to database server");
S
starlord 已提交
602 603
            }

S
starlord 已提交
604
            mysqlpp::Query updateTableFlagQuery = connectionPtr->query();
S
starlord 已提交
605 606 607
            updateTableFlagQuery << "UPDATE " << META_TABLES << " "
                                 << "SET flag = " << flag << " "
                                 << "WHERE table_id = " << mysqlpp::quote << table_id << ";";
S
starlord 已提交
608 609 610 611

            ENGINE_LOG_DEBUG << "MySQLMetaImpl::UpdateTableFlag: " << updateTableFlagQuery.str();

            if (!updateTableFlagQuery.exec()) {
S
starlord 已提交
612
                return HandleException("QUERY ERROR WHEN UPDATING TABLE FLAG", updateTableFlagQuery.error());
S
starlord 已提交
613
            }
S
starlord 已提交
614
        }  // Scoped Connection
S
starlord 已提交
615

616
        ENGINE_LOG_DEBUG << "Successfully update table flag, table id = " << table_id;
S
starlord 已提交
617
    } catch (std::exception& e) {
S
starlord 已提交
618
        return HandleException("GENERAL ERROR WHEN UPDATING TABLE FLAG", e.what());
S
starlord 已提交
619 620 621 622 623
    }

    return Status::OK();
}

S
starlord 已提交
624
Status
S
starlord 已提交
625
MySQLMetaImpl::DescribeTableIndex(const std::string& table_id, TableIndex& index) {
S
starlord 已提交
626
    try {
Y
Yu Kun 已提交
627
        server::MetricCollector metric;
628

S
starlord 已提交
629
        {
S
starlord 已提交
630
            mysqlpp::ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab_);
631

S
starlord 已提交
632
            if (connectionPtr == nullptr) {
S
starlord 已提交
633
                return Status(DB_ERROR, "Failed to connect to database server");
S
starlord 已提交
634 635
            }

S
starlord 已提交
636
            mysqlpp::Query describeTableIndexQuery = connectionPtr->query();
S
starlord 已提交
637 638 639 640
            describeTableIndexQuery << "SELECT engine_type, nlist, index_file_size, metric_type FROM " << META_TABLES
                                    << " "
                                    << "WHERE table_id = " << mysqlpp::quote << table_id << " AND "
                                    << "state <> " << std::to_string(TableSchema::TO_DELETE) << ";";
Z
update  
zhiru 已提交
641

S
starlord 已提交
642
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::DescribeTableIndex: " << describeTableIndexQuery.str();
Z
update  
zhiru 已提交
643

S
starlord 已提交
644
            mysqlpp::StoreQueryResult res = describeTableIndexQuery.store();
S
starlord 已提交
645 646

            if (res.num_rows() == 1) {
S
starlord 已提交
647
                const mysqlpp::Row& resRow = res[0];
S
starlord 已提交
648 649 650 651 652

                index.engine_type_ = resRow["engine_type"];
                index.nlist_ = resRow["nlist"];
                index.metric_type_ = resRow["metric_type"];
            } else {
S
starlord 已提交
653
                return Status(DB_NOT_FOUND, "Table " + table_id + " not found");
S
starlord 已提交
654
            }
S
starlord 已提交
655 656
        }  // Scoped Connection
    } catch (std::exception& e) {
S
starlord 已提交
657
        return HandleException("GENERAL ERROR WHEN UPDATING TABLE FLAG", e.what());
S
starlord 已提交
658 659 660 661 662
    }

    return Status::OK();
}

S
starlord 已提交
663
Status
S
starlord 已提交
664
MySQLMetaImpl::DropTableIndex(const std::string& table_id) {
S
starlord 已提交
665
    try {
Y
Yu Kun 已提交
666
        server::MetricCollector metric;
Z
update  
zhiru 已提交
667

668
        {
S
starlord 已提交
669
            mysqlpp::ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab_);
670

671
            if (connectionPtr == nullptr) {
S
starlord 已提交
672
                return Status(DB_ERROR, "Failed to connect to database server");
673
            }
674

S
starlord 已提交
675
            mysqlpp::Query dropTableIndexQuery = connectionPtr->query();
S
starlord 已提交
676

S
starlord 已提交
677 678 679 680 681 682
            // soft delete index files
            dropTableIndexQuery << "UPDATE " << META_TABLEFILES << " "
                                << "SET file_type = " << std::to_string(TableFileSchema::TO_DELETE) << ","
                                << "updated_time = " << utils::GetMicroSecTimeStamp() << " "
                                << "WHERE table_id = " << mysqlpp::quote << table_id << " AND "
                                << "file_type = " << std::to_string(TableFileSchema::INDEX) << ";";
S
starlord 已提交
683 684 685 686

            ENGINE_LOG_DEBUG << "MySQLMetaImpl::DropTableIndex: " << dropTableIndexQuery.str();

            if (!dropTableIndexQuery.exec()) {
S
starlord 已提交
687
                return HandleException("QUERY ERROR WHEN DROPPING TABLE INDEX", dropTableIndexQuery.error());
S
starlord 已提交
688 689
            }

S
starlord 已提交
690 691 692 693 694 695
            // set all backup file to raw
            dropTableIndexQuery << "UPDATE " << META_TABLEFILES << " "
                                << "SET file_type = " << std::to_string(TableFileSchema::RAW) << ","
                                << "updated_time = " << utils::GetMicroSecTimeStamp() << " "
                                << "WHERE table_id = " << mysqlpp::quote << table_id << " AND "
                                << "file_type = " << std::to_string(TableFileSchema::BACKUP) << ";";
S
starlord 已提交
696 697 698 699

            ENGINE_LOG_DEBUG << "MySQLMetaImpl::DropTableIndex: " << dropTableIndexQuery.str();

            if (!dropTableIndexQuery.exec()) {
S
starlord 已提交
700
                return HandleException("QUERY ERROR WHEN DROPPING TABLE INDEX", dropTableIndexQuery.error());
701 702
            }

S
starlord 已提交
703 704 705 706 707 708
            // set table index type to raw
            dropTableIndexQuery << "UPDATE " << META_TABLES << " "
                                << "SET engine_type = " << std::to_string(DEFAULT_ENGINE_TYPE) << ","
                                << "nlist = " << std::to_string(DEFAULT_NLIST) << ", "
                                << "metric_type = " << std::to_string(DEFAULT_METRIC_TYPE) << " "
                                << "WHERE table_id = " << mysqlpp::quote << table_id << ";";
709 710 711 712

            ENGINE_LOG_DEBUG << "MySQLMetaImpl::DropTableIndex: " << dropTableIndexQuery.str();

            if (!dropTableIndexQuery.exec()) {
S
starlord 已提交
713
                return HandleException("QUERY ERROR WHEN DROPPING TABLE INDEX", dropTableIndexQuery.error());
S
starlord 已提交
714
            }
S
starlord 已提交
715
        }  // Scoped Connection
S
starlord 已提交
716

717
        ENGINE_LOG_DEBUG << "Successfully drop table index, table id = " << table_id;
S
starlord 已提交
718
    } catch (std::exception& e) {
S
starlord 已提交
719
        return HandleException("GENERAL ERROR WHEN DROPPING TABLE INDEX", e.what());
S
starlord 已提交
720
    }
721

S
starlord 已提交
722 723
    return Status::OK();
}
Z
update  
zhiru 已提交
724

S
starlord 已提交
725
Status
S
starlord 已提交
726
MySQLMetaImpl::DeleteTable(const std::string& table_id) {
S
starlord 已提交
727
    try {
Y
Yu Kun 已提交
728
        server::MetricCollector metric;
S
starlord 已提交
729
        {
S
starlord 已提交
730
            mysqlpp::ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab_);
Z
zhiru 已提交
731

S
starlord 已提交
732
            if (connectionPtr == nullptr) {
S
starlord 已提交
733
                return Status(DB_ERROR, "Failed to connect to database server");
S
starlord 已提交
734
            }
Z
zhiru 已提交
735

S
starlord 已提交
736
            // soft delete table
S
starlord 已提交
737
            mysqlpp::Query deleteTableQuery = connectionPtr->query();
S
starlord 已提交
738 739 740 741
            //
            deleteTableQuery << "UPDATE " << META_TABLES << " "
                             << "SET state = " << std::to_string(TableSchema::TO_DELETE) << " "
                             << "WHERE table_id = " << mysqlpp::quote << table_id << ";";
Z
update  
zhiru 已提交
742

743
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::DeleteTable: " << deleteTableQuery.str();
744

745
            if (!deleteTableQuery.exec()) {
S
starlord 已提交
746
                return HandleException("QUERY ERROR WHEN DELETING TABLE", deleteTableQuery.error());
747
            }
S
starlord 已提交
748
        }  // Scoped Connection
Z
zhiru 已提交
749

Y
yudong.cai 已提交
750
        if (mode_ == DBOptions::MODE::CLUSTER_WRITABLE) {
751 752
            DeleteTableFiles(table_id);
        }
Z
update  
zhiru 已提交
753

754
        ENGINE_LOG_DEBUG << "Successfully delete table, table id = " << table_id;
S
starlord 已提交
755
    } catch (std::exception& e) {
S
starlord 已提交
756
        return HandleException("GENERAL ERROR WHEN DELETING TABLE", e.what());
757
    }
Z
update  
zhiru 已提交
758

759 760
    return Status::OK();
}
Z
update  
zhiru 已提交
761

S
starlord 已提交
762
Status
S
starlord 已提交
763
MySQLMetaImpl::DeleteTableFiles(const std::string& table_id) {
764
    try {
Y
Yu Kun 已提交
765
        server::MetricCollector metric;
766
        {
S
starlord 已提交
767
            mysqlpp::ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab_);
768 769

            if (connectionPtr == nullptr) {
S
starlord 已提交
770
                return Status(DB_ERROR, "Failed to connect to database server");
771
            }
772

S
starlord 已提交
773
            // soft delete table files
S
starlord 已提交
774
            mysqlpp::Query deleteTableFilesQuery = connectionPtr->query();
775
            //
S
starlord 已提交
776 777 778 779 780
            deleteTableFilesQuery << "UPDATE " << META_TABLEFILES << " "
                                  << "SET file_type = " << std::to_string(TableFileSchema::TO_DELETE) << ", "
                                  << "updated_time = " << std::to_string(utils::GetMicroSecTimeStamp()) << " "
                                  << "WHERE table_id = " << mysqlpp::quote << table_id << " AND "
                                  << "file_type <> " << std::to_string(TableFileSchema::TO_DELETE) << ";";
781

782
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::DeleteTableFiles: " << deleteTableFilesQuery.str();
783

784
            if (!deleteTableFilesQuery.exec()) {
S
starlord 已提交
785
                return HandleException("QUERY ERROR WHEN DELETING TABLE FILES", deleteTableFilesQuery.error());
786
            }
S
starlord 已提交
787
        }  // Scoped Connection
788 789

        ENGINE_LOG_DEBUG << "Successfully delete table files, table id = " << table_id;
S
starlord 已提交
790
    } catch (std::exception& e) {
S
starlord 已提交
791
        return HandleException("GENERAL ERROR WHEN DELETING TABLE FILES", e.what());
Z
update  
zhiru 已提交
792 793
    }

794 795
    return Status::OK();
}
Z
zhiru 已提交
796

S
starlord 已提交
797
Status
S
starlord 已提交
798
MySQLMetaImpl::DescribeTable(TableSchema& table_schema) {
799
    try {
Y
Yu Kun 已提交
800
        server::MetricCollector metric;
S
starlord 已提交
801
        mysqlpp::StoreQueryResult res;
802
        {
S
starlord 已提交
803
            mysqlpp::ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab_);
804

805
            if (connectionPtr == nullptr) {
S
starlord 已提交
806
                return Status(DB_ERROR, "Failed to connect to database server");
807
            }
Z
zhiru 已提交
808

S
starlord 已提交
809 810 811
            mysqlpp::Query describeTableQuery = connectionPtr->query();
            describeTableQuery
                << "SELECT id, state, dimension, created_on, flag, index_file_size, engine_type, nlist, metric_type "
S
starlord 已提交
812 813 814
                << " FROM " << META_TABLES << " "
                << "WHERE table_id = " << mysqlpp::quote << table_schema.table_id_ << " "
                << "AND state <> " << std::to_string(TableSchema::TO_DELETE) << ";";
815 816

            ENGINE_LOG_DEBUG << "MySQLMetaImpl::DescribeTable: " << describeTableQuery.str();
Z
update  
zhiru 已提交
817

818
            res = describeTableQuery.store();
S
starlord 已提交
819
        }  // Scoped Connection
820

821
        if (res.num_rows() == 1) {
S
starlord 已提交
822
            const mysqlpp::Row& resRow = res[0];
823

S
starlord 已提交
824
            table_schema.id_ = resRow["id"];  // implicit conversion
Z
update  
zhiru 已提交
825

S
starlord 已提交
826 827
            table_schema.state_ = resRow["state"];

828
            table_schema.dimension_ = resRow["dimension"];
829

S
starlord 已提交
830 831 832 833
            table_schema.created_on_ = resRow["created_on"];

            table_schema.flag_ = resRow["flag"];

834 835
            table_schema.index_file_size_ = resRow["index_file_size"];

836
            table_schema.engine_type_ = resRow["engine_type"];
S
starlord 已提交
837 838 839 840

            table_schema.nlist_ = resRow["nlist"];

            table_schema.metric_type_ = resRow["metric_type"];
841
        } else {
S
starlord 已提交
842
            return Status(DB_NOT_FOUND, "Table " + table_schema.table_id_ + " not found");
843
        }
S
starlord 已提交
844
    } catch (std::exception& e) {
S
starlord 已提交
845
        return HandleException("GENERAL ERROR WHEN DESCRIBING TABLE", e.what());
Z
update  
zhiru 已提交
846 847
    }

848 849
    return Status::OK();
}
Z
zhiru 已提交
850

S
starlord 已提交
851
Status
S
starlord 已提交
852
MySQLMetaImpl::HasTable(const std::string& table_id, bool& has_or_not) {
853
    try {
Y
Yu Kun 已提交
854
        server::MetricCollector metric;
S
starlord 已提交
855
        mysqlpp::StoreQueryResult res;
856
        {
S
starlord 已提交
857
            mysqlpp::ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab_);
Z
update  
zhiru 已提交
858

859
            if (connectionPtr == nullptr) {
S
starlord 已提交
860
                return Status(DB_ERROR, "Failed to connect to database server");
861
            }
Z
update  
zhiru 已提交
862

S
starlord 已提交
863
            mysqlpp::Query hasTableQuery = connectionPtr->query();
S
starlord 已提交
864 865 866 867 868 869 870
            // since table_id is a unique column we just need to check whether it exists or not
            hasTableQuery << "SELECT EXISTS "
                          << "(SELECT 1 FROM " << META_TABLES << " "
                          << "WHERE table_id = " << mysqlpp::quote << table_id << " "
                          << "AND state <> " << std::to_string(TableSchema::TO_DELETE) << ") "
                          << "AS " << mysqlpp::quote << "check"
                          << ";";
Z
update  
zhiru 已提交
871

872
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::HasTable: " << hasTableQuery.str();
873

874
            res = hasTableQuery.store();
S
starlord 已提交
875
        }  // Scoped Connection
876

877 878
        int check = res[0]["check"];
        has_or_not = (check == 1);
S
starlord 已提交
879
    } catch (std::exception& e) {
S
starlord 已提交
880
        return HandleException("GENERAL ERROR WHEN CHECKING IF TABLE EXISTS", e.what());
881
    }
882

883 884
    return Status::OK();
}
885

S
starlord 已提交
886
Status
S
starlord 已提交
887
MySQLMetaImpl::AllTables(std::vector<TableSchema>& table_schema_array) {
888
    try {
Y
Yu Kun 已提交
889
        server::MetricCollector metric;
S
starlord 已提交
890
        mysqlpp::StoreQueryResult res;
891
        {
S
starlord 已提交
892
            mysqlpp::ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab_);
893

894
            if (connectionPtr == nullptr) {
S
starlord 已提交
895
                return Status(DB_ERROR, "Failed to connect to database server");
896
            }
Z
update  
zhiru 已提交
897

S
starlord 已提交
898 899
            mysqlpp::Query allTablesQuery = connectionPtr->query();
            allTablesQuery << "SELECT id, table_id, dimension, engine_type, nlist, index_file_size, metric_type FROM "
S
starlord 已提交
900 901
                           << META_TABLES << " "
                           << "WHERE state <> " << std::to_string(TableSchema::TO_DELETE) << ";";
Z
zhiru 已提交
902

903
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::AllTables: " << allTablesQuery.str();
Z
zhiru 已提交
904

905
            res = allTablesQuery.store();
S
starlord 已提交
906
        }  // Scoped Connection
907

S
starlord 已提交
908
        for (auto& resRow : res) {
909
            TableSchema table_schema;
Z
update  
zhiru 已提交
910

S
starlord 已提交
911
            table_schema.id_ = resRow["id"];  // implicit conversion
912

913 914 915
            std::string table_id;
            resRow["table_id"].to_string(table_id);
            table_schema.table_id_ = table_id;
916

917
            table_schema.dimension_ = resRow["dimension"];
918

919 920
            table_schema.index_file_size_ = resRow["index_file_size"];

921
            table_schema.engine_type_ = resRow["engine_type"];
922

S
starlord 已提交
923 924 925 926
            table_schema.nlist_ = resRow["nlist"];

            table_schema.metric_type_ = resRow["metric_type"];

927 928
            table_schema_array.emplace_back(table_schema);
        }
S
starlord 已提交
929
    } catch (std::exception& e) {
S
starlord 已提交
930
        return HandleException("GENERAL ERROR WHEN DESCRIBING ALL TABLES", e.what());
931
    }
Z
update  
zhiru 已提交
932

933 934
    return Status::OK();
}
935

S
starlord 已提交
936
Status
S
starlord 已提交
937
MySQLMetaImpl::CreateTableFile(TableFileSchema& file_schema) {
938
    if (file_schema.date_ == EmptyDate) {
939
        file_schema.date_ = utils::GetDate();
940 941 942 943 944 945 946
    }
    TableSchema table_schema;
    table_schema.table_id_ = file_schema.table_id_;
    auto status = DescribeTable(table_schema);
    if (!status.ok()) {
        return status;
    }
947

948
    try {
Y
Yu Kun 已提交
949
        server::MetricCollector metric;
950 951 952

        NextFileId(file_schema.file_id_);
        file_schema.dimension_ = table_schema.dimension_;
953 954
        file_schema.file_size_ = 0;
        file_schema.row_count_ = 0;
955 956
        file_schema.created_on_ = utils::GetMicroSecTimeStamp();
        file_schema.updated_time_ = file_schema.created_on_;
957
        file_schema.index_file_size_ = table_schema.index_file_size_;
958
        file_schema.engine_type_ = table_schema.engine_type_;
S
starlord 已提交
959 960
        file_schema.nlist_ = table_schema.nlist_;
        file_schema.metric_type_ = table_schema.metric_type_;
961

S
starlord 已提交
962
        std::string id = "NULL";  // auto-increment
963 964 965 966
        std::string table_id = file_schema.table_id_;
        std::string engine_type = std::to_string(file_schema.engine_type_);
        std::string file_id = file_schema.file_id_;
        std::string file_type = std::to_string(file_schema.file_type_);
S
starlord 已提交
967
        std::string file_size = std::to_string(file_schema.file_size_);
968
        std::string row_count = std::to_string(file_schema.row_count_);
969 970 971 972 973
        std::string updated_time = std::to_string(file_schema.updated_time_);
        std::string created_on = std::to_string(file_schema.created_on_);
        std::string date = std::to_string(file_schema.date_);

        {
S
starlord 已提交
974
            mysqlpp::ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab_);
Z
update  
zhiru 已提交
975

976
            if (connectionPtr == nullptr) {
S
starlord 已提交
977
                return Status(DB_ERROR, "Failed to connect to database server");
978
            }
Z
update  
zhiru 已提交
979

S
starlord 已提交
980
            mysqlpp::Query createTableFileQuery = connectionPtr->query();
981

S
starlord 已提交
982 983 984 985
            createTableFileQuery << "INSERT INTO " << META_TABLEFILES << " "
                                 << "VALUES(" << id << ", " << mysqlpp::quote << table_id << ", " << engine_type << ", "
                                 << mysqlpp::quote << file_id << ", " << file_type << ", " << file_size << ", "
                                 << row_count << ", " << updated_time << ", " << created_on << ", " << date << ");";
986 987 988

            ENGINE_LOG_DEBUG << "MySQLMetaImpl::CreateTableFile: " << createTableFileQuery.str();

S
starlord 已提交
989
            if (mysqlpp::SimpleResult res = createTableFileQuery.execute()) {
S
starlord 已提交
990
                file_schema.id_ = res.insert_id();  // Might need to use SELECT LAST_INSERT_ID()?
991

S
starlord 已提交
992
                // Consume all results to avoid "Commands out of sync" error
993
            } else {
S
starlord 已提交
994
                return HandleException("QUERY ERROR WHEN CREATING TABLE FILE", createTableFileQuery.error());
995
            }
S
starlord 已提交
996
        }  // Scoped Connection
997

998
        ENGINE_LOG_DEBUG << "Successfully create table file, file id = " << file_schema.file_id_;
999
        return utils::CreateTableFilePath(options_, file_schema);
S
starlord 已提交
1000
    } catch (std::exception& e) {
S
starlord 已提交
1001
        return HandleException("GENERAL ERROR WHEN CREATING TABLE FILE", e.what());
1002 1003
    }
}
1004

S
starlord 已提交
1005
Status
S
starlord 已提交
1006
MySQLMetaImpl::FilesToIndex(TableFilesSchema& files) {
1007
    files.clear();
1008

1009
    try {
Y
Yu Kun 已提交
1010
        server::MetricCollector metric;
S
starlord 已提交
1011
        mysqlpp::StoreQueryResult res;
1012
        {
S
starlord 已提交
1013
            mysqlpp::ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab_);
1014 1015

            if (connectionPtr == nullptr) {
S
starlord 已提交
1016
                return Status(DB_ERROR, "Failed to connect to database server");
1017
            }
1018

S
starlord 已提交
1019 1020 1021
            mysqlpp::Query filesToIndexQuery = connectionPtr->query();
            filesToIndexQuery
                << "SELECT id, table_id, engine_type, file_id, file_type, file_size, row_count, date, created_on FROM "
S
starlord 已提交
1022 1023
                << META_TABLEFILES << " "
                << "WHERE file_type = " << std::to_string(TableFileSchema::TO_INDEX) << ";";
1024

1025
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::FilesToIndex: " << filesToIndexQuery.str();
1026

1027
            res = filesToIndexQuery.store();
S
starlord 已提交
1028
        }  // Scoped Connection
1029

S
starlord 已提交
1030
        Status ret;
1031 1032
        std::map<std::string, TableSchema> groups;
        TableFileSchema table_file;
S
starlord 已提交
1033 1034
        for (auto& resRow : res) {
            table_file.id_ = resRow["id"];  // implicit conversion
1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047

            std::string table_id;
            resRow["table_id"].to_string(table_id);
            table_file.table_id_ = table_id;

            table_file.engine_type_ = resRow["engine_type"];

            std::string file_id;
            resRow["file_id"].to_string(file_id);
            table_file.file_id_ = file_id;

            table_file.file_type_ = resRow["file_type"];

S
starlord 已提交
1048 1049
            table_file.file_size_ = resRow["file_size"];

1050
            table_file.row_count_ = resRow["row_count"];
1051 1052 1053

            table_file.date_ = resRow["date"];

S
starlord 已提交
1054 1055
            table_file.created_on_ = resRow["created_on"];

1056 1057 1058 1059 1060 1061 1062
            auto groupItr = groups.find(table_file.table_id_);
            if (groupItr == groups.end()) {
                TableSchema table_schema;
                table_schema.table_id_ = table_file.table_id_;
                auto status = DescribeTable(table_schema);
                if (!status.ok()) {
                    return status;
1063
                }
1064
                groups[table_file.table_id_] = table_schema;
1065
            }
1066
            table_file.dimension_ = groups[table_file.table_id_].dimension_;
S
starlord 已提交
1067
            table_file.index_file_size_ = groups[table_file.table_id_].index_file_size_;
1068
            table_file.nlist_ = groups[table_file.table_id_].nlist_;
S
starlord 已提交
1069
            table_file.metric_type_ = groups[table_file.table_id_].metric_type_;
Z
update  
zhiru 已提交
1070

S
starlord 已提交
1071
            auto status = utils::GetTableFilePath(options_, table_file);
S
starlord 已提交
1072
            if (!status.ok()) {
S
starlord 已提交
1073
                ret = status;
S
starlord 已提交
1074
            }
1075 1076 1077

            files.push_back(table_file);
        }
S
starlord 已提交
1078

S
starlord 已提交
1079
        if (res.size() > 0) {
1080 1081
            ENGINE_LOG_DEBUG << "Collect " << res.size() << " to-index files";
        }
S
starlord 已提交
1082
        return ret;
S
starlord 已提交
1083
    } catch (std::exception& e) {
S
starlord 已提交
1084
        return HandleException("GENERAL ERROR WHEN FINDING TABLE FILES TO INDEX", e.what());
Z
update  
zhiru 已提交
1085
    }
1086 1087
}

S
starlord 已提交
1088
Status
S
starlord 已提交
1089 1090
MySQLMetaImpl::FilesToSearch(const std::string& table_id, const std::vector<size_t>& ids, const DatesT& partition,
                             DatePartionedTableFilesSchema& files) {
X
xj.lin 已提交
1091 1092 1093
    files.clear();

    try {
Y
Yu Kun 已提交
1094
        server::MetricCollector metric;
S
starlord 已提交
1095
        mysqlpp::StoreQueryResult res;
X
xj.lin 已提交
1096
        {
S
starlord 已提交
1097
            mysqlpp::ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab_);
X
xj.lin 已提交
1098 1099

            if (connectionPtr == nullptr) {
S
starlord 已提交
1100
                return Status(DB_ERROR, "Failed to connect to database server");
X
xj.lin 已提交
1101 1102
            }

S
starlord 已提交
1103 1104
            mysqlpp::Query filesToSearchQuery = connectionPtr->query();
            filesToSearchQuery
S
starlord 已提交
1105 1106 1107
                << "SELECT id, table_id, engine_type, file_id, file_type, file_size, row_count, date FROM "
                << META_TABLEFILES << " "
                << "WHERE table_id = " << mysqlpp::quote << table_id;
X
xj.lin 已提交
1108 1109 1110

            if (!partition.empty()) {
                std::stringstream partitionListSS;
S
starlord 已提交
1111
                for (auto& date : partition) {
X
xj.lin 已提交
1112 1113 1114 1115
                    partitionListSS << std::to_string(date) << ", ";
                }
                std::string partitionListStr = partitionListSS.str();

S
starlord 已提交
1116 1117 1118
                partitionListStr = partitionListStr.substr(0, partitionListStr.size() - 2);  // remove the last ", "
                filesToSearchQuery << " AND "
                                   << "date IN (" << partitionListStr << ")";
X
xj.lin 已提交
1119 1120 1121 1122
            }

            if (!ids.empty()) {
                std::stringstream idSS;
S
starlord 已提交
1123
                for (auto& id : ids) {
X
xj.lin 已提交
1124 1125 1126
                    idSS << "id = " << std::to_string(id) << " OR ";
                }
                std::string idStr = idSS.str();
S
starlord 已提交
1127
                idStr = idStr.substr(0, idStr.size() - 4);  // remove the last " OR "
X
xj.lin 已提交
1128

S
starlord 已提交
1129 1130
                filesToSearchQuery << " AND "
                                   << "(" << idStr << ")";
X
xj.lin 已提交
1131 1132
            }
            // End
S
starlord 已提交
1133 1134 1135 1136
            filesToSearchQuery << " AND "
                               << "(file_type = " << std::to_string(TableFileSchema::RAW) << " OR "
                               << "file_type = " << std::to_string(TableFileSchema::TO_INDEX) << " OR "
                               << "file_type = " << std::to_string(TableFileSchema::INDEX) << ");";
X
xj.lin 已提交
1137 1138 1139 1140

            ENGINE_LOG_DEBUG << "MySQLMetaImpl::FilesToSearch: " << filesToSearchQuery.str();

            res = filesToSearchQuery.store();
S
starlord 已提交
1141
        }  // Scoped Connection
X
xj.lin 已提交
1142 1143 1144 1145 1146 1147 1148 1149

        TableSchema table_schema;
        table_schema.table_id_ = table_id;
        auto status = DescribeTable(table_schema);
        if (!status.ok()) {
            return status;
        }

S
starlord 已提交
1150
        Status ret;
X
xj.lin 已提交
1151
        TableFileSchema table_file;
S
starlord 已提交
1152 1153
        for (auto& resRow : res) {
            table_file.id_ = resRow["id"];  // implicit conversion
X
xj.lin 已提交
1154 1155 1156 1157 1158

            std::string table_id_str;
            resRow["table_id"].to_string(table_id_str);
            table_file.table_id_ = table_id_str;

1159 1160
            table_file.index_file_size_ = table_schema.index_file_size_;

X
xj.lin 已提交
1161 1162
            table_file.engine_type_ = resRow["engine_type"];

S
starlord 已提交
1163 1164
            table_file.nlist_ = table_schema.nlist_;

S
starlord 已提交
1165 1166
            table_file.metric_type_ = table_schema.metric_type_;

X
xj.lin 已提交
1167 1168 1169 1170 1171 1172
            std::string file_id;
            resRow["file_id"].to_string(file_id);
            table_file.file_id_ = file_id;

            table_file.file_type_ = resRow["file_type"];

S
starlord 已提交
1173 1174
            table_file.file_size_ = resRow["file_size"];

1175
            table_file.row_count_ = resRow["row_count"];
X
xj.lin 已提交
1176 1177 1178 1179 1180

            table_file.date_ = resRow["date"];

            table_file.dimension_ = table_schema.dimension_;

S
starlord 已提交
1181
            auto status = utils::GetTableFilePath(options_, table_file);
S
starlord 已提交
1182
            if (!status.ok()) {
S
starlord 已提交
1183
                ret = status;
S
starlord 已提交
1184
            }
1185

1186 1187 1188
            auto dateItr = files.find(table_file.date_);
            if (dateItr == files.end()) {
                files[table_file.date_] = TableFilesSchema();
1189 1190
            }

1191
            files[table_file.date_].push_back(table_file);
1192
        }
S
starlord 已提交
1193

S
starlord 已提交
1194
        if (res.size() > 0) {
1195 1196
            ENGINE_LOG_DEBUG << "Collect " << res.size() << " to-search files";
        }
S
starlord 已提交
1197
        return ret;
S
starlord 已提交
1198
    } catch (std::exception& e) {
S
starlord 已提交
1199
        return HandleException("GENERAL ERROR WHEN FINDING TABLE FILES TO SEARCH", e.what());
Z
update  
zhiru 已提交
1200
    }
1201
}
Z
update  
zhiru 已提交
1202

S
starlord 已提交
1203
Status
S
starlord 已提交
1204
MySQLMetaImpl::FilesToMerge(const std::string& table_id, DatePartionedTableFilesSchema& files) {
1205
    files.clear();
Z
update  
zhiru 已提交
1206

1207
    try {
Y
Yu Kun 已提交
1208
        server::MetricCollector metric;
S
starlord 已提交
1209

S
starlord 已提交
1210
        // check table existence
S
starlord 已提交
1211 1212 1213 1214 1215 1216 1217
        TableSchema table_schema;
        table_schema.table_id_ = table_id;
        auto status = DescribeTable(table_schema);
        if (!status.ok()) {
            return status;
        }

S
starlord 已提交
1218
        mysqlpp::StoreQueryResult res;
1219
        {
S
starlord 已提交
1220
            mysqlpp::ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab_);
Z
update  
zhiru 已提交
1221

1222
            if (connectionPtr == nullptr) {
S
starlord 已提交
1223
                return Status(DB_ERROR, "Failed to connect to database server");
1224
            }
Z
update  
zhiru 已提交
1225

S
starlord 已提交
1226 1227 1228
            mysqlpp::Query filesToMergeQuery = connectionPtr->query();
            filesToMergeQuery
                << "SELECT id, table_id, file_id, file_type, file_size, row_count, date, engine_type, created_on FROM "
S
starlord 已提交
1229 1230 1231 1232 1233
                << META_TABLEFILES << " "
                << "WHERE table_id = " << mysqlpp::quote << table_id << " AND "
                << "file_type = " << std::to_string(TableFileSchema::RAW) << " "
                << "ORDER BY row_count DESC"
                << ";";
Z
update  
zhiru 已提交
1234

1235
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::FilesToMerge: " << filesToMergeQuery.str();
1236

1237
            res = filesToMergeQuery.store();
S
starlord 已提交
1238
        }  // Scoped Connection
1239

S
starlord 已提交
1240
        Status ret;
S
starlord 已提交
1241
        for (auto& resRow : res) {
S
starlord 已提交
1242 1243
            TableFileSchema table_file;
            table_file.file_size_ = resRow["file_size"];
S
starlord 已提交
1244
            if (table_file.file_size_ >= table_schema.index_file_size_) {
S
starlord 已提交
1245
                continue;  // skip large file
S
starlord 已提交
1246
            }
Z
update  
zhiru 已提交
1247

S
starlord 已提交
1248
            table_file.id_ = resRow["id"];  // implicit conversion
1249

1250 1251 1252
            std::string table_id_str;
            resRow["table_id"].to_string(table_id_str);
            table_file.table_id_ = table_id_str;
Z
update  
zhiru 已提交
1253

1254 1255 1256
            std::string file_id;
            resRow["file_id"].to_string(file_id);
            table_file.file_id_ = file_id;
1257

1258
            table_file.file_type_ = resRow["file_type"];
1259

S
starlord 已提交
1260 1261
            table_file.row_count_ = resRow["row_count"];

1262
            table_file.date_ = resRow["date"];
Z
update  
zhiru 已提交
1263

1264 1265
            table_file.index_file_size_ = table_schema.index_file_size_;

S
starlord 已提交
1266 1267
            table_file.engine_type_ = resRow["engine_type"];

S
starlord 已提交
1268 1269
            table_file.nlist_ = table_schema.nlist_;

S
starlord 已提交
1270 1271
            table_file.metric_type_ = table_schema.metric_type_;

S
starlord 已提交
1272 1273
            table_file.created_on_ = resRow["created_on"];

1274
            table_file.dimension_ = table_schema.dimension_;
Z
update  
zhiru 已提交
1275

S
starlord 已提交
1276
            auto status = utils::GetTableFilePath(options_, table_file);
S
starlord 已提交
1277
            if (!status.ok()) {
S
starlord 已提交
1278
                ret = status;
S
starlord 已提交
1279
            }
Z
update  
zhiru 已提交
1280

1281 1282 1283
            auto dateItr = files.find(table_file.date_);
            if (dateItr == files.end()) {
                files[table_file.date_] = TableFilesSchema();
1284
            }
1285 1286

            files[table_file.date_].push_back(table_file);
1287
        }
Z
update  
zhiru 已提交
1288

S
starlord 已提交
1289
        if (res.size() > 0) {
1290 1291
            ENGINE_LOG_DEBUG << "Collect " << res.size() << " to-merge files";
        }
S
starlord 已提交
1292
        return ret;
S
starlord 已提交
1293
    } catch (std::exception& e) {
S
starlord 已提交
1294
        return HandleException("GENERAL ERROR WHEN FINDING TABLE FILES TO MERGE", e.what());
1295 1296 1297
    }
}

S
starlord 已提交
1298
Status
S
starlord 已提交
1299 1300
MySQLMetaImpl::GetTableFiles(const std::string& table_id, const std::vector<size_t>& ids,
                             TableFilesSchema& table_files) {
1301
    if (ids.empty()) {
Z
update  
zhiru 已提交
1302 1303 1304
        return Status::OK();
    }

1305
    std::stringstream idSS;
S
starlord 已提交
1306
    for (auto& id : ids) {
1307 1308 1309
        idSS << "id = " << std::to_string(id) << " OR ";
    }
    std::string idStr = idSS.str();
S
starlord 已提交
1310
    idStr = idStr.substr(0, idStr.size() - 4);  // remove the last " OR "
Z
zhiru 已提交
1311

1312
    try {
S
starlord 已提交
1313
        mysqlpp::StoreQueryResult res;
1314
        {
S
starlord 已提交
1315
            mysqlpp::ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab_);
1316 1317

            if (connectionPtr == nullptr) {
S
starlord 已提交
1318
                return Status(DB_ERROR, "Failed to connect to database server");
1319 1320
            }

S
starlord 已提交
1321 1322
            mysqlpp::Query getTableFileQuery = connectionPtr->query();
            getTableFileQuery
S
starlord 已提交
1323 1324 1325 1326 1327
                << "SELECT id, engine_type, file_id, file_type, file_size, row_count, date, created_on FROM "
                << META_TABLEFILES << " "
                << "WHERE table_id = " << mysqlpp::quote << table_id << " AND "
                << "(" << idStr << ") AND "
                << "file_type <> " << std::to_string(TableFileSchema::TO_DELETE) << ";";
1328 1329 1330 1331

            ENGINE_LOG_DEBUG << "MySQLMetaImpl::GetTableFiles: " << getTableFileQuery.str();

            res = getTableFileQuery.store();
S
starlord 已提交
1332
        }  // Scoped Connection
1333 1334 1335

        TableSchema table_schema;
        table_schema.table_id_ = table_id;
S
starlord 已提交
1336
        DescribeTable(table_schema);
1337

S
starlord 已提交
1338
        Status ret;
S
starlord 已提交
1339
        for (auto& resRow : res) {
1340
            TableFileSchema file_schema;
1341

1342
            file_schema.id_ = resRow["id"];
Z
zhiru 已提交
1343

1344
            file_schema.table_id_ = table_id;
Z
update  
zhiru 已提交
1345

1346 1347
            file_schema.index_file_size_ = table_schema.index_file_size_;

1348
            file_schema.engine_type_ = resRow["engine_type"];
Z
update  
zhiru 已提交
1349

S
starlord 已提交
1350 1351
            file_schema.nlist_ = table_schema.nlist_;

S
starlord 已提交
1352 1353
            file_schema.metric_type_ = table_schema.metric_type_;

1354 1355 1356
            std::string file_id;
            resRow["file_id"].to_string(file_id);
            file_schema.file_id_ = file_id;
Z
update  
zhiru 已提交
1357

1358
            file_schema.file_type_ = resRow["file_type"];
Z
update  
zhiru 已提交
1359

1360 1361 1362
            file_schema.file_size_ = resRow["file_size"];

            file_schema.row_count_ = resRow["row_count"];
1363

1364
            file_schema.date_ = resRow["date"];
1365

S
starlord 已提交
1366 1367
            file_schema.created_on_ = resRow["created_on"];

1368
            file_schema.dimension_ = table_schema.dimension_;
Z
update  
zhiru 已提交
1369

S
starlord 已提交
1370
            utils::GetTableFilePath(options_, file_schema);
1371 1372 1373

            table_files.emplace_back(file_schema);
        }
S
starlord 已提交
1374

1375
        ENGINE_LOG_DEBUG << "Get table files by id";
S
starlord 已提交
1376
        return ret;
S
starlord 已提交
1377
    } catch (std::exception& e) {
S
starlord 已提交
1378
        return HandleException("GENERAL ERROR WHEN RETRIEVING TABLE FILES", e.what());
Z
update  
zhiru 已提交
1379
    }
1380
}
Z
zhiru 已提交
1381

1382
// PXU TODO: Support Swap
S
starlord 已提交
1383 1384
Status
MySQLMetaImpl::Archive() {
S
starlord 已提交
1385
    auto& criterias = options_.archive_conf_.GetCriterias();
1386 1387 1388 1389
    if (criterias.empty()) {
        return Status::OK();
    }

S
starlord 已提交
1390 1391 1392
    for (auto& kv : criterias) {
        auto& criteria = kv.first;
        auto& limit = kv.second;
1393
        if (criteria == engine::ARCHIVE_CONF_DAYS) {
1394
            size_t usecs = limit * D_SEC * US_PS;
S
starlord 已提交
1395
            int64_t now = utils::GetMicroSecTimeStamp();
1396 1397

            try {
S
starlord 已提交
1398
                mysqlpp::ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab_);
Z
zhiru 已提交
1399

Z
update  
zhiru 已提交
1400
                if (connectionPtr == nullptr) {
S
starlord 已提交
1401
                    return Status(DB_ERROR, "Failed to connect to database server");
Z
update  
zhiru 已提交
1402 1403
                }

S
starlord 已提交
1404
                mysqlpp::Query archiveQuery = connectionPtr->query();
S
starlord 已提交
1405 1406 1407 1408
                archiveQuery << "UPDATE " << META_TABLEFILES << " "
                             << "SET file_type = " << std::to_string(TableFileSchema::TO_DELETE) << " "
                             << "WHERE created_on < " << std::to_string(now - usecs) << " AND "
                             << "file_type <> " << std::to_string(TableFileSchema::TO_DELETE) << ";";
Z
update  
zhiru 已提交
1409

1410
                ENGINE_LOG_DEBUG << "MySQLMetaImpl::Archive: " << archiveQuery.str();
Z
update  
zhiru 已提交
1411

1412
                if (!archiveQuery.exec()) {
S
starlord 已提交
1413
                    return HandleException("QUERY ERROR DURING ARCHIVE", archiveQuery.error());
1414
                }
1415

1416
                ENGINE_LOG_DEBUG << "Archive old files";
S
starlord 已提交
1417
            } catch (std::exception& e) {
S
starlord 已提交
1418
                return HandleException("GENERAL ERROR WHEN DURING ARCHIVE", e.what());
Z
zhiru 已提交
1419
            }
1420
        }
1421
        if (criteria == engine::ARCHIVE_CONF_DISK) {
1422 1423
            uint64_t sum = 0;
            Size(sum);
Z
update  
zhiru 已提交
1424

1425 1426
            auto to_delete = (sum - limit * G);
            DiscardFiles(to_delete);
1427 1428

            ENGINE_LOG_DEBUG << "Archive files to free disk";
1429
        }
Z
update  
zhiru 已提交
1430 1431
    }

1432 1433
    return Status::OK();
}
Z
zhiru 已提交
1434

S
starlord 已提交
1435
Status
S
starlord 已提交
1436
MySQLMetaImpl::Size(uint64_t& result) {
1437
    result = 0;
1438

S
starlord 已提交
1439
    try {
S
starlord 已提交
1440
        mysqlpp::StoreQueryResult res;
1441
        {
S
starlord 已提交
1442
            mysqlpp::ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab_);
1443

1444
            if (connectionPtr == nullptr) {
S
starlord 已提交
1445
                return Status(DB_ERROR, "Failed to connect to database server");
1446
            }
Z
zhiru 已提交
1447

S
starlord 已提交
1448
            mysqlpp::Query getSizeQuery = connectionPtr->query();
S
starlord 已提交
1449 1450
            getSizeQuery << "SELECT IFNULL(SUM(file_size),0) AS sum FROM " << META_TABLEFILES << " "
                         << "WHERE file_type <> " << std::to_string(TableFileSchema::TO_DELETE) << ";";
Z
update  
zhiru 已提交
1451

1452
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::Size: " << getSizeQuery.str();
Z
update  
zhiru 已提交
1453

1454
            res = getSizeQuery.store();
S
starlord 已提交
1455
        }  // Scoped Connection
Z
update  
zhiru 已提交
1456

1457 1458 1459 1460 1461
        if (res.empty()) {
            result = 0;
        } else {
            result = res[0]["sum"];
        }
S
starlord 已提交
1462
    } catch (std::exception& e) {
S
starlord 已提交
1463
        return HandleException("GENERAL ERROR WHEN RETRIEVING SIZE", e.what());
1464
    }
1465

1466 1467
    return Status::OK();
}
1468

S
starlord 已提交
1469 1470
Status
MySQLMetaImpl::DiscardFiles(int64_t to_discard_size) {
1471 1472
    if (to_discard_size <= 0) {
        return Status::OK();
Z
update  
zhiru 已提交
1473
    }
1474
    ENGINE_LOG_DEBUG << "About to discard size=" << to_discard_size;
Z
update  
zhiru 已提交
1475

1476
    try {
Y
Yu Kun 已提交
1477
        server::MetricCollector metric;
1478 1479
        bool status;
        {
S
starlord 已提交
1480
            mysqlpp::ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab_);
1481

1482
            if (connectionPtr == nullptr) {
S
starlord 已提交
1483
                return Status(DB_ERROR, "Failed to connect to database server");
1484
            }
Z
zhiru 已提交
1485

S
starlord 已提交
1486
            mysqlpp::Query discardFilesQuery = connectionPtr->query();
S
starlord 已提交
1487 1488 1489 1490
            discardFilesQuery << "SELECT id, file_size FROM " << META_TABLEFILES << " "
                              << "WHERE file_type <> " << std::to_string(TableFileSchema::TO_DELETE) << " "
                              << "ORDER BY id ASC "
                              << "LIMIT 10;";
Z
update  
zhiru 已提交
1491

1492
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::DiscardFiles: " << discardFilesQuery.str();
1493

S
starlord 已提交
1494
            mysqlpp::StoreQueryResult res = discardFilesQuery.store();
1495 1496 1497
            if (res.num_rows() == 0) {
                return Status::OK();
            }
1498

1499 1500
            TableFileSchema table_file;
            std::stringstream idsToDiscardSS;
S
starlord 已提交
1501
            for (auto& resRow : res) {
1502 1503
                if (to_discard_size <= 0) {
                    break;
Z
update  
zhiru 已提交
1504
                }
1505
                table_file.id_ = resRow["id"];
1506
                table_file.file_size_ = resRow["file_size"];
1507 1508
                idsToDiscardSS << "id = " << std::to_string(table_file.id_) << " OR ";
                ENGINE_LOG_DEBUG << "Discard table_file.id=" << table_file.file_id_
1509 1510
                                 << " table_file.size=" << table_file.file_size_;
                to_discard_size -= table_file.file_size_;
1511
            }
Z
update  
zhiru 已提交
1512

1513
            std::string idsToDiscardStr = idsToDiscardSS.str();
S
starlord 已提交
1514
            idsToDiscardStr = idsToDiscardStr.substr(0, idsToDiscardStr.size() - 4);  // remove the last " OR "
1515

S
starlord 已提交
1516 1517 1518 1519
            discardFilesQuery << "UPDATE " << META_TABLEFILES << " "
                              << "SET file_type = " << std::to_string(TableFileSchema::TO_DELETE) << ", "
                              << "updated_time = " << std::to_string(utils::GetMicroSecTimeStamp()) << " "
                              << "WHERE " << idsToDiscardStr << ";";
1520

1521
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::DiscardFiles: " << discardFilesQuery.str();
Z
update  
zhiru 已提交
1522

1523 1524
            status = discardFilesQuery.exec();
            if (!status) {
S
starlord 已提交
1525
                return HandleException("QUERY ERROR WHEN DISCARDING FILES", discardFilesQuery.error());
1526
            }
S
starlord 已提交
1527
        }  // Scoped Connection
1528 1529

        return DiscardFiles(to_discard_size);
S
starlord 已提交
1530
    } catch (std::exception& e) {
S
starlord 已提交
1531
        return HandleException("GENERAL ERROR WHEN DISCARDING FILES", e.what());
P
peng.xu 已提交
1532
    }
1533
}
P
peng.xu 已提交
1534

S
starlord 已提交
1535
// ZR: this function assumes all fields in file_schema have value
S
starlord 已提交
1536
Status
S
starlord 已提交
1537
MySQLMetaImpl::UpdateTableFile(TableFileSchema& file_schema) {
1538
    file_schema.updated_time_ = utils::GetMicroSecTimeStamp();
1539

S
starlord 已提交
1540
    try {
Y
Yu Kun 已提交
1541
        server::MetricCollector metric;
1542
        {
S
starlord 已提交
1543
            mysqlpp::ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab_);
Z
update  
zhiru 已提交
1544

1545
            if (connectionPtr == nullptr) {
S
starlord 已提交
1546
                return Status(DB_ERROR, "Failed to connect to database server");
1547
            }
Z
update  
zhiru 已提交
1548

S
starlord 已提交
1549
            mysqlpp::Query updateTableFileQuery = connectionPtr->query();
Z
update  
zhiru 已提交
1550

S
starlord 已提交
1551 1552 1553 1554
            // if the table has been deleted, just mark the table file as TO_DELETE
            // clean thread will delete the file later
            updateTableFileQuery << "SELECT state FROM " << META_TABLES << " "
                                 << "WHERE table_id = " << mysqlpp::quote << file_schema.table_id_ << ";";
Z
update  
zhiru 已提交
1555

1556
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::UpdateTableFile: " << updateTableFileQuery.str();
Z
update  
zhiru 已提交
1557

S
starlord 已提交
1558
            mysqlpp::StoreQueryResult res = updateTableFileQuery.store();
1559

1560 1561 1562 1563
            if (res.num_rows() == 1) {
                int state = res[0]["state"];
                if (state == TableSchema::TO_DELETE) {
                    file_schema.file_type_ = TableFileSchema::TO_DELETE;
Z
update  
zhiru 已提交
1564
                }
1565 1566 1567 1568 1569 1570 1571 1572 1573
            } else {
                file_schema.file_type_ = TableFileSchema::TO_DELETE;
            }

            std::string id = std::to_string(file_schema.id_);
            std::string table_id = file_schema.table_id_;
            std::string engine_type = std::to_string(file_schema.engine_type_);
            std::string file_id = file_schema.file_id_;
            std::string file_type = std::to_string(file_schema.file_type_);
1574 1575
            std::string file_size = std::to_string(file_schema.file_size_);
            std::string row_count = std::to_string(file_schema.row_count_);
1576 1577 1578
            std::string updated_time = std::to_string(file_schema.updated_time_);
            std::string created_on = std::to_string(file_schema.created_on_);
            std::string date = std::to_string(file_schema.date_);
Z
update  
zhiru 已提交
1579

S
starlord 已提交
1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590
            updateTableFileQuery << "UPDATE " << META_TABLEFILES << " "
                                 << "SET table_id = " << mysqlpp::quote << table_id << ", "
                                 << "engine_type = " << engine_type << ", "
                                 << "file_id = " << mysqlpp::quote << file_id << ", "
                                 << "file_type = " << file_type << ", "
                                 << "file_size = " << file_size << ", "
                                 << "row_count = " << row_count << ", "
                                 << "updated_time = " << updated_time << ", "
                                 << "created_on = " << created_on << ", "
                                 << "date = " << date << " "
                                 << "WHERE id = " << id << ";";
1591 1592 1593 1594 1595

            ENGINE_LOG_DEBUG << "MySQLMetaImpl::UpdateTableFile: " << updateTableFileQuery.str();

            if (!updateTableFileQuery.exec()) {
                ENGINE_LOG_DEBUG << "table_id= " << file_schema.table_id_ << " file_id=" << file_schema.file_id_;
S
starlord 已提交
1596
                return HandleException("QUERY ERROR WHEN UPDATING TABLE FILE", updateTableFileQuery.error());
1597
            }
S
starlord 已提交
1598
        }  // Scoped Connection
1599

1600
        ENGINE_LOG_DEBUG << "Update single table file, file id = " << file_schema.file_id_;
S
starlord 已提交
1601
    } catch (std::exception& e) {
S
starlord 已提交
1602
        return HandleException("GENERAL ERROR WHEN UPDATING TABLE FILE", e.what());
1603
    }
S
starlord 已提交
1604

1605 1606
    return Status::OK();
}
1607

S
starlord 已提交
1608
Status
S
starlord 已提交
1609
MySQLMetaImpl::UpdateTableFilesToIndex(const std::string& table_id) {
1610
    try {
S
starlord 已提交
1611
        mysqlpp::ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab_);
1612

1613
        if (connectionPtr == nullptr) {
S
starlord 已提交
1614
            return Status(DB_ERROR, "Failed to connect to database server");
1615
        }
Z
update  
zhiru 已提交
1616

S
starlord 已提交
1617
        mysqlpp::Query updateTableFilesToIndexQuery = connectionPtr->query();
Z
zhiru 已提交
1618

S
starlord 已提交
1619 1620 1621 1622
        updateTableFilesToIndexQuery << "UPDATE " << META_TABLEFILES << " "
                                     << "SET file_type = " << std::to_string(TableFileSchema::TO_INDEX) << " "
                                     << "WHERE table_id = " << mysqlpp::quote << table_id << " AND "
                                     << "file_type = " << std::to_string(TableFileSchema::RAW) << ";";
1623

Z
zhiru 已提交
1624
        ENGINE_LOG_DEBUG << "MySQLMetaImpl::UpdateTableFilesToIndex: " << updateTableFilesToIndexQuery.str();
Z
update  
zhiru 已提交
1625

Z
fix  
zhiru 已提交
1626
        if (!updateTableFilesToIndexQuery.exec()) {
S
starlord 已提交
1627 1628
            return HandleException("QUERY ERROR WHEN UPDATING TABLE FILE TO INDEX",
                                   updateTableFilesToIndexQuery.error());
Z
fix  
zhiru 已提交
1629 1630
        }

1631
        ENGINE_LOG_DEBUG << "Update files to to_index, table id = " << table_id;
S
starlord 已提交
1632
    } catch (std::exception& e) {
S
starlord 已提交
1633
        return HandleException("GENERAL ERROR WHEN UPDATING TABLE FILES TO INDEX", e.what());
1634
    }
Z
update  
zhiru 已提交
1635

1636 1637
    return Status::OK();
}
Z
zhiru 已提交
1638

S
starlord 已提交
1639
Status
S
starlord 已提交
1640
MySQLMetaImpl::UpdateTableFiles(TableFilesSchema& files) {
1641
    try {
Y
Yu Kun 已提交
1642
        server::MetricCollector metric;
1643
        {
S
starlord 已提交
1644
            mysqlpp::ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab_);
1645 1646

            if (connectionPtr == nullptr) {
S
starlord 已提交
1647
                return Status(DB_ERROR, "Failed to connect to database server");
1648
            }
Z
update  
zhiru 已提交
1649

S
starlord 已提交
1650
            mysqlpp::Query updateTableFilesQuery = connectionPtr->query();
1651

1652
            std::map<std::string, bool> has_tables;
S
starlord 已提交
1653
            for (auto& file_schema : files) {
1654 1655 1656
                if (has_tables.find(file_schema.table_id_) != has_tables.end()) {
                    continue;
                }
1657

S
starlord 已提交
1658 1659 1660 1661 1662 1663
                updateTableFilesQuery << "SELECT EXISTS "
                                      << "(SELECT 1 FROM " << META_TABLES << " "
                                      << "WHERE table_id = " << mysqlpp::quote << file_schema.table_id_ << " "
                                      << "AND state <> " << std::to_string(TableSchema::TO_DELETE) << ") "
                                      << "AS " << mysqlpp::quote << "check"
                                      << ";";
1664

1665
                ENGINE_LOG_DEBUG << "MySQLMetaImpl::UpdateTableFiles: " << updateTableFilesQuery.str();
1666

S
starlord 已提交
1667
                mysqlpp::StoreQueryResult res = updateTableFilesQuery.store();
1668

1669 1670 1671
                int check = res[0]["check"];
                has_tables[file_schema.table_id_] = (check == 1);
            }
1672

S
starlord 已提交
1673
            for (auto& file_schema : files) {
1674 1675
                if (!has_tables[file_schema.table_id_]) {
                    file_schema.file_type_ = TableFileSchema::TO_DELETE;
1676
                }
1677
                file_schema.updated_time_ = utils::GetMicroSecTimeStamp();
1678

1679 1680 1681 1682 1683
                std::string id = std::to_string(file_schema.id_);
                std::string table_id = file_schema.table_id_;
                std::string engine_type = std::to_string(file_schema.engine_type_);
                std::string file_id = file_schema.file_id_;
                std::string file_type = std::to_string(file_schema.file_type_);
1684 1685
                std::string file_size = std::to_string(file_schema.file_size_);
                std::string row_count = std::to_string(file_schema.row_count_);
1686 1687 1688
                std::string updated_time = std::to_string(file_schema.updated_time_);
                std::string created_on = std::to_string(file_schema.created_on_);
                std::string date = std::to_string(file_schema.date_);
Z
fix  
zhiru 已提交
1689

S
starlord 已提交
1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700
                updateTableFilesQuery << "UPDATE " << META_TABLEFILES << " "
                                      << "SET table_id = " << mysqlpp::quote << table_id << ", "
                                      << "engine_type = " << engine_type << ", "
                                      << "file_id = " << mysqlpp::quote << file_id << ", "
                                      << "file_type = " << file_type << ", "
                                      << "file_size = " << file_size << ", "
                                      << "row_count = " << row_count << ", "
                                      << "updated_time = " << updated_time << ", "
                                      << "created_on = " << created_on << ", "
                                      << "date = " << date << " "
                                      << "WHERE id = " << id << ";";
1701 1702 1703 1704

                ENGINE_LOG_DEBUG << "MySQLMetaImpl::UpdateTableFiles: " << updateTableFilesQuery.str();

                if (!updateTableFilesQuery.exec()) {
S
starlord 已提交
1705
                    return HandleException("QUERY ERROR WHEN UPDATING TABLE FILES", updateTableFilesQuery.error());
1706 1707
                }
            }
S
starlord 已提交
1708
        }  // Scoped Connection
1709

1710
        ENGINE_LOG_DEBUG << "Update " << files.size() << " table files";
S
starlord 已提交
1711
    } catch (std::exception& e) {
S
starlord 已提交
1712
        return HandleException("GENERAL ERROR WHEN UPDATING TABLE FILES", e.what());
1713
    }
S
starlord 已提交
1714

1715 1716
    return Status::OK();
}
Z
fix  
zhiru 已提交
1717

S
starlord 已提交
1718 1719
Status
MySQLMetaImpl::CleanUpFilesWithTTL(uint16_t seconds) {
1720
    auto now = utils::GetMicroSecTimeStamp();
S
starlord 已提交
1721 1722
    std::set<std::string> table_ids;

S
starlord 已提交
1723
    // remove to_delete files
1724
    try {
Y
Yu Kun 已提交
1725
        server::MetricCollector metric;
1726

1727
        {
S
starlord 已提交
1728
            mysqlpp::ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab_);
Z
update  
zhiru 已提交
1729

1730
            if (connectionPtr == nullptr) {
S
starlord 已提交
1731
                return Status(DB_ERROR, "Failed to connect to database server");
1732
            }
Z
zhiru 已提交
1733

S
starlord 已提交
1734
            mysqlpp::Query cleanUpFilesWithTTLQuery = connectionPtr->query();
S
starlord 已提交
1735 1736 1737
            cleanUpFilesWithTTLQuery << "SELECT id, table_id, file_id, date FROM " << META_TABLEFILES << " "
                                     << "WHERE file_type = " << std::to_string(TableFileSchema::TO_DELETE) << " AND "
                                     << "updated_time < " << std::to_string(now - seconds * US_PS) << ";";
Z
update  
zhiru 已提交
1738

1739
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::CleanUpFilesWithTTL: " << cleanUpFilesWithTTLQuery.str();
Z
update  
zhiru 已提交
1740

S
starlord 已提交
1741
            mysqlpp::StoreQueryResult res = cleanUpFilesWithTTLQuery.store();
Z
update  
zhiru 已提交
1742

1743 1744
            TableFileSchema table_file;
            std::vector<std::string> idsToDelete;
1745

S
starlord 已提交
1746 1747
            for (auto& resRow : res) {
                table_file.id_ = resRow["id"];  // implicit conversion
1748

1749 1750 1751
                std::string table_id;
                resRow["table_id"].to_string(table_id);
                table_file.table_id_ = table_id;
Z
fix  
zhiru 已提交
1752

1753 1754 1755
                std::string file_id;
                resRow["file_id"].to_string(file_id);
                table_file.file_id_ = file_id;
Z
update  
zhiru 已提交
1756

1757
                table_file.date_ = resRow["date"];
Z
update  
zhiru 已提交
1758

1759 1760
                utils::DeleteTableFilePath(options_, table_file);

S
starlord 已提交
1761
                ENGINE_LOG_DEBUG << "Removing file id:" << table_file.id_ << " location:" << table_file.location_;
1762 1763

                idsToDelete.emplace_back(std::to_string(table_file.id_));
S
starlord 已提交
1764 1765

                table_ids.insert(table_file.table_id_);
1766 1767 1768 1769
            }

            if (!idsToDelete.empty()) {
                std::stringstream idsToDeleteSS;
S
starlord 已提交
1770
                for (auto& id : idsToDelete) {
1771
                    idsToDeleteSS << "id = " << id << " OR ";
1772
                }
1773

1774
                std::string idsToDeleteStr = idsToDeleteSS.str();
S
starlord 已提交
1775 1776 1777
                idsToDeleteStr = idsToDeleteStr.substr(0, idsToDeleteStr.size() - 4);  // remove the last " OR "
                cleanUpFilesWithTTLQuery << "DELETE FROM " << META_TABLEFILES << " "
                                         << "WHERE " << idsToDeleteStr << ";";
1778

1779 1780 1781
                ENGINE_LOG_DEBUG << "MySQLMetaImpl::CleanUpFilesWithTTL: " << cleanUpFilesWithTTLQuery.str();

                if (!cleanUpFilesWithTTLQuery.exec()) {
S
starlord 已提交
1782 1783
                    return HandleException("QUERY ERROR WHEN CLEANING UP FILES WITH TTL",
                                           cleanUpFilesWithTTLQuery.error());
1784 1785
                }
            }
1786

S
starlord 已提交
1787
            if (res.size() > 0) {
1788 1789
                ENGINE_LOG_DEBUG << "Clean " << res.size() << " files deleted in " << seconds << " seconds";
            }
S
starlord 已提交
1790 1791
        }  // Scoped Connection
    } catch (std::exception& e) {
S
starlord 已提交
1792
        return HandleException("GENERAL ERROR WHEN CLEANING UP FILES WITH TTL", e.what());
Z
update  
zhiru 已提交
1793
    }
1794

S
starlord 已提交
1795
    // remove to_delete tables
1796
    try {
Y
Yu Kun 已提交
1797
        server::MetricCollector metric;
1798 1799

        {
S
starlord 已提交
1800
            mysqlpp::ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab_);
Z
zhiru 已提交
1801

Z
update  
zhiru 已提交
1802
            if (connectionPtr == nullptr) {
S
starlord 已提交
1803
                return Status(DB_ERROR, "Failed to connect to database server");
Z
update  
zhiru 已提交
1804 1805
            }

S
starlord 已提交
1806
            mysqlpp::Query cleanUpFilesWithTTLQuery = connectionPtr->query();
S
starlord 已提交
1807 1808
            cleanUpFilesWithTTLQuery << "SELECT id, table_id FROM " << META_TABLES << " "
                                     << "WHERE state = " << std::to_string(TableSchema::TO_DELETE) << ";";
1809

1810 1811
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::CleanUpFilesWithTTL: " << cleanUpFilesWithTTLQuery.str();

S
starlord 已提交
1812
            mysqlpp::StoreQueryResult res = cleanUpFilesWithTTLQuery.store();
Z
update  
zhiru 已提交
1813

Z
update  
zhiru 已提交
1814
            if (!res.empty()) {
1815
                std::stringstream idsToDeleteSS;
S
starlord 已提交
1816
                for (auto& resRow : res) {
1817 1818 1819
                    size_t id = resRow["id"];
                    std::string table_id;
                    resRow["table_id"].to_string(table_id);
Z
update  
zhiru 已提交
1820

S
starlord 已提交
1821
                    utils::DeleteTablePath(options_, table_id, false);  // only delete empty folder
1822 1823

                    idsToDeleteSS << "id = " << std::to_string(id) << " OR ";
Z
update  
zhiru 已提交
1824
                }
1825
                std::string idsToDeleteStr = idsToDeleteSS.str();
S
starlord 已提交
1826 1827 1828
                idsToDeleteStr = idsToDeleteStr.substr(0, idsToDeleteStr.size() - 4);  // remove the last " OR "
                cleanUpFilesWithTTLQuery << "DELETE FROM " << META_TABLES << " "
                                         << "WHERE " << idsToDeleteStr << ";";
1829

1830
                ENGINE_LOG_DEBUG << "MySQLMetaImpl::CleanUpFilesWithTTL: " << cleanUpFilesWithTTLQuery.str();
Z
update  
zhiru 已提交
1831

1832
                if (!cleanUpFilesWithTTLQuery.exec()) {
S
starlord 已提交
1833 1834
                    return HandleException("QUERY ERROR WHEN CLEANING UP TABLES WITH TTL",
                                           cleanUpFilesWithTTLQuery.error());
1835 1836
                }
            }
1837

S
starlord 已提交
1838
            if (res.size() > 0) {
1839 1840
                ENGINE_LOG_DEBUG << "Remove " << res.size() << " tables from meta";
            }
S
starlord 已提交
1841 1842
        }  // Scoped Connection
    } catch (std::exception& e) {
S
starlord 已提交
1843
        return HandleException("GENERAL ERROR WHEN CLEANING UP TABLES WITH TTL", e.what());
Z
update  
zhiru 已提交
1844 1845
    }

S
starlord 已提交
1846 1847
    // remove deleted table folder
    // don't remove table folder until all its files has been deleted
S
starlord 已提交
1848
    try {
Y
Yu Kun 已提交
1849
        server::MetricCollector metric;
S
starlord 已提交
1850 1851

        {
S
starlord 已提交
1852
            mysqlpp::ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab_);
S
starlord 已提交
1853 1854

            if (connectionPtr == nullptr) {
S
starlord 已提交
1855
                return Status(DB_ERROR, "Failed to connect to database server");
S
starlord 已提交
1856 1857
            }

S
starlord 已提交
1858
            for (auto& table_id : table_ids) {
S
starlord 已提交
1859
                mysqlpp::Query cleanUpFilesWithTTLQuery = connectionPtr->query();
S
starlord 已提交
1860 1861
                cleanUpFilesWithTTLQuery << "SELECT file_id FROM " << META_TABLEFILES << " "
                                         << "WHERE table_id = " << mysqlpp::quote << table_id << ";";
S
starlord 已提交
1862 1863 1864

                ENGINE_LOG_DEBUG << "MySQLMetaImpl::CleanUpFilesWithTTL: " << cleanUpFilesWithTTLQuery.str();

S
starlord 已提交
1865
                mysqlpp::StoreQueryResult res = cleanUpFilesWithTTLQuery.store();
S
starlord 已提交
1866 1867 1868 1869 1870

                if (res.empty()) {
                    utils::DeleteTablePath(options_, table_id);
                }
            }
1871

S
starlord 已提交
1872
            if (table_ids.size() > 0) {
1873 1874
                ENGINE_LOG_DEBUG << "Remove " << table_ids.size() << " tables folder";
            }
S
starlord 已提交
1875
        }
S
starlord 已提交
1876
    } catch (std::exception& e) {
S
starlord 已提交
1877
        return HandleException("GENERAL ERROR WHEN CLEANING UP TABLES WITH TTL", e.what());
S
starlord 已提交
1878 1879
    }

1880 1881
    return Status::OK();
}
1882

S
starlord 已提交
1883 1884
Status
MySQLMetaImpl::CleanUp() {
1885
    try {
S
starlord 已提交
1886
        mysqlpp::ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab_);
1887

1888
        if (connectionPtr == nullptr) {
S
starlord 已提交
1889
            return Status(DB_ERROR, "Failed to connect to database server");
1890
        }
1891

S
starlord 已提交
1892
        mysqlpp::Query cleanUpQuery = connectionPtr->query();
S
starlord 已提交
1893 1894 1895 1896
        cleanUpQuery << "SELECT table_name "
                     << "FROM information_schema.tables "
                     << "WHERE table_schema = " << mysqlpp::quote << mysql_connection_pool_->getDB() << " "
                     << "AND table_name = " << mysqlpp::quote << META_TABLEFILES << ";";
Z
update  
zhiru 已提交
1897

1898
        ENGINE_LOG_DEBUG << "MySQLMetaImpl::CleanUp: " << cleanUpQuery.str();
Z
update  
zhiru 已提交
1899

S
starlord 已提交
1900
        mysqlpp::StoreQueryResult res = cleanUpQuery.store();
Z
update  
zhiru 已提交
1901

1902 1903
        if (!res.empty()) {
            ENGINE_LOG_DEBUG << "Remove table file type as NEW";
1904
            cleanUpQuery << "DELETE FROM " << META_TABLEFILES << " WHERE file_type IN ("
S
starlord 已提交
1905 1906
                         << std::to_string(TableFileSchema::NEW) << "," << std::to_string(TableFileSchema::NEW_MERGE)
                         << "," << std::to_string(TableFileSchema::NEW_INDEX) << ");";
1907

1908
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::CleanUp: " << cleanUpQuery.str();
1909

1910
            if (!cleanUpQuery.exec()) {
S
starlord 已提交
1911
                return HandleException("QUERY ERROR WHEN CLEANING UP FILES", cleanUpQuery.error());
Z
update  
zhiru 已提交
1912
            }
1913
        }
1914

S
starlord 已提交
1915
        if (res.size() > 0) {
1916 1917
            ENGINE_LOG_DEBUG << "Clean " << res.size() << " files";
        }
S
starlord 已提交
1918
    } catch (std::exception& e) {
S
starlord 已提交
1919
        return HandleException("GENERAL ERROR WHEN CLEANING UP FILES", e.what());
Z
update  
zhiru 已提交
1920 1921
    }

1922 1923 1924
    return Status::OK();
}

S
starlord 已提交
1925
Status
S
starlord 已提交
1926
MySQLMetaImpl::Count(const std::string& table_id, uint64_t& result) {
1927
    try {
Y
Yu Kun 已提交
1928
        server::MetricCollector metric;
1929 1930 1931 1932 1933 1934 1935

        TableSchema table_schema;
        table_schema.table_id_ = table_id;
        auto status = DescribeTable(table_schema);

        if (!status.ok()) {
            return status;
1936
        }
Z
zhiru 已提交
1937

S
starlord 已提交
1938
        mysqlpp::StoreQueryResult res;
1939
        {
S
starlord 已提交
1940
            mysqlpp::ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab_);
Z
zhiru 已提交
1941

Z
update  
zhiru 已提交
1942
            if (connectionPtr == nullptr) {
S
starlord 已提交
1943
                return Status(DB_ERROR, "Failed to connect to database server");
Z
update  
zhiru 已提交
1944 1945
            }

S
starlord 已提交
1946
            mysqlpp::Query countQuery = connectionPtr->query();
S
starlord 已提交
1947 1948 1949 1950 1951
            countQuery << "SELECT row_count FROM " << META_TABLEFILES << " "
                       << "WHERE table_id = " << mysqlpp::quote << table_id << " AND "
                       << "(file_type = " << std::to_string(TableFileSchema::RAW) << " OR "
                       << "file_type = " << std::to_string(TableFileSchema::TO_INDEX) << " OR "
                       << "file_type = " << std::to_string(TableFileSchema::INDEX) << ");";
Z
update  
zhiru 已提交
1952

1953
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::Count: " << countQuery.str();
Z
update  
zhiru 已提交
1954

1955
            res = countQuery.store();
S
starlord 已提交
1956
        }  // Scoped Connection
1957 1958

        result = 0;
S
starlord 已提交
1959
        for (auto& resRow : res) {
S
starlord 已提交
1960
            size_t size = resRow["row_count"];
1961
            result += size;
1962
        }
S
starlord 已提交
1963
    } catch (std::exception& e) {
S
starlord 已提交
1964
        return HandleException("GENERAL ERROR WHEN RETRIEVING COUNT", e.what());
Z
update  
zhiru 已提交
1965
    }
S
starlord 已提交
1966

1967 1968 1969
    return Status::OK();
}

S
starlord 已提交
1970 1971
Status
MySQLMetaImpl::DropAll() {
1972
    try {
S
starlord 已提交
1973
        ENGINE_LOG_DEBUG << "Drop all mysql meta";
S
starlord 已提交
1974
        mysqlpp::ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab_);
1975 1976

        if (connectionPtr == nullptr) {
S
starlord 已提交
1977
            return Status(DB_ERROR, "Failed to connect to database server");
Z
zhiru 已提交
1978
        }
1979

S
starlord 已提交
1980
        mysqlpp::Query dropTableQuery = connectionPtr->query();
1981
        dropTableQuery << "DROP TABLE IF EXISTS " << TABLES_SCHEMA.name() << ", " << TABLEFILES_SCHEMA.name() << ";";
1982 1983 1984 1985 1986 1987

        ENGINE_LOG_DEBUG << "MySQLMetaImpl::DropAll: " << dropTableQuery.str();

        if (dropTableQuery.exec()) {
            return Status::OK();
        } else {
S
starlord 已提交
1988
            return HandleException("QUERY ERROR WHEN DROPPING ALL", dropTableQuery.error());
1989
        }
S
starlord 已提交
1990
    } catch (std::exception& e) {
S
starlord 已提交
1991
        return HandleException("GENERAL ERROR WHEN DROPPING ALL", e.what());
1992 1993 1994
    }
}

S
starlord 已提交
1995 1996 1997 1998
}  // namespace meta
}  // namespace engine
}  // namespace milvus
}  // namespace zilliz