specweave 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/INSTALL.md +848 -0
- package/LICENSE +21 -0
- package/README.md +675 -0
- package/SPECWEAVE.md +665 -0
- package/bin/install-agents.sh +57 -0
- package/bin/install-all.sh +49 -0
- package/bin/install-commands.sh +56 -0
- package/bin/install-skills.sh +57 -0
- package/bin/specweave.js +81 -0
- package/dist/adapters/adapter-base.d.ts +50 -0
- package/dist/adapters/adapter-base.d.ts.map +1 -0
- package/dist/adapters/adapter-base.js +146 -0
- package/dist/adapters/adapter-base.js.map +1 -0
- package/dist/adapters/adapter-interface.d.ts +108 -0
- package/dist/adapters/adapter-interface.d.ts.map +1 -0
- package/dist/adapters/adapter-interface.js +9 -0
- package/dist/adapters/adapter-interface.js.map +1 -0
- package/dist/adapters/claude/adapter.d.ts +54 -0
- package/dist/adapters/claude/adapter.d.ts.map +1 -0
- package/dist/adapters/claude/adapter.js +184 -0
- package/dist/adapters/claude/adapter.js.map +1 -0
- package/dist/adapters/copilot/adapter.d.ts +42 -0
- package/dist/adapters/copilot/adapter.d.ts.map +1 -0
- package/dist/adapters/copilot/adapter.js +239 -0
- package/dist/adapters/copilot/adapter.js.map +1 -0
- package/dist/adapters/cursor/adapter.d.ts +42 -0
- package/dist/adapters/cursor/adapter.d.ts.map +1 -0
- package/dist/adapters/cursor/adapter.js +297 -0
- package/dist/adapters/cursor/adapter.js.map +1 -0
- package/dist/adapters/generic/adapter.d.ts +40 -0
- package/dist/adapters/generic/adapter.d.ts.map +1 -0
- package/dist/adapters/generic/adapter.js +155 -0
- package/dist/adapters/generic/adapter.js.map +1 -0
- package/dist/cli/commands/init.d.ts +6 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +247 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/install.d.ts +7 -0
- package/dist/cli/commands/install.d.ts.map +1 -0
- package/dist/cli/commands/install.js +160 -0
- package/dist/cli/commands/install.js.map +1 -0
- package/dist/cli/commands/list.d.ts +6 -0
- package/dist/cli/commands/list.d.ts.map +1 -0
- package/dist/cli/commands/list.js +154 -0
- package/dist/cli/commands/list.js.map +1 -0
- package/package.json +90 -0
- package/src/adapters/README.md +312 -0
- package/src/adapters/adapter-base.ts +146 -0
- package/src/adapters/adapter-interface.ts +120 -0
- package/src/adapters/claude/README.md +241 -0
- package/src/adapters/claude/adapter.ts +157 -0
- package/src/adapters/copilot/.github/copilot/instructions.md +376 -0
- package/src/adapters/copilot/README.md +200 -0
- package/src/adapters/copilot/adapter.ts +210 -0
- package/src/adapters/cursor/.cursor/context/docs-context.md +62 -0
- package/src/adapters/cursor/.cursor/context/increments-context.md +71 -0
- package/src/adapters/cursor/.cursor/context/strategy-context.md +73 -0
- package/src/adapters/cursor/.cursor/context/tests-context.md +89 -0
- package/src/adapters/cursor/.cursorrules +325 -0
- package/src/adapters/cursor/README.md +243 -0
- package/src/adapters/cursor/adapter.ts +268 -0
- package/src/adapters/generic/README.md +277 -0
- package/src/adapters/generic/SPECWEAVE-MANUAL.md +676 -0
- package/src/adapters/generic/adapter.ts +159 -0
- package/src/adapters/registry.yaml +126 -0
- package/src/agents/architect/AGENT.md +416 -0
- package/src/agents/devops/AGENT.md +1738 -0
- package/src/agents/docs-writer/AGENT.md +239 -0
- package/src/agents/performance/AGENT.md +228 -0
- package/src/agents/pm/AGENT.md +751 -0
- package/src/agents/qa-lead/AGENT.md +150 -0
- package/src/agents/security/AGENT.md +179 -0
- package/src/agents/sre/AGENT.md +582 -0
- package/src/agents/sre/modules/backend-diagnostics.md +481 -0
- package/src/agents/sre/modules/database-diagnostics.md +509 -0
- package/src/agents/sre/modules/infrastructure.md +561 -0
- package/src/agents/sre/modules/monitoring.md +439 -0
- package/src/agents/sre/modules/security-incidents.md +421 -0
- package/src/agents/sre/modules/ui-diagnostics.md +302 -0
- package/src/agents/sre/playbooks/01-high-cpu-usage.md +204 -0
- package/src/agents/sre/playbooks/02-database-deadlock.md +241 -0
- package/src/agents/sre/playbooks/03-memory-leak.md +252 -0
- package/src/agents/sre/playbooks/04-slow-api-response.md +269 -0
- package/src/agents/sre/playbooks/05-ddos-attack.md +293 -0
- package/src/agents/sre/playbooks/06-disk-full.md +314 -0
- package/src/agents/sre/playbooks/07-service-down.md +333 -0
- package/src/agents/sre/playbooks/08-data-corruption.md +337 -0
- package/src/agents/sre/playbooks/09-cascade-failure.md +430 -0
- package/src/agents/sre/playbooks/10-rate-limit-exceeded.md +464 -0
- package/src/agents/sre/scripts/health-check.sh +230 -0
- package/src/agents/sre/scripts/log-analyzer.py +213 -0
- package/src/agents/sre/scripts/metrics-collector.sh +294 -0
- package/src/agents/sre/scripts/trace-analyzer.js +257 -0
- package/src/agents/sre/templates/incident-report.md +249 -0
- package/src/agents/sre/templates/mitigation-plan.md +375 -0
- package/src/agents/sre/templates/post-mortem.md +418 -0
- package/src/agents/sre/templates/runbook-template.md +412 -0
- package/src/agents/tech-lead/AGENT.md +263 -0
- package/src/commands/add-tasks.md +176 -0
- package/src/commands/close-increment.md +347 -0
- package/src/commands/create-increment.md +223 -0
- package/src/commands/create-project.md +528 -0
- package/src/commands/generate-docs.md +623 -0
- package/src/commands/list-increments.md +180 -0
- package/src/commands/review-docs.md +331 -0
- package/src/commands/start-increment.md +139 -0
- package/src/commands/sync-github.md +115 -0
- package/src/commands/validate-increment.md +800 -0
- package/src/hooks/README.md +252 -0
- package/src/hooks/docs-changed.sh +59 -0
- package/src/hooks/human-input-required.sh +55 -0
- package/src/hooks/post-task-completion.sh +57 -0
- package/src/hooks/pre-implementation.sh +47 -0
- package/src/skills/ado-sync/README.md +449 -0
- package/src/skills/ado-sync/SKILL.md +245 -0
- package/src/skills/ado-sync/test-cases/test-1.yaml +9 -0
- package/src/skills/ado-sync/test-cases/test-2.yaml +8 -0
- package/src/skills/ado-sync/test-cases/test-3.yaml +9 -0
- package/src/skills/bmad-method-expert/SKILL.md +628 -0
- package/src/skills/bmad-method-expert/scripts/analyze-project.js +318 -0
- package/src/skills/bmad-method-expert/scripts/check-setup.js +208 -0
- package/src/skills/bmad-method-expert/scripts/generate-template.js +1149 -0
- package/src/skills/bmad-method-expert/scripts/validate-documents.js +340 -0
- package/src/skills/bmad-method-expert/test-cases/test-1-placeholder.yaml +12 -0
- package/src/skills/bmad-method-expert/test-cases/test-2-placeholder.yaml +12 -0
- package/src/skills/bmad-method-expert/test-cases/test-3-placeholder.yaml +12 -0
- package/src/skills/brownfield-analyzer/SKILL.md +523 -0
- package/src/skills/brownfield-analyzer/test-cases/test-1-basic-analysis.yaml +48 -0
- package/src/skills/brownfield-analyzer/test-cases/test-2-placeholder.yaml +12 -0
- package/src/skills/brownfield-analyzer/test-cases/test-3-placeholder.yaml +12 -0
- package/src/skills/brownfield-onboarder/SKILL.md +625 -0
- package/src/skills/brownfield-onboarder/test-cases/test-1-placeholder.yaml +12 -0
- package/src/skills/brownfield-onboarder/test-cases/test-2-placeholder.yaml +12 -0
- package/src/skills/brownfield-onboarder/test-cases/test-3-placeholder.yaml +12 -0
- package/src/skills/calendar-system/test-cases/test-1-placeholder.yaml +12 -0
- package/src/skills/calendar-system/test-cases/test-2-placeholder.yaml +12 -0
- package/src/skills/calendar-system/test-cases/test-3-placeholder.yaml +12 -0
- package/src/skills/context-loader/SKILL.md +734 -0
- package/src/skills/context-loader/test-cases/test-1-basic-loading.yaml +39 -0
- package/src/skills/context-loader/test-cases/test-2-token-budget-exceeded.yaml +44 -0
- package/src/skills/context-loader/test-cases/test-3-section-anchors.yaml +45 -0
- package/src/skills/context-optimizer/SKILL.md +618 -0
- package/src/skills/context-optimizer/test-cases/test-1-bug-fix-narrow.yaml +97 -0
- package/src/skills/context-optimizer/test-cases/test-2-feature-focused.yaml +109 -0
- package/src/skills/context-optimizer/test-cases/test-3-architecture-broad.yaml +98 -0
- package/src/skills/cost-optimizer/SKILL.md +190 -0
- package/src/skills/cost-optimizer/test-cases/test-1-basic-comparison.yaml +75 -0
- package/src/skills/cost-optimizer/test-cases/test-2-budget-constraint.yaml +52 -0
- package/src/skills/cost-optimizer/test-cases/test-3-scale-requirement.yaml +63 -0
- package/src/skills/cost-optimizer/test-results/README.md +46 -0
- package/src/skills/design-system-architect/SKILL.md +107 -0
- package/src/skills/design-system-architect/test-cases/test-1-token-structure.yaml +23 -0
- package/src/skills/design-system-architect/test-cases/test-2-component-hierarchy.yaml +24 -0
- package/src/skills/design-system-architect/test-cases/test-3-accessibility-checklist.yaml +23 -0
- package/src/skills/diagrams-architect/SKILL.md +763 -0
- package/src/skills/diagrams-generator/SKILL.md +25 -0
- package/src/skills/diagrams-generator/test-cases/test-1.yaml +9 -0
- package/src/skills/diagrams-generator/test-cases/test-2.yaml +9 -0
- package/src/skills/diagrams-generator/test-cases/test-3.yaml +8 -0
- package/src/skills/docs-updater/README.md +48 -0
- package/src/skills/docs-updater/test-cases/test-1-placeholder.yaml +12 -0
- package/src/skills/docs-updater/test-cases/test-2-placeholder.yaml +12 -0
- package/src/skills/docs-updater/test-cases/test-3-placeholder.yaml +12 -0
- package/src/skills/dotnet-backend/SKILL.md +250 -0
- package/src/skills/e2e-playwright/README.md +506 -0
- package/src/skills/e2e-playwright/SKILL.md +457 -0
- package/src/skills/e2e-playwright/execute.js +373 -0
- package/src/skills/e2e-playwright/lib/utils.js +514 -0
- package/src/skills/e2e-playwright/package.json +33 -0
- package/src/skills/e2e-playwright/test-cases/TC-001-basic-navigation.yaml +54 -0
- package/src/skills/e2e-playwright/test-cases/TC-002-form-interaction.yaml +64 -0
- package/src/skills/e2e-playwright/test-cases/TC-003-specweave-integration.yaml +74 -0
- package/src/skills/e2e-playwright/test-cases/TC-004-accessibility-check.yaml +98 -0
- package/src/skills/figma-designer/SKILL.md +149 -0
- package/src/skills/figma-implementer/SKILL.md +148 -0
- package/src/skills/figma-mcp-connector/SKILL.md +136 -0
- package/src/skills/figma-mcp-connector/test-cases/test-1-read-file-desktop.yaml +22 -0
- package/src/skills/figma-mcp-connector/test-cases/test-2-read-file-framelink.yaml +21 -0
- package/src/skills/figma-mcp-connector/test-cases/test-3-error-handling.yaml +18 -0
- package/src/skills/figma-to-code/SKILL.md +128 -0
- package/src/skills/figma-to-code/test-cases/test-1-token-generation.yaml +29 -0
- package/src/skills/figma-to-code/test-cases/test-2-component-generation.yaml +27 -0
- package/src/skills/figma-to-code/test-cases/test-3-typescript-generation.yaml +28 -0
- package/src/skills/frontend/SKILL.md +177 -0
- package/src/skills/github-sync/SKILL.md +252 -0
- package/src/skills/github-sync/test-cases/test-1-placeholder.yaml +12 -0
- package/src/skills/github-sync/test-cases/test-2-placeholder.yaml +12 -0
- package/src/skills/github-sync/test-cases/test-3-placeholder.yaml +12 -0
- package/src/skills/hetzner-provisioner/README.md +308 -0
- package/src/skills/hetzner-provisioner/SKILL.md +251 -0
- package/src/skills/hetzner-provisioner/test-cases/test-1-basic-provision.yaml +71 -0
- package/src/skills/hetzner-provisioner/test-cases/test-2-postgres-provision.yaml +85 -0
- package/src/skills/hetzner-provisioner/test-cases/test-3-ssl-config.yaml +126 -0
- package/src/skills/hetzner-provisioner/test-results/README.md +259 -0
- package/src/skills/increment-planner/SKILL.md +889 -0
- package/src/skills/increment-planner/scripts/feature-utils.js +250 -0
- package/src/skills/increment-planner/test-cases/test-1-basic-feature.yaml +27 -0
- package/src/skills/increment-planner/test-cases/test-2-complex-feature.yaml +30 -0
- package/src/skills/increment-planner/test-cases/test-3-auto-numbering.yaml +24 -0
- package/src/skills/increment-quality-judge/SKILL.md +566 -0
- package/src/skills/increment-quality-judge/test-cases/test-1-good-spec.yaml +95 -0
- package/src/skills/increment-quality-judge/test-cases/test-2-poor-spec.yaml +108 -0
- package/src/skills/increment-quality-judge/test-cases/test-3-export-suggestions.yaml +87 -0
- package/src/skills/jira-sync/README.md +328 -0
- package/src/skills/jira-sync/SKILL.md +209 -0
- package/src/skills/jira-sync/test-cases/test-1.yaml +9 -0
- package/src/skills/jira-sync/test-cases/test-2.yaml +9 -0
- package/src/skills/jira-sync/test-cases/test-3.yaml +10 -0
- package/src/skills/nextjs/SKILL.md +176 -0
- package/src/skills/nodejs-backend/SKILL.md +181 -0
- package/src/skills/notification-system/test-cases/test-1-placeholder.yaml +12 -0
- package/src/skills/notification-system/test-cases/test-2-placeholder.yaml +12 -0
- package/src/skills/notification-system/test-cases/test-3-placeholder.yaml +12 -0
- package/src/skills/python-backend/SKILL.md +226 -0
- package/src/skills/role-orchestrator/README.md +197 -0
- package/src/skills/role-orchestrator/SKILL.md +1184 -0
- package/src/skills/role-orchestrator/test-cases/test-1-simple-product.yaml +98 -0
- package/src/skills/role-orchestrator/test-cases/test-2-quality-gate-failure.yaml +73 -0
- package/src/skills/role-orchestrator/test-cases/test-3-security-workflow.yaml +121 -0
- package/src/skills/role-orchestrator/test-cases/test-4-parallel-execution.yaml +145 -0
- package/src/skills/role-orchestrator/test-cases/test-5-feedback-loops.yaml +149 -0
- package/src/skills/skill-creator/LICENSE.txt +202 -0
- package/src/skills/skill-creator/SKILL.md +209 -0
- package/src/skills/skill-creator/scripts/init_skill.py +303 -0
- package/src/skills/skill-creator/scripts/package_skill.py +110 -0
- package/src/skills/skill-creator/scripts/quick_validate.py +65 -0
- package/src/skills/skill-creator/test-cases/test-1-placeholder.yaml +12 -0
- package/src/skills/skill-creator/test-cases/test-2-placeholder.yaml +12 -0
- package/src/skills/skill-creator/test-cases/test-3-placeholder.yaml +12 -0
- package/src/skills/skill-router/SKILL.md +497 -0
- package/src/skills/skill-router/test-cases/test-1-basic-routing.yaml +33 -0
- package/src/skills/skill-router/test-cases/test-2-ambiguous-request.yaml +42 -0
- package/src/skills/skill-router/test-cases/test-3-nested-orchestration.yaml +50 -0
- package/src/skills/spec-driven-brainstorming/README.md +264 -0
- package/src/skills/spec-driven-brainstorming/SKILL.md +439 -0
- package/src/skills/spec-driven-brainstorming/test-cases/TC-001-simple-idea-to-design.yaml +148 -0
- package/src/skills/spec-driven-brainstorming/test-cases/TC-002-complex-ultrathink-design.yaml +190 -0
- package/src/skills/spec-driven-brainstorming/test-cases/TC-003-unclear-requirements-socratic.yaml +233 -0
- package/src/skills/spec-driven-debugging/README.md +479 -0
- package/src/skills/spec-driven-debugging/SKILL.md +652 -0
- package/src/skills/spec-driven-debugging/test-cases/TC-001-simple-auth-bug.yaml +212 -0
- package/src/skills/spec-driven-debugging/test-cases/TC-002-race-condition-ultrathink.yaml +461 -0
- package/src/skills/spec-driven-debugging/test-cases/TC-003-brownfield-missing-spec.yaml +366 -0
- package/src/skills/spec-kit-expert/SKILL.md +1012 -0
- package/src/skills/spec-kit-expert/test-cases/test-1-placeholder.yaml +12 -0
- package/src/skills/spec-kit-expert/test-cases/test-2-placeholder.yaml +12 -0
- package/src/skills/spec-kit-expert/test-cases/test-3-placeholder.yaml +12 -0
- package/src/skills/specweave-ado-mapper/SKILL.md +501 -0
- package/src/skills/specweave-detector/SKILL.md +420 -0
- package/src/skills/specweave-detector/test-cases/test-1-basic-detection.yaml +37 -0
- package/src/skills/specweave-detector/test-cases/test-2-missing-config.yaml +37 -0
- package/src/skills/specweave-detector/test-cases/test-3-non-specweave-project.yaml +34 -0
- package/src/skills/specweave-jira-mapper/SKILL.md +500 -0
- package/src/skills/stripe-integrator/test-cases/test-1-placeholder.yaml +12 -0
- package/src/skills/stripe-integrator/test-cases/test-2-placeholder.yaml +12 -0
- package/src/skills/stripe-integrator/test-cases/test-3-placeholder.yaml +12 -0
- package/src/skills/task-builder/README.md +90 -0
- package/src/skills/task-builder/test-cases/test-1-placeholder.yaml +12 -0
- package/src/skills/task-builder/test-cases/test-2-placeholder.yaml +12 -0
- package/src/skills/task-builder/test-cases/test-3-placeholder.yaml +12 -0
- package/src/templates/.env.example +144 -0
- package/src/templates/.gitignore.template +81 -0
- package/src/templates/CLAUDE.md.template +383 -0
- package/src/templates/README.md.template +240 -0
- package/src/templates/config.yaml +333 -0
- package/src/templates/docs/README.md +124 -0
- package/src/templates/docs/adr-template.md +118 -0
- package/src/templates/docs/hld-template.md +220 -0
- package/src/templates/docs/lld-template.md +580 -0
- package/src/templates/docs/prd-template.md +132 -0
- package/src/templates/docs/rfc-template.md +229 -0
- package/src/templates/docs/runbook-template.md +298 -0
- package/src/templates/environments/minimal/.env.production +16 -0
- package/src/templates/environments/minimal/README.md +54 -0
- package/src/templates/environments/minimal/deploy-production.yml +52 -0
- package/src/templates/environments/progressive/.env.qa +28 -0
- package/src/templates/environments/progressive/README.md +129 -0
- package/src/templates/environments/progressive/deploy-production.yml +93 -0
- package/src/templates/environments/progressive/deploy-qa.yml +62 -0
- package/src/templates/environments/progressive/deploy-staging.yml +67 -0
- package/src/templates/environments/standard/.env.development +20 -0
- package/src/templates/environments/standard/.env.production +30 -0
- package/src/templates/environments/standard/.env.staging +23 -0
- package/src/templates/environments/standard/README.md +97 -0
- package/src/templates/environments/standard/deploy-production.yml +68 -0
- package/src/templates/environments/standard/deploy-staging.yml +61 -0
- package/src/templates/environments/standard/docker-compose.yml +43 -0
- package/src/templates/increment-metadata-template.yaml +138 -0
|
@@ -0,0 +1,509 @@
|
|
|
1
|
+
# Database Diagnostics
|
|
2
|
+
|
|
3
|
+
**Purpose**: Troubleshoot database performance, slow queries, deadlocks, and connection issues.
|
|
4
|
+
|
|
5
|
+
## Common Database Issues
|
|
6
|
+
|
|
7
|
+
### 1. Slow Query
|
|
8
|
+
|
|
9
|
+
**Symptoms**:
|
|
10
|
+
- API response time high
|
|
11
|
+
- Specific endpoint slow
|
|
12
|
+
- Database CPU high
|
|
13
|
+
|
|
14
|
+
**Diagnosis**:
|
|
15
|
+
|
|
16
|
+
#### Enable Slow Query Log (PostgreSQL)
|
|
17
|
+
```sql
|
|
18
|
+
-- Set slow query threshold (1 second)
|
|
19
|
+
ALTER SYSTEM SET log_min_duration_statement = 1000;
|
|
20
|
+
SELECT pg_reload_conf();
|
|
21
|
+
|
|
22
|
+
-- Check slow query log
|
|
23
|
+
-- /var/log/postgresql/postgresql.log
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
#### Enable Slow Query Log (MySQL)
|
|
27
|
+
```sql
|
|
28
|
+
-- Enable slow query log
|
|
29
|
+
SET GLOBAL slow_query_log = 'ON';
|
|
30
|
+
SET GLOBAL long_query_time = 1;
|
|
31
|
+
|
|
32
|
+
-- Check slow query log
|
|
33
|
+
-- /var/log/mysql/mysql-slow.log
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
#### Analyze Query with EXPLAIN
|
|
39
|
+
```sql
|
|
40
|
+
-- PostgreSQL
|
|
41
|
+
EXPLAIN ANALYZE
|
|
42
|
+
SELECT users.*, posts.*
|
|
43
|
+
FROM users
|
|
44
|
+
LEFT JOIN posts ON posts.user_id = users.id
|
|
45
|
+
WHERE users.last_login_at > NOW() - INTERVAL '30 days';
|
|
46
|
+
|
|
47
|
+
-- Look for:
|
|
48
|
+
-- - Seq Scan (sequential scan = BAD for large tables)
|
|
49
|
+
-- - High cost numbers
|
|
50
|
+
-- - High actual time
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**Red flags in EXPLAIN output**:
|
|
54
|
+
- **Seq Scan** on large table (>10k rows) → Missing index
|
|
55
|
+
- **Nested Loop** with large outer table → Missing index
|
|
56
|
+
- **Hash Join** with large tables → Consider index
|
|
57
|
+
- **Actual time** >> **Planned time** → Statistics outdated
|
|
58
|
+
|
|
59
|
+
**Example Bad Query**:
|
|
60
|
+
```
|
|
61
|
+
Seq Scan on users (cost=0.00..100000 rows=10000000)
|
|
62
|
+
Filter: (last_login_at > '2025-09-26'::date)
|
|
63
|
+
Rows Removed by Filter: 9900000
|
|
64
|
+
```
|
|
65
|
+
→ **Missing index on last_login_at**
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
#### Check Missing Indexes
|
|
70
|
+
```sql
|
|
71
|
+
-- PostgreSQL: Find missing indexes
|
|
72
|
+
SELECT
|
|
73
|
+
schemaname,
|
|
74
|
+
tablename,
|
|
75
|
+
seq_scan,
|
|
76
|
+
seq_tup_read,
|
|
77
|
+
idx_scan,
|
|
78
|
+
seq_tup_read / seq_scan AS avg_seq_read
|
|
79
|
+
FROM pg_stat_user_tables
|
|
80
|
+
WHERE seq_scan > 0
|
|
81
|
+
ORDER BY seq_tup_read DESC
|
|
82
|
+
LIMIT 20;
|
|
83
|
+
|
|
84
|
+
-- Tables with high seq_scan and low idx_scan need indexes
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
#### Create Index
|
|
90
|
+
```sql
|
|
91
|
+
-- PostgreSQL (CONCURRENTLY = no table lock)
|
|
92
|
+
CREATE INDEX CONCURRENTLY idx_users_last_login_at
|
|
93
|
+
ON users(last_login_at);
|
|
94
|
+
|
|
95
|
+
-- Verify index is used
|
|
96
|
+
EXPLAIN ANALYZE
|
|
97
|
+
SELECT * FROM users WHERE last_login_at > NOW() - INTERVAL '30 days';
|
|
98
|
+
-- Should show: Index Scan using idx_users_last_login_at
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**Impact**:
|
|
102
|
+
- Before: 7.8 seconds (Seq Scan)
|
|
103
|
+
- After: 50ms (Index Scan)
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
### 2. Database Deadlock
|
|
108
|
+
|
|
109
|
+
**Symptoms**:
|
|
110
|
+
- "Deadlock detected" errors
|
|
111
|
+
- Transactions timing out
|
|
112
|
+
- API 500 errors
|
|
113
|
+
|
|
114
|
+
**Diagnosis**:
|
|
115
|
+
|
|
116
|
+
#### Check for Deadlocks (PostgreSQL)
|
|
117
|
+
```sql
|
|
118
|
+
-- Check currently locked queries
|
|
119
|
+
SELECT
|
|
120
|
+
blocked_locks.pid AS blocked_pid,
|
|
121
|
+
blocked_activity.usename AS blocked_user,
|
|
122
|
+
blocking_locks.pid AS blocking_pid,
|
|
123
|
+
blocking_activity.usename AS blocking_user,
|
|
124
|
+
blocked_activity.query AS blocked_statement,
|
|
125
|
+
blocking_activity.query AS blocking_statement
|
|
126
|
+
FROM pg_catalog.pg_locks blocked_locks
|
|
127
|
+
JOIN pg_catalog.pg_stat_activity blocked_activity ON blocked_activity.pid = blocked_locks.pid
|
|
128
|
+
JOIN pg_catalog.pg_locks blocking_locks
|
|
129
|
+
ON blocking_locks.locktype = blocked_locks.locktype
|
|
130
|
+
AND blocking_locks.database IS NOT DISTINCT FROM blocked_locks.database
|
|
131
|
+
AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation
|
|
132
|
+
AND blocking_locks.pid != blocked_locks.pid
|
|
133
|
+
JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid
|
|
134
|
+
WHERE NOT blocked_locks.granted;
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
#### Check for Deadlocks (MySQL)
|
|
138
|
+
```sql
|
|
139
|
+
-- Show InnoDB status (includes deadlock info)
|
|
140
|
+
SHOW ENGINE INNODB STATUS\G
|
|
141
|
+
|
|
142
|
+
-- Look for "LATEST DETECTED DEADLOCK" section
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
#### Common Deadlock Patterns
|
|
148
|
+
```sql
|
|
149
|
+
-- Pattern 1: Lock order mismatch
|
|
150
|
+
-- Transaction 1:
|
|
151
|
+
BEGIN;
|
|
152
|
+
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
|
|
153
|
+
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
|
|
154
|
+
COMMIT;
|
|
155
|
+
|
|
156
|
+
-- Transaction 2 (runs concurrently):
|
|
157
|
+
BEGIN;
|
|
158
|
+
UPDATE accounts SET balance = balance - 50 WHERE id = 2; -- Locks id=2
|
|
159
|
+
UPDATE accounts SET balance = balance + 50 WHERE id = 1; -- Waits for id=1 (deadlock!)
|
|
160
|
+
COMMIT;
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
**Fix**: Always lock in same order
|
|
164
|
+
```sql
|
|
165
|
+
-- Both transactions lock in order: id=1, then id=2
|
|
166
|
+
BEGIN;
|
|
167
|
+
UPDATE accounts SET balance = balance - 100 WHERE id = LEAST(1, 2);
|
|
168
|
+
UPDATE accounts SET balance = balance + 100 WHERE id = GREATEST(1, 2);
|
|
169
|
+
COMMIT;
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
#### Immediate Mitigation
|
|
175
|
+
```sql
|
|
176
|
+
-- PostgreSQL: Kill blocking query
|
|
177
|
+
SELECT pg_terminate_backend(<blocking_pid>);
|
|
178
|
+
|
|
179
|
+
-- PostgreSQL: Kill idle transactions
|
|
180
|
+
SELECT pg_terminate_backend(pid)
|
|
181
|
+
FROM pg_stat_activity
|
|
182
|
+
WHERE state = 'idle in transaction'
|
|
183
|
+
AND state_change < NOW() - INTERVAL '5 minutes';
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
### 3. Connection Pool Exhausted
|
|
189
|
+
|
|
190
|
+
**Symptoms**:
|
|
191
|
+
- "Too many connections" errors
|
|
192
|
+
- "Connection pool exhausted" errors
|
|
193
|
+
- New connections timing out
|
|
194
|
+
|
|
195
|
+
**Diagnosis**:
|
|
196
|
+
|
|
197
|
+
#### Check Active Connections (PostgreSQL)
|
|
198
|
+
```sql
|
|
199
|
+
-- Count connections by state
|
|
200
|
+
SELECT state, count(*)
|
|
201
|
+
FROM pg_stat_activity
|
|
202
|
+
GROUP BY state;
|
|
203
|
+
|
|
204
|
+
-- Show all connections
|
|
205
|
+
SELECT pid, usename, application_name, state, query
|
|
206
|
+
FROM pg_stat_activity
|
|
207
|
+
WHERE state != 'idle';
|
|
208
|
+
|
|
209
|
+
-- Check max connections
|
|
210
|
+
SHOW max_connections;
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
#### Check Active Connections (MySQL)
|
|
214
|
+
```sql
|
|
215
|
+
-- Show all connections
|
|
216
|
+
SHOW PROCESSLIST;
|
|
217
|
+
|
|
218
|
+
-- Count connections by state
|
|
219
|
+
SELECT state, COUNT(*)
|
|
220
|
+
FROM information_schema.processlist
|
|
221
|
+
GROUP BY state;
|
|
222
|
+
|
|
223
|
+
-- Check max connections
|
|
224
|
+
SHOW VARIABLES LIKE 'max_connections';
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
**Red flags**:
|
|
228
|
+
- Connections = max_connections
|
|
229
|
+
- Many "idle in transaction" (connections held but not used)
|
|
230
|
+
- Long-running queries holding connections
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
#### Immediate Mitigation
|
|
235
|
+
```sql
|
|
236
|
+
-- PostgreSQL: Kill idle connections
|
|
237
|
+
SELECT pg_terminate_backend(pid)
|
|
238
|
+
FROM pg_stat_activity
|
|
239
|
+
WHERE state = 'idle'
|
|
240
|
+
AND state_change < NOW() - INTERVAL '10 minutes';
|
|
241
|
+
|
|
242
|
+
-- Increase max_connections (temporary)
|
|
243
|
+
ALTER SYSTEM SET max_connections = 200;
|
|
244
|
+
SELECT pg_reload_conf();
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
**Long-term Fix**:
|
|
248
|
+
- Fix connection leaks in application code
|
|
249
|
+
- Increase connection pool size (if needed)
|
|
250
|
+
- Add connection timeout
|
|
251
|
+
- Use connection pooler (PgBouncer, ProxySQL)
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
### 4. High Database CPU
|
|
256
|
+
|
|
257
|
+
**Symptoms**:
|
|
258
|
+
- Database CPU >80%
|
|
259
|
+
- All queries slow
|
|
260
|
+
- Server overload
|
|
261
|
+
|
|
262
|
+
**Diagnosis**:
|
|
263
|
+
|
|
264
|
+
#### Find CPU-heavy Queries (PostgreSQL)
|
|
265
|
+
```sql
|
|
266
|
+
-- Top queries by total time
|
|
267
|
+
SELECT
|
|
268
|
+
query,
|
|
269
|
+
calls,
|
|
270
|
+
total_exec_time,
|
|
271
|
+
mean_exec_time,
|
|
272
|
+
max_exec_time
|
|
273
|
+
FROM pg_stat_statements
|
|
274
|
+
ORDER BY total_exec_time DESC
|
|
275
|
+
LIMIT 10;
|
|
276
|
+
|
|
277
|
+
-- Requires: CREATE EXTENSION pg_stat_statements;
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
#### Find CPU-heavy Queries (MySQL)
|
|
281
|
+
```sql
|
|
282
|
+
-- Enable performance schema
|
|
283
|
+
SET GLOBAL performance_schema = ON;
|
|
284
|
+
|
|
285
|
+
-- Top queries by execution time
|
|
286
|
+
SELECT
|
|
287
|
+
DIGEST_TEXT,
|
|
288
|
+
COUNT_STAR,
|
|
289
|
+
SUM_TIMER_WAIT,
|
|
290
|
+
AVG_TIMER_WAIT
|
|
291
|
+
FROM performance_schema.events_statements_summary_by_digest
|
|
292
|
+
ORDER BY SUM_TIMER_WAIT DESC
|
|
293
|
+
LIMIT 10;
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
**Common causes**:
|
|
297
|
+
- Missing indexes (Seq Scan)
|
|
298
|
+
- Complex queries (many JOINs)
|
|
299
|
+
- Aggregations on large tables
|
|
300
|
+
- Full table scans
|
|
301
|
+
|
|
302
|
+
**Mitigation**:
|
|
303
|
+
- Add missing indexes
|
|
304
|
+
- Optimize queries (reduce JOINs)
|
|
305
|
+
- Add query caching
|
|
306
|
+
- Scale database (read replicas)
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
### 5. Disk Full
|
|
311
|
+
|
|
312
|
+
**Symptoms**:
|
|
313
|
+
- "No space left on device" errors
|
|
314
|
+
- Database refuses writes
|
|
315
|
+
- Application crashes
|
|
316
|
+
|
|
317
|
+
**Diagnosis**:
|
|
318
|
+
|
|
319
|
+
#### Check Disk Usage
|
|
320
|
+
```bash
|
|
321
|
+
# Linux
|
|
322
|
+
df -h
|
|
323
|
+
|
|
324
|
+
# Database data directory
|
|
325
|
+
du -sh /var/lib/postgresql/data/*
|
|
326
|
+
du -sh /var/lib/mysql/*
|
|
327
|
+
|
|
328
|
+
# Find large tables
|
|
329
|
+
# PostgreSQL:
|
|
330
|
+
SELECT
|
|
331
|
+
schemaname,
|
|
332
|
+
tablename,
|
|
333
|
+
pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) AS size
|
|
334
|
+
FROM pg_tables
|
|
335
|
+
ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC
|
|
336
|
+
LIMIT 20;
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
---
|
|
340
|
+
|
|
341
|
+
#### Immediate Mitigation
|
|
342
|
+
```bash
|
|
343
|
+
# 1. Clean up logs
|
|
344
|
+
rm /var/log/postgresql/postgresql-*.log.1
|
|
345
|
+
rm /var/log/mysql/mysql-slow.log.1
|
|
346
|
+
|
|
347
|
+
# 2. Vacuum database (PostgreSQL)
|
|
348
|
+
VACUUM FULL;
|
|
349
|
+
|
|
350
|
+
# 3. Archive old data
|
|
351
|
+
# Move old records to archive table or backup
|
|
352
|
+
|
|
353
|
+
# 4. Expand disk (cloud)
|
|
354
|
+
# AWS: Modify EBS volume size
|
|
355
|
+
# Azure: Expand managed disk
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
---
|
|
359
|
+
|
|
360
|
+
### 6. Replication Lag
|
|
361
|
+
|
|
362
|
+
**Symptoms**:
|
|
363
|
+
- Stale data on read replicas
|
|
364
|
+
- Monitoring alerts for lag
|
|
365
|
+
- Eventually consistent reads
|
|
366
|
+
|
|
367
|
+
**Diagnosis**:
|
|
368
|
+
|
|
369
|
+
#### Check Replication Lag (PostgreSQL)
|
|
370
|
+
```sql
|
|
371
|
+
-- On primary:
|
|
372
|
+
SELECT * FROM pg_stat_replication;
|
|
373
|
+
|
|
374
|
+
-- On replica:
|
|
375
|
+
SELECT
|
|
376
|
+
now() - pg_last_xact_replay_timestamp() AS replication_lag;
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
#### Check Replication Lag (MySQL)
|
|
380
|
+
```sql
|
|
381
|
+
-- On replica:
|
|
382
|
+
SHOW SLAVE STATUS\G
|
|
383
|
+
|
|
384
|
+
-- Look for: Seconds_Behind_Master
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
**Red flags**:
|
|
388
|
+
- Lag >1 minute
|
|
389
|
+
- Lag increasing over time
|
|
390
|
+
|
|
391
|
+
**Common causes**:
|
|
392
|
+
- High write load on primary
|
|
393
|
+
- Replica under-provisioned
|
|
394
|
+
- Network latency
|
|
395
|
+
- Long-running query blocking replay
|
|
396
|
+
|
|
397
|
+
**Mitigation**:
|
|
398
|
+
- Scale up replica (more CPU, memory)
|
|
399
|
+
- Optimize slow queries on primary
|
|
400
|
+
- Increase network bandwidth
|
|
401
|
+
- Add more replicas (distribute read load)
|
|
402
|
+
|
|
403
|
+
---
|
|
404
|
+
|
|
405
|
+
## Database Performance Metrics
|
|
406
|
+
|
|
407
|
+
**Query Performance**:
|
|
408
|
+
- p50 query time: <10ms
|
|
409
|
+
- p95 query time: <100ms
|
|
410
|
+
- p99 query time: <500ms
|
|
411
|
+
|
|
412
|
+
**Resource Usage**:
|
|
413
|
+
- CPU: <70% average
|
|
414
|
+
- Memory: <80% of available
|
|
415
|
+
- Disk I/O: <80% of throughput
|
|
416
|
+
- Connections: <80% of max
|
|
417
|
+
|
|
418
|
+
**Availability**:
|
|
419
|
+
- Uptime: 99.99% (52.6 min downtime/year)
|
|
420
|
+
- Replication lag: <1 second
|
|
421
|
+
|
|
422
|
+
---
|
|
423
|
+
|
|
424
|
+
## Database Diagnostic Checklist
|
|
425
|
+
|
|
426
|
+
**When diagnosing slow database**:
|
|
427
|
+
|
|
428
|
+
- [ ] Check slow query log
|
|
429
|
+
- [ ] Run EXPLAIN ANALYZE on slow queries
|
|
430
|
+
- [ ] Check for missing indexes (seq_scan > idx_scan)
|
|
431
|
+
- [ ] Check for deadlocks
|
|
432
|
+
- [ ] Check connection count (target: <80% of max)
|
|
433
|
+
- [ ] Check database CPU (target: <70%)
|
|
434
|
+
- [ ] Check disk space (target: <80% used)
|
|
435
|
+
- [ ] Check replication lag (target: <1s)
|
|
436
|
+
- [ ] Check for long-running queries (>30s)
|
|
437
|
+
- [ ] Check for idle transactions (>5 min)
|
|
438
|
+
|
|
439
|
+
**Tools**:
|
|
440
|
+
- `EXPLAIN ANALYZE`
|
|
441
|
+
- `pg_stat_statements` (PostgreSQL)
|
|
442
|
+
- Performance Schema (MySQL)
|
|
443
|
+
- `pg_stat_activity` (PostgreSQL)
|
|
444
|
+
- `SHOW PROCESSLIST` (MySQL)
|
|
445
|
+
- Database monitoring (CloudWatch, DataDog)
|
|
446
|
+
|
|
447
|
+
---
|
|
448
|
+
|
|
449
|
+
## Database Anti-Patterns
|
|
450
|
+
|
|
451
|
+
### 1. N+1 Query Problem
|
|
452
|
+
```javascript
|
|
453
|
+
// BAD: N+1 queries
|
|
454
|
+
const users = await db.query('SELECT * FROM users');
|
|
455
|
+
for (const user of users) {
|
|
456
|
+
const posts = await db.query('SELECT * FROM posts WHERE user_id = ?', [user.id]);
|
|
457
|
+
}
|
|
458
|
+
// 1 query + N queries = N+1
|
|
459
|
+
|
|
460
|
+
// GOOD: Single query with JOIN
|
|
461
|
+
const usersWithPosts = await db.query(`
|
|
462
|
+
SELECT users.*, posts.*
|
|
463
|
+
FROM users
|
|
464
|
+
LEFT JOIN posts ON posts.user_id = users.id
|
|
465
|
+
`);
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
### 2. SELECT *
|
|
469
|
+
```sql
|
|
470
|
+
-- BAD: Fetches all columns (inefficient)
|
|
471
|
+
SELECT * FROM users WHERE id = 1;
|
|
472
|
+
|
|
473
|
+
-- GOOD: Fetch only needed columns
|
|
474
|
+
SELECT id, name, email FROM users WHERE id = 1;
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
### 3. Missing Indexes
|
|
478
|
+
```sql
|
|
479
|
+
-- BAD: No index on frequently queried column
|
|
480
|
+
SELECT * FROM users WHERE email = 'user@example.com';
|
|
481
|
+
-- Seq Scan on users
|
|
482
|
+
|
|
483
|
+
-- GOOD: Add index
|
|
484
|
+
CREATE INDEX idx_users_email ON users(email);
|
|
485
|
+
-- Index Scan using idx_users_email
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
### 4. Long Transactions
|
|
489
|
+
```javascript
|
|
490
|
+
// BAD: Long transaction holding locks
|
|
491
|
+
BEGIN;
|
|
492
|
+
const user = await db.query('SELECT * FROM users WHERE id = 1 FOR UPDATE');
|
|
493
|
+
await sendEmail(user.email); // External API call (slow!)
|
|
494
|
+
await db.query('UPDATE users SET last_email_sent = NOW() WHERE id = 1');
|
|
495
|
+
COMMIT;
|
|
496
|
+
|
|
497
|
+
// GOOD: Keep transactions short
|
|
498
|
+
const user = await db.query('SELECT * FROM users WHERE id = 1');
|
|
499
|
+
await sendEmail(user.email); // Outside transaction
|
|
500
|
+
await db.query('UPDATE users SET last_email_sent = NOW() WHERE id = 1');
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
---
|
|
504
|
+
|
|
505
|
+
## Related Documentation
|
|
506
|
+
|
|
507
|
+
- [SKILL.md](../SKILL.md) - Main SRE agent
|
|
508
|
+
- [backend-diagnostics.md](backend-diagnostics.md) - Backend troubleshooting
|
|
509
|
+
- [infrastructure.md](infrastructure.md) - Server/network troubleshooting
|