MySQLMetaImpl.cpp 82.0 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
class MetricCollector {
 public:
    MetricCollector() {
        server::Metrics::GetInstance().MetaAccessTotalIncrement();
        start_time_ = METRICS_NOW_TIME;
Z
update  
zhiru 已提交
47 48
    }

49 50 51 52 53
    ~MetricCollector() {
        auto end_time = METRICS_NOW_TIME;
        auto total_time = METRICS_MICROSECONDS(start_time_, end_time);
        server::Metrics::GetInstance().MetaAccessDurationSecondsHistogramObserve(total_time);
    }
54

55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
 private:
    using TIME_POINT = std::chrono::system_clock::time_point;
    TIME_POINT start_time_;
};

}

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();
}

MySQLMetaImpl::MySQLMetaImpl(const DBMetaOptions &options_, const int &mode)
    : options_(options_),
      mode_(mode) {
    Initialize();
}

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 已提交
90 91 92
        }
    }

93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
    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");
115
        }
116 117 118 119 120 121
        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());
122
        }
123
        std::string dbName = pieces_match[6].str();
124 125


126 127 128 129
        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);
130

131 132
        ENGINE_LOG_DEBUG << "MySQL connection pool: maximum pool size = " << std::to_string(maxPoolSize);
        try {
133

134 135
            if (mode_ != Options::MODE::READ_ONLY) {
                CleanUp();
136 137
            }

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

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

145

146 147 148
                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.");
149
                }
150
                Query InitializeQuery = connectionPtr->query();
Z
update  
zhiru 已提交
151

152 153 154 155 156 157 158
                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, " <<
                                "engine_type INT DEFAULT 1 NOT NULL, " <<
159 160 161
                                "nlist INT DEFAULT 16384 NOT NULL, " <<
                                "index_file_size INT DEFAULT 1024 NOT NULL, " <<
                                "metric_type INT DEFAULT 1 NOT NULL);";
Z
zhiru 已提交
162

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

165 166
                if (!InitializeQuery.exec()) {
                    return Status::DBTransactionError("Initialization Error", InitializeQuery.error());
Z
update  
zhiru 已提交
167 168
                }

169 170 171 172 173 174
                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, " <<
175 176
                                "file_size BIGINT DEFAULT 0 NOT NULL, " <<
                                "row_count BIGINT DEFAULT 0 NOT NULL, " <<
177 178 179 180 181 182 183 184
                                "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());
185
                }
186
            } //Scoped Connection
Z
update  
zhiru 已提交
187

188
        } catch (const BadQuery &er) {
Z
update  
zhiru 已提交
189
            // Handle any query errors
190 191 192
            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 已提交
193
            // Catch-all for any other MySQL++ exceptions
194 195
            ENGINE_LOG_ERROR << "GENERAL ERROR DURING INITIALIZATION" << ": " << er.what();
            return Status::DBTransactionError("GENERAL ERROR DURING INITIALIZATION", er.what());
Z
zhiru 已提交
196
        } catch (std::exception &e) {
197
            return HandleException("Encounter exception during initialization", e);
198
        }
199 200 201
    } else {
        ENGINE_LOG_ERROR << "Wrong URI format. URI = " << uri;
        return Status::Error("Wrong URI format");
Z
update  
zhiru 已提交
202
    }
S
starlord 已提交
203 204

    return Status::OK();
205 206 207 208 209 210
}

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

214 215 216 217 218 219
    TableSchema table_schema;
    table_schema.table_id_ = table_id;
    auto status = DescribeTable(table_schema);
    if (!status.ok()) {
        return status;
    }
Z
zhiru 已提交
220

221
    try {
Z
update  
zhiru 已提交
222

223
        auto yesterday = GetDateWithDelta(-1);
Z
update  
zhiru 已提交
224

225 226 227 228 229
        for (auto &date : dates) {
            if (date >= yesterday) {
                return Status::Error("Could not delete partitions within 2 days");
            }
        }
Z
zhiru 已提交
230

231 232 233 234 235 236
        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 已提交
237

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

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

Z
update  
zhiru 已提交
245

246
            Query dropPartitionsByDatesQuery = connectionPtr->query();
247

248 249 250 251
            dropPartitionsByDatesQuery << "UPDATE TableFiles " <<
                                       "SET file_type = " << std::to_string(TableFileSchema::TO_DELETE) << " " <<
                                       "WHERE table_id = " << quote << table_id << " AND " <<
                                       "date in (" << dateListStr << ");";
Z
update  
zhiru 已提交
252

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

255 256 257 258
            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 已提交
259
            }
260 261 262 263 264 265 266 267 268
        } //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 已提交
269
    }
270 271
    return Status::OK();
}
Z
update  
zhiru 已提交
272

