Skip to content
Back to skills

2288 Sqlite Backup Restore 3397c3eb

BSecurity

SQLite databases are single files, so simple copy works when database is not being written to:

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 11, 2026
databasespythonbashsqlapidatabaseperformance

Works with

  • api

Security analysis

B88/100
  • criticalModifies startup scripts or system services for persistence

Pro shows the line behind each finding and how to fix it

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 2288-sqlite_backup_restore_3397c3eb --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 2288 Sqlite Backup Restore 3397c3eb?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 2288 Sqlite Backup Restore 3397c3eb
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-2288-sqlite-backup-restore-3397c3eb/badge)](https://www.skillsdirectory.com/skills/tools-only-2288-sqlite-backup-restore-3397c3eb)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
# SQLite Backup and Restore Guide

## Backup Methods

### File Copy (Simple)

SQLite databases are single files, so simple copy works when database is not being written to:

```bash
# Ensure no writes during copy
cp /path/to/database.db /backup/database_$(date +%Y%m%d).db
```

### sqlite3 .backup Command (Safe)

Uses SQLite's online backup API - safe during active connections:

```bash
sqlite3 /path/to/database.db ".backup '/backup/database.db'"
```

**With Compression:**
```bash
sqlite3 /path/to/database.db ".backup '/dev/stdout'" | gzip > /backup/database.db.gz
```

### sqlite3 .dump Command (SQL Export)

Exports as SQL statements - portable and inspectable:

```bash
sqlite3 /path/to/database.db .dump > /backup/database.sql

# With compression
sqlite3 /path/to/database.db .dump | gzip > /backup/database.sql.gz
```

### VACUUM INTO (SQLite 3.27+)

Creates optimized copy:

```bash
sqlite3 /path/to/database.db "VACUUM INTO '/backup/database_optimized.db'"
```

## Backup Comparison

| Method | During Writes | Portable | Size | Speed |
|--------|--------------|----------|------|-------|
| File copy | Risky | Yes | Original | Fast |
| .backup | Safe | Yes | Original | Fast |
| .dump | Safe | Very | Larger | Slower |
| VACUUM INTO | Safe | Yes | Optimized | Medium |

## Restore Methods

### From File Copy

```bash
# Stop application
systemctl stop myapp

# Replace database
cp /backup/database.db /path/to/database.db

# Fix permissions
chown app:app /path/to/database.db
chmod 644 /path/to/database.db

# Start application
systemctl start myapp
```

### From SQL Dump

```bash
# Create new database from dump
sqlite3 /path/to/database_new.db < /backup/database.sql

# From compressed
gunzip -c /backup/database.sql.gz | sqlite3 /path/to/database_new.db
```

### Selective Restore

**Single Table from Dump:**
```bash
# Extract CREATE TABLE and INSERT statements for specific table
grep -E "^(CREATE TABLE|INSERT INTO) \"?users" /backup/database.sql > users.sql
sqlite3 /path/to/database.db < users.sql
```

## Production Backup Script

```bash
#!/bin/bash
set -euo pipefail

# Configuration
DB_PATH="/var/lib/myapp/database.db"
BACKUP_DIR="/var/backups/sqlite"
RETENTION_DAYS=7
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="${BACKUP_DIR}/database_${DATE}.db"
LOG_FILE="${BACKUP_DIR}/backup.log"

mkdir -p "$BACKUP_DIR"

log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

log "Starting backup of $DB_PATH"

# Check database exists
if [ ! -f "$DB_PATH" ]; then
    log "ERROR: Database not found: $DB_PATH"
    exit 1
fi

# Check database integrity before backup
if ! sqlite3 "$DB_PATH" "PRAGMA integrity_check;" | grep -q "^ok$"; then
    log "WARNING: Database integrity check failed"
fi

# Perform backup using online backup API
if sqlite3 "$DB_PATH" ".backup '$BACKUP_FILE'" 2>> "$LOG_FILE"; then
    SIZE=$(du -h "$BACKUP_FILE" | cut -f1)
    log "Backup completed: $BACKUP_FILE ($SIZE)"

    # Verify backup
    if sqlite3 "$BACKUP_FILE" "PRAGMA integrity_check;" | grep -q "^ok$"; then
        log "Backup verification passed"
    else
        log "ERROR: Backup verification failed"
        exit 1
    fi

    # Compress backup
    gzip "$BACKUP_FILE"
    log "Compressed to: ${BACKUP_FILE}.gz"
else
    log "ERROR: Backup failed"
    exit 1
fi

# Cleanup old backups
log "Cleaning backups older than $RETENTION_DAYS days"
find "$BACKUP_DIR" -name "*.db.gz" -mtime "+$RETENTION_DAYS" -delete

log "Backup process completed"
```

## Incremental Backup Strategy

SQLite doesn't have built-in incremental backup, but you can use these strategies:

### WAL Mode Backup

```bash
# Enable WAL mode (run once)
sqlite3 /path/to/database.db "PRAGMA journal_mode=WAL;"

# Checkpoint before backup to merge WAL into main file
sqlite3 /path/to/database.db "PRAGMA wal_checkpoint(TRUNCATE);"

# Then backup
sqlite3 /path/to/database.db ".backup '/backup/database.db'"
```

### Change Tracking with Triggers

```sql
-- Create change log table
CREATE TABLE IF NOT EXISTS change_log (
    id INTEGER PRIMARY KEY,
    table_name TEXT,
    row_id INTEGER,
    action TEXT,
    changed_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

-- Create trigger for each table
CREATE TRIGGER users_changes AFTER INSERT OR UPDATE OR DELETE ON users
BEGIN
    INSERT INTO change_log (table_name, row_id, action)
    VALUES ('users', COALESCE(NEW.id, OLD.id),
            CASE WHEN NEW.id IS NULL THEN 'DELETE'
                 WHEN OLD.id IS NULL THEN 'INSERT'
                 ELSE 'UPDATE' END);
END;
```

## Performance Optimization

### Before Backup

```bash
# Optimize database
sqlite3 /path/to/database.db "VACUUM;"
sqlite3 /path/to/database.db "ANALYZE;"
```

### WAL Mode for Concurrent Access

```sql
PRAGMA journal_mode=WAL;
PRAGMA synchronous=NORMAL;
```

## Database Integrity Check

```bash
# Quick integrity check
sqlite3 /path/to/database.db "PRAGMA quick_check;"

# Full integrity check
sqlite3 /path/to/database.db "PRAGMA integrity_check;"

# Check foreign keys
sqlite3 /path/to/database.db "PRAGMA foreign_key_check;"
```

## Troubleshooting

| Issue | Solution |
|-------|----------|
| "database is locked" | Wait for transactions, use WAL mode |
| Backup too slow | Use `.backup` instead of `.dump` |
| Corrupted backup | Run integrity check on source first |
| Permission denied | Check file and directory permissions |
| Disk full | Clean old backups, check df -h |
| Large WAL file | Run `PRAGMA wal_checkpoint(TRUNCATE)` |

## Restore Verification

```bash
# After restore, verify
sqlite3 /path/to/restored.db <<EOF
PRAGMA integrity_check;
SELECT COUNT(*) FROM users;
SELECT COUNT(*) FROM orders;
.tables
EOF
```

## Python Backup Script

```python
#!/usr/bin/env python3
"""SQLite backup with verification."""
import sqlite3
import shutil
from pathlib import Path
from datetime import datetime

def backup_database(source: str, backup_dir: str) -> str:
    """Create verified backup of SQLite database."""
    source_path = Path(source)
    backup_path = Path(backup_dir) / f"{source_path.stem}_{datetime.now():%Y%m%d_%H%M%S}.db"

    # Ensure backup directory exists
    backup_path.parent.mkdir(parents=True, exist_ok=True)

    # Use SQLite backup API
    source_conn = sqlite3.connect(source)
    backup_conn = sqlite3.connect(str(backup_path))

    with backup_conn:
        source_conn.backup(backup_conn)

    source_conn.close()

    # Verify backup
    verify_conn = sqlite3.connect(str(backup_path))
    result = verify_conn.execute("PRAGMA integrity_check").fetchone()
    verify_conn.close()

    if result[0] != "ok":
        raise RuntimeError(f"Backup integrity check failed: {result}")

    return str(backup_path)

if __name__ == "__main__":
    import sys
    if len(sys.argv) != 3:
        print(f"Usage: {sys.argv[0]} <source.db> <backup_dir>")
        sys.exit(1)

    backup_file = backup_database(sys.argv[1], sys.argv[2])
    print(f"Backup created: {backup_file}")
```

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.