Bug #87681 Documentation for open_files_limit is not full
Submitted: 6 Sep 2017 11:43 Modified: 7 Oct 2017 13:39
Reporter: Sveta Smirnova (OCA) Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Documentation Severity:S3 (Non-critical)
Version:5.5, 5.6.37, 5.7.19 OS:Any
Assigned to: CPU Architecture:Any

[6 Sep 2017 11:43] Sveta Smirnova
Description:
At https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_open_files_lim... we read:

----<q>----
 The number of files that the operating system permits mysqld to open. The value of this variable at runtime is the real value permitted by the system and might be different from the value you specify at server startup. The value is 0 on systems where MySQL cannot change the number of open files.

The effective open_files_limit value is based on the value specified at system startup (if any) and the values of max_connections and table_open_cache, using these formulas:

1) 10 + max_connections + (table_open_cache * 2)
2) max_connections * 5
3) open_files_limit value specified at startup, 5000 if none
----<q>-----

However in file mysys/my_file.c we see:

----<c>----
static uint set_max_open_files(uint max_file_limit)
{
  struct rlimit rlimit;
  uint old_cur;
  DBUG_ENTER("set_max_open_files");
  DBUG_PRINT("enter",("files: %u", max_file_limit));

  if (!getrlimit(RLIMIT_NOFILE,&rlimit))
  {
    old_cur= (uint) rlimit.rlim_cur;
    DBUG_PRINT("info", ("rlim_cur: %u  rlim_max: %u",
            (uint) rlimit.rlim_cur,
            (uint) rlimit.rlim_max));
    if (rlimit.rlim_cur == RLIM_INFINITY)
      rlimit.rlim_cur = max_file_limit;
    if (rlimit.rlim_cur >= max_file_limit)
      DBUG_RETURN(rlimit.rlim_cur);     /* purecov: inspected */
    rlimit.rlim_cur= rlimit.rlim_max= max_file_limit;
    if (setrlimit(RLIMIT_NOFILE, &rlimit))
      max_file_limit= old_cur;          /* Use original value */
    else
    {   
      rlimit.rlim_cur= 0;           /* Safety if next call fails */
      (void) getrlimit(RLIMIT_NOFILE,&rlimit);
      DBUG_PRINT("info", ("rlim_cur: %u", (uint) rlimit.rlim_cur));
      if (rlimit.rlim_cur)          /* If call didn't fail */
    max_file_limit= (uint) rlimit.rlim_cur;
    }   
  }
  DBUG_PRINT("exit",("max_file_limit: %u", max_file_limit));
  DBUG_RETURN(max_file_limit);
}
----<c>----

This code means what if your OS limit is infinity value from the variable open_file_limit will be used, if OS limit not infinity, but larger than variable value: OS file limit will be used; if OS limit smaller than specified value; again OS file limit will be used.

How to repeat:
See description

Suggested fix:
Update documentation to something like:

...
The effective open_files_limit value is based on the value specified at system startup (if any) and the values of max_connections and table_open_cache, using these formulas:

1) 10 + max_connections + (table_open_cache * 2)
2) max_connections * 5
3) OS limit if positive
4) If OS limit set to Infinity: open_files_limit value specified at startup , 5000 if none
[7 Sep 2017 7:04] MySQL Verification Team
Hello Sveta,

Thank you for the report and feedback!

Thanks,
Umesh
[7 Oct 2017 13:39] Paul DuBois
Posted by developer:
 
Made suggested change. Thanks for pointing it out.