Yedek Zamanlamaları

1.6k görüntülenme Markdown

Yedek zamanlamalarını kuran ve alınmış yedekleri yöneten dokuz uç.

Genel Bakış

Bu dokuz uç iki şeyi yönetir. Beşi zamanlamaları kurar: hangi içerik, ne sıklıkta, hangi hedefe. Dördü ise alınmış yedeklerin kendisiyle ilgilenir.

Bir zamanlama yalnız bir niyettir. Yedeği asıl üreten, sırası gelince işi alan zamanlanmış görevdir. Bu yüzden yazma çağrıları hemen sonuç döndürmez: iş sıraya girer, kayıt açılır ve durum zamanla ilerler.

Yedeklerin nereye gideceği ayrı bir konudur. Hedefler kendi uçlarıyla kurulur; buradaki storage_id yalnız onlardan birini işaret eder.

Referans

Zamanlamaları Listeleme

get/api/v1/admin/settings/backup/schedules
Settings/GetBackupSchedules admin

Tanımlı yedek zamanlamalarını döndürür.

Sorgu 1
searchstringAda göre arar.
Dönen alanlar data[] — 14
idintZamanlamanın kimliği.
namestringZamanlamanın adı.
statusstringAçık mı kapalı mı.
frequencystringNe sıklıkta çalıştığı: hourly, daily, weekly, monthly.
run_timestringÇalışma saati.
run_dowint | nullHaftanın günü. Yalnız haftalık sıklıkta işler.
run_domint | nullAyın günü. Yalnız aylık sıklıkta işler.
contentsstring[]Yedeğe girecek içerikler: database, files, uploads.
storage_idintGönderilecek hedef. Sıfır, sunucunun kendisi demektir.
keep_localintSunucuda da kopya bırakılıp bırakılmadığı.
retention_countintKaç yedeğin saklandığı.
notify_adminintYöneticiye haber verilip verilmediği.
next_run_atstring | nullSonraki çalışma anı.
created_atstring | nullOluşturulma anı.
Hatalar 1
insufficient_scope403Anahtar gerekli kapsamı taşımıyor.
İstek
curl 'https://panel.ornek.com/api/v1/admin/settings/backup/schedules' \
  -H "Authorization: Bearer $API_KEY"
const res  = await fetch('https://panel.ornek.com/api/v1/admin/settings/backup/schedules', {
  headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();
$ch = curl_init('https://panel.ornek.com/api/v1/admin/settings/backup/schedules');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// Sonraki calisma ani KAPALI zamanlamada da dolu gorunur; durumu ayrica okuyun.
$due = array_filter(
    Api::Settings()->GetBackupSchedules()['data'],
    fn ($s) => $s['status'] === 'enabled',
);

Zamanlama Oluşturma

post/api/v1/admin/settings/backup/schedules
Settings/CreateBackupSchedule admin kapalı doğar

Yeni bir yedek zamanlaması kurar.

Gövde 11
namestringreqZamanlamanın adı. En çok 150 karakter.
contentsstring[]reqYedeğe girecek içerikler: database, files, uploads. En az biri gerekir.
statusintZamanlamayı açar. Verilmezse kapalı doğar.
frequencystringÇalışma sıklığı: hourly, daily, weekly, monthly. Öntanımlı günlük.
run_timestringÇalışma saati. Öntanımlı gece üç.
run_dowintHaftanın günü (0-6).
run_domintAyın günü (1-31).
storage_idintGönderilecek hedef. Sıfır, sunucunun kendisi demektir.
keep_localintSunucuda kopya bırakır. Hedef sunucunun kendisiyse zorlanır.
retention_countintSaklanacak yedek sayısı. Öntanımlı yedi.
notify_adminintYöneticiye haber verir.
Dönen alanlar 201 — data
dataobjectOluşan zamanlama. Liste öğesiyle aynı şekildedir.
Hatalar 3
name_required422Ad boş.
contents_empty422Hiçbir içerik seçilmedi.
insufficient_scope403Anahtar gerekli kapsamı taşımıyor.
İstek
curl -X POST 'https://panel.ornek.com/api/v1/admin/settings/backup/schedules' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"name":"Gecelik veritabani","frequency":"daily","run_time":"03:00","contents":["database"],"status":1}'
const res = await fetch('https://panel.ornek.com/api/v1/admin/settings/backup/schedules', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    name: 'Nightly database',
    frequency: 'daily',
    run_time: '03:00',
    contents: ['database'],
    status: 1,
  }),
});

