MySQLMetaImpl.cpp 83.6 KB
Newer Older
Z
update  
zhiru 已提交
1 2 3 4 5 6
/*******************************************************************************
 * Copyright 上海赜睿信息科技有限公司(Zilliz) - All Rights Reserved
 * Unauthorized copying of this file, via any medium is strictly prohibited.
 * Proprietary and confidential.
 ******************************************************************************/
#include "MySQLMetaImpl.h"
S
starlord 已提交
7 8 9
#include "db/IDGenerator.h"
#include "db/Utils.h"
#include "db/Log.h"
Z
update  
zhiru 已提交
10
#include "MetaConsts.h"
S
starlord 已提交
11
#include "db/Factories.h"
Z
update  
zhiru 已提交
12 13 14 15 16 17 18 19 20 21
#include "metrics/Metrics.h"

#include <unistd.h>
#include <sstream>
#include <iostream>
#include <boost/filesystem.hpp>
#include <chrono>
#include <fstream>
#include <regex>
#include <string>
Z
zhiru 已提交
22
#include <mutex>
Z
zhiru 已提交
23
#include <thread>
Z
update  
zhiru 已提交
24 25 26

#include "mysql++/mysql++.h"

27

Z
update  
zhiru 已提交
28 29 30 31 32
namespace zilliz {
namespace milvus {
namespace engine {
namespace meta {

33
using namespace mysqlpp;
Z
update  
zhiru 已提交
34

35
namespace {
Z
update  
zhiru 已提交
36

37 38 39 40
Status HandleException(const std::string &desc, std::exception &e) {
    ENGINE_LOG_ERROR << desc << ": " << e.what();
    return Status::DBTransactionError(desc, e.what());
}
Z
update  
zhiru 已提交
41

42 43
}

44 45 46 47 48 49 50
MySQLMetaImpl::MySQLMetaImpl(const DBMetaOptions &options_, const int &mode)
    : options_(options_),
      mode_(mode) {
    Initialize();
}

MySQLMetaImpl::~MySQLMetaImpl() {
S
starlord 已提交
51

52 53
}

54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
Status MySQLMetaImpl::NextTableId(std::string &table_id) {
    std::stringstream ss;
    SimpleIDGenerator g;
    ss << g.GetNextIDNumber();
    table_id = ss.str();
    return Status::OK();
}

Status MySQLMetaImpl::NextFileId(std::string &file_id) {
    std::stringstream ss;
    SimpleIDGenerator g;
    ss << g.GetNextIDNumber();
    file_id = ss.str();
    return Status::OK();
}

Status MySQLMetaImpl::Initialize() {
    if (!boost::filesystem::is_directory(options_.path)) {
        auto ret = boost::filesystem::create_directory(options_.path);
        if (!ret) {
            ENGINE_LOG_ERROR << "Failed to create db directory " << options_.path;
            return Status::DBTransactionError("Failed to create db directory", options_.path);
Z
update  
zhiru 已提交
76 77 78
        }
    }

79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
    std::string uri = options_.backend_uri;

    std::string dialectRegex = "(.*)";
    std::string usernameRegex = "(.*)";
    std::string passwordRegex = "(.*)";
    std::string hostRegex = "(.*)";
    std::string portRegex = "(.*)";
    std::string dbNameRegex = "(.*)";
    std::string uriRegexStr = dialectRegex + "\\:\\/\\/" +
        usernameRegex + "\\:" +
        passwordRegex + "\\@" +
        hostRegex + "\\:" +
        portRegex + "\\/" +
        dbNameRegex;
    std::regex uriRegex(uriRegexStr);
    std::smatch pieces_match;

    if (std::regex_match(uri, pieces_match, uriRegex)) {
        std::string dialect = pieces_match[1].str();
        std::transform(dialect.begin(), dialect.end(), dialect.begin(), ::tolower);
        if (dialect.find("mysql") == std::string::npos) {
            return Status::Error("URI's dialect is not MySQL");
101
        }
102 103 104 105 106 107
        std::string username = pieces_match[2].str();
        std::string password = pieces_match[3].str();
        std::string serverAddress = pieces_match[4].str();
        unsigned int port = 0;
        if (!pieces_match[5].str().empty()) {
            port = std::stoi(pieces_match[5].str());
108
        }
109
        std::string dbName = pieces_match[6].str();
110 111


112 113 114 115
        int threadHint = std::thread::hardware_concurrency();
        int maxPoolSize = threadHint == 0 ? 8 : threadHint;
        mysql_connection_pool_ =
            std::make_shared<MySQLConnectionPool>(dbName, username, password, serverAddress, port, maxPoolSize);
116

117 118
        ENGINE_LOG_DEBUG << "MySQL connection pool: maximum pool size = " << std::to_string(maxPoolSize);
        try {
119

120 121
            if (mode_ != Options::MODE::READ_ONLY) {
                CleanUp();
122 123
            }

124
            {
Z
update  
zhiru 已提交
125
                ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);
126

Z
update  
zhiru 已提交
127 128 129 130
                if (connectionPtr == nullptr) {
                    return Status::Error("Failed to connect to database server");
                }

131

132 133 134
                if (!connectionPtr->thread_aware()) {
                    ENGINE_LOG_ERROR << "MySQL++ wasn't built with thread awareness! Can't run without it.";
                    return Status::Error("MySQL++ wasn't built with thread awareness! Can't run without it.");
135
                }
136
                Query InitializeQuery = connectionPtr->query();
Z
update  
zhiru 已提交
137

138 139 140 141 142 143
                InitializeQuery << "CREATE TABLE IF NOT EXISTS Tables (" <<
                                "id BIGINT PRIMARY KEY AUTO_INCREMENT, " <<
                                "table_id VARCHAR(255) UNIQUE NOT NULL, " <<
                                "state INT NOT NULL, " <<
                                "dimension SMALLINT NOT NULL, " <<
                                "created_on BIGINT NOT NULL, " <<
S
starlord 已提交
144
                                "flag BIGINT DEFAULT 0 NOT NULL, " <<
S
starlord 已提交
145
                                "index_file_size BIGINT DEFAULT 1024 NOT NULL, " <<
146
                                "engine_type INT DEFAULT 1 NOT NULL, " <<
147 148
                                "nlist INT DEFAULT 16384 NOT NULL, " <<
                                "metric_type INT DEFAULT 1 NOT NULL);";
Z
zhiru 已提交
149

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

152 153
                if (!InitializeQuery.exec()) {
                    return Status::DBTransactionError("Initialization Error", InitializeQuery.error());
Z
update  
zhiru 已提交
154 155
                }

156 157 158 159 160 161
                InitializeQuery << "CREATE TABLE IF NOT EXISTS TableFiles (" <<
                                "id BIGINT PRIMARY KEY AUTO_INCREMENT, " <<
                                "table_id VARCHAR(255) NOT NULL, " <<
                                "engine_type INT DEFAULT 1 NOT NULL, " <<
                                "file_id VARCHAR(255) NOT NULL, " <<
                                "file_type INT DEFAULT 0 NOT NULL, " <<
162 163
                                "file_size BIGINT DEFAULT 0 NOT NULL, " <<
                                "row_count BIGINT DEFAULT 0 NOT NULL, " <<
164 165 166 167 168 169 170 171
                                "updated_time BIGINT NOT NULL, " <<
                                "created_on BIGINT NOT NULL, " <<
                                "date INT DEFAULT -1 NOT NULL);";

                ENGINE_LOG_DEBUG << "MySQLMetaImpl::Initialize: " << InitializeQuery.str();

                if (!InitializeQuery.exec()) {
                    return Status::DBTransactionError("Initialization Error", InitializeQuery.error());
172
                }
173
            } //Scoped Connection
Z
update  
zhiru 已提交
174

175
        } catch (const BadQuery &er) {
Z
update  
zhiru 已提交
176
            // Handle any query errors
177 178 179
            ENGINE_LOG_ERROR << "QUERY ERROR DURING INITIALIZATION" << ": " << er.what();
            return Status::DBTransactionError("QUERY ERROR DURING INITIALIZATION", er.what());
        } catch (const Exception &er) {
Z
update  
zhiru 已提交
180
            // Catch-all for any other MySQL++ exceptions
181 182
            ENGINE_LOG_ERROR << "GENERAL ERROR DURING INITIALIZATION" << ": " << er.what();
            return Status::DBTransactionError("GENERAL ERROR DURING INITIALIZATION", er.what());
Z
zhiru 已提交
183
        } catch (std::exception &e) {
184
            return HandleException("Encounter exception during initialization", e);
185
        }
186 187 188
    } else {
        ENGINE_LOG_ERROR << "Wrong URI format. URI = " << uri;
        return Status::Error("Wrong URI format");
Z
update  
zhiru 已提交
189
    }
S
starlord 已提交
190 191