273 274 275 276 277
Status MySQLMetaImpl::CreateTable(TableSchema &table_schema) {
    try {
        MetricCollector metric;
        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);
278

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

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

285 286 287 288 289
            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 已提交
290

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

293
                StoreQueryResult res = createTableQuery.store();
294

295 296 297 298 299 300 301 302 303
                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");
                    }
                }
            }
304

305 306
            table_schema.id_ = -1;
            table_schema.created_on_ = utils::GetMicroSecTimeStamp();
Z
update  
zhiru 已提交
307

308 309 310 311 312 313
            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_);
            std::string engine_type = std::to_string(table_schema.engine_type_);
Z
update  
zhiru 已提交
314

315 316
            createTableQuery << "INSERT INTO Tables VALUES" <<
                             "(" << id << ", " << quote << table_id << ", " << state << ", " << dimension << ", " <<
317
                             created_on << ", " << engine_type << ");";
Z
update  
zhiru 已提交
318

319
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::CreateTable: " << createTableQuery.str();
320

321 322
            if (SimpleResult res = createTableQuery.execute()) {
                table_schema.id_ = res.insert_id(); //Might need to use SELECT LAST_INSERT_ID()?
323

324 325 326 327
                //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());
328
            }
329
        } //Scoped Connection
330

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

333 334 335 336 337 338 339 340 341 342 343 344
    } 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);
    }
}
345

346
Status MySQLMetaImpl::HasNonIndexFiles(const std::string &table_id, bool &has) {
Z
zhiru 已提交
347 348 349 350 351 352 353 354 355 356 357 358 359 360
    has = false;

    try {
        StoreQueryResult res;
        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);

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

            Query hasNonIndexFilesQuery = connectionPtr->query();
            //since table_id is a unique column we just need to check whether it exists or not
            hasNonIndexFilesQuery << "SELECT EXISTS " <<
Z
fix  
zhiru 已提交
361 362 363 364
                                  "(SELECT 1 FROM TableFiles " <<
                                  "WHERE table_id = " << quote << table_id << " AND " <<
                                  "(file_type = " << std::to_string(TableFileSchema::RAW) << " OR " <<
                                  "file_type = " << std::to_string(TableFileSchema::NEW) << " OR " <<
365 366
                                  "file_type = " << std::to_string(TableFileSchema::NEW_MERGE) << " OR " <<
                                  "file_type = " << std::to_string(TableFileSchema::NEW_INDEX) << " OR " <<
Z
fix  
zhiru 已提交
367 368
                                  "file_type = " << std::to_string(TableFileSchema::TO_INDEX) << ")) " <<
                                  "AS " << quote << "check" << ";";
Z
zhiru 已提交
369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387

            ENGINE_LOG_DEBUG << "MySQLMetaImpl::HasNonIndexFiles: " << hasNonIndexFilesQuery.str();

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

        int check = res[0]["check"];
        has = (check == 1);

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

388 389
    return Status::OK();
}
390

391
Status MySQLMetaImpl::UpdateTableIndexParam(const std::string &table_id, const TableIndex& index) {
S
starlord 已提交
392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 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
    try {
        MetricCollector metric;

        {
            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_ << ", " <<
                                           "index_file_size = " << index.index_file_size_ << ", " <<
                                           "metric_type = " << index.metric_type_ << ", " <<
                                           "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());
    }

455 456 457 458
    return Status::OK();
}

Status MySQLMetaImpl::DescribeTableIndex(const std::string &table_id, TableIndex& index) {
S
starlord 已提交
459 460
    try {
        MetricCollector metric;
461

S
starlord 已提交
462 463
        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);
464

S
starlord 已提交
465 466 467 468 469 470 471 472 473
            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 已提交
474

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

S
starlord 已提交
477 478 479 480 481 482 483 484 485 486 487 488 489 490
            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.index_file_size_ = resRow["index_file_size"];
                index.metric_type_ = resRow["metric_type"];
            } else {
                return Status::NotFound("Table " + table_id + " not found");
            }

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

S
starlord 已提交
492 493 494 495 496 497 498 499 500 501 502 503 504 505 506
    } 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 {
507
        MetricCollector metric;
Z
update  
zhiru 已提交
508

509 510
        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);
511

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

S
starlord 已提交
516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556
            Query dropTableIndexQuery = connectionPtr->query();

            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());
            }

            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()) {
                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());
    }
557

S
starlord 已提交
558 559
    return Status::OK();
}
Z
update  
zhiru 已提交
560

S
starlord 已提交
561 562 563 564 565
Status MySQLMetaImpl::DeleteTable(const std::string &table_id) {
    try {
        MetricCollector metric;
        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);
Z
zhiru 已提交
566

S
starlord 已提交
567 568 569
            if (connectionPtr == nullptr) {
                return Status::Error("Failed to connect to database server");
            }
Z
zhiru 已提交
570

571 572 573 574 575 576
            //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 已提交
577

578
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::DeleteTable: " << deleteTableQuery.str();
579

580 581 582 583
            if (!deleteTableQuery.exec()) {
                ENGINE_LOG_ERROR << "QUERY ERROR WHEN DELETING TABLE";
                return Status::DBTransactionError("QUERY ERROR WHEN DELETING TABLE", deleteTableQuery.error());
            }
584

585
        } //Scoped Connection