const body = await res.json();
$ch = curl_init('https://panel.ornek.com/api/v1/admin/settings/backup/schedules');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'name'      => 'Nightly database',
        'frequency' => 'daily',
        'run_time'  => '03:00',
        'contents'  => ['database'],
        'status'    => 1,
    ]),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// Durumu VERMEZSENIZ zamanlama kapali dogar ve hicbir gece calismaz.
Api::Settings()->CreateBackupSchedule([
    'name'     => 'Nightly database',
    'contents' => ['database'],
    'status'   => 1,
]);

Zamanlama Detayı

get/api/v1/admin/settings/backup/schedules/{id}
Settings/GetBackupSchedule admin

Tek bir zamanlamayı döndürür.

Dönen alanlar data — 14
idintZamanlamanın kimliği.
namestringZamanlamanın adı.
statusstringAçık mı kapalı mı.
frequencystringNe sıklıkta çalıştığı: hourly, daily, weekly, monthly.
run_timestringÇalışma saati.
run_dowint | nullHaftanın günü. Yalnız haftalık sıklıkta işler.
run_domint | nullAyın günü. Yalnız aylık sıklıkta işler.
contentsstring[]Yedeğe girecek içerikler: database, files, uploads.
storage_idintGönderilecek hedef. Sıfır, sunucunun kendisi demektir.
keep_localintSunucuda da kopya bırakılıp bırakılmadığı.
retention_countintKaç yedeğin saklandığı.
notify_adminintYöneticiye haber verilip verilmediği.
next_run_atstring | nullSonraki çalışma anı.
created_atstring | nullOluşturulma anı.
Hatalar 2
not_found404Zamanlama bulunamadı.
insufficient_scope403Anahtar gerekli kapsamı taşımıyor.
İstek
curl 'https://panel.ornek.com/api/v1/admin/settings/backup/schedules/4' \
  -H "Authorization: Bearer $API_KEY"
const res  = await fetch(`https://panel.ornek.com/api/v1/admin/settings/backup/schedules/${id}`, {
  headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();
$ch = curl_init('https://panel.ornek.com/api/v1/admin/settings/backup/schedules/' . $id);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// Gun alanlari siklikla ESLESMIYORSA dolu gorunur ama hicbir ise yaramaz.
$s = Api::Settings()->GetBackupSchedule(['id' => $id])['data'];
$day = $s['frequency'] === 'weekly' ? $s['run_dow'] : null;

Zamanlamayı Güncelleme

patch/api/v1/admin/settings/backup/schedules/{id}
Settings/UpdateBackupSchedule admin

Zamanlamayı değiştirir; zamanı etkileyen alan değişirse sonraki çalışma yeniden hesaplanır.

Gövde 11
namestringreqZamanlamanın adı. En çok 150 karakter.
contentsstring[]reqYedeğe girecek içerikler: database, files, uploads. En az biri gerekir.
statusintZamanlamayı açar. Verilmezse kapalı doğar.
frequencystringÇalışma sıklığı: hourly, daily, weekly, monthly. Öntanımlı günlük.
run_timestringÇalışma saati. Öntanımlı gece üç.
run_dowintHaftanın günü (0-6).
run_domintAyın günü (1-31).
storage_idintGönderilecek hedef. Sıfır, sunucunun kendisi demektir.
keep_localintSunucuda kopya bırakır. Hedef sunucunun kendisiyse zorlanır.
retention_countintSaklanacak yedek sayısı. Öntanımlı yedi.
notify_adminintYöneticiye haber verir.
Dönen alanlar data — 14
dataobjectGüncel zamanlama. Liste satırıyla aynı şekildedir.
next_run_atstringYeniden hesaplanmış sonraki çalışma zamanı. Sıklık, saat, haftanın günü ya da ayın günü değiştiğinde iş yeniden zamanlanır; eski değeri korumak yerine yeni zamanı buradan okuyun.
Hatalar 4
not_found404Zamanlama bulunamadı.
name_required422Ad boş.
contents_empty422Hiçbir içerik seçilmedi.
insufficient_scope403Anahtar gerekli kapsamı taşımıyor.
İstek
curl -X PATCH 'https://panel.ornek.com/api/v1/admin/settings/backup/schedules/4' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"run_time":"04:30","retention_count":14}'
const res = await fetch(`https://panel.ornek.com/api/v1/admin/settings/backup/schedules/${id}`, {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ run_time: '04:30', retention_count: 14 }),
});

