diff --git a/mysql-test/r/all_persisted_variables.result b/mysql-test/r/all_persisted_variables.result index b476ba10a28f..67659a15e3a4 100644 --- a/mysql-test/r/all_persisted_variables.result +++ b/mysql-test/r/all_persisted_variables.result @@ -37,7 +37,7 @@ include/assert.inc [Expect 500+ variables in the table. Due to open Bugs, we are # Test SET PERSIST -include/assert.inc [Expect 404 persisted variables in the table.] +include/assert.inc [Expect 405 persisted variables in the table.] ************************************************************ * 3. Restart server, it must preserve the persisted variable @@ -45,9 +45,9 @@ include/assert.inc [Expect 404 persisted variables in the table.] ************************************************************ # restart -include/assert.inc [Expect 404 persisted variables in persisted_variables table.] -include/assert.inc [Expect 404 persisted variables shown as PERSISTED in variables_info table.] -include/assert.inc [Expect 404 persisted variables with matching peristed and global values.] +include/assert.inc [Expect 405 persisted variables in persisted_variables table.] +include/assert.inc [Expect 405 persisted variables shown as PERSISTED in variables_info table.] +include/assert.inc [Expect 405 persisted variables with matching peristed and global values.] ************************************************************ * 4. Test RESET PERSIST IF EXISTS. Verify persisted variable diff --git a/mysql-test/suite/sys_vars/r/innodb_txlog_init_rate_basic.result b/mysql-test/suite/sys_vars/r/innodb_txlog_init_rate_basic.result new file mode 100644 index 000000000000..2540be0d368e --- /dev/null +++ b/mysql-test/suite/sys_vars/r/innodb_txlog_init_rate_basic.result @@ -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; diff --git a/mysql-test/suite/sys_vars/t/innodb_txlog_init_rate_basic.test b/mysql-test/suite/sys_vars/t/innodb_txlog_init_rate_basic.test new file mode 100644 index 000000000000..649e9398f2e5 --- /dev/null +++ b/mysql-test/suite/sys_vars/t/innodb_txlog_init_rate_basic.test @@ -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; diff --git a/mysql-test/t/all_persisted_variables.test b/mysql-test/t/all_persisted_variables.test index 9419f01bd2ad..670fc355bbff 100644 --- a/mysql-test/t/all_persisted_variables.test +++ b/mysql-test/t/all_persisted_variables.test @@ -39,7 +39,7 @@ call mtr.add_suppression("Failed to set up SSL because of the following SSL library error"); let $total_global_vars=`SELECT COUNT(*) FROM performance_schema.global_variables where variable_name NOT LIKE 'ndb_%'`; -let $total_persistent_vars=404; +let $total_persistent_vars=405; --echo *************************************************************** --echo * 0. Verify that variables present in performance_schema.global diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 6a74d54ec959..b5d4b90a76e6 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -22015,6 +22015,13 @@ static MYSQL_SYSVAR_ULONGLONG( "entire file at once before closing it.", NULL, NULL, 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 " @@ -22514,6 +22521,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), diff --git a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h index 496a4241aae0..dece4dce8e8b 100644 --- a/storage/innobase/include/os0file.h +++ b/storage/innobase/include/os0file.h @@ -77,6 +77,10 @@ extern 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 ulint os_aio_n_outstanding; #ifdef UNIV_DEBUG @@ -823,7 +827,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 { @@ -1611,10 +1614,11 @@ os_offset_t os_file_get_size(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 diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc index 68695ea45dc8..aef1a782008c 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -100,6 +100,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; @@ -5543,9 +5546,11 @@ void os_file_set_nocache(int fd MY_ATTRIBUTE((unused)), @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) { + 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; @@ -5576,6 +5581,7 @@ bool os_file_set_size(const char *name, pfs_os_file_t file, os_offset_t offset, os_offset_t current_size = offset; + ulonglong start_time = my_timer_now(); while (current_size < size) { ulint n_bytes; @@ -5605,6 +5611,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 */ + } + } + /* Print about progress for each 100 MB written */ if ((current_size + n_bytes) / (100 << 20) != current_size / (100 << 20)) { fprintf(stderr, " %lu00", diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 845340277fd4..79427bdbda38 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -312,7 +312,7 @@ static MY_ATTRIBUTE((warn_unused_result)) dberr_t #endif /* UNIV_DEBUG_DEDICATED */ ret = os_file_set_size(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);