fix(backups): large database backups are not working (#6217)
This commit is contained in:
@@ -23,6 +23,8 @@ use Illuminate\Foundation\Bus\Dispatchable;
|
|||||||
use Illuminate\Queue\InteractsWithQueue;
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
use Illuminate\Queue\SerializesModels;
|
use Illuminate\Queue\SerializesModels;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
use Throwable;
|
||||||
|
use Visus\Cuid2\Cuid2;
|
||||||
|
|
||||||
class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue
|
class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue
|
||||||
{
|
{
|
||||||
@@ -60,9 +62,16 @@ class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue
|
|||||||
|
|
||||||
public ?S3Storage $s3 = null;
|
public ?S3Storage $s3 = null;
|
||||||
|
|
||||||
|
public $timeout = 3600;
|
||||||
|
|
||||||
|
public string $backup_log_uuid;
|
||||||
|
|
||||||
public function __construct(public ScheduledDatabaseBackup $backup)
|
public function __construct(public ScheduledDatabaseBackup $backup)
|
||||||
{
|
{
|
||||||
$this->onQueue('high');
|
$this->onQueue('high');
|
||||||
|
$this->timeout = $backup->timeout;
|
||||||
|
|
||||||
|
$this->backup_log_uuid = (string) new Cuid2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function handle(): void
|
public function handle(): void
|
||||||
@@ -219,12 +228,8 @@ class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue
|
|||||||
$this->mongo_root_username = str($rootUsername)->after('MONGO_INITDB_ROOT_USERNAME=')->value();
|
$this->mongo_root_username = str($rootUsername)->after('MONGO_INITDB_ROOT_USERNAME=')->value();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
\Log::info('MongoDB credentials extracted from environment', [
|
|
||||||
'has_username' => filled($this->mongo_root_username),
|
|
||||||
'has_password' => filled($this->mongo_root_password),
|
|
||||||
]);
|
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
\Log::warning('Failed to extract MongoDB environment variables', ['error' => $e->getMessage()]);
|
|
||||||
// Continue without env vars - will be handled in backup_standalone_mongodb method
|
// Continue without env vars - will be handled in backup_standalone_mongodb method
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -288,6 +293,7 @@ class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue
|
|||||||
}
|
}
|
||||||
$this->backup_location = $this->backup_dir.$this->backup_file;
|
$this->backup_location = $this->backup_dir.$this->backup_file;
|
||||||
$this->backup_log = ScheduledDatabaseBackupExecution::create([
|
$this->backup_log = ScheduledDatabaseBackupExecution::create([
|
||||||
|
'uuid' => $this->backup_log_uuid,
|
||||||
'database_name' => $database,
|
'database_name' => $database,
|
||||||
'filename' => $this->backup_location,
|
'filename' => $this->backup_location,
|
||||||
'scheduled_database_backup_id' => $this->backup->id,
|
'scheduled_database_backup_id' => $this->backup->id,
|
||||||
@@ -307,6 +313,7 @@ class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue
|
|||||||
$this->backup_file = "/mongo-dump-$databaseName-".Carbon::now()->timestamp.'.tar.gz';
|
$this->backup_file = "/mongo-dump-$databaseName-".Carbon::now()->timestamp.'.tar.gz';
|
||||||
$this->backup_location = $this->backup_dir.$this->backup_file;
|
$this->backup_location = $this->backup_dir.$this->backup_file;
|
||||||
$this->backup_log = ScheduledDatabaseBackupExecution::create([
|
$this->backup_log = ScheduledDatabaseBackupExecution::create([
|
||||||
|
'uuid' => $this->backup_log_uuid,
|
||||||
'database_name' => $databaseName,
|
'database_name' => $databaseName,
|
||||||
'filename' => $this->backup_location,
|
'filename' => $this->backup_location,
|
||||||
'scheduled_database_backup_id' => $this->backup->id,
|
'scheduled_database_backup_id' => $this->backup->id,
|
||||||
@@ -319,6 +326,7 @@ class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue
|
|||||||
}
|
}
|
||||||
$this->backup_location = $this->backup_dir.$this->backup_file;
|
$this->backup_location = $this->backup_dir.$this->backup_file;
|
||||||
$this->backup_log = ScheduledDatabaseBackupExecution::create([
|
$this->backup_log = ScheduledDatabaseBackupExecution::create([
|
||||||
|
'uuid' => $this->backup_log_uuid,
|
||||||
'database_name' => $database,
|
'database_name' => $database,
|
||||||
'filename' => $this->backup_location,
|
'filename' => $this->backup_location,
|
||||||
'scheduled_database_backup_id' => $this->backup->id,
|
'scheduled_database_backup_id' => $this->backup->id,
|
||||||
@@ -331,6 +339,7 @@ class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue
|
|||||||
}
|
}
|
||||||
$this->backup_location = $this->backup_dir.$this->backup_file;
|
$this->backup_location = $this->backup_dir.$this->backup_file;
|
||||||
$this->backup_log = ScheduledDatabaseBackupExecution::create([
|
$this->backup_log = ScheduledDatabaseBackupExecution::create([
|
||||||
|
'uuid' => $this->backup_log_uuid,
|
||||||
'database_name' => $database,
|
'database_name' => $database,
|
||||||
'filename' => $this->backup_location,
|
'filename' => $this->backup_location,
|
||||||
'scheduled_database_backup_id' => $this->backup->id,
|
'scheduled_database_backup_id' => $this->backup->id,
|
||||||
@@ -574,4 +583,18 @@ class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue
|
|||||||
|
|
||||||
return "{$helperImage}:{$latestVersion}";
|
return "{$helperImage}:{$latestVersion}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function failed(?Throwable $exception): void
|
||||||
|
{
|
||||||
|
$log = ScheduledDatabaseBackupExecution::where('uuid', $this->backup_log_uuid)->first();
|
||||||
|
|
||||||
|
if ($log) {
|
||||||
|
$log->update([
|
||||||
|
'status' => 'failed',
|
||||||
|
'message' => 'Job failed: '.$exception->getMessage(),
|
||||||
|
'size' => 0,
|
||||||
|
'filename' => null,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -73,6 +73,9 @@ class BackupEdit extends Component
|
|||||||
#[Validate(['required', 'boolean'])]
|
#[Validate(['required', 'boolean'])]
|
||||||
public bool $dumpAll = false;
|
public bool $dumpAll = false;
|
||||||
|
|
||||||
|
#[Validate(['required', 'int', 'min:1', 'max:36000'])]
|
||||||
|
public int $timeout = 3600;
|
||||||
|
|
||||||
public function mount()
|
public function mount()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
@@ -98,6 +101,7 @@ class BackupEdit extends Component
|
|||||||
$this->backup->s3_storage_id = $this->s3StorageId;
|
$this->backup->s3_storage_id = $this->s3StorageId;
|
||||||
$this->backup->databases_to_backup = $this->databasesToBackup;
|
$this->backup->databases_to_backup = $this->databasesToBackup;
|
||||||
$this->backup->dump_all = $this->dumpAll;
|
$this->backup->dump_all = $this->dumpAll;
|
||||||
|
$this->backup->timeout = $this->timeout;
|
||||||
$this->customValidate();
|
$this->customValidate();
|
||||||
$this->backup->save();
|
$this->backup->save();
|
||||||
} else {
|
} else {
|
||||||
@@ -114,6 +118,7 @@ class BackupEdit extends Component
|
|||||||
$this->s3StorageId = $this->backup->s3_storage_id;
|
$this->s3StorageId = $this->backup->s3_storage_id;
|
||||||
$this->databasesToBackup = $this->backup->databases_to_backup;
|
$this->databasesToBackup = $this->backup->databases_to_backup;
|
||||||
$this->dumpAll = $this->backup->dump_all;
|
$this->dumpAll = $this->backup->dump_all;
|
||||||
|
$this->timeout = $this->backup->timeout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('scheduled_database_backups', function (Blueprint $table) {
|
||||||
|
$table->integer('timeout')->default(3600);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
@@ -77,6 +77,7 @@
|
|||||||
<x-forms.input label="Frequency" id="frequency" />
|
<x-forms.input label="Frequency" id="frequency" />
|
||||||
<x-forms.input label="Timezone" id="timezone" disabled
|
<x-forms.input label="Timezone" id="timezone" disabled
|
||||||
helper="The timezone of the server where the backup is scheduled to run (if not set, the instance timezone will be used)" />
|
helper="The timezone of the server where the backup is scheduled to run (if not set, the instance timezone will be used)" />
|
||||||
|
<x-forms.input label="Timeout" id="timeout" helper="The timeout of the backup job in seconds."/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h3 class="mt-6 mb-2 text-lg font-medium">Backup Retention Settings</h3>
|
<h3 class="mt-6 mb-2 text-lg font-medium">Backup Retention Settings</h3>
|
||||||
|
Reference in New Issue
Block a user