Z
zhiru 已提交
586

587 588 589
        if (mode_ == Options::MODE::CLUSTER) {
            DeleteTableFiles(table_id);
        }
Z
update  
zhiru 已提交
590

591 592 593 594 595 596 597 598 599
    } 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 已提交
600

601 602
    return Status::OK();
}
Z
update  
zhiru 已提交
603

604 605 606 607 608 609 610 611 612
Status MySQLMetaImpl::DeleteTableFiles(const std::string &table_id) {
    try {
        MetricCollector metric;
        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);

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

614 615 616 617 618 619 620 621
            //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) << ";";
622

623
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::DeleteTableFiles: " << deleteTableFilesQuery.str();
624

625 626 627
            if (!deleteTableFilesQuery.exec()) {
                ENGINE_LOG_ERROR << "QUERY ERROR WHEN DELETING TABLE FILES";
                return Status::DBTransactionError("QUERY ERROR WHEN DELETING TABLE", deleteTableFilesQuery.error());
628
            }
629 630 631 632 633 634 635 636 637
        } //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 已提交
638 639
    }

640 641
    return Status::OK();
}
Z
zhiru 已提交
642

643 644 645 646 647 648
Status MySQLMetaImpl::DescribeTable(TableSchema &table_schema) {
    try {
        MetricCollector metric;
        StoreQueryResult res;
        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);
649

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

654 655 656 657 658 659 660
            Query describeTableQuery = connectionPtr->query();
            describeTableQuery << "SELECT id, dimension, files_cnt, engine_type, store_raw_data " <<
                               "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 已提交
661

662 663
            res = describeTableQuery.store();
        } //Scoped Connection
664

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

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

670
            table_schema.dimension_ = resRow["dimension"];
671

672 673 674
            table_schema.engine_type_ = resRow["engine_type"];
        } else {
            return Status::NotFound("Table " + table_schema.table_id_ + " not found");
675
        }
Z
update  
zhiru 已提交
676

677 678 679 680 681 682 683 684
    } 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 已提交
685 686
    }

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

690 691 692 693 694 695
Status MySQLMetaImpl::HasTable(const std::string &table_id, bool &has_or_not) {
    try {
        MetricCollector metric;
        StoreQueryResult res;
        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);
Z
update  
zhiru 已提交
696

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

701 702 703 704 705 706 707
            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 已提交
708

709
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::HasTable: " << hasTableQuery.str();
710

711 712
            res = hasTableQuery.store();
        } //Scoped Connection
713

714 715
        int check = res[0]["check"];
        has_or_not = (check == 1);
716

717 718 719 720 721 722 723 724 725
    } 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());
    }
726

727 728
    return Status::OK();
}
729

730 731 732 733 734 735
Status MySQLMetaImpl::AllTables(std::vector<TableSchema> &table_schema_array) {
    try {
        MetricCollector metric;
        StoreQueryResult res;
        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);
736

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

741 742 743 744
            Query allTablesQuery = connectionPtr->query();
            allTablesQuery << "SELECT id, table_id, dimension, files_cnt, engine_type, store_raw_data " <<
                           "FROM Tables " <<
                           "WHERE state <> " << std::to_string(TableSchema::TO_DELETE) << ";";
Z
zhiru 已提交
745

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

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

751 752
        for (auto &resRow : res) {
            TableSchema table_schema;
Z
update  
zhiru 已提交
753

754
            table_schema.id_ = resRow["id"]; //implicit conversion
755

756 757 758
            std::string table_id;
            resRow["table_id"].to_string(table_id);
            table_schema.table_id_ = table_id;
759

760
            table_schema.dimension_ = resRow["dimension"];
761

762
            table_schema.engine_type_ = resRow["engine_type"];
763

764 765 766 767 768 769 770 771 772 773 774
            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 已提交
775

776 777
    return Status::OK();
}
778

779 780 781 782 783 784 785 786 787 788
Status MySQLMetaImpl::CreateTableFile(TableFileSchema &file_schema) {
    if (file_schema.date_ == EmptyDate) {
        file_schema.date_ = Meta::GetDate();
    }
    TableSchema table_schema;
    table_schema.table_id_ = file_schema.table_id_;
    auto status = DescribeTable(table_schema);
    if (!status.ok()) {
        return status;
    }
789

790 791 792 793 794
    try {
        MetricCollector metric;

        NextFileId(file_schema.file_id_);
        file_schema.dimension_ = table_schema.dimension_;
795 796
        file_schema.file_size_ = 0;
        file_schema.row_count_ = 0;
797 798 799 800 801 802 803 804 805 806
        file_schema.created_on_ = utils::GetMicroSecTimeStamp();
        file_schema.updated_time_ = file_schema.created_on_;
        file_schema.engine_type_ = table_schema.engine_type_;
        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_);
807
        std::string row_count = std::to_string(file_schema.row_count_);
808 809 810 811 812 813
        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 已提交
814

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

819
            Query createTableFileQuery = connectionPtr->query();
820

821 822
            createTableFileQuery << "INSERT INTO TableFiles VALUES" <<
                                 "(" << id << ", " << quote << table_id << ", " << engine_type << ", " <<
823
                                 quote << file_id << ", " << file_type << ", " << row_count << ", " <<
824 825 826 827 828 829 830 831 832 833 834
                                 updated_time << ", " << created_on << ", " << date << ");";

            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());
835
            }
