feat(db): перевести хранилище с SQLite на PostgreSQL
Docker images / prepare-release (push) Successful in 12s
Docker images / backend-test (push) Successful in 4m9s
Docker images / frontend-image (push) Successful in 4m28s
Docker images / updater-image (push) Successful in 58s
Docker images / backend-image (push) Successful in 2m49s
Docker images / notify-webhook (push) Skipped
Docker images / publish-release (push) Successful in 11s
Docker images / prepare-release (push) Successful in 12s
Docker images / backend-test (push) Successful in 4m9s
Docker images / frontend-image (push) Successful in 4m28s
Docker images / updater-image (push) Successful in 58s
Docker images / backend-image (push) Successful in 2m49s
Docker images / notify-webhook (push) Skipped
Docker images / publish-release (push) Successful in 11s
При старте backend накатывает схему PostgreSQL 18 и, если база пустая, один раз импортирует mikrotik.db с тома. Повторный старт не копирует данные. Бэкап в UI идёт через pg_dump. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
import Database from "better-sqlite3"
|
||||
import fs from "node:fs"
|
||||
|
||||
const path = process.argv[2] ?? "./mikrotik.db"
|
||||
if (!fs.existsSync(path)) {
|
||||
console.error("NO_SQLITE", path)
|
||||
process.exit(2)
|
||||
}
|
||||
const st = fs.statSync(path)
|
||||
const db = new Database(path, { readonly: true, fileMustExist: true })
|
||||
const tables = db
|
||||
.prepare(`SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY 1`)
|
||||
.all()
|
||||
console.log("FILE_BYTES", st.size)
|
||||
console.log("TABLES", tables.length)
|
||||
for (const t of tables) {
|
||||
const c = db.prepare(`SELECT COUNT(*) AS c FROM "${t.name}"`).get()
|
||||
console.log(`COUNT\t${t.name}\t${c.c}`)
|
||||
}
|
||||
try {
|
||||
const d = db.prepare(`SELECT COUNT(*) AS c FROM (
|
||||
SELECT dedupe_key FROM alert_outbox GROUP BY dedupe_key HAVING COUNT(*) > 1
|
||||
)`).get()
|
||||
console.log("DUP_DEDUPE_KEYS", d.c)
|
||||
} catch (e) {
|
||||
console.log("DUP_DEDUPE_ERR", e instanceof Error ? e.message : e)
|
||||
}
|
||||
for (const [label, sql] of [
|
||||
["ORPHAN_FLOW_MINUTE", `SELECT COUNT(*) c FROM flow_minute_stats s WHERE s.server_id NOT IN (SELECT id FROM servers)`],
|
||||
["ORPHAN_FLOW_BUCKETS", `SELECT COUNT(*) c FROM flow_buckets s WHERE s.server_id NOT IN (SELECT id FROM servers)`],
|
||||
["ORPHAN_BINDINGS", `SELECT COUNT(*) c FROM user_interface_bindings s WHERE s.server_id NOT IN (SELECT id FROM servers)`],
|
||||
]) {
|
||||
try {
|
||||
console.log(label, db.prepare(sql).get().c)
|
||||
} catch (e) {
|
||||
console.log(label + "_ERR", e instanceof Error ? e.message : e)
|
||||
}
|
||||
}
|
||||
db.close()
|
||||
Reference in New Issue
Block a user