fix(dr): Windows Update rebota VM 109 in mijlocul testului DR
Testul DR din 2026-08-08 a raportat "Restore failed" dupa 11 secunde, fara niciun log RMAN. Cauza nu a fost restore-ul: KB5101001 fusese descarcat in timpul testului din 2026-08-01 (singurul moment in care VM 109 e pornit), a ramas staged dupa qm stop si s-a finalizat la boot-ul testului urmator. Cronologie din Event Log-ul guest-ului: 06:00:58 RestartManager 10010 - nu poate reporni powershell.exe (restore-ul) 06:01:04 SCM 7034 - OpenSSH SSH Server terminat neasteptat 06:01:06 pveelite: client_loop: send disconnect: Broken pipe -> FAILED 06:01:38 VM-ul se reboteaza singur Fereastra testului (Sambata 06:00) era in afara Active Hours (08:00-17:00), deci pentru Windows era fereastra de mentenanta valida - iar VM 109 fiind pornit doar in timpul testului, aceea era singura fereastra posibila. Agravant: sshd nu avea acsiuni de recovery (RESET_PERIOD 0), deci dupa ce a murit a ramas mort si au esuat si colectarea logului si shutdown-ul gratios. Masuri: - NoAutoUpdate=1 + AUOptions=2 pe VM 109 (aplicat direct in registry) - actiuni de recovery pentru sshd: restart la 5s/10s/30s, reset=86400 - guard "STEP 3b: Windows servicing" inainte de restore (check_servicing.ps1): asteapta idle 300s, consuma controlat un reboot in asteptare, altfel abandoneaza cu "ABORTED - Windows servicing" in loc de un "Restore failed" inselator. Fail-open daca checkul lipseste - nu are voie sa pice testul. - fereastra lunara de patching (vm109-patch-window.sh + install_updates.ps1), prima duminica 03:00, cu re-armare NoAutoUpdate=1 indiferent de rezultat Adaugat si .gitattributes: cu core.autocrlf=true scripturile .sh ajungeau in working tree cu CRLF, iar ele se deployeaza prin scp direct pe Proxmox. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhQBTegE4PiMPPaapLHjkc
This commit is contained in:
@@ -357,6 +357,7 @@ run_dr_test() {
|
||||
local cleanup_freed=0
|
||||
local backup_count=0
|
||||
local restore_log="Not collected"
|
||||
local servicing_abort=false
|
||||
|
||||
log "=========================================="
|
||||
log "Oracle DR Weekly Test - Starting"
|
||||
@@ -467,12 +468,92 @@ run_dr_test() {
|
||||
WARNINGS+=("NFS mount may need manual intervention")
|
||||
fi
|
||||
|
||||
# Step 3b: Windows servicing guard
|
||||
#
|
||||
# Incident 2026-08-08: KB5101001 descărcat în timpul testului din
|
||||
# 2026-08-01 s-a finalizat la boot-ul următorului test. RestartManager
|
||||
# a omorât powershell.exe (restore-ul) la 06:00:58, sshd la 06:01:04,
|
||||
# iar VM-ul a rebootat la 06:01:38 — testul a raportat "Restore failed"
|
||||
# la 11s, fără log RMAN, deși RMAN nu pornise deloc.
|
||||
#
|
||||
# Măsura principală este NoAutoUpdate=1 pe VM 109 (vezi
|
||||
# vm109-patch-window.sh pentru fereastra lunară de patching).
|
||||
# Guard-ul de aici este plasa de siguranță: dacă totuși stack-ul de
|
||||
# servicing este activ, nu pornim restore-ul într-un VM care e pe
|
||||
# cale să se reboteze — raportăm cauza reală în loc de un
|
||||
# "Restore failed" care arată ca o problemă de backup.
|
||||
step_start=$(date +%s)
|
||||
log "STEP 3b: Checking Windows servicing state"
|
||||
|
||||
local servicing_out=""
|
||||
local servicing_idle=false
|
||||
local SERVICING_WAIT=300
|
||||
local servicing_elapsed=0
|
||||
|
||||
while [ $servicing_elapsed -lt $SERVICING_WAIT ]; do
|
||||
if servicing_out=$(ssh -p "$DR_VM_PORT" -o ConnectTimeout=10 -o StrictHostKeyChecking=no "$DR_VM_USER@$DR_VM_IP" \
|
||||
"powershell -ExecutionPolicy Bypass -File D:\\oracle\\scripts\\check_servicing.ps1" 2>/dev/null | tr -d '\r'); then
|
||||
servicing_idle=true
|
||||
break
|
||||
fi
|
||||
|
||||
# Check absent (ieșire non-zero fără output) => nu blocăm testul.
|
||||
if [ -z "$servicing_out" ]; then
|
||||
log_warning "check_servicing.ps1 did not respond, skipping servicing guard"
|
||||
WARNINGS+=("Servicing guard skipped: check_servicing.ps1 missing or unreachable on VM $DR_VM_ID")
|
||||
servicing_idle=true
|
||||
break
|
||||
fi
|
||||
|
||||
log "Windows servicing busy: $servicing_out (${servicing_elapsed}s/${SERVICING_WAIT}s)"
|
||||
sleep 15
|
||||
servicing_elapsed=$((servicing_elapsed + 15))
|
||||
done
|
||||
|
||||
if [ "$servicing_idle" = true ]; then
|
||||
track_step "Windows Servicing Check" true "Servicing stack idle" "$step_start"
|
||||
else
|
||||
# Reboot în așteptare: îl consumăm controlat, o singură dată,
|
||||
# ca testul să poată continua pe un sistem stabil.
|
||||
if echo "$servicing_out" | grep -q "REBOOT_PENDING=true"; then
|
||||
log_warning "Pending reboot detected, rebooting VM $DR_VM_ID once before restore"
|
||||
ssh -p "$DR_VM_PORT" -o ConnectTimeout=10 "$DR_VM_USER@$DR_VM_IP" "shutdown /r /t 5 /f" 2>/dev/null || true
|
||||
sleep 45
|
||||
|
||||
local reboot_elapsed=0
|
||||
while [ $reboot_elapsed -lt 300 ]; do
|
||||
if servicing_out=$(ssh -p "$DR_VM_PORT" -o ConnectTimeout=10 -o StrictHostKeyChecking=no -o BatchMode=yes "$DR_VM_USER@$DR_VM_IP" \
|
||||
"powershell -ExecutionPolicy Bypass -File D:\\oracle\\scripts\\check_servicing.ps1" 2>/dev/null | tr -d '\r'); then
|
||||
servicing_idle=true
|
||||
break
|
||||
fi
|
||||
sleep 15
|
||||
reboot_elapsed=$((reboot_elapsed + 15))
|
||||
done
|
||||
fi
|
||||
|
||||
if [ "$servicing_idle" = true ]; then
|
||||
track_step "Windows Servicing Check" true "Servicing completed after controlled reboot" "$step_start"
|
||||
WARNINGS+=("VM $DR_VM_ID had a pending servicing reboot; consumed before restore. Check NoAutoUpdate policy.")
|
||||
else
|
||||
track_step "Windows Servicing Check" false \
|
||||
"Windows Update/servicing active, restore not attempted - backups NOT implicated ($servicing_out)" "$step_start"
|
||||
test_result="ABORTED - Windows servicing"
|
||||
servicing_abort=true
|
||||
fi
|
||||
fi
|
||||
|
||||
# Step 4: Run restore
|
||||
step_start=$(date +%s)
|
||||
local restore_start=$step_start
|
||||
log "STEP 4: Running database restore"
|
||||
|
||||
if ssh -p "$DR_VM_PORT" "$DR_VM_USER@$DR_VM_IP" \
|
||||
if [ "$servicing_abort" = true ]; then
|
||||
log_error "Skipping restore: Windows servicing active on VM $DR_VM_ID"
|
||||
# Fără track_step aici: eșecul e deja raportat de "Windows Servicing
|
||||
# Check", iar un al doilea ERRORS ar duplica alarma pentru o singură cauză.
|
||||
restore_log="Restore not attempted. Windows Update/servicing was active on VM $DR_VM_ID: $servicing_out"
|
||||
elif ssh -p "$DR_VM_PORT" "$DR_VM_USER@$DR_VM_IP" \
|
||||
"powershell -ExecutionPolicy Bypass -File D:\\oracle\\scripts\\rman_restore_from_zero.ps1 -TestMode" 2>&1 | tee -a "$LOG_FILE"; then
|
||||
|
||||
local restore_end=$(date +%s)
|
||||
|
||||
Reference in New Issue
Block a user