836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851
        } // 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);
    }
}
852

853 854
Status MySQLMetaImpl::FilesToIndex(TableFilesSchema &files) {
    files.clear();
855

856 857 858 859 860 861 862 863 864
    try {
        MetricCollector metric;
        StoreQueryResult res;
        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);

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

866
            Query filesToIndexQuery = connectionPtr->query();
867
            filesToIndexQuery << "SELECT id, table_id, engine_type, file_id, file_type, row_count, date " <<
868 869
                              "FROM TableFiles " <<
                              "WHERE file_type = " << std::to_string(TableFileSchema::TO_INDEX) << ";";
870

871
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::FilesToIndex: " << filesToIndexQuery.str();
872

873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893
            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"];

894
            table_file.row_count_ = resRow["row_count"];
895 896 897 898 899 900 901 902 903 904

            table_file.date_ = resRow["date"];

            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;
905
                }
906
                groups[table_file.table_id_] = table_schema;
907 908

            }
909
            table_file.dimension_ = groups[table_file.table_id_].dimension_;
Z
update  
zhiru 已提交
910

911 912 913 914 915 916 917 918 919 920 921 922
            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 已提交
923 924
    }

925 926 927 928 929
    return Status::OK();
}

Status MySQLMetaImpl::FilesToSearch(const std::string &table_id,
                                    const DatesT &partition,
Z
update  
zhiru 已提交
930
                                    DatePartionedTableFilesSchema &files) {
931
    files.clear();
932

933 934 935 936 937
    try {
        MetricCollector metric;
        StoreQueryResult res;
        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);
Z
update  
zhiru 已提交
938

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

943
            if (partition.empty()) {
Z
update  
zhiru 已提交
944

945
                Query filesToSearchQuery = connectionPtr->query();
946
                filesToSearchQuery << "SELECT id, table_id, engine_type, file_id, file_type, row_count, date " <<
947 948 949 950 951
                                   "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) << ");";
952

953 954 955 956 957 958 959 960 961 962 963 964 965 966 967
                ENGINE_LOG_DEBUG << "MySQLMetaImpl::FilesToSearch: " << filesToSearchQuery.str();

                res = filesToSearchQuery.store();

            } else {

                Query filesToSearchQuery = connectionPtr->query();

                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 ", "

968
                filesToSearchQuery << "SELECT id, table_id, engine_type, file_id, file_type, row_count, date " <<
969 970 971 972 973 974 975 976 977 978
                                   "FROM TableFiles " <<
                                   "WHERE table_id = " << quote << table_id << " AND " <<
                                   "date IN (" << partitionListStr << ") 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();
979 980

            }
981
        } //Scoped Connection
982

983 984 985 986 987 988
        TableSchema table_schema;
        table_schema.table_id_ = table_id;
        auto status = DescribeTable(table_schema);
        if (!status.ok()) {
            return status;
        }
989

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

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

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

999
            table_file.engine_type_ = resRow["engine_type"];
1000

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

1005
            table_file.file_type_ = resRow["file_type"];
1006

1007
            table_file.row_count_ = resRow["row_count"];
1008

1009
            table_file.date_ = resRow["date"];
1010

1011 1012 1013
            table_file.dimension_ = table_schema.dimension_;

            utils::GetTableFilePath(options_, table_file);
X
xj.lin 已提交
1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051

            auto dateItr = files.find(table_file.date_);
            if (dateItr == files.end()) {
                files[table_file.date_] = TableFilesSchema();
            }

            files[table_file.date_].push_back(table_file);
        }
    } 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());
    }

    return Status::OK();
}

Status MySQLMetaImpl::FilesToSearch(const std::string &table_id,
                                    const std::vector<size_t> &ids,
                                    const DatesT &partition,
                                    DatePartionedTableFilesSchema &files) {
    files.clear();

    try {
        MetricCollector metric;
        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();
1052
            filesToSearchQuery << "SELECT id, table_id, engine_type, file_id, file_type, row_count, date " <<
X
xj.lin 已提交
1053 1054 1055 1056 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 1109 1110 1111 1112
                               "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;

            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"];

1113
            table_file.row_count_ = resRow["row_count"];
X
xj.lin 已提交
1114 1115 1116 1117 1118 1119

            table_file.date_ = resRow["date"];

            table_file.dimension_ = table_schema.dimension_;

            utils::GetTableFilePath(options_, table_file);
1120

1121 1122 1123
            auto dateItr = files.find(table_file.date_);
            if (dateItr == files.end()) {
                files[table_file.date_] = TableFilesSchema();
1124 1125
            }

1126
            files[table_file.date_].push_back(table_file);
1127
        }
1128 1129 1130 1131 1132 1133 1134 1135
    } 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 已提交
