fix(ha): wire raft trace to DEBUG3; drop NOP on promoted ep; fix --vcpus in deploy script
- ha.c: add raft_cb_trace callback wired to s_real_cbs.on_trace; emits RAFT[pN] term=T event=E at DEBUG3 level, visible with -vvv flag. - ha.c: repl_ack_decode_and_dispatch now silently drops OPCode_nop and OPCode_reply instead of WARNING — heartbeat NOP replies from standbys arrive on promoted endpoints and are expected. - deploy-ha.sh: fix --vcpu -> --vcpus; add \$VERBOSE passthrough so start.sh respects VERBOSE=-vvv from the environment.
This commit is contained in:
parent
7b39650229
commit
d00d3bb051
2 changed files with 94 additions and 1 deletions
|
|
@ -550,6 +550,19 @@ static int raft_cb_persist(void *ctx, uint64_t term, int voted_for)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* raft_cb_trace: emit raft state-machine events at DEBUG3 level.
|
||||||
|
* Active when controller is started with -vvv; suppressed otherwise. */
|
||||||
|
static void raft_cb_trace(void *ctx, const char *event, const char *detail)
|
||||||
|
{
|
||||||
|
ha_state_t *ha = (ha_state_t *)ctx;
|
||||||
|
tlog(TLOG_DEBUG3, "RAFT[%s] term=%" PRIu64 " event=%s%s%s",
|
||||||
|
ha->my_priority == 0 ? "p0" :
|
||||||
|
ha->my_priority == 1 ? "p1" : "p2",
|
||||||
|
atomic_load_explicit(&ha->term, memory_order_relaxed),
|
||||||
|
event,
|
||||||
|
detail ? " " : "", detail ? detail : "");
|
||||||
|
}
|
||||||
|
|
||||||
static const raft_callbacks_t s_real_cbs = {
|
static const raft_callbacks_t s_real_cbs = {
|
||||||
.on_send_vote_request = raft_cb_send_vote_request,
|
.on_send_vote_request = raft_cb_send_vote_request,
|
||||||
.on_vote_eligible = raft_cb_vote_eligible,
|
.on_vote_eligible = raft_cb_vote_eligible,
|
||||||
|
|
@ -559,7 +572,7 @@ static const raft_callbacks_t s_real_cbs = {
|
||||||
.on_schedule_timeout = raft_cb_schedule_timeout,
|
.on_schedule_timeout = raft_cb_schedule_timeout,
|
||||||
.on_cancel_timeout = raft_cb_cancel_timeout,
|
.on_cancel_timeout = raft_cb_cancel_timeout,
|
||||||
.on_start_election_after_delay = raft_cb_start_election_after_delay,
|
.on_start_election_after_delay = raft_cb_start_election_after_delay,
|
||||||
.on_trace = NULL,
|
.on_trace = raft_cb_trace,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ── PRNG seeding ───────────────────────────────────────────── */
|
/* ── PRNG seeding ───────────────────────────────────────────── */
|
||||||
|
|
@ -2058,6 +2071,8 @@ static int repl_ack_decode_and_dispatch(endpoint_t *ep, vote_ep_ctx_t *vctx)
|
||||||
|
|
||||||
if (opcode == OPCode_replCatchUpDone) {
|
if (opcode == OPCode_replCatchUpDone) {
|
||||||
ha_repl_ack_received(ha, c);
|
ha_repl_ack_received(ha, c);
|
||||||
|
} else if (opcode == OPCode_nop || opcode == OPCode_reply) {
|
||||||
|
/* Heartbeat NOP reply or generic reply — silently drop */
|
||||||
} else {
|
} else {
|
||||||
WARN("repl_ack_decode_and_dispatch: unexpected opcode %d on promoted ep",
|
WARN("repl_ack_decode_and_dispatch: unexpected opcode %d on promoted ep",
|
||||||
opcode);
|
opcode);
|
||||||
|
|
|
||||||
78
src/tools/deploy-ha.sh
Executable file
78
src/tools/deploy-ha.sh
Executable file
|
|
@ -0,0 +1,78 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
BINARY=$1
|
||||||
|
DATADIR=$2
|
||||||
|
TOP=$3
|
||||||
|
PEERS=$4
|
||||||
|
|
||||||
|
if [ -z "$BINARY" ] || [ -z "$DATADIR" ] || [ -z "$TOP" ] || [ -z "$PEERS" ]; then
|
||||||
|
echo "Usage: $0 <binary> <data-dir> <top-dir> <peers>"
|
||||||
|
echo " peers: comma-separated host:port list (e.g. host1:port1,host2:port2)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
BINARY=$(realpath "$BINARY")
|
||||||
|
|
||||||
|
IFS=',' read -ra PEER_ARRAY <<< "$PEERS"
|
||||||
|
N=${#PEER_ARRAY[@]}
|
||||||
|
|
||||||
|
# Create directory structure
|
||||||
|
mkdir -p "$TOP/certs"
|
||||||
|
mkdir -p "$TOP/logs"
|
||||||
|
mkdir -p "$TOP/scripts"
|
||||||
|
for i in $(seq 1 $N); do
|
||||||
|
mkdir -p "$TOP/ctrl-$i/conf"
|
||||||
|
mkdir -p "$TOP/ctrl-$i/data"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Copy certificates
|
||||||
|
cp "$DATADIR/xce.crt" "$TOP/certs/"
|
||||||
|
cp "$DATADIR/xce.key" "$TOP/certs/"
|
||||||
|
|
||||||
|
# Tag and copy cluster.bin
|
||||||
|
TAG=$(sha256sum "$DATADIR/cluster.bin" | cut -c1-12)
|
||||||
|
cp "$DATADIR/cluster.bin" "$TOP/ctrl-1/conf/cluster.bin.$TAG"
|
||||||
|
echo "cluster.bin.$TAG" > "$TOP/ctrl-1/conf/current"
|
||||||
|
|
||||||
|
# Build peers string: ctrl-1=host1:port1,ctrl-2=host2:port2,...
|
||||||
|
PEERS_STR=""
|
||||||
|
for i in "${!PEER_ARRAY[@]}"; do
|
||||||
|
n=$((i+1))
|
||||||
|
[ -n "$PEERS_STR" ] && PEERS_STR+=","
|
||||||
|
PEERS_STR+="ctrl-$n=${PEER_ARRAY[$i]}"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Generate start script
|
||||||
|
cat > "$TOP/scripts/start.sh" << EOF
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
NAME=\$1
|
||||||
|
if [ -z "\$NAME" ]; then
|
||||||
|
echo "Usage: \$0 <ctrl-name>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
CTRL_DIR=$TOP/\$NAME
|
||||||
|
if [ ! -d "\$CTRL_DIR/conf" ] || [ ! -d "\$CTRL_DIR/data" ]; then
|
||||||
|
echo "Error: \$CTRL_DIR/conf or \$CTRL_DIR/data does not exist"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
$BINARY --myname \$NAME --peers "$PEERS_STR" --workdir $TOP --logfile $TOP/logs/\$NAME.log --vcpus 4 \$VERBOSE
|
||||||
|
EOF
|
||||||
|
chmod +x "$TOP/scripts/start.sh"
|
||||||
|
|
||||||
|
# Generate cleanup script
|
||||||
|
cat > "$TOP/scripts/cleanup.sh" << EOF
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
rm -f $TOP/logs/*.log
|
||||||
|
for i in \$(seq 1 $N); do
|
||||||
|
rm -rf $TOP/ctrl-\$i/data/*
|
||||||
|
done
|
||||||
|
for i in \$(seq 2 $N); do
|
||||||
|
rm -rf $TOP/ctrl-\$i/conf/*
|
||||||
|
done
|
||||||
|
EOF
|
||||||
|
chmod +x "$TOP/scripts/cleanup.sh"
|
||||||
|
|
||||||
|
echo "Deployed $N-node cluster to $TOP (tag: $TAG)"
|
||||||
Loading…
Add table
Add a link
Reference in a new issue