MySQLMetaImpl.cpp 77.2 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

namespace milvus {
namespace engine {
namespace meta {

45
namespace {
Z
update  
zhiru 已提交
46

S
starlord 已提交
47
Status
S
starlord 已提交
48
HandleException(const std::string& desc, const char* what = nullptr) {
S
starlord 已提交
49
    if (what == nullptr) {
S
starlord 已提交
50 51 52
        ENGINE_LOG_ERROR << desc;
        return Status(DB_META_TRANSACTION_FAILED, desc);
    }
S
starlord 已提交
53 54 55 56

    std::string msg = desc + ":" + what;
    ENGINE_LOG_ERROR << msg;
    return Status(DB_META_TRANSACTION_FAILED, msg);
57
}
Z
update  
zhiru 已提交
58

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

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

S
starlord 已提交
70 71
    std::string
    ToString() const {
72 73 74 75 76
        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 已提交
77 78
    bool
    IsEqual(const MetaField& field) const {
79 80 81
        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 已提交
82
               strncasecmp(field.type_.c_str(), type_.c_str(), type_len_min) == 0;
83 84
    }

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

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

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

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

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

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

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

S
starlord 已提交
136
// Tables schema
137
static const MetaSchema TABLES_SCHEMA(META_TABLES, {
S
starlord 已提交
138 139 140 141 142 143 144 145 146 147 148 149 150
                                                       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
S
starlord 已提交
151 152 153 154 155 156 157 158 159 160 161 162
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"),
                                                           });
S
starlord 已提交
163 164

}  // namespace
165

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

MySQLMetaImpl::~MySQLMetaImpl() {
}

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

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

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

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

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

        MetaFields exist_fields;

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

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

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

        return schema.IsEqual(exist_fields);
    };

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

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

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

S
starlord 已提交
253
    std::string uri = options_.backend_uri_;
254

S
starlord 已提交
255
    // step 2: parse and check meta uri
256 257
    utils::MetaUriInfo uri_info;
    auto status = utils::ParseMetaUri(uri, uri_info);
S
starlord 已提交
258
    if (!status.ok()) {
259 260 261 262 263 264 265 266 267 268 269
        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 已提交
270
    // step 3: connect mysql
271 272 273 274 275 276 277
    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 已提交
278 279
    mysql_connection_pool_ = std::make_shared<MySQLConnectionPool>(
        uri_info.db_name_, uri_info.username_, uri_info.password_, uri_info.host_, port, max_pool_size);
280 281
    ENGINE_LOG_DEBUG << "MySQL connection pool: maximum pool size = " << std::to_string(max_pool_size);

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

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

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

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

298 299 300
            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.");
301
            }
S
starlord 已提交
302
            mysqlpp::Query InitializeQuery = connectionPtr->query();
303

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

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

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

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

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

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