1136 1137
    }

1138 1139
    return Status::OK();
}
Z
update  
zhiru 已提交
1140

1141 1142 1143
Status MySQLMetaImpl::FilesToMerge(const std::string &table_id,
                                   DatePartionedTableFilesSchema &files) {
    files.clear();
Z
update  
zhiru 已提交
1144

1145 1146 1147 1148 1149
    try {
        MetricCollector metric;
        StoreQueryResult res;
        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);
Z
update  
zhiru 已提交
1150

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

1155
            Query filesToMergeQuery = connectionPtr->query();
1156
            filesToMergeQuery << "SELECT id, table_id, file_id, file_type, file_size, date " <<
1157 1158 1159
                              "FROM TableFiles " <<
                              "WHERE table_id = " << quote << table_id << " AND " <<
                              "file_type = " << std::to_string(TableFileSchema::RAW) << " " <<
1160
                              "ORDER BY row_count DESC" << ";";
Z
update  
zhiru 已提交
1161

1162
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::FilesToMerge: " << filesToMergeQuery.str();
1163

1164 1165
            res = filesToMergeQuery.store();
        } //Scoped Connection
1166

1167 1168 1169
        TableSchema table_schema;
        table_schema.table_id_ = table_id;
        auto status = DescribeTable(table_schema);
Z
update  
zhiru 已提交
1170

1171 1172 1173
        if (!status.ok()) {
            return status;
        }
1174

1175 1176
        TableFileSchema table_file;
        for (auto &resRow : res) {
Z
update  
zhiru 已提交
1177

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

1180 1181 1182
            std::string table_id_str;
            resRow["table_id"].to_string(table_id_str);
            table_file.table_id_ = table_id_str;
Z
update  
zhiru 已提交
1183

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

1188
            table_file.file_type_ = resRow["file_type"];
1189

1190
            table_file.file_size_ = resRow["file_size"];
1191

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

1194
            table_file.dimension_ = table_schema.dimension_;
Z
update  
zhiru 已提交
1195

1196
            utils::GetTableFilePath(options_, table_file);
Z
update  
zhiru 已提交
1197

1198 1199 1200
            auto dateItr = files.find(table_file.date_);
            if (dateItr == files.end()) {
                files[table_file.date_] = TableFilesSchema();
1201
            }
1202 1203

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

1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222
    } 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 已提交
1223 1224 1225
        return Status::OK();
    }

1226 1227 1228 1229 1230 1231
    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 已提交
1232

1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243
    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();
1244
            getTableFileQuery << "SELECT id, engine_type, file_id, file_type, file_size, row_count, date " <<
1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258
                              "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;
1259 1260
        }

1261
        for (auto &resRow : res) {
Z
zhiru 已提交
1262

1263
            TableFileSchema file_schema;
1264

1265
            file_schema.id_ = resRow["id"];
Z
zhiru 已提交
1266

1267
            file_schema.table_id_ = table_id;
Z
update  
zhiru 已提交
1268

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

1271 1272 1273
            std::string file_id;
            resRow["file_id"].to_string(file_id);
            file_schema.file_id_ = file_id;
Z
update  
zhiru 已提交
1274

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

1277 1278 1279
            file_schema.file_size_ = resRow["file_size"];

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

1281
            file_schema.date_ = resRow["date"];
1282

1283
            file_schema.dimension_ = table_schema.dimension_;
Z
update  
zhiru 已提交
1284

1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296
            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 已提交
1297 1298
    }

1299 1300
    return Status::OK();
}
Z
zhiru 已提交
1301

1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316
// 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 已提交
1317
                ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);
Z
zhiru 已提交
1318

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

1323 1324 1325 1326 1327
                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 已提交
1328

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

1331 1332 1333
                if (!archiveQuery.exec()) {
                    return Status::DBTransactionError("QUERY ERROR DURING ARCHIVE", archiveQuery.error());
                }
1334

1335 1336 1337 1338 1339 1340 1341 1342
            } 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 已提交
1343
            }
1344
        }
1345 1346 1347
        if (criteria == "disk") {
            uint64_t sum = 0;
            Size(sum);
Z
update  
zhiru 已提交
1348

1349 1350 1351
            auto to_delete = (sum - limit * G);
            DiscardFiles(to_delete);
        }
Z
update  
zhiru 已提交
1352 1353
    }

1354 1355
    return Status::OK();
}
Z
zhiru 已提交
1356

