2021-10-27 12:26:42 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <sstream>
|
|
|
|
#include <string>
|
|
|
|
#include <unordered_map>
|
2021-11-18 20:17:22 +00:00
|
|
|
|
2021-10-27 12:26:42 +00:00
|
|
|
#include <Coordination/KeeperDispatcher.h>
|
|
|
|
#include <IO/WriteBufferFromString.h>
|
|
|
|
|
2022-09-28 08:55:05 +00:00
|
|
|
#include "config_version.h"
|
2021-10-27 12:26:42 +00:00
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
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
|
|
|
|
2022-03-17 10:55:15 +00:00
|
|
|
///represent '*' which is used in allow list
|
|
|
|
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;
|
|
|
|
};
|
|
|
|
|
2022-04-13 14:08:13 +00:00
|
|
|
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-22 14:31:17 +00:00
|
|
|
|
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-22 14:31:17 +00:00
|
|
|
{
|
2022-10-24 12:08:58 +00:00
|
|
|
explicit LogInfoCommand(KeeperDispatcher & keeper_dispatcher_)
|
2022-10-22 14:31:17 +00:00
|
|
|
: IFourLetterCommand(keeper_dispatcher_)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2022-10-24 12:08:58 +00:00
|
|
|
String name() override { return "lgif"; }
|
2022-10-22 14:31:17 +00:00
|
|
|
String run() override;
|
2022-10-24 12:08:58 +00:00
|
|
|
~LogInfoCommand() override = default;
|
2022-10-22 14:31:17 +00:00
|
|
|
};
|
|
|
|
|
2022-11-08 04:01:53 +00:00
|
|
|
/// 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;
|
|
|
|
};
|
|
|
|
|
2023-02-06 14:33:45 +00:00
|
|
|
/// Request to be leader.
|
|
|
|
struct RecalculateCommand : public IFourLetterCommand
|
|
|
|
{
|
|
|
|
explicit RecalculateCommand(KeeperDispatcher & keeper_dispatcher_)
|
|
|
|
: IFourLetterCommand(keeper_dispatcher_)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
String name() override { return "rclc"; }
|
|
|
|
String run() override;
|
|
|
|
~RecalculateCommand() override = default;
|
|
|
|
};
|
|
|
|
|
2021-10-27 12:26:42 +00:00
|
|
|
}
|