Common Issues
SQLite Troubleshooting
Solutions for SQLite-specific issues with FraiseQL.
Connection Issues
Section titled “Connection Issues”Database File Not Found
Section titled “Database File Not Found”Problem: Error: cannot open database file
Cause: Database file path incorrect or doesn’t exist
Solutions:
# 1. Check file existsls -la /path/to/fraiseql.db
# 2. Verify DATABASE_URL formatecho $DATABASE_URL# Should be: sqlite:///path/to/fraiseql.db (3 slashes)# Or: sqlite:///:memory: (in-memory, for testing)
# 3. Create database if missingtouch /path/to/fraiseql.db
# 4. Check file permissionschmod 666 /path/to/fraiseql.db
# 5. Check directory permissionschmod 755 $(dirname /path/to/fraiseql.db)Database is Locked
Section titled “Database is Locked”Problem: Error: database is locked
Cause: Concurrent access or lock timeout
Solutions:
# 1. Find what's locking databaselsof /path/to/fraiseql.db
# 2. Increase lock timeoutDATABASE_URL="sqlite:////path/to/fraiseql.db?timeout=20"
# 3. Restart applicationdocker-compose restart fraiseql
# 4. Check for corrupted lock filels -la /path/to/fraiseql.db*# Delete .db-journal if exists (carefully)rm -f /path/to/fraiseql.db-journal
# 5. Enable WAL mode for better concurrencysqlite3 /path/to/fraiseql.db "PRAGMA journal_mode=WAL;"Disk I/O Error
Section titled “Disk I/O Error”Problem: Error: disk I/O error
Cause: Disk problem, permission issue, or file system issue
Solutions:
# 1. Check disk spacedf -h
# 2. Check file permissionsls -la /path/to/fraiseql.db
# 3. Run disk checksudo fsck /dev/sda1
# 4. Repair corrupted databasesqlite3 /path/to/fraiseql.db ".recover" | sqlite3 /tmp/recovered.db
# 5. Verify database integritysqlite3 /path/to/fraiseql.db "PRAGMA integrity_check;"
# 6. Check temp directory spacedf -h /tmpOut of Memory
Section titled “Out of Memory”Problem: Error: out of memory
Solutions:
# 1. Check available memoryfree -hdocker stats fraiseql
# 2. Limit query results-- Instead of: SELECT * FROM large_table-- Use: SELECT * FROM large_table LIMIT 1000
# 3. Reduce page cachesqlite3 /path/to/fraiseql.db "PRAGMA cache_size = 1000;"Query Issues
Section titled “Query Issues”Slow Queries
Section titled “Slow Queries”Problem: p95 latency > 500ms
Solutions:
# 1. Analyze query plansqlite3 /path/to/fraiseql.db "EXPLAIN QUERY PLAN SELECT * FROM posts WHERE user_id = 1;"
# 2. Create index if missingsqlite3 /path/to/fraiseql.db "CREATE INDEX idx_posts_user_id ON posts(user_id);"
# 3. Update statisticssqlite3 /path/to/fraiseql.db "ANALYZE;"
# 4. Reindex if corruptedsqlite3 /path/to/fraiseql.db "REINDEX;"Full Table Scan
Section titled “Full Table Scan”Problem: “SCAN TABLE posts” in query plan
Solutions:
# 1. Add index on WHERE columnsqlite3 /path/to/fraiseql.db "CREATE INDEX idx_posts_user_id ON posts(user_id);"
# 2. Analyze tablesqlite3 /path/to/fraiseql.db "ANALYZE posts;"
# 3. Check query plansqlite3 /path/to/fraiseql.db "EXPLAIN QUERY PLAN SELECT * FROM posts WHERE user_id = 1;"
# 4. Force index use if neededSELECT * FROM posts INDEXED BY idx_posts_user_id WHERE user_id = 1;Data Issues
Section titled “Data Issues”Foreign Key Constraint Violation
Section titled “Foreign Key Constraint Violation”Problem: Error: FOREIGN KEY constraint failed
Solutions:
# 1. Enable foreign keys (default is disabled!)sqlite3 /path/to/fraiseql.db "PRAGMA foreign_keys = ON;"
# 2. Check if enabledsqlite3 /path/to/fraiseql.db "PRAGMA foreign_keys;"
# 3. Check foreign key definitionssqlite3 /path/to/fraiseql.db ".schema posts"
# 4. Verify referenced records existsqlite3 /path/to/fraiseql.db "SELECT * FROM posts WHERE id = 123;"
# 5. Find orphaned recordssqlite3 /path/to/fraiseql.db "SELECT c.* FROM comments cLEFT JOIN posts p ON c.post_id = p.idWHERE p.id IS NULL;"
# 6. Delete orphaned recordssqlite3 /path/to/fraiseql.db "DELETE FROM commentsWHERE post_id NOT IN (SELECT id FROM posts);"
# 7. For FraiseQL, enable in app initializationconn.execute("PRAGMA foreign_keys = ON")CASCADE Delete Not Working
Section titled “CASCADE Delete Not Working”Problem: Deleting parent doesn’t delete children
Solutions:
# 1. Check table definitionsqlite3 /path/to/fraiseql.db ".schema comments"# Should show: REFERENCES posts(id) ON DELETE CASCADE
# 2. Enable foreign keyssqlite3 /path/to/fraiseql.db "PRAGMA foreign_keys = ON;"
# 3. Recreate table with correct CASCADEsqlite3 /path/to/fraiseql.db "-- Backup dataCREATE TABLE comments_backup AS SELECT * FROM comments;
-- Drop old tableDROP TABLE comments;
-- Recreate with CASCADECREATE TABLE comments ( id INTEGER PRIMARY KEY, post_id INTEGER NOT NULL REFERENCES posts(id) ON DELETE CASCADE, text TEXT);
-- Restore dataINSERT INTO comments SELECT * FROM comments_backup;
-- CleanupDROP TABLE comments_backup;"
# 4. Test CASCADEsqlite3 /path/to/fraiseql.db "BEGIN TRANSACTION;DELETE FROM posts WHERE id = 1;-- Check if comments deletedSELECT COUNT(*) FROM comments WHERE post_id = 1;ROLLBACK;"Duplicate Key Error
Section titled “Duplicate Key Error”Problem: Error: UNIQUE constraint failed
Solutions:
# 1. Check unique constraintssqlite3 /path/to/fraiseql.db "PRAGMA index_list(users);"
# 2. Find duplicate valuessqlite3 /path/to/fraiseql.db "SELECT email, COUNT(*) as cnt FROM usersGROUP BY email HAVING cnt > 1;"
# 3. Remove duplicates (keep one)sqlite3 /path/to/fraiseql.db "DELETE FROM users WHERE rowid NOT IN ( SELECT MIN(rowid) FROM users GROUP BY email);"
# 4. Add unique constraintsqlite3 /path/to/fraiseql.db "CREATE UNIQUE INDEX idx_users_email ON users(email);"NULL in NOT NULL Column
Section titled “NULL in NOT NULL Column”Problem: Error: NOT NULL constraint failed
Solutions:
# 1. Check column definitionsqlite3 /path/to/fraiseql.db ".schema posts"
# 2. Find NULL valuessqlite3 /path/to/fraiseql.db "SELECT * FROM posts WHERE title IS NULL;"
# 3. Fix NULL valuessqlite3 /path/to/fraiseql.db "UPDATE posts SET title = 'Untitled' WHERE title IS NULL;"
# Note: SQLite doesn't allow adding NOT NULL to an existing column that has NULLs# Solution: Migrate the table carefullyTransaction Issues
Section titled “Transaction Issues”Transaction Deadlock
Section titled “Transaction Deadlock”Problem: Error: database is locked or timeouts
Cause: Concurrent writers (SQLite limitation)
Solutions:
# 1. Increase timeoutDATABASE_URL="sqlite:////path/to/fraiseql.db?timeout=30"
# 2. Enable WAL mode (better concurrency)sqlite3 /path/to/fraiseql.db "PRAGMA journal_mode=WAL;"
# 3. Minimize transaction scope-- BAD: Long transactionBEGIN;SELECT COUNT(*) FROM posts;-- Long operationUPDATE posts SET title = 'New';COMMIT;
-- GOOD: Short transactionBEGIN;UPDATE posts SET title = 'New' WHERE id = 1;COMMIT;-- Long operation outside transactionIndex Issues
Section titled “Index Issues”Unused Indexes
Section titled “Unused Indexes”Problem: Taking space without improving performance
Solutions:
# 1. List all indexessqlite3 /path/to/fraiseql.db ".indices"
# 2. SQLite doesn't track index usage statistics# Manually review and remove indexes that are not needed
# 3. Drop unused indexsqlite3 /path/to/fraiseql.db "DROP INDEX idx_old_index;"
# 4. Check database sizels -lh /path/to/fraiseql.dbIndex Corruption
Section titled “Index Corruption”Problem: Query crashes or returns wrong results
Solutions:
# 1. Verify database integritysqlite3 /path/to/fraiseql.db "PRAGMA integrity_check;"
# 2. Reindex allsqlite3 /path/to/fraiseql.db "REINDEX;"
# 3. Drop and recreate specific indexsqlite3 /path/to/fraiseql.db "DROP INDEX idx_posts_user_id;CREATE INDEX idx_posts_user_id ON posts(user_id);"
# 4. Vacuum to compact databasesqlite3 /path/to/fraiseql.db "VACUUM;"Maintenance
Section titled “Maintenance”Database File Growth
Section titled “Database File Growth”Problem: Database file keeps growing
Solutions:
# 1. Check current sizels -lh /path/to/fraiseql.db
# 2. Vacuum to reclaim spacesqlite3 /path/to/fraiseql.db "VACUUM;"
# 3. Archive old datasqlite3 /path/to/fraiseql.db "DELETE FROM audit_logs WHERE created_at < datetime('now', '-1 year');"
# 4. Check free pagessqlite3 /path/to/fraiseql.db "PRAGMA freelist_count;"
# 5. Enable incremental vacuum (WAL mode)sqlite3 /path/to/fraiseql.db "PRAGMA journal_mode=WAL;"sqlite3 /path/to/fraiseql.db "PRAGMA incremental_vacuum(1000);"Backup Strategy
Section titled “Backup Strategy”Solutions:
# 1. Simple file copy (if app not running)cp /path/to/fraiseql.db /backups/fraiseql-$(date +%Y%m%d).db
# 2. SQL dump (works while running)sqlite3 /path/to/fraiseql.db ".dump" > backup.sql
# 3. Backup with WAL filescp /path/to/fraiseql.db* /backups/
# 4. Restore from SQL dumpsqlite3 /path/to/new.db < backup.sql
# 5. Restore from file copycp /backups/fraiseql-20240115.db /path/to/fraiseql.dbPerformance Tuning
Section titled “Performance Tuning”Journal Mode
Section titled “Journal Mode”Problem: Slow writes or frequent locking
Solutions:
# 1. Check current journal modesqlite3 /path/to/fraiseql.db "PRAGMA journal_mode;"
# 2. Switch to WAL (Write-Ahead Logging)sqlite3 /path/to/fraiseql.db "PRAGMA journal_mode=WAL;"# Better for concurrent reads/writes
# 3. Synchronous modesqlite3 /path/to/fraiseql.db "PRAGMA synchronous=NORMAL;"# Default: FULL (safest)# NORMAL: Good balance# OFF: Fastest but riskyCache Size
Section titled “Cache Size”Problem: High I/O or memory pressure
Solutions:
# 1. Check current cache sizesqlite3 /path/to/fraiseql.db "PRAGMA cache_size;"
# 2. Increase cache (negative value = MB)sqlite3 /path/to/fraiseql.db "PRAGMA cache_size = -10000;" # 10MB cache
# 3. For embedded usesqlite3 /path/to/fraiseql.db "PRAGMA cache_size = 1000;" # 1MB cacheWhen to Migrate from SQLite
Section titled “When to Migrate from SQLite”SQLite is ideal for development but has production limitations:
Migrate to PostgreSQL or MySQL if:
- Multiple writers (SQLite allows one writer at a time)
- High concurrency (more than 100 concurrent users)
- Data size exceeds 10GB
- Replication or failover is required
- Production deployment is required
Keep SQLite if:
- Single application instance
- Low to moderate load
- Development or testing environment
- Embedded or mobile applications
- Data is less than 1GB
Diagnostic Queries
Section titled “Diagnostic Queries”Run PRAGMA integrity_check; to verify database integrity:
sqlite> PRAGMA integrity_check;okok confirms the database has no corruption. Any other output indicates an issue.
-- Database integrityPRAGMA integrity_check;
-- Foreign keys enabled?PRAGMA foreign_keys;
-- Journal modePRAGMA journal_mode;
-- Cache infoPRAGMA cache_size;
-- Table infoPRAGMA table_info(posts);
-- Index infoPRAGMA index_info(idx_posts_user_id);
-- Database sizePRAGMA page_count;PRAGMA page_size;
-- Free spacePRAGMA freelist_count;