fix(api): сбросить кэши после восстановления базы

This commit is contained in:
Denozordec committed 2026-10-07 23:12:32 +07:00
1 parent 2943032462
commit f1aac49dfc
18 files changed
+150 -17

No files matched your search

+1 -1
View File
@@ -37,7 +37,7 @@
"test:ospf-optimizer": "tsx src/services/ospf-optimizer-identity.test.ts && tsx src/services/ospf-optimizer-metrics.test.ts && tsx src/services/ospf-optimizer-plan.test.ts && tsx src/routes/ospf-optimizer.test.ts",
"test:containers": "tsx src/services/containers-state.test.ts && tsx src/routes/containers-state.test.ts",
"test:certificates": "tsx src/services/certificate-issue-execution.test.ts && tsx src/services/certificate-issue-request.test.ts && tsx src/routes/certificates-issue.test.ts && tsx src/services/certificate-issue-dto.test.ts && tsx src/services/certificate-parse.test.ts && tsx src/services/certificates-state.test.ts && tsx src/routes/certificates-state.test.ts",
"test:system-database": "tsx src/services/database-background-work.test.ts && tsx src/services/database-request-gate.test.ts && tsx src/services/traffic-flow-worker-shutdown.test.ts && tsx src/services/system-database-restore-execution.test.ts && tsx src/services/system-database-operation.test.ts && tsx src/routes/system-database.test.ts && tsx src/plugins/auth.system-database.test.ts"
"test:system-database": "tsx src/services/system-database-cache.test.ts && tsx src/services/database-background-work.test.ts && tsx src/services/database-request-gate.test.ts && tsx src/services/traffic-flow-worker-shutdown.test.ts && tsx src/services/system-database-restore-execution.test.ts && tsx src/services/system-database-operation.test.ts && tsx src/routes/system-database.test.ts && tsx src/plugins/auth.system-database.test.ts"
},
"dependencies": {
"@aws-sdk/client-s3": "^3.888.0",
@@ -10,6 +10,7 @@ import { withOperationLock } from "../db/operation-lock.js"
import { executeDatabaseOperation, type DatabaseOperationWarnings } from "./system-database-operation.js"
import { restartSchedulerAfterDatabaseOperation, stopSchedulerForDatabaseOperation } from "./scheduler.js"
import { pauseRipeBackgroundWork, resumeRipeBackgroundWork } from "./traffic-flow-ripe.js"
import { invalidateSystemDatabaseCaches } from "./system-database-cache.js"
import {
restartTrafficFlowListenerAfterDatabaseOperation,
stopTrafficFlowListenerForDatabaseOperation,
@@ -83,5 +84,6 @@ export async function restoreSystemDatabaseBackup(buffer: Buffer): Promise<Syste
write: (file, data) => writeFile(file, data),
run: async args => { await spawnCollected("pg_restore", args) },
remove: file => rm(file, { force: true }),
invalidate: invalidateSystemDatabaseCaches,
}))
}
@@ -0,0 +1,55 @@
import assert from "node:assert/strict"
import { test } from "node:test"
import { invalidateSystemDatabaseCaches } from "./system-database-cache.js"
import { applyRingSnapshot, snapshotRings } from "./traffic-flow-engine.js"
import { rememberServerIfaces, ifaceCacheHas } from "./traffic-flow-ifindex.js"
import { DatabaseBackgroundWork } from "./database-background-work.js"
import { executeDatabaseOperation } from "./system-database-operation.js"
import { executeSystemDatabaseRestore } from "./system-database-restore-execution.js"
import {
disableRipePersistForTests, seedRipeCacheForTests, lookupRipeCached,
pauseRipeBackgroundWork, resumeRipeBackgroundWork, enqueueRipeMisses, ripeFetchCountForTests,
} from "./traffic-flow-ripe.js"
test("restore discards old RIPE, interface and live data without reopening RIPE admission", async () => {
disableRipePersistForTests()
seedRipeCacheForTests({ prefix: "8.8.8.0/24", asn: 15169, country: "US", lat: null, lng: null,
holder: "old database", ok: true, fetchedAt: Date.now() })
rememberServerIfaces(1, [{ ".id": "*1", name: "ether1" }])
applyRingSnapshot([{ key: "old database", inBps: [1_000_000], outBps: [1_000_000] }])
assert.equal(lookupRipeCached("8.8.8.8")?.holder, "old database")
assert.equal(ifaceCacheHas(1), true)
assert.equal(snapshotRings().length, 1)
await pauseRipeBackgroundWork()
try {
const count = ripeFetchCountForTests()
invalidateSystemDatabaseCaches()
assert.equal(lookupRipeCached("8.8.8.8"), null)
assert.equal(ifaceCacheHas(1), false)
assert.equal(snapshotRings().length, 0)
enqueueRipeMisses(["8.8.8.8"])
assert.equal(ripeFetchCountForTests(), count)
} finally { resumeRipeBackgroundWork() }
})
test("background drain precedes restore and consumers restart with invalidated caches", async () => {
const work = new DatabaseBackgroundWork(), calls: string[] = []
let release!: () => void
work.track(new Promise<void>(r => { release = r }))
rememberServerIfaces(1, [{ ".id": "*1", name: "old-interface" }])
const operation = executeDatabaseOperation(() => executeSystemDatabaseRestore(Buffer.from("PGDMPfixture"), "fixture", {
allocate: async () => "fixture.dump", write: async () => {}, remove: async () => {},
run: async () => { calls.push("restore") },
invalidate: () => { calls.push("invalidate"); invalidateSystemDatabaseCaches() },
}), {
stopListener: () => { calls.push("stop listener") },
stopScheduler: async () => { await work.drain(); calls.push("drained") },
startListener: () => { assert.equal(ifaceCacheHas(1), false); calls.push("restart listener") },
startScheduler: () => { calls.push("restart scheduler") },
})
await Promise.resolve(); await Promise.resolve()
assert.equal(calls.includes("restore"), false)
assert.equal(ifaceCacheHas(1), true)
release(); await operation
assert.deepEqual(calls, ["stop listener", "drained", "restore", "invalidate", "restart listener", "restart scheduler"])
})
@@ -0,0 +1,20 @@
import { invalidateTrafficFlowSettingsCache } from "./traffic-flow-settings.js"
import { invalidateFlowCatalogCache } from "./traffic-flow-topology.js"
import { invalidateRipeCache } from "./traffic-flow-ripe.js"
import { invalidateIfaceCache } from "./traffic-flow-ifindex.js"
import { invalidateFlowClassificationCache } from "./traffic-flow-classify.js"
import { invalidateFlowAnalyticsCache } from "./traffic-flow-analytics.js"
import { invalidateFlowMapHopsCache } from "./traffic-flow-map-hops.js"
import { resetEngineAfterDatabaseRestore } from "./traffic-flow-engine.js"
/** Synchronous invalidation after confirmed restore and before consumers restart. */
export function invalidateSystemDatabaseCaches(): void {
invalidateTrafficFlowSettingsCache()
invalidateFlowCatalogCache()
invalidateRipeCache()
invalidateIfaceCache()
invalidateFlowClassificationCache()
invalidateFlowAnalyticsCache()
invalidateFlowMapHopsCache()
resetEngineAfterDatabaseRestore()
}
@@ -7,3 +7,12 @@ test("invalid archive never allocates or runs command",async()=>{const f=fixture
test("restore runs one transactional command and cleans file after success",async()=>{const f=fixture();assert.deepEqual(await executeSystemDatabaseRestore(dump,"postgres://fixture",f.deps),{});assert.deepEqual(f.calls,["allocate","write","run","remove"])})
test("write or restore failure always cleans temporary file and never retries",async()=>{for(const step of ["write","run"]){const f=fixture();if(step==="write")f.setWrite();else f.setRun();await assert.rejects(executeSystemDatabaseRestore(dump,"postgres://fixture",f.deps),/failed/);assert.deepEqual(f.calls,step==="write"?["allocate","write","remove"]:["allocate","write","run","remove"])}})
test("cleanup failure keeps confirmed restore result; main failure is preserved",async()=>{const f=fixture();f.setRemove();assert.deepEqual(await executeSystemDatabaseRestore(dump,"postgres://fixture",f.deps),{cleanupError:"Не удалось удалить временный файл восстановления"});const bad=fixture();bad.setRun();bad.setRemove();await assert.rejects(executeSystemDatabaseRestore(dump,"postgres://fixture",bad.deps),/restore failed; Не удалось удалить/)})
test("cache invalidation follows confirmed restore and is skipped on process failure", async () => {
const success=fixture()
await executeSystemDatabaseRestore(dump,"postgres://fixture",{...success.deps,invalidate:()=>{success.calls.push("invalidate")}})
assert.deepEqual(success.calls,["allocate","write","run","invalidate","remove"])
const failure=fixture();failure.setRun()
await assert.rejects(executeSystemDatabaseRestore(dump,"postgres://fixture",{...failure.deps,invalidate:()=>{failure.calls.push("invalidate")}}),/restore failed/)
assert.equal(failure.calls.includes("invalidate"),false)
})
@@ -4,6 +4,7 @@ interface Dependencies {
write:(path:string,buffer:Buffer)=>Promise<void>
run:(args:string[])=>Promise<void>
remove:(path:string)=>Promise<void>
invalidate?:()=>void
}
export function validateSystemDatabaseRestoreArchive(buffer:Buffer):void{
if(buffer.length>512*1024*1024)throw new Error("Файл бэкапа слишком большой")
@@ -16,6 +17,7 @@ export async function executeSystemDatabaseRestore(buffer:Buffer,databaseUrl:str
try{
await deps.write(file,buffer)
await deps.run(["--single-transaction","--clean","--if-exists","-d",databaseUrl,file])
deps.invalidate?.()
}catch(error){failed=true;failure=error}
finally{try{await deps.remove(file)}catch{cleanupError="Не удалось удалить временный файл восстановления"}}
if(failed){const message=failure instanceof Error?failure.message:"Восстановление PostgreSQL не подтверждено";throw new Error(message+(cleanupError?"; "+cleanupError:""))}
@@ -152,7 +152,9 @@ export async function buildFlowAnalytics(q: FlowAnalyticsQuery): Promise<FlowAna
return dto
}
export function resetFlowAnalyticsCacheForTests(): void {
export const resetFlowAnalyticsCacheForTests = invalidateFlowAnalyticsCache
export function invalidateFlowAnalyticsCache(): void {
analyticsCache = null
}
@@ -28,7 +28,9 @@ export function disableCatalogFetchForTests(): void {
catalogFetchEnabled = false
}
export function resetFlowCatalogForTests(): void {
export const resetFlowCatalogForTests = invalidateFlowClassificationCache
export function invalidateFlowClassificationCache(): void {
cidrs = []
asnPurpose = new Map()
fetchedAt = 0
+9 -3
View File
@@ -24,7 +24,7 @@ import {
factsPendingSize,
flushFlowFacts,
hourBucketIso,
resetFactsForTests,
resetFactsAfterDatabaseRestore,
} from "./traffic-flow-facts.js"
export const TICK_MS = 2_000
@@ -1039,13 +1039,20 @@ export function ingestParsedFlowsForServerForTests(serverId: number, flows: Pars
}
export function resetEngineForTests(): void {
resetEngineAfterDatabaseRestore()
pendingCap = MAX_PENDING
}
/** Writers are drained before replacing the database; discard data from the old snapshot. */
export function resetEngineAfterDatabaseRestore(): void {
pending.clear()
recent.clear()
tickAccum.clear()
rings.clear()
minuteRollup.clear()
minuteDims.clear()
resetFactsForTests()
resetFactsAfterDatabaseRestore()
ensuredParts.clear()
packetsReceived = 0
lastExporterIp = null
lastError = ""
@@ -1060,7 +1067,6 @@ export function resetEngineForTests(): void {
lastStatsPersistAt = 0
lastPersistedStats = null
bumpDataEpoch()
pendingCap = MAX_PENDING
}
export function pendingSizeForTests(): number {
+3 -1
View File
@@ -270,7 +270,9 @@ export function factsPendingSize(): number {
return hourFacts.size
}
export function resetFactsForTests(): void {
export const resetFactsForTests = resetFactsAfterDatabaseRestore
export function resetFactsAfterDatabaseRestore(): void {
hourFacts.clear()
ensuredParts.clear()
}
+3 -1
View File
@@ -187,7 +187,9 @@ export function markIfaceRefreshAttempt(serverId: number, at = Date.now()): void
lastAttempt.set(serverId, at)
}
export function resetIfaceCacheForTests(): void {
export const resetIfaceCacheForTests = invalidateIfaceCache
export function invalidateIfaceCache(): void {
cache.clear()
fetchedAt.clear()
lastAttempt.clear()
@@ -121,7 +121,9 @@ function bumpFrom(acc: DstAcc, exporterId: string, bytes: number, client: { user
let hopsCache: { key: string; at: number; dto: FlowMapHopsDto } | null = null
export function resetFlowMapHopsCacheForTests(): void {
export const resetFlowMapHopsCacheForTests = invalidateFlowMapHopsCache
export function invalidateFlowMapHopsCache(): void {
hopsCache = null
}
+9 -4
View File
@@ -58,6 +58,15 @@ export function disableRipeEnqueueForTests(): void {
}
export function resetRipeCacheForTests(): void {
invalidateRipeCache()
workerRunning = false
fetchCount = 0
enqueueEnabled = true
fetchImpl = globalThis.fetch.bind(globalThis)
}
/** Call only after resolver/persistence drain; preserve pause and runtime options. */
export function invalidateRipeCache(): void {
mem.clear()
asnHolder.clear()
inflight.clear()
@@ -68,10 +77,6 @@ export function resetRipeCacheForTests(): void {
wideIndex.length = 0
lastCandidateCount = 0
loaded = persistEnabled ? false : true
workerRunning = false
fetchCount = 0
enqueueEnabled = true
fetchImpl = globalThis.fetch.bind(globalThis)
}
export function seedRipeCacheForTests(entry: FlowIpMeta): void {
+1 -1
View File
@@ -25,7 +25,7 @@
Приложение использует pg_dump -Fc и pg_restore --single-transaction --clean --if-exists. Транзакционный режим описан в [документации PostgreSQL](https://www.postgresql.org/docs/current/app-pgrestore.html). Проверка пяти байтов PGDMP проверяет заголовок, но не полноту и не доверие к архиву. Для rollback нужен сценарий с ошибкой исполнения restore, а не только отказ HTTP до его начала.
В локальном блоке12.5.8 добавлено ожидание текущих scheduler jobs с закрытием admission, но этот код ещё не развёрнут на стенде673e5ba. Блок12.5.9 добавляет отдельный graceful shutdown worker для database operation, serial flush, pool.end и обязательные acknowledgement/exit0. Локальные protocol tests и настоящий isolated collector/UDP/blocked SQL drain12.5.10 прошли: [evidence](ux-ui/acceptance/netflow-worker-2026-10-07.json). Основной код на стенде ещё не обновлён; app-wide quiescence этим не подтверждена. Блок12.5.11 локально добавляет admission/drain всех API handlers иtraffic live streams; новые tests/build passed, на стенде patch не развёрнут. В12.5.12 локально добавлен общий background registry/drain дляbackup/audit/certificate/partition maintenance/cache work, атакжеpause RIPE enqueue. Tests/build passed; всяцепочка требуетintegrated quiescence12.5.13 иcache invalidation передrestore. Основнойстенд покаsource673e5ba. Другие экземпляры/хосты требуют отдельного контроля. PG-6 остаётся открытым до наблюдаемого подтверждения; восстановление стенда выполняется после его получения. Реальные тесты backend, способные очищать таблицы, запускаются только против выделенной тестовой БД.
В локальном блоке12.5.8 добавлено ожидание текущих scheduler jobs с закрытием admission, но этот код ещё не развёрнут на стенде673e5ba. Блок12.5.9 добавляет отдельный graceful shutdown worker для database operation, serial flush, pool.end и обязательные acknowledgement/exit0. Локальные protocol tests и настоящий isolated collector/UDP/blocked SQL drain12.5.10 прошли: [evidence](ux-ui/acceptance/netflow-worker-2026-10-07.json). Основной код на стенде ещё не обновлён; app-wide quiescence этим не подтверждена. Блок12.5.11 локально добавляет admission/drain всех API handlers иtraffic live streams; новые tests/build passed, на стенде patch не развёрнут. В12.5.12 локально добавлен общий background registry/drain дляbackup/audit/certificate/partition maintenance/cache work, атакжеpause RIPE enqueue. Tests/build passed; В12.5.13 добавленcache invalidation послеуспешногоrestore идоconsumer restart, локальныесовместныеhelpers tests passed. Всяцепочка требуетreal-PG integrated quiescence/restore12.5.14. Основнойстенд покаsource673e5ba. Другие экземпляры/хосты требуют отдельного контроля. PG-6 остаётся открытым до наблюдаемого подтверждения; восстановление стенда выполняется после его получения. Реальные тесты backend, способные очищать таблицы, запускаются только против выделенной тестовой БД.
После bootstrap достаточно следующих запросов чтения для начальной проверки, без вывода секретов:
+1 -1
View File
@@ -1,6 +1,6 @@
# План реализации UX/UI по пятичасовым окнам
Актуальное продолжение 2026-10-07:12.5.12 завершён локально — учтены detached backup jobs/audit, выпуск сертификатов, poll partition maintenance иbackground cache work; RIPE admission закрывается перед drain.19lifecycle/database tests,HTTP/JWT,backup/RIPE,10certificate tests иbuild passed. Основной runtime673e5ba не обновлён. Следующий12.5.13 — integrated HTTP/scheduler/background/UDP quiescence ввыделеннойБД, cache invalidation послеrestore иdeployment; PG-6/PG-3/4 ещёоткрыты.
Актуальное продолжение 2026-10-07:12.5.13 завершён локально в части cache invalidation после подтверждённогоrestore. Проверен порядокbackground drain→restore→cache reset→consumer restart;22lifecycle/database tests,HTTP/JWT,RIPE/ifindex/classify иbuild passed. Runtime673e5ba не обновлён. Следующий12.5.14 — integrated real-PG quiescence/restore ввыделеннойБД иdeployment; PG-6/PG-3/4 ещёоткрыты.
Общий план проекта MikrotikManager. Основан на согласованном плане из задачи; точка продолжения обновлена 2026-10-07. Источник фактического прогресса, проверок и ограничений — [журнал реализации](ux-ui-progress.md). Этот документ задаёт объём и критерии завершения, журнал фиксирует результат.
+11 -1
View File
@@ -1,6 +1,6 @@
# UX/UI: журнал реализации
Актуальное продолжение 2026-10-07:12.5.12 завершён локально — учтены detached backup jobs/audit, выпуск сертификатов, poll partition maintenance иbackground cache work; RIPE admission закрывается перед drain.19lifecycle/database tests,HTTP/JWT,backup/RIPE,10certificate tests иbuild passed. Основной runtime673e5ba не обновлён. Следующий12.5.13 — integrated HTTP/scheduler/background/UDP quiescence ввыделеннойБД, cache invalidation послеrestore иdeployment; PG-6/PG-3/4 ещёоткрыты.
Актуальное продолжение 2026-10-07:12.5.13 завершён локально в части cache invalidation после подтверждённогоrestore. Проверен порядокbackground drain→restore→cache reset→consumer restart;22lifecycle/database tests,HTTP/JWT,RIPE/ifindex/classify иbuild passed. Runtime673e5ba не обновлён. Следующий12.5.14 — integrated real-PG quiescence/restore ввыделеннойБД иdeployment; PG-6/PG-3/4 ещёоткрыты.
Общий план: [UX/UI по этапам и пятичасовым окнам](ux-ui-plan.md). План задаёт объём, этот журнал фиксирует выполненные блоки и ограничения. Записи расположены от новых к старым; подробная история этапа12 также сохранена в [ux-ui-stage-12.md](ux-ui-stage-12.md).
@@ -34,6 +34,16 @@
| 11Б | Оповещения, сбор данных, интеграции, релизы и настройки | Завершён в границах локальной приёмки 2026-10-03; ограничения и evidence в11Б.7 |
| 12 | Итоговая доступность, адаптивность, производительность и регрессия | Локальная приёмка завершена в описанных границах:12.3.83,main1186/1186,context221/221. Этап остаётся в работе: стенд12.5.1–3 развёрнут,bootstrap/smoke проверены;остальные сценарии12.5 не выполнены. |
## 12.5.13 — сброс кэшей после подтверждённого восстановления БД (2026-10-07)
Добавлен invalidateSystemDatabaseCaches, вызываемый послеуспешногоpg_restore внутриrestore execution, доcleanup иперезапускаconsumers. Очищаются settingsRowCache, server/topology catalog, RIPE/index/ASN cache, интерфейсы, classification catalog, analytics/map hops, engine pending/recent/rings/minute accumulators иfact/engine ensured partition sets. Последнее исключаетповторноеиспользованиепамяткиосозданныхразделах, которыхуже можетнебытьввосстановленнойБД. Engine data epoch обновлён, runtime pending cap сохранён. GeoIP readers/file state не изменены: MMDB лежатвнеPostgreSQL dump.
Production invalidate/reset функции отделеныотForTests API; старыеимена сохраненыдлясуществующихтестов. RIPE invalidation сохраняетdatabase pause/enqueue/persist/fetch options: очисткакэшейне открывает admission воперации. Inflight tasks должныбытьпредварительнодренированы механизмами12.5.8–12; приошибкеpg_restore invalidation неприменяется.
Проверки: полныйtest:system-database21tests иHTTP/JWT scripts passed, затемновыйсовместныйcache/drain testpassed (всего22различныхtests). ПровереныудалениестарыхRIPE/interface/live данных безоткрытияRIPE, успешныйrestore→invalidate иотсутствиеinvalidate приошибкепроцесса. Совместныйfixtureснастоящимиoperation/restore helpers иbackground registry доказалпорядокstop listener→background drain→restore→invalidate→restart listener/scheduler; restart увиделочищенныйinterfacecache. Командаpg_restore вэтомfixture подмененаDI, это не реальныйPG-3. RIPE/ifindex/classify regression scripts иcontracts/backend build прошли; diff-check passed. БД/RouterOS влокальныхтестахнеизменялись.
Коднеразвёрнут: основнойruntime673e5ba сохраняется. PG-6 целикомоткрыт, чтение/rollback реальногоAPIrestore ещёнеподтверждено. PostgreSQL dump не содержитGeoIP/backup/certificate files; ихдоступностьнужноучитыватьвприёмке. Другиепроцессы/хосты gate/registry неостанавливает. Следующий12.5.14 — integrated real-PG HTTP/scheduler/background/UDP quiescence ввыделеннойпроверочнойБД, успешныйAPIrestore/ошибкапроцесса/sequence, затемdeploymentпроверенногообраза. Локальныйкоммитбезpush.
## 12.5.12 — ожидание фоновых jobs, audit и записей RIPE (2026-10-07)
Добавлен общий process-local DatabaseBackgroundWork. Promise регистрируется до запуска отложенного тела; drain ждёт settlement всех задач, включая дочерние записи, которые регистрируются во время завершения parent task. Timeout30сек отменяет database operation; pending registry сохраняется для следующего drain. Rejection наблюдается отдельно и не ломает ожидание остальных задач; завершение drain не объявляет неуспешные записи успешными.
+11 -1
View File
@@ -1,6 +1,6 @@
# Этап 12: итоговая приёмка UX/UI
Актуальное продолжение 2026-10-07:12.5.12 завершён локально — учтены detached backup jobs/audit, выпуск сертификатов, poll partition maintenance иbackground cache work; RIPE admission закрывается перед drain.19lifecycle/database tests,HTTP/JWT,backup/RIPE,10certificate tests иbuild passed. Основной runtime673e5ba не обновлён. Следующий12.5.13 — integrated HTTP/scheduler/background/UDP quiescence ввыделеннойБД, cache invalidation послеrestore иdeployment; PG-6/PG-3/4 ещёоткрыты.
Актуальное продолжение 2026-10-07:12.5.13 завершён локально в части cache invalidation после подтверждённогоrestore. Проверен порядокbackground drain→restore→cache reset→consumer restart;22lifecycle/database tests,HTTP/JWT,RIPE/ifindex/classify иbuild passed. Runtime673e5ba не обновлён. Следующий12.5.14 — integrated real-PG quiescence/restore ввыделеннойБД иdeployment; PG-6/PG-3/4 ещёоткрыты.
План: [ux-ui-plan.md](ux-ui-plan.md). Фактические результаты: [ux-ui-progress.md](ux-ui-progress.md). Подготовлен после сводных проверок 11Б; завершение каждого блока требует локального коммита без push.
@@ -1066,3 +1066,13 @@ RIPE учитывает loadPg, resolver worker иотдельные persist/per
Проверки: test:system-database19pure/protocol tests иHTTP/JWT scripts passed (4background,4HTTPgate,4shutdown,4restore,3operation). Новый integration fixture среальнымbackup handler подтвердилHTTP202 иdrain, которыйне завершается доотложеннойcreate task. RIPE test сотключённымpersist иподменённымfetch подтвердил0fetch во времяpause ивозобновлениепослеresume. Существующийbackups-operations HTTP test passed;10certificate execution tests passed; contracts/backend build послеокончательныхизменений passed; diff-check passed. Тесты неочищалиБД инеприменялиRouterOS config.
Код пока неразвёрнут, основнойruntime673e5ba сохраняется; данные/CHR/auth стенданеизменялись. PG-6 остаётсяоткрытым доинтегрированногонаблюдения всехпутей. Restore ещёнепроверен; отдельнотребуется cache invalidation послевосстановления, иначеmemory topology/RIPE/settings могут отражатьпредыдущуюБД. Другиеэкземпляры/хосты registry негарантируетостанавливать. Следующий12.5.13 — integrated HTTP/scheduler/background/UDP quiescence ввыделеннойпроверочнойБД, аудитcache invalidation/deployment, затемPG-3/4. Локальныйкоммитбезpush.
## 12.5.13 — сброс кэшей после подтверждённого восстановления БД (2026-10-07)
Добавлен invalidateSystemDatabaseCaches, вызываемый послеуспешногоpg_restore внутриrestore execution, доcleanup иперезапускаconsumers. Очищаются settingsRowCache, server/topology catalog, RIPE/index/ASN cache, интерфейсы, classification catalog, analytics/map hops, engine pending/recent/rings/minute accumulators иfact/engine ensured partition sets. Последнее исключаетповторноеиспользованиепамяткиосозданныхразделах, которыхуже можетнебытьввосстановленнойБД. Engine data epoch обновлён, runtime pending cap сохранён. GeoIP readers/file state не изменены: MMDB лежатвнеPostgreSQL dump.
Production invalidate/reset функции отделеныотForTests API; старыеимена сохраненыдлясуществующихтестов. RIPE invalidation сохраняетdatabase pause/enqueue/persist/fetch options: очисткакэшейне открывает admission воперации. Inflight tasks должныбытьпредварительнодренированы механизмами12.5.8–12; приошибкеpg_restore invalidation неприменяется.
Проверки: полныйtest:system-database21tests иHTTP/JWT scripts passed, затемновыйсовместныйcache/drain testpassed (всего22различныхtests). ПровереныудалениестарыхRIPE/interface/live данных безоткрытияRIPE, успешныйrestore→invalidate иотсутствиеinvalidate приошибкепроцесса. Совместныйfixtureснастоящимиoperation/restore helpers иbackground registry доказалпорядокstop listener→background drain→restore→invalidate→restart listener/scheduler; restart увиделочищенныйinterfacecache. Командаpg_restore вэтомfixture подмененаDI, это не реальныйPG-3. RIPE/ifindex/classify regression scripts иcontracts/backend build прошли; diff-check passed. БД/RouterOS влокальныхтестахнеизменялись.
Коднеразвёрнут: основнойruntime673e5ba сохраняется. PG-6 целикомоткрыт, чтение/rollback реальногоAPIrestore ещёнеподтверждено. PostgreSQL dump не содержитGeoIP/backup/certificate files; ихдоступностьнужноучитыватьвприёмке. Другиепроцессы/хосты gate/registry неостанавливает. Следующий12.5.14 — integrated real-PG HTTP/scheduler/background/UDP quiescence ввыделеннойпроверочнойБД, успешныйAPIrestore/ошибкапроцесса/sequence, затемdeploymentпроверенногообраза. Локальныйкоммитбезpush.
+4
View File
@@ -93,3 +93,7 @@ ssh -N -L 3000:127.0.0.1:3000 -L 8000:127.0.0.1:8000 [email protected]
## Локальный detached work drain — 2026-10-07
12.5.12 добавляетучётbackground backup/audit/certificate/partition maintenance/cache work иpause RIPE enqueue сdrain текущихresolver/writes.19lifecycle/database tests,HTTP/JWT,backup/RIPE,10certificate tests иbuild прошли. На стенднеразвёрнуто; source673e5ba сохраняется. Следующий12.5.13 — integrated quiescence иcache invalidation передrestore/deployment. PG-6/3/4 остаютсяоткрытыми.
## Локальный cache invalidation patch — 2026-10-07
12.5.13 сбрасываетDB-зависимыеNetFlow caches/live buffers/partition memo послеуспешногоrestore доconsumer restart, сохраняяRIPE pause.22различныхlifecycle/database tests,HTTP/JWT,RIPE/ifindex/classify иbuild прошли. Runtime673e5ba не обновлён; следующий12.5.14 — integrated real-PG quiescence/restore ввыделеннойБД иdeployment. PG-6/3/4 остаютсяоткрытыми. Dump не включаетвнешниеbackup/certificate/MMDB files.