1357 1358
Status MySQLMetaImpl::Size(uint64_t &result) {
    result = 0;
1359

S
starlord 已提交
1360
    try {
1361 1362 1363
        StoreQueryResult res;
        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);
1364

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

Z
update  
zhiru 已提交
1369

1370
            Query getSizeQuery = connectionPtr->query();
1371
            getSizeQuery << "SELECT IFNULL(SUM(file_size),0) AS sum " <<
1372 1373
                         "FROM TableFiles " <<
                         "WHERE file_type <> " << std::to_string(TableFileSchema::TO_DELETE) << ";";
Z
update  
zhiru 已提交
1374

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

1377 1378
            res = getSizeQuery.store();
        } //Scoped Connection
Z
update  
zhiru 已提交
1379

1380 1381 1382 1383 1384
        if (res.empty()) {
            result = 0;
        } else {
            result = res[0]["sum"];
        }
Z
update  
zhiru 已提交
1385

1386 1387 1388 1389 1390 1391 1392 1393 1394
    } 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());
    }
1395

1396 1397
    return Status::OK();
}
1398

1399 1400 1401 1402
Status MySQLMetaImpl::DiscardFiles(long long to_discard_size) {
    if (to_discard_size <= 0) {

        return Status::OK();
Z
update  
zhiru 已提交
1403
    }
1404
    ENGINE_LOG_DEBUG << "About to discard size=" << to_discard_size;
Z
update  
zhiru 已提交
1405

1406 1407 1408 1409 1410
    try {
        MetricCollector metric;
        bool status;
        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);
1411

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

1416
            Query discardFilesQuery = connectionPtr->query();
1417
            discardFilesQuery << "SELECT id, file_size " <<
1418 1419 1420 1421
                              "FROM TableFiles " <<
                              "WHERE file_type <> " << std::to_string(TableFileSchema::TO_DELETE) << " " <<
                              "ORDER BY id ASC " <<
                              "LIMIT 10;";
Z
update  
zhiru 已提交
1422

1423
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::DiscardFiles: " << discardFilesQuery.str();
1424

1425 1426 1427 1428
            StoreQueryResult res = discardFilesQuery.store();
            if (res.num_rows() == 0) {
                return Status::OK();
            }
1429

1430 1431 1432 1433 1434
            TableFileSchema table_file;
            std::stringstream idsToDiscardSS;
            for (auto &resRow : res) {
                if (to_discard_size <= 0) {
                    break;
Z
update  
zhiru 已提交
1435
                }
1436
                table_file.id_ = resRow["id"];
1437
                table_file.file_size_ = resRow["file_size"];
1438 1439
                idsToDiscardSS << "id = " << std::to_string(table_file.id_) << " OR ";
                ENGINE_LOG_DEBUG << "Discard table_file.id=" << table_file.file_id_
1440 1441
                                 << " table_file.size=" << table_file.file_size_;
                to_discard_size -= table_file.file_size_;
1442
            }
Z
update  
zhiru 已提交
1443

1444 1445
            std::string idsToDiscardStr = idsToDiscardSS.str();
            idsToDiscardStr = idsToDiscardStr.substr(0, idsToDiscardStr.size() - 4); //remove the last " OR "
1446

1447 1448 1449 1450
            discardFilesQuery << "UPDATE TableFiles " <<
                              "SET file_type = " << std::to_string(TableFileSchema::TO_DELETE) << ", " <<
                              "updated_time = " << std::to_string(utils::GetMicroSecTimeStamp()) << " " <<
                              "WHERE " << idsToDiscardStr << ";";
1451

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

1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470
            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 已提交
1471
    }
1472
}
P
peng.xu 已提交
1473

1474 1475 1476
//ZR: this function assumes all fields in file_schema have value
Status MySQLMetaImpl::UpdateTableFile(TableFileSchema &file_schema) {
    file_schema.updated_time_ = utils::GetMicroSecTimeStamp();
1477

S
starlord 已提交
1478
    try {
1479 1480 1481
        MetricCollector metric;
        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);
Z
update  
zhiru 已提交
1482

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

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

1489 1490 1491 1492
            //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 已提交
1493

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

1496
            StoreQueryResult res = updateTableFileQuery.store();
1497

1498 1499 1500 1501
            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 已提交
1502
                }
1503 1504 1505 1506 1507 1508 1509 1510 1511
            } 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_);
1512 1513
            std::string file_size = std::to_string(file_schema.file_size_);
            std::string row_count = std::to_string(file_schema.row_count_);
1514 1515 1516
            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 已提交
1517

1518 1519 1520 1521 1522
            updateTableFileQuery << "UPDATE TableFiles " <<
                                 "SET table_id = " << quote << table_id << ", " <<
                                 "engine_type = " << engine_type << ", " <<
                                 "file_id = " << quote << file_id << ", " <<
                                 "file_type = " << file_type << ", " <<