    return Status::OK();
192 193 194 195 196 197
}

// PXU TODO: Temp solution. Will fix later
Status MySQLMetaImpl::DropPartitionsByDates(const std::string &table_id,
                                            const DatesT &dates) {
    if (dates.empty()) {
P
peng.xu 已提交
198 199 200
        return Status::OK();
    }

201 202 203 204 205 206
    TableSchema table_schema;
    table_schema.table_id_ = table_id;
    auto status = DescribeTable(table_schema);
    if (!status.ok()) {
        return status;
    }
Z
zhiru 已提交
207

208 209 210 211 212 213 214
    try {
        std::stringstream dateListSS;
        for (auto &date : dates) {
            dateListSS << std::to_string(date) << ", ";
        }
        std::string dateListStr = dateListSS.str();
        dateListStr = dateListStr.substr(0, dateListStr.size() - 2); //remove the last ", "
Z
update  
zhiru 已提交
215

216 217
        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);
Z
update  
zhiru 已提交
218

219 220 221
            if (connectionPtr == nullptr) {
                return Status::Error("Failed to connect to database server");
            }
Z
update  
zhiru 已提交
222

Z
update  
zhiru 已提交
223

224
            Query dropPartitionsByDatesQuery = connectionPtr->query();
225

226
            dropPartitionsByDatesQuery << "UPDATE TableFiles " <<
227 228
                                       "SET file_type = " << std::to_string(TableFileSchema::TO_DELETE) << "," <<
                                       "updated_time = " << utils::GetMicroSecTimeStamp() << " " <<
229 230
                                       "WHERE table_id = " << quote << table_id << " AND " <<
                                       "date in (" << dateListStr << ");";
Z
update  
zhiru 已提交
231

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

234 235 236 237
            if (!dropPartitionsByDatesQuery.exec()) {
                ENGINE_LOG_ERROR << "QUERY ERROR WHEN DROPPING PARTITIONS BY DATES";
                return Status::DBTransactionError("QUERY ERROR WHEN DROPPING PARTITIONS BY DATES",
                                                  dropPartitionsByDatesQuery.error());
Z
update  
zhiru 已提交
238
            }
239 240 241 242 243 244 245 246 247
        } //Scoped Connection
    } catch (const BadQuery &er) {
        // Handle any query errors
        ENGINE_LOG_ERROR << "QUERY ERROR WHEN DROPPING PARTITIONS BY DATES" << ": " << er.what();
        return Status::DBTransactionError("QUERY ERROR WHEN DROPPING PARTITIONS BY DATES", er.what());
    } catch (const Exception &er) {
        // Catch-all for any other MySQL++ exceptions
        ENGINE_LOG_ERROR << "GENERAL ERROR WHEN DROPPING PARTITIONS BY DATES" << ": " << er.what();
        return Status::DBTransactionError("GENERAL ERROR WHEN DROPPING PARTITIONS BY DATES", er.what());
Z
update  
zhiru 已提交
248
    }
249 250
    return Status::OK();
}
Z
update  
zhiru 已提交
251

252 253
Status MySQLMetaImpl::CreateTable(TableSchema &table_schema) {
    try {
Y
Yu Kun 已提交
254
        server::MetricCollector metric;
255 256
        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);
257

258 259 260
            if (connectionPtr == nullptr) {
                return Status::Error("Failed to connect to database server");
            }
Z
update  
zhiru 已提交
261

262
            Query createTableQuery = connectionPtr->query();
Z
update  
zhiru 已提交
263

264 265 266 267 268
            if (table_schema.table_id_.empty()) {
                NextTableId(table_schema.table_id_);
            } else {
                createTableQuery << "SELECT state FROM Tables " <<
                                 "WHERE table_id = " << quote << table_schema.table_id_ << ";";
Z
zhiru 已提交
269

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

272
                StoreQueryResult res = createTableQuery.store();
273

274 275 276 277 278 279 280 281 282
                if (res.num_rows() == 1) {
                    int state = res[0]["state"];
                    if (TableSchema::TO_DELETE == state) {
                        return Status::Error("Table already exists and it is in delete state, please wait a second");
                    } else {
                        return Status::AlreadyExist("Table already exists");
                    }
                }
            }
283

284 285
            table_schema.id_ = -1;
            table_schema.created_on_ = utils::GetMicroSecTimeStamp();
Z
update  
zhiru 已提交
286

287 288 289 290 291
            std::string id = "NULL"; //auto-increment
            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 已提交
292 293
            std::string flag = std::to_string(table_schema.flag_);
            std::string index_file_size = std::to_string(table_schema.index_file_size_);
294
            std::string engine_type = std::to_string(table_schema.engine_type_);
S
starlord 已提交
295 296
            std::string nlist = std::to_string(table_schema.nlist_);
            std::string metric_type = std::to_string(table_schema.metric_type_);
Z
update  
zhiru 已提交
297

298 299
            createTableQuery << "INSERT INTO Tables VALUES" <<
                             "(" << id << ", " << quote << table_id << ", " << state << ", " << dimension << ", " <<
S
starlord 已提交
300 301
                             created_on << ", " << flag << ", " << index_file_size << ", " << engine_type << ", " <<
                             nlist << ", " << metric_type << ");";
Z
update  
zhiru 已提交
302

303
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::CreateTable: " << createTableQuery.str();
304

305 306
            if (SimpleResult res = createTableQuery.execute()) {
                table_schema.id_ = res.insert_id(); //Might need to use SELECT LAST_INSERT_ID()?
307

308 309 310 311
                //Consume all results to avoid "Commands out of sync" error
            } else {
                ENGINE_LOG_ERROR << "Add Table Error";
                return Status::DBTransactionError("Add Table Error", createTableQuery.error());
312
            }
313
        } //Scoped Connection
314

315
        return utils::CreateTablePath(options_, table_schema.table_id_);
Z
update  
zhiru 已提交
316

317 318 319 320 321 322 323 324 325 326 327 328
    } catch (const BadQuery &er) {
        // Handle any query errors
        ENGINE_LOG_ERROR << "QUERY ERROR WHEN ADDING TABLE" << ": " << er.what();
        return Status::DBTransactionError("QUERY ERROR WHEN ADDING TABLE", er.what());
    } catch (const Exception &er) {
        // Catch-all for any other MySQL++ exceptions
        ENGINE_LOG_ERROR << "GENERAL ERROR WHEN ADDING TABLE" << ": " << er.what();
        return Status::DBTransactionError("GENERAL ERROR WHEN ADDING TABLE", er.what());
    } catch (std::exception &e) {
        return HandleException("Encounter exception when create table", e);
    }
}
329

330 331 332 333 334 335
Status MySQLMetaImpl::FilesByType(const std::string &table_id,
                                  const std::vector<int> &file_types,
                                  std::vector<std::string> &file_ids) {
    if(file_types.empty()) {
        return Status::Error("file types array is empty");
    }
Z
zhiru 已提交
336 337

    try {
338 339
        file_ids.clear();

Z
zhiru 已提交
340 341 342 343 344 345 346 347
        StoreQueryResult res;
        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);

            if (connectionPtr == nullptr) {
                return Status::Error("Failed to connect to database server");
            }

348 349 350 351 352 353 354 355
            std::string types;
            for(auto type : file_types) {
                if(!types.empty()) {
                    types += ",";
                }
                types += std::to_string(type);
            }

Z
zhiru 已提交
356 357
            Query hasNonIndexFilesQuery = connectionPtr->query();
            //since table_id is a unique column we just need to check whether it exists or not
358
            hasNonIndexFilesQuery << "SELECT file_id, file_type FROM TableFiles " <<
Z
fix  
zhiru 已提交
359
                                  "WHERE table_id = " << quote << table_id << " AND " <<
360
                                  "file_type in (" << types << ");";
Z
zhiru 已提交
361

362
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::FilesByType: " << hasNonIndexFilesQuery.str();
Z
zhiru 已提交
363 364 365 366

            res = hasNonIndexFilesQuery.store();
        } //Scoped Connection

367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407
        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;
            for (auto &resRow : res) {
                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) {
                    case (int) TableFileSchema::RAW:
                        raw_count++;
                        break;
                    case (int) TableFileSchema::NEW:
                        new_count++;
                        break;
                    case (int) TableFileSchema::NEW_MERGE:
                        new_merge_count++;
                        break;
                    case (int) TableFileSchema::NEW_INDEX:
                        new_index_count++;
                        break;
                    case (int) TableFileSchema::TO_INDEX:
                        to_index_count++;
                        break;
                    case (int) TableFileSchema::INDEX:
                        index_count++;
                        break;
                    case (int) TableFileSchema::BACKUP:
                        backup_count++;
                        break;
                    default:
                        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;
        }
Z
zhiru 已提交
408 409 410

    } catch (const BadQuery &er) {
        // Handle any query errors
411 412
        ENGINE_LOG_ERROR << "QUERY ERROR WHEN GET FILE BY TYPE" << ": " << er.what();
        return Status::DBTransactionError("QUERY ERROR WHEN GET FILE BY TYPE", er.what());
Z
zhiru 已提交
413 414
    } catch (const Exception &er) {
        // Catch-all for any other MySQL++ exceptions
415 416
        ENGINE_LOG_ERROR << "GENERAL ERROR WHEN GET FILE BY TYPE" << ": " << er.what();
        return Status::DBTransactionError("GENERAL ERROR WHEN GET FILE BY TYPE", er.what());
Z
zhiru 已提交
417 418
    }

419 420
    return Status::OK();
}
421

422
Status MySQLMetaImpl::UpdateTableIndexParam(const std::string &table_id, const TableIndex& index) {
S
starlord 已提交
423
    try {
Y
Yu Kun 已提交
424
        server::MetricCollector metric;
S
starlord 已提交
425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457

        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);

            if (connectionPtr == nullptr) {
                return Status::Error("Failed to connect to database server");
            }

            Query updateTableIndexParamQuery = connectionPtr->query();
            updateTableIndexParamQuery << "SELECT id, state, dimension, created_on " <<
                                       "FROM Tables " <<
                                       "WHERE table_id = " << quote << table_id << " AND " <<
                                       "state <> " << std::to_string(TableSchema::TO_DELETE) << ";";

            ENGINE_LOG_DEBUG << "MySQLMetaImpl::UpdateTableIndexParam: " << updateTableIndexParamQuery.str();

            StoreQueryResult res = updateTableIndexParamQuery.store();

            if (res.num_rows() == 1) {
                const Row &resRow = res[0];

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

                updateTableIndexParamQuery << "UPDATE Tables " <<
                                           "SET id = " << id << ", " <<
                                           "state = " << state << ", " <<
                                           "dimension = " << dimension << ", " <<
                                           "created_on = " << created_on << ", " <<
                                           "engine_type_ = " << index.engine_type_ << ", " <<
                                           "nlist = " << index.nlist_ << ", " <<
S
starlord 已提交
458
                                           "metric_type = " << index.metric_type_ << " " <<
S
starlord 已提交
459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484
                                           "WHERE id = " << quote << table_id << ";";

                ENGINE_LOG_DEBUG << "MySQLMetaImpl::UpdateTableIndexParam: " << updateTableIndexParamQuery.str();


                if (!updateTableIndexParamQuery.exec()) {
                    ENGINE_LOG_ERROR << "QUERY ERROR WHEN UPDATING TABLE INDEX PARAM";
                    return Status::DBTransactionError("QUERY ERROR WHEN UPDATING TABLE INDEX PARAM",
                                                      updateTableIndexParamQuery.error());
                }
            } else {
                return Status::NotFound("Table " + table_id + " not found");
            }

        } //Scoped Connection

    } catch (const BadQuery &er) {
        // Handle any query errors
        ENGINE_LOG_ERROR << "QUERY ERROR WHEN UPDATING TABLE INDEX PARAM" << ": " << er.what();
        return Status::DBTransactionError("QUERY ERROR WHEN UPDATING TABLE INDEX PARAM", er.what());
    } catch (const Exception &er) {
        // Catch-all for any other MySQL++ exceptions
        ENGINE_LOG_ERROR << "GENERAL ERROR WHEN UPDATING TABLE INDEX PARAM" << ": " << er.what();
        return Status::DBTransactionError("GENERAL ERROR WHEN UPDATING TABLE INDEX PARAM", er.what());
    }

485 486 487
    return Status::OK();
}