    return Status::OK();
327 328
}

S
starlord 已提交
329
// TODO(myh): Delete single vecotor by id
S
starlord 已提交
330
Status
S
starlord 已提交
331
MySQLMetaImpl::DropPartitionsByDates(const std::string& table_id, const DatesT& dates) {
332
    if (dates.empty()) {
P
peng.xu 已提交
333 334 335
        return Status::OK();
    }

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

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

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

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

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

S
starlord 已提交
360 361 362 363 364
            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 已提交
365

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

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

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

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

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

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

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

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

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

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

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

S
starlord 已提交
417
            std::string id = "NULL";  // auto-increment
418 419 420 421
            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 已提交
422 423
            std::string flag = std::to_string(table_schema.flag_);
            std::string index_file_size = std::to_string(table_schema.index_file_size_);
424
            std::string engine_type = std::to_string(table_schema.engine_type_);
S
starlord 已提交
425 426
            std::string nlist = std::to_string(table_schema.nlist_);
            std::string metric_type = std::to_string(table_schema.metric_type_);
Z
update  
zhiru 已提交
427

S
starlord 已提交
428 429 430 431
            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 已提交
432

433
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::CreateTable: " << createTableQuery.str();
434

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

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

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

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

    try {
459 460
        file_ids.clear();

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

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

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

S
starlord 已提交
477
            mysqlpp::Query hasNonIndexFilesQuery = connectionPtr->query();
S
starlord 已提交
478 479 480 481
            // 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 已提交
482

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

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

488 489 490
        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 已提交
491
            for (auto& resRow : res) {
492 493 494 495 496 497
                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 已提交
498 499
                    case (int)TableFileSchema::RAW:
                        raw_count++;
500
                        break;
S
starlord 已提交
501 502
                    case (int)TableFileSchema::NEW:
                        new_count++;
503
                        break;
S
starlord 已提交
504 505
                    case (int)TableFileSchema::NEW_MERGE:
                        new_merge_count++;
506
                        break;
S
starlord 已提交
507 508
                    case (int)TableFileSchema::NEW_INDEX:
                        new_index_count++;
509
                        break;
S
starlord 已提交
510 511
                    case (int)TableFileSchema::TO_INDEX:
                        to_index_count++;
512
                        break;
S
starlord 已提交
513 514
                    case (int)TableFileSchema::INDEX:
                        index_count++;
515
                        break;
S
starlord 已提交
516 517 518 519
                    case (int)TableFileSchema::BACKUP:
                        backup_count++;
                        break;
                    default:
520 521 522 523 524 525 526 527 528
                        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 已提交
529
    } catch (std::exception& e) {
S
starlord 已提交
530
        return HandleException("GENERAL ERROR WHEN GET FILE BY TYPE", e.what());
Z
zhiru 已提交
531 532
    }

533 534
    return Status::OK();
}
535

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

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

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

S
starlord 已提交
548
            mysqlpp::Query updateTableIndexParamQuery = connectionPtr->query();
S
starlord 已提交
549 550 551
            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 已提交
552

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

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

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

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

S
starlord 已提交
565 566 567 568 569 570 571 572 573
                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 已提交
574

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

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

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

591 592 593
    return Status::OK();
}

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

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

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

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

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

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

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

    return Status::OK();
}

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

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

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

S
starlord 已提交
638
            mysqlpp::Query describeTableIndexQuery = connectionPtr->query();
S
starlord 已提交
639 640 641 642
            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 已提交
643

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

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

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

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

    return Status::OK();
}

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

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

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

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

S
starlord 已提交
679 680 681 682 683 684
            // 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 已提交
685 686 687 688

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

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

S
starlord 已提交
692 693 694 695 696 697
            // 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 已提交
698 699 700 701

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

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

S
starlord 已提交
705 706 707 708 709 710
            // 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 << ";";
711 712 713 714

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

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

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

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

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

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

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

745
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::DeleteTable: " << deleteTableQuery.str();
746

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

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

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

761 762
    return Status::OK();
}
Z
update  
zhiru 已提交
763

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

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

S
starlord 已提交
775
            // soft delete table files
S
starlord 已提交
776
            mysqlpp::Query deleteTableFilesQuery = connectionPtr->query();
777
            //
S
starlord 已提交
778 779 780 781 782
            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) << ";";
783

784
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::DeleteTableFiles: " << deleteTableFilesQuery.str();
785

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

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

796 797
    return Status::OK();
}
Z
zhiru 已提交
798

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

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

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

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

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

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

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

S
starlord 已提交
828 829
            table_schema.state_ = resRow["state"];

830
            table_schema.dimension_ = resRow["dimension"];
831

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

            table_schema.flag_ = resRow["flag"];

836 837
            table_schema.index_file_size_ = resRow["index_file_size"];

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

            table_schema.nlist_ = resRow["nlist"];

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

850 851
    return Status::OK();
}
Z
zhiru 已提交
852

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

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

S
starlord 已提交
865
            mysqlpp::Query hasTableQuery = connectionPtr->query();
S
starlord 已提交
866 867 868 869 870 871 872
            // 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 已提交
873

874
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::HasTable: " << hasTableQuery.str();
875

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

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

885 886
    return Status::OK();
}
887

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

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

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

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

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

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

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

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

919
            table_schema.dimension_ = resRow["dimension"];
920

921 922
            table_schema.index_file_size_ = resRow["index_file_size"];

923
            table_schema.engine_type_ = resRow["engine_type"];
924

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

            table_schema.metric_type_ = resRow["metric_type"];

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

935 936
    return Status::OK();
}
937

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

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

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

S
starlord 已提交
964
        std::string id = "NULL";  // auto-increment
965 966 967 968
        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 已提交
969
        std::string file_size = std::to_string(file_schema.file_size_);
970
        std::string row_count = std::to_string(file_schema.row_count_);