1523 1524
                                 "file_size = " << file_size << ", " <<
                                 "row_count = " << row_count << ", " <<
1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553
                                 "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();
}
1554

1555 1556 1557
Status MySQLMetaImpl::UpdateTableFilesToIndex(const std::string &table_id) {
    try {
        ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);
1558

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

1563
        Query updateTableFilesToIndexQuery = connectionPtr->query();
Z
zhiru 已提交
1564

1565
        updateTableFilesToIndexQuery << "UPDATE TableFiles " <<
Z
fix  
zhiru 已提交
1566 1567 1568
                                     "SET file_type = " << std::to_string(TableFileSchema::TO_INDEX) << " " <<
                                     "WHERE table_id = " << quote << table_id << " AND " <<
                                     "file_type = " << std::to_string(TableFileSchema::RAW) << ";";
1569

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

Z
fix  
zhiru 已提交
1572 1573 1574 1575 1576 1577
        if (!updateTableFilesToIndexQuery.exec()) {
            ENGINE_LOG_ERROR << "QUERY ERROR WHEN UPDATING TABLE FILE";
            return Status::DBTransactionError("QUERY ERROR WHEN UPDATING TABLE FILE",
                                              updateTableFilesToIndexQuery.error());
        }

1578 1579 1580 1581 1582 1583 1584 1585 1586
    } 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 已提交
1587

1588 1589
    return Status::OK();
}
Z
zhiru 已提交
1590

1591 1592 1593 1594 1595 1596 1597 1598 1599
Status MySQLMetaImpl::UpdateTableFiles(TableFilesSchema &files) {
    try {
        MetricCollector metric;
        {
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);

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

1601
            Query updateTableFilesQuery = connectionPtr->query();
1602

1603 1604
            std::map<std::string, bool> has_tables;
            for (auto &file_schema : files) {
1605

1606 1607 1608
                if (has_tables.find(file_schema.table_id_) != has_tables.end()) {
                    continue;
                }
1609

1610 1611 1612 1613 1614
                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" << ";";
1615

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

1618
                StoreQueryResult res = updateTableFilesQuery.store();
1619

1620 1621 1622
                int check = res[0]["check"];
                has_tables[file_schema.table_id_] = (check == 1);
            }
1623

1624
            for (auto &file_schema : files) {
1625

1626 1627
                if (!has_tables[file_schema.table_id_]) {
                    file_schema.file_type_ = TableFileSchema::TO_DELETE;
1628
                }
1629
                file_schema.updated_time_ = utils::GetMicroSecTimeStamp();
1630

1631 1632 1633 1634 1635
                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_);
1636 1637
                std::string file_size = std::to_string(file_schema.file_size_);
                std::string row_count = std::to_string(file_schema.row_count_);
1638 1639 1640
                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 已提交
1641

1642 1643 1644 1645 1646
                updateTableFilesQuery << "UPDATE TableFiles " <<
                                      "SET table_id = " << quote << table_id << ", " <<
                                      "engine_type = " << engine_type << ", " <<
                                      "file_id = " << quote << file_id << ", " <<
                                      "file_type = " << file_type << ", " <<
1647 1648
                                      "file_size = " << file_size << ", " <<
                                      "row_count = " << row_count << ", " <<
1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672
                                      "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 已提交
1673

1674 1675
    return Status::OK();
}
Z
fix  
zhiru 已提交
1676

1677 1678
Status MySQLMetaImpl::CleanUpFilesWithTTL(uint16_t seconds) {
    auto now = utils::GetMicroSecTimeStamp();
S
starlord 已提交
1679 1680 1681
    std::set<std::string> table_ids;

    //remove to_delete files
1682 1683
    try {
        MetricCollector metric;
1684

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

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

1692 1693 1694 1695 1696
            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 已提交
1697

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

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

1702 1703
            TableFileSchema table_file;
            std::vector<std::string> idsToDelete;
1704

1705
            for (auto &resRow : res) {
1706

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

1709 1710 1711
                std::string table_id;
                resRow["table_id"].to_string(table_id);
                table_file.table_id_ = table_id;
Z
fix  
zhiru 已提交
1712

1713 1714 1715
                std::string file_id;
                resRow["file_id"].to_string(file_id);
                table_file.file_id_ = file_id;
Z
update  
zhiru 已提交
1716

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

1719 1720
                utils::DeleteTableFilePath(options_, table_file);

S
starlord 已提交
1721
                ENGINE_LOG_DEBUG << "Removing file id:" << table_file.id_ << " location:" << table_file.location_;
1722 1723

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

                table_ids.insert(table_file.table_id_);
1726 1727 1728 1729 1730 1731 1732
            }

            if (!idsToDelete.empty()) {

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

1735 1736 1737 1738
                std::string idsToDeleteStr = idsToDeleteSS.str();
                idsToDeleteStr = idsToDeleteStr.substr(0, idsToDeleteStr.size() - 4); //remove the last " OR "
                cleanUpFilesWithTTLQuery << "DELETE FROM TableFiles WHERE " <<
                                         idsToDeleteStr << ";";
1739

1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757
                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 已提交
1758
    }
1759

S
starlord 已提交
1760
    //remove to_delete tables
1761 1762 1763 1764
    try {
        MetricCollector metric;

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

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

1771 1772 1773 1774
            Query cleanUpFilesWithTTLQuery = connectionPtr->query();
            cleanUpFilesWithTTLQuery << "SELECT id, table_id " <<
                                     "FROM Tables " <<
                                     "WHERE state = " << std::to_string(TableSchema::TO_DELETE) << ";";
1775

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

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

Z
update  
zhiru 已提交
1780 1781
            if (!res.empty()) {

1782 1783 1784 1785 1786
                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 已提交
1787

S
starlord 已提交
1788
                    utils::DeleteTablePath(options_, table_id, false);//only delete empty folder
1789 1790

                    idsToDeleteSS << "id = " << std::to_string(id) << " OR ";
Z
update  
zhiru 已提交
1791
                }
1792 1793 1794 1795
                std::string idsToDeleteStr = idsToDeleteSS.str();
                idsToDeleteStr = idsToDeleteStr.substr(0, idsToDeleteStr.size() - 4); //remove the last " OR "
                cleanUpFilesWithTTLQuery << "DELETE FROM Tables WHERE " <<
                                         idsToDeleteStr << ";";
1796

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

1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814
                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 已提交
1815 1816
    }

S
starlord 已提交
1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832
    //remove deleted table folder
    //don't remove table folder until all its files has been deleted
    try {
        MetricCollector metric;

        {
            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 已提交
1833
                                         "WHERE table_id = " << quote << table_id << ";";
S
starlord 已提交
1834 1835 1836 1837 1838 1839 1840 1841 1842 1843

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

                StoreQueryResult res = cleanUpFilesWithTTLQuery.store();

                if (res.empty()) {
                    utils::DeleteTablePath(options_, table_id);
                }
            }
        }
S
starlord 已提交
1844 1845 1846 1847
    } 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 已提交
1848 1849 1850 1851 1852 1853
    } 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());
    }

