Truncate Check
Check ID: truncate | Severity: HIGH
What It Checks For
This check detects when TRUNCATE TABLE statements are used. These operations can cause data loss and table locks, making them risky in production environments.
Example risky SQL:
or
Why Its Risky
Using TRUNCATE TABLE in PostgreSQL has several implications:
- Data Loss:
TRUNCATEimmediately removes all rows from a table without possibility of rollback (if committed) - Locking: It acquires an ACCESS EXCLUSIVE lock on the table, blocking all concurrent access
- CASCADE Effects: With CASCADE option, it can cause unexpected data loss in related tables
- Autovacuum: Truncated tables don't need vacuuming, but may affect statistics/planning
- Transaction Visibility: Even in a transaction, other sessions may observe the truncated state due to lock acquisition
Safer Alternative
Instead of using TRUNCATE, consider these alternatives:
- Use
DELETE FROMwith aWHEREclause to remove specific data:
- For large tables, use batched deletes to reduce lock time:
-- Delete in batches of 10,000 rows
DELETE FROM audit_logs
WHERE id IN (SELECT id FROM audit_logs WHERE created_at < '2023-01-01' LIMIT 10000);
-
If you must clear an entire table, perform the operation during maintenance windows when application impact is minimized.
-
Consider creating a new empty table with the same structure and then renaming tables:
-- Create a new empty table with same structure
CREATE TABLE audit_logs_new (LIKE audit_logs INCLUDING ALL);
-- Switch tables
ALTER TABLE audit_logs RENAME TO audit_logs_old;
ALTER TABLE audit_logs_new RENAME TO audit_logs;
-- Later, when safe
DROP TABLE audit_logs_old;
Configuration Options
You can configure or disable this check in your .ddlcheck configuration file: