用于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.
 
 
 
 
 
 

292 lines
8.7 KiB

/* Copyright (c) 2014, 2018, 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 RPL_SESSION_H
#define RPL_SESSION_H
#include <sys/types.h>
#include <memory>
#include "my_inttypes.h" // IWYU pragma: keep
class Gtid_set;
class Sid_map;
class THD;
struct Gtid;
/** Type of replication channel thread/transaction might be associated to*/
enum enum_rpl_channel_type {
NO_CHANNEL_INFO = 0, // No information exists about the channel
RPL_STANDARD_CHANNEL = 1, // It is a standard replication channel
GR_APPLIER_CHANNEL = 2, // It is a GR applier channel
GR_RECOVERY_CHANNEL = 3 // It is a GR recovery channel
};
/**
This class is an interface for session consistency instrumentation
in the server. It holds the context information for a given session.
It does not require locking since access to this content is mutually
exclusive by design (only one thread reading or writing to this object
at a time).
*/
class Session_consistency_gtids_ctx {
public:
/**
This is an interface to be implemented by classes that want to listen
to changes to this context. This can be used, for instance, by the
session tracker gtids to become aware of ctx modifications.
*/
class Ctx_change_listener {
public:
Ctx_change_listener() {}
virtual ~Ctx_change_listener() {}
virtual void notify_session_gtids_ctx_change() = 0;
private:
// not implemented
Ctx_change_listener(const Ctx_change_listener &rsc);
Ctx_change_listener &operator=(const Ctx_change_listener &rsc);
};
private:
/*
Local sid_map to enable a lock free m_gtid_set.
*/
Sid_map *m_sid_map;
/**
Set holding the transaction identifiers of the gtids
to reply back on the response packet.
Lifecycle: Emptied after the reply is sent back to the application. Remains
empty until:
- a RW transaction commits and a GTID is written to the binary log.
- a RO transaction is issued, the consistency level is set to "Check
Potential Writes" and the transaction is committed.
*/
Gtid_set *m_gtid_set;
/**
If a listener is registered, e.g., the session track gtids, then this
points to an instance of such listener.
Since this context is valid only for one session, there is no need
to protect this with locks.
*/
Session_consistency_gtids_ctx::Ctx_change_listener *m_listener;
/**
Keeps track of the current session track gtids, so that we capture
according to what was set before. For instance, if the user does:
SET @@SESSION.SESSION_TRACK_GTIDS='ALL_GTIDS';
...
SET @@SESSION.SESSION_TRACK_GTIDS='OWN_GTID';
The last statement should return a set of GTIDs.
*/
ulong m_curr_session_track_gtids;
protected:
/*
Auxiliary function to determine if GTID collection should take place
when it is invoked. It takes into consideration the gtid_mode and
the current session context.
@param thd the thread context.
@return true if should collect gtids, false otherwise.
*/
inline bool shall_collect(const THD *thd);
/**
Auxiliary function that allows notification of ctx change listeners.
*/
inline void notify_ctx_change_listener() {
m_listener->notify_session_gtids_ctx_change();
}
public:
/**
Simple constructor.
*/
Session_consistency_gtids_ctx();
/**
The destructor. Deletes the m_gtid_set and the sid_map.
*/
virtual ~Session_consistency_gtids_ctx();
/**
Registers the listener. The pointer MUST not be NULL.
@param listener a pointer to the listener to register.
@param thd THD context associated to this listener.
*/
void register_ctx_change_listener(
Session_consistency_gtids_ctx::Ctx_change_listener *listener, THD *thd);
/**
Unregisters the listener. The listener MUST have registered previously.
@param listener a pointer to the listener to register.
*/
void unregister_ctx_change_listener(
Session_consistency_gtids_ctx::Ctx_change_listener *listener);
/**
This member function MUST return a reference to the set of collected
GTIDs so far.
@return the set of collected GTIDs so far.
*/
inline Gtid_set *state() { return m_gtid_set; }
/**
This function MUST be called after the response packet is set to the
client connected. The implementation may act on the collected state
for instance to do garbage collection.
@param thd The thread context.
* @return true on error, false otherwise.
*/
virtual bool notify_after_response_packet(const THD *thd);
/**
This function SHALL be called once the GTID for the given transaction has
has been added to GTID_EXECUTED.
This function SHALL store the data if the
thd->variables.session_track_gtids is set to a value other than NONE.
@param thd The thread context.
@return true on error, false otherwise.
*/
virtual bool notify_after_gtid_executed_update(const THD *thd);
/**
This function MUST be called after a transaction is committed
in the server. It should be called regardless whether it is a
RO or RW transaction. Also, DDLs, DDS are considered transaction
for what is worth.
This function SHALL store relevant data for the session consistency.
@param thd The thread context.
@return true on error, false otherwise.
*/
virtual bool notify_after_transaction_commit(const THD *thd);
virtual bool notify_after_xa_prepare(const THD *thd) {
return notify_after_transaction_commit(thd);
}
private:
// not implemented
Session_consistency_gtids_ctx(const Session_consistency_gtids_ctx &rsc);
Session_consistency_gtids_ctx &operator=(
const Session_consistency_gtids_ctx &rsc);
};
/*
This object encapsulates the state kept between transactions of the same
client in order to compute logical timestamps based on WRITESET_SESSION.
*/
class Dependency_tracker_ctx {
public:
Dependency_tracker_ctx() : m_last_session_sequence_number(0) {}
void set_last_session_sequence_number(int64 sequence_number) {
m_last_session_sequence_number = sequence_number;
}
int64 get_last_session_sequence_number() {
return m_last_session_sequence_number;
}
private:
int64 m_last_session_sequence_number;
};
/**
This class tracks the last used GTID per session.
*/
class Last_used_gtid_tracker_ctx {
public:
Last_used_gtid_tracker_ctx();
virtual ~Last_used_gtid_tracker_ctx();
/**
Set the last used GTID the session.
@param[in] gtid the used gtid.
*/
void set_last_used_gtid(const Gtid &gtid);
/**
Get the last used GTID the session.
@param[out] gtid the used gtid.
*/
void get_last_used_gtid(Gtid &gtid);
private:
std::unique_ptr<Gtid> m_last_used_gtid;
};
/*
This class SHALL encapsulate the replication context associated with the THD
object.
*/
class Rpl_thd_context {
private:
Session_consistency_gtids_ctx m_session_gtids_ctx;
Dependency_tracker_ctx m_dependency_tracker_ctx;
Last_used_gtid_tracker_ctx m_last_used_gtid_tracker_ctx;
/** If this thread is a channel, what is its type*/
enum_rpl_channel_type rpl_channel_type;
Rpl_thd_context(const Rpl_thd_context &rsc);
Rpl_thd_context &operator=(const Rpl_thd_context &rsc);
public:
Rpl_thd_context() : rpl_channel_type(NO_CHANNEL_INFO) {}
inline Session_consistency_gtids_ctx &session_gtids_ctx() {
return m_session_gtids_ctx;
}
inline Dependency_tracker_ctx &dependency_tracker_ctx() {
return m_dependency_tracker_ctx;
}
inline Last_used_gtid_tracker_ctx &last_used_gtid_tracker_ctx() {
return m_last_used_gtid_tracker_ctx;
}
enum_rpl_channel_type get_rpl_channel_type() { return rpl_channel_type; }
void set_rpl_channel_type(enum_rpl_channel_type rpl_channel_type_arg) {
rpl_channel_type = rpl_channel_type_arg;
}
};
#endif /* RPL_SESSION_H */