{"record":{"id":"c3982ca1e2af76eb","repo":"benbjohnson/litestream","slug":"vacuum-w","errorCode":null,"errorMessage":"vacuum: %w","messagePattern":"vacuum: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/litestream-test/shrink.go","lineNumber":122,"sourceCode":"\t\t\"size_mb\", sizeAfterDelete/1024/1024,\n\t\t\"change_mb\", (initialSize-sizeAfterDelete)/1024/1024,\n\t)\n\n\tif c.Checkpoint {\n\t\tif err := c.runCheckpoint(db); err != nil {\n\t\t\treturn fmt.Errorf(\"checkpoint: %w\", err)\n\t\t}\n\n\t\tsizeAfterCheckpoint, _ := getDatabaseSize(c.DB)\n\t\tslog.Info(\"Size after checkpoint\",\n\t\t\t\"size_mb\", sizeAfterCheckpoint/1024/1024,\n\t\t\t\"change_from_delete_mb\", (sizeAfterDelete-sizeAfterCheckpoint)/1024/1024,\n\t\t)\n\t}\n\n\tif c.Vacuum {\n\t\tif err := c.runVacuum(db); err != nil {\n\t\t\treturn fmt.Errorf(\"vacuum: %w\", err)\n\t\t}\n\n\t\tsizeAfterVacuum, _ := getDatabaseSize(c.DB)\n\t\tslog.Info(\"Size after VACUUM\",\n\t\t\t\"size_mb\", sizeAfterVacuum/1024/1024,\n\t\t\t\"total_reduction_mb\", (initialSize-sizeAfterVacuum)/1024/1024,\n\t\t)\n\t}\n\n\tfinalSize, err := getDatabaseSize(c.DB)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"get final size: %w\", err)\n\t}\n\n\treductionPercent := float64(initialSize-finalSize) / float64(initialSize) * 100\n\tslog.Info(\"Shrink operation complete\",\n\t\t\"initial_size_mb\", initialSize/1024/1024,\n\t\t\"final_size_mb\", finalSize/1024/1024,","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/cmd/litestream-test/shrink.go#L104-L140","documentation":"When -vacuum is passed, shrinkDatabase runs c.runVacuum(db), executing a full `VACUUM` statement; any failure is wrapped as `vacuum: %w`. VACUUM rebuilds the entire database file to reclaim space, so it needs free disk space roughly equal to the database size plus an exclusive-ish lock for the duration. Failures typically mean insufficient disk space, a locked database, or I/O errors.","triggerScenarios":"VACUUM on a large database with insufficient free disk space for the temporary rebuild; another connection holding a write transaction or active read preventing VACUUM's exclusive access; the connection being inside a transaction (VACUUM cannot run within one); disk quota exceeded.","commonSituations":"Shrinking multi-GB test databases on small CI runners or containers with tight disk quotas; running while the app is live; WAL journal mode leftovers interfering on some setups.","solutions":["Free up disk space at least equal to the current database size before running with -vacuum","Stop other processes using the database during VACUUM","Retry the command; VACUUM is atomic — a failed attempt leaves the original file intact","Check the wrapped inner error: SQLITE_FULL means disk space, SQLITE_BUSY means locking"],"exampleFix":"// before\ndf -h /tmp   # 1GB free, database is 4GB\nlitestream-test shrink -db /tmp/big.db -vacuum\n// after\ndf -h /tmp   # ensure > database size free\nlitestream-test shrink -db /tmp/big.db -vacuum","handlingStrategy":"fallback","validationCode":"info, err := os.Stat(dbPath)\nif err == nil {\n    if free, ferr := diskFree(filepath.Dir(dbPath)); ferr == nil && free < 2*info.Size() {\n        return fmt.Errorf(\"insufficient disk space for VACUUM: need ~%d, have %d\", info.Size(), free)\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := runShrink(args); err != nil {\n    if strings.Contains(err.Error(), \"vacuum\") {\n        if strings.Contains(err.Error(), \"database or disk is full\") {\n            log.Printf(\"free disk space and retry: %v\", err)\n        } else if strings.Contains(err.Error(), \"locked\") {\n            log.Printf(\"stop other connections and retry: %v\", err)\n        }\n    }\n    return err\n}","preventionTips":["Ensure free disk space at least equal to the database size before using -vacuum","Run VACUUM only when no other connections are using the database","Drop -vacuum first when debugging failures — deletions and checkpoint still succeed without it"],"tags":["sqlite","vacuum","disk-space","locking"],"backgroundTag":"database-write-failed","analyzedSha":"4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3","analyzedAt":"2026-09-06T18:29:25.564Z","contentChangedAt":"2026-09-06T18:29:25.564Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}