WL#6402: Non blocking show slave status

Affects: Server-5.7   —   Status: Complete

RATIONALE
---------

Add a option to "SHOW SLAVE STATUS" command that when used returns immediately
instead of blocking when there are locks held by "STOP SLAVE" command, this
command is intended for monitoring tools which requests should not block.

We propose to add a option to "SHOW SLAVE STATUS", which when used will
make "SHOW SLAVE STATUS" non-blocking when running in parallel with "STOP SLAVE".
"STOP SLAVE" command may take a long time to complete when it is waiting for SQL
thread to apply a big event.

That option will be NONBLOCKING, so when invoked like
"SHOW SLAVE STATUS NONBLOCKING" lock LOCK_active_mi won't be hold when slave is
being stopped, what may cause not most recent status.
Control access to non-volatile members like mi->info_thd or rli->info_thd will
be performed by new info_thd_lock mutex or run_lock, for read access
info_thd_lock or run_lock hold is required, for write access both mutex hold is
required.
Although "SHOW SLAVE STATUS NONBLOCKING" will block when run in parallel with
"START SLAVE" due to mi->data_lock and mi->rli->data_lock, but since "START
SLAVE" is fast there won't be blocked requests.

This command is intended to be executed by monitoring tools, like
Nagios, on which is more important to do not block requests then have
the last updated status.
The possible inconsistent results will be IO and SQL thread
running status, them may be reported as running when a STOP SLAVE is
being executed, although this window is small, it is only from when STOP
SLAVE is not waiting from SQL/IO thread to stop until STOP SLAVE terminates.
Add command SHOW SLAVE STATUS NONBLOCKING which don't lock LOCK_active_mi,
mi->run_lock and mi->rli->run_lock:

 case SQLCOM_SHOW_SLAVE_STAT_NONBLOCKING:
  {
    /* Accept one of two privileges */
    if (check_global_access(thd, SUPER_ACL | REPL_CLIENT_ACL))
      goto error;
    res= show_slave_status(thd, active_mi, false);
    break;
  }

Changes to show slave status implementation:
bool show_slave_status(THD* thd, Master_info* mi)
{
...
    /*   
      slave_running can be accessed without run_lock but not other
      non-volatile members like mi->info_thd or rli->info_thd, for
      them either info_thd_lock or run_lock hold is required.
    */
    mysql_mutex_lock(&mi->info_thd_lock);
    protocol->store(mi->info_thd ? mi->info_thd->get_proc_info() : "",
&my_charset_bin);
    mysql_mutex_unlock(&mi->info_thd_lock);

    mysql_mutex_lock(&mi->rli->info_thd_lock);
    slave_sql_running_state= const_cast(mi->rli->info_thd ?
mi->rli->info_thd->get_proc_info() : ""); 
    mysql_mutex_unlock(&mi->rli->info_thd_lock);
...
}

Add new parser command:
        | SLAVE STATUS_SYM NONBLOCKING_SYM
          {
            Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT_NONBLOCKING;
          }
        | SLAVE STATUS_SYM
          {
            Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT;
          }