S
starlord 已提交
488 489
Status MySQLMetaImpl::UpdateTableFlag(const std::string &table_id, int64_t flag) {
    try {
Y
Yu Kun 已提交
490
        server::MetricCollector metric;
S
starlord 已提交
491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527

        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);

            if (connectionPtr == nullptr) {
                return Status::Error("Failed to connect to database server");
            }

            Query updateTableFlagQuery = connectionPtr->query();
            updateTableFlagQuery << "UPDATE Tables " <<
                                 "SET flag = " << flag << " " <<
                                 "WHERE id = " << quote << table_id << ";";

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


            if (!updateTableFlagQuery.exec()) {
                ENGINE_LOG_ERROR << "QUERY ERROR WHEN UPDATING TABLE FLAG";
                return Status::DBTransactionError("QUERY ERROR WHEN UPDATING TABLE FLAG",
                                                  updateTableFlagQuery.error());
            }

        } //Scoped Connection

    } catch (const BadQuery &er) {
        // Handle any query errors
        ENGINE_LOG_ERROR << "QUERY ERROR WHEN UPDATING TABLE FLAG" << ": " << er.what();
        return Status::DBTransactionError("QUERY ERROR WHEN UPDATING TABLE FLAG", er.what());
    } catch (const Exception &er) {
        // Catch-all for any other MySQL++ exceptions
        ENGINE_LOG_ERROR << "GENERAL ERROR WHEN UPDATING TABLE FLAG" << ": " << er.what();
        return Status::DBTransactionError("GENERAL ERROR WHEN UPDATING TABLE FLAG", er.what());
    }

    return Status::OK();
}

528
Status MySQLMetaImpl::DescribeTableIndex(const std::string &table_id, TableIndex& index) {
S
starlord 已提交
529
    try {
Y
Yu Kun 已提交
530
        server::MetricCollector metric;
531

S
starlord 已提交
532 533
        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);
534

S
starlord 已提交
535 536 537 538 539 540 541 542 543
            if (connectionPtr == nullptr) {
                return Status::Error("Failed to connect to database server");
            }

            Query describeTableIndexQuery = connectionPtr->query();
            describeTableIndexQuery << "SELECT engine_type, nlist, index_file_size, metric_type " <<
                                       "FROM Tables " <<
                                       "WHERE table_id = " << quote << table_id << " AND " <<
                                       "state <> " << std::to_string(TableSchema::TO_DELETE) << ";";
Z
update  
zhiru 已提交
544

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

S
starlord 已提交
547 548 549 550 551 552 553 554 555 556 557 558 559
            StoreQueryResult res = describeTableIndexQuery.store();

            if (res.num_rows() == 1) {
                const Row &resRow = res[0];

                index.engine_type_ = resRow["engine_type"];
                index.nlist_ = resRow["nlist"];
                index.metric_type_ = resRow["metric_type"];
            } else {
                return Status::NotFound("Table " + table_id + " not found");
            }

        } //Scoped Connection
Z
update  
zhiru 已提交
560

S
starlord 已提交
561 562 563 564 565 566 567 568 569 570 571 572 573 574 575
    } catch (const BadQuery &er) {
        // Handle any query errors
        ENGINE_LOG_ERROR << "QUERY ERROR WHEN DESCRIBE TABLE INDEX" << ": " << er.what();
        return Status::DBTransactionError("QUERY ERROR WHEN DESCRIBE TABLE INDEX", er.what());
    } catch (const Exception &er) {
        // Catch-all for any other MySQL++ exceptions
        ENGINE_LOG_ERROR << "GENERAL ERROR WHEN DESCRIBE TABLE INDEX" << ": " << er.what();
        return Status::DBTransactionError("GENERAL ERROR WHEN DESCRIBE TABLE INDEX", er.what());
    }

    return Status::OK();
}

Status MySQLMetaImpl::DropTableIndex(const std::string &table_id) {
    try {
Y
Yu Kun 已提交
576
        server::MetricCollector metric;
Z
update  
zhiru 已提交
577

578 579
        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);
580

581 582 583
            if (connectionPtr == nullptr) {
                return Status::Error("Failed to connect to database server");
            }
584

S
starlord 已提交
585 586
            Query dropTableIndexQuery = connectionPtr->query();

587
            //soft delete index files
S
starlord 已提交
588 589 590 591 592 593 594 595 596 597 598 599 600 601
            dropTableIndexQuery << "UPDATE TableFiles " <<
                                "SET file_type = " << std::to_string(TableFileSchema::TO_DELETE) << "," <<
                                "updated_time = " << utils::GetMicroSecTimeStamp() << " " <<
                                "WHERE table_id = " << quote << table_id << " AND " <<
                                "file_type = " << std::to_string(TableFileSchema::INDEX) << ";";

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

            if (!dropTableIndexQuery.exec()) {
                ENGINE_LOG_ERROR << "QUERY ERROR WHEN DROP TABLE INDEX";
                return Status::DBTransactionError("QUERY ERROR WHEN DROP TABLE INDEX",
                                                  dropTableIndexQuery.error());
            }

602
            //set all backup file to raw
S
starlord 已提交
603 604 605 606 607 608 609 610 611
            dropTableIndexQuery << "UPDATE TableFiles " <<
                                "SET file_type = " << std::to_string(TableFileSchema::RAW) << "," <<
                                "updated_time = " << utils::GetMicroSecTimeStamp() << " " <<
                                "WHERE table_id = " << quote << table_id << " AND " <<
                                "file_type = " << std::to_string(TableFileSchema::BACKUP) << ";";

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

            if (!dropTableIndexQuery.exec()) {
612 613 614 615 616 617 618 619 620 621 622 623 624 625 626
                ENGINE_LOG_ERROR << "QUERY ERROR WHEN DROP TABLE INDEX";
                return Status::DBTransactionError("QUERY ERROR WHEN DROP TABLE INDEX",
                                                  dropTableIndexQuery.error());
            }

            //set table index type to raw
            dropTableIndexQuery << "UPDATE 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 = " << quote << table_id << ";";

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

            if (!dropTableIndexQuery.exec()) {
S
starlord 已提交
627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642
                ENGINE_LOG_ERROR << "QUERY ERROR WHEN DROP TABLE INDEX";
                return Status::DBTransactionError("QUERY ERROR WHEN DROP TABLE INDEX",
                                                  dropTableIndexQuery.error());
            }

        } //Scoped Connection

    } catch (const BadQuery &er) {
        // Handle any query errors
        ENGINE_LOG_ERROR << "QUERY ERROR WHEN DROP TABLE INDEX" << ": " << er.what();
        return Status::DBTransactionError("QUERY ERROR WHEN DROP TABLE INDEX", er.what());
    } catch (const Exception &er) {
        // Catch-all for any other MySQL++ exceptions
        ENGINE_LOG_ERROR << "GENERAL ERROR WHEN DROP TABLE INDEX" << ": " << er.what();
        return Status::DBTransactionError("GENERAL ERROR WHEN DROP TABLE INDEX", er.what());
    }
643

S
starlord 已提交
644 645
    return Status::OK();
}
Z
update  
zhiru 已提交
646

S
starlord 已提交
647 648
Status MySQLMetaImpl::DeleteTable(const std::string &table_id) {
    try {
Y
Yu Kun 已提交
649
        server::MetricCollector metric;
S
starlord 已提交
650 651
        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);
Z
zhiru 已提交
652

S
starlord 已提交
653 654 655
            if (connectionPtr == nullptr) {
                return Status::Error("Failed to connect to database server");
            }
Z
zhiru 已提交
656

657 658 659 660 661 662
            //soft delete table
            Query deleteTableQuery = connectionPtr->query();
//
            deleteTableQuery << "UPDATE Tables " <<
                             "SET state = " << std::to_string(TableSchema::TO_DELETE) << " " <<
                             "WHERE table_id = " << quote << table_id << ";";
Z
update  
zhiru 已提交
663

664
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::DeleteTable: " << deleteTableQuery.str();
665

666 667 668 669
            if (!deleteTableQuery.exec()) {
                ENGINE_LOG_ERROR << "QUERY ERROR WHEN DELETING TABLE";
                return Status::DBTransactionError("QUERY ERROR WHEN DELETING TABLE", deleteTableQuery.error());
            }
670

671
        } //Scoped Connection
Z
zhiru 已提交
672

673 674 675
        if (mode_ == Options::MODE::CLUSTER) {
            DeleteTableFiles(table_id);
        }
Z
update  
zhiru 已提交
676

677 678 679 680 681 682 683 684 685
    } catch (const BadQuery &er) {
        // Handle any query errors
        ENGINE_LOG_ERROR << "GENERAL ERROR WHEN DELETING TABLE" << ": " << er.what();
        return Status::DBTransactionError("QUERY ERROR WHEN DELETING TABLE", er.what());
    } catch (const Exception &er) {
        // Catch-all for any other MySQL++ exceptions
        ENGINE_LOG_ERROR << "GENERAL ERROR WHEN DELETING TABLE" << ": " << er.what();
        return Status::DBTransactionError("GENERAL ERROR WHEN DELETING TABLE", er.what());
    }
Z
update  
zhiru 已提交
686

687 688
    return Status::OK();
}
Z
update  
zhiru 已提交
689

690 691
Status MySQLMetaImpl::DeleteTableFiles(const std::string &table_id) {
    try {
Y
Yu Kun 已提交
692
        server::MetricCollector metric;
693 694 695 696 697 698
        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);

            if (connectionPtr == nullptr) {
                return Status::Error("Failed to connect to database server");
            }
699

700 701 702 703 704 705 706 707
            //soft delete table files
            Query deleteTableFilesQuery = connectionPtr->query();
            //
            deleteTableFilesQuery << "UPDATE TableFiles " <<
                                  "SET file_type = " << std::to_string(TableFileSchema::TO_DELETE) << ", " <<
                                  "updated_time = " << std::to_string(utils::GetMicroSecTimeStamp()) << " " <<
                                  "WHERE table_id = " << quote << table_id << " AND " <<
                                  "file_type <> " << std::to_string(TableFileSchema::TO_DELETE) << ";";
708

709
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::DeleteTableFiles: " << deleteTableFilesQuery.str();
710

711 712 713
            if (!deleteTableFilesQuery.exec()) {
                ENGINE_LOG_ERROR << "QUERY ERROR WHEN DELETING TABLE FILES";
                return Status::DBTransactionError("QUERY ERROR WHEN DELETING TABLE", deleteTableFilesQuery.error());
714
            }
715 716 717 718 719 720 721 722 723
        } //Scoped Connection
    } catch (const BadQuery &er) {
        // Handle any query errors
        ENGINE_LOG_ERROR << "QUERY ERROR WHEN DELETING TABLE FILES" << ": " << er.what();
        return Status::DBTransactionError("QUERY ERROR WHEN DELETING TABLE FILES", er.what());
    } catch (const Exception &er) {
        // Catch-all for any other MySQL++ exceptions
        ENGINE_LOG_ERROR << "GENERAL ERROR WHEN DELETING TABLE FILES" << ": " << er.what();
        return Status::DBTransactionError("GENERAL ERROR WHEN DELETING TABLE FILES", er.what());
Z
update  
zhiru 已提交
724 725
    }

726 727
    return Status::OK();
}
Z
zhiru 已提交
728

