import { BaseSchema } from '@adonisjs/lucid/schema' /** * What inspection learns about a file (content type, archive listing) lives * in file_details, on the NVMe, instead of in `files` (LOG.md 2026-10-08 (14)). * `files` sits on the HDD and was updated after its insert by every probe: * a new row version on a random page and an entry in each of its indexes * (3.7M updates against 49.5M inserts in a day, 27% HOT). Its rows are now * only inserted (and moved between releases or renamed, rarely). * The existing values are copied by `files:move-details` after this deploy; * a later migration drops the columns. */ export default class extends BaseSchema { async up() { // The foreign key locks `files` briefly: take the lock first, so it can't deadlock with writers. await this.db.rawQuery(`SET LOCAL lock_timeout = '60s'`) await this.db.rawQuery(`LOCK TABLE files IN SHARE ROW EXCLUSIVE MODE`) await this.db.rawQuery(` CREATE TABLE IF NOT EXISTS file_details ( file_id bigint PRIMARY KEY REFERENCES files (id) ON DELETE CASCADE, content_type varchar(16), archive jsonb)`) } async down() { await this.db.rawQuery(`DROP TABLE IF EXISTS file_details`) } }