Elasticsearch Index Temizleme Scripti
Bu doküman, Apinizer trafik index'leri (apinizer_api_traffic_*) üzerinde disk alanı kazanmak için kullanılan tek dosyalık es_cleanup.sh scriptini anlatır.
Script vi ile açılır, en üstteki AYAR BÖLÜMÜ doldurulur ve çalıştırılır. Yapılacak işlem ve işlemin kapsamı, hangi alanların doldurulduğuna göre otomatik belirlenir.
Script geri alınamaz işlemler yapar. Çalıştırmadan önce ilgili index'in snapshot / yedeğinin alınmış olduğundan emin olun. İşlem öncesi DRY_RUN="true" ile planı kontrol etmeniz önerilir.
Script index'in tamamını silmez; yalnızca alan temizler veya döküman siler.
1) Ön Koşullar
- Elasticsearch sunucusuna erişim (
IP:PORT) ve ilgili index üzerinde yazma/yönetim yetkisi curlvejqaraçlarının kurulu olması
# jq kurulu değilse
sudo apt update
sudo apt install -y jq
2) Yapılacak İşlemin Belirlenmesi
Ayar bölümündeki iki işlem alanından yalnızca biri kullanılır:
| Doldurulan alan | Yapılan işlem | Yöntem |
|---|---|---|
FIELDS="fcrb,tba" | Seçilen alanlar temizlenir, dökümanlar kalır | _update_by_query |
DELETE_DOCS="true" | Eşleşen dökümanlar silinir | _delete_by_query |
İkisi aynı anda doldurulursa script hata verip durur.
3) İşlemin Kapsamının Belirlenmesi
Kapsam alanları opsiyoneldir. Boş bırakılan filtre uygulanmaz:
| Doldurulan alan(lar) | Kapsam |
|---|---|
| Hiçbiri | Index'teki tüm dökümanlar (match_all) |
START_TS + END_TS | Sadece o zaman aralığındaki dökümanlar |
PROXY_VALUE | Sadece o proxy'ye ait dökümanlar |
| Her ikisi birden | Proxy ve zaman aralığının kesişimi |
Dolu olan filtreler bir bool.filter içinde birleştirilir.
Alan Adları ve Filtre Alanları
- Temizlenecek alanlar, dökümanın
_sourceiçindeki anahtar adıyla birebir eşleşmelidir. Apinizer template'indeki kısaltmalar kullanılır (fcrb,tba…), açıklama isimleri değil. Disk kullanımının büyük kısmınıtexttipindeki body alanları oluşturur:
| Alan | Açıklama |
|---|---|
fcrb | From Client Body |
tba | To Backend Body |
fbarb | From Backend Body |
tcb | To Client Body |
- Proxy filtresi
apn(API Proxy Adı) veyaapi(API Proxy ID) alanı üzerinden yapılır. - Zaman filtresi
@timestampalanı üzerinden yapılır. Format:yyyy-MM-dd'T'HH:mm:ss.SSS'Z'(örnek:2025-01-01T00:00:00.000Z).START_TSveEND_TSbirlikte doldurulmalıdır.
4) Data Stream Kullanılıyorsa (.ds- ile başlayan index'ler)
Apinizer log index'leri data stream olarak yapılandırılmış olabilir. Bu durumda gerçek veri, adı .ds- ile başlayan backing index'lerde tutulur:
.ds-apinizer-log-apiproxy-qa8-2026.07.09-000025
Elasticsearch data stream'leri append-only kabul eder; bir data stream adına doğrudan _update_by_query veya _delete_by_query çalıştırılamaz. Bu nedenle INDEX ayarına data stream adı (apinizer-log-apiproxy-qa8) değil, backing index adı (.ds-apinizer-log-apiproxy-qa8-2026.07.09-000025) yazılmalıdır.
Bir data stream'in backing index'leri rollover ile çoğalır. Tüm data stream'i temizlemek için backing index'lerin listesi alınır ve script her biri için ayrı ayrı çalıştırılır:
# Backing index listesi
curl -s -u "elastic:PAROLA" -k -X GET \
"https://ES_HOST:ES_PORT/_data_stream/apinizer-log-apiproxy-qa8?pretty" \
| jq -r '.data_streams[].indices[].index_name'
# Alternatif: _cat ile boyutlariyla birlikte
curl -s -u "elastic:PAROLA" -k -X GET \
"https://ES_HOST:ES_PORT/_cat/indices/.ds-apinizer-log-apiproxy-qa8-*?v&h=index,docs.count,store.size&s=index"
Aktif Backing Index
Bir data stream'in en yeni backing index'i yazma yapılan index'tir. Temizleme sırasında yeni döküman gelmeye devam edeceğinden, işlem sonrası döküman sayısı beklenenden farklı olabilir. Bu normaldir; conflicts=proceed sayesinde işlem durmaz.
ILM politikası backing index'i cold/frozen fazına aldıysa index read-only olabilir. Script bu durumu algılar, write bloğunu geçici açar ve işlem sonunda eski durumuna geri koyar.
5) Alan Temizleme Yöntemi
FIELD_MODE ayarı iki değer alır:
| Değer | Davranış |
|---|---|
remove (varsayılan) | Alan _source'tan komple silinir |
empty | Alan kalır, içeriği boş string ("") olur |
Script painless içinde alanı containsKey() kontrolüyle işler. Böylece ilgili alanı zaten bulunmayan dökümanlar boş yere yeniden yazılmaz (gereksiz reindex ve _version artışı önlenir).
boolean changed = false;
if (ctx._source.containsKey('fcrb')) { ctx._source.remove('fcrb'); changed = true; }
if (!changed) { ctx.op = 'noop'; }
ctx.op = 'noop' Neden Var?
_update_by_query, painless script _source'u hiç değiştirmese bile eşleşen her dökümanı yeniden yazar. Bu, gereksiz _version artışına, yeni segment oluşmasına ve boşa I/O harcanmasına yol açar.
Script, hiçbir alan değişmediğinde ctx.op = 'noop' atar; Elasticsearch bu dökümanlara hiç dokunmaz.
Pratik etkisi: aynı temizlik ikinci kez çalıştırıldığında (alanlar zaten silinmişse) tüm dökümanlar noops olarak raporlanır, disk ve CPU harcanmaz:
{"total":1387,"updated":0,"noops":1387,"deleted":0,"failures":[]}
Bu koruma olmasaydı aynı çalıştırma updated: 1387 gösterir ve 1387 döküman boşuna yeniden yazılırdı.
Alanın silinmesini değil, yalnızca içeriğinin boşaltılmasını istiyorsanız (alan _source çıktısında görünmeye devam etsin, dökümanların şema yapısı bozulmasın) FIELD_MODE="empty" kullanın.
İki yöntemin karşılaştırması:
remove (varsayılan) | empty | |
|---|---|---|
_source içindeki anahtar | Tamamen kaldırılır | "fcrb": "" olarak kalır |
| Disk kazanımı | En yüksek | Sınırlı |
| API/dashboard çıktısı | Alan hiç dönmez | Alan boş string ile döner |
exists sorgusu eşleşir mi? | Hayır | Evet (boş string bir değerdir) |
Disk alanı kazanmak birincil amaç olduğundan remove tercih edilmelidir. empty, yalnızca alanın çıktıda görünmeye devam etmesi gereken özel durumlarda kullanılmalıdır.
6) Güvenlik ve Kontrol Ayarları
| Ayar | Açıklama |
|---|---|
ES_PASS | Boş bırakılırsa çalışma anında sorulur. Parolanın dosyada saklanmaması önerilir. |
ES_USER | Kümede güvenlik kapalıysa (xpack.security.enabled: false) boş bırakılır; -u parametresi hiç kullanılmaz. |
DRY_RUN | "true" ise hiçbir değişiklik yapılmaz; plan, etkilenecek döküman sayısı ve üretilecek sorgu/painless script ekrana basılır. |
SKIP_CONFIRM | "true" ise onay sorulmaz. Yalnızca otomasyon için, dikkatli kullanılmalıdır. |
FORCE_MERGE | "true" ise işlem sonrası disk alanını geri kazanmak için force merge çalıştırılır. |
Script ayrıca:
- Çalıştırdığı her
curlkomutunu>> curl ...formatında ekrana basar; parolayı maskeler (kullanici:****). - İşlem öncesi
_countile etkilenecek döküman sayısını gösterir veyesonayı ister. - Index read-only ise write bloğunu geçici açar, işlem sonunda önceki durumuna geri koyar.
httpsseçilirse self-signed sertifikalar için-kparametresini otomatik ekler.
7) Script
#!/bin/bash
# ============================================================================
# Apinizer - Elasticsearch Index Temizleme Scripti
# es_cleanup.sh
# ----------------------------------------------------------------------------
# Tum temizleme senaryolarini tek dosyada toplar.
# Scripti "vi es_cleanup.sh" ile acin, asagidaki AYAR BOLUMUNU doldurun.
# Hangi alanlari doldurdugunuza gore islem ve kapsam otomatik belirlenir.
#
# ISLEM (birini secin):
# FIELDS dolu -> secilen ALANLAR temizlenir (dokumanlar kalir)
# DELETE_DOCS="true" -> eslesen DOKUMANLAR silinir
#
# KAPSAM (opsiyonel, bos birakilanlar uygulanmaz):
# START_TS + END_TS -> sadece bu zaman araligindaki dokumanlar
# PROXY_VALUE -> sadece bu proxy'ye ait dokumanlar
# ikisi de bos -> index'teki TUM dokumanlar
#
# Not: Bu script index'in tamamini SILMEZ; yalnizca alan temizler
# veya dokuman siler.
#
# KULLANIM:
# vi es_cleanup.sh # AYAR BOLUMUNU doldurun
# chmod +x es_cleanup.sh
# ./es_cleanup.sh
# ============================================================================
# ############################################################################
# # AYAR BOLUMU (BURAYI DOLDURUN) #
# ############################################################################
# ---- Baglanti (ZORUNLU) ----------------------------------------------------
ES_HOST="10.10.10.10:9200" # IP:PORT
ES_PROTO="https" # http | https
# ---- Kimlik dogrulama (OPSIYONEL) ------------------------------------------
# Kumede guvenlik kapaliysa (xpack.security.enabled: false) ikisini de
# BOS birakin; -u parametresi hic kullanilmaz.
# ES_PASS bos birakilirsa calisma aninda sorulur (parolayi dosyada
# saklamak istemiyorsaniz onerilir).
ES_USER="elastic"
ES_PASS=""
# ---- Index (ZORUNLU) -------------------------------------------------------
INDEX="apinizer_api_traffic_v2"
# ############################################################################
# # ISLEM SECIMI - Asagidakilerden SADECE BIRINI kullanin #
# ############################################################################
# ---- ISLEM A: Alanlari temizle ---------------------------------------------
# Virgulle ayrilir. Dokumanin _source anahtarlariyla birebir eslesmelidir.
# Apinizer body alanlari (disk kullaniminin buyuk kismi):
# fcrb = From Client Body
# tba = To Backend Body
# fbarb = From Backend Body
# tcb = To Client Body
# BOS birakilirsa alan temizleme yapilmaz.
FIELDS="fcrb,tba,fbarb,tcb"
# Alan temizleme yontemi:
# "remove" -> alan _source'tan komple silinir (varsayilan, en yuksek disk kazanimi)
# "empty" -> alan kalir, icerigi "" olur (disk kazanimi sinirli)
FIELD_MODE="remove"
# ---- ISLEM B: Dokumanlari sil ----------------------------------------------
# "true" yapilirsa, asagidaki kapsama uyan DOKUMANLAR SILINIR.
# FIELDS ile ayni anda kullanilamaz (FIELDS'i bosaltin).
DELETE_DOCS="false"
# ############################################################################
# # KAPSAM (OPSIYONEL) - Bos birakilan filtre uygulanmaz #
# ############################################################################
# ---- Zaman araligi ---------------------------------------------------------
# Format: yyyy-MM-dd'T'HH:mm:ss.SSS'Z'
# IKISI DE bos -> zaman filtresi yok (tum zamanlar)
# Biri dolu digeri bos birakilamaz.
START_TS="" # ornek: 2025-01-01T00:00:00.000Z
END_TS="" # ornek: 2025-02-01T00:00:00.000Z
# ---- Proxy -----------------------------------------------------------------
# PROXY_VALUE bos -> proxy filtresi yok (tum proxy'ler)
# PROXY_FIELD: apn = API Proxy Adi | api = API Proxy ID
PROXY_FIELD="apn"
PROXY_VALUE="" # ornek: MyProxy
# ############################################################################
# # DAVRANIS #
# ############################################################################
FORCE_MERGE="true" # Islem sonrasi disk alanini geri kazanmak icin
DRY_RUN="false" # "true" -> degisiklik yapmaz, sadece plani gosterir
SKIP_CONFIRM="false" # "true" -> onay sormaz (otomasyon; DIKKATLI KULLANIN)
# ############################################################################
# # AYAR BOLUMU SONU - ASAGISINA DOKUNMAYIN #
# ############################################################################
set -o pipefail
die() { echo "HATA: $*" >&2; exit 1; }
# ---------------------------------------------------------------------------
# Ayar dogrulama
# ---------------------------------------------------------------------------
command -v jq >/dev/null 2>&1 || die "'jq' kurulu degil. Kurun: sudo apt install -y jq"
[ -z "$ES_HOST" ] && die "ES_HOST bos olamaz."
[ -z "$INDEX" ] && die "INDEX bos olamaz."
[[ "$ES_PROTO" != "http" && "$ES_PROTO" != "https" ]] && die "ES_PROTO 'http' veya 'https' olmali."
[[ "$FIELD_MODE" != "remove" && "$FIELD_MODE" != "empty" ]] && die "FIELD_MODE 'remove' veya 'empty' olmali."
[[ "$PROXY_FIELD" != "apn" && "$PROXY_FIELD" != "api" ]] && die "PROXY_FIELD 'apn' veya 'api' olmali."
# Zaman araligi: ya ikisi de dolu ya ikisi de bos
[ -n "$START_TS" ] && [ -z "$END_TS" ] && die "START_TS dolu ama END_TS bos."
[ -z "$START_TS" ] && [ -n "$END_TS" ] && die "END_TS dolu ama START_TS bos."
# Islem secimi: tam olarak biri
if [ -n "$FIELDS" ] && [ "$DELETE_DOCS" == "true" ]; then
die "FIELDS ile DELETE_DOCS ayni anda kullanilamaz. Ya alanlari temizleyin ya dokumanlari silin."
fi
if [ -z "$FIELDS" ] && [ "$DELETE_DOCS" != "true" ]; then
die "Yapilacak islem yok. FIELDS doldurun veya DELETE_DOCS=\"true\" yapin."
fi
# ---------------------------------------------------------------------------
# Parola: dosyada bos birakildiysa calisma aninda sorulur
# ---------------------------------------------------------------------------
if [ -n "$ES_USER" ] && [ -z "$ES_PASS" ]; then
read -s -p "Elasticsearch parolasi ($ES_USER): " ES_PASS
echo ""
fi
BASE_URL="$ES_PROTO://$ES_HOST"
CURL_OPTS=(-s)
[ -n "$ES_USER" ] && CURL_OPTS+=(-u "$ES_USER:$ES_PASS") # Basic Auth (varsa)
[ "$ES_PROTO" == "https" ] && CURL_OPTS+=(-k) # https + self-signed
# Calistirilan curl komutunu (parola maskeli) ekrana basar
run_curl() {
local shown=() arg
for arg in "$@"; do
if [ -n "$ES_USER" ] && [[ "$arg" == "$ES_USER:$ES_PASS" ]]; then
shown+=("$ES_USER:****")
else
shown+=("$arg")
fi
done
echo ">> curl ${shown[*]}" >&2
curl "$@"
}
# ---------------------------------------------------------------------------
# Sorgu uretimi: dolu olan filtreler bool.filter icinde birlestirilir.
# Hicbir filtre yoksa match_all -> index'teki tum dokumanlar.
# ---------------------------------------------------------------------------
build_query() {
local filters=()
[ -n "$PROXY_VALUE" ] && filters+=("{\"term\":{\"$PROXY_FIELD\":\"$PROXY_VALUE\"}}")
[ -n "$START_TS" ] && filters+=("{\"range\":{\"@timestamp\":{\"gte\":\"$START_TS\",\"lte\":\"$END_TS\"}}}")
if [ ${#filters[@]} -eq 0 ]; then
echo '{"match_all":{}}'
else
local joined
joined=$(IFS=,; echo "${filters[*]}")
echo "{\"bool\":{\"filter\":[$joined]}}"
fi
}
# ---------------------------------------------------------------------------
# Painless script uretimi
# FIELD_MODE="remove" -> alan _source'tan komple silinir
# FIELD_MODE="empty" -> alan kalir, icerigi "" olur
#
# containsKey kontrolu, alani zaten olmayan dokumanlarda islem yapilmasini onler.
#
# ctx.op = 'noop': Hicbir alan degismediyse Elasticsearch dokumani hic yeniden
# yazmaz. Bu olmadan _update_by_query, script _source'u degistirmese bile her
# eslesen dokumani reindex eder (gereksiz _version artisi, segment copu, I/O).
# Ozellikle ayni temizlik ikinci kez calistirildiginda onemlidir; o calismada
# tum dokumanlar "noops" olarak raporlanir ve disk/CPU harcanmaz.
# ---------------------------------------------------------------------------
build_field_script() {
local input="$1" IFS=',' fields s="" f
read -r -a fields <<< "$input"
s="boolean changed = false; "
for f in "${fields[@]}"; do
f=$(echo "$f" | xargs)
[ -z "$f" ] && continue
if [ "$FIELD_MODE" == "remove" ]; then
s+="if (ctx._source.containsKey('$f')) { ctx._source.remove('$f'); changed = true; } "
else
s+="if (ctx._source.containsKey('$f') && ctx._source.$f != '') { ctx._source.$f = ''; changed = true; } "
fi
done
s+="if (!changed) { ctx.op = 'noop'; }"
echo "$s"
}
QUERY=$(build_query)
# ---------------------------------------------------------------------------
# Ozet
# ---------------------------------------------------------------------------
echo "===================================================================="
echo " YAPILACAK ISLEM"
echo "===================================================================="
echo " Sunucu : $BASE_URL"
echo " Kimlik : ${ES_USER:-<auth yok>}"
echo " Index : $INDEX"
if [ -n "$FIELDS" ]; then
if [ "$FIELD_MODE" == "remove" ]; then
echo " Islem : ALANLAR _source'TAN KOMPLE SILINECEK"
else
echo " Islem : ALANLARIN ICERIGI BOSALTILACAK (\"\")"
fi
echo " Alanlar : $FIELDS"
else
echo " Islem : DOKUMANLAR SILINECEK"
fi
echo " Kapsam :"
if [ -n "$PROXY_VALUE" ]; then
echo " proxy : $PROXY_FIELD = $PROXY_VALUE"
else
echo " proxy : (filtre yok, tum proxy'ler)"
fi
if [ -n "$START_TS" ]; then
echo " zaman : $START_TS -> $END_TS"
else
echo " zaman : (filtre yok, tum zamanlar)"
fi
if [ -z "$PROXY_VALUE" ] && [ -z "$START_TS" ]; then
echo " ==> Index'teki TUM dokumanlar islenecek."
fi
echo " Force merge : $FORCE_MERGE"
[ "$DRY_RUN" == "true" ] && echo " DRY_RUN : true (hicbir degisiklik yapilmayacak)"
echo "===================================================================="
echo ""
# ---------------------------------------------------------------------------
# Etkilenecek dokuman sayisi
# ---------------------------------------------------------------------------
echo "Etkilenecek dokuman sayisi kontrol ediliyor..."
COUNT=$(run_curl "${CURL_OPTS[@]}" -X POST "$BASE_URL/$INDEX/_count" \
-H 'Content-Type: application/json' -d "{\"query\":$QUERY}" | jq -r '.count')
echo "Etkilenecek dokuman sayisi: $COUNT"
echo ""
if [ -z "$COUNT" ] || [ "$COUNT" == "null" ]; then
die "Dokuman sayisi alinamadi. Baglanti bilgilerini ve index adini kontrol edin."
fi
if [ "$COUNT" == "0" ]; then
echo "Eslesen dokuman yok. Yapilacak islem yok."
exit 0
fi
# ---------------------------------------------------------------------------
# DRY_RUN
# ---------------------------------------------------------------------------
if [ "$DRY_RUN" == "true" ]; then
echo "DRY_RUN - calistirilacak sorgu:"
echo " $QUERY"
if [ -n "$FIELDS" ]; then
echo "DRY_RUN - calistirilacak painless script:"
echo " $(build_field_script "$FIELDS")"
fi
echo ""
echo "DRY_RUN aktif oldugundan hicbir degisiklik yapilmadi."
exit 0
fi
# ---------------------------------------------------------------------------
# Onay
# ---------------------------------------------------------------------------
if [ "$SKIP_CONFIRM" != "true" ]; then
read -p "Devam etmek icin 'yes' yazin: " CONFIRM
[ "$CONFIRM" != "yes" ] && { echo "Islem iptal edildi."; exit 1; }
echo ""
fi
# ---------------------------------------------------------------------------
# Write blogu / force merge yardimcilari
# ---------------------------------------------------------------------------
open_write() {
local wb
wb=$(run_curl "${CURL_OPTS[@]}" -X GET "$BASE_URL/$INDEX/_settings" \
| jq -r ".[\"$INDEX\"].settings.index.blocks.write")
if [ "$wb" == "true" ]; then
echo "Index read-only, write aciliyor..."
run_curl "${CURL_OPTS[@]}" -X PUT "$BASE_URL/$INDEX/_settings" \
-H 'Content-Type: application/json' -d '{"index.blocks.write": false}'
echo ""
RESTORE_READONLY="true"
else
RESTORE_READONLY="false"
fi
}
restore_write() {
if [ "$RESTORE_READONLY" == "true" ]; then
echo "Index tekrar read-only olarak ayarlaniyor..."
run_curl "${CURL_OPTS[@]}" -X PUT "$BASE_URL/$INDEX/_settings" \
-H 'Content-Type: application/json' -d '{"index.blocks.write": true}'
echo ""
fi
}
force_merge() {
[ "$FORCE_MERGE" != "true" ] && return
echo "Force merge calistiriliyor..."
run_curl "${CURL_OPTS[@]}" -X POST "$BASE_URL/$INDEX/_forcemerge?only_expunge_deletes=true&pretty" \
| tee forcemerge_result.json
echo ""
}
# ---------------------------------------------------------------------------
# Islem
# ---------------------------------------------------------------------------
open_write
if [ -n "$FIELDS" ]; then
SCRIPT=$(build_field_script "$FIELDS")
run_curl "${CURL_OPTS[@]}" -X POST "$BASE_URL/$INDEX/_update_by_query?conflicts=proceed&wait_for_completion=true" \
-H 'Content-Type: application/json' \
-d "{\"script\":{\"source\":\"$SCRIPT\",\"lang\":\"painless\"},\"query\":$QUERY}" \
| tee update_result.json
else
run_curl "${CURL_OPTS[@]}" -X POST "$BASE_URL/$INDEX/_delete_by_query?conflicts=proceed&wait_for_completion=true" \
-H 'Content-Type: application/json' -d "{\"query\":$QUERY}" \
| tee delete_result.json
fi
echo ""
force_merge
restore_write
# Ipucu komutu, calisma sirasinda kullanilan curl parametreleriyle ayni
# olacak sekilde uretilir (auth varsa -u, https ise -k).
HINT_AUTH=""
HINT_K=""
[ -n "$ES_USER" ] && HINT_AUTH="-u \"$ES_USER:PAROLA\" "
[ "$ES_PROTO" == "https" ] && HINT_K="-k "
echo "===================================================================="
echo "Islem tamamlandi."
echo "Not: Buyuk indexlerde disk alaninin hemen geri bosalmamasi normaldir."
echo "Index boyutunu kontrol etmek icin:"
echo " curl -s ${HINT_AUTH}${HINT_K}-X GET \"$BASE_URL/$INDEX/_stats/store?pretty\" | jq -r '._all.primaries.store.size_in_bytes'"
echo "===================================================================="
8) Çalıştırma
vi es_cleanup.sh # AYAR BÖLÜMÜNÜ doldurun
chmod +x es_cleanup.sh
./es_cleanup.sh
Örnek Ayarlar
Belirli bir proxy'nin, belirli tarih aralığındaki body alanlarını sil (data stream backing index üzerinde):
INDEX=".ds-apinizer-log-apiproxy-qa8-2026.07.09-000025"
FIELDS="tba,tcb"
FIELD_MODE="remove"
DELETE_DOCS="false"
START_TS="2026-07-09T13:10:00.600Z"
END_TS="2026-07-09T14:13:00.600Z"
PROXY_FIELD="apn"
PROXY_VALUE="testm"
Index'teki tüm dökümanların body alanlarını sil (filtresiz):
INDEX="apinizer_api_traffic_v2"
FIELDS="fcrb,tba,fbarb,tcb"
DELETE_DOCS="false"
START_TS=""
END_TS=""
PROXY_VALUE=""
Belirli tarih aralığındaki dökümanları tamamen sil:
INDEX="apinizer_api_traffic_v2"
FIELDS=""
DELETE_DOCS="true"
START_TS="2025-01-01T00:00:00.000Z"
END_TS="2025-02-01T00:00:00.000Z"
PROXY_VALUE=""
9) Örnek Çalışma Çıktısı
Script önce yapılacak işlemin özetini ve etkilenecek döküman sayısını gösterir:
====================================================================
YAPILACAK ISLEM
====================================================================
Sunucu : https://10.10.10.10:9200
Kimlik : elastic
Index : apinizer_api_traffic_v2
Islem : ALANLAR _source'TAN KOMPLE SILINECEK
Alanlar : fcrb,tba,fbarb,tcb
Kapsam :
proxy : apn = MyProxy
zaman : 2025-01-01T00:00:00.000Z -> 2025-02-01T00:00:00.000Z
Force merge : true
====================================================================
Etkilenecek dokuman sayisi kontrol ediliyor...
>> curl -s -u elastic:**** -k -X POST https://10.10.10.10:9200/apinizer_api_traffic_v2/_count ...
Etkilenecek dokuman sayisi: 4210
Devam etmek icin 'yes' yazin: yes
>> curl -s -u elastic:**** -k -X GET https://10.10.10.10:9200/apinizer_api_traffic_v2/_settings
Index read-only, write aciliyor...
>> curl -s -u elastic:**** -k -X POST https://10.10.10.10:9200/apinizer_api_traffic_v2/_update_by_query?...
{"took":1482,"timed_out":false,"total":2294,"updated":2294,"deleted":0,"batches":3,"version_conflicts":0,"noops":0,...,"failures":[]}
Force merge calistiriliyor...
{
"_shards" : {
"total" : 1,
"successful" : 1,
"failed" : 0
}
}
Index tekrar read-only olarak ayarlaniyor...
====================================================================
Islem tamamlandi.
====================================================================
DRY_RUN="true" ile çalıştırıldığında hiçbir değişiklik yapılmaz, yalnızca plan gösterilir:
DRY_RUN - calistirilacak sorgu:
{"bool":{"filter":[{"term":{"apn":"MyProxy"}},{"range":{"@timestamp":{"gte":"2025-01-01T00:00:00.000Z","lte":"2025-02-01T00:00:00.000Z"}}}]}}
DRY_RUN - calistirilacak painless script:
if (ctx._source.containsKey('fcrb')) { ctx._source.remove('fcrb'); } if (ctx._source.containsKey('tba')) { ctx._source.remove('tba'); } ...
DRY_RUN aktif oldugundan hicbir degisiklik yapilmadi.
Çıktının Yorumlanması
total— sorguyla eşleşen döküman sayısıupdated/deleted— gerçekten güncellenen / silinen döküman sayısınoops— değişiklik gerekmediği için dokunulmayan döküman sayısı (alanlar zaten temizlenmişse beklenen değerdir)version_conflicts—conflicts=proceedsayesinde işlem durmaz; sıfırdan büyükse eşzamanlı yazma olmuşturfailures— boş dizi olmalıdır; dolu ise işlem kısmen başarısızdır_shards.failed— force merge sonucunda0olmalıdır
10) Doğrulama
İşlem sonrası index boyutu kontrol edilir:
curl -s -u "elastic:PAROLA" -k -X GET "https://ES_HOST:ES_PORT/INDEX/_stats/store?pretty" \
| jq -r '._all.primaries.store.size_in_bytes'
Büyük index'lerde disk alanının hemen geri boşalmaması normaldir. Force merge yüksek I/O maliyeti oluşturduğundan, işlemlerin iş yükünün düşük olduğu saatlerde çalıştırılması önerilir.
Script update_result.json, delete_result.json ve forcemerge_result.json çıktı dosyalarını çalıştığı dizinde oluşturur.