Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-36301

SET GLOBAL innodb_log_group_home_dir, innodb_log_file_disabled

Details

    • Q2/2025 Development

    Description

      MySQL 8.0 introduced a way to disable or enable the InnoDB redo log while the server is running. jeanfrancois.gagne has pointed out that this could make sense for speeding up some bulk operations, such as setting up a replica.

      I believe that the most straightforward way to implement this would be to rely on the log resizing mechanism that was introduced in MDEV-27812.

      We can leverage the fact that SET GLOBAL of multiple parameters can be atomic:

      • innodb_log_file_disabled (new parameter, default OFF): disable or enable the redo log
      • innodb_log_group_home_dir (previously read-only the storage location of ib_logfile0
      • innodb_encrypt_log and possible encryption parameters (this will remain read-only while the server is running)
      • innodb_log_file_size (MDEV-27812 enabled SET GLOBAL for this).

      The logic of online log resizing or log rebuild is straightforward.

      1. Create and allocate a new file ib_logfile101 that will be the new log file.
      2. Start replicating log to ib_logfile101.
      3. On the next log checkpoint (page cleaner batch) that advances the LSN beyond the start of ib_logfile101, make ib_logfile101 the main write-ahead log ib_logfile0.

      For disabling or enabling the redo log, instead of SET GLOBAL, MySQL 8.0 uses the following syntax:

      ALTER INSTANCE DISABLE INNODB REDO_LOG;
      ALTER INSTANCE ENABLE INNODB REDO_LOG;
      

      Disabling the write-ahead log would be special in the way that no ib_logfile0 would exist at all. We would continue to allocate LSN and possibly write log records to log_sys.buf, but the log "writes" would simply advance log_sys.write_lsn and log_sys.flushed_to_disk_lsn without accessing the non-existent file. During the time when no redo log exists, crash recovery would be refused by default, thanks to MDEV-27199. When the redo log is re-enabled, the ib_logfile101 would be ignored by recovery until it is renamed to ib_logfile0 as part of a log checkpoint.

      Attachments

        Issue Links

          Activity

            marko Marko Mäkelä added a comment -

            We can’t allow SET GLOBAL innodb_encrypt_log without major file format changes. This is because in the current MDEV-14425 format (not subject to change in MDEV-36024) the setting innodb_encrypt_log=ON makes each mini-transaction grow by 8 bytes. Not only would we have to write both encrypted and unencrypted log records during the log rebuild, but the LSN would grow differently, and the switchover mechanism that was designed in MDEV-27812 would no longer work. The only way how it could possibly work is if there is a sharp checkpoint. We already allow innodb_encrypt_log to be changed on InnoDB startup.

            marko Marko Mäkelä added a comment - We can’t allow SET GLOBAL innodb_encrypt_log without major file format changes. This is because in the current MDEV-14425 format (not subject to change in MDEV-36024 ) the setting innodb_encrypt_log=ON makes each mini-transaction grow by 8 bytes. Not only would we have to write both encrypted and unencrypted log records during the log rebuild, but the LSN would grow differently, and the switchover mechanism that was designed in MDEV-27812 would no longer work. The only way how it could possibly work is if there is a sharp checkpoint. We already allow innodb_encrypt_log to be changed on InnoDB startup.
            marko Marko Mäkelä added a comment -

            serg, your idea of initializing shared context cannot work for the following:

            SET GLOBAL innodb_log_file_size=DEFAULT;
            

            For such assignments, sys_var::set_default() does invoke sys_var::check(), but no callback would be invoked, because var->value==nullptr:

            bool sys_var::check(THD *thd, set_var *var)
            {
              if (unlikely((var->value && do_check(thd, var)) ||
                           (on_check && on_check(this, thd, var))))
            

            When assigning something else than DEFAULT, sys_var_pluginvar::do_check() would be invoked, and it would invoke the callback function that is specified in the storage engine.

            Implementing something like group-sysvar-check.diff would cause the regression that SET GLOBAL innodb_log_file_size=DEFAULT; would become a no-op, or require a rather delicate work-around in the storage engine.

            marko Marko Mäkelä added a comment - serg , your idea of initializing shared context cannot work for the following: SET GLOBAL innodb_log_file_size= DEFAULT ; For such assignments, sys_var::set_default() does invoke sys_var::check() , but no callback would be invoked, because var->value==nullptr : bool sys_var::check(THD *thd, set_var *var) { if (unlikely((var->value && do_check(thd, var)) || (on_check && on_check( this , thd, var)))) When assigning something else than DEFAULT , sys_var_pluginvar::do_check() would be invoked, and it would invoke the callback function that is specified in the storage engine. Implementing something like group-sysvar-check.diff would cause the regression that SET GLOBAL innodb_log_file_size=DEFAULT; would become a no-op, or require a rather delicate work-around in the storage engine.
            serg Sergei Golubchik added a comment - - edited

            let's call it a bug. Apparently, the logic was that the default value should be always valid. But it cannot be guaranteed, even a default value might not be valid at some specific point of time, may a variable is not assignable inside a transaction?

            so this has to change and the check callback should be called for a default value too, I think.

            serg Sergei Golubchik added a comment - - edited let's call it a bug. Apparently, the logic was that the default value should be always valid. But it cannot be guaranteed, even a default value might not be valid at some specific point of time, may a variable is not assignable inside a transaction? so this has to change and the check callback should be called for a default value too, I think.
            marko Marko Mäkelä added a comment -

            Another problem of the plugin interface is that the "update" callback function cannot return an error code. For example, when there is an attempt to specify a SET GLOBAL innodb_log_group_home_dir such that the file system would change, and atomic rename will not be possible. The SET GLOBAL statement would finish without an error, but also without changing the requested parameters.

            Currently, if an error occurs during log_t::resize_start(), such as a failure to create a file in the specified directory, it will be flagged, but a failure to replace the log file on a log checkpoint will be silently ignored.

            Also, I wonder what kind of validation is desirable innodb_log_group_home_dir. Currently, for a start-up parameter, any semicolons (;) are forbidden for no apparent reason, but colons (:) are OK, even when they might look like Windows alternate resource data streams (something that emulates macOS "resource forks"). For SET GLOBAL innodb_log_group_home_dir, I did not implement any restrictions yet.

            marko Marko Mäkelä added a comment - Another problem of the plugin interface is that the "update" callback function cannot return an error code. For example, when there is an attempt to specify a SET GLOBAL innodb_log_group_home_dir such that the file system would change, and atomic rename will not be possible. The SET GLOBAL statement would finish without an error, but also without changing the requested parameters. Currently, if an error occurs during log_t::resize_start() , such as a failure to create a file in the specified directory, it will be flagged, but a failure to replace the log file on a log checkpoint will be silently ignored. Also, I wonder what kind of validation is desirable innodb_log_group_home_dir . Currently, for a start-up parameter, any semicolons ( ; ) are forbidden for no apparent reason, but colons ( : ) are OK, even when they might look like Windows alternate resource data streams (something that emulates macOS "resource forks"). For SET GLOBAL innodb_log_group_home_dir , I did not implement any restrictions yet.
            marko Marko Mäkelä added a comment -

            serg, I am assigning this to you again, for clarifying the open questions. Other than this, it should be feature complete.

            marko Marko Mäkelä added a comment - serg , I am assigning this to you again, for clarifying the open questions. Other than this, it should be feature complete.

            People

              serg Sergei Golubchik
              marko Marko Mäkelä
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:

                Git Integration

                  Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.