Blog · 4 Kasım 2026 · 2 dk okuma

FTS5 tablosu olan bir Cloudflare D1 veritabanını yedeklemek

D1'in export API'si sanal tablolu veritabanlarını reddediyor. Çalışan sorgu tabanlı döküm, geri yükleme ve tam metin dizininin sağlam kaldığını doğrulama.

Yazan seops ekibi · In English

Kısa cevap. Cloudflare D1 export ucu "cannot export databases with virtual tables (like FTS5)" hatasıyla duruyor. Bunun yerine şemayı sqlite_master'dan, satırları sorgu API'sinden dök: önce CREATE ifadeleri, satırlar 2.000'erli sayfalarla INSERT olarak, FTS5 tabloları CREATE VIRTUAL TABLE ile yeniden kurulup rowid ile doldurulur, gölge tablolar atlanır, dizin ve tetikleyiciler sonda. wrangler d1 execute --file ile geri yükle; satır sayılarını ve bir MATCH sorgusunu karşılaştır.

Hata

seops bildiği her D1 veritabanının gece dökümünü alıp R2’ye koyar. Biri her gece hata vermeye başladı:

D1 Export error: cannot export databases with virtual tables (like FTS5)

Bu veritabanı FTS5 tablolu bir site aramasını besliyor (codes_fts USING fts5(body, tokenize = 'unicode61 remove_diacritics 2')). Export API’si (POST /d1/database/{id}/export) tek bir sanal tablo olduğu anda veritabanının tamamını reddediyor. FTS5’i kaldırmak seçenek değildi: sitenin araması onunla çalışıyor.

Çalışan döküm

Aşağıdakilerin hepsi normal sorgu API’sinden (/d1/database/{id}/query) geçer; onda böyle bir kısıt yok.

1. Şemayı oku.

SELECT type, name, tbl_name, sql FROM sqlite_master WHERE sql IS NOT NULL ORDER BY rowid;

2. Sınıflandır. Normal tablolar satır olarak dökülür. Sanal tablolar (sql LIKE 'CREATE VIRTUAL TABLE%') özel işlenir. Gölge tabloları (<ad>_data, _idx, _content, _docsize, _config) tamamen atlanır; SQLite onları yeniden kurar. _cf_* ve sqlite_* tabloları da atlanır.

3. Normal tabloları dök. CREATE TABLE ifadesini yaz, satırları sayfala:

SELECT * FROM "codes" ORDER BY rowid LIMIT 2000 OFFSET 0;

Her sayfa çok satırlı INSERT INTO "codes" (...) VALUES (...), (...); olur. Metinlerde tek tırnağı ikile, blob’ları X'..' yaz, NULL’ları NULL bırak.

4. FTS5 tablolarını dök. Özgün CREATE VIRTUAL TABLE ifadesini yaz, sonra:

SELECT rowid, * FROM "codes_fts" ORDER BY rowid LIMIT 2000 OFFSET 0;

ve rowid dahil ekle: INSERT INTO "codes_fts" (rowid, body) VALUES (...). İçeriksiz ya da dış içerikli FTS tablosunda içerik kaynağına ekleyip sonda INSERT INTO fts(fts) VALUES('rebuild') çalıştır.

5. Dizin ve tetikleyiciler en sona, aynı sqlite_master okumasından. FTS tablosunu dolduran tetikleyiciler veriden sonra gelmeli; yoksa her satır iki kez dizinlenir.

6. Sıkıştır ve sakla. SQL’i gzip’le, R2’de d1/<veritabanı>/<tarih>.sql.gz yoluna, export API’sinden gelen dökümlerin yanına koy. Yedek kaydına yöntemi yaz (“sorgu API’si, sanal tablo”).

Geri yükle ve doğrula

wrangler d1 execute my-db --local --file=2026-11-04.sql
wrangler d1 execute my-db --local --command="SELECT count(*) FROM codes; SELECT count(*) FROM codes_fts; SELECT count(*) FROM codes_fts WHERE codes_fts MATCH 'e13';"

Satır sayıları kaynakla aynı olmalı (burada 1.203 ve 1.203), MATCH sorgusu canlıdakiyle aynı sonucu vermeli. Yüklenen ama arayamayan döküm yedek değildir.

seops bununla ne yapıyor

Panelde Ayarlar › Altyapı › Yedekler her D1 veritabanını, son başarılı dökümü, yöntemi ve boyutu listeler. Export API’si sanal tablo hatası verirse sorgu API’si yolu kendiliğinden çalışır. 36 saattir başarılı dökümü olmayan veritabanı uyarı üretir.

Sorular

FTS5'i kaldırıp LIKE kullansam?

Site araması ona dayanıyorsa hayır. FTS5 sıralı, belirteçlenmiş arama verir; LIKE bunu yapamaz. Yukarıdaki döküm yolunun çalışma zamanında maliyeti yok.

Time Travel bunu karşılamıyor mu?

Time Travel veritabanını son 30 gün içindeki bir ana yerinde geri alır. İndirebileceğin, bir yıl saklayabileceğin ya da başka yere yükleyebileceğin bir kopya değildir. İkisini birlikte kullan.

Döküm ne kadar büyür?

Sorgu API'si sayfa sayfa döner; 2.000 satırlık sayfalar her yanıtı küçük tutar. FTS dizinli 1.200 satırlık bir tablo birkaç saniyede dökülür, gzip'le birkaç yüz KB olur.

Bir siteyle ücretsiz başla

İlk site süresiz ücretsiz; kart istemez. Her ek site ayda $2,50.