Skip to content

Commit 80ca845

Browse files
tianxjtolmer
authored andcommitted
Slowing down transaction log init
Summary: This diff added a configurable variable to throttle the write rate of new innodb log file initialization. Default speed is 128MB/second, and setting it to 0 will turn off the throttling. I also changed the default value of innodb_fsync_freq to 1MB to reduce system stalls caused by fsyncing large trunks of file. Test Plan: jenkins Testing command: mysqld --datadir=/tmp/log_init --skip-grant-tables --skip-networking --socket=socket --innodb-log-file-size=1G --innodb-txlog-init-rate=[rate] With --innodb-txlog-init-rate=0 (no throttling, 1GB init finished in ~49s) 2015-05-22 16:51:20 4018018 [Note] InnoDB: Setting log file ./ib_logfile101 size to 1024 MB InnoDB: Progress in MB: 100 200 300 400 500 600 700 800 900 1000 2015-05-22 16:52:09 4018018 [Note] InnoDB: Setting log file ./ib_logfile1 size to 1024 MB InnoDB: Progress in MB: 100 200 300 400 500 600 700 800 900 1000 With --innodb-txlog-init-rate=10485760 (10MB/s throttling, 1GB log init finished in ~103s) 2015-05-22 16:55:28 4022136 [Note] InnoDB: Setting log file ./ib_logfile101 size to 1024 MB InnoDB: log file write is throttled at 10MB/s InnoDB: Progress in MB: 100 200 300 400 500 600 700 800 900 1000 2015-05-22 16:57:11 4022136 [Note] InnoDB: Setting log file ./ib_logfile1 size to 1024 MB InnoDB: log file write is throttled at 10MB/s InnoDB: Progress in MB: 100 200 300 400 500 600 700 800 900 1000 Without setting the option (use default. 1GB init finished in ~50s. Note the write is already below 128MB/s, so the throttling didn't have any effect) 2015-05-22 17:18:51 4055898 [Note] InnoDB: Setting log file ./ib_logfile101 size to 1024 MB InnoDB: log file write is throttled at 128MB/s InnoDB: Progress in MB: 100 200 300 400 500 600 700 800 900 1000 2015-05-22 17:19:41 4055898 [Note] InnoDB: Setting log file ./ib_logfile1 size to 1024 MB InnoDB: log file write is throttled at 128MB/s InnoDB: Progress in MB: 100 200 300 400 500 600 700 800 900 1000 Reviewers: jtolmer Reviewed By: jtolmer
1 parent eb82f73 commit 80ca845

File tree

6 files changed

+84
-8
lines changed

6 files changed

+84
-8
lines changed

mysql-test/suite/sys_vars/r/innodb_fsync_freq_basic.result

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
SET @orig_fsync_freq = @@global.innodb_fsync_freq;
22
SELECT @orig_fsync_freq;
33
@orig_fsync_freq
4-
134217728
4+
1048576
55
SET GLOBAL innodb_fsync_freq = 1024*1024*1024;
66
SELECT @@global.innodb_fsync_freq;
77
@@global.innodb_fsync_freq
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
SET @orig_txlog_init_rate = @@global.innodb_txlog_init_rate;
2+
SELECT @orig_txlog_init_rate;
3+
@orig_txlog_init_rate
4+
134217728
5+
SET GLOBAL innodb_txlog_init_rate = 500*1024*1024;
6+
SELECT @@global.innodb_txlog_init_rate;
7+
@@global.innodb_txlog_init_rate
8+
524288000
9+
SET GLOBAL innodb_txlog_init_rate = 0;
10+
SELECT @@global.innodb_txlog_init_rate;
11+
@@global.innodb_txlog_init_rate
12+
0
13+
SET GLOBAL innodb_txlog_init_rate = -1;
14+
Warnings:
15+
Warning 1292 Truncated incorrect innodb_txlog_init_rate value: '-1'
16+
SELECT @@global.innodb_txlog_init_rate;
17+
@@global.innodb_txlog_init_rate
18+
0
19+
SET GLOBAL innodb_txlog_init_rate = 12345;
20+
Warnings:
21+
Warning 1292 Truncated incorrect innodb_txlog_init_rate value: '12345'
22+
SELECT @@global.innodb_txlog_init_rate;
23+
@@global.innodb_txlog_init_rate
24+
0
25+
SET GLOBAL innodb_txlog_init_rate = @orig_txlog_init_rate;
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
--source include/have_innodb.inc
2+
3+
4+
SET @orig_txlog_init_rate = @@global.innodb_txlog_init_rate;
5+
6+
SELECT @orig_txlog_init_rate;
7+
8+
# 500MB/s
9+
SET GLOBAL innodb_txlog_init_rate = 500*1024*1024;
10+
SELECT @@global.innodb_txlog_init_rate;
11+
12+
# min value
13+
SET GLOBAL innodb_txlog_init_rate = 0;
14+
SELECT @@global.innodb_txlog_init_rate;
15+
16+
# invalid value
17+
# too small
18+
SET GLOBAL innodb_txlog_init_rate = -1;
19+
SELECT @@global.innodb_txlog_init_rate;
20+
21+
# not bound to page size
22+
SET GLOBAL innodb_txlog_init_rate = 12345;
23+
SELECT @@global.innodb_txlog_init_rate;
24+
25+
SET GLOBAL innodb_txlog_init_rate = @orig_txlog_init_rate;

storage/innobase/handler/ha_innodb.cc

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18175,9 +18175,17 @@ static MYSQL_SYSVAR_ULONG(spin_wait_delay, srv_spin_wait_delay,
1817518175
static MYSQL_SYSVAR_ULONGLONG(fsync_freq, os_fsync_freq,
1817618176
PLUGIN_VAR_RQCMDARG,
1817718177
"The value of this variable determines how often InnoDB calls fsync when "
18178-
"creating a new file. Default is to call fsync after every 128M written. "
18179-
"Setting this value to zero would make InnoDB flush the file before closing "
18180-
"it.", NULL, NULL, 1ULL << 27, 0, ULONG_MAX, UNIV_PAGE_SIZE);
18178+
"creating a new file. Default is to call fsync after every time the buffer "
18179+
"(1MB) is written. Setting this value to zero would make InnoDB flush the "
18180+
"file before closing it.",
18181+
NULL, NULL, OS_FILE_WRITE_BUF_SIZE, 0, ULONG_MAX, OS_FILE_WRITE_BUF_SIZE);
18182+
18183+
static MYSQL_SYSVAR_ULONGLONG(txlog_init_rate, os_txlog_init_rate,
18184+
PLUGIN_VAR_OPCMDARG,
18185+
"The value of this variable determines how fast (in bytes/s) InnoDB "
18186+
"initializes the transaction log when creating a new file"
18187+
"Setting this value to 0 means no limit. Default is 128MB",
18188+
NULL, NULL, 1ULL << 27, 0ULL, ULONG_MAX, 1ULL << 20);
1818118189

1818218190
static MYSQL_SYSVAR_UINT(load_table_thread_num, innobase_load_table_thread_num,
1818318191
PLUGIN_VAR_RQCMDARG,
@@ -18688,6 +18696,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
1868818696
MYSQL_SYSVAR(sync_spin_loops),
1868918697
MYSQL_SYSVAR(spin_wait_delay),
1869018698
MYSQL_SYSVAR(fsync_freq),
18699+
MYSQL_SYSVAR(txlog_init_rate),
1869118700
MYSQL_SYSVAR(load_table_thread_num),
1869218701
MYSQL_SYSVAR(table_locks),
1869318702
MYSQL_SYSVAR(thread_concurrency),

storage/innobase/include/os0file.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ enum os_file_create_t {
142142
ON_ERROR_NO_EXIT is set */
143143
};
144144

145+
#define OS_FILE_WRITE_BUF_SIZE 1ULL<<20
146+
145147
#define OS_FILE_READ_ONLY 333
146148
#define OS_FILE_READ_WRITE 444
147149
#define OS_FILE_READ_ALLOW_DELETE 555 /* for mysqlbackup */
@@ -227,6 +229,7 @@ extern ulint os_n_file_reads;
227229
extern ulint os_n_file_writes;
228230
extern ulint os_n_fsyncs;
229231
extern ullint os_fsync_freq;
232+
extern ullint os_txlog_init_rate;
230233

231234
/** Seconds waiting for file flushes to finish */
232235
extern ulonglong os_file_flush_time;

storage/innobase/os/os0file.cc

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ UNIV_INTERN ulint os_innodb_umask = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
9595
UNIV_INTERN ulint os_innodb_umask = 0;
9696
#endif /* __WIN__ */
9797

98-
UNIV_INTERN ullint os_fsync_freq = 1ULL << 27;
98+
UNIV_INTERN ullint os_fsync_freq = OS_FILE_WRITE_BUF_SIZE;
99+
UNIV_INTERN ullint os_txlog_init_rate = 1ULL << 27;
99100

100101
#ifndef UNIV_HOTBACKUP
101102
/* We use these mutexes to protect lseek + file i/o operation, if the
@@ -2322,9 +2323,8 @@ os_file_set_size(
23222323

23232324
current_size = 0;
23242325

2325-
/* Write up to 1 megabyte at a time. */
2326-
buf_size = ut_min(64, (ulint) (size / UNIV_PAGE_SIZE))
2327-
* UNIV_PAGE_SIZE;
2326+
/* Write 1 megabyte at a time. */
2327+
buf_size = OS_FILE_WRITE_BUF_SIZE;
23282328
buf2 = static_cast<byte*>(ut_malloc(buf_size + UNIV_PAGE_SIZE));
23292329

23302330
/* Align the buffer for possible raw i/o */
@@ -2333,11 +2333,17 @@ os_file_set_size(
23332333
/* Write buffer full of zeros */
23342334
memset(buf, 0, buf_size);
23352335

2336+
if (os_txlog_init_rate > 0) {
2337+
fprintf(stderr, "InnoDB: log file write is throttled at %lluMB/s\n",
2338+
os_txlog_init_rate/(1ULL<<20));
2339+
}
2340+
23362341
if (size >= (os_offset_t) 100 << 20) {
23372342

23382343
fprintf(stderr, "InnoDB: Progress in MB:");
23392344
}
23402345

2346+
ulonglong start_time = my_timer_now();
23412347
while (current_size < size) {
23422348
ulint n_bytes;
23432349

@@ -2353,6 +2359,14 @@ os_file_set_size(
23532359
goto error_handling;
23542360
}
23552361

2362+
if (os_txlog_init_rate > 0) {
2363+
/* check write rate on every chunk (1MB) we write */
2364+
while ((double)(current_size + n_bytes) > os_txlog_init_rate *
2365+
my_timer_to_seconds(my_timer_since(start_time))) {
2366+
os_thread_sleep(1000); /* sleep for 1000 usecs */
2367+
}
2368+
}
2369+
23562370
/* Print about progress for each 100 MB written */
23572371
if ((current_size + n_bytes) / (100 << 20)
23582372
!= current_size / (100 << 20)) {

0 commit comments

Comments
 (0)