1854 1855
    return Status::OK();
}
1856

1857 1858 1859
Status MySQLMetaImpl::CleanUp() {
    try {
        ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);
1860

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

1865 1866 1867 1868 1869
        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 已提交
1870

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

1873
        StoreQueryResult res = cleanUpQuery.store();
Z
update  
zhiru 已提交
1874

1875 1876
        if (!res.empty()) {
            ENGINE_LOG_DEBUG << "Remove table file type as NEW";
1877 1878 1879 1880
            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) << ");";
1881

1882
            ENGINE_LOG_DEBUG << "MySQLMetaImpl::CleanUp: " << cleanUpQuery.str();
1883

1884 1885 1886
            if (!cleanUpQuery.exec()) {
                ENGINE_LOG_ERROR << "QUERY ERROR WHEN CLEANING UP FILES";
                return Status::DBTransactionError("Clean up Error", cleanUpQuery.error());
Z
update  
zhiru 已提交
1887
            }
1888
        }
1889 1890 1891 1892 1893 1894 1895 1896 1897

    } 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 已提交
1898 1899
    }

1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912
    return Status::OK();
}

Status MySQLMetaImpl::Count(const std::string &table_id, uint64_t &result) {
    try {
        MetricCollector metric;

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

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

1915 1916
        StoreQueryResult res;
        {
Z
update  
zhiru 已提交
1917
            ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);
Z
zhiru 已提交
1918

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

Z
update  
zhiru 已提交
1923

1924 1925 1926 1927 1928 1929 1930
            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 已提交
1931

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

1934 1935 1936 1937 1938 1939 1940
            res = countQuery.store();
        } //Scoped Connection

        result = 0;
        for (auto &resRow : res) {
            size_t size = resRow["size"];
            result += size;
1941
        }
1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960

        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 已提交
1961
    }
S
starlord 已提交
1962

1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974
    return Status::OK();
}

Status MySQLMetaImpl::DropAll() {
    if (boost::filesystem::is_directory(options_.path)) {
        boost::filesystem::remove_all(options_.path);
    }
    try {
        ScopedConnection connectionPtr(*mysql_connection_pool_, safe_grab);

        if (connectionPtr == nullptr) {
            return Status::Error("Failed to connect to database server");
Z
zhiru 已提交
1975
        }
1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996

        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 已提交
1997

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

MySQLMetaImpl::~MySQLMetaImpl() {
    if (mode_ != Options::MODE::READ_ONLY) {
        CleanUp();
Z
update  
zhiru 已提交
2004
    }
2005
}
Z
update  
zhiru 已提交
2006 2007 2008 2009 2010

} // namespace meta
} // namespace engine
} // namespace milvus
} // namespace zilliz