const body = await res.json();
$ch = curl_init('https://panel.ornek.com/api/v1/admin/settings/backup/schedules/' . $id);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'PATCH',
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode(['run_time' => '04:30', 'retention_count' => 14]),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// Gondermediginiz alan KORUNUR; saati degistirmek sonraki calismayi kaydirir.
Api::Settings()->UpdateBackupSchedule([
    'id'       => $id,
    'run_time' => '04:30',
]);

Zamanlamayı Silme

delete/api/v1/admin/settings/backup/schedules/{id}
Settings/DeleteBackupSchedule admin

Zamanlamayı kaldırır ve geçmişteki yedeklerin bağını koparır.

Dönen alanlar data — 2
deletedboolSilme çalıştı mı.
idintSilinen zamanlamanın kimliği.
Hatalar 2
not_found404Zamanlama bulunamadı.
insufficient_scope403Anahtar gerekli kapsamı taşımıyor.
İstek
curl -X DELETE 'https://panel.ornek.com/api/v1/admin/settings/backup/schedules/4' \
  -H "Authorization: Bearer $API_KEY"
const res = await fetch(`https://panel.ornek.com/api/v1/admin/settings/backup/schedules/${id}`, {
  method: 'DELETE',
  headers: { Authorization: `Bearer ${apiKey}` },
});

const body = await res.json();
$ch = curl_init('https://panel.ornek.com/api/v1/admin/settings/backup/schedules/' . $id);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'DELETE',
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// Yedekler SILINMEZ, yalniz zamanlama bagi kopar; dosyalar yerinde kalir.
Api::Settings()->DeleteBackupSchedule(['id' => $id]);

Yedekleri Listeleme

get/api/v1/admin/settings/backup/backups
Settings/GetBackups admin

Alınmış yedeklerin geçmişini döndürür.

Sorgu 1
searchstringKayıtlarda arar.
Dönen alanlar data[] — 21
idintYedeğin kimliği.
schedule_idint | nullYedeği üreten zamanlama. Elle alınan yedekte boştur.
storage_idintGönderildiği hedef.
keep_localintSunucuda kopya bırakılıp bırakılmadığı.
contentsstringYedeğe giren içerikler.
labelstringYedeğin etiketi.
file_namestringArşivin adı.
file_sizeintArşivin boyutu.
local_pathstring | nullSunucudaki yolu.
remote_pathstring | nullHedefteki yolu.
upload_statusstringGönderimin durumu. Yedeğin kendi durumundan ayrıdır.
upload_errorstring | nullGönderim neden düştü.
uploaded_atstring | nullGönderimin bittiği an.
statusstringYedeğin durumu. Bekliyor, çalışıyor, hazır, düştü ya da süresi doldu.
progressstring | nullİlerleme bilgisi.
error_messagestring | nullYedek neden düştü.
duration_secondsintNe kadar sürdüğü.
started_atstring | nullBaşladığı an.
completed_atstring | nullBittiği an.
cdatestringKaydın açıldığı an.
Hatalar 1
insufficient_scope403Anahtar gerekli kapsamı taşımıyor.
İstek
curl 'https://panel.ornek.com/api/v1/admin/settings/backup/backups' \
  -H "Authorization: Bearer $API_KEY"
