Skip to content

Commit e53ff3d

Browse files
committed
WIP MDEV-36301: innodb_log_file_disabled
innodb_log_file_disabled: A new Boolean parameter, default OFF. FIXME: This currently only "works" during bootstrap. log_t::buf_size_requested: A new parameter, separate from buf_size, which will be the log buffer size that is currently in use. log_t::disable(): The beginnings of implementing SET GLOBAL innodb_log_file_disabled=OFF.
1 parent 4d41ec0 commit e53ff3d

File tree

9 files changed

+273
-22
lines changed

9 files changed

+273
-22
lines changed

extra/mariabackup/xtrabackup.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -1887,8 +1887,8 @@ struct my_option xb_server_options[] =
18871887

18881888
{"innodb_log_buffer_size", OPT_INNODB_LOG_BUFFER_SIZE,
18891889
"Redo log buffer size in bytes.",
1890-
(G_PTR*) &log_sys.buf_size, (G_PTR*) &log_sys.buf_size, 0,
1891-
GET_UINT, REQUIRED_ARG, 2U << 20,
1890+
(G_PTR*) &log_sys.buf_size_requested, (G_PTR*) &log_sys.buf_size_requested,
1891+
0, GET_UINT, REQUIRED_ARG, 2U << 20,
18921892
2U << 20, log_sys.buf_size_max, 0, 4096, 0},
18931893
{"innodb_log_file_mmap", OPT_INNODB_LOG_FILE_SIZE,
18941894
"Whether ib_logfile0 should be memory-mapped",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# restart: --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/log --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/log --innodb-log-file-disabled
2+
SELECT * FROM INFORMATION_SCHEMA.ENGINES
3+
WHERE engine = 'innodb'
4+
AND support IN ('YES', 'DEFAULT', 'ENABLED');
5+
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
6+
InnoDB YES Supports transactions, row-level locking, foreign keys and encryption for tables YES YES YES
7+
# restart
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
--source include/have_innodb.inc
2+
3+
let $bugdir= $MYSQLTEST_VARDIR/tmp/log;
4+
--mkdir $bugdir
5+
let $check_no_innodb=SELECT * FROM INFORMATION_SCHEMA.ENGINES
6+
WHERE engine = 'innodb'
7+
AND support IN ('YES', 'DEFAULT', 'ENABLED');
8+
9+
--let $ibp=--innodb-log-group-home-dir=$bugdir --innodb-data-home-dir=$bugdir
10+
11+
--let $restart_parameters= $ibp --innodb-log-file-disabled
12+
--source include/restart_mysqld.inc
13+
eval $check_no_innodb;
14+
#--rmdir $bugdir
15+
#--mkdir $bugdir
16+
#--let $restart_parameters= $ibp
17+
#--source include/restart_mysqld.inc
18+
#SET GLOBAL innodb_log_file_disabled=ON;
19+
#--source include/restart_mysqld.inc
20+
#eval $check_no_innodb;
21+
--let $restart_parameters=
22+
--source include/restart_mysqld.inc
23+
--rmdir $bugdir

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

+12
Original file line numberDiff line numberDiff line change
@@ -1051,6 +1051,18 @@ NUMERIC_BLOCK_SIZE NULL
10511051
ENUM_VALUE_LIST OFF,ON
10521052
READ_ONLY NO
10531053
COMMAND_LINE_ARGUMENT OPTIONAL
1054+
VARIABLE_NAME INNODB_LOG_FILE_DISABLED
1055+
SESSION_VALUE NULL
1056+
DEFAULT_VALUE OFF
1057+
VARIABLE_SCOPE GLOBAL
1058+
VARIABLE_TYPE BOOLEAN
1059+
VARIABLE_COMMENT Whether the ib_logfile0 is disabled (and InnoDB is crash-unsafe)
1060+
NUMERIC_MIN_VALUE NULL
1061+
NUMERIC_MAX_VALUE NULL
1062+
NUMERIC_BLOCK_SIZE NULL
1063+
ENUM_VALUE_LIST OFF,ON
1064+
READ_ONLY NO
1065+
COMMAND_LINE_ARGUMENT OPTIONAL
10541066
VARIABLE_NAME INNODB_LOG_FILE_MMAP
10551067
SESSION_VALUE NULL
10561068
DEFAULT_VALUE ON

storage/innobase/buf/buf0flu.cc

+3-2
Original file line numberDiff line numberDiff line change
@@ -1850,7 +1850,8 @@ inline void log_t::write_checkpoint(lsn_t end_lsn) noexcept
18501850
ut_ad(ut_is_2pow(write_size));
18511851
ut_ad(write_size >= 512);
18521852
ut_ad(write_size <= 4096);
1853-
log.write(offset, {c, write_size});
1853+
if (UNIV_LIKELY(!disabled))
1854+
log.write(offset, {c, write_size});
18541855
if (resizing > 1 && resizing <= next_checkpoint_lsn)
18551856
{
18561857
resize_log.write(CHECKPOINT_1, {c, write_size});
@@ -1861,7 +1862,7 @@ inline void log_t::write_checkpoint(lsn_t end_lsn) noexcept
18611862
aligned_free(buf);
18621863
}
18631864

1864-
if (srv_file_flush_method != SRV_O_DSYNC)
1865+
if (srv_file_flush_method != SRV_O_DSYNC && UNIV_LIKELY(!disabled))
18651866
ut_a(log.flush());
18661867
latch.wr_lock(SRW_LOCK_CALL);
18671868
ut_ad(checkpoint_pending);

storage/innobase/handler/ha_innodb.cc

+76-4
Original file line numberDiff line numberDiff line change
@@ -18608,6 +18608,71 @@ buffer_pool_load_abort(
1860818608
}
1860918609
}
1861018610

18611+
static void innodb_log_file_disabled_update(THD *thd, st_mysql_sys_var*,
18612+
void *var, const void *save)
18613+
{
18614+
ut_ad(var == &log_sys.disabled);
18615+
mysql_mutex_unlock(&LOCK_global_system_variables);
18616+
18617+
if (high_level_read_only)
18618+
ib_senderrf(thd, IB_LOG_LEVEL_ERROR, ER_READ_ONLY_MODE);
18619+
else if (!*static_cast<const my_bool*>(save))
18620+
{
18621+
if (log_sys.disable())
18622+
in_progress:
18623+
my_printf_error(ER_WRONG_USAGE,
18624+
"innodb_log_file_* change is already in progress",
18625+
MYF(0));
18626+
}
18627+
else
18628+
{
18629+
switch (log_sys.resize_start(srv_log_file_size, thd)) {
18630+
case log_t::RESIZE_NO_CHANGE:
18631+
break;
18632+
case log_t::RESIZE_IN_PROGRESS:
18633+
goto in_progress;
18634+
case log_t::RESIZE_FAILED:
18635+
ib_senderrf(thd, IB_LOG_LEVEL_ERROR, ER_CANT_CREATE_HANDLER_FILE);
18636+
break;
18637+
case log_t::RESIZE_STARTED:
18638+
for (timespec abstime;;)
18639+
{
18640+
if (thd_kill_level(thd))
18641+
{
18642+
log_sys.resize_abort(thd);
18643+
break;
18644+
}
18645+
18646+
set_timespec(abstime, 5);
18647+
mysql_mutex_lock(&buf_pool.flush_list_mutex);
18648+
lsn_t resizing= log_sys.resize_in_progress();
18649+
if (resizing > buf_pool.get_oldest_modification(0))
18650+
{
18651+
buf_pool.page_cleaner_wakeup(true);
18652+
my_cond_timedwait(&buf_pool.done_flush_list,
18653+
&buf_pool.flush_list_mutex.m_mutex, &abstime);
18654+
resizing= log_sys.resize_in_progress();
18655+
}
18656+
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
18657+
if (!resizing || !log_sys.resize_running(thd))
18658+
break;
18659+
log_sys.latch.wr_lock(SRW_LOCK_CALL);
18660+
while (resizing > log_sys.get_lsn())
18661+
{
18662+
ut_ad(!log_sys.is_mmap());
18663+
/* The server is almost idle. Write dummy FILE_CHECKPOINT records
18664+
to ensure that the log resizing will complete. */
18665+
mtr_t mtr;
18666+
mtr.start();
18667+
mtr.commit_files(log_sys.last_checkpoint_lsn);
18668+
}
18669+
log_sys.latch.wr_unlock();
18670+
}
18671+
}
18672+
}
18673+
mysql_mutex_lock(&LOCK_global_system_variables);
18674+
}
18675+
1861118676
#if defined __linux__ || defined _WIN32
1861218677
static void innodb_log_file_buffering_update(THD *thd, st_mysql_sys_var*,
1861318678
void *, const void *save)
@@ -18630,18 +18695,19 @@ static void innodb_log_file_size_update(THD *thd, st_mysql_sys_var*,
1863018695
#ifdef HAVE_PMEM
1863118696
!log_sys.is_mmap() &&
1863218697
#endif
18633-
*static_cast<const ulonglong*>(save) < log_sys.buf_size)
18698+
*static_cast<const ulonglong*>(save) < log_sys.buf_size_requested)
1863418699
my_printf_error(ER_WRONG_ARGUMENTS,
1863518700
"innodb_log_file_size must be at least"
18636-
" innodb_log_buffer_size=%u", MYF(0), log_sys.buf_size);
18701+
" innodb_log_buffer_size=%u", MYF(0),
18702+
log_sys.buf_size_requested);
1863718703
else
1863818704
{
1863918705
switch (log_sys.resize_start(*static_cast<const ulonglong*>(save), thd)) {
1864018706
case log_t::RESIZE_NO_CHANGE:
1864118707
break;
1864218708
case log_t::RESIZE_IN_PROGRESS:
1864318709
my_printf_error(ER_WRONG_USAGE,
18644-
"innodb_log_file_size change is already in progress",
18710+
"innodb_log_file_* change is already in progress",
1864518711
MYF(0));
1864618712
break;
1864718713
case log_t::RESIZE_FAILED:
@@ -19517,11 +19583,16 @@ static MYSQL_SYSVAR_ULONG(page_size, srv_page_size,
1951719583
NULL, NULL, UNIV_PAGE_SIZE_DEF,
1951819584
UNIV_PAGE_SIZE_MIN, UNIV_PAGE_SIZE_MAX, 0);
1951919585

19520-
static MYSQL_SYSVAR_UINT(log_buffer_size, log_sys.buf_size,
19586+
static MYSQL_SYSVAR_UINT(log_buffer_size, log_sys.buf_size_requested,
1952119587
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
1952219588
"Redo log buffer size in bytes.",
1952319589
NULL, NULL, 16U << 20, 2U << 20, log_sys.buf_size_max, 4096);
1952419590

19591+
static MYSQL_SYSVAR_BOOL(log_file_disabled, log_sys.disabled,
19592+
PLUGIN_VAR_OPCMDARG,
19593+
"Whether the ib_logfile0 is disabled (and InnoDB is crash-unsafe)",
19594+
nullptr, innodb_log_file_disabled_update, FALSE);
19595+
1952519596
static constexpr const char *innodb_log_file_mmap_description=
1952619597
"Whether ib_logfile0"
1952719598
" resides in persistent memory (when supported) or"
@@ -20003,6 +20074,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
2000320074
MYSQL_SYSVAR(deadlock_report),
2000420075
MYSQL_SYSVAR(page_size),
2000520076
MYSQL_SYSVAR(log_buffer_size),
20077+
MYSQL_SYSVAR(log_file_disabled),
2000620078
MYSQL_SYSVAR(log_file_mmap),
2000720079
#if defined __linux__ || defined _WIN32
2000820080
MYSQL_SYSVAR(log_file_buffering),

storage/innobase/include/log0log.h

+15-2
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ class log_file_t
130130
/** Redo log buffer */
131131
struct log_t
132132
{
133-
/** The maximum buf_size */
133+
/** The maximum buf_size_requested */
134134
static constexpr unsigned buf_size_max= os_file_request_size_max;
135135

136136
/** The original (not version-tagged) InnoDB redo log format */
@@ -182,7 +182,7 @@ struct log_t
182182
/** the first guaranteed-durable log sequence number */
183183
std::atomic<lsn_t> flushed_to_disk_lsn;
184184
public:
185-
/** innodb_log_buffer_size (usable append_prepare() size in bytes) */
185+
/** innodb_log_buffer_size or the PMEM file_size */
186186
unsigned buf_size;
187187
/** log file size in bytes, including the header */
188188
lsn_t file_size;
@@ -264,10 +264,14 @@ struct log_t
264264
/** the log sequence number at the start of the log file */
265265
lsn_t first_lsn;
266266
public:
267+
/** innodb_log_buffer_size (usable append_prepare() size in bytes) */
268+
unsigned buf_size_requested;
267269
/** current innodb_log_write_ahead_size */
268270
uint write_size;
269271
/** format of the redo log: e.g., FORMAT_10_8 */
270272
uint32_t format;
273+
/** whether the log is disabled */
274+
my_bool disabled;
271275
/** whether the memory-mapped interface is enabled for the log */
272276
my_bool log_mmap;
273277
/** the default value of log_mmap */
@@ -331,6 +335,11 @@ struct log_t
331335
is_mmap() && !is_opened() holds for PMEM */
332336
bool is_opened() const noexcept { return log.is_opened(); }
333337

338+
/** Try to disable the redo log.
339+
@retval false if the log is or was disabled
340+
@retval true if resize_in_progress() */
341+
bool disable() noexcept;
342+
334343
/** @return LSN at which log resizing was started and is still in progress
335344
@retval 0 if no log resizing is in progress
336345
@retval 1 if resize_start() is in progress */
@@ -543,6 +552,10 @@ struct log_t
543552
RESIZING
544553
};
545554

555+
/** Pretend to write to (non-existing) ib_logfile0 while disabled==true
556+
@return the current log sequence number */
557+
static lsn_t skip_write_buf() noexcept;
558+
546559
/** Write buf to ib_logfile0 and possibly ib_logfile101.
547560
@tparam resizing whether to release latch and whether resize_in_progress()>1
548561
@return the current log sequence number */

0 commit comments

Comments
 (0)