fix(db): индексировать историю для очистки планировщика
Docker images / prepare-release (push) Successful in 14s
Docker images / backend-test (push) Failing after 2m49s
Docker images / backend-image (push) Skipped
Docker images / frontend-image (push) Successful in 2m39s
Docker images / notify-webhook (push) Skipped
Docker images / updater-image (push) Successful in 42s
Docker images / publish-release (push) Skipped
Docker images / prepare-release (push) Successful in 14s
Docker images / backend-test (push) Failing after 2m49s
Docker images / backend-image (push) Skipped
Docker images / frontend-image (push) Successful in 2m39s
Docker images / notify-webhook (push) Skipped
Docker images / updater-image (push) Successful in 42s
Docker images / publish-release (push) Skipped
This commit is contained in:
1 parent
fda7f353ad
commit
b2cf71fcc7
7 files changed
+136
-2
No files matched your search
@@ -0,0 +1,33 @@
|
||||
import assert from "node:assert/strict"
|
||||
import { readFileSync } from "node:fs"
|
||||
import pg from "pg"
|
||||
import { env } from "../config.js"
|
||||
|
||||
// No bootstrap/migrations against public tables: this test needs only a connection.
|
||||
const pool = new pg.Pool({ connectionString: env.DATABASE_URL, connectionTimeoutMillis: 8000, statement_timeout: 10000 })
|
||||
try {
|
||||
const client = await pool.connect()
|
||||
try {
|
||||
await client.query("BEGIN")
|
||||
// Temporary shadow table: public scheduler history is never changed.
|
||||
await client.query("CREATE TEMP TABLE scheduler_runs(id integer PRIMARY KEY, finished_at timestamptz NOT NULL) ON COMMIT DROP")
|
||||
await client.query(`INSERT INTO scheduler_runs SELECT i, now() - CASE WHEN i=1 THEN interval '60 days' ELSE i * interval '1 second' END FROM generate_series(1,20000) AS i`)
|
||||
await client.query("ANALYZE scheduler_runs")
|
||||
const cutoff = new Date(Date.now() - 30 * 86400_000).toISOString()
|
||||
const plan = async () => JSON.stringify((await client.query("EXPLAIN (FORMAT JSON) SELECT id FROM scheduler_runs WHERE finished_at < $1", [cutoff])).rows)
|
||||
assert.match(await plan(), /Seq Scan/)
|
||||
const migration = readFileSync(new URL("../../drizzle/0013_scheduler_retention_index.sql", import.meta.url), "utf8")
|
||||
await client.query(migration)
|
||||
await client.query(migration)
|
||||
assert.match(await plan(), /Index Scan|Bitmap Index Scan/)
|
||||
assert.deepEqual((await client.query("SELECT id FROM scheduler_runs WHERE finished_at < $1", [cutoff])).rows, [{ id: 1 }])
|
||||
const index = (await client.query("SELECT indisvalid FROM pg_index WHERE indrelid = 'pg_temp.scheduler_runs'::regclass AND indexrelid::regclass::text LIKE '%idx_scheduler_runs_finished_at'")).rows
|
||||
assert.deepEqual(index, [{ indisvalid: true }])
|
||||
console.log("Scheduler retention: actual migration/idempotence/valid index/selective plan/result preservation passed on 20,000 temporary rows")
|
||||
} finally {
|
||||
await client.query("ROLLBACK")
|
||||
client.release()
|
||||
}
|
||||
} finally {
|
||||
await pool.end()
|
||||
}
|
||||
@@ -649,6 +649,7 @@ export const schedulerRuns = pgTable("scheduler_runs", {
|
||||
resultJson: jsonb("result_json"),
|
||||
}, (t) => [
|
||||
index("idx_scheduler_runs_job_time").on(t.jobKey, t.startedAt),
|
||||
index("idx_scheduler_runs_finished_at").on(t.finishedAt),
|
||||
])
|
||||
|
||||
export const events = pgTable("events", {
|
||||
|
||||
Reference in new issue
Block a user