mirror of
https://github.com/MariaDB/server.git
synced 2026-05-16 20:07:13 +02:00
MDEV-26: Global Transaction ID.
Move a bunch of GTID specific code into new file rpl_gtid.cc. Make libmysqld build.
This commit is contained in:
parent
320863530f
commit
5e414f6b06
9 changed files with 1215 additions and 1158 deletions
|
|
@ -98,6 +98,7 @@ SET(SQL_EMBEDDED_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc
|
|||
../sql/rpl_reporting.cc
|
||||
../sql/sql_expression_cache.cc
|
||||
../sql/my_apc.cc ../sql/my_apc.h
|
||||
../sql/rpl_gtid.cc
|
||||
${GEN_SOURCES}
|
||||
${MYSYS_LIBWRAP_SOURCE}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@ SET (SQL_SOURCE
|
|||
threadpool_common.cc
|
||||
../sql-common/mysql_async.c
|
||||
my_apc.cc my_apc.h
|
||||
rpl_gtid.cc
|
||||
${GEN_SOURCES}
|
||||
${MYSYS_LIBWRAP_SOURCE}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -2737,6 +2737,11 @@ void Item_func_binlog_gtid_pos::fix_length_and_dec()
|
|||
String *Item_func_binlog_gtid_pos::val_str(String *str)
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
#ifndef HAVE_REPLICATION
|
||||
null_value= 0;
|
||||
str->copy("", 0, system_charset_info);
|
||||
return str;
|
||||
#else
|
||||
String name_str, *name;
|
||||
longlong pos;
|
||||
|
||||
|
|
@ -2757,6 +2762,7 @@ String *Item_func_binlog_gtid_pos::val_str(String *str)
|
|||
err:
|
||||
null_value= 1;
|
||||
return NULL;
|
||||
#endif /* !HAVE_REPLICATION */
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
1011
sql/log_event.cc
1011
sql/log_event.cc
File diff suppressed because it is too large
Load diff
145
sql/log_event.h
145
sql/log_event.h
|
|
@ -49,6 +49,8 @@
|
|||
#include "sql_class.h" /* THD */
|
||||
#endif
|
||||
|
||||
#include "rpl_gtid.h"
|
||||
|
||||
/* Forward declarations */
|
||||
class String;
|
||||
|
||||
|
|
@ -2947,149 +2949,6 @@ public:
|
|||
};
|
||||
|
||||
|
||||
struct rpl_gtid
|
||||
{
|
||||
uint32 domain_id;
|
||||
uint32 server_id;
|
||||
uint64 seq_no;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Replication slave state.
|
||||
|
||||
For every independent replication stream (identified by domain_id), this
|
||||
remembers the last gtid applied on the slave within this domain.
|
||||
|
||||
Since events are always committed in-order within a single domain, this is
|
||||
sufficient to maintain the state of the replication slave.
|
||||
*/
|
||||
struct rpl_slave_state
|
||||
{
|
||||
/* Elements in the list of GTIDs kept for each domain_id. */
|
||||
struct list_element
|
||||
{
|
||||
struct list_element *next;
|
||||
uint64 sub_id;
|
||||
uint64 seq_no;
|
||||
uint32 server_id;
|
||||
};
|
||||
|
||||
/* Elements in the HASH that hold the state for one domain_id. */
|
||||
struct element
|
||||
{
|
||||
struct list_element *list;
|
||||
uint64 last_sub_id;
|
||||
uint32 domain_id;
|
||||
|
||||
list_element *grab_list() { list_element *l= list; list= NULL; return l; }
|
||||
void add(list_element *l)
|
||||
{
|
||||
l->next= list;
|
||||
list= l;
|
||||
if (last_sub_id < l->sub_id)
|
||||
last_sub_id= l->sub_id;
|
||||
}
|
||||
};
|
||||
|
||||
/* Mapping from domain_id to its element. */
|
||||
HASH hash;
|
||||
/* Mutex protecting access to the state. */
|
||||
mysql_mutex_t LOCK_slave_state;
|
||||
|
||||
bool inited;
|
||||
bool loaded;
|
||||
|
||||
rpl_slave_state();
|
||||
~rpl_slave_state();
|
||||
|
||||
void init();
|
||||
void deinit();
|
||||
void truncate_hash();
|
||||
ulong count() const { return hash.records; }
|
||||
int update(uint32 domain_id, uint32 server_id, uint64 sub_id, uint64 seq_no);
|
||||
int truncate_state_table(THD *thd);
|
||||
int record_gtid(THD *thd, const rpl_gtid *gtid, uint64 sub_id,
|
||||
bool in_transaction);
|
||||
uint64 next_subid(uint32 domain_id);
|
||||
int tostring(String *dest, rpl_gtid *extra_gtids, uint32 num_extra);
|
||||
int load(THD *thd, char *state_from_master, size_t len, bool reset);
|
||||
bool is_empty();
|
||||
|
||||
void lock() { DBUG_ASSERT(inited); mysql_mutex_lock(&LOCK_slave_state); }
|
||||
void unlock() { DBUG_ASSERT(inited); mysql_mutex_unlock(&LOCK_slave_state); }
|
||||
|
||||
element *get_element(uint32 domain_id);
|
||||
|
||||
void update_state_hash(uint64 sub_id, rpl_gtid *gtid);
|
||||
int record_and_update_gtid(THD *thd, Relay_log_info *rli);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Binlog state.
|
||||
This keeps the last GTID written to the binlog for every distinct
|
||||
(domain_id, server_id) pair.
|
||||
This will be logged at the start of the next binlog file as a
|
||||
Gtid_list_log_event; this way, it is easy to find the binlog file
|
||||
containing a gigen GTID, by simply scanning backwards from the newest
|
||||
one until a lower seq_no is found in the Gtid_list_log_event at the
|
||||
start of a binlog for the given domain_id and server_id.
|
||||
|
||||
We also remember the last logged GTID for every domain_id. This is used
|
||||
to know where to start when a master is changed to a slave. As a side
|
||||
effect, it also allows to skip a hash lookup in the very common case of
|
||||
logging a new GTID with same server id as last GTID.
|
||||
*/
|
||||
struct rpl_binlog_state
|
||||
{
|
||||
struct element {
|
||||
uint32 domain_id;
|
||||
HASH hash; /* Containing all server_id for one domain_id */
|
||||
/* The most recent entry in the hash. */
|
||||
rpl_gtid *last_gtid;
|
||||
};
|
||||
/* Mapping from domain_id to collection of elements. */
|
||||
HASH hash;
|
||||
/* Mutex protecting access to the state. */
|
||||
mysql_mutex_t LOCK_binlog_state;
|
||||
|
||||
rpl_binlog_state();
|
||||
~rpl_binlog_state();
|
||||
|
||||
void reset();
|
||||
int update(const struct rpl_gtid *gtid);
|
||||
uint32 seq_no_from_state();
|
||||
int write_to_iocache(IO_CACHE *dest);
|
||||
int read_from_iocache(IO_CACHE *src);
|
||||
uint32 count();
|
||||
int get_gtid_list(rpl_gtid *gtid_list, uint32 list_size);
|
||||
int get_most_recent_gtid_list(rpl_gtid **list, uint32 *size);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Represent the GTID state that a slave connection to a master requests
|
||||
the master to start sending binlog events from.
|
||||
*/
|
||||
struct slave_connection_state
|
||||
{
|
||||
/* Mapping from domain_id to the GTID requested for that domain. */
|
||||
HASH hash;
|
||||
|
||||
slave_connection_state();
|
||||
~slave_connection_state();
|
||||
|
||||
int load(char *slave_request, size_t len);
|
||||
int load(const rpl_gtid *gtid_list, uint32 count);
|
||||
rpl_gtid *find(uint32 domain_id);
|
||||
int update(const rpl_gtid *in_gtid);
|
||||
void remove(const rpl_gtid *gtid);
|
||||
ulong count() const { return hash.records; }
|
||||
int to_string(String *out_str);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
@class Gtid_log_event
|
||||
|
||||
|
|
|
|||
1035
sql/rpl_gtid.cc
Normal file
1035
sql/rpl_gtid.cc
Normal file
File diff suppressed because it is too large
Load diff
170
sql/rpl_gtid.h
Normal file
170
sql/rpl_gtid.h
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
/* Copyright (c) 2013, Kristian Nielsen and MariaDB Services Ab.
|
||||
|
||||
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 */
|
||||
|
||||
#ifndef RPL_GTID_H
|
||||
#define RPL_GTID_H
|
||||
|
||||
/* Definitions for MariaDB global transaction ID (GTID). */
|
||||
|
||||
|
||||
class String;
|
||||
|
||||
struct rpl_gtid
|
||||
{
|
||||
uint32 domain_id;
|
||||
uint32 server_id;
|
||||
uint64 seq_no;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Replication slave state.
|
||||
|
||||
For every independent replication stream (identified by domain_id), this
|
||||
remembers the last gtid applied on the slave within this domain.
|
||||
|
||||
Since events are always committed in-order within a single domain, this is
|
||||
sufficient to maintain the state of the replication slave.
|
||||
*/
|
||||
struct rpl_slave_state
|
||||
{
|
||||
/* Elements in the list of GTIDs kept for each domain_id. */
|
||||
struct list_element
|
||||
{
|
||||
struct list_element *next;
|
||||
uint64 sub_id;
|
||||
uint64 seq_no;
|
||||
uint32 server_id;
|
||||
};
|
||||
|
||||
/* Elements in the HASH that hold the state for one domain_id. */
|
||||
struct element
|
||||
{
|
||||
struct list_element *list;
|
||||
uint64 last_sub_id;
|
||||
uint32 domain_id;
|
||||
|
||||
list_element *grab_list() { list_element *l= list; list= NULL; return l; }
|
||||
void add(list_element *l)
|
||||
{
|
||||
l->next= list;
|
||||
list= l;
|
||||
if (last_sub_id < l->sub_id)
|
||||
last_sub_id= l->sub_id;
|
||||
}
|
||||
};
|
||||
|
||||
/* Mapping from domain_id to its element. */
|
||||
HASH hash;
|
||||
/* Mutex protecting access to the state. */
|
||||
mysql_mutex_t LOCK_slave_state;
|
||||
|
||||
bool inited;
|
||||
bool loaded;
|
||||
|
||||
rpl_slave_state();
|
||||
~rpl_slave_state();
|
||||
|
||||
void init();
|
||||
void deinit();
|
||||
void truncate_hash();
|
||||
ulong count() const { return hash.records; }
|
||||
int update(uint32 domain_id, uint32 server_id, uint64 sub_id, uint64 seq_no);
|
||||
int truncate_state_table(THD *thd);
|
||||
int record_gtid(THD *thd, const rpl_gtid *gtid, uint64 sub_id,
|
||||
bool in_transaction);
|
||||
uint64 next_subid(uint32 domain_id);
|
||||
int tostring(String *dest, rpl_gtid *extra_gtids, uint32 num_extra);
|
||||
int load(THD *thd, char *state_from_master, size_t len, bool reset);
|
||||
bool is_empty();
|
||||
|
||||
void lock() { DBUG_ASSERT(inited); mysql_mutex_lock(&LOCK_slave_state); }
|
||||
void unlock() { DBUG_ASSERT(inited); mysql_mutex_unlock(&LOCK_slave_state); }
|
||||
|
||||
element *get_element(uint32 domain_id);
|
||||
|
||||
void update_state_hash(uint64 sub_id, rpl_gtid *gtid);
|
||||
int record_and_update_gtid(THD *thd, Relay_log_info *rli);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Binlog state.
|
||||
This keeps the last GTID written to the binlog for every distinct
|
||||
(domain_id, server_id) pair.
|
||||
This will be logged at the start of the next binlog file as a
|
||||
Gtid_list_log_event; this way, it is easy to find the binlog file
|
||||
containing a gigen GTID, by simply scanning backwards from the newest
|
||||
one until a lower seq_no is found in the Gtid_list_log_event at the
|
||||
start of a binlog for the given domain_id and server_id.
|
||||
|
||||
We also remember the last logged GTID for every domain_id. This is used
|
||||
to know where to start when a master is changed to a slave. As a side
|
||||
effect, it also allows to skip a hash lookup in the very common case of
|
||||
logging a new GTID with same server id as last GTID.
|
||||
*/
|
||||
struct rpl_binlog_state
|
||||
{
|
||||
struct element {
|
||||
uint32 domain_id;
|
||||
HASH hash; /* Containing all server_id for one domain_id */
|
||||
/* The most recent entry in the hash. */
|
||||
rpl_gtid *last_gtid;
|
||||
};
|
||||
/* Mapping from domain_id to collection of elements. */
|
||||
HASH hash;
|
||||
/* Mutex protecting access to the state. */
|
||||
mysql_mutex_t LOCK_binlog_state;
|
||||
|
||||
rpl_binlog_state();
|
||||
~rpl_binlog_state();
|
||||
|
||||
void reset();
|
||||
int update(const struct rpl_gtid *gtid);
|
||||
uint32 seq_no_from_state();
|
||||
int write_to_iocache(IO_CACHE *dest);
|
||||
int read_from_iocache(IO_CACHE *src);
|
||||
uint32 count();
|
||||
int get_gtid_list(rpl_gtid *gtid_list, uint32 list_size);
|
||||
int get_most_recent_gtid_list(rpl_gtid **list, uint32 *size);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Represent the GTID state that a slave connection to a master requests
|
||||
the master to start sending binlog events from.
|
||||
*/
|
||||
struct slave_connection_state
|
||||
{
|
||||
/* Mapping from domain_id to the GTID requested for that domain. */
|
||||
HASH hash;
|
||||
|
||||
slave_connection_state();
|
||||
~slave_connection_state();
|
||||
|
||||
int load(char *slave_request, size_t len);
|
||||
int load(const rpl_gtid *gtid_list, uint32 count);
|
||||
rpl_gtid *find(uint32 domain_id);
|
||||
int update(const rpl_gtid *in_gtid);
|
||||
void remove(const rpl_gtid *gtid);
|
||||
ulong count() const { return hash.records; }
|
||||
int to_string(String *out_str);
|
||||
};
|
||||
|
||||
extern bool rpl_slave_state_tostring_helper(String *dest, const rpl_gtid *gtid,
|
||||
bool *first);
|
||||
extern const LEX_STRING rpl_gtid_slave_state_table_name;
|
||||
|
||||
#endif /* RPL_GTID_H */
|
||||
|
|
@ -37,9 +37,6 @@ static int count_relay_log_space(Relay_log_info* rli);
|
|||
*/
|
||||
rpl_slave_state rpl_global_gtid_slave_state;
|
||||
|
||||
const LEX_STRING rpl_gtid_slave_state_table_name=
|
||||
{ STRING_WITH_LEN("rpl_slave_state") };
|
||||
|
||||
|
||||
// Defined in slave.cc
|
||||
int init_intvar_from_file(int* var, IO_CACHE* f, int default_val);
|
||||
|
|
|
|||
|
|
@ -592,7 +592,6 @@ private:
|
|||
int init_relay_log_info(Relay_log_info* rli, const char* info_fname);
|
||||
|
||||
|
||||
extern const LEX_STRING rpl_gtid_slave_state_table_name;
|
||||
extern struct rpl_slave_state rpl_global_gtid_slave_state;
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue