| name | database-operations |
| description | Perform Drupal database operations including backups, restores, queries, and migrations. Use for database maintenance, troubleshooting, and data operations. |
| allowed-tools | Bash, Read, Grep |
Database Operations Skill
This skill guides database operations for Drupal sites using PostgreSQL or MySQL/MariaDB.
Important Notes
- Supported Databases: PostgreSQL and MySQL/MariaDB
- Primary Tool: Drush (
./vendor/bin/drush) for database-agnostic operations
- Config Location:
sites/default/settings.php or settings.local.php
Detecting Your Database Type
./vendor/bin/drush status --fields=db-driver
grep "'driver'" sites/default/settings.php
Backup Operations
Using Drush (Database-Agnostic)
./vendor/bin/drush sql:dump > backup.sql
./vendor/bin/drush sql:dump --gzip > backup-$(date +%Y%m%d-%H%M%S).sql.gz
./vendor/bin/drush sql:dump --tables-list=node,node_field_data > partial-backup.sql
./vendor/bin/drush sql:dump --skip-tables-list=cache_default,cache_render,cache_page,cache_discovery > backup-no-cache.sql
PostgreSQL Native Dump
pg_dump -h localhost -U drupal_user drupal_db > backup.sql
pg_dump -h localhost -U drupal_user -Fc drupal_db > backup.dump
pg_dump -h localhost -U drupal_user -Fd drupal_db -j 4 -f backup_dir/
MySQL Native Dump
mysqldump -h localhost -u drupal_user -p drupal_db > backup.sql
mysqldump -h localhost -u drupal_user -p --single-transaction drupal_db > backup.sql
mysqldump -h localhost -u drupal_user -p --single-transaction drupal_db | gzip > backup.sql.gz
Restore Operations
Using Drush (Database-Agnostic)
./vendor/bin/drush sql:cli < backup.sql
gunzip -c backup.sql.gz | ./vendor/bin/drush sql:cli
./vendor/bin/drush sql:drop -y
./vendor/bin/drush sql:cli < backup.sql
PostgreSQL Native Restore
psql -h localhost -U drupal_user drupal_db < backup.sql
pg_restore -h localhost -U drupal_user -d drupal_db backup.dump
pg_restore -h localhost -U drupal_user -d drupal_db --clean --if-exists backup.dump
MySQL Native Restore
mysql -h localhost -u drupal_user -p drupal_db < backup.sql
gunzip -c backup.sql.gz | mysql -h localhost -u drupal_user -p drupal_db
Drush Database Commands
Cache and Updates
./vendor/bin/drush cr
./vendor/bin/drush updb -y
./vendor/bin/drush status
Configuration
./vendor/bin/drush cex -y
./vendor/bin/drush cim -y
Features (Module Config)
./vendor/bin/drush fr <module> -y
Database Queries
Via Drush
./vendor/bin/drush sql:query "SELECT COUNT(*) FROM node"
./vendor/bin/drush sql:cli
Common Queries (Database-Agnostic)
SELECT type, COUNT(*) FROM node GROUP BY type;
SELECT nid, title FROM node_field_data ORDER BY changed DESC LIMIT 10;
SELECT uid, name, mail FROM users_field_data WHERE status = 1 LIMIT 10;
SELECT n.type, COUNT(*) AS total
FROM node n
JOIN node_field_data nfd ON n.nid = nfd.nid
WHERE nfd.status = 1
GROUP BY n.type
ORDER BY total DESC;
PostgreSQL-Specific Queries
SELECT pg_size_pretty(pg_database_size(current_database()));
SELECT relname, pg_size_pretty(pg_total_relation_size(relid))
FROM pg_catalog.pg_statio_user_tables
ORDER BY pg_total_relation_size(relid) DESC
LIMIT 20;
SELECT count(*) FROM pg_stat_activity WHERE state = 'active';
SELECT pid, age(clock_timestamp(), query_start), usename, query
FROM pg_stat_activity
WHERE state != 'idle'
ORDER BY query_start;
SELECT indexrelname, idx_scan, idx_tup_read
FROM pg_stat_user_indexes
ORDER BY idx_scan DESC;
SELECT indexrelname, idx_scan
FROM pg_stat_user_indexes
WHERE idx_scan = 0;
MySQL-Specific Queries
SELECT table_schema AS db,
ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS 'Size (MB)'
FROM information_schema.tables
WHERE table_schema = DATABASE()
GROUP BY table_schema;
SELECT table_name,
ROUND(((data_length + index_length) / 1024 / 1024), 2) AS 'Size (MB)',
table_rows
FROM information_schema.tables
WHERE table_schema = DATABASE()
ORDER BY (data_length + index_length) DESC
LIMIT 20;
SHOW PROCESSLIST;
SELECT * FROM information_schema.processlist
WHERE command != 'Sleep'
ORDER BY time DESC;
SELECT * FROM sys.schema_unused_indexes
WHERE object_schema = DATABASE();
Maintenance Tasks
Rebuild Cache Tables
./vendor/bin/drush cr
Update Entity Schema
./vendor/bin/drush updb -y
./vendor/bin/drush entup
Clear Specific Caches
./vendor/bin/drush cache:rebuild
./vendor/bin/drush cache:clear render
./vendor/bin/drush cache:clear menu
Database Maintenance
./vendor/bin/drush sql:query "VACUUM ANALYZE"
./vendor/bin/drush sql:query "OPTIMIZE TABLE cache_default, cache_render, cache_page"
Truncate Large Tables
./vendor/bin/drush watchdog:delete all -y
./vendor/bin/drush sql:query "TRUNCATE TABLE cache_default RESTART IDENTITY"
./vendor/bin/drush sql:query "TRUNCATE TABLE cache_default"
Migration Operations
Check Migrations
./vendor/bin/drush ms
./vendor/bin/drush migrate:status
Run Migrations
./vendor/bin/drush mim <migration_id>
./vendor/bin/drush mr <migration_id>
./vendor/bin/drush mrs <migration_id>
Best Practices
- Always backup before changes:
./vendor/bin/drush sql:dump --gzip > backup.sql.gz
- Test restores in non-production: Verify backups are usable
- Use transactions for bulk operations: Wrap manual SQL in BEGIN/COMMIT
- Monitor database size: Check growth trends regularly
- Run maintenance during low traffic: Schedule VACUUM/OPTIMIZE off-peak
- Document any manual queries: Keep a record of ad-hoc changes
- Use Drush for portability: Prefer
drush sql:* commands over native tools for database-agnostic operations
Troubleshooting
Connection Issues
./vendor/bin/drush status database
systemctl status postgresql
systemctl status mysql
systemctl status mariadb
View Recent Errors
./vendor/bin/drush ws --count=50 --severity=error
Lock Issues
SELECT blocked_locks.pid AS blocked_pid,
blocking_locks.pid AS blocking_pid,
blocked_activity.query AS blocked_statement
FROM pg_catalog.pg_locks blocked_locks
JOIN pg_catalog.pg_stat_activity blocked_activity ON blocked_activity.pid = blocked_locks.pid
JOIN pg_catalog.pg_locks blocking_locks ON blocking_locks.locktype = blocked_locks.locktype
WHERE NOT blocked_locks.granted;
SHOW OPEN TABLES WHERE In_use > 0;
SELECT * FROM information_schema.innodb_trx;
Repair/Recovery
./vendor/bin/drush sql:query "REINDEX DATABASE current_database"
./vendor/bin/drush sql:query "CHECK TABLE node_field_data"
./vendor/bin/drush sql:query "REPAIR TABLE cache_default"