polardbxengine/storage/innobase/srv/srv0file.cc

160 lines
5.3 KiB
C++

/* Copyright (c) 2018, 2021, Alibaba 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, version 2.0,
as published by the Free Software Foundation.
This program is also distributed with certain software (including
but not limited to OpenSSL) that is licensed under separate terms,
as designated in a particular file or component or in included license
documentation. The authors of MySQL/PolarDB-X Engine hereby grant you an
additional permission to link the program and your derivative works with the
separately licensed software that they have included with
MySQL/PolarDB-X Engine.
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, version 2.0, 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 */
/** @file srv/srv0file.cc
Service of data file purge operation.
Created 1/11/2019 Galaxy SQL
*******************************************************/
#include "fil0purge.h"
#include "my_inttypes.h"
#include "sql/mysqld.h"
#include "sql/mysqld_thd_manager.h"
#include "srv0start.h"
#include "srv0file.h"
#ifdef UNIV_PFS_THREAD
/* File purge thread PFS key */
mysql_pfs_key_t srv_file_purge_thread_key;
#endif
#ifdef UNIV_PFS_MUTEX
/* File purge list mutex PFS key */
mysql_pfs_key_t file_purge_list_mutex_key;
#endif
/** Whether enable the data file purge background little by little */
bool srv_data_file_purge = false;
/** Whether unlink the file immediately by purge thread */
bool srv_data_file_purge_immediate = false;
/** Whether purge all when normal shutdown */
bool srv_data_file_purge_all_at_shutdown = false;
/** Time interval (milliseconds) every data file purge operation */
ulong srv_data_file_purge_interval = 100;
/** Max size (MB) every data file purge operation */
ulong srv_data_file_purge_max_size = 512;
/** The directory that purged data file will be removed into */
char *srv_data_file_purge_dir = nullptr;
/** Whether to print data file purge process */
bool srv_print_data_file_purge_process = false;
/** Indicate whether file purge system initted */
static bool file_purge_system_inited = false;
/** Purge thread event condition */
os_event_t file_purge_event;
/** Data file purge system initialize when InnoDB server boots */
void srv_file_purge_init() {
file_purge_sys = UT_NEW_NOKEY(
File_purge(Global_THD_manager::reserved_thread_id, server_start_time));
file_purge_event = os_event_create(0);
/** If not setting special directory, inherit MySQL datadir directly. */
if (srv_data_file_purge_dir) {
os_file_type_t type;
bool exists;
bool success = os_file_status(srv_data_file_purge_dir, &exists, &type);
if (success && exists) {
/* If directory has existed, set dir directly */
file_purge_sys->set_dir(srv_data_file_purge_dir);
} else if ((os_file_create_subdirs_if_needed(srv_data_file_purge_dir) ==
DB_SUCCESS) &&
(os_file_create_directory(srv_data_file_purge_dir, false))) {
/* If not exist, try to create dir */
file_purge_sys->set_dir(srv_data_file_purge_dir);
} else {
/* Defaultly use innodb data dir */
file_purge_sys->set_dir(MySQL_datadir_path);
}
} else { /* srv_data_file_purge_dir is null */
file_purge_sys->set_dir(MySQL_datadir_path);
}
file_purge_system_inited = true;
}
/** Data file purge system destroy when InnoDB server shutdown */
void srv_file_purge_destroy() {
UT_DELETE(file_purge_sys);
os_event_destroy(file_purge_event);
file_purge_system_inited = false;
}
/* Data file purge thread runtime */
void srv_file_purge_thread(void) {
int64_t sig_count;
ut_a(file_purge_sys);
int truncated = 0;
ulint truncated_size = 0;
ulong max_size;
loop:
max_size = srv_data_file_purge_max_size * 1024 * 1024;
std::pair<int, ulint> result =
file_purge_sys->purge_file(max_size, srv_data_file_purge_immediate);
truncated = result.first;
truncated_size += result.second;
if (truncated <= 0) {
sig_count = os_event_reset(file_purge_event);
os_event_wait_time_low(file_purge_event, 5000000, sig_count);
truncated_size = 0;
} else if (truncated > 0) {
if (truncated_size >= max_size) {
os_thread_sleep(srv_data_file_purge_interval * 1000);
truncated_size = 0;
}
}
if (srv_shutdown_state.load() >= SRV_SHUTDOWN_CLEANUP) goto exit_func;
goto loop;
exit_func:
/**
Purge all renamed tmp data file requirement when shutdown:
- innodb_fast_shutdown = 0 or 1;
- innodb_data_file_purge_all_at_shutdown is true;
It will unlink files regardless of file size.
*/
if (srv_fast_shutdown < 2 && srv_data_file_purge_all_at_shutdown) {
ib::info(ER_IB_MSG_FP_CLEANUP, file_purge_sys->length());
file_purge_sys->purge_all(srv_data_file_purge_max_size * 1024 * 1024, true);
ib::info(ER_IB_MSG_FP_COMPLETE);
}
}
/** Wakeup the background thread when shutdown */
void srv_wakeup_file_purge_thread() { os_event_set(file_purge_event); }