const res  = await fetch('https://panel.ornek.com/api/v1/admin/settings/backup/backups', {
  headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();
$ch = curl_init('https://panel.ornek.com/api/v1/admin/settings/backup/backups');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// Hazir bir yedegin uzak kopyasi YINE DE dusmus olabilir: iki durumu birlikte okuyun.
$risky = array_filter(
    Api::Settings()->GetBackups()['data'],
    fn ($b) => $b['status'] === 'ready' && $b['upload_status'] === 'failed',
);

Elle Yedek Alma

post/api/v1/admin/settings/backup/backups
Settings/CreateManualBackup admin sıraya alınır

Zamanlamayı beklemeden bir yedek işini sıraya alır.

Gövde 3
contentsstring[]reqYedeğe girecek içerikler: database, files, uploads.
storage_idintGönderilecek hedef. Sıfır, sunucunun kendisi demektir.
keep_localintSunucuda kopya bırakır.
Dönen alanlar 201 — data — 2
queuedboolİş sıraya alındı mı. Yedeğin bittiği anlamına gelmez.
backup_idintAçılan yedek kaydının kimliği.
Hatalar 5
contents_empty422Hiçbir içerik seçilmedi.
system_disabled422Yedek sistemi kapalı.
already_running422Çalışan bir yedek var.
system_incompatible422Sunucuda yedeklemenin ihtiyaç duyduğu bir yetenek eksik, yedek sıraya alınmaz. details.critical eksik olanları listeler: zlib ve/veya spl.
insufficient_scope403Anahtar gerekli kapsamı taşımıyor.
İstek
curl -X POST 'https://panel.ornek.com/api/v1/admin/settings/backup/backups' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"contents":["database","files"],"storage_id":0}'
const res = await fetch('https://panel.ornek.com/api/v1/admin/settings/backup/backups', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    contents: ['database', 'files'],
    storage_id: 0,
  }),
});

const body = await res.json();
$ch = curl_init('https://panel.ornek.com/api/v1/admin/settings/backup/backups');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'contents'   => ['database', 'files'],
        'storage_id' => 0,
    ]),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// Ayni anda TEK yedek calisir: gece penceresine denk gelen istek reddedilir.
$id = Api::Settings()->CreateManualBackup([
    'contents' => ['database'],
])['data']['backup_id'];

Yedeği Yeniden Deneme

post/api/v1/admin/settings/backup/backups/{id}/retry
Settings/RetryBackup admin

Düşmüş bir yedeği yeniden sıraya alır. Arşiv diskte duruyor ve yalnız aktarım başarısız olduysa yalnız yükleme tekrarlanır; aksi hâlde yedek baştan alınır ve başarısız denemenin yerel yedek klasöründe bıraktığı arşiv silinir.

Gövde —
——Gövde gerekmez, boş gönderin. Yedeği adresteki kimlik belirler.
Dönen alanlar data — 2
requeuedboolİş yeniden sıraya alındı mı.
backup_idintYedeğin kimliği.
Hatalar 7
invalid_id422Kimlik geçersiz.
not_found404Yedek bulunamadı.
not_failed422Yedek düşmemiş. Yalnız düşmüş olanlar yeniden denenir.
system_disabled422Yedek sistemi kapalı.
already_running422Çalışan bir yedek var.
system_incompatible422Sunucuda yedeklemenin ihtiyaç duyduğu bir yetenek eksik, yedek yeniden sıraya alınmaz. details.critical eksik olanları listeler: zlib ve/veya spl. Yalnız yedek baştan kurulacaksa denetlenir; yalnız yüklemenin tekrarlandığı denemede atlanır.
insufficient_scope403Anahtar gerekli kapsamı taşımıyor.
İstek
curl -X POST 'https://panel.ornek.com/api/v1/admin/settings/backup/backups/91/retry' \
  -H "Authorization: Bearer $API_KEY"
const res = await fetch(`https://panel.ornek.com/api/v1/admin/settings/backup/backups/${id}/retry`, {
  method: 'POST',
  headers: { Authorization: `Bearer ${apiKey}` },
});

