ClickHouse/src/Coordination/FourLetterCommand.h

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

496 lines
14 KiB
C++
Raw Normal View History

2021-10-27 12:26:42 +00:00
#pragma once
2024-02-01 10:04:34 +00:00
#include "config.h"
2021-10-27 12:26:42 +00:00
2024-02-01 10:04:34 +00:00
#include <unordered_map>
#include <string>
#include <boost/noncopyable.hpp>
2023-08-09 03:02:50 +00:00
2021-10-27 12:26:42 +00:00
namespace DB
{
2023-08-09 03:02:50 +00:00
2024-02-01 10:04:34 +00:00
class WriteBufferFromOwnString;
class KeeperDispatcher;
using String = std::string;
2021-10-27 12:26:42 +00:00
struct IFourLetterCommand;
using FourLetterCommandPtr = std::shared_ptr<DB::IFourLetterCommand>;
/// Just like zookeeper Four Letter Words commands, CH Keeper responds to a small set of commands.
/// Each command is composed of four letters, these commands are useful to monitor and issue system problems.
/// The feature is based on Zookeeper 3.5.9, details is in https://zookeeper.apache.org/doc/r3.5.9/zookeeperAdmin.html#sc_zkCommands.
2022-10-25 09:15:49 +00:00
/// Also we add some additional commands such as csnp, lgif etc.
2021-10-27 12:26:42 +00:00
struct IFourLetterCommand
{
public:
using StringBuffer = DB::WriteBufferFromOwnString;
2021-11-18 20:17:22 +00:00
explicit IFourLetterCommand(KeeperDispatcher & keeper_dispatcher_);
2021-10-27 12:26:42 +00:00
virtual String name() = 0;
virtual String run() = 0;
virtual ~IFourLetterCommand();
2021-11-18 20:17:22 +00:00
int32_t code();
2021-10-27 12:26:42 +00:00
2021-11-18 20:17:22 +00:00
static String toName(int32_t code);
static inline int32_t toCode(const String & name);
2021-10-28 14:22:56 +00:00
2021-10-27 12:26:42 +00:00
protected:
2021-11-18 20:17:22 +00:00
KeeperDispatcher & keeper_dispatcher;
2021-10-27 12:26:42 +00:00
};
struct FourLetterCommandFactory : private boost::noncopyable
{
public:
2021-11-18 20:17:22 +00:00
using Commands = std::unordered_map<int32_t, FourLetterCommandPtr>;
2022-03-17 10:55:15 +00:00
using AllowList = std::vector<int32_t>;
2021-10-28 14:22:56 +00:00
2023-08-09 03:02:50 +00:00
/// Represents '*' which is used in allow list.
2022-03-17 10:55:15 +00:00
static constexpr int32_t ALLOW_LIST_ALL = 0;
2021-10-27 12:26:42 +00:00
2021-11-18 20:17:22 +00:00
bool isKnown(int32_t code);
bool isEnabled(int32_t code);
2021-10-28 14:22:56 +00:00
2021-11-18 20:17:22 +00:00
FourLetterCommandPtr get(int32_t code);
2021-10-27 12:26:42 +00:00
/// There is no need to make it thread safe, because registration is no initialization and get is after startup.
void registerCommand(FourLetterCommandPtr & command);
2022-03-17 10:55:15 +00:00
void initializeAllowList(KeeperDispatcher & keeper_dispatcher);
2021-10-27 12:26:42 +00:00
2021-10-28 14:22:56 +00:00
void checkInitialization() const;
2021-10-27 12:26:42 +00:00
bool isInitialized() const { return initialized; }
void setInitialize(bool flag) { initialized = flag; }
static FourLetterCommandFactory & instance();
2021-11-18 20:17:22 +00:00
static void registerCommands(KeeperDispatcher & keeper_dispatcher);
2021-10-27 12:26:42 +00:00
private:
2021-11-18 20:17:22 +00:00
std::atomic<bool> initialized = false;
2021-10-27 12:26:42 +00:00
Commands commands;
2022-03-17 10:55:15 +00:00
AllowList allow_list;
2021-10-27 12:26:42 +00:00
};
/**Tests if server is running in a non-error state. The server will respond with imok if it is running.
* Otherwise it will not respond at all.
*
* A response of "imok" does not necessarily indicate that the server has joined the quorum,
* just that the server process is active and bound to the specified client port.
* Use "stat" for details on state wrt quorum and client connection information.
*/
struct RuokCommand : public IFourLetterCommand
{
2021-11-18 20:17:22 +00:00
explicit RuokCommand(KeeperDispatcher & keeper_dispatcher_) : IFourLetterCommand(keeper_dispatcher_) { }
2021-10-27 12:26:42 +00:00
2021-11-05 10:21:34 +00:00
String name() override { return "ruok"; }
2021-10-27 12:26:42 +00:00
String run() override;
2021-11-05 10:21:34 +00:00
~RuokCommand() override = default;
2021-10-27 12:26:42 +00:00
};
2021-11-18 20:17:22 +00:00
/**
* Outputs a list of variables that could be used for monitoring the health of the cluster.
2021-10-27 12:26:42 +00:00
*
* echo mntr | nc localhost 2181
* zk_version 3.5.9
* zk_avg_latency 0
* zk_max_latency 0
* zk_min_latency 0
* zk_packets_received 70
* zk_packets_sent 69
* zk_outstanding_requests 0
* zk_server_state leader
* zk_znode_count 4
* zk_watch_count 0
* zk_ephemerals_count 0
* zk_approximate_data_size 27
* zk_open_file_descriptor_count 23 - only available on Unix platforms
* zk_max_file_descriptor_count 1024 - only available on Unix platforms
* zk_followers 2 - only exposed by the Leader
* zk_synced_followers 2 - only exposed by the Leader
* zk_pending_syncs 0 - only exposed by the Leader
*/
struct MonitorCommand : public IFourLetterCommand
{
2021-11-18 20:17:22 +00:00
explicit MonitorCommand(KeeperDispatcher & keeper_dispatcher_)
: IFourLetterCommand(keeper_dispatcher_)
{
}
2021-10-27 12:26:42 +00:00
2021-11-05 10:21:34 +00:00
String name() override { return "mntr"; }
2021-10-27 12:26:42 +00:00
String run() override;
2021-11-05 10:21:34 +00:00
~MonitorCommand() override = default;
2021-10-27 12:26:42 +00:00
};
struct StatResetCommand : public IFourLetterCommand
{
2021-11-18 20:17:22 +00:00
explicit StatResetCommand(KeeperDispatcher & keeper_dispatcher_) :
IFourLetterCommand(keeper_dispatcher_)
{
}
2021-10-27 12:26:42 +00:00
2021-11-05 10:21:34 +00:00
String name() override { return "srst"; }
2021-10-27 12:26:42 +00:00
String run() override;
2021-11-05 10:21:34 +00:00
~StatResetCommand() override = default;
2021-10-27 12:26:42 +00:00
};
2021-11-05 10:21:34 +00:00
/// A command that does not do anything except reply to client with predefined message.
2022-03-17 10:55:15 +00:00
///It is used to inform clients who execute none allow listed four letter word commands.
2021-10-27 12:26:42 +00:00
struct NopCommand : public IFourLetterCommand
{
2021-11-18 20:17:22 +00:00
explicit NopCommand(KeeperDispatcher & keeper_dispatcher_)
: IFourLetterCommand(keeper_dispatcher_)
{
}
2021-10-27 12:26:42 +00:00
2021-11-05 10:21:34 +00:00
String name() override { return "nopc"; }
2021-10-27 12:26:42 +00:00
String run() override;
2021-11-05 10:21:34 +00:00
~NopCommand() override = default;
2021-10-27 12:26:42 +00:00
};
struct ConfCommand : public IFourLetterCommand
{
2021-11-18 20:17:22 +00:00
explicit ConfCommand(KeeperDispatcher & keeper_dispatcher_)
: IFourLetterCommand(keeper_dispatcher_)
{
}
2021-10-27 12:26:42 +00:00
2021-11-05 10:21:34 +00:00
String name() override { return "conf"; }
String run() override;
~ConfCommand() override = default;
};
/// List full connection/session details for all clients connected to this server.
/// Includes information on numbers of packets received/sent, session id, operation latencies, last operation performed, etc...
struct ConsCommand : public IFourLetterCommand
{
2021-11-18 20:17:22 +00:00
explicit ConsCommand(KeeperDispatcher & keeper_dispatcher_)
: IFourLetterCommand(keeper_dispatcher_)
{
}
2021-11-05 10:21:34 +00:00
String name() override { return "cons"; }
String run() override;
~ConsCommand() override = default;
};
/// Reset connection/session statistics for all connections.
struct RestConnStatsCommand : public IFourLetterCommand
{
2021-11-18 20:17:22 +00:00
explicit RestConnStatsCommand(KeeperDispatcher & keeper_dispatcher_)
: IFourLetterCommand(keeper_dispatcher_)
{
}
2021-11-05 10:21:34 +00:00
String name() override { return "crst"; }
String run() override;
~RestConnStatsCommand() override = default;
};
/// Lists full details for the server.
struct ServerStatCommand : public IFourLetterCommand
{
2021-11-18 20:17:22 +00:00
explicit ServerStatCommand(KeeperDispatcher & keeper_dispatcher_)
: IFourLetterCommand(keeper_dispatcher_)
{
}
2021-11-05 10:21:34 +00:00
String name() override { return "srvr"; }
String run() override;
~ServerStatCommand() override = default;
};
/// Lists brief details for the server and connected clients.
struct StatCommand : public IFourLetterCommand
{
2021-11-18 20:17:22 +00:00
explicit StatCommand(KeeperDispatcher & keeper_dispatcher_)
: IFourLetterCommand(keeper_dispatcher_)
{
}
2021-11-05 10:21:34 +00:00
String name() override { return "stat"; }
String run() override;
~StatCommand() override = default;
};
/// Lists brief information on watches for the server.
struct BriefWatchCommand : public IFourLetterCommand
{
2021-11-18 20:17:22 +00:00
explicit BriefWatchCommand(KeeperDispatcher & keeper_dispatcher_)
: IFourLetterCommand(keeper_dispatcher_)
{
}
2021-11-05 10:21:34 +00:00
String name() override { return "wchs"; }
String run() override;
~BriefWatchCommand() override = default;
};
/// Lists detailed information on watches for the server, by session.
/// This outputs a list of sessions(connections) with associated watches (paths).
/// Note, depending on the number of watches this operation may be expensive (ie impact server performance), use it carefully.
struct WatchCommand : public IFourLetterCommand
{
2021-11-18 20:17:22 +00:00
explicit WatchCommand(KeeperDispatcher & keeper_dispatcher_)
: IFourLetterCommand(keeper_dispatcher_)
{
}
2021-11-05 10:21:34 +00:00
String name() override { return "wchc"; }
String run() override;
~WatchCommand() override = default;
};
/// Lists detailed information on watches for the server, by path.
/// This outputs a list of paths (znodes) with associated sessions.
/// Note, depending on the number of watches this operation may be expensive (ie impact server performance), use it carefully.
struct WatchByPathCommand : public IFourLetterCommand
{
2021-11-18 20:17:22 +00:00
explicit WatchByPathCommand(KeeperDispatcher & keeper_dispatcher_)
: IFourLetterCommand(keeper_dispatcher_)
{
}
2021-11-05 10:21:34 +00:00
String name() override { return "wchp"; }
2021-10-27 12:26:42 +00:00
String run() override;
2021-11-05 10:21:34 +00:00
~WatchByPathCommand() override = default;
2021-10-27 12:26:42 +00:00
};
2021-11-05 10:21:34 +00:00
/// Lists the outstanding sessions and ephemeral nodes. This only works on the leader.
struct DumpCommand : public IFourLetterCommand
{
2021-11-18 20:17:22 +00:00
explicit DumpCommand(KeeperDispatcher & keeper_dispatcher_):
IFourLetterCommand(keeper_dispatcher_)
{
}
2021-11-05 10:21:34 +00:00
String name() override { return "dump"; }
String run() override;
~DumpCommand() override = default;
};
/// Print details about serving environment
struct EnviCommand : public IFourLetterCommand
{
2021-11-18 20:17:22 +00:00
explicit EnviCommand(KeeperDispatcher & keeper_dispatcher_)
: IFourLetterCommand(keeper_dispatcher_)
{
}
2021-11-05 10:21:34 +00:00
String name() override { return "envi"; }
String run() override;
~EnviCommand() override = default;
};
/// Shows the total size of snapshot and log files in bytes
struct DataSizeCommand : public IFourLetterCommand
{
2021-11-18 20:17:22 +00:00
explicit DataSizeCommand(KeeperDispatcher & keeper_dispatcher_):
IFourLetterCommand(keeper_dispatcher_)
{
}
2021-11-05 10:21:34 +00:00
String name() override { return "dirs"; }
String run() override;
~DataSizeCommand() override = default;
};
/// Tests if server is running in read-only mode.
/// The server will respond with "ro" if in read-only mode or "rw" if not in read-only mode.
struct IsReadOnlyCommand : public IFourLetterCommand
{
2021-11-18 20:17:22 +00:00
explicit IsReadOnlyCommand(KeeperDispatcher & keeper_dispatcher_)
: IFourLetterCommand(keeper_dispatcher_)
{
}
2021-11-05 10:21:34 +00:00
String name() override { return "isro"; }
String run() override;
~IsReadOnlyCommand() override = default;
};
struct RecoveryCommand : public IFourLetterCommand
{
explicit RecoveryCommand(KeeperDispatcher & keeper_dispatcher_)
: IFourLetterCommand(keeper_dispatcher_)
{
}
String name() override { return "rcvr"; }
String run() override;
~RecoveryCommand() override = default;
};
2022-07-19 09:02:57 +00:00
struct ApiVersionCommand : public IFourLetterCommand
{
explicit ApiVersionCommand(KeeperDispatcher & keeper_dispatcher_)
: IFourLetterCommand(keeper_dispatcher_)
{
}
String name() override { return "apiv"; }
String run() override;
~ApiVersionCommand() override = default;
};
2022-09-26 10:29:15 +00:00
/// Create snapshot manually
struct CreateSnapshotCommand : public IFourLetterCommand
{
explicit CreateSnapshotCommand(KeeperDispatcher & keeper_dispatcher_)
: IFourLetterCommand(keeper_dispatcher_)
{
}
String name() override { return "csnp"; }
String run() override;
~CreateSnapshotCommand() override = default;
};
2022-10-24 12:08:58 +00:00
/** Raft log information:
2022-10-25 09:15:49 +00:00
* first_log_idx 1
* first_log_term 1
* last_log_idx 101
* last_log_term 1
* last_committed_idx 100
* leader_committed_log_idx 101
* target_committed_log_idx 101
* last_snapshot_idx 50
2022-10-24 12:08:58 +00:00
*/
struct LogInfoCommand : public IFourLetterCommand
{
2022-10-24 12:08:58 +00:00
explicit LogInfoCommand(KeeperDispatcher & keeper_dispatcher_)
: IFourLetterCommand(keeper_dispatcher_)
{
}
2022-10-24 12:08:58 +00:00
String name() override { return "lgif"; }
String run() override;
2022-10-24 12:08:58 +00:00
~LogInfoCommand() override = default;
};
/// Request to be leader.
struct RequestLeaderCommand : public IFourLetterCommand
{
explicit RequestLeaderCommand(KeeperDispatcher & keeper_dispatcher_)
: IFourLetterCommand(keeper_dispatcher_)
{
}
String name() override { return "rqld"; }
String run() override;
~RequestLeaderCommand() override = default;
};
struct RecalculateCommand : public IFourLetterCommand
{
explicit RecalculateCommand(KeeperDispatcher & keeper_dispatcher_)
: IFourLetterCommand(keeper_dispatcher_)
{
}
String name() override { return "rclc"; }
String run() override;
~RecalculateCommand() override = default;
};
2023-03-05 16:45:17 +00:00
struct CleanResourcesCommand : public IFourLetterCommand
{
explicit CleanResourcesCommand(KeeperDispatcher & keeper_dispatcher_)
: IFourLetterCommand(keeper_dispatcher_)
{
}
String name() override { return "clrs"; }
String run() override;
~CleanResourcesCommand() override = default;
};
2023-06-12 10:57:03 +00:00
struct FeatureFlagsCommand : public IFourLetterCommand
{
explicit FeatureFlagsCommand(KeeperDispatcher & keeper_dispatcher_)
: IFourLetterCommand(keeper_dispatcher_)
{
}
String name() override { return "ftfl"; }
String run() override;
~FeatureFlagsCommand() override = default;
};
/// Yield leadership and become follower.
struct YieldLeadershipCommand : public IFourLetterCommand
{
explicit YieldLeadershipCommand(KeeperDispatcher & keeper_dispatcher_)
: IFourLetterCommand(keeper_dispatcher_)
{
}
String name() override { return "ydld"; }
String run() override;
~YieldLeadershipCommand() override = default;
};
#if USE_JEMALLOC
struct JemallocDumpStats : public IFourLetterCommand
{
explicit JemallocDumpStats(KeeperDispatcher & keeper_dispatcher_)
: IFourLetterCommand(keeper_dispatcher_)
{
}
String name() override { return "jmst"; }
String run() override;
~JemallocDumpStats() override = default;
};
struct JemallocFlushProfile : public IFourLetterCommand
{
explicit JemallocFlushProfile(KeeperDispatcher & keeper_dispatcher_)
: IFourLetterCommand(keeper_dispatcher_)
{
}
String name() override { return "jmfp"; }
String run() override;
~JemallocFlushProfile() override = default;
};
struct JemallocEnableProfile : public IFourLetterCommand
{
explicit JemallocEnableProfile(KeeperDispatcher & keeper_dispatcher_)
: IFourLetterCommand(keeper_dispatcher_)
{
}
String name() override { return "jmep"; }
String run() override;
~JemallocEnableProfile() override = default;
};
struct JemallocDisableProfile : public IFourLetterCommand
{
explicit JemallocDisableProfile(KeeperDispatcher & keeper_dispatcher_)
: IFourLetterCommand(keeper_dispatcher_)
{
}
String name() override { return "jmdp"; }
String run() override;
~JemallocDisableProfile() override = default;
};
#endif
2024-02-01 10:04:34 +00:00
struct ProfileEventsCommand : public IFourLetterCommand
{
explicit ProfileEventsCommand(KeeperDispatcher & keeper_dispatcher_)
: IFourLetterCommand(keeper_dispatcher_)
{
}
String name() override { return "pfev"; }
String run() override;
~ProfileEventsCommand() override = default;
};
2021-10-27 12:26:42 +00:00
}