polardbxengine/sql/server_component/page_track_service.cc

195 lines
5.4 KiB
C++

/* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include <components/mysql_server/mysql_page_track.h>
#include <sql/handler.h>
#include <sql/sql_class.h>
void page_track_service_init() { return; }
/** Check if thd has backup privilige.
@param[in] thd thread context
@return 0 if thd has backup privilege, else 1 */
bool check_backup_privilege(MYSQL_THD thd) {
auto sctx = thd->security_context();
if (!(sctx->has_global_grant(STRING_WITH_LEN("BACKUP_ADMIN")).first)) {
my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "BACKUP_ADMIN");
return (1);
}
return (0);
}
DEFINE_METHOD(int, Page_track_implementation::start,
(MYSQL_THD opaque_thd, Page_Track_SE se_type,
uint64_t *start_id)) {
if (check_backup_privilege(opaque_thd)) {
return (ER_SPECIFIC_ACCESS_DENIED_ERROR);
}
DBUG_ASSERT(se_type == PAGE_TRACK_SE_INNODB);
enum legacy_db_type db_type;
switch (se_type) {
case PAGE_TRACK_SE_INNODB:
db_type = DB_TYPE_INNODB;
break;
}
handlerton *ddse = ha_resolve_by_legacy_type(opaque_thd, db_type);
return (ddse->page_track.start(start_id));
}
DEFINE_METHOD(int, Page_track_implementation::stop,
(MYSQL_THD opaque_thd, Page_Track_SE se_type,
uint64_t *stop_id)) {
if (check_backup_privilege(opaque_thd)) {
return (ER_SPECIFIC_ACCESS_DENIED_ERROR);
}
DBUG_ASSERT(se_type == PAGE_TRACK_SE_INNODB);
enum legacy_db_type db_type = DB_TYPE_UNKNOWN;
switch (se_type) {
case PAGE_TRACK_SE_INNODB:
db_type = DB_TYPE_INNODB;
break;
}
handlerton *ddse = ha_resolve_by_legacy_type(opaque_thd, db_type);
return (ddse->page_track.stop(stop_id));
}
DEFINE_METHOD(int, Page_track_implementation::purge,
(MYSQL_THD opaque_thd, Page_Track_SE se_type,
uint64_t *purge_id)) {
if (check_backup_privilege(opaque_thd)) {
return (ER_SPECIFIC_ACCESS_DENIED_ERROR);
}
DBUG_ASSERT(se_type == PAGE_TRACK_SE_INNODB);
enum legacy_db_type db_type = DB_TYPE_UNKNOWN;
switch (se_type) {
case PAGE_TRACK_SE_INNODB:
db_type = DB_TYPE_INNODB;
break;
}
handlerton *ddse = ha_resolve_by_legacy_type(opaque_thd, db_type);
return (ddse->page_track.purge(purge_id));
}
DEFINE_METHOD(int, Page_track_implementation::get_page_ids,
(MYSQL_THD opaque_thd, Page_Track_SE se_type, uint64_t *start_id,
uint64_t *stop_id, unsigned char *buffer, size_t buffer_len,
Page_Track_Callback cbk_func, void *cbk_ctx)) {
if (check_backup_privilege(opaque_thd)) {
return (ER_SPECIFIC_ACCESS_DENIED_ERROR);
}
DBUG_ASSERT(se_type == PAGE_TRACK_SE_INNODB);
enum legacy_db_type db_type = DB_TYPE_UNKNOWN;
switch (se_type) {
case PAGE_TRACK_SE_INNODB:
db_type = DB_TYPE_INNODB;
break;
}
handlerton *ddse = ha_resolve_by_legacy_type(opaque_thd, db_type);
return (ddse->page_track.get_page_ids(cbk_func, cbk_ctx, start_id, stop_id,
buffer, buffer_len));
}
DEFINE_METHOD(int, Page_track_implementation::get_num_page_ids,
(MYSQL_THD opaque_thd, Page_Track_SE se_type, uint64_t *start_id,
uint64_t *stop_id, uint64_t *num_pages)) {
if (check_backup_privilege(opaque_thd)) {
return (ER_SPECIFIC_ACCESS_DENIED_ERROR);
}
DBUG_ASSERT(se_type == PAGE_TRACK_SE_INNODB);
enum legacy_db_type db_type = DB_TYPE_UNKNOWN;
switch (se_type) {
case PAGE_TRACK_SE_INNODB:
db_type = DB_TYPE_INNODB;
break;
}
handlerton *ddse = ha_resolve_by_legacy_type(opaque_thd, db_type);
return (ddse->page_track.get_num_page_ids(start_id, stop_id, num_pages));
}
DEFINE_METHOD(int, Page_track_implementation::get_status,
(MYSQL_THD opaque_thd, Page_Track_SE se_type,
uint64_t *initial_start_id, uint64_t *last_start_id)) {
if (check_backup_privilege(opaque_thd)) {
return (ER_SPECIFIC_ACCESS_DENIED_ERROR);
}
DBUG_ASSERT(se_type == PAGE_TRACK_SE_INNODB);
*initial_start_id = 0;
*last_start_id = 0;
enum legacy_db_type db_type = DB_TYPE_UNKNOWN;
switch (se_type) {
case PAGE_TRACK_SE_INNODB:
db_type = DB_TYPE_INNODB;
break;
}
handlerton *ddse = ha_resolve_by_legacy_type(opaque_thd, db_type);
/** Vector of a pair of (ID, bool) where ID is the start/stop point and bool
is true if the ID is a start point else false */
static std::vector<std::pair<uint64_t, bool>> status;
status.clear();
ddse->page_track.get_status(status);
if (status.size() == 0) {
return (false);
}
bool is_active = (status.back().second == true);
if (is_active) {
*last_start_id = status.back().first;
for (auto rit = status.rbegin(); rit != status.rend(); ++rit) {
if (rit->second == false) {
break;
}
*initial_start_id = rit->first;
}
}
return (is_active);
}