729 730
Status MySQLMetaImpl::DescribeTable(TableSchema &table_schema) {
    try {
Y
Yu Kun 已提交
731
        server::MetricCollector metric;
732 733 734
        StoreQueryResult res;
        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);
735

736 737 738
            if (connectionPtr == nullptr) {
                return Status::Error("Failed to connect to database server");
            }
Z
zhiru 已提交
739

740
            Query describeTableQuery = connectionPtr->query();
S
starlord 已提交
741
            describeTableQuery << "SELECT id, state, dimension, engine_type, nlist, index_file_size, metric_type " <<
742 743 744 745 746
                               "FROM Tables " <<
                               "WHERE table_id = " << quote << table_schema.table_id_ << " " <<
                               "AND state <> " << std::to_string(TableSchema::TO_DELETE) << ";";

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

748 749
            res = describeTableQuery.store();
        } //Scoped Connection
750

751 752
        if (res.num_rows() == 1) {
            const Row &resRow = res[0];
753

754
            table_schema.id_ = resRow["id"]; //implicit conversion
Z
update  
zhiru 已提交
755

S
starlord 已提交
756 757
            table_schema.state_ = resRow["state"];

758
            table_schema.dimension_ = resRow["dimension"];
759

760 761
            table_schema.index_file_size_ = resRow["index_file_size"];

762
            table_schema.engine_type_ = resRow["engine_type"];
S
starlord 已提交
763 764 765 766

            table_schema.nlist_ = resRow["nlist"];

            table_schema.metric_type_ = resRow["metric_type"];
767 768
        } else {
            return Status::NotFound("Table " + table_schema.table_id_ + " not found");
769
        }
Z
update  
zhiru 已提交
770

771 772 773 774 775 776 777 778
    } catch (const BadQuery &er) {
        // Handle any query errors
        ENGINE_LOG_ERROR << "QUERY ERROR WHEN DESCRIBING TABLE" << ": " << er.what();
        return Status::DBTransactionError("QUERY ERROR WHEN DESCRIBING TABLE", er.what());
    } catch (const Exception &er) {
        // Catch-all for any other MySQL++ exceptions
        ENGINE_LOG_ERROR << "GENERAL ERROR WHEN DESCRIBING TABLE" << ": " << er.what();
        return Status::DBTransactionError("GENERAL ERROR WHEN DESCRIBING TABLE", er.what());
Z
update  
zhiru 已提交
779 780
    }

781 782
    return Status::OK();
}
Z
zhiru 已提交
783

784 785
Status MySQLMetaImpl::HasTable(const std::string &table_id, bool &has_or_not) {
    try {
Y
Yu Kun 已提交
786
        server::MetricCollector metric;
787 788 789
        StoreQueryResult res;
        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);
Z
update  
zhiru 已提交
790

791 792 793
            if (connectionPtr == nullptr) {
                return Status::Error("Failed to connect to database server");
            }
Z
update  
zhiru 已提交
794

795 796 797 798 799 800 801
            Query hasTableQuery = connectionPtr->query();
            //since table_id is a unique column we just need to check whether it exists or not
            hasTableQuery << "SELECT EXISTS " <<
                          "(SELECT 1 FROM Tables " <<
                          "WHERE table_id = " << quote << table_id << " " <<
                          "AND state <> " << std::to_string(TableSchema::TO_DELETE) << ") " <<
                          "AS " << quote << "check" << ";";
Z
update  
zhiru 已提交
802

803
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::HasTable: " << hasTableQuery.str();
804

805 806
            res = hasTableQuery.store();
        } //Scoped Connection
807

808 809
        int check = res[0]["check"];
        has_or_not = (check == 1);
810

811 812 813 814 815 816 817 818 819
    } catch (const BadQuery &er) {
        // Handle any query errors
        ENGINE_LOG_ERROR << "QUERY ERROR WHEN CHECKING IF TABLE EXISTS" << ": " << er.what();
        return Status::DBTransactionError("QUERY ERROR WHEN CHECKING IF TABLE EXISTS", er.what());
    } catch (const Exception &er) {
        // Catch-all for any other MySQL++ exceptions
        ENGINE_LOG_ERROR << "GENERAL ERROR WHEN CHECKING IF TABLE EXISTS" << ": " << er.what();
        return Status::DBTransactionError("GENERAL ERROR WHEN CHECKING IF TABLE EXISTS", er.what());
    }
820

821 822
    return Status::OK();
}
823

824 825
Status MySQLMetaImpl::AllTables(std::vector<TableSchema> &table_schema_array) {
    try {
Y
Yu Kun 已提交
826
        server::MetricCollector metric;
827 828 829
        StoreQueryResult res;
        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);
830

831 832
            if (connectionPtr == nullptr) {
                return Status::Error("Failed to connect to database server");
833
            }
Z
update  
zhiru 已提交
834

835
            Query allTablesQuery = connectionPtr->query();
S
starlord 已提交
836
            allTablesQuery << "SELECT id, table_id, dimension, engine_type, nlist, index_file_size, metric_type " <<
837 838
                           "FROM Tables " <<
                           "WHERE state <> " << std::to_string(TableSchema::TO_DELETE) << ";";
Z
zhiru 已提交
839

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

842 843
            res = allTablesQuery.store();
        } //Scoped Connection
844

845 846
        for (auto &resRow : res) {
            TableSchema table_schema;
Z
update  
zhiru 已提交
847

848
            table_schema.id_ = resRow["id"]; //implicit conversion
849

850 851 852
            std::string table_id;
            resRow["table_id"].to_string(table_id);
            table_schema.table_id_ = table_id;
853

854
            table_schema.dimension_ = resRow["dimension"];
855

856 857
            table_schema.index_file_size_ = resRow["index_file_size"];

858
            table_schema.engine_type_ = resRow["engine_type"];
859

S
starlord 已提交
860 861 862 863
            table_schema.nlist_ = resRow["nlist"];

            table_schema.metric_type_ = resRow["metric_type"];

864 865 866 867 868 869 870 871 872 873 874
            table_schema_array.emplace_back(table_schema);
        }
    } catch (const BadQuery &er) {
        // Handle any query errors
        ENGINE_LOG_ERROR << "QUERY ERROR WHEN DESCRIBING ALL TABLES" << ": " << er.what();
        return Status::DBTransactionError("QUERY ERROR WHEN DESCRIBING ALL TABLES", er.what());
    } catch (const Exception &er) {
        // Catch-all for any other MySQL++ exceptions
        ENGINE_LOG_ERROR << "GENERAL ERROR WHEN DESCRIBING ALL TABLES" << ": " << er.what();
        return Status::DBTransactionError("GENERAL ERROR WHEN DESCRIBING ALL TABLES", er.what());
    }
Z
update  
zhiru 已提交
875

876 877
    return Status::OK();
}
878

879 880
Status MySQLMetaImpl::CreateTableFile(TableFileSchema &file_schema) {
    if (file_schema.date_ == EmptyDate) {
881
        file_schema.date_ = utils::GetDate();
882 883 884 885 886 887 888
    }
    TableSchema table_schema;
    table_schema.table_id_ = file_schema.table_id_;
    auto status = DescribeTable(table_schema);
    if (!status.ok()) {
        return status;
    }
889

890
    try {
Y
Yu Kun 已提交
891
        server::MetricCollector metric;
892 893 894

        NextFileId(file_schema.file_id_);
        file_schema.dimension_ = table_schema.dimension_;
895 896
        file_schema.file_size_ = 0;
        file_schema.row_count_ = 0;
897 898
        file_schema.created_on_ = utils::GetMicroSecTimeStamp();
        file_schema.updated_time_ = file_schema.created_on_;
899
        file_schema.index_file_size_ = table_schema.index_file_size_;
900
        file_schema.engine_type_ = table_schema.engine_type_;
S
starlord 已提交
901 902
        file_schema.nlist_ = table_schema.nlist_;
        file_schema.metric_type_ = table_schema.metric_type_;
903 904 905 906 907 908 909
        utils::GetTableFilePath(options_, file_schema);

        std::string id = "NULL"; //auto-increment
        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 已提交
910
        std::string file_size = std::to_string(file_schema.file_size_);
911
        std::string row_count = std::to_string(file_schema.row_count_);
912 913 914 915 916 917
        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_);

        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);
Z
update  
zhiru 已提交
918

919 920 921
            if (connectionPtr == nullptr) {
                return Status::Error("Failed to connect to database server");
            }
Z
update  
zhiru 已提交
922

923
            Query createTableFileQuery = connectionPtr->query();
924

925 926
            createTableFileQuery << "INSERT INTO TableFiles VALUES" <<
                                 "(" << id << ", " << quote << table_id << ", " << engine_type << ", " <<
S
starlord 已提交
927 928
                                 quote << file_id << ", " << file_type << ", " << file_size << ", " <<
                                 row_count << ", " << updated_time << ", " << created_on << ", " << date << ");";
929 930 931 932 933 934 935 936 937 938

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

            if (SimpleResult res = createTableFileQuery.execute()) {
                file_schema.id_ = res.insert_id(); //Might need to use SELECT LAST_INSERT_ID()?

                //Consume all results to avoid "Commands out of sync" error
            } else {
                ENGINE_LOG_ERROR << "QUERY ERROR WHEN ADDING TABLE FILE";
                return Status::DBTransactionError("Add file Error", createTableFileQuery.error());
939
            }
940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955
        } // Scoped Connection

        return utils::CreateTableFilePath(options_, file_schema);

    } catch (const BadQuery &er) {
        // Handle any query errors
        ENGINE_LOG_ERROR << "QUERY ERROR WHEN ADDING TABLE FILE" << ": " << er.what();
        return Status::DBTransactionError("QUERY ERROR WHEN ADDING TABLE FILE", er.what());
    } catch (const Exception &er) {
        // Catch-all for any other MySQL++ exceptions
        ENGINE_LOG_ERROR << "GENERAL ERROR WHEN ADDING TABLE FILE" << ": " << er.what();
        return Status::DBTransactionError("GENERAL ERROR WHEN ADDING TABLE FILE", er.what());
    } catch (std::exception &ex) {
        return HandleException("Encounter exception when create table file", ex);
    }
}
956

957 958
Status MySQLMetaImpl::FilesToIndex(TableFilesSchema &files) {
    files.clear();
959

960
    try {
Y
Yu Kun 已提交
961
        server::MetricCollector metric;
962 963 964 965 966 967 968
        StoreQueryResult res;
        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);

            if (connectionPtr == nullptr) {
                return Status::Error("Failed to connect to database server");
            }
969

970
            Query filesToIndexQuery = connectionPtr->query();
S
starlord 已提交
971
            filesToIndexQuery << "SELECT id, table_id, engine_type, file_id, file_type, file_size, row_count, date, created_on " <<
972 973
                              "FROM TableFiles " <<
                              "WHERE file_type = " << std::to_string(TableFileSchema::TO_INDEX) << ";";
974

975
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::FilesToIndex: " << filesToIndexQuery.str();
976

977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997
            res = filesToIndexQuery.store();
        } //Scoped Connection

        std::map<std::string, TableSchema> groups;
        TableFileSchema table_file;
        for (auto &resRow : res) {

            table_file.id_ = resRow["id"]; //implicit conversion

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

1000
            table_file.row_count_ = resRow["row_count"];
1001 1002 1003

            table_file.date_ = resRow["date"];

S
starlord 已提交
1004 1005
            table_file.created_on_ = resRow["created_on"];

1006 1007 1008 1009 1010 1011 1012
            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;
1013
                }
