Skip to content

Commit

Permalink
FB8-52: Slowing down transaction log init (facebook#931) (facebook#931)
Browse files Browse the repository at this point in the history
Summary:
JIRA: https://jira.percona.com/browse/FB8-52

Reference Patch: facebook@80ca845
Reference Patch: facebook@0fb428b

Patch introduces new variable 'innodb_txlog_init_rate' to limit
the IO rate of InnoDB redo log file initialization.
Pull Request resolved: facebook#931

Reviewed By: lloyd

Differential Revision: D13789095 (facebook@48615c4)

Pulled By: lth

fbshipit-source-id: d667be91978
  • Loading branch information
satya-bodapati authored and inikep committed Jul 12, 2021
1 parent e70e108 commit e5cdb5b
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 8 deletions.
25 changes: 25 additions & 0 deletions mysql-test/suite/sys_vars/r/innodb_txlog_init_rate_basic.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
SET @orig_txlog_init_rate = @@global.innodb_txlog_init_rate;
SELECT @orig_txlog_init_rate;
@orig_txlog_init_rate
134217728
SET GLOBAL innodb_txlog_init_rate = 500*1024*1024;
SELECT @@global.innodb_txlog_init_rate;
@@global.innodb_txlog_init_rate
524288000
SET GLOBAL innodb_txlog_init_rate = 0;
SELECT @@global.innodb_txlog_init_rate;
@@global.innodb_txlog_init_rate
0
SET GLOBAL innodb_txlog_init_rate = -1;
Warnings:
Warning 1292 Truncated incorrect innodb_txlog_init_rate value: '-1'
SELECT @@global.innodb_txlog_init_rate;
@@global.innodb_txlog_init_rate
0
SET GLOBAL innodb_txlog_init_rate = 12345;
Warnings:
Warning 1292 Truncated incorrect innodb_txlog_init_rate value: '12345'
SELECT @@global.innodb_txlog_init_rate;
@@global.innodb_txlog_init_rate
0
SET GLOBAL innodb_txlog_init_rate = @orig_txlog_init_rate;
22 changes: 22 additions & 0 deletions mysql-test/suite/sys_vars/t/innodb_txlog_init_rate_basic.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
SET @orig_txlog_init_rate = @@global.innodb_txlog_init_rate;

SELECT @orig_txlog_init_rate;

# 500MB/s
SET GLOBAL innodb_txlog_init_rate = 500*1024*1024;
SELECT @@global.innodb_txlog_init_rate;

# min value
SET GLOBAL innodb_txlog_init_rate = 0;
SELECT @@global.innodb_txlog_init_rate;

# invalid value
# too small
SET GLOBAL innodb_txlog_init_rate = -1;
SELECT @@global.innodb_txlog_init_rate;

# not bound to page size
SET GLOBAL innodb_txlog_init_rate = 12345;
SELECT @@global.innodb_txlog_init_rate;

SET GLOBAL innodb_txlog_init_rate = @orig_txlog_init_rate;
8 changes: 8 additions & 0 deletions storage/innobase/handler/ha_innodb.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22141,6 +22141,13 @@ static MYSQL_SYSVAR_ULONGLONG(
"entire file at once before closing it.",
nullptr, nullptr, 0, 0, ~0ULL, UNIV_PAGE_SIZE);

static MYSQL_SYSVAR_ULONGLONG(
txlog_init_rate, os_txlog_init_rate, PLUGIN_VAR_OPCMDARG,
"The value of this variable determines how fast (in bytes/s) InnoDB "
"initializes the transaction log when creating a new file"
"Setting this value to 0 means no limit. Default is 128MB",
nullptr, nullptr, 1ULL << 27, 0ULL, ULONG_MAX, 1ULL << 20);

static MYSQL_SYSVAR_ULONG(thread_concurrency, srv_thread_concurrency,
PLUGIN_VAR_RQCMDARG,
"Helps in performance tuning in heavily concurrent "
Expand Down Expand Up @@ -22675,6 +22682,7 @@ static SYS_VAR *innobase_system_variables[] = {
MYSQL_SYSVAR(spin_wait_delay),
MYSQL_SYSVAR(spin_wait_pause_multiplier),
MYSQL_SYSVAR(fsync_threshold),
MYSQL_SYSVAR(txlog_init_rate),
MYSQL_SYSVAR(table_locks),
MYSQL_SYSVAR(thread_concurrency),
MYSQL_SYSVAR(adaptive_max_sleep_delay),
Expand Down
13 changes: 9 additions & 4 deletions storage/innobase/include/os0file.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ extern std::atomic<ulint> os_n_pending_writes;
/* Flush after each os_fsync_threshold bytes */
extern unsigned long long os_fsync_threshold;

/** This is used to limit the IO write rate during
initalization of redo log. Unit is bytes/second */
extern unsigned long long os_txlog_init_rate;

/** Number of outstanding aio requests */
extern std::atomic<ulint> os_aio_n_outstanding;
#ifdef UNIV_DEBUG
Expand Down Expand Up @@ -670,7 +674,6 @@ enum class AIO_mode : size_t {
extern ulint os_n_file_reads;
extern ulint os_n_file_writes;
extern ulint os_n_fsyncs;

/* File types for directory entry data type */

enum os_file_type_t {
Expand Down Expand Up @@ -1482,7 +1485,8 @@ zeros otherwise.
@return true if success */
bool os_file_set_size_fast(const char *name, pfs_os_file_t file,
os_offset_t offset, os_offset_t size, bool read_only,
bool flush) MY_ATTRIBUTE((warn_unused_result));
bool flush, bool throttle = false)
MY_ATTRIBUTE((warn_unused_result));

/** Write the specified number of zeros to a file from specific offset.
@param[in] name name of the file or path as a null-terminated
Expand All @@ -1492,10 +1496,11 @@ bool os_file_set_size_fast(const char *name, pfs_os_file_t file,
@param[in] size file size
@param[in] read_only enable read-only checks if true
@param[in] flush flush file content to disk
@param[in] throttle throttle the initialization IO write rate
@return true if success */
bool os_file_set_size(const char *name, pfs_os_file_t file, os_offset_t offset,
os_offset_t size, bool read_only, bool flush)
MY_ATTRIBUTE((warn_unused_result));
os_offset_t size, bool read_only, bool flush,
bool throttle = false) MY_ATTRIBUTE((warn_unused_result));

/** Truncates a file at its current position.
@param[in,out] file file to be truncated
Expand Down
21 changes: 18 additions & 3 deletions storage/innobase/os/os0file.cc
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
/* Flush after each os_fsync_threshold bytes */
unsigned long long os_fsync_threshold = 0;

/* Redo log initialization rate (128MB) */
unsigned long long os_txlog_init_rate = 1ULL << 27;

/** Insert buffer segment id */
static const ulint IO_IBUF_SEGMENT = 0;

Expand Down Expand Up @@ -5639,7 +5642,7 @@ void os_file_set_nocache(int fd MY_ATTRIBUTE((unused)),

bool os_file_set_size_fast(const char *name, pfs_os_file_t pfs_file,
os_offset_t offset, os_offset_t size, bool read_only,
bool flush) {
bool flush, bool throttle) {
#if !defined(NO_FALLOCATE) && defined(UNIV_LINUX) && \
defined(HAVE_FALLOC_FL_ZERO_RANGE)
ut_a(size >= offset);
Expand Down Expand Up @@ -5667,11 +5670,13 @@ bool os_file_set_size_fast(const char *name, pfs_os_file_t pfs_file,
}
#endif /* !NO_FALLOCATE && UNIV_LINUX && HAVE_FALLOC_FL_ZERO_RANGE */

return os_file_set_size(name, pfs_file, offset, size, read_only, flush);
return os_file_set_size(name, pfs_file, offset, size, read_only, flush,
throttle);
}

bool os_file_set_size(const char *name, pfs_os_file_t file, os_offset_t offset,
os_offset_t size, bool read_only, bool flush) {
os_offset_t size, bool read_only, bool flush,
bool throttle) {
/* Write up to FSP_EXTENT_SIZE bytes at a time. */
ulint buf_size = 0;

Expand Down Expand Up @@ -5701,6 +5706,7 @@ bool os_file_set_size(const char *name, pfs_os_file_t file, os_offset_t offset,
/* Count to check and print progress of file write for file_size > 100 MB. */
uint percentage_count = 10;

ulonglong start_time = my_timer_now();
while (current_size < size) {
ulint n_bytes;

Expand Down Expand Up @@ -5730,6 +5736,15 @@ bool os_file_set_size(const char *name, pfs_os_file_t file, os_offset_t offset,
return (false);
}

if (os_txlog_init_rate > 0 && throttle) {
/* check write rate on every chunk (1MB) we write */
while ((double)(current_size + n_bytes) >
os_txlog_init_rate *
my_timer_to_seconds(my_timer_since(start_time))) {
os_thread_sleep(1000); /* sleep for 1000 usecs */
}
}

/* Flush after each os_fsync_threhold bytes */
if (flush && os_fsync_threshold != 0) {
if ((current_size + n_bytes) / os_fsync_threshold !=
Expand Down
2 changes: 1 addition & 1 deletion storage/innobase/srv/srv0start.cc
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ static MY_ATTRIBUTE((warn_unused_result)) dberr_t
#endif /* UNIV_DEBUG_DEDICATED */

ret = os_file_set_size_fast(name, *file, 0, (os_offset_t)srv_log_file_size,
srv_read_only_mode, true);
srv_read_only_mode, true, true);

if (!ret) {
ib::error(ER_IB_MSG_1063, name, size);
Expand Down

0 comments on commit e5cdb5b

Please sign in to comment.