Comment 7 for bug 1594964

Revision history for this message
Vlad Lesin (vlad-lesin) wrote :

I was wrong about the reasons in my previous comment.

So, what is happening here:

1) In Rpl_info_table::do_init_info() the thd is gotten with the following code:
  THD *thd= access->create_thd();

2) If we look into Rpl_info_table_access::create_thd() we will see that thd is created only in the case if the current_thd is NULL, otherwise the current_thd is returned. For our case that means the replication thread is used to store data in rpl info table.

THD *Rpl_info_table_access::create_thd()
{
  THD *thd= current_thd;

  if (!thd)
  {
    thd= System_table_access::create_thd();
    thd->system_thread= SYSTEM_THREAD_INFO_REPOSITORY;
    thd_created= true;
  }

  return(thd);
}

3) If wee look at the massif.out file we will see that new memory is allocated with "new" operator with parameters, and thd->mem_root is used as the parameter, so the memory is allocated in thd->mem_root arena.

 ->09.32% (578,806,592B) 0x188E91C: my_raw_malloc (in /usr/sbin/mysqld-debug)
| ->09.32% (578,806,592B) 0x188E519: my_malloc (in /usr/sbin/mysqld-debug)
| ->09.03% (561,046,608B) 0x1887A44: alloc_root (in /usr/sbin/mysqld-debug)
| | ->08.75% (543,172,776B) 0xEFC948: Sql_alloc::operator new(unsigned long, st_mem_root*) (in /usr/sbin/mysqld-debug)
| | | ->06.25% (388,424,352B) 0x153B929: LEX::new_query(st_select_lex*) (in /usr/sbin/mysqld-debug)
| | | | ->06.25% (388,424,352B) 0x153BEEE: LEX::new_top_level_query() (in /usr/sbin/mysqld-debug)
| | | | ->06.25% (388,424,352B) 0x153B5E2: lex_start(THD*) (in /usr/sbin/mysqld-debug)
| | | | ->06.25% (388,424,352B) 0x1858CB9: Rpl_info_table_access::before_open(THD*) (in /usr/sbin/mysqld-debug)
| | | | | ->06.25% (388,424,352B) 0x181FA59: System_table_access::open_table(THD*, st_mysql_lex_string, st_mysql_lex_string, unsigned int, thr_lock_type, TABLE**, Open_tables_backup*) (in /usr/sbin/mysqld-debug)
| | | | | ->06.25% (388,424,352B) 0x186E3D3: Rpl_info_table::do_flush_info(bool) (in /usr/sbin/mysqld-debug)

4) If we look at the end of Rpl_info_table::do_init_info() function we will see the call of access->drop_thd(thd) which code is the following:

void Rpl_info_table_access::drop_thd(THD *thd)
{
  DBUG_ENTER("Rpl_info::drop_thd");

  if (thd_created)
  {
    System_table_access::drop_thd(thd);
    thd_created= false;
  }

  DBUG_VOID_RETURN;
}

For our case thd_created is false, and that is why thd is not deleted and the memory managed with thd->mem_root is not deallocated.

That is why if slave sql thread is restarted, it's thd is deleted, and, as a result thd->mem_root memory is deallocated, what can be considered as workaround for this bug.