1014
                groups[table_file.table_id_] = table_schema;
1015 1016

            }
1017
            table_file.dimension_ = groups[table_file.table_id_].dimension_;
S
starlord 已提交
1018
            table_file.index_file_size_ = groups[table_file.table_id_].index_file_size_;
1019
            table_file.nlist_ = groups[table_file.table_id_].nlist_;
S
starlord 已提交
1020
            table_file.metric_type_ = groups[table_file.table_id_].metric_type_;
Z
update  
zhiru 已提交
1021

1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033
            utils::GetTableFilePath(options_, table_file);

            files.push_back(table_file);
        }
    } catch (const BadQuery &er) {
        // Handle any query errors
        ENGINE_LOG_ERROR << "QUERY ERROR WHEN FINDING TABLE FILES TO INDEX" << ": " << er.what();
        return Status::DBTransactionError("QUERY ERROR WHEN FINDING TABLE FILES TO INDEX", er.what());
    } catch (const Exception &er) {
        // Catch-all for any other MySQL++ exceptions
        ENGINE_LOG_ERROR << "GENERAL ERROR WHEN FINDING TABLE FILES TO INDEX" << ": " << er.what();
        return Status::DBTransactionError("GENERAL ERROR WHEN FINDING TABLE FILES TO INDEX", er.what());
Z
update  
zhiru 已提交
1034 1035
    }

1036 1037 1038
    return Status::OK();
}

X
xj.lin 已提交
1039 1040 1041 1042 1043 1044 1045
Status MySQLMetaImpl::FilesToSearch(const std::string &table_id,
                                    const std::vector<size_t> &ids,
                                    const DatesT &partition,
                                    DatePartionedTableFilesSchema &files) {
    files.clear();

    try {
Y
Yu Kun 已提交
1046
        server::MetricCollector metric;
X
xj.lin 已提交
1047 1048 1049 1050 1051 1052 1053 1054 1055
        StoreQueryResult res;
        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);

            if (connectionPtr == nullptr) {
                return Status::Error("Failed to connect to database server");
            }

            Query filesToSearchQuery = connectionPtr->query();
S
starlord 已提交
1056
            filesToSearchQuery << "SELECT id, table_id, engine_type, file_id, file_type, file_size, row_count, date " <<
X
xj.lin 已提交
1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108
                               "FROM TableFiles " <<
                               "WHERE table_id = " << quote << table_id;

            if (!partition.empty()) {
                std::stringstream partitionListSS;
                for (auto &date : partition) {
                    partitionListSS << std::to_string(date) << ", ";
                }
                std::string partitionListStr = partitionListSS.str();

                partitionListStr = partitionListStr.substr(0, partitionListStr.size() - 2); //remove the last ", "
                filesToSearchQuery << " AND " << "date IN (" << partitionListStr << ")";
            }

            if (!ids.empty()) {
                std::stringstream idSS;
                for (auto &id : ids) {
                    idSS << "id = " << std::to_string(id) << " OR ";
                }
                std::string idStr = idSS.str();
                idStr = idStr.substr(0, idStr.size() - 4); //remove the last " OR "

                filesToSearchQuery  << " AND " << "(" << idStr << ")";

            }
            // End
            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) << ");";

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

            res = filesToSearchQuery.store();
        } //Scoped Connection

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

        TableFileSchema table_file;
        for (auto &resRow : res) {

            table_file.id_ = resRow["id"]; //implicit conversion

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

1109 1110
            table_file.index_file_size_ = table_schema.index_file_size_;

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

S
starlord 已提交
1113 1114
            table_file.nlist_ = table_schema.nlist_;

S
starlord 已提交
1115 1116
            table_file.metric_type_ = table_schema.metric_type_;

X
xj.lin 已提交
1117 1118 1119 1120 1121 1122
            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 已提交
1123 1124
            table_file.file_size_ = resRow["file_size"];

1125
            table_file.row_count_ = resRow["row_count"];
X
xj.lin 已提交
1126 1127 1128 1129 1130 1131

            table_file.date_ = resRow["date"];

            table_file.dimension_ = table_schema.dimension_;

            utils::GetTableFilePath(options_, table_file);
1132

1133 1134 1135
            auto dateItr = files.find(table_file.date_);
            if (dateItr == files.end()) {
                files[table_file.date_] = TableFilesSchema();
1136 1137
            }

1138
            files[table_file.date_].push_back(table_file);
1139
        }
1140 1141 1142 1143 1144 1145 1146 1147
    } catch (const BadQuery &er) {
        // Handle any query errors
        ENGINE_LOG_ERROR << "QUERY ERROR WHEN FINDING TABLE FILES TO SEARCH" << ": " << er.what();
        return Status::DBTransactionError("QUERY ERROR WHEN FINDING TABLE FILES TO SEARCH", er.what());
    } catch (const Exception &er) {
        // Catch-all for any other MySQL++ exceptions
        ENGINE_LOG_ERROR << "GENERAL ERROR WHEN FINDING TABLE FILES TO SEARCH" << ": " << er.what();
        return Status::DBTransactionError("GENERAL ERROR WHEN FINDING TABLE FILES TO SEARCH", er.what());
Z
update  
zhiru 已提交
1148 1149
    }

1150 1151
    return Status::OK();
}
Z
update  
zhiru 已提交
1152

1153 1154 1155
Status MySQLMetaImpl::FilesToMerge(const std::string &table_id,
                                   DatePartionedTableFilesSchema &files) {
    files.clear();
Z
update  
zhiru 已提交
1156

1157
    try {
Y
Yu Kun 已提交
1158
        server::MetricCollector metric;
S
starlord 已提交
1159 1160 1161 1162 1163 1164 1165 1166 1167

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

1168 1169 1170
        StoreQueryResult res;
        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);
Z
update  
zhiru 已提交
1171

1172 1173 1174
            if (connectionPtr == nullptr) {
                return Status::Error("Failed to connect to database server");
            }
Z
update  
zhiru 已提交
1175

1176
            Query filesToMergeQuery = connectionPtr->query();
S
starlord 已提交
1177
            filesToMergeQuery << "SELECT id, table_id, file_id, file_type, file_size, row_count, date, engine_type, created_on " <<
1178 1179 1180
                              "FROM TableFiles " <<
                              "WHERE table_id = " << quote << table_id << " AND " <<
                              "file_type = " << std::to_string(TableFileSchema::RAW) << " " <<
1181
                              "ORDER BY row_count DESC" << ";";
Z
update  
zhiru 已提交
1182

1183
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::FilesToMerge: " << filesToMergeQuery.str();
1184

1185 1186
            res = filesToMergeQuery.store();
        } //Scoped Connection
1187

1188
        for (auto &resRow : res) {
S
starlord 已提交
1189 1190 1191 1192 1193
            TableFileSchema table_file;
            table_file.file_size_ = resRow["file_size"];
            if(table_file.file_size_ >= table_schema.index_file_size_) {
                continue;//skip large file
            }
Z
update  
zhiru 已提交
1194

1195
            table_file.id_ = resRow["id"]; //implicit conversion
1196

1197 1198 1199
            std::string table_id_str;
            resRow["table_id"].to_string(table_id_str);
            table_file.table_id_ = table_id_str;
Z
update  
zhiru 已提交
1200

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

1205
            table_file.file_type_ = resRow["file_type"];
1206

S
starlord 已提交
1207 1208
            table_file.row_count_ = resRow["row_count"];

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

1211 1212
            table_file.index_file_size_ = table_schema.index_file_size_;

S
starlord 已提交
1213 1214
            table_file.engine_type_ = resRow["engine_type"];

S
starlord 已提交
1215 1216
            table_file.nlist_ = table_schema.nlist_;

S
starlord 已提交
1217 1218
            table_file.metric_type_ = table_schema.metric_type_;

S
starlord 已提交
1219 1220
            table_file.created_on_ = resRow["created_on"];

1221
            table_file.dimension_ = table_schema.dimension_;
Z
update  
zhiru 已提交
1222

1223
            utils::GetTableFilePath(options_, table_file);
Z
update  
zhiru 已提交
1224

1225 1226 1227
            auto dateItr = files.find(table_file.date_);
            if (dateItr == files.end()) {
                files[table_file.date_] = TableFilesSchema();
1228
            }
1229 1230

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

1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249
    } catch (const BadQuery &er) {
        // Handle any query errors
        ENGINE_LOG_ERROR << "QUERY ERROR WHEN FINDING TABLE FILES TO MERGE" << ": " << er.what();
        return Status::DBTransactionError("QUERY ERROR WHEN FINDING TABLE FILES TO MERGE", er.what());
    } catch (const Exception &er) {
        // Catch-all for any other MySQL++ exceptions
        ENGINE_LOG_ERROR << "GENERAL ERROR WHEN FINDING TABLE FILES TO MERGE" << ": " << er.what();
        return Status::DBTransactionError("GENERAL ERROR WHEN FINDING TABLE FILES TO MERGE", er.what());
    }

    return Status::OK();
}

Status MySQLMetaImpl::GetTableFiles(const std::string &table_id,
                                    const std::vector<size_t> &ids,
                                    TableFilesSchema &table_files) {
    if (ids.empty()) {
Z
update  
zhiru 已提交
1250 1251 1252
        return Status::OK();
    }

1253 1254 1255 1256 1257 1258
    std::stringstream idSS;
    for (auto &id : ids) {
        idSS << "id = " << std::to_string(id) << " OR ";
    }
    std::string idStr = idSS.str();
    idStr = idStr.substr(0, idStr.size() - 4); //remove the last " OR "
Z
zhiru 已提交
1259

1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270
    try {
        StoreQueryResult res;
        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);

            if (connectionPtr == nullptr) {
                return Status::Error("Failed to connect to database server");
            }


            Query getTableFileQuery = connectionPtr->query();
S
starlord 已提交
1271
            getTableFileQuery << "SELECT id, engine_type, file_id, file_type, file_size, row_count, date, created_on " <<
1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285
                              "FROM TableFiles " <<
                              "WHERE table_id = " << quote << table_id << " AND " <<
                              "(" << idStr << ");";

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

            res = getTableFileQuery.store();
        } //Scoped Connection

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

