用于EagleEye3.0 规则集漏报和误报测试的示例项目,项目收集于github和gitee
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

194 lines
7.1 KiB

5 months ago
/* Copyright (c) 2013, 2019, 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, version 2.0,
as published by the Free Software Foundation.
This program is also distributed with certain software (including
but not limited to OpenSSL) that is licensed under separate terms,
as designated in a particular file or component or in included license
documentation. The authors of MySQL hereby grant you an additional
permission to link the program and your derivative works with the
separately licensed software that they have included with MySQL.
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, version 2.0, 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 MTS_SUBMODE_H
#define MTS_SUBMODE_H
#include <stddef.h>
#include <sys/types.h>
#include <atomic>
#include <utility>
#include "libbinlogevents/include/binlog_event.h" // SEQ_UNINIT
#include "my_inttypes.h"
#include "my_thread_local.h" // my_thread_id
#include "prealloced_array.h" // Prealloced_array
class Log_event;
class Query_log_event;
class Relay_log_info;
class Slave_worker;
class THD;
struct TABLE;
typedef Prealloced_array<Slave_worker *, 4> Slave_worker_array;
enum enum_mts_parallel_type {
/* Parallel slave based on Database name */
MTS_PARALLEL_TYPE_DB_NAME = 0,
/* Parallel slave based on group information from Binlog group commit */
MTS_PARALLEL_TYPE_LOGICAL_CLOCK = 1
};
// Extend the following class as per requirement for each sub mode
class Mts_submode {
private:
protected:
/* Parallel type */
enum_mts_parallel_type type;
public:
Mts_submode() {}
inline enum_mts_parallel_type get_type() { return type; }
// pure virtual methods. Should be extended in the derieved class
/* Logic to schedule the next event. called at the B event for each
transaction */
virtual int schedule_next_event(Relay_log_info *rli, Log_event *ev) = 0;
/* logic to attach temp tables Should be extended in the derieved class */
virtual void attach_temp_tables(THD *thd, const Relay_log_info *rli,
Query_log_event *ev) = 0;
/* logic to detach temp tables. Should be extended in the derieved class */
virtual void detach_temp_tables(THD *thd, const Relay_log_info *rli,
Query_log_event *ev) = 0;
/* returns the least occupied worker. Should be extended in the derieved class
*/
virtual Slave_worker *get_least_occupied_worker(Relay_log_info *rli,
Slave_worker_array *ws,
Log_event *ev) = 0;
/* wait for slave workers to finish */
virtual int wait_for_workers_to_finish(Relay_log_info *rli,
Slave_worker *ignore = nullptr) = 0;
virtual ~Mts_submode() {}
};
/**
DB partitioned submode
For significance of each method check definition of Mts_submode
*/
class Mts_submode_database : public Mts_submode {
public:
Mts_submode_database() { type = MTS_PARALLEL_TYPE_DB_NAME; }
int schedule_next_event(Relay_log_info *rli, Log_event *ev);
void attach_temp_tables(THD *thd, const Relay_log_info *rli,
Query_log_event *ev);
void detach_temp_tables(THD *thd, const Relay_log_info *rli,
Query_log_event *ev);
Slave_worker *get_least_occupied_worker(Relay_log_info *,
Slave_worker_array *ws, Log_event *);
~Mts_submode_database() {}
int wait_for_workers_to_finish(Relay_log_info *rli,
Slave_worker *ignore = nullptr);
};
/**
Parallelization using Master parallelization information
For significance of each method check definition of Mts_submode
*/
class Mts_submode_logical_clock : public Mts_submode {
private:
bool first_event, force_new_group;
bool is_new_group;
uint delegated_jobs;
/* "instant" value of committed transactions low-water-mark */
std::atomic<longlong> last_lwm_timestamp;
/* GAQ index corresponding to the min commit point */
ulong last_lwm_index;
longlong last_committed;
longlong sequence_number;
public:
uint jobs_done;
bool is_error;
/*
the logical timestamp of the olderst transaction that is being waited by
before to resume scheduling.
*/
std::atomic<longlong> min_waited_timestamp;
/*
Committed transactions and those that are waiting for their commit parents
comprise sequences whose items are identified as GAQ index.
An empty sequence is described by the following magic value which can't
be in the GAQ legitimate range.
todo: an alternative could be to pass a magic value to the constructor.
E.g GAQ.size as a good candidate being outside of the valid range.
That requires further wl6314 refactoring in activation/deactivation
of the scheduler.
*/
static const ulong INDEX_UNDEF = (ulong)-1;
protected:
std::pair<uint, my_thread_id> get_server_and_thread_id(TABLE *table);
Slave_worker *get_free_worker(Relay_log_info *rli);
public:
Mts_submode_logical_clock();
int schedule_next_event(Relay_log_info *rli, Log_event *ev);
void attach_temp_tables(THD *thd, const Relay_log_info *rli,
Query_log_event *ev);
void detach_temp_tables(THD *thd, const Relay_log_info *rli,
Query_log_event *);
Slave_worker *get_least_occupied_worker(Relay_log_info *rli,
Slave_worker_array *ws,
Log_event *ev);
/* Sets the force new group variable */
inline void start_new_group() {
force_new_group = true;
first_event = true;
}
/**
Withdraw the delegated_job increased by the group.
*/
void withdraw_delegated_job() { delegated_jobs--; }
int wait_for_workers_to_finish(Relay_log_info *rli,
Slave_worker *ignore = nullptr);
bool wait_for_last_committed_trx(Relay_log_info *rli,
longlong last_committed_arg);
/*
LEQ comparison of two logical timestamps follows regular rules for
integers. SEQ_UNINIT is regarded as the least value in the clock domain.
@param a the lhs logical timestamp value
@param b the rhs logical timestamp value
@return true when a "<=" b,
false otherwise
*/
static bool clock_leq(longlong a, longlong b) {
if (a == SEQ_UNINIT)
return true;
else if (b == SEQ_UNINIT)
return false;
else
return a <= b;
}
longlong get_lwm_timestamp(Relay_log_info *rli, bool need_lock);
longlong estimate_lwm_timestamp() { return last_lwm_timestamp.load(); }
~Mts_submode_logical_clock() {}
};
#endif /*MTS_SUBMODE_H*/