Bug #103059 system_variable_source does not report DYNAMIC when queried from sys_var update
Submitted: 22 Mar 2021 12:35 Modified: 22 Mar 2021 13:23
Reporter: Yura Sorokin (OCA) Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: InnoDB storage engine Severity:S3 (Non-critical)
Version:8.0.23 OS:Any
Assigned to: CPU Architecture:Any
Tags: Contribution

[22 Mar 2021 12:35] Yura Sorokin
Description:
Several existing InnoDB system variables (including innodb_undo_tablespaces, innodb_buffer_pool_size, innodb_log_file_size) use the following pattern in their "update" handler to determine the source from where the var is being changed.
Internally they use something like
******************************************
  acquire_sysvar_source_service();
  if (sysvar_source_svc != nullptr) {
    static const char *variable_name = "<var_name>";
    enum enum_variable_source source;
    if (!sysvar_source_svc->get(
            variable_name, static_cast<unsigned int>(strlen(variable_name)),
            &source)) {
      if (source != COMPILED) {
        ...
      }
    }
  }
  release_sysvar_source_service();
******************************************

However, this approach does not work because according to
******************************************
int set_var::update(THD *thd) {
  int ret = 0;
  /* for persist only syntax do not update the value */
  if (type != OPT_PERSIST_ONLY) {
    if (value)
      ret = (int)var->update(thd, this);
    else
      ret = (int)var->set_default(thd, this);
  }
  /*
   For PERSIST_ONLY syntax we dont change the value of the variable
   for the current session, thus we should not change variables
   source/timestamp/user/host.
  */
  if (ret == 0 && type != OPT_PERSIST_ONLY) {
    update_source_user_host_timestamp(thd);
  }
  return ret;
}
******************************************
the "source" of the "sys_var" change is set to DYNAMIC only AFTER "update()" handler is called (inside "update_source_user_host_timestamp()").

Therefore, when system_variable_source component is queried from within the sys_var update handler, user get the source of previous operation rather than the current one being executed.

How to repeat:
Changing innodb_undo_tablespaces for the first time won't produce a deprecation warning in the error log.

Suggested fix:
Set variable source to DYNAMIC before calling the "update()" handler
var->set_source(enum_variable_source::DYNAMIC);
[22 Mar 2021 13:12] Yura Sorokin
8.0 patch

Attachment: bug_103059.diff (application/octet-stream, text), 625 bytes.

[22 Mar 2021 13:23] MySQL Verification Team
Hello Yura Sorokin,

Thank you for the report and contribution.
Please ensure to re-send the patch "Contribution" tab. Otherwise we would not be able to accept it.

regards,
Umesh
[22 Mar 2021 22:56] Yura Sorokin
8.0 patch

(*) I confirm the code being submitted is offered under the terms of the OCA, and that I am authorized to contribute it.

Contribution: bug_103059.diff (application/octet-stream, text), 625 bytes.