1288
        for (auto &resRow : res) {
Z
zhiru 已提交
1289

1290
            TableFileSchema file_schema;
1291

1292
            file_schema.id_ = resRow["id"];
Z
zhiru 已提交
1293

1294
            file_schema.table_id_ = table_id;
Z
update  
zhiru 已提交
1295

1296 1297
            file_schema.index_file_size_ = table_schema.index_file_size_;

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

S
starlord 已提交
1300 1301
            file_schema.nlist_ = table_schema.nlist_;

S
starlord 已提交
1302 1303
            file_schema.metric_type_ = table_schema.metric_type_;

1304 1305 1306
            std::string file_id;
            resRow["file_id"].to_string(file_id);
            file_schema.file_id_ = file_id;
Z
update  
zhiru 已提交
1307

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

1310 1311 1312
            file_schema.file_size_ = resRow["file_size"];

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

1314
            file_schema.date_ = resRow["date"];
1315

S
starlord 已提交
1316 1317
            file_schema.created_on_ = resRow["created_on"];

1318
            file_schema.dimension_ = table_schema.dimension_;
Z
update  
zhiru 已提交
1319

1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331
            utils::GetTableFilePath(options_, file_schema);

            table_files.emplace_back(file_schema);
        }
    } catch (const BadQuery &er) {
        // Handle any query errors
        ENGINE_LOG_ERROR << "QUERY ERROR WHEN RETRIEVING TABLE FILES" << ": " << er.what();
        return Status::DBTransactionError("QUERY ERROR WHEN RETRIEVING TABLE FILES", er.what());
    } catch (const Exception &er) {
        // Catch-all for any other MySQL++ exceptions
        ENGINE_LOG_ERROR << "GENERAL ERROR WHEN RETRIEVING TABLE FILES" << ": " << er.what();
        return Status::DBTransactionError("GENERAL ERROR WHEN RETRIEVING TABLE FILES", er.what());
Z
update  
zhiru 已提交
1332 1333
    }

1334 1335
    return Status::OK();
}
Z
zhiru 已提交
1336

1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351
// PXU TODO: Support Swap
Status MySQLMetaImpl::Archive() {
    auto &criterias = options_.archive_conf.GetCriterias();
    if (criterias.empty()) {
        return Status::OK();
    }

    for (auto &kv : criterias) {
        auto &criteria = kv.first;
        auto &limit = kv.second;
        if (criteria == "days") {
            size_t usecs = limit * D_SEC * US_PS;
            long now = utils::GetMicroSecTimeStamp();

            try {
Z
update  
zhiru 已提交
1352
                ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);
Z
zhiru 已提交
1353

Z
update  
zhiru 已提交
1354 1355 1356 1357
                if (connectionPtr == nullptr) {
                    return Status::Error("Failed to connect to database server");
                }

1358 1359 1360 1361 1362
                Query archiveQuery = connectionPtr->query();
                archiveQuery << "UPDATE 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 已提交
1363

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

1366 1367 1368
                if (!archiveQuery.exec()) {
                    return Status::DBTransactionError("QUERY ERROR DURING ARCHIVE", archiveQuery.error());
                }
1369

1370 1371 1372 1373 1374 1375 1376 1377
            } catch (const BadQuery &er) {
                // Handle any query errors
                ENGINE_LOG_ERROR << "QUERY ERROR WHEN DURING ARCHIVE" << ": " << er.what();
                return Status::DBTransactionError("QUERY ERROR WHEN DURING ARCHIVE", er.what());
            } catch (const Exception &er) {
                // Catch-all for any other MySQL++ exceptions
                ENGINE_LOG_ERROR << "GENERAL ERROR WHEN DURING ARCHIVE" << ": " << er.what();
                return Status::DBTransactionError("GENERAL ERROR WHEN DURING ARCHIVE", er.what());
Z
zhiru 已提交
1378
            }
1379
        }
1380 1381 1382
        if (criteria == "disk") {
            uint64_t sum = 0;
            Size(sum);
Z
update  
zhiru 已提交
1383

1384 1385 1386
            auto to_delete = (sum - limit * G);
            DiscardFiles(to_delete);
        }
Z
update  
zhiru 已提交
1387 1388
    }

1389 1390
    return Status::OK();
}
Z
zhiru 已提交
1391

1392 1393
Status MySQLMetaImpl::Size(uint64_t &result) {
    result = 0;
1394

S
starlord 已提交
1395
    try {
1396 1397 1398
        StoreQueryResult res;
        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);
1399

1400 1401 1402
            if (connectionPtr == nullptr) {
                return Status::Error("Failed to connect to database server");
            }
Z
zhiru 已提交
1403

Z
update  
zhiru 已提交
1404

1405
            Query getSizeQuery = connectionPtr->query();
1406
            getSizeQuery << "SELECT IFNULL(SUM(file_size),0) AS sum " <<
1407 1408
                         "FROM TableFiles " <<
                         "WHERE file_type <> " << std::to_string(TableFileSchema::TO_DELETE) << ";";
Z
update  
zhiru 已提交
1409

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

1412 1413
            res = getSizeQuery.store();
        } //Scoped Connection
Z
update  
zhiru 已提交
1414

1415 1416 1417 1418 1419
        if (res.empty()) {
            result = 0;
        } else {
            result = res[0]["sum"];
        }
Z
update  
zhiru 已提交
1420

1421 1422 1423 1424 1425 1426 1427 1428 1429
    } catch (const BadQuery &er) {
        // Handle any query errors
        ENGINE_LOG_ERROR << "QUERY ERROR WHEN RETRIEVING SIZE" << ": " << er.what();
        return Status::DBTransactionError("QUERY ERROR WHEN RETRIEVING SIZE", er.what());
    } catch (const Exception &er) {
        // Catch-all for any other MySQL++ exceptions
        ENGINE_LOG_ERROR << "GENERAL ERROR WHEN RETRIEVING SIZE" << ": " << er.what();
        return Status::DBTransactionError("GENERAL ERROR WHEN RETRIEVING SIZE", er.what());
    }
1430

1431 1432
    return Status::OK();
}
1433

1434 1435 1436 1437
Status MySQLMetaImpl::DiscardFiles(long long to_discard_size) {
    if (to_discard_size <= 0) {

        return Status::OK();
Z
update  
zhiru 已提交
1438
    }
1439
    ENGINE_LOG_DEBUG << "About to discard size=" << to_discard_size;
Z
update  
zhiru 已提交
1440

1441
    try {
Y
Yu Kun 已提交
1442
        server::MetricCollector metric;
1443 1444 1445
        bool status;
        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);
1446

1447 1448 1449
            if (connectionPtr == nullptr) {
                return Status::Error("Failed to connect to database server");
            }
Z
zhiru 已提交
1450

1451
            Query discardFilesQuery = connectionPtr->query();
1452
            discardFilesQuery << "SELECT id, file_size " <<
1453 1454 1455 1456
                              "FROM TableFiles " <<
                              "WHERE file_type <> " << std::to_string(TableFileSchema::TO_DELETE) << " " <<
                              "ORDER BY id ASC " <<
                              "LIMIT 10;";
Z
update  
zhiru 已提交
1457

1458
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::DiscardFiles: " << discardFilesQuery.str();
1459

1460 1461 1462 1463
            StoreQueryResult res = discardFilesQuery.store();
            if (res.num_rows() == 0) {
                return Status::OK();
            }
1464

1465 1466 1467 1468 1469
            TableFileSchema table_file;
            std::stringstream idsToDiscardSS;
            for (auto &resRow : res) {
                if (to_discard_size <= 0) {
                    break;
Z
update  
zhiru 已提交
1470
                }
1471
                table_file.id_ = resRow["id"];
1472
                table_file.file_size_ = resRow["file_size"];
1473 1474
                idsToDiscardSS << "id = " << std::to_string(table_file.id_) << " OR ";
                ENGINE_LOG_DEBUG << "Discard table_file.id=" << table_file.file_id_
1475 1476
                                 << " table_file.size=" << table_file.file_size_;
                to_discard_size -= table_file.file_size_;
1477
            }
Z
update  
zhiru 已提交
1478

1479 1480
            std::string idsToDiscardStr = idsToDiscardSS.str();
            idsToDiscardStr = idsToDiscardStr.substr(0, idsToDiscardStr.size() - 4); //remove the last " OR "
1481

1482 1483 1484 1485
            discardFilesQuery << "UPDATE TableFiles " <<
                              "SET file_type = " << std::to_string(TableFileSchema::TO_DELETE) << ", " <<
                              "updated_time = " << std::to_string(utils::GetMicroSecTimeStamp()) << " " <<
                              "WHERE " << idsToDiscardStr << ";";
1486

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

1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505
            status = discardFilesQuery.exec();
            if (!status) {
                ENGINE_LOG_ERROR << "QUERY ERROR WHEN DISCARDING FILES";
                return Status::DBTransactionError("QUERY ERROR WHEN DISCARDING FILES", discardFilesQuery.error());
            }
        } //Scoped Connection

        return DiscardFiles(to_discard_size);

    } catch (const BadQuery &er) {
        // Handle any query errors
        ENGINE_LOG_ERROR << "QUERY ERROR WHEN DISCARDING FILES" << ": " << er.what();
        return Status::DBTransactionError("QUERY ERROR WHEN DISCARDING FILES", er.what());
    } catch (const Exception &er) {
        // Catch-all for any other MySQL++ exceptions
        ENGINE_LOG_ERROR << "GENERAL ERROR WHEN DISCARDING FILES" << ": " << er.what();
        return Status::DBTransactionError("GENERAL ERROR WHEN DISCARDING FILES", er.what());
P
peng.xu 已提交
1506
    }
1507
}
P
peng.xu 已提交
1508

1509 1510 1511
//ZR: this function assumes all fields in file_schema have value
Status MySQLMetaImpl::UpdateTableFile(TableFileSchema &file_schema) {
    file_schema.updated_time_ = utils::GetMicroSecTimeStamp();
1512

S
starlord 已提交
1513
    try {
Y
Yu Kun 已提交
1514
        server::MetricCollector metric;
1515 1516
        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);
Z
update  
zhiru 已提交
1517

1518 1519 1520
            if (connectionPtr == nullptr) {
                return Status::Error("Failed to connect to database server");
            }
Z
update  
zhiru 已提交
1521

1522
            Query updateTableFileQuery = connectionPtr->query();
Z
update  
zhiru 已提交
1523

1524 1525 1526 1527
            //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 Tables " <<
                                 "WHERE table_id = " << quote << file_schema.table_id_ << ";";
Z
update  
zhiru 已提交
1528

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

1531
            StoreQueryResult res = updateTableFileQuery.store();
1532

1533 1534 1535 1536
            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 已提交
1537
                }
1538 1539 1540 1541 1542 1543 1544 1545 1546
            } 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_);
1547 1548
            std::string file_size = std::to_string(file_schema.file_size_);
            std::string row_count = std::to_string(file_schema.row_count_);
1549 1550 1551
            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 已提交
1552