971 972 973 974 975
        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 已提交
976
            mysqlpp::ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab_);
Z
update  
zhiru 已提交
977

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

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

S
starlord 已提交
984 985 986 987
            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 << ");";
988 989 990

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

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

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

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

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

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

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

S
starlord 已提交
1021 1022 1023
            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 已提交
1024 1025
                << META_TABLEFILES << " "
                << "WHERE file_type = " << std::to_string(TableFileSchema::TO_INDEX) << ";";
1026

1027
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::FilesToIndex: " << filesToIndexQuery.str();
1028

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

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

            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 已提交
1050 1051
            table_file.file_size_ = resRow["file_size"];

1052
            table_file.row_count_ = resRow["row_count"];
1053 1054 1055

            table_file.date_ = resRow["date"];

S
starlord 已提交
1056 1057
            table_file.created_on_ = resRow["created_on"];

1058 1059 1060 1061 1062 1063 1064
            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;
1065
                }
1066
                groups[table_file.table_id_] = table_schema;
1067
            }
1068
            table_file.dimension_ = groups[table_file.table_id_].dimension_;
S
starlord 已提交
1069
            table_file.index_file_size_ = groups[table_file.table_id_].index_file_size_;
1070
            table_file.nlist_ = groups[table_file.table_id_].nlist_;
S
starlord 已提交
1071
            table_file.metric_type_ = groups[table_file.table_id_].metric_type_;
Z
update  
zhiru 已提交
1072

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

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

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

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

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

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

S
starlord 已提交
1105 1106
            mysqlpp::Query filesToSearchQuery = connectionPtr->query();
            filesToSearchQuery
S
starlord 已提交
1107 1108 1109
                << "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 已提交
1110 1111 1112

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

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

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

S
starlord 已提交
1131 1132
                filesToSearchQuery << " AND "
                                   << "(" << idStr << ")";
X
xj.lin 已提交
1133 1134
            }
            // End
S
starlord 已提交
1135 1136 1137 1138
            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 已提交
1139 1140 1141 1142

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

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

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

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

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

1161 1162
            table_file.index_file_size_ = table_schema.index_file_size_;

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

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

S
starlord 已提交
1167 1168
            table_file.metric_type_ = table_schema.metric_type_;

X
xj.lin 已提交
1169 1170 1171 1172 1173 1174
            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 已提交
1175 1176
            table_file.file_size_ = resRow["file_size"];

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

            table_file.date_ = resRow["date"];

            table_file.dimension_ = table_schema.dimension_;

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

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

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

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

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

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

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

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

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

S
starlord 已提交
1228 1229 1230
            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 已提交
1231 1232 1233 1234 1235
                << 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 已提交
1236

1237
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::FilesToMerge: " << filesToMergeQuery.str();
1238

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

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

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

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

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

1260
            table_file.file_type_ = resRow["file_type"];
1261

S
starlord 已提交
1262 1263
            table_file.row_count_ = resRow["row_count"];

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

1266 1267
            table_file.index_file_size_ = table_schema.index_file_size_;

S
starlord 已提交
1268 1269
            table_file.engine_type_ = resRow["engine_type"];

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

S
starlord 已提交
1272 1273
            table_file.metric_type_ = table_schema.metric_type_;

S
starlord 已提交
1274 1275
            table_file.created_on_ = resRow["created_on"];

1276
            table_file.dimension_ = table_schema.dimension_;
Z
update  
zhiru 已提交
1277

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

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

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

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

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

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

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

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

S
starlord 已提交
1323 1324
            mysqlpp::Query getTableFileQuery = connectionPtr->query();
            getTableFileQuery
S
starlord 已提交
1325 1326 1327 1328 1329
                << "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) << ";";
1330 1331 1332 1333

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

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

        TableSchema table_schema;
        table_schema.table_id_ = table_id;
S
starlord 已提交
1338
        DescribeTable(table_schema);
1339

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

1344
            file_schema.id_ = resRow["id"];
Z
zhiru 已提交
1345

1346
            file_schema.table_id_ = table_id;
Z
update  
zhiru 已提交
1347

1348 1349
            file_schema.index_file_size_ = table_schema.index_file_size_;

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

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

S
starlord 已提交
1354 1355
            file_schema.metric_type_ = table_schema.metric_type_;

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

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

