mirror of
https://github.com/MariaDB/server.git
synced 2025-07-27 21:55:03 +02:00
130 lines
4 KiB
C++
130 lines
4 KiB
C++
/* Copyright (c) 2013,2024, 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-1335 USA */
|
|
|
|
#ifndef RPL_GTID_BASE_H
|
|
#define RPL_GTID_BASE_H
|
|
|
|
#include "hash.h"
|
|
|
|
|
|
/* Definitions for MariaDB global transaction ID (GTID). */
|
|
|
|
struct slave_connection_state;
|
|
|
|
struct rpl_gtid
|
|
{
|
|
uint32 domain_id;
|
|
uint32 server_id;
|
|
uint64 seq_no;
|
|
};
|
|
|
|
/*
|
|
Binlog state.
|
|
|
|
A binlog state records the last GTID written to the binlog for every
|
|
distinct (domain_id, server_id) pair. Thus, each point in the binlog
|
|
corresponds to a specific binlog state.
|
|
|
|
When starting replication from a specific GTID position, the starting point
|
|
is identified as the most recent one where the binlog state has no higher
|
|
seq_no than the GTID position for any (domain_id, server_id) combination.
|
|
|
|
We also remember the most recent 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.
|
|
|
|
This base class rpl_binlog_state_base contains just be basic data operations
|
|
to insert/update GTIDs, and is used eg. from Gtid_index_*.
|
|
*/
|
|
struct rpl_binlog_state_base
|
|
{
|
|
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;
|
|
/* Counter to allocate next seq_no for this domain. */
|
|
uint64 seq_no_counter;
|
|
|
|
int update_element(const rpl_gtid *gtid);
|
|
};
|
|
|
|
/* Mapping from domain_id to collection of elements. */
|
|
HASH hash;
|
|
my_bool initialized;
|
|
|
|
rpl_binlog_state_base() : initialized(0) {}
|
|
~rpl_binlog_state_base();
|
|
void init();
|
|
void reset_nolock();
|
|
void free();
|
|
bool load_nolock(struct rpl_gtid *list, uint32 count);
|
|
bool load_nolock(rpl_binlog_state_base *orig_state);
|
|
int update_nolock(const struct rpl_gtid *gtid);
|
|
int alloc_element_nolock(const rpl_gtid *gtid);
|
|
uint32 count_nolock();
|
|
int get_gtid_list_nolock(rpl_gtid *gtid_list, uint32 list_size);
|
|
rpl_gtid *find_nolock(uint32 domain_id, uint32 server_id);
|
|
bool is_before_pos(slave_connection_state *pos);
|
|
|
|
/*
|
|
Inline iterator over a binlog state, most recent GTID comes last for each
|
|
domain just like get_gtid_list_nolock().
|
|
|
|
The ITERATOR_FUNC should have signature bool f(const rpl_gtid *), and
|
|
return true in case of error (in which case iterate() aborts and also
|
|
returns true).
|
|
|
|
Intended to do custom GTID state processing without requiring the overhead
|
|
of an intermediate list, and where the extra code generation is justified.
|
|
*/
|
|
template <typename F> bool iterate(F iterator_func)
|
|
{
|
|
uint32 i, j;
|
|
ulong outer_records= hash.records;
|
|
|
|
for (i= 0; i < outer_records; ++i)
|
|
{
|
|
element *e= (element *)my_hash_element(&hash, i);
|
|
ulong inner_records= e->hash.records;
|
|
const rpl_gtid *last_gtid= e->last_gtid;
|
|
if (unlikely(!last_gtid))
|
|
{
|
|
DBUG_ASSERT(inner_records==0);
|
|
continue;
|
|
}
|
|
for (j= 0; j <= inner_records; ++j)
|
|
{
|
|
const rpl_gtid *gtid;
|
|
if (j < inner_records)
|
|
{
|
|
gtid= (rpl_gtid *)my_hash_element(&e->hash, j);
|
|
if (gtid == last_gtid)
|
|
continue;
|
|
}
|
|
else
|
|
gtid= e->last_gtid;
|
|
if (iterator_func(gtid))
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false; // No error
|
|
}
|
|
};
|
|
|
|
|
|
#endif /* RPL_GTID_BASE_H */
|