1553 1554 1555 1556 1557
            updateTableFileQuery << "UPDATE TableFiles " <<
                                 "SET table_id = " << quote << table_id << ", " <<
                                 "engine_type = " << engine_type << ", " <<
                                 "file_id = " << quote << file_id << ", " <<
                                 "file_type = " << file_type << ", " <<
1558 1559
                                 "file_size = " << file_size << ", " <<
                                 "row_count = " << row_count << ", " <<
1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588
                                 "updated_time = " << updated_time << ", " <<
                                 "created_on = " << created_on << ", " <<
                                 "date = " << date << " " <<
                                 "WHERE id = " << id << ";";

            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_;
                ENGINE_LOG_ERROR << "QUERY ERROR WHEN UPDATING TABLE FILE";
                return Status::DBTransactionError("QUERY ERROR WHEN UPDATING TABLE FILE",
                                                  updateTableFileQuery.error());
            }
        } //Scoped Connection

    } catch (const BadQuery &er) {
        // Handle any query errors
        ENGINE_LOG_DEBUG << "table_id= " << file_schema.table_id_ << " file_id=" << file_schema.file_id_;
        ENGINE_LOG_ERROR << "QUERY ERROR WHEN UPDATING TABLE FILE" << ": " << er.what();
        return Status::DBTransactionError("QUERY ERROR WHEN UPDATING TABLE FILE", er.what());
    } catch (const Exception &er) {
        // Catch-all for any other MySQL++ exceptions
        ENGINE_LOG_DEBUG << "table_id= " << file_schema.table_id_ << " file_id=" << file_schema.file_id_;
        ENGINE_LOG_ERROR << "GENERAL ERROR WHEN UPDATING TABLE FILE" << ": " << er.what();
        return Status::DBTransactionError("GENERAL ERROR WHEN UPDATING TABLE FILE", er.what());
    }
    return Status::OK();
}
1589

1590 1591 1592
Status MySQLMetaImpl::UpdateTableFilesToIndex(const std::string &table_id) {
    try {
        ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);
1593

1594 1595
        if (connectionPtr == nullptr) {
            return Status::Error("Failed to connect to database server");
1596
        }
Z
update  
zhiru 已提交
1597

1598
        Query updateTableFilesToIndexQuery = connectionPtr->query();
Z
zhiru 已提交
1599

1600
        updateTableFilesToIndexQuery << "UPDATE TableFiles " <<
Z
fix  
zhiru 已提交
1601 1602 1603
                                     "SET file_type = " << std::to_string(TableFileSchema::TO_INDEX) << " " <<
                                     "WHERE table_id = " << quote << table_id << " AND " <<
                                     "file_type = " << std::to_string(TableFileSchema::RAW) << ";";
1604

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

Z
fix  
zhiru 已提交
1607 1608 1609 1610 1611 1612
        if (!updateTableFilesToIndexQuery.exec()) {
            ENGINE_LOG_ERROR << "QUERY ERROR WHEN UPDATING TABLE FILE";
            return Status::DBTransactionError("QUERY ERROR WHEN UPDATING TABLE FILE",
                                              updateTableFilesToIndexQuery.error());
        }

1613 1614 1615 1616 1617 1618 1619 1620 1621
    } catch (const BadQuery &er) {
        // Handle any query errors
        ENGINE_LOG_ERROR << "QUERY ERROR WHEN UPDATING TABLE FILES TO INDEX" << ": " << er.what();
        return Status::DBTransactionError("QUERY ERROR WHEN UPDATING TABLE FILES TO INDEX", er.what());
    } catch (const Exception &er) {
        // Catch-all for any other MySQL++ exceptions
        ENGINE_LOG_ERROR << "GENERAL ERROR WHEN UPDATING TABLE FILES TO INDEX" << ": " << er.what();
        return Status::DBTransactionError("GENERAL ERROR WHEN UPDATING TABLE FILES TO INDEX", er.what());
    }
Z
update  
zhiru 已提交
1622

1623 1624
    return Status::OK();
}
Z
zhiru 已提交
1625

1626 1627
Status MySQLMetaImpl::UpdateTableFiles(TableFilesSchema &files) {
    try {
Y
Yu Kun 已提交
1628
        server::MetricCollector metric;
1629 1630 1631 1632 1633 1634
        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);

            if (connectionPtr == nullptr) {
                return Status::Error("Failed to connect to database server");
            }
Z
update  
zhiru 已提交
1635

1636
            Query updateTableFilesQuery = connectionPtr->query();
1637

1638 1639
            std::map<std::string, bool> has_tables;
            for (auto &file_schema : files) {
1640

1641 1642 1643
                if (has_tables.find(file_schema.table_id_) != has_tables.end()) {
                    continue;
                }
1644

1645 1646 1647 1648 1649
                updateTableFilesQuery << "SELECT EXISTS " <<
                                      "(SELECT 1 FROM Tables " <<
                                      "WHERE table_id = " << quote << file_schema.table_id_ << " " <<
                                      "AND state <> " << std::to_string(TableSchema::TO_DELETE) << ") " <<
                                      "AS " << quote << "check" << ";";
1650

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

1653
                StoreQueryResult res = updateTableFilesQuery.store();
1654

1655 1656 1657
                int check = res[0]["check"];
                has_tables[file_schema.table_id_] = (check == 1);
            }
1658

1659
            for (auto &file_schema : files) {
1660

1661 1662
                if (!has_tables[file_schema.table_id_]) {
                    file_schema.file_type_ = TableFileSchema::TO_DELETE;
1663
                }
1664
                file_schema.updated_time_ = utils::GetMicroSecTimeStamp();
1665

1666 1667 1668 1669 1670
                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_);
1671 1672
                std::string file_size = std::to_string(file_schema.file_size_);
                std::string row_count = std::to_string(file_schema.row_count_);
1673 1674 1675
                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 已提交
1676

1677 1678 1679 1680 1681
                updateTableFilesQuery << "UPDATE TableFiles " <<
                                      "SET table_id = " << quote << table_id << ", " <<
                                      "engine_type = " << engine_type << ", " <<
                                      "file_id = " << quote << file_id << ", " <<
                                      "file_type = " << file_type << ", " <<
1682 1683
                                      "file_size = " << file_size << ", " <<
                                      "row_count = " << row_count << ", " <<
1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707
                                      "updated_time = " << updated_time << ", " <<
                                      "created_on = " << created_on << ", " <<
                                      "date = " << date << " " <<
                                      "WHERE id = " << id << ";";

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

                if (!updateTableFilesQuery.exec()) {
                    ENGINE_LOG_ERROR << "QUERY ERROR WHEN UPDATING TABLE FILES";
                    return Status::DBTransactionError("QUERY ERROR WHEN UPDATING TABLE FILES",
                                                      updateTableFilesQuery.error());
                }
            }
        } //Scoped Connection

    } catch (const BadQuery &er) {
        // Handle any query errors
        ENGINE_LOG_ERROR << "QUERY ERROR WHEN UPDATING TABLE FILES" << ": " << er.what();
        return Status::DBTransactionError("QUERY ERROR WHEN UPDATING TABLE FILES", er.what());
    } catch (const Exception &er) {
        // Catch-all for any other MySQL++ exceptions
        ENGINE_LOG_ERROR << "GENERAL ERROR WHEN UPDATING TABLE FILES" << ": " << er.what();
        return Status::DBTransactionError("GENERAL ERROR WHEN UPDATING TABLE FILES", er.what());
    }
S
starlord 已提交
1708

1709 1710
    return Status::OK();
}
Z
fix  
zhiru 已提交
1711

1712 1713
Status MySQLMetaImpl::CleanUpFilesWithTTL(uint16_t seconds) {
    auto now = utils::GetMicroSecTimeStamp();
S
starlord 已提交
1714 1715 1716
    std::set<std::string> table_ids;

    //remove to_delete files
1717
    try {
Y
Yu Kun 已提交
1718
        server::MetricCollector metric;
1719

1720 1721
        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);
Z
update  
zhiru 已提交
1722

1723 1724 1725
            if (connectionPtr == nullptr) {
                return Status::Error("Failed to connect to database server");
            }
Z
zhiru 已提交
1726

1727 1728 1729 1730 1731
            Query cleanUpFilesWithTTLQuery = connectionPtr->query();
            cleanUpFilesWithTTLQuery << "SELECT id, table_id, file_id, date " <<
                                     "FROM TableFiles " <<
                                     "WHERE file_type = " << std::to_string(TableFileSchema::TO_DELETE) << " AND " <<
                                     "updated_time < " << std::to_string(now - seconds * US_PS) << ";";
Z
update  
zhiru 已提交
1732

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

1735
            StoreQueryResult res = cleanUpFilesWithTTLQuery.store();
Z
update  
zhiru 已提交
1736

1737 1738
            TableFileSchema table_file;
            std::vector<std::string> idsToDelete;
1739

1740
            for (auto &resRow : res) {
1741

1742
                table_file.id_ = resRow["id"]; //implicit conversion
1743

1744 1745 1746
                std::string table_id;
                resRow["table_id"].to_string(table_id);
                table_file.table_id_ = table_id;
Z
fix  
zhiru 已提交
1747

1748 1749 1750
                std::string file_id;
                resRow["file_id"].to_string(file_id);
                table_file.file_id_ = file_id;
Z
update  
zhiru 已提交
1751

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

1754 1755
                utils::DeleteTableFilePath(options_, table_file);

S
starlord 已提交
1756
                ENGINE_LOG_DEBUG << "Removing file id:" << table_file.id_ << " location:" << table_file.location_;
1757 1758

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

                table_ids.insert(table_file.table_id_);
1761 1762 1763 1764 1765 1766 1767
            }

            if (!idsToDelete.empty()) {

                std::stringstream idsToDeleteSS;
                for (auto &id : idsToDelete) {
                    idsToDeleteSS << "id = " << id << " OR ";
1768
                }
1769

1770 1771 1772 1773
                std::string idsToDeleteStr = idsToDeleteSS.str();
                idsToDeleteStr = idsToDeleteStr.substr(0, idsToDeleteStr.size() - 4); //remove the last " OR "
                cleanUpFilesWithTTLQuery << "DELETE FROM TableFiles WHERE " <<
                                         idsToDeleteStr << ";";
1774

1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792
                ENGINE_LOG_DEBUG << "MySQLMetaImpl::CleanUpFilesWithTTL: " << cleanUpFilesWithTTLQuery.str();

                if (!cleanUpFilesWithTTLQuery.exec()) {
                    ENGINE_LOG_ERROR << "QUERY ERROR WHEN CLEANING UP FILES WITH TTL";
                    return Status::DBTransactionError("CleanUpFilesWithTTL Error",
                                                      cleanUpFilesWithTTLQuery.error());
                }
            }
        } //Scoped Connection

    } catch (const BadQuery &er) {
        // Handle any query errors
        ENGINE_LOG_ERROR << "QUERY ERROR WHEN CLEANING UP FILES WITH TTL" << ": " << er.what();
        return Status::DBTransactionError("QUERY ERROR WHEN CLEANING UP FILES WITH TTL", er.what());
    } catch (const Exception &er) {
        // Catch-all for any other MySQL++ exceptions
        ENGINE_LOG_ERROR << "GENERAL ERROR WHEN CLEANING UP FILES WITH TTL" << ": " << er.what();
        return Status::DBTransactionError("GENERAL ERROR WHEN CLEANING UP FILES WITH TTL", er.what());
Z
update  
zhiru 已提交
1793
    }
1794

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

        {
Z
update  
zhiru 已提交
1800
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);
Z
zhiru 已提交
1801

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

1806 1807 1808 1809
            Query cleanUpFilesWithTTLQuery = connectionPtr->query();
            cleanUpFilesWithTTLQuery << "SELECT id, table_id " <<
                                     "FROM Tables " <<
                                     "WHERE state = " << std::to_string(TableSchema::TO_DELETE) << ";";
1810

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

            StoreQueryResult res = cleanUpFilesWithTTLQuery.store();
Z
update  
zhiru 已提交
1814

Z
update  
zhiru 已提交
1815 1816
            if (!res.empty()) {

1817 1818 1819 1820 1821
                std::stringstream idsToDeleteSS;
                for (auto &resRow : res) {
                    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 1828 1829 1830
                std::string idsToDeleteStr = idsToDeleteSS.str();
                idsToDeleteStr = idsToDeleteStr.substr(0, idsToDeleteStr.size() - 4); //remove the last " OR "
                cleanUpFilesWithTTLQuery << "DELETE FROM Tables WHERE " <<
                                         idsToDeleteStr << ";";
1831

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

1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849
                if (!cleanUpFilesWithTTLQuery.exec()) {
                    ENGINE_LOG_ERROR << "QUERY ERROR WHEN CLEANING UP FILES WITH TTL";
                    return Status::DBTransactionError("QUERY ERROR WHEN CLEANING UP FILES WITH TTL",
                                                      cleanUpFilesWithTTLQuery.error());
                }
            }
        } //Scoped Connection

    } catch (const BadQuery &er) {
        // Handle any query errors
        ENGINE_LOG_ERROR << "QUERY ERROR WHEN CLEANING UP FILES WITH TTL" << ": " << er.what();
        return Status::DBTransactionError("QUERY ERROR WHEN CLEANING UP FILES WITH TTL", er.what());
    } catch (const Exception &er) {
        // Catch-all for any other MySQL++ exceptions
        ENGINE_LOG_ERROR << "GENERAL ERROR WHEN CLEANING UP FILES WITH TTL" << ": " << er.what();
        return Status::DBTransactionError("GENERAL ERROR WHEN CLEANING UP FILES WITH TTL", er.what());
Z
update  
zhiru 已提交
1850 1851
    }

S
starlord 已提交
1852 1853 1854
    //remove deleted table folder
    //don't remove table folder until all its files has been deleted
    try {
Y
Yu Kun 已提交
1855
        server::MetricCollector metric;
S
starlord 已提交
1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867

        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);

            if (connectionPtr == nullptr) {
                return Status::Error("Failed to connect to database server");
            }

            for(auto& table_id : table_ids) {
                Query cleanUpFilesWithTTLQuery = connectionPtr->query();
                cleanUpFilesWithTTLQuery << "SELECT file_id " <<
                                         "FROM TableFiles " <<
S
starlord 已提交
1868
                                         "WHERE table_id = " << quote << table_id << ";";
S
starlord 已提交
1869 1870 1871 1872 1873 1874 1875 1876 1877 1878

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

                StoreQueryResult res = cleanUpFilesWithTTLQuery.store();

                if (res.empty()) {
                    utils::DeleteTablePath(options_, table_id);
                }
            }
        }
S
starlord 已提交
1879 1880 1881 1882
    } catch (const BadQuery &er) {
        // Handle any query errors
        ENGINE_LOG_ERROR << "QUERY ERROR WHEN CLEANING UP FILES WITH TTL" << ": " << er.what();
        return Status::DBTransactionError("QUERY ERROR WHEN CLEANING UP FILES WITH TTL", er.what());
S
starlord 已提交
1883 1884 1885 1886 1887 1888
    } catch (const Exception &er) {
        // Catch-all for any other MySQL++ exceptions
        ENGINE_LOG_ERROR << "GENERAL ERROR WHEN CLEANING UP TABLES WITH TTL" << ": " << er.what();
        return Status::DBTransactionError("GENERAL ERROR WHEN CLEANING UP TABLES WITH TTL", er.what());
    }

1889 1890
    return Status::OK();
}
1891

1892 1893 1894
Status MySQLMetaImpl::CleanUp() {
    try {
        ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);
1895

1896 1897 1898
        if (connectionPtr == nullptr) {
            return Status::Error("Failed to connect to database server");
        }
1899

1900 1901 1902 1903 1904
        Query cleanUpQuery = connectionPtr->query();
        cleanUpQuery << "SELECT table_name " <<
                     "FROM information_schema.tables " <<
                     "WHERE table_schema = " << quote << mysql_connection_pool_->getDB() << " " <<
                     "AND table_name = " << quote << "TableFiles" << ";";
Z
update  
zhiru 已提交
1905

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

1908
        StoreQueryResult res = cleanUpQuery.store();
Z
update  
zhiru 已提交
1909

1910 1911
        if (!res.empty()) {
            ENGINE_LOG_DEBUG << "Remove table file type as NEW";
1912 1913 1914 1915
            cleanUpQuery << "DELETE FROM TableFiles WHERE file_type IN ("
                    << std::to_string(TableFileSchema::NEW) << ","
                    << std::to_string(TableFileSchema::NEW_MERGE) << ","
                    << std::to_string(TableFileSchema::NEW_INDEX) << ");";
1916

1917
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::CleanUp: " << cleanUpQuery.str();
1918

1919 1920 1921
            if (!cleanUpQuery.exec()) {
                ENGINE_LOG_ERROR << "QUERY ERROR WHEN CLEANING UP FILES";
                return Status::DBTransactionError("Clean up Error", cleanUpQuery.error());
Z
update  
zhiru 已提交
1922
            }
1923
        }
1924 1925 1926 1927 1928 1929 1930 1931 1932

    } catch (const BadQuery &er) {
        // Handle any query errors
        ENGINE_LOG_ERROR << "QUERY ERROR WHEN CLEANING UP FILES" << ": " << er.what();
        return Status::DBTransactionError("QUERY ERROR WHEN CLEANING UP FILES", er.what());
    } catch (const Exception &er) {
        // Catch-all for any other MySQL++ exceptions
        ENGINE_LOG_ERROR << "GENERAL ERROR WHEN CLEANING UP FILES" << ": " << er.what();
        return Status::DBTransactionError("GENERAL ERROR WHEN CLEANING UP FILES", er.what());
Z
update  
zhiru 已提交
1933 1934
    }

1935 1936 1937 1938 1939
    return Status::OK();
}

Status MySQLMetaImpl::Count(const std::string &table_id, uint64_t &result) {
    try {
Y
Yu Kun 已提交
1940
        server::MetricCollector metric;
1941 1942 1943 1944 1945 1946 1947

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

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

1950 1951
        StoreQueryResult res;
        {
Z
update  
zhiru 已提交
1952
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);
Z
zhiru 已提交
1953

Z
update  
zhiru 已提交
1954 1955 1956 1957
            if (connectionPtr == nullptr) {
                return Status::Error("Failed to connect to database server");
            }

Z
update  
zhiru 已提交
1958

1959 1960 1961 1962 1963 1964 1965
            Query countQuery = connectionPtr->query();
            countQuery << "SELECT size " <<
                       "FROM TableFiles " <<
                       "WHERE table_id = " << 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 已提交
1966

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

1969 1970 1971 1972 1973 1974 1975
            res = countQuery.store();
        } //Scoped Connection

        result = 0;
        for (auto &resRow : res) {
            size_t size = resRow["size"];
            result += size;
1976
        }
1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995

        if (table_schema.dimension_ <= 0) {
            std::stringstream errorMsg;
            errorMsg << "MySQLMetaImpl::Count: " << "table dimension = " << std::to_string(table_schema.dimension_)
                     << ", table_id = " << table_id;
            ENGINE_LOG_ERROR << errorMsg.str();
            return Status::Error(errorMsg.str());
        }
        result /= table_schema.dimension_;
        result /= sizeof(float);

    } catch (const BadQuery &er) {
        // Handle any query errors
        ENGINE_LOG_ERROR << "QUERY ERROR WHEN RETRIEVING COUNT" << ": " << er.what();
        return Status::DBTransactionError("QUERY ERROR WHEN RETRIEVING COUNT", er.what());
    } catch (const Exception &er) {
        // Catch-all for any other MySQL++ exceptions
        ENGINE_LOG_ERROR << "GENERAL ERROR WHEN RETRIEVING COUNT" << ": " << er.what();
        return Status::DBTransactionError("GENERAL ERROR WHEN RETRIEVING COUNT", er.what());
Z
update  
zhiru 已提交
1996
    }
S
starlord 已提交
1997

1998 1999 2000 2001 2002
    return Status::OK();
}

Status MySQLMetaImpl::DropAll() {
    try {
S
starlord 已提交
2003
        ENGINE_LOG_DEBUG << "Drop all mysql meta";
2004 2005 2006 2007
        ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);

        if (connectionPtr == nullptr) {
            return Status::Error("Failed to connect to database server");
Z
zhiru 已提交
2008
        }
2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029

        Query dropTableQuery = connectionPtr->query();
        dropTableQuery << "DROP TABLE IF EXISTS Tables, TableFiles;";

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

        if (dropTableQuery.exec()) {
            return Status::OK();
        } else {
            ENGINE_LOG_ERROR << "QUERY ERROR WHEN DROPPING TABLE";
            return Status::DBTransactionError("DROP TABLE ERROR", dropTableQuery.error());
        }
    } catch (const BadQuery &er) {
        // Handle any query errors
        ENGINE_LOG_ERROR << "QUERY ERROR WHEN DROPPING TABLE" << ": " << er.what();
        return Status::DBTransactionError("QUERY ERROR WHEN DROPPING TABLE", er.what());
    } catch (const Exception &er) {
        // Catch-all for any other MySQL++ exceptions
        ENGINE_LOG_ERROR << "GENERAL ERROR WHEN DROPPING TABLE" << ": " << er.what();
        return Status::DBTransactionError("GENERAL ERROR WHEN DROPPING TABLE", er.what());
    }
S
starlord 已提交
2030

2031 2032 2033
    return Status::OK();
}

Z
update  
zhiru 已提交
2034 2035 2036 2037
} // namespace meta
} // namespace engine
} // namespace milvus
} // namespace zilliz