mysql5/mysql-5.7.27/sql/rpl_msr.cc

244 lines
6.0 KiB
C++

/* Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "rpl_msr.h"
#include "rpl_rli.h" // Relay_log_info
const char* Multisource_info::default_channel= "";
const char* Multisource_info::group_replication_channel_names[] = {
"group_replication_applier",
"group_replication_recovery"
};
bool Multisource_info::add_mi(const char* channel_name, Master_info* mi)
{
DBUG_ENTER("Multisource_info::add_mi");
m_channel_map_lock->assert_some_wrlock();
mi_map::const_iterator it;
std::pair<mi_map::iterator, bool> ret;
bool res= false;
/* The check of mi exceeding MAX_CHANNELS shall be done in the caller */
DBUG_ASSERT(current_mi_count < MAX_CHANNELS);
replication_channel_map::iterator map_it;
enum_channel_type type= is_group_replication_channel_name(channel_name)
? GROUP_REPLICATION_CHANNEL: SLAVE_REPLICATION_CHANNEL;
map_it= rep_channel_map.find(type);
if (map_it == rep_channel_map.end())
{
std::pair<replication_channel_map::iterator, bool> map_ret =
rep_channel_map.insert(replication_channel_map::value_type(type, mi_map()));
if (!map_ret.second)
DBUG_RETURN(true);
map_it = rep_channel_map.find(type);
}
ret = map_it->second.insert(mi_map::value_type(channel_name, mi));
/* If a map insert fails, ret.second is false */
if(!ret.second)
DBUG_RETURN(true);
/* Save the pointer for the default_channel to avoid searching it */
if (!strcmp(channel_name, get_default_channel()))
default_channel_mi= mi;
#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
res= add_mi_to_rpl_pfs_mi(mi);
#endif
current_mi_count++;
DBUG_RETURN(res);
}
Master_info* Multisource_info::get_mi(const char* channel_name)
{
DBUG_ENTER("Multisource_info::get_mi");
m_channel_map_lock->assert_some_lock();
DBUG_ASSERT(channel_name != 0);
mi_map::iterator it;
replication_channel_map::iterator map_it;
map_it= rep_channel_map.find(SLAVE_REPLICATION_CHANNEL);
if (map_it != rep_channel_map.end())
{
it= map_it->second.find(channel_name);
}
if (map_it == rep_channel_map.end() || //If not a slave channel, maybe a group one
it == map_it->second.end())
{
map_it= rep_channel_map.find(GROUP_REPLICATION_CHANNEL);
if (map_it == rep_channel_map.end())
{
DBUG_RETURN(0);
}
it= map_it->second.find(channel_name);
if (it == map_it->second.end())
{
DBUG_RETURN(0);
}
}
DBUG_RETURN(it->second);
}
void Multisource_info::delete_mi(const char* channel_name)
{
DBUG_ENTER("Multisource_info::delete_mi");
m_channel_map_lock->assert_some_wrlock();
Master_info *mi= 0;
mi_map::iterator it;
DBUG_ASSERT(channel_name != 0);
replication_channel_map::iterator map_it;
map_it= rep_channel_map.find(SLAVE_REPLICATION_CHANNEL);
if (map_it != rep_channel_map.end())
{
it= map_it->second.find(channel_name);
}
if (map_it == rep_channel_map.end() || //If not a slave channel, maybe a group one
it == map_it->second.end())
{
map_it= rep_channel_map.find(GROUP_REPLICATION_CHANNEL);
DBUG_ASSERT(map_it != rep_channel_map.end());
it= map_it->second.find(channel_name);
DBUG_ASSERT(it != map_it->second.end());
}
#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
int index= -1;
/* get the index of mi from rpl_pfs_mi */
index= get_index_from_rpl_pfs_mi(channel_name);
DBUG_ASSERT(index != -1);
/* set the current index to 0 and decrease current_mi_count */
rpl_pfs_mi[index] = 0;
#endif
current_mi_count--;
mi= it->second;
it->second= 0;
/* erase from the map */
map_it->second.erase(it);
if (default_channel_mi == mi)
default_channel_mi= NULL;
/* delete the master info */
if (mi)
{
mi->channel_assert_some_wrlock();
mi->wait_until_no_reference(current_thd);
if(mi->rli)
{
delete mi->rli;
}
delete mi;
}
DBUG_VOID_RETURN;
}
bool Multisource_info::is_group_replication_channel_name(const char* channel,
bool is_applier)
{
if (is_applier)
return !strcmp(channel, group_replication_channel_names[0]);
else
return !strcmp(channel, group_replication_channel_names[0]) ||
!strcmp(channel, group_replication_channel_names[1]);
}
#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
bool Multisource_info::add_mi_to_rpl_pfs_mi(Master_info *mi)
{
DBUG_ENTER("Multisource_info::add_mi_to_rpl_pfs_mi");
m_channel_map_lock->assert_some_wrlock();
bool res=true; // not added
/* Point to this added mi in the rpl_pfs_mi*/
for (uint i = 0; i < MAX_CHANNELS; i++)
{
if (rpl_pfs_mi[i] == 0)
{
rpl_pfs_mi[i] = mi;
res= false; // success
break;
}
}
DBUG_RETURN(res);
}
int Multisource_info::get_index_from_rpl_pfs_mi(const char * channel_name)
{
m_channel_map_lock->assert_some_lock();
Master_info* mi= 0;
for (uint i= 0; i < MAX_CHANNELS; i++)
{
mi= rpl_pfs_mi[i];
if (mi)
{
if ( !strcmp(mi->get_channel(), channel_name))
return i;
}
}
return -1;
}
Master_info* Multisource_info::get_mi_at_pos(uint pos)
{
DBUG_ENTER("Multisource_info::get_mi_at_pos");
m_channel_map_lock->assert_some_lock();
if ( pos < MAX_CHANNELS)
DBUG_RETURN(rpl_pfs_mi[pos]);
DBUG_RETURN(0);
}
#endif /*WITH_PERFSCHEMA_STORAGE_ENGINE */
/* There is only one channel_map for the whole server */
Multisource_info channel_map;