const body = await res.json();
$ch = curl_init('https://panel.ornek.com/api/v1/admin/settings/backup/backups/' . $id . '/retry');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// Gonderimi dusmus ama kendisi HAZIR bir yedek buradan yeniden denenemez.
if ($backup['status'] === 'failed')
    Api::Settings()->RetryBackup(['id' => $backup['id']]);

Yedeği Silme

delete/api/v1/admin/settings/backup/backups/{id}
Settings/DeleteBackup admin dosyalar da gider

Yedek kaydını, bekleyen işini ve dosyalarını kaldırır. running durumundaki yedek sinyal vermeye devam ederken reddedilir; son sinyali 30 dakikadan eskiyse satır terk edilmiş sayılır ve diğerleri gibi silinir.

Dönen alanlar data — 2
deletedboolSilme çalıştı mı.
idintSilinen yedeğin kimliği.
Hatalar 4
invalid_id422Kimlik geçersiz.
not_found404Yedek bulunamadı.
backup_running422Yedek hâlâ çalışıyor (son sinyali 30 dakikadan yeni).
insufficient_scope403Anahtar gerekli kapsamı taşımıyor.
İstek
curl -X DELETE 'https://panel.ornek.com/api/v1/admin/settings/backup/backups/91' \
  -H "Authorization: Bearer $API_KEY"
const res = await fetch(`https://panel.ornek.com/api/v1/admin/settings/backup/backups/${id}`, {
  method: 'DELETE',
  headers: { Authorization: `Bearer ${apiKey}` },
});

const body = await res.json();
$ch = curl_init('https://panel.ornek.com/api/v1/admin/settings/backup/backups/' . $id);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'DELETE',
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// Calisan yedek silinemez; once bitmesini bekleyin, iptal eden bir uc YOKTUR.
Api::Settings()->DeleteBackup(['id' => $id]);

Tuzaklar

Yeni zamanlama kapalı doğar

Durum alanını göndermezseniz zamanlama kapalı oluşur. Listede görünür, sonraki çalışma anı bile dolu gelir, ama hiçbir gece çalışmaz. Kurduktan sonra çalıştığını sanıp aylar sonra yedeksiz kalmak buradan gelir; oluştururken durumu birlikte gönderin.

Aynı anda tek yedek çalışır

Bir yedek çalışırken elle yedek alma ve yeniden deneme çağrıları reddedilir. Gece penceresine denk gelen bir betik bunu hata sanır. Yanıt kalıcı bir sorunu değil, o anki meşguliyeti anlatır: bir süre sonra yeniden deneyin.

İki ayrı durum vardır

Yedeğin kendi durumu ile hedefe gönderim durumu ayrı alanlardır. Bir yedek hazır görünürken uzak kopyası düşmüş olabilir: arşiv sunucuda durur, hedefte hiç yoktur. Sunucuyu kaybettiğiniz gün asıl önemli olan ikinci alandır, o yüzden ikisini birlikte okuyun.

Yeniden deneme yalnız düşmüş yedekler için

Yeniden deneme ucu, durumu düşmüş olmayan bir yedekte reddeder. Gönderimi başarısız olmuş ama kendisi hazır kalmış bir yedek de bu kapıdan geçemez; oradaki eksik uzak kopyadır, yedeğin kendisi değil. O durumda yeni bir yedek almak gerekir.

Zamanlamayı silmek yedekleri silmez

Zamanlama silinince ürettiği yedeklerin bağı kopar, kendileri durur. Dosyalar yerinde kalır ve saklama sayısı artık onları kimseye saydırmaz. Yer açmak istiyorsanız yedekleri tek tek silmeniz gerekir; yedeği silmek bekleyen işini iptal eder ve dosyalarını kaldırır.

Faydalı oldu mu?

Geri bildiriminiz için teşekkürler!

Hâlâ Yardıma mı İhtiyacınız Var?

Yukarıda bulamadığınız her şey için destek ekibimiz her zaman yanınızda.