1362 1363 1364
            file_schema.file_size_ = resRow["file_size"];

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

1366
            file_schema.date_ = resRow["date"];
1367

S
starlord 已提交
1368 1369
            file_schema.created_on_ = resRow["created_on"];

1370
            file_schema.dimension_ = table_schema.dimension_;
Z
update  
zhiru 已提交
1371

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

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

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

S
starlord 已提交
1384
// TODO(myh): Support swap to cloud storage
S
starlord 已提交
1385 1386
Status
MySQLMetaImpl::Archive() {
S
starlord 已提交
1387
    auto& criterias = options_.archive_conf_.GetCriterias();
1388 1389 1390 1391
    if (criterias.empty()) {
        return Status::OK();
    }

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

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

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

S
starlord 已提交
1406
                mysqlpp::Query archiveQuery = connectionPtr->query();
S
starlord 已提交
1407 1408 1409 1410
                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 已提交
1411

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

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

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

1427 1428
            auto to_delete = (sum - limit * G);
            DiscardFiles(to_delete);
1429 1430

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

1434 1435
    return Status::OK();
}
Z
zhiru 已提交
1436

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

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

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

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

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

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

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

1468 1469
    return Status::OK();
}
1470

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

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

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

S
starlord 已提交
1488
            mysqlpp::Query discardFilesQuery = connectionPtr->query();
S
starlord 已提交
1489 1490 1491 1492
            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 已提交
1493

1494
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::DiscardFiles: " << discardFilesQuery.str();
1495

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

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

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

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

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

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

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

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

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

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

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

S
starlord 已提交
1553 1554 1555 1556
            // 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 已提交
1557

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

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

1562 1563 1564 1565
            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 已提交
1566
                }
1567 1568 1569 1570 1571 1572 1573 1574 1575
            } 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_);
1576 1577
            std::string file_size = std::to_string(file_schema.file_size_);
            std::string row_count = std::to_string(file_schema.row_count_);
1578 1579 1580
            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 已提交
1581

S
starlord 已提交
1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592
            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 << ";";
1593 1594 1595 1596 1597

            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 已提交
1598
                return HandleException("QUERY ERROR WHEN UPDATING TABLE FILE", updateTableFileQuery.error());
1599
            }
S
starlord 已提交
1600
        }  // Scoped Connection
1601

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

1607 1608
    return Status::OK();
}
1609

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

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

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

S
starlord 已提交
1621 1622 1623 1624
        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) << ";";
1625

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

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

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

1638 1639
    return Status::OK();
}
Z
zhiru 已提交
1640

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

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

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

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

S
starlord 已提交
1660 1661 1662 1663 1664 1665
                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"
                                      << ";";
1666

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

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

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

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

1681 1682 1683 1684 1685
                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_);
1686 1687
                std::string file_size = std::to_string(file_schema.file_size_);
                std::string row_count = std::to_string(file_schema.row_count_);
1688 1689 1690
                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 已提交
1691

S
starlord 已提交
1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702
                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 << ";";
1703 1704 1705 1706

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

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

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

1717 1718
    return Status::OK();
}
Z
fix  
zhiru 已提交
1719

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

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

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

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

S
starlord 已提交
1736
            mysqlpp::Query cleanUpFilesWithTTLQuery = connectionPtr->query();
S
starlord 已提交
1737 1738 1739
            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 已提交
1740

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

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

1745 1746
            TableFileSchema table_file;
            std::vector<std::string> idsToDelete;
1747

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

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

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

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

1761 1762
                utils::DeleteTableFilePath(options_, table_file);

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

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

                table_ids.insert(table_file.table_id_);
1768 1769 1770 1771
            }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1882 1883
    return Status::OK();
}
1884

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

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

S
starlord 已提交
1894
        mysqlpp::Query cleanUpQuery = connectionPtr->query();
S
starlord 已提交
1895 1896 1897 1898
        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 已提交
1899

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

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

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

1910
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::CleanUp: " << cleanUpQuery.str();
1911

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

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

1924 1925 1926
    return Status::OK();
}

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

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

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

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

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

S
starlord 已提交
1948
            mysqlpp::Query countQuery = connectionPtr->query();
S
starlord 已提交
1949 1950 1951 1952 1953
            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 已提交
1954

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

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

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

1969 1970 1971
    return Status::OK();
}

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

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

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

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

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

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