Исправлен битый архив бэкапа - использование временного файла
shell_exec некорректно работает с бинарными данными. Теперь mysqldump пишет во временный файл, который потом стримится клиенту. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -23,30 +23,36 @@ class BackupService
|
||||
}
|
||||
|
||||
/**
|
||||
* Создать дамп и вернуть содержимое (gzip сжатое)
|
||||
* Создать дамп и вернуть путь к временному файлу
|
||||
*/
|
||||
public function dumpDatabase(string $database): string
|
||||
{
|
||||
$tempFile = sys_get_temp_dir() . '/backup_' . $database . '_' . uniqid() . '.sql.gz';
|
||||
|
||||
$cmd = sprintf(
|
||||
'mysqldump --host=%s --port=%s --user=%s --password=%s --single-transaction --routines --triggers %s 2>/dev/null | gzip',
|
||||
'mysqldump --host=%s --port=%s --user=%s --password=%s --single-transaction --routines --triggers %s 2>&1 | gzip > %s',
|
||||
escapeshellarg($this->host),
|
||||
escapeshellarg($this->port),
|
||||
escapeshellarg($this->user),
|
||||
escapeshellarg($this->pass),
|
||||
escapeshellarg($database)
|
||||
escapeshellarg($database),
|
||||
escapeshellarg($tempFile)
|
||||
);
|
||||
|
||||
$output = shell_exec($cmd);
|
||||
exec($cmd, $output, $returnCode);
|
||||
|
||||
if ($output === null || $output === '') {
|
||||
throw new \RuntimeException("Failed to create dump for database: $database");
|
||||
if ($returnCode !== 0 || !file_exists($tempFile) || filesize($tempFile) < 100) {
|
||||
if (file_exists($tempFile)) {
|
||||
unlink($tempFile);
|
||||
}
|
||||
throw new \RuntimeException("mysqldump failed: " . implode("\n", $output));
|
||||
}
|
||||
|
||||
return $output;
|
||||
return $tempFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Создать дамп всех баз данных (один файл)
|
||||
* Создать дамп всех баз данных
|
||||
*/
|
||||
public function dumpAllDatabases(\PDO $pdo): string
|
||||
{
|
||||
@@ -56,23 +62,28 @@ class BackupService
|
||||
throw new \RuntimeException("No databases available for backup");
|
||||
}
|
||||
|
||||
$tempFile = sys_get_temp_dir() . '/backup_all_' . uniqid() . '.sql.gz';
|
||||
$dbList = implode(' ', array_map('escapeshellarg', $databases));
|
||||
|
||||
$cmd = sprintf(
|
||||
'mysqldump --host=%s --port=%s --user=%s --password=%s --single-transaction --routines --triggers --databases %s 2>/dev/null | gzip',
|
||||
'mysqldump --host=%s --port=%s --user=%s --password=%s --single-transaction --routines --triggers --databases %s 2>&1 | gzip > %s',
|
||||
escapeshellarg($this->host),
|
||||
escapeshellarg($this->port),
|
||||
escapeshellarg($this->user),
|
||||
escapeshellarg($this->pass),
|
||||
$dbList
|
||||
$dbList,
|
||||
escapeshellarg($tempFile)
|
||||
);
|
||||
|
||||
$output = shell_exec($cmd);
|
||||
exec($cmd, $output, $returnCode);
|
||||
|
||||
if ($output === null || $output === '') {
|
||||
throw new \RuntimeException("Failed to create dump");
|
||||
if ($returnCode !== 0 || !file_exists($tempFile) || filesize($tempFile) < 100) {
|
||||
if (file_exists($tempFile)) {
|
||||
unlink($tempFile);
|
||||
}
|
||||
throw new \RuntimeException("mysqldump failed: " . implode("\n", $output));
|
||||
}
|
||||
|
||||
return $output;
|
||||
return $tempFile;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user