2026-04-29 10:01:32 +00:00
|
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
|
|
return [
|
|
|
|
|
|
/*
|
|
|
|
|
|
|--------------------------------------------------------------------------
|
|
|
|
|
|
| Backup Settings
|
|
|
|
|
|
|--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
feat: backup hardening + verify, stats overview, queue health
Backups:
- restore --fresh wipes a dirty/partial schema (same mysql client + $cfg as the
import, scoped to DATABASE(), so it can't wipe the wrong DB) after a verified
pre-restore safety snapshot; unmissable recovery message on post-wipe failure
- workkit:db:verify (+ --verify on backup): decrypt + xz integrity + completion
marker + sha256 sidecar check, no DB needed
- metadata sidecar per backup; prune --keep-min floor so prune can't leave zero
- FK_CHECKS=0 import prepend; deadlock-proof concurrent stdout/stderr drain
Ops:
- workkit:stats: per-model row counts (estimate/--exact), largest tables, DB size,
queue + backup summary; MySQL/MariaDB info_schema, graceful elsewhere
- workkit:queue:health: per-queue depth/due/delayed/reserved + oldest-due age,
failed-job counts, STALLED detection, DB-error breach, non-zero exit for cron
README + CHANGELOG; new config read with code-side defaults (nested-merge safe).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 10:39:03 +00:00
|
|
|
|
| Used by workkit:db:backup, workkit:db:restore, workkit:db:verify and
|
2026-04-29 10:01:32 +00:00
|
|
|
|
| workkit:db:prune-backups. The default `path` is storage_path('backups')
|
|
|
|
|
|
| so backups live alongside the rest of the app's storage. `retention_days`
|
|
|
|
|
|
| is the threshold workkit:db:prune-backups uses by default — anything
|
feat: backup hardening + verify, stats overview, queue health
Backups:
- restore --fresh wipes a dirty/partial schema (same mysql client + $cfg as the
import, scoped to DATABASE(), so it can't wipe the wrong DB) after a verified
pre-restore safety snapshot; unmissable recovery message on post-wipe failure
- workkit:db:verify (+ --verify on backup): decrypt + xz integrity + completion
marker + sha256 sidecar check, no DB needed
- metadata sidecar per backup; prune --keep-min floor so prune can't leave zero
- FK_CHECKS=0 import prepend; deadlock-proof concurrent stdout/stderr drain
Ops:
- workkit:stats: per-model row counts (estimate/--exact), largest tables, DB size,
queue + backup summary; MySQL/MariaDB info_schema, graceful elsewhere
- workkit:queue:health: per-queue depth/due/delayed/reserved + oldest-due age,
failed-job counts, STALLED detection, DB-error breach, non-zero exit for cron
README + CHANGELOG; new config read with code-side defaults (nested-merge safe).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 10:39:03 +00:00
|
|
|
|
| older than that gets deleted on the next prune run, EXCEPT the
|
|
|
|
|
|
| `retention_min_keep` newest, which are kept regardless of age so prune
|
|
|
|
|
|
| can never leave you with zero recovery points.
|
|
|
|
|
|
|
|
|
|
|
|
|
| NOTE: every command reads these nested keys with an explicit code-side
|
|
|
|
|
|
| default (e.g. config('workkit.backup.retention_min_keep', 5)) because
|
|
|
|
|
|
| mergeConfigFrom does not deep-merge nested arrays — a consumer who
|
|
|
|
|
|
| published an older config without a new key still gets a sane value.
|
2026-04-29 10:01:32 +00:00
|
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
'backup' => [
|
|
|
|
|
|
'path' => env('WORKKIT_BACKUP_PATH'), // null → storage_path('backups')
|
|
|
|
|
|
'retention_days' => (int) env('WORKKIT_BACKUP_RETENTION_DAYS', 30),
|
feat: backup hardening + verify, stats overview, queue health
Backups:
- restore --fresh wipes a dirty/partial schema (same mysql client + $cfg as the
import, scoped to DATABASE(), so it can't wipe the wrong DB) after a verified
pre-restore safety snapshot; unmissable recovery message on post-wipe failure
- workkit:db:verify (+ --verify on backup): decrypt + xz integrity + completion
marker + sha256 sidecar check, no DB needed
- metadata sidecar per backup; prune --keep-min floor so prune can't leave zero
- FK_CHECKS=0 import prepend; deadlock-proof concurrent stdout/stderr drain
Ops:
- workkit:stats: per-model row counts (estimate/--exact), largest tables, DB size,
queue + backup summary; MySQL/MariaDB info_schema, graceful elsewhere
- workkit:queue:health: per-queue depth/due/delayed/reserved + oldest-due age,
failed-job counts, STALLED detection, DB-error breach, non-zero exit for cron
README + CHANGELOG; new config read with code-side defaults (nested-merge safe).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 10:39:03 +00:00
|
|
|
|
// Always keep at least this many newest backups regardless of age.
|
|
|
|
|
|
// 0 disables the floor (prune may then leave zero backups).
|
|
|
|
|
|
'retention_min_keep' => (int) env('WORKKIT_BACKUP_RETENTION_MIN_KEEP', 5),
|
2026-04-29 12:26:17 +00:00
|
|
|
|
// xz compression level. Lower = faster + larger output. 3 is a
|
|
|
|
|
|
// good default for SQL dumps (~10× ratio at ~3× the speed of -9).
|
|
|
|
|
|
'xz_level' => (int) env('WORKKIT_BACKUP_XZ_LEVEL', 3),
|
2026-04-29 10:01:32 +00:00
|
|
|
|
],
|
feat: backup hardening + verify, stats overview, queue health
Backups:
- restore --fresh wipes a dirty/partial schema (same mysql client + $cfg as the
import, scoped to DATABASE(), so it can't wipe the wrong DB) after a verified
pre-restore safety snapshot; unmissable recovery message on post-wipe failure
- workkit:db:verify (+ --verify on backup): decrypt + xz integrity + completion
marker + sha256 sidecar check, no DB needed
- metadata sidecar per backup; prune --keep-min floor so prune can't leave zero
- FK_CHECKS=0 import prepend; deadlock-proof concurrent stdout/stderr drain
Ops:
- workkit:stats: per-model row counts (estimate/--exact), largest tables, DB size,
queue + backup summary; MySQL/MariaDB info_schema, graceful elsewhere
- workkit:queue:health: per-queue depth/due/delayed/reserved + oldest-due age,
failed-job counts, STALLED detection, DB-error breach, non-zero exit for cron
README + CHANGELOG; new config read with code-side defaults (nested-merge safe).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 10:39:03 +00:00
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|--------------------------------------------------------------------------
|
|
|
|
|
|
| Stats overview (workkit:stats)
|
|
|
|
|
|
|--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
| `models` is an explicit list of Eloquent model FQCNs to count. When null
|
|
|
|
|
|
| the command auto-discovers models by scanning `models_path` (default:
|
|
|
|
|
|
| app_path('Models')). Set an explicit list to avoid scanning, or to count
|
|
|
|
|
|
| models that live outside app/Models.
|
|
|
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
'stats' => [
|
|
|
|
|
|
'models' => null, // e.g. [\App\Models\User::class, \App\Models\Order::class]
|
|
|
|
|
|
'models_path' => null, // null → app_path('Models')
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|--------------------------------------------------------------------------
|
|
|
|
|
|
| Queue health thresholds (workkit:queue:health)
|
|
|
|
|
|
|--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
| The command exits non-zero when any of these is breached. `max_depth`
|
|
|
|
|
|
| applies per queue; `max_depth_per_queue` overrides it for named queues
|
|
|
|
|
|
| (e.g. an intentionally-slow, rate-limited queue allowed a deeper backlog).
|
|
|
|
|
|
| A queue is flagged STALLED when its oldest *due* job is older than
|
|
|
|
|
|
| `max_age_minutes` while nothing is reserved (worker likely down).
|
|
|
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
'queue' => [
|
|
|
|
|
|
'max_depth' => (int) env('WORKKIT_QUEUE_MAX_DEPTH', 250),
|
|
|
|
|
|
'max_depth_per_queue' => [], // e.g. ['geoip' => 5000]
|
|
|
|
|
|
'max_age_minutes' => (int) env('WORKKIT_QUEUE_MAX_AGE_MINUTES', 15),
|
|
|
|
|
|
'max_failed' => (int) env('WORKKIT_QUEUE_MAX_FAILED', 25),
|
|
|
|
|
|
],
|
2026-04-29 10:01:32 +00:00
|
|
|
|
];
|