{"index.json":{"schemaVersion":2,"app":"DBAtlas","updated":"2026-07-04","engines":"engines.json","rosetta":["rosetta/sessions.json","rosetta/storage.json","rosetta/performance.json","rosetta/backup.json","rosetta/security.json","rosetta/maintenance.json","rosetta/schema.json","rosetta/replication.json","rosetta/connect.json","rosetta/objects.json","rosetta/datamove.json","rosetta/monitoring.json","rosetta/automation.json","rosetta/lifecycle.json","rosetta/migration.json","rosetta/tuning.json","rosetta/tuning-adv.json","rosetta/advanced-features.json","rosetta/sql-syntax.json"],"cloud":["cloud/cloud-ops-1.json","cloud/cloud-ops-2.json"],"guide":{"bestPractices":["guide/best-practices.json","guide/best-practices-2.json","guide/best-practices-3.json","guide/best-practices-4.json"],"glossary":["guide/glossary.json","guide/glossary-2.json","guide/glossary-3.json"]},"rosettaOverlays":["rosetta/overlay-elasticsearch.json"],"types":"types/types-functions.json","errors":["errors/oracle.json","errors/postgres.json","errors/mysql.json","errors/mssql.json","errors/mongodb.json","errors/redis.json","errors/elasticsearch.json","errors/oracle-more.json","errors/postgres-more.json","errors/mysql-more.json","errors/mssql-more.json","errors/mongodb-more.json","errors/redis-more.json","errors/elasticsearch-more.json","errors/oracle-more2.json","errors/postgres-more2.json","errors/mysql-more2.json","errors/mssql-more2.json","errors/mongodb-more2.json","errors/redis-more2.json","errors/elasticsearch-more2.json","errors/oracle-more3.json","errors/postgres-more3.json","errors/mysql-more3.json","errors/mssql-more3.json","errors/mongodb-more3.json","errors/redis-more3.json","errors/elasticsearch-more3.json","errors/oracle-more4.json","errors/postgres-more4.json","errors/mysql-more4.json","errors/mssql-more4.json","errors/mongodb-more4.json","errors/redis-more4.json","errors/elasticsearch-more4.json"],"health":["health/oracle.json","health/postgres.json","health/mysql.json","health/mssql.json","health/mongodb.json","health/redis.json","health/elasticsearch.json"],"recipes":["recipes/oracle.json","recipes/oracle-ha.json","recipes/oracle-ops.json","recipes/postgres.json","recipes/postgres-ha.json","recipes/postgres-ops.json","recipes/mysql.json","recipes/mysql-ext.json","recipes/mssql.json","recipes/mssql-ext.json","recipes/mongodb.json","recipes/mongodb-ext.json","recipes/redis.json","recipes/redis-ext.json","recipes/elasticsearch.json","recipes/elasticsearch-ext.json"],"playbooks":["playbooks/playbooks.json","playbooks/hadr.json","playbooks/security.json","playbooks/cloud.json","playbooks/automation.json"],"solver":["solver/slow-query.json","solver/deadlock.json","solver/disk-full.json","solver/connection-storm.json","solver/replication-lag.json","solver/ora-01555.json","solver/backup-restore.json","solver/upgrade-wizard.json","solver/migration-wizard.json","solver/high-cpu.json","solver/memory-pressure.json","solver/install-setup.json","solver/corruption-recovery.json","solver/failover-drill.json","solver/security-incident.json","solver/audit-setup.json","solver/decide-ha.json","solver/decide-isolation.json","solver/decide-sqlnosql.json","solver/decide-shard-replica.json","solver/decide-backup.json","solver/decide-index.json","solver/decide-partition.json","solver/decide-pooling.json","solver/decide-cache.json","solver/decide-datatype.json","solver/decide-capacity.json","solver/slow-write.json","solver/io-bottleneck.json","solver/undo-temp-pressure.json","solver/long-transaction.json","solver/plan-regression.json","solver/replica-resync.json","solver/cache-hit-low.json","solver/arch-oltp.json","solver/arch-dwh.json","solver/arch-microservice.json","solver/arch-eventdriven.json","solver/arch-multiregion.json","solver/arch-highscale.json"],"reference":{"params":["reference/params-oracle.json","reference/params-postgres.json","reference/params-mysql.json","reference/params-mssql.json","reference/params-mongodb.json","reference/params-redis.json","reference/params-elasticsearch.json"],"waits":["reference/waits-oracle.json","reference/waits-postgres.json","reference/waits-mysql.json","reference/waits-mssql.json","reference/waits-mongodb.json","reference/waits-redis.json","reference/waits-elasticsearch.json"],"alerts":["reference/alerts-oracle.json","reference/alerts-postgres.json","reference/alerts-mysql.json","reference/alerts-mssql.json","reference/alerts-mongodb.json","reference/alerts-redis.json","reference/alerts-elasticsearch.json"]},"install":"install/index.json"},"engines.json":{"schemaVersion":1,"updated":"2026-07-03","engines":[{"id":"oracle","name":"Oracle","full":"Oracle Database","color":"#C74634","family":"sql","cli":"sqlplus","docs":"https://docs.oracle.com/en/database/"},{"id":"postgres","name":"PostgreSQL","full":"PostgreSQL","color":"#3461B5","family":"sql","cli":"psql","docs":"https://www.postgresql.org/docs/"},{"id":"mysql","name":"MySQL","full":"MySQL / MariaDB","color":"#00758F","family":"sql","cli":"mysql","docs":"https://dev.mysql.com/doc/"},{"id":"mssql","name":"SQL Server","full":"Microsoft SQL Server","color":"#6E3FC4","family":"sql","cli":"sqlcmd","docs":"https://learn.microsoft.com/en-us/sql/"},{"id":"mongodb","name":"MongoDB","full":"MongoDB","color":"#2E7D32","family":"document","cli":"mongosh","docs":"https://www.mongodb.com/docs/"},{"id":"redis","name":"Redis","full":"Redis","color":"#B45309","family":"keyvalue","cli":"redis-cli","docs":"https://redis.io/docs/"},{"id":"elasticsearch","name":"Elasticsearch","full":"Elasticsearch","color":"#BE2A6E","family":"search","cli":"curl / Kibana","docs":"https://www.elastic.co/guide/"}]},"rosetta/sessions.json":{"category":"Oturumlar & Aktivite","categoryId":"sessions","order":1,"concepts":[{"id":"active-sessions","title":"Aktif oturumları / çalışan sorguları göster","aliases":["active sessions","running queries","who is connected","current activity","aktif oturum","calisan sorgu","kim bagli","processlist","current op"],"engines":{"oracle":{"command":"SELECT sid, serial#, username, status, sql_id, machine, program\nFROM v$session\nWHERE type = 'USER' AND status = 'ACTIVE';","note":"v$session anlık aktif oturumları verir. Tam SQL metni için v$sql ile sql_id üzerinden join yapın.","danger":"safe"},"postgres":{"command":"SELECT pid, usename, state, wait_event_type, query\nFROM pg_stat_activity\nWHERE state <> 'idle';","note":"state = 'active' o an sorgu çalıştıranları gösterir. backend_start / query_start ile süre hesaplanır.","danger":"safe"},"mysql":{"command":"SELECT id, user, host, db, command, time, state, info\nFROM information_schema.processlist\nWHERE command <> 'Sleep';\n-- Kısa yol: SHOW FULL PROCESSLIST;","note":"MySQL 8 / MariaDB'de performance_schema.processlist daha az lock tutar.","danger":"safe"},"mssql":{"command":"SELECT r.session_id, s.login_name, r.status, r.command,\n       r.cpu_time, r.total_elapsed_time, t.text AS sql_text\nFROM sys.dm_exec_requests r\nJOIN sys.dm_exec_sessions s ON r.session_id = s.session_id\nCROSS APPLY sys.dm_exec_sql_text(r.sql_handle) t\nWHERE s.is_user_process = 1;","note":"Hızlı bakış için: EXEC sp_who2 'active';","danger":"safe"},"mongodb":{"command":"db.currentOp({ \"active\": true })","note":"Uzun süren işlemleri süzmek için: db.currentOp({ active: true, secs_running: { $gt: 5 } })","danger":"safe"},"redis":{"command":"CLIENT LIST\n# Özet için: INFO clients","note":"Redis tek thread'li olduğundan 'çalışan sorgu' yerine bağlı istemciler listelenir. Yavaş komutlar için SLOWLOG GET.","danger":"safe"}}},{"id":"blocking-sessions","title":"Bloklayan / lock bekleyen oturumları bul","aliases":["blocking","locks","lock wait","deadlock kaynagi","bloklayan oturum","kilit bekleme","who is blocking","kim blokluyor","blokluyor","kilitleyen","beni bekleten"],"engines":{"oracle":{"command":"SELECT blocking_session, sid, serial#, username,\n       sql_id, seconds_in_wait, event\nFROM v$session\nWHERE blocking_session IS NOT NULL;","note":"blocking_session dolu olan oturum, blocking_session değerindeki SID tarafından bloklanıyordur.","danger":"safe"},"postgres":{"command":"SELECT pid, usename, pg_blocking_pids(pid) AS blocked_by,\n       wait_event, query\nFROM pg_stat_activity\nWHERE cardinality(pg_blocking_pids(pid)) > 0;","note":"blocked_by dizisi, bu pid'i bloklayan PID'leri verir.","danger":"safe"},"mysql":{"command":"SELECT * FROM sys.innodb_lock_waits\\G\n-- MySQL 8: SELECT * FROM performance_schema.data_lock_waits;","note":"sys şeması, bekleyen ve bloklayan trx_id / thread'i okunur biçimde verir.","danger":"safe"},"mssql":{"command":"SELECT r.session_id, r.blocking_session_id,\n       r.wait_type, r.wait_time, r.wait_resource\nFROM sys.dm_exec_requests r\nWHERE r.blocking_session_id <> 0;","note":"blocking_session_id <> 0 olan istekler bloklanmıştır. Zincir için özyinelemeli sorgu kurulabilir.","danger":"safe"},"mongodb":{"command":"db.currentOp({ \"waitingForLock\": true })","note":"WiredTiger belge/koleksiyon düzeyinde kilitler. Uzun işlemleri killOp ile sonlandırabilirsiniz.","danger":"safe"},"redis":{"command":"# Uygulanamaz: Redis komutları tek tek atomik çalışır, satır kilidi yoktur.\n# En yakın teşhis: SLOWLOG GET 10","note":"Bloklanma genelde uzun süren tek bir komuttan (ör. KEYS *, büyük SORT) kaynaklanır; SLOWLOG bunları gösterir.","danger":"safe"}}},{"id":"kill-session","title":"Bir oturumu / sorguyu sonlandır (kill)","aliases":["kill session","terminate","cancel query","oturum sonlandir","sorguyu iptal et","kill query","killop"],"engines":{"oracle":{"command":"ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE;\n-- Yalnız çalışan sorguyu kesmek için (18c+):\n-- ALTER SYSTEM CANCEL SQL 'sid,serial#';","note":"sid ve serial# değerlerini v$session'dan alın. IMMEDIATE, rollback'i hemen başlatır.","danger":"danger"},"postgres":{"command":"-- Sadece çalışan sorguyu iptal et (oturum kalır):\nSELECT pg_cancel_backend(pid);\n-- Oturumu tamamen kapat:\nSELECT pg_terminate_backend(pid);","note":"Önce pg_cancel_backend deneyin; işe yaramazsa pg_terminate_backend kullanın.","danger":"danger"},"mysql":{"command":"-- Sadece sorguyu kes:\nKILL QUERY <id>;\n-- Bağlantıyı tamamen kapat:\nKILL CONNECTION <id>;","note":"<id> değeri processlist'teki Id sütunudur.","danger":"danger"},"mssql":{"command":"KILL <session_id>;\n-- Geri alma ilerlemesini görmek için:\n-- KILL <session_id> WITH STATUSONLY;","note":"KILL, açık transaction'ı geri alır; büyük transaction'larda rollback uzun sürebilir.","danger":"danger"},"mongodb":{"command":"db.killOp(<opid>)","note":"opid değerini db.currentOp() çıktısındaki opid alanından alın.","danger":"danger"},"redis":{"command":"CLIENT KILL ID <client-id>\n# veya adrese göre: CLIENT KILL ADDR 10.0.0.5:6379","note":"client-id için CLIENT LIST kullanın. Çalışmakta olan tek bir komut yarıda kesilemez (Lua betiği hariç: SCRIPT KILL); bitmesi beklenir. BLPOP/XREAD BLOCK gibi bloklayıcı bir komutta bekleyen istemciyi bağlantısını kesmeden serbest bırakmak için CLIENT UNBLOCK <client-id> [TIMEOUT|ERROR] kullanılır. CLIENT UNPAUSE ise yalnızca CLIENT PAUSE ile duraklatılmış istemcileri sürdürür.","danger":"caution"}}},{"id":"connection-count","title":"Bağlantı sayısı ve bağlantı limitini gör","aliases":["connections","max connections","connection limit","baglanti sayisi","kac baglanti","connection pool dolu mu"],"engines":{"oracle":{"command":"SELECT COUNT(*) AS current_sessions FROM v$session WHERE type = 'USER';\nSELECT name, value FROM v$parameter WHERE name IN ('processes','sessions');","note":"Limit processes/sessions parametreleridir. Doluluk için resource_limit view'ına de bakılabilir.","danger":"safe"},"postgres":{"command":"SELECT count(*) FROM pg_stat_activity WHERE backend_type = 'client backend';\nSHOW max_connections;","note":"pg_stat_activity arka plan süreçlerini de içerdiği için yalnızca istemci bağlantıları (backend_type = 'client backend') sayılır. superuser_reserved_connections kadar bağlantı adminlere ayrılır.","danger":"safe"},"mysql":{"command":"SHOW STATUS LIKE 'Threads_connected';\nSHOW VARIABLES LIKE 'max_connections';","note":"Max_used_connections durumu, tepe noktasını gösterir.","danger":"safe"},"mssql":{"command":"SELECT COUNT(*) FROM sys.dm_exec_sessions WHERE is_user_process = 1;\nSELECT @@MAX_CONNECTIONS AS configured_max;","note":"@@MAX_CONNECTIONS teorik üst sınırdır; pratik sınır bellek ve worker thread'lere bağlıdır.","danger":"safe"},"mongodb":{"command":"db.serverStatus().connections","note":"current, available ve totalCreated alanlarını verir. Limit için net.maxIncomingConnections ayarı.","danger":"safe"},"redis":{"command":"INFO clients\nCONFIG GET maxclients","note":"connected_clients anlık, maxclients yapılandırılmış üst sınırdır (varsayılan 10000).","danger":"safe"}}}]},"rosetta/storage.json":{"category":"Alan & Depolama","categoryId":"storage","order":2,"concepts":[{"id":"database-size","title":"Veritabanı toplam boyutunu göster","aliases":["database size","db size","veritabani boyutu","ne kadar yer kapliyor","disk usage","total size"],"engines":{"oracle":{"command":"SELECT ROUND(SUM(bytes)/1024/1024/1024, 2) AS total_gb\nFROM dba_data_files;","note":"Yalnız kullanılan segmentler için dba_segments toplamına bakın. TEMP için dba_temp_files ekleyin.","danger":"safe"},"postgres":{"command":"SELECT pg_size_pretty(pg_database_size(current_database()));","note":"Tüm veritabanları için: SELECT datname, pg_size_pretty(pg_database_size(datname)) FROM pg_database ORDER BY 2 DESC;","danger":"safe"},"mysql":{"command":"SELECT table_schema AS db,\n       ROUND(SUM(data_length + index_length)/1024/1024, 1) AS mb\nFROM information_schema.tables\nGROUP BY table_schema\nORDER BY mb DESC;","note":"InnoDB için bu değer tahminidir; kesin dosya boyutu için OS düzeyinde ibdata/dosyalara bakın.","danger":"safe"},"mssql":{"command":"EXEC sp_spaceused;\n-- Tüm veritabanları:\nSELECT DB_NAME(database_id) AS db,\n       CAST(SUM(size) * 8.0 / 1024 AS DECIMAL(10,1)) AS mb\nFROM sys.master_files\nGROUP BY database_id;","note":"size sütunu 8 KB sayfa cinsindedir; * 8 / 1024 ile MB'ye çevrilir.","danger":"safe"},"mongodb":{"command":"db.stats(1024*1024)\n// dataSize, storageSize, indexSize alanlarını MB olarak verir","note":"storageSize sıkıştırılmış disk boyutu, dataSize sıkıştırılmamış mantıksal boyuttur.","danger":"safe"},"redis":{"command":"INFO memory\n# used_memory_human satırı bellekteki toplam boyutu verir\nDBSIZE  # anahtar sayısı","note":"Redis bellek temellidir; 'boyut' RAM kullanımıdır. RDB/AOF dosya boyutu diskteki kalıcı hâldir.","danger":"safe"}}},{"id":"largest-tables","title":"En büyük tabloları / koleksiyonları listele","aliases":["largest tables","biggest tables","top tables by size","en buyuk tablo","yer kaplayan tablolar","bigkeys"],"engines":{"oracle":{"command":"SELECT segment_name, segment_type,\n       ROUND(bytes/1024/1024, 1) AS mb\nFROM dba_segments\nWHERE segment_type IN ('TABLE','TABLE PARTITION')\nORDER BY bytes DESC\nFETCH FIRST 10 ROWS ONLY;","note":"Index'leri de görmek için segment_type filtresini kaldırın.","danger":"safe"},"postgres":{"command":"SELECT relname AS table,\n       pg_size_pretty(pg_total_relation_size(relid)) AS total\nFROM pg_catalog.pg_statio_user_tables\nORDER BY pg_total_relation_size(relid) DESC\nLIMIT 10;","note":"pg_total_relation_size tablo + index + TOAST toplamıdır; sadece tablo için pg_relation_size.","danger":"safe"},"mysql":{"command":"SELECT table_name,\n       ROUND((data_length + index_length)/1024/1024, 1) AS mb\nFROM information_schema.tables\nWHERE table_schema = DATABASE()\nORDER BY (data_length + index_length) DESC\nLIMIT 10;","note":"Belirli bir şema için WHERE table_schema = 'ad' yazın.","danger":"safe"},"mssql":{"command":"SELECT TOP 10 OBJECT_NAME(object_id) AS table_name,\n       SUM(reserved_page_count) * 8 / 1024 AS mb\nFROM sys.dm_db_partition_stats\nGROUP BY object_id\nORDER BY mb DESC;","note":"reserved_page_count ayrılan tüm sayfaları (veri + index) kapsar.","danger":"safe"},"mongodb":{"command":"db.getCollectionNames()\n  .map(c => ({ name: c, mb: +(db[c].stats().storageSize/1048576).toFixed(1) }))\n  .sort((a, b) => b.mb - a.mb)\n  .slice(0, 10)","note":"storageSize sıkıştırılmış disk boyutudur. Büyük koleksiyonlarda stats() maliyeti düşüktür.","danger":"safe"},"redis":{"command":"redis-cli --bigkeys\n# Bellek (bayt) ölçütüyle sıralama için: redis-cli --memkeys","note":"İkisi de tüm keyspace'i SCAN ile tarar (sunucuyu bloklamaz ama ek yük getirir); fark ölçüttedir: --bigkeys tür başına eleman sayısı/uzunluğa göre, --memkeys MEMORY USAGE ile bellek tüketimine göre en büyük anahtarları raporlar. Tek anahtar için MEMORY USAGE <key> kullanılır.","danger":"caution"}}},{"id":"free-space","title":"Boş alan / doluluk oranını kontrol et","aliases":["free space","disk full","bos alan","doluluk","space left","tablespace usage","disk doldu"],"engines":{"oracle":{"command":"SELECT df.tablespace_name,\n       ROUND(SUM(df.bytes)/1024/1024) AS total_mb,\n       ROUND(NVL(fs.free, 0)/1024/1024) AS free_mb,\n       ROUND((1 - NVL(fs.free,0)/SUM(df.bytes)) * 100, 1) AS pct_used\nFROM dba_data_files df\nLEFT JOIN (SELECT tablespace_name, SUM(bytes) free\n           FROM dba_free_space GROUP BY tablespace_name) fs\n  ON df.tablespace_name = fs.tablespace_name\nGROUP BY df.tablespace_name, fs.free;","note":"AUTOEXTEND açık dosyalarda gerçek sınır maxbytes'tır; MAXSIZE için dba_data_files.maxbytes'a bakın.","danger":"safe"},"postgres":{"command":"-- Data file doluluğu OS düzeyindedir (df -h). DB içinden tablespace boyutları:\nSELECT spcname, pg_size_pretty(pg_tablespace_size(spcname))\nFROM pg_tablespace;","note":"PostgreSQL disk boş alanını OS'ten okur; kritik eşik için işletim sistemi izlemesi (df) şarttır.","danger":"safe"},"mysql":{"command":"SELECT table_schema,\n       ROUND(SUM(data_free)/1024/1024, 1) AS reclaimable_mb\nFROM information_schema.tables\nGROUP BY table_schema;","note":"data_free, tablo içinde geri kazanılabilir (parçalanmış) alandır; disk boş alanı OS düzeyindedir.","danger":"safe"},"mssql":{"command":"SELECT name AS file_name,\n       size/128.0 AS size_mb,\n       size/128.0 - CAST(FILEPROPERTY(name,'SpaceUsed') AS int)/128.0 AS free_mb\nFROM sys.database_files;","note":"SpaceUsed sayfa cinsindendir; 128 ile bölünce MB elde edilir (8 KB sayfa).","danger":"safe"},"mongodb":{"command":"var s = db.stats();\n({ fsTotalGB: +(s.fsTotalSize/1073741824).toFixed(1),\n   fsUsedGB:  +(s.fsUsedSize/1073741824).toFixed(1) })","note":"fsTotalSize / fsUsedSize WiredTiger'da diskin OS düzeyindeki toplam ve kullanılan boyutunu verir.","danger":"safe"},"redis":{"command":"INFO memory\nCONFIG GET maxmemory\n# Doluluk = used_memory / maxmemory","note":"maxmemory 0 ise sınır yoktur ve RAM dolunca OS OOM devreye girer. maxmemory-policy eviction davranışını belirler.","danger":"safe"}}},{"id":"row-count","title":"Satır / belge sayısını (hızlı) öğren","aliases":["row count","count rows","satir sayisi","kac kayit","document count","how many rows"],"engines":{"oracle":{"command":"-- İstatistik temelli (hızlı, tahmini):\nSELECT num_rows FROM dba_tables WHERE table_name = 'MUSTERI';\n-- Kesin: SELECT COUNT(*) FROM musteri;","note":"num_rows son ANALYZE/DBMS_STATS anına aittir; kesinlik için COUNT(*).","danger":"safe"},"postgres":{"command":"-- Tahmini (anında):\nSELECT reltuples::bigint FROM pg_class WHERE relname = 'musteri';\n-- Kesin: SELECT count(*) FROM musteri;","note":"reltuples son ANALYZE/VACUUM'a göre tahminidir; büyük tablolarda tam COUNT pahalıdır.","danger":"safe"},"mysql":{"command":"-- Tahmini (InnoDB):\nSELECT table_rows FROM information_schema.tables\nWHERE table_name = 'musteri';\n-- Kesin: SELECT COUNT(*) FROM musteri;","note":"InnoDB'de table_rows tahminidir ve %50'ye kadar sapabilir.","danger":"safe"},"mssql":{"command":"SELECT SUM(row_count) AS rows\nFROM sys.dm_db_partition_stats\nWHERE object_id = OBJECT_ID('dbo.musteri')\n  AND index_id IN (0, 1);","note":"index_id 0 (heap) veya 1 (clustered) satır sayısını verir; COUNT(*) taramadan çok hızlıdır.","danger":"safe"},"mongodb":{"command":"// Hızlı (metadata'dan):\ndb.musteri.estimatedDocumentCount()\n// Kesin (filtreli sayabilir): db.musteri.countDocuments({})","note":"estimatedDocumentCount metadata okur (anında); countDocuments gerçek tarama yapar.","danger":"safe"},"redis":{"command":"DBSIZE\n# Belirli desen: kabaca SCAN ile sayılır (KEYS * üretimde kullanmayın)","note":"DBSIZE seçili veritabanındaki toplam anahtar sayısını O(1) verir.","danger":"safe"}}}]},"rosetta/performance.json":{"category":"Performans","categoryId":"performance","order":3,"concepts":[{"id":"top-slow-queries","title":"En yavaş / en maliyetli sorguları bul","aliases":["slow queries","top queries","yavas sorgular","en cok kaynak yiyen","expensive queries","slowlog"],"engines":{"oracle":{"command":"SELECT sql_id,\n       ROUND(elapsed_time/1e6, 1) AS elapsed_sec,\n       executions,\n       ROUND(elapsed_time/1e6/NULLIF(executions,0), 3) AS sec_per_exec,\n       sql_text\nFROM v$sql\nORDER BY elapsed_time DESC\nFETCH FIRST 10 ROWS ONLY;","note":"Geçmiş analiz için AWR: dba_hist_sqlstat. sql_id ile DBMS_XPLAN.DISPLAY_CURSOR planı verir.","danger":"safe"},"postgres":{"command":"SELECT calls,\n       ROUND(total_exec_time::numeric, 1) AS total_ms,\n       ROUND(mean_exec_time::numeric, 2) AS mean_ms,\n       query\nFROM pg_stat_statements\nORDER BY total_exec_time DESC\nLIMIT 10;","note":"pg_stat_statements eklentisi gerekir (shared_preload_libraries). Sıfırlamak için pg_stat_statements_reset().","danger":"safe"},"mysql":{"command":"SELECT digest_text,\n       count_star AS calls,\n       ROUND(sum_timer_wait/1e12, 2) AS total_sec,\n       ROUND(avg_timer_wait/1e9, 2) AS avg_ms\nFROM performance_schema.events_statements_summary_by_digest\nORDER BY sum_timer_wait DESC\nLIMIT 10;","note":"Alternatif: slow_query_log = ON ve long_query_time ayarıyla yavaş sorgu logu.","danger":"safe"},"mssql":{"command":"SELECT TOP 10\n       qs.execution_count,\n       qs.total_elapsed_time/1000 AS total_ms,\n       qs.total_elapsed_time/qs.execution_count/1000 AS avg_ms,\n       SUBSTRING(t.text, 1, 200) AS sql_text\nFROM sys.dm_exec_query_stats qs\nCROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) t\nORDER BY qs.total_elapsed_time DESC;","note":"Query Store açıksa daha zengin tarihsel analiz için sys.query_store_runtime_stats kullanın.","danger":"safe"},"mongodb":{"command":"// Profiler'ı 100ms üstü için aç:\ndb.setProfilingLevel(1, { slowms: 100 })\n// Sonra en yavaşları oku:\ndb.system.profile.find().sort({ millis: -1 }).limit(10)","note":"Profiler yazma yükü getirir; teşhis sonrası db.setProfilingLevel(0) ile kapatın.","danger":"caution"},"redis":{"command":"SLOWLOG GET 10\n# Eşiği ayarla (mikrosaniye): CONFIG SET slowlog-log-slower-than 10000","note":"slowlog-log-slower-than mikrosaniye cinsindendir (10000 = 10 ms). SLOWLOG RESET ile temizlenir.","danger":"safe"}}},{"id":"explain-plan","title":"Bir sorgunun çalışma planını (EXPLAIN) al","aliases":["explain","execution plan","query plan","calisma plani","aciklama plani","explain analyze","why slow"],"engines":{"oracle":{"command":"EXPLAIN PLAN FOR\nSELECT * FROM musteri WHERE il = 'Ankara';\nSELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);\n-- Gerçek çalışmış plan için:\n-- SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('&sql_id', NULL, 'ALLSTATS LAST'));","note":"EXPLAIN PLAN tahmini planı verir; gerçek satır sayıları için DISPLAY_CURSOR + STATISTICS_LEVEL=ALL.","danger":"safe"},"postgres":{"command":"EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)\nSELECT * FROM musteri WHERE il = 'Ankara';","note":"ANALYZE sorguyu GERÇEKTEN çalıştırır (INSERT/UPDATE/DELETE'te dikkat; transaction içinde ROLLBACK ile deneyin).","danger":"caution"},"mysql":{"command":"EXPLAIN ANALYZE\nSELECT * FROM musteri WHERE il = 'Ankara';\n-- Yalnız tahmin (çalıştırmaz): EXPLAIN FORMAT=JSON SELECT ...;","note":"EXPLAIN ANALYZE (MySQL 8.0.18+) sorguyu çalıştırır; FORMAT=JSON çalıştırmadan detay verir.","danger":"caution"},"mssql":{"command":"SET STATISTICS PROFILE ON;\nSELECT * FROM dbo.musteri WHERE il = 'Ankara';\nSET STATISTICS PROFILE OFF;\n-- Yalnız tahmini plan (çalıştırmaz):\n-- SET SHOWPLAN_XML ON;","note":"SSMS'te 'Include Actual Execution Plan' (Ctrl+M) görsel planı verir.","danger":"caution"},"mongodb":{"command":"db.musteri.find({ il: \"Ankara\" }).explain(\"executionStats\")","note":"executionStats gerçek dönen belge sayısını ve index kullanımını (IXSCAN vs COLLSCAN) gösterir.","danger":"safe"},"redis":{"command":"# Uygulanamaz: Redis'te sorgu planlayıcı yoktur.\n# Her komutun karmaşıklığı belgelidir (ör. GET O(1), SORT O(N+M*log(M))).","note":"Performans, komut karmaşıklığından ve anahtar/veri yapısı boyutundan gelir; SLOWLOG ile ölçün.","danger":"safe"}}},{"id":"unused-indexes","title":"Kullanılmayan index'leri tespit et","aliases":["unused indexes","kullanilmayan indeks","gereksiz indeks","index usage","drop index candidate"],"engines":{"oracle":{"command":"-- İzlemeyi başlat:\nALTER INDEX musteri_il_idx MONITORING USAGE;\n-- Bir süre sonra kontrol et (12c+, tüm şemalar):\nSELECT owner, index_name, used FROM dba_object_usage;","note":"USED = NO ise index izleme süresince kullanılmamıştır. İzlemeyi NOMONITORING USAGE ile kapatın. Eski v$object_usage yalnızca oturum kullanıcısının index'lerini gösterir ve 12c'den beri kullanımdan kaldırılmıştır (deprecated). 12.2+ sürümlerde index kullanımı DBA_INDEX_USAGE ile otomatik izlenir.","danger":"safe"},"postgres":{"command":"SELECT relname AS table, indexrelname AS index, idx_scan\nFROM pg_stat_user_indexes\nWHERE idx_scan = 0\nORDER BY relname;","note":"idx_scan = 0 istatistik sıfırlanmasından beri hiç kullanılmadığını gösterir; UNIQUE/PK'leri düşürmeyin.","danger":"safe"},"mysql":{"command":"SELECT * FROM sys.schema_unused_indexes;","note":"performance_schema açık olmalı ve sunucu bir süredir çalışıyor olmalı; UNIQUE constraint'leri hariç tutulur.","danger":"safe"},"mssql":{"command":"SELECT OBJECT_NAME(i.object_id) AS table_name, i.name AS index_name\nFROM sys.indexes i\nLEFT JOIN sys.dm_db_index_usage_stats s\n  ON i.object_id = s.object_id AND i.index_id = s.index_id\n  AND s.database_id = DB_ID()\nWHERE i.type_desc = 'NONCLUSTERED'\n  AND COALESCE(s.user_seeks + s.user_scans + s.user_lookups, 0) = 0;","note":"usage_stats sunucu yeniden başlayınca sıfırlanır; yeterli gözlem penceresi bırakın.","danger":"safe"},"mongodb":{"command":"db.musteri.aggregate([{ $indexStats: {} }])\n// accesses.ops düşük/0 olan indeksler aday","note":"accesses.since alanından beri gelen erişim sayısıdır; _id index'ini silemezsiniz.","danger":"safe"},"redis":{"command":"# Uygulanamaz: Redis çekirdeğinde ikincil indeks yoktur.\n# RediSearch modülü kullanılıyorsa FT.INFO <index> ile istatistiklere bakılır.","note":"Veri modeli anahtar-değer olduğundan geleneksel index kavramı yoktur.","danger":"safe"}}},{"id":"cache-hit-ratio","title":"Önbellek isabet oranını (cache hit) ölç","aliases":["cache hit ratio","buffer cache","onbellek isabet","hit ratio","buffer pool hit"],"engines":{"oracle":{"command":"SELECT metric_name, ROUND(value, 2) AS pct\nFROM v$sysmetric\nWHERE metric_name = 'Buffer Cache Hit Ratio'\n  AND intsize_csec = (SELECT MAX(intsize_csec) FROM v$sysmetric);","note":"Düşük oran her zaman kötü değildir; tek başına değil iş yükü bağlamında yorumlayın.","danger":"safe"},"postgres":{"command":"SELECT ROUND(sum(blks_hit) * 100.0 / NULLIF(sum(blks_hit) + sum(blks_read), 0), 2) AS cache_hit_pct\nFROM pg_stat_database;","note":"Genelde %99+ hedeflenir. Düşükse shared_buffers ve OS önbelleği gözden geçirilir.","danger":"safe"},"mysql":{"command":"SELECT ROUND((1 - (\n    (SELECT variable_value FROM performance_schema.global_status WHERE variable_name='Innodb_buffer_pool_reads') /\n    (SELECT variable_value FROM performance_schema.global_status WHERE variable_name='Innodb_buffer_pool_read_requests')\n  )) * 100, 2) AS buffer_pool_hit_pct;","note":"reads diskten, read_requests toplam okumadır. Düşükse innodb_buffer_pool_size artırılır.","danger":"safe"},"mssql":{"command":"SELECT ROUND(\n  100.0 * (SELECT cntr_value FROM sys.dm_os_performance_counters WHERE counter_name='Buffer cache hit ratio')\n        / NULLIF((SELECT cntr_value FROM sys.dm_os_performance_counters WHERE counter_name='Buffer cache hit ratio base'), 0), 2) AS pct;","note":"Modern SQL Server'da Page Life Expectancy (PLE) daha anlamlı bir bellek baskısı göstergesidir.","danger":"safe"},"mongodb":{"command":"var c = db.serverStatus().wiredTiger.cache;\n({ configuredMB: +(c['maximum bytes configured']/1048576).toFixed(0),\n   inCacheMB:    +(c['bytes currently in the cache']/1048576).toFixed(0),\n   readIntoCache: c['pages read into cache'],\n   evictedPages:  c['unmodified pages evicted'] })","note":"Yüksek 'pages read into cache' ve eviction, WiredTiger cache'in küçük olduğunu işaret eder.","danger":"safe"},"redis":{"command":"INFO stats\n# keyspace_hits / (keyspace_hits + keyspace_misses) = isabet oranı","note":"Sürekli düşük isabet oranı, TTL/eviction ayarlarının veya erişim deseninin gözden geçirilmesi gerektiğini gösterir.","danger":"safe"}}}]},"rosetta/backup.json":{"category":"Yedekleme & Kurtarma","categoryId":"backup","order":4,"concepts":[{"id":"logical-dump","title":"Mantıksal yedek (dump) al","aliases":["backup","dump","export","yedek al","mantiksal yedek","logical backup","pg_dump","mysqldump","mongodump"],"engines":{"oracle":{"command":"expdp system/parola DIRECTORY=dpump_dir \\\n  SCHEMAS=hr DUMPFILE=hr_%U.dmp LOGFILE=hr_exp.log PARALLEL=4","note":"Data Pump kullanılır. DIRECTORY nesnesi önceden CREATE DIRECTORY ile tanımlanmalıdır. Fiziksel yedek için RMAN.","danger":"safe"},"postgres":{"command":"pg_dump -U postgres -h localhost -Fc -f db.dump veritabani\n# -Fc = sıkıştırılmış custom format (pg_restore ile geri yüklenir)","note":"-Fc esnek geri yükleme (seçici tablo/paralel) sağlar. Tüm cluster için pg_dumpall (roller dahil).","danger":"safe"},"mysql":{"command":"mysqldump -u root -p --single-transaction \\\n  --routines --triggers --events veritabani > db.sql","note":"--single-transaction InnoDB'de kilitsiz tutarlı yedek verir. Büyük veri için paralel seçenekler: mydumper/myloader veya MySQL Shell util.dumpInstance()/dumpSchemas() (mysqlpump 8.0.34'te deprecated oldu, 8.4'te kaldırıldı).","danger":"safe"},"mssql":{"command":"BACKUP DATABASE [MyDB]\nTO DISK = N'C:\\yedek\\MyDB_full.bak'\nWITH COMPRESSION, CHECKSUM, INIT;","note":"INIT var olan dosyanın üzerine yazar; eklemek için NOINIT. Log yedeği için BACKUP LOG (FULL recovery modelinde).","danger":"safe"},"mongodb":{"command":"mongodump --uri=\"mongodb://localhost:27017\" \\\n  --archive=db.archive.gz --gzip --db=veritabani","note":"Sharded cluster'da tutarlılık için mongos üzerinden ve dengeleyici (balancer) kapalıyken alın.","danger":"safe"},"redis":{"command":"BGSAVE\n# Arka planda RDB snapshot'ı alır (dump.rdb).\n# Bloklamayan kopya: redis-cli --rdb /yedek/dump.rdb","note":"BGSAVE fork ile arka planda çalışır; SAVE ise sunucuyu bloklar (üretimde kullanmayın). AOF açıksa daha az veri kaybı.","danger":"safe"}}},{"id":"restore-dump","title":"Yedekten geri yükle (restore)","aliases":["restore","import","geri yukle","yedekten don","recover","pg_restore","mongorestore"],"engines":{"oracle":{"command":"impdp system/parola DIRECTORY=dpump_dir \\\n  SCHEMAS=hr DUMPFILE=hr_%U.dmp LOGFILE=hr_imp.log","note":"Farklı şemaya yüklemek için REMAP_SCHEMA, farklı tablespace için REMAP_TABLESPACE.","danger":"danger"},"postgres":{"command":"# custom format:\npg_restore -U postgres -d hedef_db --clean --if-exists db.dump\n# düz SQL: psql -U postgres -d hedef_db -f db.sql","note":"--clean var olan nesneleri düşürür. Paralel geri yükleme için -j <n>.","danger":"danger"},"mysql":{"command":"mysql -u root -p hedef_db < db.sql","note":"Hedef veritabanı önceden CREATE DATABASE ile var olmalıdır. Büyük dosyalarda source komutu tercih edilir.","danger":"danger"},"mssql":{"command":"RESTORE DATABASE [MyDB]\nFROM DISK = N'C:\\yedek\\MyDB_full.bak'\nWITH REPLACE, RECOVERY;","note":"Point-in-time için WITH NORECOVERY ile full geri yükleyip ardından log yedeklerini STOPAT ile uygulayın.","danger":"danger"},"mongodb":{"command":"mongorestore --uri=\"mongodb://localhost:27017\" \\\n  --archive=db.archive.gz --gzip --drop","note":"--drop hedef koleksiyonları geri yüklemeden önce siler. --nsInclude ile seçici geri yükleme.","danger":"danger"},"redis":{"command":"# 1) Redis'i durdur   2) dump.rdb dosyasını 'dir' konumuna kopyala\n# 3) Redis'i başlat (açılışta RDB otomatik yüklenir)\nredis-cli CONFIG GET dir   # hedef dizini öğren","note":"AOF açıksa RDB yerine AOF yüklenir; RDB'den dönmek için appendonly no ile başlatın veya AOF'u yeniden oluşturun.","danger":"danger"}}},{"id":"last-backup-status","title":"Son yedek durumunu / zamanını kontrol et","aliases":["last backup","backup status","son yedek ne zaman","yedek durumu","backup history","rpo"],"engines":{"oracle":{"command":"SELECT session_key, input_type, status,\n       start_time, end_time,\n       output_bytes_display\nFROM v$rman_backup_job_details\nORDER BY start_time DESC\nFETCH FIRST 10 ROWS ONLY;","note":"RMAN geçmişi RMAN> LIST BACKUP SUMMARY ile de görülür.","danger":"safe"},"postgres":{"command":"-- WAL arşivleme sağlığı (fiziksel yedek/PITR için):\nSELECT last_archived_wal, last_archived_time,\n       failed_count, last_failed_time\nFROM pg_stat_archiver;","note":"Mantıksal (pg_dump) yedeklerin kaydı DB içinde tutulmaz; yedek aracının/işin loglarına bakın.","danger":"safe"},"mysql":{"command":"-- Yerleşik yedek kaydı yoktur; yedek aracının loguna bakılır.\n-- Binlog tabanlı PITR penceresi için:\nSHOW BINARY LOGS;","note":"SHOW BINARY LOGS mevcut binlog dosyalarını (PITR penceresini) gösterir; yedek geçmişi araç (Xtrabackup vb.) logundadır.","danger":"safe"},"mssql":{"command":"SELECT database_name,\n       MAX(backup_finish_date) AS last_backup,\n       CASE type WHEN 'D' THEN 'Full' WHEN 'I' THEN 'Diff'\n                 WHEN 'L' THEN 'Log' END AS backup_type\nFROM msdb.dbo.backupset\nGROUP BY database_name, type\nORDER BY database_name;","note":"msdb.dbo.backupset SQL Server'ın yaptığı tüm yedeklerin kaydını tutar.","danger":"safe"},"mongodb":{"command":"// Yerleşik yedek kaydı yoktur. PITR penceresi = oplog süresi:\nrs.printReplicationInfo()  // oplog first/last event zamanları","note":"oplog penceresi, replica set'ten ne kadar geriye PITR yapılabileceğini belirler; yedek geçmişi araç logundadır.","danger":"safe"},"redis":{"command":"INFO persistence\n# rdb_last_save_time (epoch), rdb_last_bgsave_status,\n# aof_last_bgrewrite_status satırlarına bakın","note":"rdb_last_save_time son başarılı RDB anını (Unix epoch) verir; rdb_changes_since_last_save kaç yazmanın yedeksiz olduğunu gösterir.","danger":"safe"}}}]},"rosetta/security.json":{"category":"Kullanıcılar & Yetki","categoryId":"security","order":5,"concepts":[{"id":"list-users","title":"Kullanıcıları / rolleri listele","aliases":["list users","show users","kullanicilari listele","roller","who has access","accounts"],"engines":{"oracle":{"command":"SELECT username, account_status, default_tablespace, created\nFROM dba_users\nORDER BY username;","note":"account_status LOCKED/EXPIRED durumlarını gösterir. Roller için dba_roles.","danger":"safe"},"postgres":{"command":"SELECT rolname, rolsuper, rolcanlogin, rolvaliduntil\nFROM pg_roles\nORDER BY rolname;\n-- Kısa yol (psql): \\du","note":"PostgreSQL'de kullanıcı = LOGIN yetkili roldür; rolcanlogin bunu ayırt eder.","danger":"safe"},"mysql":{"command":"SELECT user, host, account_locked, password_expired\nFROM mysql.user\nORDER BY user;","note":"MySQL'de kimlik user + host çiftidir ('app'@'%' ile 'app'@'localhost' farklıdır).","danger":"safe"},"mssql":{"command":"-- Sunucu login'leri:\nSELECT name, type_desc, is_disabled FROM sys.server_principals\nWHERE type IN ('S','U','G');\n-- Veritabanı kullanıcıları:\nSELECT name, type_desc FROM sys.database_principals\nWHERE type IN ('S','U','G');","note":"Login sunucu düzeyinde, user veritabanı düzeyindedir; ikisi SID ile eşleşir.","danger":"safe"},"mongodb":{"command":"// Geçerli veritabanındaki kullanıcılar:\ndb.getUsers()\n// Tüm sistemdekiler: use admin; db.system.users.find({}, {user:1, db:1, roles:1})","note":"Kullanıcılar hangi veritabanında oluşturulduysa orada tanımlıdır (authenticationDatabase).","danger":"safe"},"redis":{"command":"ACL LIST\n# Sadece isimler: ACL USERS\n# Kendi kimliğin: ACL WHOAMI","note":"Redis 6+ ACL sistemi. Öncesinde tek 'default' kullanıcı ve requirepass vardı.","danger":"safe"}}},{"id":"create-user-grant","title":"Kullanıcı oluştur ve yetki ver (grant)","aliases":["create user","grant","add user","kullanici olustur","yetki ver","izin ver","new user"],"engines":{"oracle":{"command":"CREATE USER app IDENTIFIED BY \"Guclu#Parola1\";\nGRANT CREATE SESSION TO app;\nGRANT SELECT, INSERT, UPDATE ON hr.calisan TO app;","note":"CREATE SESSION olmadan kullanıcı bağlanamaz. Kota için: ALTER USER app QUOTA 100M ON users;","danger":"caution"},"postgres":{"command":"CREATE ROLE app LOGIN PASSWORD 'Guclu#Parola1';\nGRANT CONNECT ON DATABASE veritabani TO app;\nGRANT USAGE ON SCHEMA public TO app;\nGRANT SELECT, INSERT, UPDATE ON ALL TABLES IN SCHEMA public TO app;","note":"Gelecekte oluşturulacak tablolar için: ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO app;","danger":"caution"},"mysql":{"command":"CREATE USER 'app'@'%' IDENTIFIED BY 'Guclu#Parola1';\nGRANT SELECT, INSERT, UPDATE ON veritabani.* TO 'app'@'%';","note":"'%' her host'tan bağlanmaya izin verir; güvenlik için mümkünse belirli IP/host verin. CREATE USER/GRANT anında etkilidir; FLUSH PRIVILEGES yalnızca grant tablolarına doğrudan DML yapıldıysa gerekir.","danger":"caution"},"mssql":{"command":"CREATE LOGIN app WITH PASSWORD = 'Guclu#Parola1';\nUSE veritabani;\nCREATE USER app FOR LOGIN app;\nGRANT SELECT, INSERT, UPDATE ON SCHEMA::dbo TO app;","note":"Login sunucu geneli, user her veritabanında ayrı oluşturulur. Rol için ALTER ROLE db_datareader ADD MEMBER app;","danger":"caution"},"mongodb":{"command":"db.createUser({\n  user: \"app\",\n  pwd: \"Guclu#Parola1\",\n  roles: [ { role: \"readWrite\", db: \"veritabani\" } ]\n})","note":"Kullanıcı hangi db'de oluşturulursa auth db o olur. Yerleşik roller: read, readWrite, dbAdmin, clusterAdmin...","danger":"caution"},"redis":{"command":"ACL SETUSER app on >Guclu#Parola1 ~app:* +@read +@write\n# Kalıcı olması için: aclfile tanımlıysa ACL SAVE, değilse CONFIG REWRITE (kullanıcılar redis.conf'a yazılır)","note":"on = etkin, >parola parola ekler, ~app:* anahtar deseni, +@read/+@write komut kategorileri. Kalıcı hale getirilmezse restart'ta kaybolur: ACL SAVE yalnızca aclfile yapılandırılmışsa çalışır, aksi halde hata verir; bu durumda CONFIG REWRITE kullanılır.","danger":"caution"}}},{"id":"show-privileges","title":"Bir kullanıcının yetkilerini göster","aliases":["show grants","privileges","yetkileri goster","kim neye erisebiliyor","permissions","roles of user"],"engines":{"oracle":{"command":"SELECT privilege FROM dba_sys_privs WHERE grantee = 'APP'\nUNION ALL SELECT granted_role FROM dba_role_privs WHERE grantee = 'APP'\nUNION ALL SELECT privilege||' ON '||owner||'.'||table_name\n          FROM dba_tab_privs WHERE grantee = 'APP';","note":"Grantee büyük harf saklanır. Rol üzerinden gelen dolaylı yetkiler için role_role_privs'i de dolaşın.","danger":"safe"},"postgres":{"command":"SELECT grantee, table_schema, table_name, privilege_type\nFROM information_schema.role_table_grants\nWHERE grantee = 'app';\n-- Rol üyelikleri (doğrudan): \\drg app (PG16+; öncesi \\du app)","note":"Rol üyelikleri (kalıtım) pg_auth_members'ta tutulur; \\du/\\drg yalnızca doğrudan üyelikleri gösterir, dolaylı üyelik için pg_has_role('app', '<rol>', 'MEMBER') kullanın.","danger":"safe"},"mysql":{"command":"SHOW GRANTS FOR 'app'@'%';","note":"Roller (MySQL 8) için önce SET ROLE ALL veya SHOW GRANTS FOR 'app'@'%' USING 'rol_adi';","danger":"safe"},"mssql":{"command":"SELECT dp.name AS principal, p.permission_name,\n       p.state_desc, o.name AS object\nFROM sys.database_permissions p\nJOIN sys.database_principals dp ON p.grantee_principal_id = dp.principal_id\nLEFT JOIN sys.objects o ON p.major_id = o.object_id\nWHERE dp.name = 'app';","note":"Rol üzerinden gelen yetkiler için sys.database_role_members üzerinden üyelikleri de kontrol edin.","danger":"safe"},"mongodb":{"command":"db.getUser(\"app\", { showPrivileges: true, showCredentials: false })","note":"showPrivileges rollerin genişletilmiş (etkin) izinlerini de listeler.","danger":"safe"},"redis":{"command":"ACL GETUSER app","note":"Etkin komutlar, anahtar desenleri (~), pub/sub kanalları (&) ve parola hash'lerini döndürür.","danger":"safe"}}},{"id":"change-password","title":"Kullanıcı şifresini değiştir","aliases":["change password","reset password","sifre degistir","parola sifirla","alter password"],"engines":{"oracle":{"command":"ALTER USER app IDENTIFIED BY \"Yeni#Parola2\";","note":"Kilitli hesabı açmak için: ALTER USER app ACCOUNT UNLOCK; Süresi dolduysa aynı komut sıfırlar.","danger":"caution"},"postgres":{"command":"ALTER ROLE app WITH PASSWORD 'Yeni#Parola2';","note":"Parola loglara düşmesin diye \\password app (psql) meta-komutu şifreyi istemci tarafında hash'ler.","danger":"caution"},"mysql":{"command":"ALTER USER 'app'@'%' IDENTIFIED BY 'Yeni#Parola2';","note":"Doğru host'u seçtiğinizden emin olun; 'app'@'localhost' ayrı bir hesaptır. ALTER USER anında etkilidir; ayrıca FLUSH PRIVILEGES gerekmez.","danger":"caution"},"mssql":{"command":"ALTER LOGIN app WITH PASSWORD = 'Yeni#Parola2';\n-- Kullanıcının kendi şifresi için: OLD_PASSWORD ekleyin","note":"MUST_CHANGE ile ilk girişte değiştirme zorunlu kılınabilir: WITH PASSWORD='...' MUST_CHANGE, CHECK_POLICY=ON.","danger":"caution"},"mongodb":{"command":"db.changeUserPassword(\"app\", \"Yeni#Parola2\")","note":"Kullanıcının auth veritabanına geçtiğinizden emin olun (use veritabani).","danger":"caution"},"redis":{"command":"# Eski parolaları temizleyip yenisini koy:\nACL SETUSER app resetpass >Yeni#Parola2\n# Kalıcılık: aclfile tanımlıysa ACL SAVE, değilse CONFIG REWRITE","note":"resetpass tüm mevcut parolaları siler; > yalnızca ekler. Kalıcılık için aclfile kullanılıyorsa ACL SAVE, kullanıcılar redis.conf içinde tanımlıysa CONFIG REWRITE çalıştırın (ACL SAVE aclfile olmadan hata verir).","danger":"caution"}}}]},"rosetta/maintenance.json":{"category":"Bakım & Yönetim","categoryId":"maintenance","order":6,"concepts":[{"id":"update-statistics","title":"İstatistikleri güncelle (optimizer için)","aliases":["update statistics","analyze","istatistik guncelle","gather stats","optimizer stats","planner icin analiz"],"engines":{"oracle":{"command":"EXEC DBMS_STATS.GATHER_TABLE_STATS('HR', 'CALISAN');\n-- Tüm şema: EXEC DBMS_STATS.GATHER_SCHEMA_STATS('HR');","note":"AUTO görev genelde geceleri toplar; sorun anında elle toplayın. ESTIMATE_PERCENT=>AUTO_SAMPLE_SIZE önerilir.","danger":"safe"},"postgres":{"command":"ANALYZE musteri;\n-- Hem temizlik hem analiz: VACUUM ANALYZE musteri;","note":"Autovacuum bunu otomatik yapar; ani veri yüklemesinden sonra elle ANALYZE isabetli plan sağlar.","danger":"safe"},"mysql":{"command":"ANALYZE TABLE musteri;","note":"InnoDB'de kısa bir read lock alır; büyük tablolarda düşük yoğunlukta çalıştırın.","danger":"safe"},"mssql":{"command":"UPDATE STATISTICS dbo.musteri WITH FULLSCAN;\n-- Tüm veritabanı: EXEC sp_updatestats;","note":"FULLSCAN en doğru ama en maliyetlisidir; büyük tablolarda örnekleme (SAMPLE) tercih edilebilir.","danger":"safe"},"mongodb":{"command":"// Elle istatistik yoktur; planlayıcı çalışma zamanında ölçer.\n// Bayat plan önbelleğini temizlemek için:\ndb.musteri.getPlanCache().clear()","note":"MongoDB maliyet tahmini yerine gerçek deneme (plan yarışı) yapar; manuel istatistik gerekmez.","danger":"safe"},"redis":{"command":"# Uygulanamaz: Redis'te sorgu optimizeri / istatistik yoktur.","note":"Komut karmaşıklığı sabittir; performans veri yapısı seçimine bağlıdır.","danger":"safe"}}},{"id":"rebuild-index","title":"Index'i yeniden oluştur / düzenle (rebuild)","aliases":["rebuild index","reindex","indeks yenile","reorganize","index bakim","defrag index"],"engines":{"oracle":{"command":"ALTER INDEX musteri_il_idx REBUILD ONLINE;","note":"ONLINE tabloyu kilitlemeden yeniden oluşturur (Enterprise Edition). Tablespace taşımak için ... REBUILD TABLESPACE yeni_ts.","danger":"caution"},"postgres":{"command":"REINDEX INDEX CONCURRENTLY musteri_il_idx;\n-- Tüm tablo: REINDEX TABLE CONCURRENTLY musteri;","note":"CONCURRENTLY (PG 12+) tabloyu yazmaya kapamadan yeniden oluşturur; daha yavaş ama güvenlidir.","danger":"caution"},"mysql":{"command":"-- InnoDB indeks + tablo yeniden inşa:\nALTER TABLE musteri ENGINE=InnoDB, ALGORITHM=INPLACE, LOCK=NONE;\n-- Alternatif: OPTIMIZE TABLE musteri;","note":"LOCK=NONE eşzamanlı yazmaya izin verir; her ALTER için INPLACE mümkün olmayabilir.","danger":"caution"},"mssql":{"command":"-- Yüksek parçalanmada yeniden inşa:\nALTER INDEX ALL ON dbo.musteri REBUILD WITH (ONLINE = ON);\n-- Düşük parçalanmada hafif seçenek:\n-- ALTER INDEX ALL ON dbo.musteri REORGANIZE;","note":"Genel eşik: %5-30 parçalanma REORGANIZE, >%30 REBUILD. ONLINE Enterprise özelliğidir.","danger":"caution"},"mongodb":{"command":"db.musteri.reIndex()","note":"Tüm index'leri önplanda yeniden kurar ve koleksiyonu kilitler. 6.0+ sürümlerde yalnızca standalone'da çalışır (replica set üyelerinde izin verilmez); replica set'te tek bir index'i dropIndex + createIndex ile, düğüm düğüm (rolling) yeniden kurun.","danger":"danger"},"redis":{"command":"# Uygulanamaz (çekirdek). RediSearch kullanılıyorsa:\n# FT.ALTER / yeniden oluşturma modül belgelerine göre yapılır.","note":"Anahtar-değer modelinde geleneksel index bakımı yoktur.","danger":"safe"}}},{"id":"reclaim-space","title":"Boş alanı geri kazan (shrink / vacuum / compact)","aliases":["reclaim space","vacuum","shrink","compact","alan geri kazan","sisme temizle","bloat"],"engines":{"oracle":{"command":"ALTER TABLE musteri ENABLE ROW MOVEMENT;\nALTER TABLE musteri SHRINK SPACE;","note":"SHRINK high water mark'ı (HWM) düşürür. Index'leri de küçültmek için SHRINK SPACE CASCADE.","danger":"caution"},"postgres":{"command":"-- Online, kilit hafif (alanı OS'e vermez):\nVACUUM (VERBOSE, ANALYZE) musteri;\n-- Alanı OS'e geri ver (tabloyu kilitler!):\n-- VACUUM FULL musteri;","note":"VACUUM FULL AccessExclusiveLock alır ve tabloyu yeniden yazar; yoğun saatlerde çalıştırmayın. Alternatif: pg_repack.","danger":"caution"},"mysql":{"command":"OPTIMIZE TABLE musteri;","note":"InnoDB'de tabloyu yeniden oluşturur ve data_free alanını geri verir; büyük tablolarda uzun sürer.","danger":"caution"},"mssql":{"command":"-- Genelde ÖNERİLMEZ (parçalanma yaratır). Gerçekten gerekliyse:\nDBCC SHRINKFILE (N'MyDB_data', 1024);  -- hedef 1024 MB","note":"Data file küçültme index parçalanmasına yol açar; sonra index'leri REBUILD edin. Log için önce yedek alın.","danger":"danger"},"mongodb":{"command":"db.runCommand({ compact: \"musteri\" })","note":"WiredTiger'da boş alanı işletim sistemine iade etmeye çalışır (her zaman mümkün olmayabilir). 4.4+ sürümlerde okuma/yazmayı engellemez, yalnızca aynı koleksiyondaki bazı DDL işlemlerini bloklar; yoğun IO ürettiği için secondary düğümde ve bakım penceresinde çalıştırmak daha güvenlidir.","danger":"danger"},"redis":{"command":"MEMORY PURGE\n# jemalloc parçalanmasını OS'e iade etmeye çalışır","note":"activedefrag yes ayarı online otomatik birleştirme yapar; MEMORY DOCTOR öneri verir.","danger":"caution"}}},{"id":"version-uptime","title":"Sürüm ve çalışma süresini (uptime) göster","aliases":["version","uptime","surum","ne zamandir calisiyor","server version","kac gundur ayakta"],"engines":{"oracle":{"command":"SELECT banner_full FROM v$version;\nSELECT startup_time, ROUND(SYSDATE - startup_time, 1) AS up_days\nFROM v$instance;","note":"v$instance status ve host_name gibi örnek bilgilerini de verir.","danger":"safe"},"postgres":{"command":"SELECT version();\nSELECT pg_postmaster_start_time() AS started,\n       now() - pg_postmaster_start_time() AS uptime;","note":"server_version_num sayısal karşılaştırma için pratiktir (ör. 160002 = 16.2).","danger":"safe"},"mysql":{"command":"SELECT VERSION();\nSHOW GLOBAL STATUS LIKE 'Uptime';  -- saniye","note":"Uptime saniye cinsindendir; /86400 ile güne çevrilir.","danger":"safe"},"mssql":{"command":"SELECT @@VERSION;\nSELECT sqlserver_start_time,\n       DATEDIFF(DAY, sqlserver_start_time, GETDATE()) AS up_days\nFROM sys.dm_os_sys_info;","note":"SERVERPROPERTY('ProductVersion') ve ('Edition') sürüm/edisyon ayrıntısı verir.","danger":"safe"},"mongodb":{"command":"db.version()\ndb.serverStatus().uptime   // saniye","note":"serverStatus() ayrıca host, process ve connections bilgisini de içerir.","danger":"safe"},"redis":{"command":"INFO server\n# redis_version ve uptime_in_seconds / uptime_in_days satırları","note":"INFO server ayrıca os, run_id ve tcp_port bilgisini verir.","danger":"safe"}}},{"id":"show-config-param","title":"Bir yapılandırma parametresini görüntüle","aliases":["show config","parameter","ayar goster","config parametre","setting","memory ayari","variable"],"engines":{"oracle":{"command":"SHOW PARAMETER sga_target;\n-- veya: SELECT name, value, isdefault FROM v$parameter WHERE name = 'sga_target';","note":"Değiştirmek için ALTER SYSTEM SET ... SCOPE=BOTH; (bazıları yalnız SCOPE=SPFILE + restart).","danger":"safe"},"postgres":{"command":"SHOW shared_buffers;\n-- Detay: SELECT name, setting, unit, context FROM pg_settings WHERE name = 'shared_buffers';","note":"context sütunu değişikliğin restart mı yoksa reload (SELECT pg_reload_conf()) mı gerektirdiğini söyler.","danger":"safe"},"mysql":{"command":"SHOW VARIABLES LIKE 'innodb_buffer_pool_size';","note":"GLOBAL vs SESSION ayrımına dikkat: SHOW GLOBAL VARIABLES sunucu genelini gösterir.","danger":"safe"},"mssql":{"command":"SELECT name, value, value_in_use, is_dynamic\nFROM sys.configurations\nWHERE name LIKE '%max server memory%';","note":"Değiştirmek için sp_configure + RECONFIGURE; is_dynamic=0 olanlar yeniden başlatma ister.","danger":"safe"},"mongodb":{"command":"db.adminCommand({ getParameter: 1, cursorTimeoutMillis: 1 })\n// Tüm başlangıç seçenekleri: db.adminCommand({ getCmdLineOpts: 1 })","note":"Çalışırken değiştirilebilenler için setParameter; kalıcı ayarlar mongod.conf dosyasındadır.","danger":"safe"},"redis":{"command":"CONFIG GET maxmemory\n# Joker: CONFIG GET max*","note":"Çalışırken değiştirmek için CONFIG SET; kalıcılık için CONFIG REWRITE (redis.conf'a yazar).","danger":"safe"}}}]},"rosetta/schema.json":{"category":"Şema & Nesneler","categoryId":"schema","order":7,"concepts":[{"id":"list-tables","title":"Tabloları / koleksiyonları listele","aliases":["list tables","show tables","tablolari listele","tablo listesi","koleksiyonlar","collections","hangi tablolar var"],"engines":{"oracle":{"command":"SELECT table_name FROM user_tables ORDER BY table_name;\n-- Tüm şemalar: SELECT owner, table_name FROM dba_tables ORDER BY owner, table_name;","note":"user_tables geçerli şemadaki tabloları, all_tables erişilebilir olanları verir.","danger":"safe"},"postgres":{"command":"SELECT table_schema, table_name\nFROM information_schema.tables\nWHERE table_type = 'BASE TABLE' AND table_schema NOT IN ('pg_catalog','information_schema')\nORDER BY 1, 2;\n-- psql kısa yol: \\dt *.*","note":"Yalnız public şema için WHERE table_schema = 'public'.","danger":"safe"},"mysql":{"command":"SHOW TABLES;\n-- Başka şema: SHOW TABLES FROM veritabani;","note":"Ayrıntı için: SELECT table_name, table_rows FROM information_schema.tables WHERE table_schema = DATABASE();","danger":"safe"},"mssql":{"command":"SELECT s.name AS schema_name, t.name AS table_name\nFROM sys.tables t\nJOIN sys.schemas s ON t.schema_id = s.schema_id\nORDER BY s.name, t.name;","note":"Kısa yol: SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE';","danger":"safe"},"mongodb":{"command":"show collections\n// veya: db.getCollectionNames()","note":"Sistem koleksiyonlarını da görmek için: db.getCollectionInfos().","danger":"safe"},"redis":{"command":"SCAN 0 MATCH * COUNT 100\n# Kürsörü döndükçe tekrar SCAN <cursor> ... ile devam edin","note":"Redis'te 'tablo' yoktur; anahtarlar listelenir. Üretimde ASLA KEYS * kullanmayın (bloklar); SCAN kürsörlüdür.","danger":"caution"}}},{"id":"describe-table","title":"Tablonun kolonlarını / yapısını göster (describe)","aliases":["describe","desc table","columns","kolonlar","tablo yapisi","sema goster","field types","alanlar"],"engines":{"oracle":{"command":"SELECT column_name, data_type, data_length, nullable\nFROM user_tab_columns\nWHERE table_name = 'CALISAN'\nORDER BY column_id;\n-- Kısa yol (SQL*Plus): DESC calisan","note":"Tablo adları büyük harf saklanır (tırnaksız oluşturulduysa).","danger":"safe"},"postgres":{"command":"SELECT column_name, data_type, is_nullable, column_default\nFROM information_schema.columns\nWHERE table_name = 'musteri'\nORDER BY ordinal_position;\n-- psql kısa yol: \\d musteri","note":"\\d ayrıca index'leri, constraint'leri ve foreign key'leri de gösterir.","danger":"safe"},"mysql":{"command":"DESCRIBE musteri;\n-- veya: SHOW COLUMNS FROM musteri;","note":"Tam tanım için SHOW CREATE TABLE musteri; (aşağıdaki 'DDL üret' kavramına bakın).","danger":"safe"},"mssql":{"command":"SELECT c.name, t.name AS type, c.max_length, c.is_nullable\nFROM sys.columns c\nJOIN sys.types t ON c.user_type_id = t.user_type_id\nWHERE c.object_id = OBJECT_ID('dbo.musteri')\nORDER BY c.column_id;\n-- Kısa yol: EXEC sp_help 'dbo.musteri';","note":"sp_help kolonların yanı sıra index ve constraint'leri da listeler.","danger":"safe"},"mongodb":{"command":"// Şema esnektir; örnek belgeden çıkarım yapın:\ndb.musteri.findOne()\n// Alan kapsamı için: db.musteri.aggregate([{ $sample: { size: 100 } }])","note":"MongoDB'de sabit şema yoktur; alanlar belgeden belgeye değişebilir. $jsonSchema validator tanımlıysa db.getCollectionInfos ile görülür.","danger":"safe"},"redis":{"command":"TYPE anahtar        # string | list | set | hash | zset | stream\nOBJECT ENCODING anahtar   # dahili kodlama","note":"Sabit şema yoktur; her anahtarın türü ve kodlaması ayrı sorgulanır. Hash alanları için HGETALL.","danger":"safe"}}},{"id":"list-indexes","title":"Bir tablonun index'lerini listele","aliases":["list indexes","show indexes","indeksleri goster","hangi indeksler","table indexes","getindexes"],"engines":{"oracle":{"command":"SELECT index_name, column_name, column_position\nFROM user_ind_columns\nWHERE table_name = 'CALISAN'\nORDER BY index_name, column_position;","note":"Index türü/benzersizlik için user_indexes ile join yapın.","danger":"safe"},"postgres":{"command":"SELECT indexname, indexdef\nFROM pg_indexes\nWHERE tablename = 'musteri';","note":"indexdef tam CREATE INDEX ifadesini verir; psql'de \\d musteri de listeler.","danger":"safe"},"mysql":{"command":"SHOW INDEX FROM musteri;","note":"Non_unique, Seq_in_index ve Cardinality sütunları index yapısını ve seçiciliğini gösterir.","danger":"safe"},"mssql":{"command":"EXEC sp_helpindex 'dbo.musteri';\n-- Ayrıntı: sys.indexes + sys.index_columns join","note":"sp_helpindex index adı, tür ve kolonları verir; filtrelenmiş/dahil kolonlar için sys view'ları.","danger":"safe"},"mongodb":{"command":"db.musteri.getIndexes()","note":"Her index'in anahtarlarını, benzersizlik ve TTL/partial gibi seçeneklerini döndürür.","danger":"safe"},"redis":{"command":"# Uygulanamaz (çekirdek). RediSearch modülü varsa:\n# FT._LIST        (tüm indeksler)\n# FT.INFO idx     (bir indeksin ayrıntısı)","note":"Anahtar-değer modelinde ikincil index yoktur; yalnız RediSearch/RedisJSON gibi modüllerle gelir.","danger":"safe"}}},{"id":"create-index","title":"Index oluştur","aliases":["create index","add index","indeks olustur","indeks ekle","createindex"],"engines":{"oracle":{"command":"CREATE INDEX musteri_il_idx ON musteri(il) ONLINE;","note":"ONLINE tabloyu kilitlemeden oluşturur. Benzersiz için CREATE UNIQUE INDEX; birleşik için (a, b).","danger":"caution"},"postgres":{"command":"CREATE INDEX CONCURRENTLY musteri_il_idx ON musteri(il);","note":"CONCURRENTLY tabloyu yazmaya kapamaz ama transaction bloğu içinde çalışmaz ve daha yavaştır.","danger":"caution"},"mysql":{"command":"CREATE INDEX musteri_il_idx ON musteri(il);\n-- Kilitsiz: ... ALGORITHM=INPLACE, LOCK=NONE;","note":"InnoDB çoğu index'i online ekler; büyük tablolarda LOCK=NONE ile yazmaya izin verin.","danger":"caution"},"mssql":{"command":"CREATE NONCLUSTERED INDEX IX_musteri_il\nON dbo.musteri (il)\nWITH (ONLINE = ON);","note":"ONLINE Enterprise özelliğidir. Kapsayıcı kolonlar için INCLUDE (kolon1, kolon2).","danger":"caution"},"mongodb":{"command":"db.musteri.createIndex({ il: 1 })\n// Benzersiz: { il: 1 }, { unique: true }\n// Arka planda çakışmasız (4.2+ varsayılan davranış)","note":"1 artan, -1 azalan sıralamadır. Büyük koleksiyonlarda secondary düğümde önce kurmak yükü azaltır.","danger":"caution"},"redis":{"command":"# Uygulanamaz (çekirdek). RediSearch varsa:\n# FT.CREATE idx ON HASH PREFIX 1 musteri: SCHEMA il TAG","note":"İkincil index yalnız RediSearch modülüyle gelir; çekirdek Redis erişimi anahtar üzerinden yapılır.","danger":"safe"}}},{"id":"show-ddl","title":"Bir nesnenin DDL'ini (CREATE ifadesi) üret","aliases":["show ddl","get ddl","create statement","ddl uret","tablo tanimi","show create table","generate script"],"engines":{"oracle":{"command":"SELECT DBMS_METADATA.GET_DDL('TABLE', 'CALISAN', 'HR') FROM dual;","note":"Index için 'INDEX', paket için 'PACKAGE' vb. SET LONG 100000 ile uzun çıktı kırpılmasını önleyin.","danger":"safe"},"postgres":{"command":"-- SQL içinden tek fonksiyon yoktur; kabuktan:\npg_dump -t public.musteri --schema-only veritabani","note":"psql'de \\d musteri yapıyı okunur gösterir; tam DDL için pg_dump --schema-only.","danger":"safe"},"mysql":{"command":"SHOW CREATE TABLE musteri\\G","note":"Tek komutla tam CREATE TABLE (kolonlar, index'ler, motor, charset) verir.","danger":"safe"},"mssql":{"command":"-- T-SQL yerleşik tek komut yoktur. Seçenekler:\n-- 1) SSMS: sağ tık > Script Table as > CREATE To\n-- 2) EXEC sp_help 'dbo.musteri';  (yapı özeti)\n-- 3) mssql-scripter aracı (komut satırı)","note":"Prosedür/view gövdesi için: SELECT OBJECT_DEFINITION(OBJECT_ID('dbo.usp_ad'));","danger":"safe"},"mongodb":{"command":"// DDL yoktur (şemasız). Koleksiyon seçeneklerini/validator'ı gör:\ndb.getCollectionInfos({ name: \"musteri\" })","note":"options.validator ($jsonSchema) tanımlıysa tek 'şema tanımı' odur; index'ler ayrı getIndexes() ile.","danger":"safe"},"redis":{"command":"# Uygulanamaz: şema/DDL kavramı yoktur.","note":"Veri yapısı uygulama kodunda tanımlanır; kalıcılık RDB/AOF dosyalarındadır.","danger":"safe"}}}]},"rosetta/replication.json":{"category":"Replikasyon & HA","categoryId":"replication","order":8,"concepts":[{"id":"replication-status","title":"Replikasyon durumunu ve gecikmeyi (lag) gör","aliases":["replication status","replica lag","replikasyon durumu","gecikme","slave lag","standby lag","ne kadar geride"],"engines":{"oracle":{"command":"-- Rol ve mod:\nSELECT database_role, open_mode FROM v$database;\n-- Data Guard gecikmesi:\nSELECT name, value, unit FROM v$dataguard_stats\nWHERE name LIKE '%lag%';","note":"Apply lag ve transport lag Data Guard'ın ana gecikme metrikleridir; standby'da çalıştırın.","danger":"safe"},"postgres":{"command":"-- PRIMARY üzerinde:\nSELECT client_addr, state, sync_state,\n       write_lag, flush_lag, replay_lag\nFROM pg_stat_replication;\n-- STANDBY üzerinde:\nSELECT now() - pg_last_xact_replay_timestamp() AS replay_lag;","note":"replay_lag replay gecikmesidir; sync_state = 'sync' senkron replikayı gösterir.","danger":"safe"},"mysql":{"command":"SHOW REPLICA STATUS\\G\n-- 8.0.22 öncesi: SHOW SLAVE STATUS\\G","note":"Seconds_Behind_Source gecikmeyi verir; Replica_IO_Running ve Replica_SQL_Running 'Yes' olmalı. SHOW SLAVE STATUS 8.0.22–8.3'te takma addır, 8.4'te kaldırıldı.","danger":"safe"},"mssql":{"command":"SELECT ar.replica_server_name, drs.synchronization_state_desc,\n       drs.log_send_queue_size, drs.redo_queue_size\nFROM sys.dm_hadr_database_replica_states drs\nJOIN sys.availability_replicas ar ON drs.replica_id = ar.replica_id;","note":"Always On için. redo_queue_size büyükse secondary replika geride kalıyordur.","danger":"safe"},"mongodb":{"command":"rs.printSecondaryReplicationInfo()\n// Ayrıntılı durum: rs.status()","note":"Her secondary'nin primary'e göre kaç saniye geride olduğunu gösterir; optimeDate karşılaştırılır.","danger":"safe"},"redis":{"command":"INFO replication\n# role, connected_slaves, master_repl_offset,\n# slaveN:...,offset=... satırlarına bakın","note":"master_repl_offset ile slave offset farkı gecikmeyi verir; master_link_status 'up' olmalı.","danger":"safe"}}},{"id":"list-replicas","title":"Replikaları / küme düğümlerini listele","aliases":["list replicas","show replicas","replikalari listele","nodes","cluster members","slaves","standby list"],"engines":{"oracle":{"command":"-- Standby hedefleri:\nSELECT dest_id, destination, status, target\nFROM v$archive_dest\nWHERE status <> 'INACTIVE';\n-- RAC örnekleri: SELECT inst_id, instance_name, status FROM gv$instance;","note":"Data Guard yapılandırması DGMGRL> SHOW CONFIGURATION ile de görülür.","danger":"safe"},"postgres":{"command":"SELECT application_name, client_addr, state, sync_state\nFROM pg_stat_replication;","note":"Yalnız PRIMARY üzerinde bağlı replikaları listeler; her satır bir standby'dır.","danger":"safe"},"mysql":{"command":"SHOW REPLICAS;\n-- 8.0.22 öncesi: SHOW SLAVE HOSTS;","note":"Kaynak (source) sunucuda çalıştırılır; report-host ayarlı replikaları gösterir. SHOW SLAVE HOSTS 8.0.22–8.3'te takma addır, 8.4'te kaldırıldı.","danger":"safe"},"mssql":{"command":"SELECT ar.replica_server_name, ars.role_desc,\n       ars.connected_state_desc, ars.synchronization_health_desc\nFROM sys.dm_hadr_availability_replica_states ars\nJOIN sys.availability_replicas ar ON ars.replica_id = ar.replica_id;","note":"role_desc PRIMARY/SECONDARY ayrımını, synchronization_health_desc genel sağlığı verir.","danger":"safe"},"mongodb":{"command":"rs.status().members.map(m => ({ name: m.name, state: m.stateStr, health: m.health }))","note":"stateStr PRIMARY/SECONDARY/ARBITER değerlerini verir; health 1 sağlıklı demektir.","danger":"safe"},"redis":{"command":"INFO replication\n# Sentinel kullanılıyorsa:\n# SENTINEL replicas <master-adi>","note":"slave0, slave1... satırları her replikanın ip/port/offset bilgisini verir.","danger":"safe"}}},{"id":"promote-failover","title":"Replikayı yükselt / failover yap (promote)","aliases":["promote","failover","switchover","yukselt","el degistir","stepdown","master yap","primary yap"],"engines":{"oracle":{"command":"-- Data Guard broker (DGMGRL):\nSWITCHOVER TO 'standby_db';     -- planlı, veri kaybısız\n-- FAILOVER TO 'standby_db';     -- primary kaybında, acil","note":"SWITCHOVER roller arası planlı geçiştir; FAILOVER primary erişilemezken yapılır ve veri kaybı riski taşır.","danger":"danger"},"postgres":{"command":"-- Standby'ı primary'e yükselt:\nSELECT pg_promote();\n-- veya kabuktan: pg_ctl promote -D /var/lib/pgsql/data","note":"Promote öncesinde eski primary'nin gerçekten durduğundan emin olun (split-brain riski). Yükselttikten sonra eski primary'yi yeni primary'ye replika olarak geri katmak için pg_rewind gerekir; bunun için wal_log_hints = on ya da data checksums açık olmalıdır.","danger":"danger"},"mysql":{"command":"-- Replika üzerinde (manuel):\n-- 1) Yeni olay almayı durdur, alınmış relay log'un tamamen uygulanmasını bekle:\nSTOP REPLICA IO_THREAD;\nSELECT RECEIVED_TRANSACTION_SET FROM performance_schema.replication_connection_status;\nSELECT @@GLOBAL.gtid_executed;  -- alınan küme burada tamamen yer almalı\n-- 2) Replikasyonu kaldır ve yazmayı aç:\nSTOP REPLICA;\nRESET REPLICA ALL;\nSET GLOBAL read_only = OFF;  -- super_read_only'yi de kapatır\n-- 3) Eski kaynağı yazmaya kapatın (fencing), sonra uygulamayı yönlendirin.","note":"Relay log tamamen uygulanmadan RESET REPLICA ALL yapılırsa alınmış ama uygulanmamış işlemler kaybolur. Replikalar genelde read_only/super_read_only açık çalışır; bunlar kapatılmadan yazma kabul edilmez. Eski kaynak hâlâ yazılabilir durumdaysa split-brain riski vardır. Söz dizimi 8.0.22+ (öncesinde STOP SLAVE / RESET SLAVE ALL; 8.4'te eski biçim kaldırıldı). Üretimde otomatik ve güvenli failover için InnoDB Cluster/Group Replication, Orchestrator veya MHA tercih edin.","danger":"danger"},"mssql":{"command":"-- Hedef secondary replika üzerinde (senkron):\nALTER AVAILABILITY GROUP [AG_Ad] FAILOVER;\n-- Veri kaybı riskiyle zorla:\n-- ALTER AVAILABILITY GROUP [AG_Ad] FORCE_FAILOVER_ALLOW_DATA_LOSS;","note":"Planlı failover senkron replikada veri kaybısızdır; FORCE yalnız felaket senaryosunda kullanılır.","danger":"danger"},"mongodb":{"command":"// Mevcut primary'de seçim tetikle:\nrs.stepDown(60)   // 60 sn primary olmaktan çekil","note":"stepDown yeni bir seçim başlatır; belirli düğümü zorlamak için üyelerin priority değerlerini ayarlayın.","danger":"danger"},"redis":{"command":"# Replikayı bağımsız primary yap:\nREPLICAOF NO ONE\n# Sentinel varsa (önerilen): SENTINEL FAILOVER <master-adi>","note":"Sentinel/Cluster kullanıyorsanız manuel REPLICAOF yerine SENTINEL FAILOVER ile yapın; aksi halde split-brain riski.","danger":"danger"}}},{"id":"open-transactions","title":"Açık / uzun süren transaction'ları bul","aliases":["open transactions","long running transaction","acik transaction","uzun islem","idle in transaction","oldest transaction","undo"],"engines":{"oracle":{"command":"SELECT s.sid, s.serial#, s.username,\n       t.start_time, t.used_ublk AS undo_blocks\nFROM v$transaction t\nJOIN v$session s ON t.ses_addr = s.saddr\nORDER BY t.start_time;","note":"used_ublk yüksekse büyük bir transaction çok undo tüketiyordur; commit/rollback bekleniyor olabilir.","danger":"safe"},"postgres":{"command":"SELECT pid, usename, state,\n       now() - xact_start AS xact_age, query\nFROM pg_stat_activity\nWHERE xact_start IS NOT NULL\nORDER BY xact_start;","note":"'idle in transaction' durumundaki uzun transaction'lar VACUUM'u ve tuple temizliğini engeller; bunları izleyin.","danger":"safe"},"mysql":{"command":"SELECT trx_id, trx_state, trx_started,\n       TIMESTAMPDIFF(SECOND, trx_started, NOW()) AS age_sec,\n       trx_mysql_thread_id\nFROM information_schema.innodb_trx\nORDER BY trx_started;","note":"trx_mysql_thread_id ile PROCESSLIST'e bağlanıp gerekirse KILL edebilirsiniz.","danger":"safe"},"mssql":{"command":"DBCC OPENTRAN;\n-- Ayrıntılı:\nSELECT st.session_id, dt.database_transaction_begin_time\nFROM sys.dm_tran_database_transactions dt\nJOIN sys.dm_tran_session_transactions st ON st.transaction_id = dt.transaction_id\nWHERE dt.database_id = DB_ID()\nORDER BY dt.database_transaction_begin_time;","note":"Uzun açık transaction'lar log'un kesilmesini (truncate) engeller ve log dosyasını şişirir.","danger":"safe"},"mongodb":{"command":"db.adminCommand({\n  currentOp: 1,\n  \"transaction\": { $exists: true }\n})","note":"Uzun çok-belge transaction'ları transactionLifetimeLimitSeconds (varsayılan 60 sn) sonunda otomatik iptal edilir.","danger":"safe"},"redis":{"command":"# Uygulanamaz: MULTI/EXEC işlemleri kısa ve atomiktir, açık kalmaz.","note":"Redis transaction'ları lock tutmaz; uzun süren tek komutlar için SLOWLOG'a bakın.","danger":"safe"}}}]},"rosetta/connect.json":{"category":"Bağlantı & CLI","categoryId":"connect","order":9,"concepts":[{"id":"connect-cli","title":"Komut satırından bağlan (CLI / connection string)","aliases":["connect","connection string","baglan","nasil baglanirim","cli connect","login","dsn","uri"],"engines":{"oracle":{"command":"sqlplus kullanici/parola@//host:1521/servis_adi\n# SYSDBA olarak: sqlplus sys/parola@//host:1521/orcl AS SYSDBA","note":"//host:port/servis 'Easy Connect' biçimidir; alternatif olarak tnsnames.ora'daki TNS alias kullanılır.","danger":"safe"},"postgres":{"command":"psql -h host -p 5432 -U postgres -d veritabani\n# URI ile: psql \"postgresql://kullanici:parola@host:5432/veritabani?sslmode=require\"","note":"Parolayı komut satırına yazmamak için ~/.pgpass dosyası veya PGPASSWORD ortam değişkeni kullanın.","danger":"safe"},"mysql":{"command":"mysql -h host -P 3306 -u root -p veritabani\n# TLS zorunlu: --ssl-mode=REQUIRED","note":"-p'yi tek başına verin (parola sorulur); 'mysql -pParola' biçimi parolayı süreç listesinde açık eder.","danger":"safe"},"mssql":{"command":"sqlcmd -S host,1433 -U sa -P parola -d veritabani\n# Windows kimlik doğrulama: sqlcmd -S host -E -d veritabani","note":"Yeni go-sqlcmd sürümünde -C (sertifikaya güven) ve -N (şifreli) bayrakları TLS için gerekebilir.","danger":"safe"},"mongodb":{"command":"mongosh \"mongodb://kullanici:parola@host:27017/veritabani?authSource=admin\"\n# Replica set: ...mongodb://h1,h2,h3/db?replicaSet=rs0","note":"authSource genelde kullanıcının tanımlı olduğu veritabanıdır (çoğunlukla admin).","danger":"safe"},"redis":{"command":"redis-cli -h host -p 6379 -a parola\n# TLS ile: redis-cli -h host -p 6379 --tls -a parola\n# Redis 6+ ACL: redis-cli -h host --user app --pass parola","note":"-a parolayı komut satırında verir (uyarı basar); güvenli giriş için REDISCLI_AUTH ortam değişkeni.","danger":"safe"}}},{"id":"list-databases","title":"Veritabanlarını / şemaları listele","aliases":["list databases","show databases","veritabanlarini listele","hangi veritabanlari","list schemas","pdbs","show dbs"],"engines":{"oracle":{"command":"-- Şemalar (kullanıcılar):\nSELECT username FROM dba_users ORDER BY username;\n-- Çok kiracılı (CDB) PDB'ler:\nSELECT name, open_mode FROM v$pdbs;","note":"Oracle'da 'veritabanı' örneğe eşittir; ayrım şema (kullanıcı) veya CDB içindeki PDB düzeyindedir.","danger":"safe"},"postgres":{"command":"SELECT datname FROM pg_database WHERE datistemplate = false;\n-- psql kısa yol: \\l","note":"Şemalar için: SELECT schema_name FROM information_schema.schemata;","danger":"safe"},"mysql":{"command":"SHOW DATABASES;","note":"MySQL'de 'database' ve 'schema' eş anlamlıdır.","danger":"safe"},"mssql":{"command":"SELECT name, state_desc FROM sys.databases ORDER BY name;","note":"state_desc ONLINE/OFFLINE/RESTORING gibi veritabanı durumunu gösterir.","danger":"safe"},"mongodb":{"command":"show dbs\n// veya: db.adminCommand({ listDatabases: 1 })","note":"Boş (hiç veri yazılmamış) veritabanları listede görünmez.","danger":"safe"},"redis":{"command":"INFO keyspace\n# db0:keys=..., db1:keys=... satırları kullanılan mantıksal DB'leri gösterir","note":"Redis'te numaralı mantıksal DB'ler (varsayılan 0-15) vardır; Cluster modunda yalnız DB 0 kullanılır.","danger":"safe"}}},{"id":"switch-database","title":"Aktif veritabanını / şemayı değiştir","aliases":["switch database","use database","veritabani degistir","gecis yap","change schema","sema degistir","use db"],"engines":{"oracle":{"command":"-- Varsayılan şemayı değiştir:\nALTER SESSION SET CURRENT_SCHEMA = hr;\n-- PDB'ye geç (CDB içinde):\nALTER SESSION SET CONTAINER = pdb1;","note":"CURRENT_SCHEMA yalnız nesne çözümlemesini değiştirir, yetkileri değiştirmez.","danger":"safe"},"postgres":{"command":"-- psql içinde başka DB'ye (yeniden bağlanır):\n\\c veritabani\n-- Şema arama yolu (aynı bağlantıda):\nSET search_path TO hr, public;","note":"PostgreSQL'de tek bağlantı tek veritabanına bağlıdır; DB değiştirmek yeniden bağlanmaktır.","danger":"safe"},"mysql":{"command":"USE veritabani;","note":"Bağlantıyı kesmeden aktif şemayı değiştirir.","danger":"safe"},"mssql":{"command":"USE veritabani;","note":"Toplu iş (batch) bağlamını değiştirir; sonraki komutlar bu veritabanında çalışır.","danger":"safe"},"mongodb":{"command":"use veritabani","note":"Veritabanı yoksa da geçer; ilk belge yazıldığında fiilen oluşturulur.","danger":"safe"},"redis":{"command":"SELECT 1\n# 0-15 arası mantıksal DB indeksine geçer","note":"Cluster modunda SELECT yalnız 0'ı destekler; mantıksal DB ayrımı yerine anahtar öneki kullanın.","danger":"safe"}}}]},"rosetta/objects.json":{"category":"Nesne Yönetimi","categoryId":"objects","order":10,"concepts":[{"id":"create-partition","title":"Partition oluştur / böl / at","aliases":["partition","bölüm","böl","split partition","drop partition","partition ekle","partition sil"],"engines":{"oracle":{"command":"-- RANGE partition ekle\nALTER TABLE satislar ADD PARTITION p2026 VALUES LESS THAN (TO_DATE('2027-01-01','YYYY-MM-DD'));\n\n-- Var olan partition'ı böl\nALTER TABLE satislar SPLIT PARTITION pmax AT (TO_DATE('2027-01-01','YYYY-MM-DD')) INTO (PARTITION p2026, PARTITION pmax);\n\n-- Partition at\nALTER TABLE satislar DROP PARTITION p2020 UPDATE INDEXES;","note":"RANGE/LIST/HASH partition destekler. DROP PARTITION o bölümdeki tüm satırları siler; UPDATE INDEXES ile global index'ler geçerli kalır. Interval partition ile otomatik ekleme yapılabilir.","danger":"caution","priv":"ALTER on tablo","minver":"Partitioning Option"},"postgres":{"command":"-- Declarative partitioning: ana tablo\nCREATE TABLE satislar (id bigint, tarih date, tutar numeric) PARTITION BY RANGE (tarih);\n\n-- Yeni partition ekle\nCREATE TABLE satislar_2026 PARTITION OF satislar FOR VALUES FROM ('2026-01-01') TO ('2027-01-01');\n\n-- Bağımsız (var olan) bir tabloyu partition olarak bağla\nCREATE TABLE satislar_2027 (LIKE satislar INCLUDING ALL);\nALTER TABLE satislar ATTACH PARTITION satislar_2027 FOR VALUES FROM ('2027-01-01') TO ('2028-01-01');\n\n-- Partition'ı ayır (tablo silinmez, bağımsız tablo olarak kalır)\nALTER TABLE satislar DETACH PARTITION satislar_2026;","note":"Çekirdek PostgreSQL'de SPLIT/MERGE PARTITION yoktur (PG17 itibarıyla); bölmek için partition'ı DETACH edip yeni sınırlarla iki partition oluşturur, veriyi taşıyıp ATTACH edersiniz. DETACH ... CONCURRENTLY (PG14+) lock süresini azaltır.","danger":"caution","priv":"tablo sahibi","minver":"PG10"},"mysql":{"command":"-- Partition'lı tablo\nCREATE TABLE satislar (id BIGINT, tarih DATE) PARTITION BY RANGE (YEAR(tarih)) (\n  PARTITION p2024 VALUES LESS THAN (2025),\n  PARTITION p2025 VALUES LESS THAN (2026),\n  PARTITION pmax VALUES LESS THAN MAXVALUE\n);\n\n-- Partition ekle / böl / at\nALTER TABLE satislar REORGANIZE PARTITION pmax INTO (\n  PARTITION p2026 VALUES LESS THAN (2027),\n  PARTITION pmax VALUES LESS THAN MAXVALUE\n);\nALTER TABLE satislar DROP PARTITION p2024;","note":"Partition kolonu PRIMARY KEY / UNIQUE anahtarların parçası olmalıdır. RANGE'de bölme/birleştirme REORGANIZE PARTITION ile yapılır. DROP PARTITION satırları da siler (RANGE/LIST).","danger":"caution","priv":"ALTER, DROP on tablo","minver":"5.7"},"mssql":{"command":"-- 1) Partition function ve scheme\nCREATE PARTITION FUNCTION pf_tarih (date) AS RANGE RIGHT FOR VALUES ('2025-01-01','2026-01-01');\nCREATE PARTITION SCHEME ps_tarih AS PARTITION pf_tarih ALL TO ([PRIMARY]);\n\n-- 2) Yeni sınır ekle (böl)\nALTER PARTITION SCHEME ps_tarih NEXT USED [PRIMARY];\nALTER PARTITION FUNCTION pf_tarih() SPLIT RANGE ('2027-01-01');\n\n-- 3) Sınır kaldır (birleştir)\nALTER PARTITION FUNCTION pf_tarih() MERGE RANGE ('2025-01-01');","note":"Partition function + scheme tanımlanır, tablo CREATE TABLE ... ON ps_tarih(tarih) ile bu şemaya kurulur. SPLIT öncesi NEXT USED file group ayarlanmalıdır. Veri atmak için SWITCH PARTITION ile bir staging tabloya taşınır.","danger":"caution","priv":"ALTER on tablo, ALTER ANY DATASPACE","minver":"2016 SP1 (tüm sürümler)"},"mongodb":{"command":"// MongoDB'de tablo partition'ı yerine sharding kullanılır\nsh.shardCollection(\"db.satislar\", { tarih: 1 });\n\n// Zaman serisi için native time-series koleksiyon\ndb.createCollection(\"olcumler\", { timeseries: { timeField: \"ts\", granularity: \"hours\" } });","note":"Klasik anlamda partition yoktur. Yatay bölme sharding ile chunk'lar üzerinden yapılır; zaman bazlı veride time-series koleksiyonlar otomatik bucket'lama sağlar.","danger":"safe"},"redis":{"command":"# Uygulanamaz: Redis'te tablo/partition kavramı yoktur; ölçekleme Redis Cluster hash slot'ları (16384) ile yapılır.","note":"Redis Cluster anahtarları 16384 hash slot'a dağıtır; bu uygulama düzeyinde bölmedir, tablo partition'ı değildir. Manuel partition komutu yoktur.","danger":"safe"},"elasticsearch":{"command":"# ILM politikası + data stream ile zaman bazlı otomatik bölme (rollover)\nPUT _ilm/policy/loglar-policy\n{ \"policy\": { \"phases\": { \"hot\": { \"actions\": { \"rollover\": { \"max_size\": \"50gb\", \"max_age\": \"30d\" } } } } } }\n\nPUT _index_template/loglar-tmpl\n{ \"index_patterns\": [\"loglar*\"], \"data_stream\": {}, \"template\": { \"settings\": { \"index.lifecycle.name\": \"loglar-policy\" } } }","note":"Elasticsearch'te bölme, index'in shard'lara ayrılması ve zaman serisi için ILM + data stream (rollover) ile yeni backing index oluşturulmasıyla sağlanır. Eski index'ler ILM ile silinebilir.","danger":"safe"}}},{"id":"sequence","title":"Sequence / otomatik artan değer oluştur","aliases":["sequence","dizi","auto increment","identity","otomatik artan","nextval","serial"],"engines":{"oracle":{"command":"-- Sequence\nCREATE SEQUENCE musteri_seq START WITH 1 INCREMENT BY 1 NOCACHE;\nSELECT musteri_seq.NEXTVAL FROM dual;\n\n-- veya identity kolon (12c+)\nCREATE TABLE musteri (id NUMBER GENERATED ALWAYS AS IDENTITY, ad VARCHAR2(100));","note":"Klasik yöntem CREATE SEQUENCE + NEXTVAL/CURRVAL. 12c'den itibaren GENERATED AS IDENTITY kolonlar da desteklenir. CACHE değeri performansı artırır ama boşluk (gap) oluşabilir.","danger":"safe","priv":"CREATE SEQUENCE","minver":"IDENTITY için 12c"},"postgres":{"command":"-- Sequence\nCREATE SEQUENCE musteri_seq START 1 INCREMENT 1;\nSELECT nextval('musteri_seq');\n\n-- Modern yöntem: identity kolon\nCREATE TABLE musteri (id int GENERATED ALWAYS AS IDENTITY PRIMARY KEY, ad text);\n-- Klasik: serial (arka planda sequence kurar)\nCREATE TABLE loglar (id serial PRIMARY KEY, mesaj text);","note":"GENERATED ... AS IDENTITY SQL standardıdır ve önerilir; serial eski kısayoldur. nextval/currval ile manuel erişilir. setval ile değer sıfırlanabilir.","danger":"safe","priv":"CREATE on şema","minver":"IDENTITY için PG10"},"mysql":{"command":"-- AUTO_INCREMENT kolon\nCREATE TABLE musteri (id BIGINT AUTO_INCREMENT PRIMARY KEY, ad VARCHAR(100));\n\n-- Başlangıç değerini ayarla\nALTER TABLE musteri AUTO_INCREMENT = 1000;\n\n-- Son eklenen değeri al\nSELECT LAST_INSERT_ID();","note":"MySQL/MariaDB'de bağımsız sequence nesnesi (standart) yoktur; AUTO_INCREMENT kolon kullanılır (tablo başına bir tane, index'li olmalı). MariaDB 10.3+ CREATE SEQUENCE'i destekler.","danger":"safe","priv":"CREATE, ALTER on tablo"},"mssql":{"command":"-- IDENTITY kolon\nCREATE TABLE musteri (id INT IDENTITY(1,1) PRIMARY KEY, ad NVARCHAR(100));\n\n-- Bağımsız sequence nesnesi\nCREATE SEQUENCE musteri_seq AS INT START WITH 1 INCREMENT BY 1;\nSELECT NEXT VALUE FOR musteri_seq;","note":"IDENTITY(seed,increment) tablo kolonuna bağlıdır. CREATE SEQUENCE (2012+) tablodan bağımsız, tablolar arası paylaşılabilir sayaç sağlar; NEXT VALUE FOR ile alınır.","danger":"safe","priv":"CREATE SEQUENCE / ALTER on tablo","minver":"SEQUENCE için 2012"},"mongodb":{"command":"// MongoDB'de otomatik sayaç yoktur; findOneAndUpdate ile counter deseni\ndb.sayaclar.findOneAndUpdate(\n  { _id: \"musteri\" },\n  { $inc: { seq: 1 } },\n  { upsert: true, returnDocument: \"after\" }\n);","note":"Varsayılan _id ObjectId'dir (zaten benzersiz, kabaca artan). Sıralı tam sayı gerekiyorsa ayrı bir sayaç koleksiyonunda $inc ile atomik olarak üretilir.","danger":"safe"},"redis":{"command":"# Atomik sayaç\nINCR musteri:id\n# veya belirli adımla\nINCRBY musteri:id 10","note":"INCR/INCRBY atomiktir ve dağıtık ortamda benzersiz artan ID üretmek için idealdir. Anahtar yoksa 0'dan başlar.","danger":"safe"},"elasticsearch":{"command":"# Uygulanamaz: Elasticsearch sequence nesnesi sunmaz. Doküman ID otomatik atanır;\n# eşzamanlılık kontrolü için dahili _seq_no ve _primary_term alanları kullanılır.\nPOST loglar/_doc\n{ \"mesaj\": \"ornek\" }","note":"ID vermeden POST edilirse ES rastgele benzersiz _id atar (artan değil). _seq_no her yazımda artan dahili bir sıra numarasıdır ama optimistic concurrency içindir, uygulama sayacı değildir.","danger":"safe"}}},{"id":"add-constraint","title":"Constraint ekle veya devre dışı bırak (FK/CHECK/UNIQUE)","aliases":["constraint","kısıt","foreign key","check","unique","yabancı anahtar","disable constraint"],"engines":{"oracle":{"command":"-- Foreign key ekle\nALTER TABLE siparis ADD CONSTRAINT fk_musteri FOREIGN KEY (musteri_id) REFERENCES musteri(id);\n-- CHECK\nALTER TABLE urun ADD CONSTRAINT chk_fiyat CHECK (fiyat >= 0);\n-- Devre dışı bırak / etkinleştir\nALTER TABLE siparis DISABLE CONSTRAINT fk_musteri;\nALTER TABLE siparis ENABLE CONSTRAINT fk_musteri;","note":"Oracle constraint'leri DISABLE/ENABLE ile geçici kapatılabilir (toplu yüklemede yararlı). ENABLE VALIDATE mevcut satırları kontrol eder, NOVALIDATE etmez.","danger":"caution","priv":"ALTER on tablo, REFERENCES on hedef"},"postgres":{"command":"-- Foreign key ve CHECK\nALTER TABLE siparis ADD CONSTRAINT fk_musteri FOREIGN KEY (musteri_id) REFERENCES musteri(id);\nALTER TABLE urun ADD CONSTRAINT chk_fiyat CHECK (fiyat >= 0);\n\n-- FK'yi devre dışı bırakmak yerine NOT VALID + sonra doğrula\nALTER TABLE siparis ADD CONSTRAINT fk2 FOREIGN KEY (m_id) REFERENCES musteri(id) NOT VALID;\nALTER TABLE siparis VALIDATE CONSTRAINT fk2;\nALTER TABLE siparis DROP CONSTRAINT fk2;","note":"PostgreSQL'de constraint DISABLE yoktur. Büyük tabloda lock'u azaltmak için NOT VALID ile ekleyip sonra VALIDATE edilir. ALTER TABLE ... DISABLE TRIGGER ALL FK'nin iç trigger'larını de kapatır ve superuser ister; açık kaldığı sürede eklenen veri hiç doğrulanmaz, yeniden etkinleştirmek de geriye dönük kontrol yapmaz (sessiz bütünlük kaybı riski). Bunun yerine constraint'i DROP edip NOT VALID ile yeniden ekleyin, ardından VALIDATE CONSTRAINT çalıştırın.","danger":"caution","priv":"tablo sahibi, REFERENCES on hedef"},"mysql":{"command":"-- Foreign key ve CHECK\nALTER TABLE siparis ADD CONSTRAINT fk_musteri FOREIGN KEY (musteri_id) REFERENCES musteri(id);\nALTER TABLE urun ADD CONSTRAINT chk_fiyat CHECK (fiyat >= 0);\n\n-- FK kontrolünü oturum genelinde geçici kapat\nSET FOREIGN_KEY_CHECKS = 0;\n-- ... toplu işlem ...\nSET FOREIGN_KEY_CHECKS = 1;","note":"InnoDB gerekir. Tek bir constraint'i DISABLE etmek yerine oturum bazlı SET FOREIGN_KEY_CHECKS=0 kullanılır. CHECK constraint'leri MySQL 8.0.16'dan itibaren gerçekten uygulanır (öncesinde yok sayılırdı).","danger":"caution","priv":"ALTER, REFERENCES on tablo","minver":"CHECK için 8.0.16"},"mssql":{"command":"-- Foreign key ve CHECK\nALTER TABLE siparis ADD CONSTRAINT fk_musteri FOREIGN KEY (musteri_id) REFERENCES musteri(id);\nALTER TABLE urun ADD CONSTRAINT chk_fiyat CHECK (fiyat >= 0);\n\n-- Devre dışı / yeniden etkinleştir (WITH CHECK ile doğrula)\nALTER TABLE siparis NOCHECK CONSTRAINT fk_musteri;\nALTER TABLE siparis WITH CHECK CHECK CONSTRAINT fk_musteri;","note":"SQL Server'da FK/CHECK constraint'leri NOCHECK CONSTRAINT ile kapatılır. Yeniden açarken WITH CHECK CHECK CONSTRAINT kullanılmazsa constraint 'not trusted' kalır ve sorgu iyileştirici onu kullanamaz.","danger":"caution","priv":"ALTER on tablo, REFERENCES on hedef"},"mongodb":{"command":"// Şema doğrulama (validation) kuralları ile kısıt benzeri kontrol\ndb.runCommand({ collMod: \"urun\",\n  validator: { $jsonSchema: { required: [\"fiyat\"], properties: { fiyat: { bsonType: \"number\", minimum: 0 } } } },\n  validationLevel: \"strict\"\n});\n// Benzersizlik için unique index\ndb.musteri.createIndex({ email: 1 }, { unique: true });","note":"Foreign key yoktur (uygulama katmanında sağlanır). UNIQUE karşılığı unique index'tir. CHECK yerine $jsonSchema doğrulaması; validationAction: 'warn' ile devre dışı bırakma etkisi elde edilir.","danger":"caution"},"redis":{"command":"# Uygulanamaz: Redis'te FK/CHECK/UNIQUE kısıtı yoktur. Benzersizlik için SET veya\n# SETNX/koşullu yazım ile uygulama düzeyinde sağlanır.\nSET musteri:email:ornek@x.com 1 NX","note":"İlişkisel bütünlük ve constraint kavramı yoktur. Benzersizlik SET ... NX (yalnızca yoksa yaz) veya ayrı bir SET/HASH ile kontrol edilerek uygulama tarafında yönetilir.","danger":"safe"},"elasticsearch":{"command":"# Uygulanamaz: Elasticsearch'te FK/CHECK yoktur. Alan tipi zorlaması mapping ile,\n# tekillik ise sabit _id kullanılarak sağlanır.\nPUT urun/_doc/ABC-123\n{ \"fiyat\": 100 }","note":"İlişki ve constraint motorda yoktur. Tip kontrolü mapping ile yapılır. UNIQUE etkisi için doğal anahtarı _id olarak vermek (aynı _id üzerine yazılır) veya op_type=create ile çakışmayı reddetmek gerekir.","danger":"safe"}}},{"id":"create-view","title":"View oluştur / değiştir","aliases":["view","görünüm","create view","alter view","or replace"],"engines":{"oracle":{"command":"CREATE OR REPLACE VIEW aktif_musteri AS\nSELECT id, ad, email FROM musteri WHERE durum = 'AKTIF';\n\n-- Kaldır\nDROP VIEW aktif_musteri;","note":"CREATE OR REPLACE VIEW ile hem oluşturma hem değiştirme yapılır. Belirli koşullarda güncellenebilir view'lar için WITH CHECK OPTION eklenebilir.","danger":"safe","readonly":true,"priv":"CREATE VIEW"},"postgres":{"command":"CREATE OR REPLACE VIEW aktif_musteri AS\nSELECT id, ad, email FROM musteri WHERE durum = 'AKTIF';\n\nDROP VIEW aktif_musteri;","note":"CREATE OR REPLACE ile yeni kolon ancak sona eklenebilir; kolon tipini/sırasını değiştirmek için önce DROP gerekir. Basit view'lar otomatik güncellenebilir.","danger":"safe","readonly":true,"priv":"CREATE on şema"},"mysql":{"command":"CREATE OR REPLACE VIEW aktif_musteri AS\nSELECT id, ad, email FROM musteri WHERE durum = 'AKTIF';\n\n-- Değiştir\nALTER VIEW aktif_musteri AS SELECT id, ad FROM musteri;\nDROP VIEW aktif_musteri;","note":"CREATE OR REPLACE VIEW veya ALTER VIEW ile tanım güncellenir. ALGORITHM = MERGE/TEMPTABLE ile çalışma biçimi ayarlanabilir; WITH CHECK OPTION güncellenebilir view'ları korur.","danger":"safe","readonly":true,"priv":"CREATE VIEW on tablo"},"mssql":{"command":"CREATE OR ALTER VIEW aktif_musteri AS\nSELECT id, ad, email FROM musteri WHERE durum = 'AKTIF';\n\nDROP VIEW aktif_musteri;","note":"CREATE OR ALTER VIEW (2016 SP1+) tek komutta oluşturur/değiştirir. Eski sürümlerde önce CREATE, sonra ALTER VIEW kullanılır. View ifadesi batch'in ilk deyimi olmalıdır.","danger":"safe","readonly":true,"priv":"CREATE VIEW","minver":"OR ALTER için 2016 SP1"},"mongodb":{"command":"// Read-only view (aggregation pipeline üzerine)\ndb.createView(\"aktif_musteri\", \"musteri\", [ { $match: { durum: \"AKTIF\" } }, { $project: { ad: 1, email: 1 } } ]);\n\ndb.aktif_musteri.drop();","note":"db.createView ile kaynak koleksiyon ve aggregation pipeline üzerinden salt-okunur view oluşturulur. View'a yazılamaz; tanımı değiştirmek için drop edip yeniden oluşturun (veya collMod).","danger":"safe","readonly":true},"redis":{"command":"# Uygulanamaz: Redis'te view kavramı yoktur; türetilmiş görünümler uygulama\n# tarafında ya da RedisJSON/RediSearch indeksleriyle sağlanır.","note":"Sorgu üzerine tanımlı view desteği yoktur. Benzer ihtiyaç için önceden hesaplanmış anahtarlar tutulur veya RediSearch ile aranabilir index kurulur.","danger":"safe"},"elasticsearch":{"command":"# Alias ile filtreli mantıksal görünüm\nPOST _aliases\n{ \"actions\": [ { \"add\": { \"index\": \"musteri\", \"alias\": \"aktif_musteri\",\n  \"filter\": { \"term\": { \"durum\": \"AKTIF\" } } } } ] }","note":"Klasik SQL view yoktur; filtreli alias en yakın karşılıktır ve sorgulara otomatik filtre uygular. Kolon seçimi için sorguda _source filtreleme kullanılır.","danger":"safe","readonly":true}}},{"id":"materialized-view","title":"Materialized view oluştur ve tazele (refresh)","aliases":["materialized view","mview","refresh","tazele","önbellek view","materyalize"],"engines":{"oracle":{"command":"-- FAST refresh için önce kaynak tabloda MV log gerekir:\nCREATE MATERIALIZED VIEW LOG ON satislar\n  WITH ROWID, SEQUENCE (bolge, tutar) INCLUDING NEW VALUES;\n\nCREATE MATERIALIZED VIEW mv_ciro\nBUILD IMMEDIATE REFRESH FAST ON COMMIT\nAS SELECT bolge, SUM(tutar) toplam, COUNT(*) adet, COUNT(tutar) tutar_adet\n   FROM satislar GROUP BY bolge;\n\n-- Elle tazele\nEXEC DBMS_MVIEW.REFRESH('MV_CIRO', 'C');","note":"REFRESH FAST için materialized view log gerekir; COMPLETE ('C') tam yeniden hesaplar, FAST ('F') artımlıdır. ON COMMIT/ON DEMAND tazeleme zamanını belirler.","danger":"caution","priv":"CREATE MATERIALIZED VIEW"},"postgres":{"command":"CREATE MATERIALIZED VIEW mv_ciro AS\nSELECT bolge, SUM(tutar) AS toplam FROM satislar GROUP BY bolge;\n\n-- Tazele (CONCURRENTLY için unique index şart)\nCREATE UNIQUE INDEX ON mv_ciro (bolge);\nREFRESH MATERIALIZED VIEW CONCURRENTLY mv_ciro;","note":"REFRESH tümüyle yeniden hesaplar (artımlı değildir). CONCURRENTLY okumaları bloklamaz ama benzersiz index gerektirir ve daha yavaştır.","danger":"caution","priv":"tablo sahibi","minver":"PG9.3 (CONCURRENTLY 9.4)"},"mysql":{"command":"-- MySQL/MariaDB'de yerleşik materialized view yoktur.\n-- Yaklaşım: özet tablo + trigger veya zamanlanmış event ile tazeleme\nCREATE TABLE mv_ciro (bolge VARCHAR(50) PRIMARY KEY, toplam DECIMAL(18,2));\n\nCREATE EVENT ev_mv_ciro ON SCHEDULE EVERY 1 HOUR DO\n  REPLACE INTO mv_ciro SELECT bolge, SUM(tutar) FROM satislar GROUP BY bolge;","note":"Native materialized view desteği yoktur. Özet (summary) tablo tutulur; trigger'larla anlık ya da EVENT SCHEDULER ile periyodik olarak yeniden doldurulur.","danger":"caution","priv":"CREATE, EVENT on şema"},"mssql":{"command":"-- Indexed view (materialized view karşılığı)\nCREATE VIEW dbo.mv_ciro WITH SCHEMABINDING AS\nSELECT bolge, SUM(ISNULL(tutar, 0)) AS toplam, COUNT_BIG(*) AS adet\nFROM dbo.satislar GROUP BY bolge;\nGO\nCREATE UNIQUE CLUSTERED INDEX ix_mv_ciro ON dbo.mv_ciro (bolge);","note":"SQL Server'da indexed view kullanılır: WITH SCHEMABINDING zorunlu, unique clustered index oluşturulunca veri fiziksel olarak saklanır ve otomatik güncellenir (ayrı REFRESH gerekmez). GROUP BY varsa COUNT_BIG(*) şarttır; SUM içindeki sütun NULL olabiliyorsa SUM(ISNULL(tutar, 0)) yazılmalıdır (aksi halde 8662 hatası). View QUOTED_IDENTIFIER ve ANSI_NULLS ON iken oluşturulmalıdır. Sorgu iyileştiricinin view'ı otomatik eşleştirmesi yalnızca Enterprise (ve Developer) sürümündedir; Standard'da view'a WITH (NOEXPAND) hint'iyle başvurun.","danger":"caution","priv":"CREATE VIEW, ALTER on şema"},"mongodb":{"command":"// On-demand materialized view: $merge ile sonucu koleksiyona yaz\ndb.satislar.aggregate([\n  { $group: { _id: \"$bolge\", toplam: { $sum: \"$tutar\" } } },\n  { $merge: { into: \"mv_ciro\", whenMatched: \"replace\", whenNotMatched: \"insert\" } }\n]);","note":"$out veya $merge ile aggregation sonucu kalıcı koleksiyona yazılarak on-demand materialized view elde edilir. Tazeleme için pipeline yeniden çalıştırılır (elle veya zamanlayıcıyla).","danger":"caution"},"redis":{"command":"# Uygulanamaz: Redis'te materialized view yoktur. Hesaplanmış sonuç bir anahtara\n# yazılıp TTL ile önbelleklenir.\nSET mv:ciro:bolge1 12345 EX 3600","note":"Materialized view kavramı yoktur; en yakın yaklaşım önceden hesaplanmış değerleri anahtarlarda (String/Hash/Sorted Set) tutmak ve EX/TTL ile süreli önbelleklemektir.","danger":"safe"},"elasticsearch":{"command":"# Transform ile sürekli/materyalize edilmiş özet index\nPUT _transform/mv_ciro\n{ \"source\": { \"index\": \"satislar\" },\n  \"dest\": { \"index\": \"mv_ciro\" },\n  \"pivot\": { \"group_by\": { \"bolge\": { \"terms\": { \"field\": \"bolge\" } } },\n            \"aggregations\": { \"toplam\": { \"sum\": { \"field\": \"tutar\" } } } } }\nPOST _transform/mv_ciro/_start","note":"Transform, kaynak index'i pivotlayıp özet bir hedef index'e materyalize eder. Bu örnek batch transform'dur: _start ile bir kez çalışır ve durur. Yeni veriler geldikçe otomatik güncellenen sürekli (continuous) transform için yapılandırmaya bir zaman alanıyla \"sync\": { \"time\": { \"field\": \"<zaman_alanı>\", \"delay\": \"60s\" } } eklenir (continuous: true diye bir ayar yoktur).","danger":"caution"}}},{"id":"rename-object","title":"Tablo / nesne yeniden adlandır","aliases":["rename","yeniden adlandır","ad değiştir","rename table","sp_rename"],"engines":{"oracle":{"command":"-- Tablo\nALTER TABLE eski_ad RENAME TO yeni_ad;\n-- veya\nRENAME eski_ad TO yeni_ad;\n-- Kolon\nALTER TABLE musteri RENAME COLUMN ad TO adi;","note":"Tablo/view/sequence için RENAME veya ALTER ... RENAME TO kullanılır. Bağımlı nesneler (view, sinonim) geçersiz olabilir; yeniden derlenmeleri gerekir.","danger":"caution","priv":"ALTER on nesne"},"postgres":{"command":"ALTER TABLE eski_ad RENAME TO yeni_ad;\nALTER TABLE musteri RENAME COLUMN ad TO adi;\nALTER VIEW eski_view RENAME TO yeni_view;","note":"ALTER ... RENAME TO çoğu nesne tipi için çalışır. Foreign key ve index referansları isim değişse de otomatik korunur (OID tabanlı).","danger":"caution","priv":"tablo sahibi"},"mysql":{"command":"RENAME TABLE eski_ad TO yeni_ad;\n-- veya\nALTER TABLE eski_ad RENAME TO yeni_ad;\n-- Kolon (8.0+)\nALTER TABLE musteri RENAME COLUMN ad TO adi;","note":"RENAME TABLE atomiktir ve tek komutta birden çok tabloyu taşıyabilir. Kolon yeniden adlandırma için 8.0+ RENAME COLUMN; öncesinde CHANGE ile tip de belirtilmelidir.","danger":"caution","priv":"ALTER, DROP on eski; CREATE, INSERT on yeni"},"mssql":{"command":"-- Tablo\nEXEC sp_rename 'dbo.eski_ad', 'yeni_ad';\n-- Kolon\nEXEC sp_rename 'dbo.musteri.ad', 'adi', 'COLUMN';","note":"SQL Server'da RENAME TABLE deyimi yoktur; sistem yordamı sp_rename kullanılır. Tablo adında şema öneki verilir ama yeni adda verilmez. Bağımlı view/proc'lar elle güncellenmelidir.","danger":"caution","priv":"ALTER on nesne, CONTROL"},"mongodb":{"command":"// Koleksiyon yeniden adlandır\ndb.eski_ad.renameCollection(\"yeni_ad\");\n// veya admin komutu\ndb.adminCommand({ renameCollection: \"db.eski_ad\", to: \"db.yeni_ad\" });","note":"renameCollection ile koleksiyon adı değişir. Alan (field) yeniden adlandırmak için updateMany ile $rename operatörü kullanılır. Sharded koleksiyonlar 5.0+ sürümlerde yeniden adlandırılabilir; daha eski sürümlerde desteklenmez.","danger":"caution","priv":"renameCollectionSameDB / clusterManager"},"redis":{"command":"# Anahtar yeniden adlandır\nRENAME eski_anahtar yeni_anahtar\n# Hedef varsa üzerine yazmadan\nRENAMENX eski_anahtar yeni_anahtar","note":"RENAME anahtarı yeniden adlandırır; hedef zaten varsa üzerine yazar. RENAMENX yalnızca hedef yoksa çalışır. Kaynak anahtar yoksa hata döner.","danger":"caution"},"elasticsearch":{"command":"# Index doğrudan yeniden adlandırılamaz; reindex + alias yaklaşımı\nPOST _reindex\n{ \"source\": { \"index\": \"eski_ad\" }, \"dest\": { \"index\": \"yeni_ad\" } }\nDELETE eski_ad\n# veya kesintisiz geçiş için alias kullanın\nPOST _aliases\n{ \"actions\": [ { \"add\": { \"index\": \"yeni_ad\", \"alias\": \"musteri\" } } ] }","note":"Index yeniden adlandırma komutu yoktur. Yeni ada _reindex edilip eskisi silinir. Uygulamayı isimden bağımsız tutmak için sabit bir alias arkasında çalışmak önerilir.","danger":"caution"}}}]},"rosetta/datamove.json":{"category":"Veri Taşıma","categoryId":"datamove","order":11,"concepts":[{"id":"bulk-import","title":"Toplu veri yükle (CSV / dosyadan)","aliases":["import","toplu yükle","csv yükle","bulk insert","load data","copy from","içe aktar"],"engines":{"oracle":{"command":"-- SQL*Loader (kabuktan)\nsqlldr kullanici/parola control=musteri.ctl log=yukle.log\n\n-- musteri.ctl içeriği:\n-- LOAD DATA INFILE 'musteri.csv'\n-- INTO TABLE musteri FIELDS TERMINATED BY ','\n-- (id, ad, email)\n\n-- Alternatif: external table ile\nCREATE TABLE ext_musteri (id NUMBER, ad VARCHAR2(100))\nORGANIZATION EXTERNAL (TYPE ORACLE_LOADER DEFAULT DIRECTORY dir_csv\n  ACCESS PARAMETERS (FIELDS TERMINATED BY ',') LOCATION ('musteri.csv'));","note":"En yaygın araç SQL*Loader'dır (control dosyasıyla). Dosyayı sorgu gibi okumak için external table kullanılır. Büyük hacimde direct path load (DIRECT=TRUE) hızlıdır.","danger":"caution","priv":"INSERT on tablo, DIRECTORY nesnesi"},"postgres":{"command":"-- Sunucu tarafı (dosya sunucuda, superuser/pg_read_server_files gerekir)\nCOPY musteri (id, ad, email) FROM '/veri/musteri.csv' WITH (FORMAT csv, HEADER true);\n\n-- İstemci tarafı (psql, dosya istemcide)\n\\copy musteri (id, ad, email) FROM 'musteri.csv' WITH (FORMAT csv, HEADER true)","note":"COPY sunucudaki dosyayı okur ve yetki ister; psql \\copy ise istemci dosyasını okur, ek yetki gerekmez. CSV yüklemenin en hızlı yoludur.","danger":"caution","priv":"INSERT on tablo (COPY için pg_read_server_files)"},"mysql":{"command":"-- Sunucu tarafı\nLOAD DATA INFILE '/veri/musteri.csv' INTO TABLE musteri\nFIELDS TERMINATED BY ',' ENCLOSED BY '\"' LINES TERMINATED BY '\\n' IGNORE 1 LINES;\n\n-- İstemci dosyasından\nLOAD DATA LOCAL INFILE 'musteri.csv' INTO TABLE musteri\nFIELDS TERMINATED BY ',' IGNORE 1 LINES;","note":"LOAD DATA INFILE toplu yüklemenin en hızlı yoludur. LOCAL istemci dosyasını okur ve hem sunucuda (local_infile=ON) hem istemcide etkinleştirilmelidir. secure_file_priv sunucu yolunu kısıtlar.","danger":"caution","priv":"FILE (LOCAL için INSERT)"},"mssql":{"command":"-- T-SQL BULK INSERT\nBULK INSERT musteri FROM 'C:\\veri\\musteri.csv'\nWITH (FORMAT='CSV', FIRSTROW=2, FIELDTERMINATOR=',', ROWTERMINATOR='0x0a');\n\n-- Kabuktan bcp\nbcp veritabani.dbo.musteri in musteri.csv -c -t, -S sunucu -T","note":"BULK INSERT dosyayı SQL Server servis hesabının erişebildiği yoldan okur. bcp komut satırı aracıdır; -c karakter modu, -t alan ayırıcı. En hızlısı için TABLOCK ile minimal logging hedeflenir.","danger":"caution","priv":"INSERT, ADMINISTER BULK OPERATIONS"},"mongodb":{"command":"# CSV / JSON içe aktar (kabuktan)\nmongoimport --db=magaza --collection=musteri --type=csv --headerline --file=musteri.csv\n\n# JSON dizisi için\nmongoimport --db=magaza --collection=musteri --file=musteri.json --jsonArray","note":"mongoimport CSV/TSV/JSON yükler; --headerline ilk satırı alan adı sayar. Var olan kayıtları güncellemek için --mode=upsert --upsertFields kullanılır. Büyük veride --numInsertionWorkers hızlandırır.","danger":"caution","priv":"insert (readWrite)"},"redis":{"command":"# En hızlı: protokol biçiminde besleyip pipe et\ncat komutlar.txt | redis-cli --pipe\n\n# komutlar.txt satırları örn:\n# SET musteri:1 \"Ali\"\n# SET musteri:2 \"Veli\"","note":"Toplu yükleme için redis-cli --pipe (mass insert) kullanılır; RESP protokol biçimindeki komutları tek bağlantıdan akıtarak çok hızlıdır. Alternatif olarak pipeline ile komutlar gruplanır.","danger":"caution"},"elasticsearch":{"command":"# _bulk API (NDJSON: her doküman için işlem + kaynak satırı)\ncurl -s -H 'Content-Type: application/x-ndjson' -XPOST 'localhost:9200/musteri/_bulk' --data-binary @veri.ndjson\n\n# veri.ndjson içeriği:\n# { \"index\": {} }\n# { \"id\": 1, \"ad\": \"Ali\" }\n# { \"index\": {} }\n# { \"id\": 2, \"ad\": \"Veli\" }","note":"_bulk API NDJSON alır (her belge için işlem satırı + veri satırı, dosya \\n ile bitmeli). CSV için Logstash, Filebeat veya elasticdump kullanılır. Yükleme sırasında refresh_interval'i kapatmak hızlandırır.","danger":"caution","priv":"index / create index yetkisi"}}},{"id":"bulk-export","title":"Veriyi dışa aktar (CSV / dosyaya)","aliases":["export","dışa aktar","csv çıkar","copy to","outfile","dump","veri çıkar"],"engines":{"oracle":{"command":"-- SQL*Plus ile CSV (spool)\nSET MARKUP CSV ON\nSPOOL musteri.csv\nSELECT id, ad, email FROM musteri;\nSPOOL OFF\n\n-- Data Pump ile mantıksal yedek (kabuktan)\nexpdp kullanici/parola tables=musteri directory=dir_dmp dumpfile=musteri.dmp","note":"CSV için SQL*Plus SET MARKUP CSV ON + SPOOL kullanılır (12.2+). Şema/tablo taşımak için Data Pump (expdp) ikili .dmp üretir; başka Oracle'a impdp ile alınır.","danger":"safe","readonly":true,"priv":"SELECT on tablo","minver":"MARKUP CSV için 12.2"},"postgres":{"command":"-- Sunucu tarafı\nCOPY (SELECT id, ad, email FROM musteri) TO '/veri/musteri.csv' WITH (FORMAT csv, HEADER true);\n\n-- İstemci tarafı (psql)\n\\copy (SELECT id, ad, email FROM musteri) TO 'musteri.csv' WITH (FORMAT csv, HEADER true)","note":"COPY ... TO sorgu sonucunu dosyaya yazar (sunucu tarafı, yetki ister); psql \\copy istemci dosyasına yazar. HEADER true başlık satırı ekler.","danger":"safe","readonly":true,"priv":"SELECT on tablo"},"mysql":{"command":"-- Sunucu tarafı dosyaya\nSELECT id, ad, email FROM musteri\nINTO OUTFILE '/veri/musteri.csv'\nFIELDS TERMINATED BY ',' ENCLOSED BY '\"' LINES TERMINATED BY '\\n';\n\n-- İstemciye: mysql -e ... > dosya (sekme ayraçlı)\n-- mysql -e \"SELECT * FROM musteri\" magaza > musteri.tsv","note":"SELECT ... INTO OUTFILE dosyayı sunucuda oluşturur (secure_file_priv yolu ve FILE yetkisi gerekir, üzerine yazamaz). İstemci tarafına çıktı için mysql -e ile yönlendirme kullanılır.","danger":"safe","readonly":true,"priv":"SELECT, FILE"},"mssql":{"command":"-- bcp ile dışa aktar (kabuktan)\nbcp \"SELECT id, ad, email FROM magaza.dbo.musteri\" queryout musteri.csv -c -t, -S sunucu -T\n\n-- veya tüm tablo\nbcp magaza.dbo.musteri out musteri.dat -n -S sunucu -T","note":"bcp out/queryout ile veri dosyaya yazılır: -c karakter modu, -t, alan ayırıcı, -n native ikili biçim. Sorgu sonucu için queryout kullanılır. SSMS'de 'Results to File' da bir seçenektir.","danger":"safe","readonly":true,"priv":"SELECT on tablo"},"mongodb":{"command":"# CSV dışa aktar (alanları belirtmek gerekir)\nmongoexport --db=magaza --collection=musteri --type=csv --fields=id,ad,email --out=musteri.csv\n\n# JSON olarak\nmongoexport --db=magaza --collection=musteri --out=musteri.json","note":"mongoexport CSV/JSON üretir; CSV'de --fields ile kolonlar açıkça verilmelidir. Sorguyla filtreleme için --query kullanılır. İkili tam yedek için mongodump tercih edilir.","danger":"safe","readonly":true,"priv":"find (read)"},"redis":{"command":"# Anahtarları tara (üretimde KEYS yerine SCAN)\nredis-cli --scan --pattern 'musteri:*' > anahtarlar.txt\n\n# Tam veri yedeği için RDB snapshot'ını istemci tarafına indir (bloklamaz)\nredis-cli --rdb ./dump.rdb","note":"Yapılandırılmış CSV dışa aktarımı yerleşik değildir. Anahtar listesi için --scan (bloklamayan), tam veri için RDB dosyası kullanılır: redis-cli --rdb sunucudan arka planda üretilen snapshot'ı yerel dosyaya indirir; sunucuda dosya istiyorsanız BGSAVE kullanın. SAVE ana thread'i bloklar, üretimde kullanmayın. Değerleri de almak için scan sonucu döngüyle okunur.","danger":"safe","readonly":true},"elasticsearch":{"command":"# elasticdump ile dışa aktar\nelasticdump --input=http://localhost:9200/musteri --output=musteri.json --type=data\n\n# Büyük veride scroll / point-in-time ile sayfalı okuma\nGET musteri/_search?scroll=1m\n{ \"size\": 1000, \"query\": { \"match_all\": {} } }","note":"Doğrudan CSV export yoktur. Tüm veriyi almak için elasticdump ya da scroll/PIT (point-in-time) ile sayfalayarak _search kullanılır. CSV'ye çevirmek için Logstash csv output veya harici araç gerekir.","danger":"safe","readonly":true,"priv":"read on index"}}},{"id":"copy-between","title":"Tablolar / ortamlar arası veri kopyala","aliases":["copy","kopyala","insert select","ctas","reindex","veri taşı","tablolar arası"],"engines":{"oracle":{"command":"-- Var olan tabloya\nINSERT INTO hedef (id, ad) SELECT id, ad FROM kaynak WHERE durum = 'AKTIF';\n\n-- Yeni tablo oluşturarak (CTAS)\nCREATE TABLE hedef AS SELECT * FROM kaynak;\n\n-- Uzak veritabanından database link ile\nINSERT INTO hedef SELECT * FROM kaynak@uzak_db;","note":"Aynı veritabanında INSERT ... SELECT veya CREATE TABLE AS SELECT (CTAS) kullanılır. Ortamlar arası kopyada database link (@uzak_db) veya Data Pump tercih edilir. APPEND hint direct-path ile hızlandırır.","danger":"caution","priv":"SELECT on kaynak, INSERT/CREATE on hedef"},"postgres":{"command":"-- Aynı veritabanı\nINSERT INTO hedef (id, ad) SELECT id, ad FROM kaynak;\nCREATE TABLE hedef AS SELECT * FROM kaynak;\n\n-- Ortamlar arası (psql pipe ile)\n-- pg_dump -t kaynak kaynakdb | psql hedefdb\n-- veya postgres_fdw ile uzak tabloyu okuyup INSERT","note":"Aynı DB içinde INSERT ... SELECT / CTAS kullanılır. Sunucular arası için pg_dump | psql boru hattı ya da postgres_fdw ile foreign table üzerinden kopyalama yapılır.","danger":"caution","priv":"SELECT on kaynak, INSERT/CREATE on hedef"},"mysql":{"command":"-- Aynı veritabanı\nINSERT INTO hedef (id, ad) SELECT id, ad FROM kaynak;\nCREATE TABLE hedef AS SELECT * FROM kaynak;\n\n-- Sunucular arası (mysqldump pipe)\n-- mysqldump kaynakdb kaynak | mysql -h hedefsunucu hedefdb","note":"Aynı DB'de INSERT ... SELECT veya CREATE TABLE ... AS SELECT. Farklı sunucular arasında mysqldump çıktısını mysql istemcisine boru ile aktarmak yaygındır. CTAS index ve constraint'leri kopyalamaz.","danger":"caution","priv":"SELECT on kaynak, INSERT/CREATE on hedef"},"mssql":{"command":"-- Var olan tabloya\nINSERT INTO hedef (id, ad) SELECT id, ad FROM kaynak;\n\n-- Yeni tablo oluşturarak\nSELECT * INTO hedef FROM kaynak;\n\n-- Sunucular arası: linked server\nINSERT INTO hedef SELECT * FROM [UZAK_SRV].magaza.dbo.kaynak;","note":"SQL Server'da yeni tabloya kopyalama SELECT ... INTO ile yapılır (CTAS karşılığı). Sunucular arası için linked server (dört parçalı ad) ya da bcp out/in veya SSIS kullanılır.","danger":"caution","priv":"SELECT on kaynak, INSERT / CREATE TABLE on hedef"},"mongodb":{"command":"// Aggregation sonucunu başka koleksiyona yaz\ndb.kaynak.aggregate([\n  { $match: { durum: \"AKTIF\" } },\n  { $out: \"hedef\" }\n]);\n\n// Var olan koleksiyona birleştir (upsert)\ndb.kaynak.aggregate([ { $merge: { into: \"hedef\", whenMatched: \"merge\", whenNotMatched: \"insert\" } } ]);","note":"$out hedef koleksiyonu tamamen değiştirir; $merge var olan belgelerle birleştirir/ekler (aynı veya başka DB). Sunucular arası taşımada mongodump | mongorestore veya mongoexport/mongoimport kullanılır.","danger":"caution","priv":"find on kaynak, insert on hedef"},"redis":{"command":"# Tek anahtarı başka sunucuya taşı (kaynaktan silinir)\nMIGRATE hedef_host 6379 musteri:1 0 5000\n\n# Kopyalamak için (silmeden): DUMP + RESTORE\nDUMP musteri:1          # serileştirilmiş değeri döndürür\nRESTORE musteri:1yeni 0 \"<dump-verisi>\"","note":"MIGRATE anahtarı hedef instance'a atomik taşır ve kaynaktan siler (COPY seçeneği ile silmez). Aynı instance içinde kopya için COPY komutu (6.0+) ya da DUMP+RESTORE kullanılır.","danger":"caution"},"elasticsearch":{"command":"# Aynı küme içinde\nPOST _reindex\n{ \"source\": { \"index\": \"kaynak\" }, \"dest\": { \"index\": \"hedef\" } }\n\n# Uzak kümeden (remote reindex; whitelist ayarı gerekir)\nPOST _reindex\n{ \"source\": { \"remote\": { \"host\": \"http://uzak:9200\" }, \"index\": \"kaynak\" },\n  \"dest\": { \"index\": \"hedef\" } }","note":"_reindex index'ler arası kopyalar; sorguyla filtrelenebilir ve script ile dönüştürülebilir. Kümeler arası için remote reindex kullanılır (hedefte reindex.remote.whitelist tanımlı olmalı). Büyük işler için slices ile paralelleştirilir.","danger":"caution","priv":"read on kaynak, write on hedef"}}},{"id":"generate-insert","title":"Veriyi INSERT script olarak üret","aliases":["generate insert","insert script","script üret","data dump","inserts","betik üret"],"engines":{"oracle":{"command":"-- Nesne DDL'i için DBMS_METADATA\nSELECT DBMS_METADATA.GET_DDL('TABLE','MUSTERI') FROM dual;\n\n-- Satır verisini INSERT olarak üretmek yerleşik değildir;\n-- SQL Developer 'Export > Insert' ya da SQLcl 'SET SQLFORMAT INSERT' kullanılır:\n-- SET SQLFORMAT INSERT\n-- SELECT * FROM musteri;","note":"Oracle veriyi hazır INSERT betiğine doğrudan çeviren bir SQL komutu sunmaz. DDL için DBMS_METADATA.GET_DDL; satır INSERT'leri için SQLcl (SET SQLFORMAT INSERT) veya SQL Developer'ın Export sihirbazı kullanılır.","danger":"safe","readonly":true,"priv":"SELECT on tablo"},"postgres":{"command":"-- Yalnızca veriyi INSERT deyimleri olarak\npg_dump --data-only --inserts --table=musteri magaza > insert.sql\n\n-- Kolon adlı ve daha hızlı yüklenen biçim\npg_dump --data-only --column-inserts --table=musteri magaza > insert.sql","note":"pg_dump --inserts her satırı ayrı INSERT olarak yazar; --column-inserts kolon adlarını da ekler (şema farklarına dayanıklı). Varsayılan (bayrak yok) COPY biçimi üretir ve çok daha hızlı yüklenir.","danger":"safe","readonly":true,"priv":"SELECT on tablo"},"mysql":{"command":"-- Yalnızca veri (INSERT'ler), tablo tanımı olmadan\nmysqldump --no-create-info magaza musteri > insert.sql\n\n-- Her satır ayrı INSERT olsun (daha okunur)\nmysqldump --no-create-info --skip-extended-insert magaza musteri > insert.sql","note":"mysqldump varsayılan olarak INSERT deyimleri üretir; --no-create-info CREATE TABLE'ı atlar, yalnızca veri verir. --skip-extended-insert her satırı ayrı INSERT yapar (varsayılan çok satırı tek deyimde birleştirir).","danger":"safe","readonly":true,"priv":"SELECT on tablo"},"mssql":{"command":"-- SSMS: sağ tık > Tasks > Generate Scripts >\n--   Advanced > 'Types of data to script' = Data only (veya Schema and data)\n\n-- Komut satırı alternatifi (sqlpackage / mssql-scripter aracı)\n-- mssql-scripter -S sunucu -d magaza -t musteri --data-only > insert.sql","note":"SQL Server'da yerleşik T-SQL komutu yoktur. En yaygın yol SSMS 'Generate Scripts' sihirbazında Data only seçmektir. Komut satırında Microsoft'un mssql-scripter aracı --data-only ile INSERT üretir.","danger":"safe","readonly":true,"priv":"SELECT on tablo"},"mongodb":{"command":"# INSERT SQL yerine ikili/BSON yedek üretilir\nmongodump --db=magaza --collection=musteri --out=./yedek\n\n# JSON metni olarak (insertMany'e uyarlanabilir)\nmongoexport --db=magaza --collection=musteri --jsonArray --out=musteri.json","note":"SQL INSERT kavramı yoktur. Taşınabilir yedek için mongodump (BSON, mongorestore ile geri yüklenir). Kod içine gömülecek insertMany için mongoexport --jsonArray çıktısı kullanılabilir.","danger":"safe","readonly":true,"priv":"find (read)"},"redis":{"command":"# Tek anahtarın taşınabilir serileştirmesi\nDUMP musteri:1\n# Çıktı RESTORE ile geri yüklenir:\n# RESTORE musteri:1 0 \"<dump-verisi>\"\n\n# Tüm veri için RDB snapshot'ı\nredis-cli --rdb dump.rdb","note":"SQL INSERT betiği üretilmez. Anahtar bazında DUMP + RESTORE serileştirmesi, tüm veri için RDB (--rdb) dosyası kullanılır. Komut listesi üretmek istenirse SCAN ile gezip her tip için uygun SET/HSET komutları oluşturulur.","danger":"safe","readonly":true},"elasticsearch":{"command":"# INSERT karşılığı _bulk NDJSON'dur; elasticdump ile üretilir\nelasticdump --input=http://localhost:9200/musteri --output=musteri_bulk.json --type=data\n\n# Manuel: _search sonucunu _bulk NDJSON'a dönüştürmek için harici script gerekir","note":"SQL INSERT üretilmez; Elasticsearch'te yükleme birimi _bulk NDJSON'dur. Var olan veriyi tekrar yüklenebilir biçimde almak için elasticdump (type=data) kullanılır; _search + PIT çıktısı harici bir betikle NDJSON'a çevrilebilir.","danger":"safe","readonly":true,"priv":"read on index"}}}]},"rosetta/monitoring.json":{"category":"İzleme & Tanı","categoryId":"monitoring","order":12,"concepts":[{"id":"current-locks","title":"Anlık lock'ları listele","aliases":["locks","kilitler","lock list","current locks","anlık kilitler"],"engines":{"oracle":{"command":"SELECT s.sid, s.serial#, l.type, DECODE(l.lmode,0,'None',1,'Null',2,'Row-S',3,'Row-X',4,'Share',5,'S/Row-X',6,'Exclusive') AS lmode, o.object_name, s.username, s.blocking_session\nFROM v$lock l\nJOIN v$session s ON s.sid = l.sid\nLEFT JOIN v$locked_object lo ON lo.session_id = l.sid\nLEFT JOIN dba_objects o ON o.object_id = lo.object_id\nORDER BY s.sid;","note":"v$lock ve v$locked_object üzerinden aktif lock'ları ve bloklayan oturumu (blocking_session) gösterir.","danger":"safe","readonly":true,"priv":"SELECT on v$lock, v$session"},"postgres":{"command":"SELECT l.locktype, l.mode, l.granted, a.pid, a.usename, a.state, a.wait_event_type, a.query\nFROM pg_locks l\nJOIN pg_stat_activity a ON a.pid = l.pid\nWHERE l.pid <> pg_backend_pid()\nORDER BY l.granted, a.pid;","note":"pg_locks ile pg_stat_activity birleştirilir; granted=false satırlar bekleyen (bloklanan) lock'ları gösterir.","danger":"safe","readonly":true,"priv":"pg_monitor rolü (tüm sorguları görmek için)"},"mysql":{"command":"SELECT ENGINE, OBJECT_SCHEMA, OBJECT_NAME, LOCK_TYPE, LOCK_MODE, LOCK_STATUS, THREAD_ID\nFROM performance_schema.data_locks;\n-- Bekleyenler için: SELECT * FROM performance_schema.data_lock_waits;","note":"performance_schema.data_locks anlık InnoDB lock'larını, data_lock_waits ise bekleme ilişkilerini listeler.","danger":"safe","readonly":true,"priv":"SELECT on performance_schema","minver":"8.0"},"mssql":{"command":"SELECT tl.resource_type, tl.resource_database_id, tl.request_mode, tl.request_status, tl.request_session_id, es.login_name, er.blocking_session_id\nFROM sys.dm_tran_locks tl\nLEFT JOIN sys.dm_exec_sessions es ON es.session_id = tl.request_session_id\nLEFT JOIN sys.dm_exec_requests er ON er.session_id = tl.request_session_id\nORDER BY tl.request_session_id;","note":"sys.dm_tran_locks anlık lock isteklerini; request_status = WAIT olanlar bloklanan istekleri gösterir.","danger":"safe","readonly":true,"priv":"VIEW SERVER STATE"},"mongodb":{"command":"db.currentOp({ \"$or\": [ { \"waitingForLock\": true }, { \"locks\": { \"$exists\": true } } ] })","note":"db.currentOp lock bekleyen (waitingForLock) ve lock tutan işlemleri gösterir; MongoDB satır değil belge/koleksiyon seviyesinde kilitler.","danger":"safe","priv":"inprog / clusterMonitor rolü"},"redis":{"command":"# Uygulanamaz: Redis'te satır/tablo kilidi kavramı yoktur; komutlar tek thread'de sırayla yürütülür. Bloklama analizi için SLOWLOG ve LATENCY komutlarına bakın.","note":"Redis tek thread'li olduğu için geleneksel lock listesi yoktur.","danger":"safe"},"elasticsearch":{"command":"GET _cluster/pending_tasks","note":"Elasticsearch'te row lock yoktur; master üzerinde sıraya girmiş küme değişiklik görevlerini (pending tasks) listeler.","danger":"safe","readonly":true}}},{"id":"long-operations","title":"Uzun işlemlerin ilerlemesini gör (progress)","aliases":["progress","ilerleme","long operations","uzun işlemler","longops"],"engines":{"oracle":{"command":"SELECT sid, serial#, opname, target, sofar, totalwork,\n       ROUND(sofar / NULLIF(totalwork,0) * 100, 2) AS pct_done,\n       time_remaining, elapsed_seconds\nFROM v$session_longops\nWHERE totalwork > 0 AND sofar < totalwork\nORDER BY start_time;","note":"v$session_longops 6 saniyeden uzun süren işlemlerin yüzde ilerlemesini ve kalan süresini (time_remaining) gösterir.","danger":"safe","readonly":true,"priv":"SELECT on v$session_longops"},"postgres":{"command":"SELECT pid, phase, heap_blks_total, heap_blks_scanned,\n       ROUND(heap_blks_scanned::numeric / NULLIF(heap_blks_total,0) * 100, 2) AS pct\nFROM pg_stat_progress_vacuum;\n-- Diğerleri: pg_stat_progress_create_index, _cluster, _analyze, _copy, _basebackup","note":"pg_stat_progress_* view'ları VACUUM, CREATE INDEX, CLUSTER, ANALYZE ve COPY işlemlerinin ilerlemesini verir.","danger":"safe","readonly":true,"minver":"9.6"},"mysql":{"command":"SELECT t.processlist_id, st.event_name, st.work_completed, st.work_estimated,\n       ROUND(st.work_completed / NULLIF(st.work_estimated,0) * 100, 2) AS pct\nFROM performance_schema.events_stages_current st\nJOIN performance_schema.threads t ON t.thread_id = st.thread_id\nWHERE st.work_estimated > 0;","note":"events_stages_current, aşama (stage) izleme açıksa work_completed/work_estimated ile ilerlemeyi gösterir (ör. ALTER TABLE).","danger":"safe","readonly":true,"priv":"SELECT on performance_schema"},"mssql":{"command":"SELECT session_id, command, percent_complete,\n       DATEADD(ms, estimated_completion_time, GETDATE()) AS est_finish,\n       total_elapsed_time / 1000 AS elapsed_sec\nFROM sys.dm_exec_requests\nWHERE percent_complete > 0\nORDER BY percent_complete;","note":"sys.dm_exec_requests.percent_complete BACKUP, RESTORE, DBCC, index yeniden oluşturma gibi işlemlerin yüzdesini verir.","danger":"safe","readonly":true,"priv":"VIEW SERVER STATE"},"mongodb":{"command":"db.currentOp({ \"active\": true, \"secs_running\": { \"$gte\": 3 } })","note":"db.currentOp çıktısında uzun süren işlemler ve index oluşturmalarda 'progress' alanı (done/total) ilerlemeyi gösterir.","danger":"safe","priv":"inprog / clusterMonitor rolü"},"redis":{"command":"INFO persistence\n# Anahtarlar: rdb_bgsave_in_progress, aof_rewrite_in_progress, rdb_last_bgsave_status, loading, loading_loaded_perc","note":"INFO persistence bölümü RDB/AOF kaydetme veya yeniden yazma işlemlerinin sürüp sürmediğini ve yükleme yüzdesini bildirir.","danger":"safe","readonly":true},"elasticsearch":{"command":"GET _tasks?detailed=true&actions=*reindex,*update/byquery,*delete/byquery\n# Kurtarma/parça taşıma için: GET _cat/recovery?v&active_only=true","note":"_tasks?detailed uzun görevlerin (reindex, update_by_query) durumunu; _cat/recovery aktif parça kurtarma ilerlemesini gösterir.","danger":"safe","readonly":true}}},{"id":"session-trace","title":"Bir oturumu / sorguyu izle (trace / profil aç)","aliases":["trace","izleme aç","profiling","session trace","sorgu izleme"],"engines":{"oracle":{"command":"-- Belirli bir oturum için (10046 olay izleme):\nBEGIN\n  DBMS_MONITOR.SESSION_TRACE_ENABLE(session_id => 123, serial_num => 4567, waits => TRUE, binds => TRUE);\nEND;\n/\n-- Kapatmak için: DBMS_MONITOR.SESSION_TRACE_DISABLE(123, 4567);","note":"DBMS_MONITOR.SESSION_TRACE_ENABLE oturum için 10046 izleme dosyası üretir; iş bitince mutlaka kapatın (izleme yükü ve disk kullanımı olur).","danger":"caution","priv":"EXECUTE on DBMS_MONITOR"},"postgres":{"command":"LOAD 'auto_explain';\nSET auto_explain.log_min_duration = 0;\nSET auto_explain.log_analyze = true;\n-- Basit alternatif: SET log_min_duration_statement = 0;","note":"auto_explain sorgu planlarını, log_min_duration_statement ise yavaş/tüm sorguları log dosyasına yazar; 0 değeri her sorguyu loglar, log hacmine dikkat.","danger":"caution","priv":"SUPERUSER (LOAD için) veya oturum düzeyinde SET"},"mysql":{"command":"-- performance_schema yaklaşımı (önerilen):\nUPDATE performance_schema.setup_consumers SET ENABLED='YES' WHERE NAME LIKE 'events_statements%';\n-- Eski/basit yöntem (kullanımdan kaldırılıyor):\nSET profiling = 1;\n-- sorguyu çalıştır, sonra:\nSHOW PROFILES;","note":"performance_schema events_statements ile sorgu izleme yapılır; SET profiling yöntemi eskidir (deprecated) ama oturum bazında hızlı ölçüm sağlar.","danger":"caution","priv":"SELECT/UPDATE on performance_schema"},"mssql":{"command":"CREATE EVENT SESSION [trace_slow] ON SERVER\nADD EVENT sqlserver.sql_statement_completed(\n  WHERE duration > 1000000)\nADD TARGET package0.event_file(SET filename=N'trace_slow.xel');\nGO\nALTER EVENT SESSION [trace_slow] ON SERVER STATE = START;","note":"Extended Events (XEvents) modern izleme yöntemidir; oturumu oluşturup START ile başlatın, iş bitince STOP/DROP ile durdurun.","danger":"caution","priv":"ALTER ANY EVENT SESSION"},"mongodb":{"command":"db.setProfilingLevel(2)\n// 1 = yalnızca yavaş işlemler (slowms eşiği), 0 = kapalı\n// Sonuçlar: db.system.profile.find().sort({ ts: -1 }).limit(10)","note":"setProfilingLevel(2) tüm işlemleri system.profile koleksiyonuna kaydeder; üretimde 1 (yalnızca yavaş) tercih edilir, seviye 2 yük getirir.","danger":"caution","priv":"dbAdmin / enableProfiler"},"redis":{"command":"MONITOR\n# Sunucuya gelen tüm komutları gerçek zamanlı akıtır. Çıkış: Ctrl-C","note":"MONITOR tüm komutları canlı gösterir ancak ciddi başarım düşüşüne yol açar; üretimde kısa süreli ve dikkatli kullanın. Alternatif: SLOWLOG GET.","danger":"caution"},"elasticsearch":{"command":"GET my-index/_search\n{\n  \"profile\": true,\n  \"query\": { \"match\": { \"title\": \"elastic\" } }\n}\n// Kalıcı yavaş sorgu izleme: index.search.slowlog.threshold.query.warn ayarı","note":"\"profile\": true tek bir aramanın sorgu/toplama zaman dökümünü verir; sürekli izleme için slowlog eşikleri ayarlanır.","danger":"safe","readonly":true}}},{"id":"top-wait-events","title":"En çok beklenen olayları (wait events) gör","aliases":["wait events","bekleme olayları","top waits","beklemeler"],"engines":{"oracle":{"command":"SELECT event, total_waits, time_waited, ROUND(time_waited/100,2) AS sec_waited\nFROM v$system_event\nWHERE wait_class <> 'Idle'\nORDER BY time_waited DESC\nFETCH FIRST 20 ROWS ONLY;\n-- Anlık analiz için: v$active_session_history (ASH)","note":"v$system_event kümülatif wait event'leri; v$active_session_history son dakikalardaki aktif oturum örneklemesini verir (Diagnostics Pack lisansı gerekir).","danger":"safe","readonly":true,"priv":"SELECT on v$system_event"},"postgres":{"command":"SELECT wait_event_type, wait_event, count(*)\nFROM pg_stat_activity\nWHERE wait_event IS NOT NULL AND state = 'active'\nGROUP BY 1, 2\nORDER BY 3 DESC;","note":"pg_stat_activity anlık bekleme durumunu gösterir; örnekleyerek çağırmak (poll) en sık beklenen olayları ortaya çıkarır.","danger":"safe","readonly":true,"priv":"pg_monitor rolü"},"mysql":{"command":"SELECT event_name, count_star, sum_timer_wait,\n       ROUND(sum_timer_wait/1000000000000, 2) AS sec_waited\nFROM performance_schema.events_waits_summary_global_by_event_name\nWHERE count_star > 0\nORDER BY sum_timer_wait DESC\nLIMIT 20;","note":"events_waits_summary_global_by_event_name olay bazında toplam bekleme sürelerini (pikosaniye) verir; wait instrument'ları etkin olmalıdır.","danger":"safe","readonly":true,"priv":"SELECT on performance_schema"},"mssql":{"command":"SELECT wait_type, waiting_tasks_count, wait_time_ms,\n       signal_wait_time_ms, wait_time_ms - signal_wait_time_ms AS resource_wait_ms\nFROM sys.dm_os_wait_stats\nWHERE wait_time_ms > 0\nORDER BY wait_time_ms DESC;","note":"sys.dm_os_wait_stats örnek başlangıcından beri toplam bekleme türlerini gösterir; DBCC SQLPERF ile sıfırlanabilir.","danger":"safe","readonly":true,"priv":"VIEW SERVER STATE"},"mongodb":{"command":"db.serverStatus().wiredTiger.concurrentTransactions\n// Genel bekleme/tıkanma için:\n// db.serverStatus().globalLock  ve  db.serverStatus().wiredTiger.cache","note":"WiredTiger'da klasik wait event yoktur; concurrentTransactions (ticket) tükenmesi, globalLock.currentQueue ve cache baskısı tıkanmayı gösterir.","danger":"safe","priv":"clusterMonitor rolü"},"redis":{"command":"CONFIG SET latency-monitor-threshold 100\nLATENCY LATEST\nLATENCY HISTORY command\n# En yavaş komutlar için: SLOWLOG GET 10","note":"Gecikme izleme eşiği ayarlandıktan sonra LATENCY LATEST/HISTORY en çok gecikmeye neden olan olayları raporlar.","danger":"safe"},"elasticsearch":{"command":"GET _nodes/hot_threads","note":"_nodes/hot_threads en çok CPU harcayan thread'lerin stack trace'lerini vererek darboğazları gösterir.","danger":"safe","readonly":true}}},{"id":"os-resource","title":"Sunucu kaynak kullanımını DB içinden gör (CPU/IO)","aliases":["os resource","cpu io","kaynak kullanımı","sunucu kaynağı","system metrics"],"engines":{"oracle":{"command":"SELECT stat_name, value FROM v$osstat\nWHERE stat_name IN ('NUM_CPUS','BUSY_TIME','IDLE_TIME','IOWAIT_TIME','PHYSICAL_MEMORY_BYTES');\n-- Anlık metrikler: SELECT metric_name, value FROM v$sysmetric WHERE group_id = 2;","note":"v$osstat işletim sistemi CPU/bellek sayaçlarını; v$sysmetric son aralıktaki anlık DB metriklerini (CPU, IOPS) verir.","danger":"safe","readonly":true,"priv":"SELECT on v$osstat, v$sysmetric"},"postgres":{"command":"SELECT backend_type, object, context, reads, writes, hits, evictions\nFROM pg_stat_io\nORDER BY reads DESC;\n-- Not: CPU kullanımı DB içinden görünmez; OS aracı (top, sar) gerekir.","note":"pg_stat_io okuma/yazma/önbellek isabet sayaçlarını verir; PostgreSQL CPU kullanımını sunmaz, işletim sistemi araçları gerekir.","danger":"safe","readonly":true,"minver":"16"},"mysql":{"command":"SELECT * FROM sys.host_summary;\n-- InnoDB I/O ve thread detayları için:\nSHOW ENGINE INNODB STATUS\\G","note":"sys şeması özet view'ları (host_summary) IO/gecikme dökümü verir; SHOW ENGINE INNODB STATUS buffer pool ve IO etkinliğini gösterir.","danger":"safe","readonly":true,"priv":"SELECT on sys, PROCESS"},"mssql":{"command":"SELECT object_name, counter_name, cntr_value\nFROM sys.dm_os_performance_counters\nWHERE counter_name LIKE '%CPU%' OR counter_name LIKE '%Page life expectancy%';\n-- CPU geçmişi: sys.dm_os_ring_buffers (RING_BUFFER_SCHEDULER_MONITOR)","note":"sys.dm_os_performance_counters DB performans sayaçlarını; dm_os_ring_buffers son ~256 dakikanın SQL/diğer süreç CPU oranını verir.","danger":"safe","readonly":true,"priv":"VIEW SERVER STATE"},"mongodb":{"command":"db.serverStatus().metrics\n// İlgili alanlar: .opcounters, .network, .wiredTiger.cache, .mem, .extra_info.page_faults","note":"serverStatus() bellek, ağ, opcounters ve WiredTiger önbellek metriklerini verir; ayrıntılı OS CPU/IO için mongostat veya işletim sistemi araçları kullanılır.","danger":"safe","priv":"clusterMonitor rolü"},"redis":{"command":"INFO cpu\nINFO stats\n# used_cpu_sys, used_cpu_user, instantaneous_ops_per_sec, total_net_input_bytes","note":"INFO cpu Redis sürecinin CPU tüketimini, INFO stats saniyelik işlem ve ağ trafiğini raporlar.","danger":"safe","readonly":true},"elasticsearch":{"command":"GET _nodes/stats/os,process\n// os.cpu.percent, os.mem, process.cpu.percent, fs (disk) alanlarına bakın","note":"_nodes/stats/os,process düğüm bazında CPU yüzdesi, bellek ve süreç metriklerini verir; disk için fs bölümü kullanılır.","danger":"safe","readonly":true}}}]},"rosetta/automation.json":{"category":"Otomasyon & Denetim","categoryId":"automation","order":13,"concepts":[{"id":"schedule-job","title":"Zamanlanmış iş (job) oluştur","aliases":["schedule job","zamanlanmış iş","cron","job oluştur","scheduled task"],"engines":{"oracle":{"command":"BEGIN\n  DBMS_SCHEDULER.CREATE_JOB(\n    job_name        => 'GECELIK_BAKIM',\n    job_type        => 'PLSQL_BLOCK',\n    job_action      => 'BEGIN my_maintenance_proc; END;',\n    start_date      => SYSTIMESTAMP,\n    repeat_interval => 'FREQ=DAILY; BYHOUR=3',\n    enabled         => TRUE);\nEND;\n/","note":"DBMS_SCHEDULER.CREATE_JOB ile zamanlanmış iş tanımlanır; repeat_interval takvim ifadesiyle tekrarı belirler.","danger":"caution","priv":"CREATE JOB"},"postgres":{"command":"SELECT cron.schedule('gecelik-vacuum', '0 3 * * *', 'VACUUM ANALYZE');\n-- pg_cron eklentisi gerekir. Alternatif: pgAgent.","note":"pg_cron eklentisi cron.schedule ile standart cron sözdiziminde iş tanımlar; eklenti kurulu değilse pgAgent veya işletim sistemi cron kullanılır.","danger":"caution","priv":"pg_cron kurulu; genelde superuser/uzantı sahibi"},"mysql":{"command":"SET GLOBAL event_scheduler = ON;\nCREATE EVENT gecelik_temizlik\nON SCHEDULE EVERY 1 DAY STARTS '2026-01-01 03:00:00'\nDO\n  DELETE FROM logs WHERE created_at < NOW() - INTERVAL 30 DAY;","note":"CREATE EVENT olay zamanlayıcı ile çalışır; event_scheduler global değişkeni ON olmalıdır, aksi halde olaylar tetiklenmez.","danger":"caution","priv":"EVENT"},"mssql":{"command":"USE msdb;\nEXEC dbo.sp_add_job @job_name = N'GecelikBakim';\nEXEC dbo.sp_add_jobstep @job_name = N'GecelikBakim', @step_name = N'Adim1',\n     @subsystem = N'TSQL', @command = N'EXEC dbo.usp_Bakim;';\nEXEC dbo.sp_add_schedule @schedule_name = N'HerGunSaat3',\n     @freq_type = 4, @freq_interval = 1, @active_start_time = 030000;\nEXEC dbo.sp_attach_schedule @job_name = N'GecelikBakim', @schedule_name = N'HerGunSaat3';\nEXEC dbo.sp_add_jobserver @job_name = N'GecelikBakim';","note":"SQL Server Agent işleri msdb yordamlarıyla oluşturulur: iş, adım, zamanlama tanımlanıp sunucuya bağlanır. SQL Server Agent servisi çalışıyor olmalıdır.","danger":"caution","priv":"SQLAgentUserRole veya sysadmin"},"mongodb":{"command":"# Uygulanamaz: MongoDB'de yerleşik zamanlayıcı yoktur. Dış cron/systemd timer, uygulama zamanlayıcısı veya MongoDB Atlas Scheduled Trigger kullanın.","note":"Topluluk sürümünde zamanlanmış iş yoktur; dış zamanlayıcı veya Atlas Trigger gereklidir.","danger":"safe"},"redis":{"command":"# Uygulanamaz: Redis'te yerleşik iş zamanlayıcı yoktur. Anahtar süre sonu için EXPIRE/keyspace bildirimleri, periyodik görevler için dış cron kullanın.","note":"Redis zamanlanmış iş çalıştırmaz; TTL/keyspace bildirimleri ve dış cron ile çözülür.","danger":"safe"},"elasticsearch":{"command":"PUT _slm/policy/gunluk-snapshot\n{\n  \"schedule\": \"0 30 1 * * ?\",\n  \"name\": \"<snap-{now/d}>\",\n  \"repository\": \"backup_repo\",\n  \"config\": { \"indices\": [\"*\"] },\n  \"retention\": { \"expire_after\": \"30d\" }\n}","note":"SLM (Snapshot Lifecycle Management) zamanlanmış snapshot alır; veri yaşam döngüsü için ILM, gelişmiş otomasyon için Watcher kullanılır.","danger":"caution","priv":"manage_slm cluster ayrıcalığı"}}},{"id":"list-jobs","title":"Zamanlanmış işleri listele / durumunu gör","aliases":["list jobs","işleri listele","job durumu","scheduled jobs","job history"],"engines":{"oracle":{"command":"SELECT job_name, enabled, state, last_start_date, next_run_date\nFROM dba_scheduler_jobs\nORDER BY next_run_date;\n-- Çalışma geçmişi: SELECT job_name, status, actual_start_date, run_duration\n--                 FROM dba_scheduler_job_run_details ORDER BY log_date DESC;","note":"dba_scheduler_jobs tanımlı işleri ve durumlarını; dba_scheduler_job_run_details geçmiş çalışmaların başarı/hata sonuçlarını gösterir.","danger":"safe","readonly":true,"priv":"SELECT on dba_scheduler_jobs"},"postgres":{"command":"SELECT jobid, schedule, command, nodename, active FROM cron.job;\n-- Çalışma geçmişi:\nSELECT jobid, status, return_message, start_time, end_time\nFROM cron.job_run_details ORDER BY start_time DESC LIMIT 20;","note":"pg_cron ile cron.job tanımlı işleri, cron.job_run_details her çalıştırmanın durumunu ve dönüş mesajını verir.","danger":"safe","readonly":true,"priv":"pg_cron kurulu; cron şemasına erişim"},"mysql":{"command":"SELECT event_schema, event_name, status, interval_value, interval_field, last_executed\nFROM information_schema.events\nORDER BY last_executed DESC;","note":"information_schema.events tanımlı olayları, durumlarını (ENABLED/DISABLED) ve son çalışma zamanını listeler.","danger":"safe","readonly":true,"priv":"EVENT / SELECT"},"mssql":{"command":"SELECT j.name, j.enabled, h.run_status, h.run_date, h.run_time\nFROM msdb.dbo.sysjobs j\nLEFT JOIN msdb.dbo.sysjobhistory h ON h.job_id = j.job_id AND h.step_id = 0\nORDER BY h.run_date DESC, h.run_time DESC;","note":"msdb.dbo.sysjobs tanımlı Agent işlerini, sysjobhistory ise çalışma geçmişini ve sonuç durumunu (run_status) verir.","danger":"safe","readonly":true,"priv":"SQLAgentReaderRole / msdb erişimi"},"mongodb":{"command":"# Uygulanamaz: Yerleşik zamanlayıcı olmadığından listelenecek iş yoktur. Atlas Trigger kullanılıyorsa Atlas UI/API üzerinden görüntülenir.","note":"Topluluk MongoDB'de iş tablosu yoktur; Atlas Trigger yönetimi Atlas arayüzünden yapılır.","danger":"safe"},"redis":{"command":"# Uygulanamaz: Redis'te zamanlanmış iş kavramı olmadığından listelenecek iş yoktur.","note":"Redis iş zamanlayıcı içermez; listelenecek iş bulunmaz.","danger":"safe"},"elasticsearch":{"command":"GET _slm/policy\nGET _ilm/policy\n// Watcher durumları için: GET _watcher/stats  ve  GET _watcher/_query/watches","note":"_slm/policy snapshot politikalarını, _ilm/policy yaşam döngüsü politikalarını, _watcher/stats ise Watcher çalışma durumlarını listeler.","danger":"safe","readonly":true,"priv":"read_slm / read_ilm ayrıcalığı"}}},{"id":"enable-audit","title":"Denetim (audit) / loglama aç","aliases":["audit","denetim","loglama","enable audit","audit log"],"engines":{"oracle":{"command":"-- Unified Auditing (12c+):\nCREATE AUDIT POLICY tablo_denetim\n  ACTIONS SELECT, INSERT, UPDATE, DELETE ON hr.employees;\nAUDIT POLICY tablo_denetim;\n-- İzleme: SELECT * FROM unified_audit_trail ORDER BY event_timestamp DESC;","note":"Birleşik denetim (Unified Auditing) ile politika oluşturulup AUDIT ile etkinleştirilir; kayıtlar unified_audit_trail view'ında tutulur.","danger":"caution","priv":"AUDIT SYSTEM / AUDIT_ADMIN rolü","minver":"12.1"},"postgres":{"command":"-- pgaudit eklentisi (önerilen; önce shared_preload_libraries = 'pgaudit' + restart + CREATE EXTENSION pgaudit):\nALTER SYSTEM SET pgaudit.log = 'write, ddl';\nSELECT pg_reload_conf();\n-- Basit yerleşik yöntem:\nALTER SYSTEM SET log_statement = 'ddl';\nSELECT pg_reload_conf();","note":"pgaudit ayrıntılı denetim kaydı sağlar; sunucu genelinde etkin olması için ALTER SYSTEM ile ayarlanır (oturum düzeyinde SET yalnızca o oturumu denetler). Eklenti yoksa log_statement ('ddl','mod','all') ile temel loglama açılır. Log hacmine dikkat.","danger":"caution","priv":"superuser (ALTER SYSTEM)"},"mysql":{"command":"-- Enterprise/MariaDB audit eklentisi:\nINSTALL PLUGIN audit_log SONAME 'audit_log.so';\nSET GLOBAL audit_log_policy = 'ALL';\n-- Basit alternatif (tüm sorgular):\nSET GLOBAL general_log = 'ON';","note":"audit_log eklentisi (Enterprise veya MariaDB server_audit) ayrıntılı denetim tutar; general_log tüm sorguları loglar ama başarımı düşürür.","danger":"caution","priv":"SUPER / SYSTEM_VARIABLES_ADMIN"},"mssql":{"command":"USE master;\nCREATE SERVER AUDIT Denetim_A TO FILE (FILEPATH = 'C:\\\\audit\\\\');\nALTER SERVER AUDIT Denetim_A WITH (STATE = ON);\nUSE mydb;\nCREATE DATABASE AUDIT SPECIFICATION db_spec\n  FOR SERVER AUDIT Denetim_A\n  ADD (SELECT, INSERT, UPDATE, DELETE ON SCHEMA::dbo BY public)\n  WITH (STATE = ON);","note":"Önce SERVER AUDIT hedefi (dosya/Windows Event Log) oluşturulup açılır, ardından sunucu veya veritabanı AUDIT SPECIFICATION ile hangi olayların izleneceği tanımlanır.","danger":"caution","priv":"ALTER ANY SERVER AUDIT / CONTROL SERVER"},"mongodb":{"command":"# Yalnızca MongoDB Enterprise / Atlas. Yapılandırma (mongod.conf):\n#   auditLog:\n#     destination: file\n#     format: JSON\n#     path: /var/log/mongodb/audit.json\n#     filter: '{ atype: { $in: [\"authCheck\",\"createCollection\",\"dropCollection\"] } }'\n# mongod --auditDestination file --auditPath /var/log/mongodb/audit.json","note":"Denetim yalnızca Enterprise ve Atlas sürümlerinde bulunur; mongod yapılandırmasında auditLog bölümüyle etkinleştirilir. Topluluk sürümünde yoktur.","danger":"caution"},"redis":{"command":"ACL LOG\n# Reddedilen kimlik doğrulama/komut/anahtar erişimlerini gösterir.\n# Sıfırlamak için: ACL LOG RESET\n# Genel komut denetimi için: harici proxy veya MONITOR (dikkatli).","note":"ACL LOG güvenlik olaylarını (başarısız kimlik doğrulama, yetkisiz komut/anahtar) otomatik kaydeder; tam komut denetimi yerleşik değildir.","danger":"safe","priv":"ACL yetkisi (varsayılan olarak yönetici)"},"elasticsearch":{"command":"# elasticsearch.yml (tüm düğümlerde, yeniden başlatma gerekir):\nxpack.security.audit.enabled: true\n# İsteğe bağlı olay filtresi:\nxpack.security.audit.logfile.events.include: [ \"authentication_failed\", \"access_denied\" ]","note":"Audit log xpack.security.audit.enabled ile açılır; ayar elasticsearch.yml'de yapılır ve düğüm yeniden başlatması gerektirir (dinamik değildir). Ticari lisans gerekir.","danger":"caution"}}},{"id":"current-config-diff","title":"Varsayılandan farklı ayarları listele","aliases":["config diff","değişen ayarlar","non-default settings","farklı ayarlar","modified config"],"engines":{"oracle":{"command":"SELECT name, value, isdefault\nFROM v$parameter\nWHERE isdefault = 'FALSE'\nORDER BY name;","note":"v$parameter içinde isdefault = 'FALSE' olan satırlar varsayılandan farklı (elle ayarlanmış) parametreleri gösterir.","danger":"safe","readonly":true,"priv":"SELECT on v$parameter"},"postgres":{"command":"SELECT name, setting, unit, source\nFROM pg_settings\nWHERE source NOT IN ('default', 'override')\nORDER BY name;","note":"pg_settings.source, 'default' ve 'override' dışında ise ayar bir yapılandırma dosyası, komut satırı veya oturumla değiştirilmiş demektir.","danger":"safe","readonly":true},"mysql":{"command":"SHOW GLOBAL VARIABLES;\n-- MySQL, değişkeni varsayılanla otomatik kıyaslamaz; performance_schema ile\n-- ayarın kaynağını görebilirsiniz:\nSELECT VARIABLE_NAME, VARIABLE_SOURCE, VARIABLE_VALUE\nFROM performance_schema.variables_info\nWHERE VARIABLE_SOURCE <> 'COMPILED';","note":"SHOW GLOBAL VARIABLES tüm ayarları verir; varsayılandan farkı doğrudan sunmaz. performance_schema.variables_info ile VARIABLE_SOURCE alanı derleme varsayılanı dışındaki (dosya, komut satırı, dinamik) değişiklikleri gösterir.","danger":"safe","readonly":true,"minver":"8.0"},"mssql":{"command":"SELECT name, value, value_in_use, is_dynamic, is_advanced\nFROM sys.configurations\nWHERE value <> value_in_use\nORDER BY name;\n-- value <> value_in_use: henüz RECONFIGURE edilmemiş ya da restart bekleyen (is_dynamic = 0) değişiklikler.","note":"sys.configurations sunucu ayarlarını verir; value ile value_in_use farklı ise RECONFIGURE ile uygulanmamış (veya restart bekleyen) bir değişiklik vardır. sys.configurations varsayılan değeri tutmaz (minimum/maximum yalnızca izin verilen aralıktır); varsayılandan farkı görmek için değerleri belgelenmiş varsayılanlarla karşılaştırın.","danger":"safe","readonly":true,"priv":"VIEW SERVER STATE"},"mongodb":{"command":"db.adminCommand({ getCmdLineOpts: 1 })\n// 'parsed' alanı, varsayılan dışında açıkça verilmiş (yapılandırma dosyası/komut satırı) ayarları gösterir.","note":"getCmdLineOpts komutunun 'parsed' bölümü yalnızca açıkça belirtilmiş (varsayılandan farklı) ayarları listeler.","danger":"safe","priv":"clusterMonitor / hostInfo yetkisi"},"redis":{"command":"CONFIG GET *\n# Redis tüm ayarları listeler ancak varsayılanla kıyaslamaz.\n# Farkı görmek için çıktıyı sürümün varsayılan redis.conf değerleriyle karşılaştırın.","note":"CONFIG GET * çalışan tüm ayarları verir; varsayılandan farkı yerleşik olarak sunmaz, çıktıyı ilgili sürümün varsayılan redis.conf değerleriyle karşılaştırmak gerekir.","danger":"safe","readonly":true},"elasticsearch":{"command":"GET _cluster/settings\n// Yalnızca açıkça ayarlanmış persistent ve transient ayarları döndürür.\n// Varsayılanlar dahil tümü için: GET _cluster/settings?include_defaults=true&flat_settings=true","note":"_cluster/settings varsayılan olmayan (persistent/transient) küme ayarlarını döndürür; include_defaults=true ile varsayılanlar da görülüp karşılaştırılabilir.","danger":"safe","readonly":true}}}]},"rosetta/lifecycle.json":{"category":"Kurulum & Yükseltme","categoryId":"lifecycle","order":14,"concepts":[{"id":"check-version","title":"Kurulu sürümü ve patch seviyesini göster","aliases":["version","patch level","surum","yama seviyesi","release","build"],"engines":{"oracle":{"command":"SELECT * FROM v$version;\n-- Kayıtlı RU/patch geçmişi (SQL katmanı):\nSELECT patch_id, action, status, action_time\nFROM dba_registry_sqlpatch ORDER BY action_time;\n-- İşletim sistemi kabuğundan (ORACLE_HOME'a kurulu yamalar):\n-- $ORACLE_HOME/OPatch/opatch lspatches","note":"v$version banner sürümü verir. Uygulanan Release Update (RU) ve tek yamaların SQL katmanına işlenip işlenmediğini dba_registry_sqlpatch, home üzerindeki ikili yamaları ise 'opatch lspatches' gösterir.","danger":"safe","readonly":true,"priv":"SELECT on v$version, dba_registry_sqlpatch"},"postgres":{"command":"SELECT version();\n-- Yalnızca sayısal sürüm:\nSHOW server_version;\nSELECT current_setting('server_version_num');","note":"version() derleme bilgisiyle birlikte tam metni döndürür. PostgreSQL'de ayrı bir yama numarası yoktur; minor sürüm (örn. 16.3) düzeltme seviyesini temsil eder.","danger":"safe","readonly":true},"mysql":{"command":"SELECT VERSION();\n-- Ayrıntılı derleme bilgileri:\nSHOW VARIABLES LIKE 'version%';","note":"VERSION() örneğin '8.0.36' döndürür; son bileşen yama (release) seviyesidir. version_comment değişkeni sürümün Community/Enterprise ya da MariaDB olduğunu belirtir.","danger":"safe","readonly":true},"mssql":{"command":"SELECT @@VERSION;\n-- Yapısal sürüm alanları:\nSELECT SERVERPROPERTY('ProductVersion')       AS surum,\n       SERVERPROPERTY('ProductLevel')         AS servis_paketi,\n       SERVERPROPERTY('ProductUpdateLevel')   AS cu_seviyesi,\n       SERVERPROPERTY('ProductUpdateReference') AS kb_no,\n       SERVERPROPERTY('Edition')              AS surum_turu;","note":"ProductUpdateLevel uygulanan Cumulative Update (örn. CU12), ProductUpdateReference ise ilgili KB numarasını verir. ProductLevel 'RTM' veya eski sürümlerde 'SP' değerini gösterir.","danger":"safe","readonly":true},"mongodb":{"command":"db.version()\n// Ayrıntılı derleme bilgisi:\ndb.serverBuildInfo()\n// veya: db.adminCommand({ buildInfo: 1 })","note":"db.version() sürüm dizesini (örn. '7.0.11') verir. MongoDB'de yamalar yeni bir yama (patch) sürümü olarak yayımlanır; ayrı bir 'patch level' kavramı yoktur.","danger":"safe"},"redis":{"command":"INFO server\n# redis-cli tek satır: redis-cli INFO server | grep redis_version","note":"INFO server çıktısındaki redis_version alanı kurulu sürümü verir. Redis'te yamalar yeni bir yama sürümü olarak dağıtılır (örn. 7.2.5); redis_git_sha1 alanı da derleme kimliğini gösterir.","danger":"safe"},"elasticsearch":{"command":"GET /\n# curl: curl -s http://localhost:9200/","note":"Kök uç noktası version.number (örn. '8.14.1'), lucene_version ve build_flavor bilgilerini döndürür. Tüm düğüm sürümlerini görmek için: GET _cat/nodes?v&h=name,version","danger":"safe","readonly":true}}},{"id":"check-upgrade-readiness","title":"Yükseltme öncesi uyumluluk/hazırlık kontrolü","aliases":["upgrade readiness","preupgrade","uyumluluk kontrol","hazirlik","compatibility check","deprecation"],"engines":{"oracle":{"command":"-- 19c ve sonrası önerilen yöntem (AutoUpgrade analiz modu):\n-- $ java -jar autoupgrade.jar -config db.cfg -mode analyze\n-- Eski/alternatif: preupgrade betiği (yalnız rapor üretir):\n-- $ $NEW_ORACLE_HOME/jdk/bin/java -jar $NEW_ORACLE_HOME/rdbms/admin/preupgrade.jar FILE TEXT DIR /tmp","note":"AutoUpgrade 'analyze' modu veriyi değiştirmeden yükseltme öncesi (preupgrade) raporu üretir; düzeltmesi gereken uyarıları ve otomatik çözülecek maddeleri listeler. Gerçek yükseltmeden önce mutlaka çalıştırılır.","danger":"safe"},"postgres":{"command":"# Yeni sürümün binleriyle, yalnız uyumluluk kontrolü (veri taşımaz):\n$ pg_upgrade \\\n    --old-datadir=/var/lib/pgsql/16/data \\\n    --new-datadir=/var/lib/pgsql/17/data \\\n    --old-bindir=/usr/pgsql-16/bin \\\n    --new-bindir=/usr/pgsql-17/bin \\\n    --check","note":"--check hiçbir veriyi değiştirmeden yükseltmenin yapılabilirliğini doğrular (eksik uzantı, uyumsuz veri tipi vb. bildirir). --check eski küme çalışırken de çalıştırılabilir; asıl yükseltme ise her iki küme de kapalıyken yapılır.","danger":"safe"},"mysql":{"command":"-- 8.0 ve üzeri: Upgrade Checker yardımcı programı (MySQL Shell):\n-- $ mysqlsh -- util check-for-server-upgrade { --user=root --host=localhost }\n-- Eski 5.7->8.0 için tablo tutarlılığı:\n$ mysqlcheck --all-databases --check-upgrade -u root -p","note":"MySQL Shell'in util.checkForServerUpgrade() işlevi kaldırılan özellikleri, ayrılmış sözcük çakışmalarını ve uyumsuz tanımları raporlar. 8.0'dan itibaren sunucu başlangıçta sözlük yükseltmesini kendisi yapar; ayrı mysql_upgrade artık gerekmez.","danger":"safe"},"mssql":{"command":"-- Data Migration Assistant (DMA) ile masaüstünden çalıştırılır:\n-- DmaCmd.exe /AssessmentName=... /AssessmentDatabases=...\n-- (Uyumluluk/kullanımdan kalkan özellik ve engelleyici raporları üretir.)","note":"Data Migration Assistant (DMA), eski Upgrade Advisor'ın yerini almıştır; kullanımdan kalkan özellikleri, kırıcı değişiklikleri ve engelleyicileri veritabanı bazında raporlar. Yükseltme öncesi çalıştırılıp bulgular giderilir.","danger":"safe"},"mongodb":{"command":"// Mevcut Özellik Uyumluluk Sürümünü (FCV) doğrula:\ndb.adminCommand({ getParameter: 1, featureCompatibilityVersion: 1 })\n// Sürüm notlarındaki uyumluluk maddeleri (deprecation) elle gözden geçirilir.","note":"İkili sürümü yükseltmeden önce FCV'nin mevcut sürüme eşit olması gerekir; aksi halde geçiş engellenir. MongoDB'de otomatik bir 'deprecation tarayıcı' yoktur, sürüm uyumluluk notları elle incelenir.","danger":"safe"},"redis":{"command":"# Uygulanamaz: Redis'te ayrı bir yükseltme öncesi hazırlık aracı yoktur.\n# Kontrol listesi: RDB/AOF kalıcılık biçimi, değişen yapılandırma yönergeleri\n# ve komut/argüman kaldırmaları için ilgili sürümün release notes'u okunur.","note":"Redis yükseltmeleri genelde ileri uyumludur; resmi bir hazırlık tarayıcısı bulunmadığından RDB/AOF dosya biçimi, kaldırılan yapılandırma yönergeleri ve komut değişiklikleri sürüm notlarından elle denetlenir.","danger":"safe"},"elasticsearch":{"command":"GET _migration/deprecations\n# Belirli bir bileşen için: GET <index>/_migration/deprecations","note":"Deprecation Info API, bir sonraki büyük sürüme geçişte sorun çıkaracak küme, düğüm, index ve ML ayarlarını 'critical' / 'warning' olarak listeler. Kibana Upgrade Assistant da aynı veriyi görselleştirir.","danger":"safe","readonly":true}}},{"id":"apply-patch","title":"Patch / yama uygula","aliases":["apply patch","yama uygula","patch","minor upgrade","hotfix","ru apply"],"engines":{"oracle":{"command":"# 1) Veritabanını kapat, ikili yamayı OPatch ile uygula:\n$ $ORACLE_HOME/OPatch/opatch apply\n# 2) Veritabanını aç ve SQL katmanı değişikliklerini yükle:\n$ $ORACLE_HOME/OPatch/datapatch -verbose","note":"opatch apply Oracle Home'daki ikili dosyaları günceller; ardından datapatch, açık veritabanında sözlük/SQL değişikliklerini uygular ve dba_registry_sqlpatch'e işler. RAC'ta rolling uygulanabilen yamalar düğüm düğüm yapılabilir.","danger":"caution","priv":"OS: ORACLE_HOME sahibi; SQL: SYSDBA"},"postgres":{"command":"# Minor sürüm yaması = ikilileri değiştir + yeniden başlat (dökümün gerekmez):\n$ sudo systemctl stop postgresql-16\n$ sudo dnf update postgresql16-server   # veya apt upgrade\n$ sudo systemctl start postgresql-16","note":"Aynı ana sürüm dizisindeki minor yamalar (16.3 -> 16.4) veri biçimini değiştirmez: paketi güncelleyip servisi yeniden başlatmak yeterlidir; pg_upgrade veya dump/restore gerekmez.","danger":"caution"},"mysql":{"command":"# Minor/patch yaması: paketi güncelle ve servisi yeniden başlat\n$ sudo systemctl stop mysqld\n$ sudo dnf update mysql-community-server   # veya apt upgrade\n$ sudo systemctl start mysqld","note":"MySQL 8.0+ başlangıçta veri sözlüğünü otomatik yükseltir; ayrı mysql_upgrade adımı gerekmez. Replikasyonda önce replikalar, sonra kaynak yamalanır.","danger":"caution"},"mssql":{"command":"-- Cumulative Update (CU) veya GDR güvenlik yaması yükleyicisi çalıştırılır:\n-- SQLServer2022-KB<no>-x64.exe /quiet /IAcceptSQLServerLicenseTerms\n--   /Action=Patch /InstanceName=MSSQLSERVER\n-- Ardından örnek yeniden başlar; sürümü SERVERPROPERTY ile doğrulayın.","note":"CU (Cumulative Update) ve GDR (Genel Dağıtım Sürümü) yamaları setup yükleyicisiyle uygulanır ve örneğin yeniden başlatılmasını gerektirir. Always On grubunda önce secondary replikalar yamalanıp failover ile kesinti en aza indirilir.","danger":"caution"},"mongodb":{"command":"// Replica set üzerinde 'rolling' yama: her düğümde tek tek\n// 1) mongod'u durdur, ikiliyi yeni patch sürümüyle değiştir, yeniden başlat\n// 2) Önce secondary düğümler, en son primary\n// Primary'yi yamadan önce el ile adım attır:\nrs.stepDown()","note":"Aynı ana sürüm içindeki yama güncellemeleri (7.0.x) rolling yöntemle, önce secondary düğümlerde yapılır. Primary rs.stepDown() ile devredildikten sonra yamalanarak yazma kesintisi en aza indirilir.","danger":"caution"},"redis":{"command":"# Replikasyonlu kümede rolling restart ile yama:\n# 1) Bir replika düğümünü durdur, yeni sürümü kur, başlat, senkronu bekle\n# 2) Kalan replikalar için tekrarla\n# 3) En son master'ı devret ve yama uygula:\nredis-cli -h <replica> REPLICAOF NO ONE   # yükseltilmiş replikayı öne al","note":"Yama sürümleri (7.2.x) rolling restart ile uygulanır: önce replikalar yükseltilip yeniden senkron edilir, sonra bir replika master'a terfi ettirilerek eski master yamalanır. Sentinel/Cluster failover'ı otomatikleştirir.","danger":"caution"},"elasticsearch":{"command":"# Rolling upgrade (aynı büyük sürüm içinde yama), düğüm başına:\nPUT _cluster/settings\n{ \"persistent\": { \"cluster.routing.allocation.enable\": \"primaries\" } }\n# -> düğümü durdur, paketi güncelle, düğümü başlat, sonra:\nPUT _cluster/settings\n{ \"persistent\": { \"cluster.routing.allocation.enable\": null } }","note":"Yama/minor yükseltmeleri rolling upgrade ile yapılır: shard tahsisi durdurulur, düğüm tek tek güncellenip yeniden başlatılır, ardından tahsis yeniden açılıp kümenin yeşile (green) dönmesi beklenir.","danger":"caution"}}},{"id":"upgrade-major","title":"Büyük sürüm yükseltmesi (major upgrade)","aliases":["major upgrade","buyuk surum","version upgrade","release upgrade","surum yukseltme"],"engines":{"oracle":{"command":"# Önerilen: AutoUpgrade (analiz + fixups + deploy tek akışta):\n$ java -jar $NEW_ORACLE_HOME/rdbms/admin/autoupgrade.jar -config db.cfg -mode deploy\n# Grafik alternatif: DBUA (Database Upgrade Assistant)\n$ $NEW_ORACLE_HOME/bin/dbua","note":"AutoUpgrade tek komutla analiz, ön düzeltmeler (fixups), yükseltme ve son adımları çalıştırır; kesintiyi kısaltmak için birden çok veritabanını sırayla işleyebilir. DBUA aynı işi rehberli arayüzle yapar. Öncesinde tam yedek şarttır.","danger":"danger","priv":"SYSDBA + OS: yeni ORACLE_HOME sahibi"},"postgres":{"command":"# Yeni ana sürüm için pg_upgrade (her iki küme de kapalıyken):\n$ pg_upgrade \\\n    --old-datadir=/var/lib/pgsql/16/data \\\n    --new-datadir=/var/lib/pgsql/17/data \\\n    --old-bindir=/usr/pgsql-16/bin \\\n    --new-bindir=/usr/pgsql-17/bin \\\n    --link   # sabit bağlantı ile hızlı geçiş\n# Sonra istatistikleri topla (analyze_new_cluster.sh PG14'te kaldırıldı):\n$ vacuumdb --all --analyze-in-stages","note":"pg_upgrade ana sürüm geçişini (16 -> 17) yerinde yapar; --link kipi dosyaları kopyalamak yerine sabit bağlantı kurarak süreyi kısaltır ama eski kümeyi geçersiz kılar. Geçiş sonrası istatistikler yeniden toplanmalıdır.","danger":"danger"},"mysql":{"command":"# In-place yükseltme (aynı datadir, yeni ikililer):\n$ sudo systemctl stop mysqld\n$ sudo dnf install mysql-community-server-8.4   # eski paketin yerine\n$ sudo systemctl start mysqld   # sunucu sözlüğü otomatik yükseltir","note":"MySQL 8.x'ten itibaren in-place major yükseltme desteklenir: yeni ikililerle başlatılan sunucu veri sözlüğünü ve sistem tablolarını otomatik dönüştürür (eski ayrı mysql_upgrade adımı kaldırılmıştır). Yalnız bir büyük sürüm atlanarak yükseltilmelidir.","danger":"danger"},"mssql":{"command":"-- Yerinde büyük sürüm yükseltmesi (setup ile):\n-- setup.exe /q /ACTION=upgrade /INSTANCENAME=MSSQLSERVER\n--   /IAcceptSQLServerLicenseTerms\n-- Alternatif: yeni örneğe yan yana kurup veritabanlarını taşımak (restore/attach).","note":"setup /ACTION=upgrade örneği yeni büyük sürüme yerinde yükseltir. Daha güvenli yöntem yan yana (side-by-side) kurulumdan sonra veritabanlarını backup/restore ile taşımak ve uyumluluk seviyesini ayrı bir adımda yükseltmektir.","danger":"danger"},"mongodb":{"command":"// Adımlı major yükseltme (örn. 6.0 -> 7.0), tek büyük sürüm atlayarak:\n// 1) Rolling ile tüm düğümlerde ikiliyi 7.0 yap\n// 2) Küme kararlıyken FCV'yi yükselt:\ndb.adminCommand({ setFeatureCompatibilityVersion: \"7.0\", confirm: true })","note":"MongoDB'de büyük yükseltme iki aşamalıdır: önce tüm düğümlerin ikilisi rolling ile yeni sürüme alınır, küme kararlı olduğunda FCV yeni sürüme yükseltilir. Bir seferde yalnız bir büyük sürüm atlanabilir; FCV geriye alınabilirlik için ayrı yönetilir.","danger":"danger"},"redis":{"command":"# Replika ile major yükseltme (kesintisiz):\n# 1) Yeni sürümde bir replika oluştur, master'dan tam senkron olmasını bekle\n# 2) Uygulamayı hazırla; master'ı devret:\nredis-cli -h <yeni-replica> REPLICAOF NO ONE   # yeni sürümü master yap\n# 3) Eski master'ı yükselt, yeni master'a replika olarak bağla","note":"Redis büyük sürüm geçişi (6.x -> 7.x) yeni sürümlü bir replika kurup senkron ettikten sonra o replikayı master'a terfi ederek yapılır; böylece yazma kesintisi neredeyse sıfırlanır. RDB dosyaları ileri sürümlerle uyumludur.","danger":"danger"},"elasticsearch":{"command":"# Major sürümler atlanamaz; her seferinde bir major ve önce son minor üzerinden (örn. 6.8 -> 7.17 -> 8.x):\n# 1) Son minor sürüme (7.17) yükselt, GET _migration/deprecations uyarılarını gider\n# 2) Rolling upgrade, düğüm başına: allocation'ı \"primaries\" yap -> düğümü güncelle -> başlat -> green bekle\n# Alternatif: full-cluster restart (tüm düğümleri durdur -> yükselt -> birlikte başlat); bu da yalnız bir major atlar","note":"Elasticsearch major sürüm atlamayı hiçbir yöntemle desteklemez: rolling upgrade de full-cluster restart da yalnızca bir sonraki major'a (n -> n+1) geçirir ve kaynak sürümün son minor'ı (ör. 7.17) olmasını ister. İki major önce (ör. 6.x'te) oluşturulmuş index'ler yeni sürümde açılamaz; geçişten önce _reindex ile yeniden oluşturulmalıdır (8.x bunları yalnızca salt okunur arşiv index'i olarak sınırlı biçimde okuyabilir). Geçiş öncesi snapshot alınmalı ve deprecation uyarıları giderilmelidir.","danger":"danger"}}},{"id":"set-compatibility","title":"Uyumluluk seviyesi / feature version ayarla","aliases":["compatibility level","uyumluluk seviyesi","feature version","fcv","compatible","compat level"],"engines":{"oracle":{"command":"-- COMPATIBLE başlatma parametresini yükselt (geri alınamaz!):\nALTER SYSTEM SET COMPATIBLE = '19.0.0' SCOPE=SPFILE;\n-- Ardından örnek yeniden başlatılır. Mevcut değeri görmek için:\nSHOW PARAMETER compatible;","note":"COMPATIBLE parametresi hangi sürüm özelliklerinin ve dosya biçimlerinin etkin olacağını belirler. Yükseltildikten ve örnek yeniden başlatıldıktan sonra GERİ ALINAMAZ (downgrade engellenir); bu nedenle yükseltme başarısı doğrulanana kadar kademeli artırmak önerilir.","danger":"danger","priv":"ALTER SYSTEM (SYSDBA)"},"postgres":{"command":"# Uygulanamaz: PostgreSQL'de veritabanı uyumluluk seviyesi yoktur.\n# Eski davranış istenirse ilgili GUC'lar ayarlanır (örn. SET standard_conforming_strings=off)\n# veya major geçiş dump/restore ile yönetilir.","note":"PostgreSQL'de SQL Server/Oracle gibi bir 'uyumluluk seviyesi' kavramı yoktur; sürüm davranışı doğrudan ikili sürüme bağlıdır. Sürümler arası taşıma pg_dump/pg_restore veya pg_upgrade ile yapılır.","danger":"safe"},"mysql":{"command":"# Uygulanamaz: MySQL'de ayarlanabilir bir veritabanı uyumluluk seviyesi yoktur.\n# Davranış farkları sql_mode ile yönetilir:\nSET GLOBAL sql_mode = 'STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION';","note":"MySQL'de sürüm bazlı bir uyumluluk seviyesi bulunmaz; SQL davranışı çoğunlukla ikili sürüme ve sql_mode ayarına bağlıdır. Eski uygulama davranışını korumak için sql_mode ince ayar yapılır.","danger":"caution"},"mssql":{"command":"-- Veritabanı uyumluluk seviyesini ayarla (örn. SQL Server 2022 = 160):\nALTER DATABASE Satis SET COMPATIBILITY_LEVEL = 160;\n-- Mevcut değeri görmek için:\nSELECT name, compatibility_level FROM sys.databases;","note":"COMPATIBILITY_LEVEL sorgu optimizer'ının ve dil özelliklerinin hangi sürüm gibi davranacağını belirler (150=2019, 160=2022). Örneği yükselttikten sonra veritabanları eski seviyede kalabilir; kademeli yükseltip plan gerilemelerini izlemek önerilir. Geri düşürülebilir.","danger":"caution"},"mongodb":{"command":"// Özellik Uyumluluk Sürümünü (FCV) ayarla:\ndb.adminCommand({ setFeatureCompatibilityVersion: \"7.0\", confirm: true })\n// Mevcut değeri oku:\ndb.adminCommand({ getParameter: 1, featureCompatibilityVersion: 1 })","note":"FCV, sürümle gelen kalıcı veri biçimi değişikliklerinin ve yeni özelliklerin ne zaman etkinleşeceğini denetler. İkili yükseltildikten sonra küme kararlıyken artırılır; düşürmek yalnızca aynı ikili sürüm bir alt FCV'yi hâlâ destekliyorsa mümkündür.","danger":"caution","priv":"clusterManager / root rolü"},"redis":{"command":"# Uygulanamaz: Redis'te uyumluluk seviyesi / feature version kavramı yoktur.\n# Davranış doğrudan çalışan ikili sürüme bağlıdır.","note":"Redis'te ayarlanabilir bir uyumluluk seviyesi bulunmaz; özellik kümesi tamamen çalışan sürüme bağlıdır. Uyumluluk yalnızca RDB/AOF dosya biçimi düzeyinde ileriye dönük olarak korunur.","danger":"safe"},"elasticsearch":{"command":"# Uygulanamaz: Elasticsearch'te ayarlanabilir uyumluluk seviyesi yoktur.\n# İndeks, oluşturulduğu sürümün biçimine bağlıdır; çok eski indeksler\n# yeni sürümde okunamaz ve reindex gerektirir.","note":"Elasticsearch'te uyumluluk seviyesi ayarı yoktur; her index oluşturulduğu büyük sürümün biçimini taşır. Bir önceki büyük sürümde oluşturulmuş index'ler okunabilir, daha eskiler ise yeni sürüme _reindex ile taşınmalıdır.","danger":"safe"}}},{"id":"post-upgrade-tasks","title":"Yükseltme sonrası görevler (recompile/analyze)","aliases":["post upgrade","yukseltme sonrasi","recompile","analyze","istatistik yenile","invalid objects"],"engines":{"oracle":{"command":"-- 1) Geçersiz nesneleri paralel derle:\n@?/rdbms/admin/utlrp.sql\n-- 2) Sözlük/sabit nesne istatistiklerini yenile:\nEXEC DBMS_STATS.GATHER_DICTIONARY_STATS;\nEXEC DBMS_STATS.GATHER_FIXED_OBJECTS_STATS;\n-- Kalan geçersizleri denetle:\nSELECT owner, object_name, object_type FROM dba_objects WHERE status='INVALID';","note":"utlrp.sql yükseltme sonrası INVALID duruma düşen paket/view/trigger'ları yeniden derler. Ardından sözlük ve sabit nesne istatistiklerinin toplanması, yeni sürümde optimizer'ın sağlıklı plan üretmesini sağlar.","danger":"caution","priv":"SYSDBA"},"postgres":{"command":"# 1) pg_upgrade sonrası istatistikleri yeniden topla (zorunlu):\n$ vacuumdb --all --analyze-in-stages\n-- 2) Uzantıları yeni sürüme çek:\nALTER EXTENSION postgis UPDATE;\n-- 3) Collation değiştiyse metin indekslerini yeniden oluştur (uzun sürebilir):\nREINDEX DATABASE veritabani_adi;","note":"pg_upgrade (PG17 ve öncesi) planlayıcı istatistiklerini taşımaz; analyze-in-stages önce kaba, sonra tam istatistik toplayarak sistemi hızla kullanılır hale getirir. Uzantılar ALTER EXTENSION ... UPDATE ile, collation değişmişse index'ler REINDEX ile yenilenmelidir.","danger":"caution"},"mysql":{"command":"-- 8.0+ sözlük yükseltmesi başlangıçta otomatik yapılır; ek olarak:\nANALYZE TABLE musteri;   -- kritik tabloların istatistiklerini yenile\n-- Eski 5.7 -> ilk açılışta gerekiyorsa:\n-- $ mysql_upgrade -u root -p   (8.0.16 öncesi)","note":"MySQL 8.0.16 ve sonrasında mysql_upgrade işlevi sunucuya taşındığından ayrı çalıştırılmaz. Yükseltme sonrası büyük/kritik tablolarda ANALYZE TABLE ile istatistikleri yenilemek plan kalitesini korur.","danger":"safe"},"mssql":{"command":"-- 1) Sayfa/satır kullanım sayaçlarını düzelt:\nDBCC UPDATEUSAGE(Satis);\n-- 2) İstatistikleri yenile (sp_updatestats örnekleme kullanır; kritik tablolarda FULLSCAN):\nEXEC sp_updatestats;\n-- UPDATE STATISTICS dbo.KritikTablo WITH FULLSCAN;\n-- 3) Uyumluluk seviyesini yeni sürüme yükselt (izlenerek):\nALTER DATABASE Satis SET COMPATIBILITY_LEVEL = 160;","note":"Yükseltme sonrası DBCC UPDATEUSAGE eski sürümlerden gelen hatalı alan/satır sayaçlarını düzeltir, sp_updatestats istatistikleri tazeler. Uyumluluk seviyesi yükseltilirken yeni Kardinalite Tahmincisi'nin (CE) yol açabileceği plan gerilemeleri izlenmelidir.","danger":"caution"},"mongodb":{"command":"// 1) FCV yükseltmesini doğrula:\ndb.adminCommand({ getParameter: 1, featureCompatibilityVersion: 1 })\n// 2) İndeksleri ve sunucu loglarındaki uyumluluk uyarılarını denetle:\ndb.musteri.getIndexes()\n// Uyumsuz bir indeks varsa: dropIndex + createIndex (rolling); reIndex KULLANMAYIN","note":"Büyük yükseltme sonrası FCV'nin hedeflenen sürüme çıktığı doğrulanır. Index'leri yeniden kurmak rutin bir yükseltme adımı değildir; sürüm notlarında belirtilen ya da logda uyarı veren bir index varsa dropIndex + createIndex ile yeniden oluşturulur. reIndex 6.0+ sürümlerde yalnızca standalone'da çalışır, replica set üyelerinde izin verilmez.","danger":"caution"},"redis":{"command":"# Genelde ek görev gerekmez. Öneri: kalıcılığı ve replikasyonu doğrula:\nredis-cli INFO replication   # master/replica bağlantısı sağlıklı mı\nredis-cli INFO persistence   # rdb_last_bgsave_status / aof_last_bgrewrite_status\nredis-cli DBSIZE             # anahtar sayısı beklendiği gibi mi","note":"Redis yükseltmesi sonrası şema derleme/analiz gibi bir görev yoktur; yapılacak iş replikasyonun yeniden kurulduğunu, RDB/AOF kalıcılığının sağlıklı olduğunu ve anahtar sayısının korunduğunu doğrulamaktır.","danger":"safe"},"elasticsearch":{"command":"# Kümenin sağlığını doğrula:\nGET _cluster/health\n# Eski büyük sürümde oluşturulmuş, artık okunamayan indeksleri taşı:\nPOST _reindex\n{ \"source\": { \"index\": \"eski_index\" }, \"dest\": { \"index\": \"yeni_index\" } }","note":"Yükseltme sonrası küme durumunun 'green' olduğu ve tüm shard'ların atandığı doğrulanır. Bir önceki büyük sürümden daha eski biçimdeki index'ler yeni sürümde okunamayacağından _reindex ile güncel biçime taşınmalıdır.","danger":"caution"}}}]},"rosetta/migration.json":{"category":"Migration & Taşıma","categoryId":"migration","order":15,"concepts":[{"id":"compare-schema","title":"İki şema/ortam arasında fark al (schema diff)","aliases":["schema diff","fark","karsilastir","compare","şema farkı","ddl diff"],"engines":{"oracle":{"command":"-- Her iki ortamdan şema DDL'ini çıkarıp metinsel diff al\n-- (DBMS_METADATA ile deterministik DDL üret)\nEXEC DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'SQLTERMINATOR',TRUE);\nEXEC DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'STORAGE',FALSE);\nSELECT DBMS_METADATA.GET_DDL('TABLE', table_name) FROM user_tables ORDER BY table_name;\n-- Çıktıyı iki ortamda dosyaya alıp diff/fc ile karşılaştır.\n\n-- SQLcl'in Liquibase entegrasyonuyla şemayı changelog olarak dışa aktar:\n-- SQL> lb generate-schema\n-- Ticari: Oracle SQL Developer 'Database Diff' aracı da kullanılır.","note":"Oracle'da yerleşik tek komutlu şema-diff yoktur. Yaygın yöntem DBMS_METADATA.GET_DDL ile her iki ortamdan deterministik DDL üretip (STORAGE/segment özniteliklerini kapatarak) metinsel diff almaktır. Görsel/otomatik karşılaştırma için SQL Developer'ın Database Diff sihirbazı ya da SQLcl kullanılır.","danger":"safe","readonly":true,"priv":"SELECT_CATALOG_ROLE veya ilgili şemada okuma"},"postgres":{"command":"# Her iki veritabanından yalnızca şemayı dök ve diff al\npg_dump --schema-only --no-owner --no-privileges kaynakdb > kaynak_sema.sql\npg_dump --schema-only --no-owner --no-privileges hedefdb  > hedef_sema.sql\ndiff -u kaynak_sema.sql hedef_sema.sql\n\n# Uygulanabilir ALTER üreten araç: apgdiff (Another PostgreSQL Diff Tool)\n# apgdiff kaynak_sema.sql hedef_sema.sql > gecis.sql\n# Alternatif: migra, Liquibase diffChangeLog","note":"En basit yol pg_dump --schema-only çıktısını iki ortamda alıp diff ile karşılaştırmaktır. Farkı doğrudan çalıştırılabilir ALTER deyimlerine çeviren araçlar apgdiff ve migra'dır. Deterministik çıktı için --no-owner --no-privileges eklenir.","danger":"safe","readonly":true,"priv":"SELECT / şema okuma (pg_dump için nesnelere erişim)"},"mysql":{"command":"# MySQL Utilities (5.x) ile şema/nesne karşılaştırma:\nmysqldbcompare --server1=root:parola@host1 --server2=root:parola@host2 \\\n  magaza:magaza --difftype=sql --run-all-tests\n\n# Yerleşik yöntem: iki ortamdan CREATE ifadelerini alıp diff et\nmysqldump --no-data --skip-comments magaza > kaynak_sema.sql\n# SHOW CREATE TABLE musteri;  (tek tablo tanımını görmek için)","note":"MySQL Utilities'in mysqldbcompare aracı iki sunucu arasındaki nesne/şema farkını (difftype=sql ile uygulanabilir ifade olarak) raporlar. Araçsız yöntem mysqldump --no-data (yalnız şema) veya SHOW CREATE TABLE çıktısını iki ortamdan alıp diff ile karşılaştırmaktır. mysqldbcompare artık deprecated'dır; MariaDB/8.x için Liquibase veya Skeema tercih edilir.","danger":"safe","readonly":true,"priv":"SELECT, SHOW VIEW on her iki şema"},"mssql":{"command":"-- SqlPackage ile şema karşılaştırma/deploy raporu (uygulamadan önce ne değişecek):\nsqlpackage /Action:DeployReport /SourceFile:kaynak.dacpac \\\n  /TargetConnectionString:\"Server=hedef;Database=magaza;Integrated Security=true\" \\\n  /OutputPath:fark_raporu.xml\n\n-- Veri farkı için (satır düzeyi) tablediff aracı:\ntablediff -sourceserver S1 -sourcedatabase magaza -sourcetable musteri \\\n  -destinationserver S2 -destinationdatabase magaza -destinationtable musteri","note":"Şema farkı için SqlPackage /Action:DeployReport hedefe uygulanacak değişiklikleri XML rapor olarak verir; /Action:Script çalıştırılabilir fark betiği üretir. Visual Studio / Azure Data Studio 'Schema Compare' de aynı motoru kullanır. Satır düzeyi veri farkı için tablediff komut satırı aracı vardır.","danger":"safe","readonly":true,"priv":"VIEW DEFINITION (DeployReport için hedefte okuma)"},"mongodb":{"command":"// Şema örtüktür; iki ortamın alan yapısını çıkarıp karşılaştır.\n// $jsonSchema validator tanımını oku (koleksiyon kuralları):\ndb.getCollectionInfos({ name: \"musteri\" })[0].options.validator\n\n// Örneklemeyle çıkarımsal şema karşılaştırması için harici araç:\n// mongodb-schema (npm) ya da Compass 'Schema' sekmesi\n// mongoexport ile örnek alıp iki ortamın alan/tip dağılımını diff et.","note":"MongoDB şemasızdır; sabit bir DDL yoktur. Karşılaştırma iki yönde yapılır: koleksiyonda tanımlı $jsonSchema validator kurallarını (getCollectionInfos ile) karşılaştırmak, veya mongodb-schema / Compass ile veriden çıkarımsal şema üretip alan ve tip dağılımlarını karşılaştırmak. Index'ler için db.collection.getIndexes() çıktısı diff edilir.","danger":"safe","readonly":true,"priv":"read (getCollectionInfos, listIndexes)"},"redis":{"command":"# Uygulanamaz: Redis şemasız bir anahtar-değer deposudur; karşılaştırılacak\n# tablo/kolon tanımı (DDL) yoktur.\n# En yakın karşılık: keyspace (namespace) yapısını karşılaştırmak\n# redis-cli --scan --pattern 'musteri:*' | sort > kaynak_anahtarlar.txt","note":"Uygulanamaz: Redis'te şema (tablo/kolon/DDL) kavramı yoktur, dolayısıyla klasik şema-diff geçersizdir. Yapısal karşılaştırma gerekiyorsa yalnızca anahtar isimlendirme deseni (namespace) SCAN ile listelenip karşılaştırılabilir.","danger":"safe","readonly":true},"elasticsearch":{"command":"# İki kümeden index mapping'ini alıp karşılaştır\ncurl -s 'http://kaynak:9200/musteri/_mapping?pretty' > kaynak_mapping.json\ncurl -s 'http://hedef:9200/musteri/_mapping?pretty'  > hedef_mapping.json\ndiff -u kaynak_mapping.json hedef_mapping.json\n\n# Ayarları da karşılaştırmak için:\n# GET musteri/_settings   ve   GET musteri/_mapping","note":"Elasticsearch'te şema karşılığı index mapping'idir. GET <index>/_mapping çıktısını (ve gerekirse _settings) iki kümeden alıp diff ile karşılaştırmak standart yöntemdir. Mapping alanları çoğunlukla değiştirilemez olduğundan fark tespit edilirse yeni index + _reindex gerekebilir.","danger":"safe","readonly":true,"priv":"view_index_metadata / monitor"}}},{"id":"export-for-migration","title":"Taşıma için tutarlı dışa aktarım","aliases":["export","tutarlı dışa aktarım","consistent export","dump al","taşıma dışa aktarım","snapshot"],"engines":{"oracle":{"command":"# Data Pump ile tutarlı mantıksal dışa aktarım (tek SCN'de)\nexpdp sistem/parola schemas=magaza directory=DIR_DMP \\\n  dumpfile=magaza_%U.dmp logfile=magaza_exp.log \\\n  flashback_scn=<scn> parallel=4\n\n# Anlık tutarlılık için o anki SCN:\n# SELECT current_scn FROM v$database;\n# Alternatif: FLASHBACK_TIME=SYSTIMESTAMP","note":"Data Pump (expdp) taşıma için standart mantıksal dışa aktarım aracıdır. Okuma-tutarlılığı için FLASHBACK_SCN=<scn> (veya FLASHBACK_TIME) verilerek tüm tablolar tek bir SCN'de tutarlı alınır; canlı sistemde bu kritiktir. PARALLEL ile hızlandırılır, %U çoklu dosya üretir.","danger":"caution","readonly":true,"priv":"DATAPUMP_EXP_FULL_DATABASE, DIRECTORY nesnesi","minver":"10g (Data Pump)"},"postgres":{"command":"# Sıkıştırılmış özel (custom) biçimde tek dosya (paralel restore edilebilir)\npg_dump -Fc -Z6 -f magaza.dump magaza\n\n# Dizin biçimi (paralel dump + paralel restore):\npg_dump -Fd -j4 -f magaza_dir magaza\n\n# Tüm küme + rol/tablespace için:\n# pg_dumpall --globals-only > roller.sql","note":"pg_dump -Fc (custom) veya -Fd (directory) biçimi taşıma için tercih edilir; her ikisi de pg_restore ile seçmeli/paralel yükleme sağlar. pg_dump tek transaction içinde çalıştığından çıktı otomatik olarak tutarlı bir snapshot'tır. Rol ve tablespace gibi küme-genel nesneler için pg_dumpall --globals-only ayrıca alınır.","danger":"safe","readonly":true,"priv":"SELECT (tüm dökülecek nesnelerde)"},"mysql":{"command":"# InnoDB için tutarlı, kilitsiz dışa aktarım\nmysqldump --single-transaction --quick --routines --triggers --events \\\n  --source-data=2 magaza > magaza.sql\n\n# Not: eski sürümlerde --source-data yerine --master-data=2 kullanılır.\n# Paralel ve hızlı alternatif: mydumper -B magaza -o ./yedek --threads 4","note":"InnoDB'de --single-transaction tek tutarlı snapshot sağlar ve tabloları kilitlemez. --source-data=2 (eski adı --master-data=2) çıktının başına, replikasyon/CDC başlatmak için gereken binlog konum/GTID bilgisini yorum olarak yazar; kesintisiz geçişte bu şarttır. Büyük veri için mydumper paralel çalışır.","danger":"safe","readonly":true,"priv":"SELECT, LOCK TABLES, RELOAD, REPLICATION CLIENT (--source-data için)"},"mssql":{"command":"-- Fiziksel taşıma için tam yedek (aynı/uyumlu sürüme):\nBACKUP DATABASE magaza TO DISK = 'C:\\yedek\\magaza.bak' WITH COMPRESSION, CHECKSUM;\n\n-- Taşınabilir/sürümden bağımsız mantıksal dışa aktarım (BACPAC = şema+veri):\n-- sqlpackage /Action:Export /SourceConnectionString:\"...\" /TargetFile:magaza.bacpac\n\n-- Tek tablo için: bcp magaza.dbo.musteri out musteri.dat -n -S sunucu -T","note":"Aynı/daha yeni SQL Server'a taşımada en güvenilir yol BACKUP ... RESTORE'dur (CHECKSUM ile bütünlük doğrulanır). Sürümden/platformdan bağımsız veya Azure SQL taşımasında SqlPackage /Action:Export ile şema+veriyi tek .bacpac dosyasına almak tercih edilir. Tekil tablolar için bcp kullanılır.","danger":"safe","readonly":true,"priv":"BACKUP DATABASE (db_backupoperator) veya Export için okuma"},"mongodb":{"command":"# İkili (BSON) tutarlı dışa aktarım; oplog ile nokta-tutarlılığı\nmongodump --uri=\"mongodb://kaynak:27017\" \\\n  --oplog --out=./yedek --numParallelCollections=4\n\n# --oplog dump süresince oluşan değişiklikleri yakalar (replica set gerekir);\n# yalnızca TAM dump ile çalışır, --db / --collection ile birlikte kullanılamaz.\n# Geri yüklerken mongorestore --oplogReplay ile tek noktaya oturtulur.\n# Tek veritabanı gerekiyorsa: --db=magaza ile (oplog'suz) alın ya da geri yüklemede --nsInclude='magaza.*' kullanın.","note":"mongodump taşıma için standart ikili (BSON) dışa aktarımdır. Replica set'te --oplog seçeneği, dump devam ederken yazılan değişiklikleri oplog'dan yakalayarak tutarlı bir zaman noktası sağlar (mongorestore --oplogReplay ile eşleşir); bu seçenek yalnızca tam dump'ta geçerlidir. Büyük kümede küme-düzeyi taşıma için mongosync/canlı araçlar daha uygundur.","danger":"safe","readonly":true,"priv":"read (oplog için local db'de okuma / clusterMonitor)"},"redis":{"command":"# Arka planda RDB snapshot'ı oluştur (bloklamadan)\nredis-cli BGSAVE\n# Bitişi kontrol et:\nredis-cli INFO persistence | grep rdb_bgsave_in_progress\n\n# Oluşan dosyayı taşı (yol: CONFIG GET dir + dbfilename)\n# örn. /var/lib/redis/dump.rdb  ->  hedef sunucuya kopyala","note":"Redis'te tutarlı dışa aktarım RDB snapshot'ıdır. BGSAVE ana süreci bloklamadan arka planda fork ile tutarlı bir dump.rdb üretir (SAVE ise bloklar, kullanılmamalı). Dosya yolu CONFIG GET dir ve dbfilename ile bulunur; bu dump.rdb hedef sunucunun veri dizinine kopyalanarak taşınır.","danger":"safe","readonly":true},"elasticsearch":{"command":"# 1) Yedek deposu tanımla (paylaşılan dosya sistemi / S3)\nPUT _snapshot/tasima_deposu\n{ \"type\": \"fs\", \"settings\": { \"location\": \"/mnt/es_yedek\" } }\n\n# 2) Tutarlı snapshot al\nPUT _snapshot/tasima_deposu/goc_1?wait_for_completion=true\n{ \"indices\": \"musteri,siparis\", \"include_global_state\": false }","note":"Elasticsearch'te taşıma için tutarlı dışa aktarım yöntemi snapshot'tır. Önce bir depo (fs, S3, GCS vb.) tanımlanır, sonra snapshot alınır; snapshot artımlıdır ve alındığı andaki tutarlı durumu yakalar. Küçük veri/tek index için elasticdump da kullanılabilir ama snapshot standarttır.","danger":"safe","readonly":true,"priv":"manage / create_snapshot"}}},{"id":"import-for-migration","title":"Hedefe içe aktarım","aliases":["import","içe aktarım","restore","yükle","hedefe yükle","load"],"engines":{"oracle":{"command":"# Data Pump ile içe aktarım; şema ve tablespace yeniden eşleme\nimpdp sistem/parola directory=DIR_DMP dumpfile=magaza_%U.dmp \\\n  logfile=magaza_imp.log \\\n  remap_schema=magaza:magaza_yeni \\\n  remap_tablespace=USERS:DATA parallel=4\n\n# Var olan nesnelerde: TABLE_EXISTS_ACTION=TRUNCATE|APPEND|REPLACE","note":"impdp, expdp ile alınan .dmp dosyasını hedefe yükler. REMAP_SCHEMA kaynağı farklı bir şemaya, REMAP_TABLESPACE farklı bir tablespace'e taşır; farklı ortamlar arası geçişte bunlar sık kullanılır. Var olan tabloların davranışı TABLE_EXISTS_ACTION ile, hız PARALLEL ile ayarlanır.","danger":"caution","priv":"DATAPUMP_IMP_FULL_DATABASE, hedef tablespace kotası"},"postgres":{"command":"# Paralel geri yükleme (custom/directory biçiminden)\npg_restore -j4 -d hedefdb --no-owner --clean --if-exists magaza.dump\n\n# Yalnızca belirli tablo: pg_restore -d hedefdb -t musteri magaza.dump\n# Düz .sql dökümü ise:  psql -d hedefdb -f magaza.sql","note":"pg_restore -j ile custom/directory biçimli dökümler paralel (çok işlemli) yüklenir; bu büyük veritabanlarında yüklemeyi ciddi hızlandırır. --clean --if-exists hedefteki nesneleri önce düşürür, --no-owner farklı rol yapısına uyum sağlar. Düz SQL dökümleri psql -f ile yüklenir (paralel değildir).","danger":"caution","priv":"hedef veritabanında CREATE / owner yetkileri"},"mysql":{"command":"# Düz SQL dökümünü yükle\nmysql --binary-mode magaza < magaza.sql\n\n# Paralel/hızlı yükleme (mydumper ile alınmışsa):\nmyloader --directory=./yedek --database=magaza --threads=4 --overwrite-tables\n\n# İpucu: yükleme öncesi SET FOREIGN_KEY_CHECKS=0; unique_checks=0 hız kazandırır.","note":"mysqldump SQL dökümü mysql istemcisine yönlendirilerek yüklenir (mysql magaza < dump.sql). Paralel ve çok daha hızlı yükleme için mydumper ile alınan dizin myloader --threads ile geri yüklenir. Yükleme süresince FOREIGN_KEY_CHECKS ve UNIQUE_CHECKS'i kapatmak performansı artırır.","danger":"caution","priv":"INSERT, CREATE (ve DROP, --overwrite/--clean için)"},"mssql":{"command":"-- Fiziksel yedekten geri yükle (dosya yollarını yeni ortama taşı)\nRESTORE DATABASE magaza FROM DISK = 'C:\\yedek\\magaza.bak'\nWITH MOVE 'magaza_data' TO 'D:\\data\\magaza.mdf',\n     MOVE 'magaza_log'  TO 'D:\\log\\magaza.ldf', REPLACE;\n\n-- BACPAC'ten (şema+veri) içe aktarım:\n-- sqlpackage /Action:Import /TargetConnectionString:\"...\" /SourceFile:magaza.bacpac","note":".bak yedeği RESTORE DATABASE ile yüklenir; farklı disk düzenine taşırken WITH MOVE ile veri/log dosyaları yeni yollara yönlendirilir. Sürümden bağımsız/Azure SQL hedefinde SqlPackage /Action:Import ile .bacpac dosyası (şema + veri) yeni bir veritabanı olarak oluşturulur.","danger":"caution","priv":"RESTORE için dbcreator/sysadmin; Import için CREATE DATABASE"},"mongodb":{"command":"# BSON yedeğini geri yükle; oplog'u tekrar oynatarak tek noktaya oturt\nmongorestore --uri=\"mongodb://hedef:27017\" --oplogReplay \\\n  --numParallelCollections=4 ./yedek\n\n# Ad değiştirme: --nsFrom='magaza.*' --nsTo='magaza_yeni.*'\n# Var olan veriyi silip yükleme: --drop","note":"mongorestore, mongodump BSON çıktısını hedefe yükler. --oplogReplay, --oplog ile alınmış yedekteki oplog değişikliklerini tekrar oynatarak dump'ı tutarlı tek bir zaman noktasına getirir. Veritabanı/koleksiyon adı --nsFrom/--nsTo ile değiştirilir, mevcut veri --drop ile temizlenebilir.","danger":"caution","priv":"readWrite (oplogReplay için restore/clusterAdmin)"},"redis":{"command":"# Sunucuyu durdur, dump.rdb dosyasını veri dizinine koy, tekrar başlat\n# 1) systemctl stop redis  (veya SHUTDOWN NOSAVE)\n# 2) cp dump.rdb  <CONFIG GET dir ile bulunan yol>/dump.rdb\n# 3) systemctl start redis   -> Redis açılışta RDB'yi belleğe yükler\n\n# Alternatif (canlı): redis-cli --pipe ile RESP komut akışı beslemek","note":"Redis RDB'yi yalnızca açılışta yükler. Bu yüzden taşınan dump.rdb, hedef sunucu durdurulup veri dizinine (CONFIG GET dir) konur ve sunucu yeniden başlatılır; açılışta bellek RDB'den doldurulur. Sunucuyu durdurmadan yüklemek için anahtarlar RESP biçiminde redis-cli --pipe ile akıtılır.","danger":"caution"},"elasticsearch":{"command":"# Hedef kümede aynı depoyu tanımla, sonra snapshot'ı geri yükle\nPUT _snapshot/tasima_deposu\n{ \"type\": \"fs\", \"settings\": { \"location\": \"/mnt/es_yedek\" } }\n\nPOST _snapshot/tasima_deposu/goc_1/_restore\n{ \"indices\": \"musteri,siparis\",\n  \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"restored_$1\" }","note":"Hedef kümede kaynakla aynı yedek deposu tanımlanır (dosyalar erişilebilir olmalı), ardından _snapshot/.../_restore ile index'ler geri yüklenir. rename_pattern/rename_replacement ile index adları değiştirilebilir. Var olan index'ler açıkken geri yüklenemez; önce kapatılır ya da yeniden adlandırılır.","danger":"caution","priv":"manage (create_index, restore)"}}},{"id":"heterogeneous-migration","title":"Farklı veritabanına taşıma (heterojen)","aliases":["heterogeneous","heterojen","cross-database","farklı veritabanı","dönüştür","convert"],"engines":{"oracle":{"command":"# Oracle -> PostgreSQL: Ora2Pg (şema + veri + PL/SQL dönüşümü)\nora2pg -c ora2pg.conf -t TABLE   -o sema.sql\nora2pg -c ora2pg.conf -t COPY    -o veri.sql   # veriyi COPY biçiminde\nora2pg -t SHOW_REPORT --estimate_cost           # göç maliyet tahmini\n\n# Oracle -> (çok hedef) yönetilen/online: AWS DMS veya Oracle GoldenGate","note":"Oracle'dan (özellikle PostgreSQL'e) heterojen taşımada en yaygın açık kaynak araç Ora2Pg'dir: tabloları, constraint'leri, PL/SQL'i ve veriyi hedef diyalektine çevirir; --estimate_cost göç eforunu tahmin eder. Online/az kesintili taşımada AWS DMS ya da Oracle GoldenGate (CDC'li) kullanılır.","danger":"caution","readonly":true,"priv":"kaynak şemada SELECT (DBA view'ları için okuma)"},"postgres":{"command":"# MySQL -> PostgreSQL: pgloader (tek komutta şema+veri+tip dönüşümü)\npgloader mysql://kullanici:parola@kaynak/magaza \\\n         postgresql://kullanici:parola@hedef/magaza\n\n# SQLite/MSSQL kaynaklarından da: pgloader ./gecis.load betiği ile\n# Yönetilen/online hedef PostgreSQL için: AWS DMS","note":"PostgreSQL'e başka motorlardan (MySQL, SQLite, MS SQL) taşımada pgloader standart araçtır: bağlantı dizeleriyle tek komutta şemayı yaratır, tipleri eşler ve veriyi hızlıca kopyalar; .load betiğiyle özel dönüşüm/tip eşleme tanımlanır. Kaynak Oracle ise Ora2Pg, online geçişte AWS DMS tercih edilir.","danger":"caution","priv":"hedefte CREATE; kaynakta SELECT"},"mysql":{"command":"# PostgreSQL/Oracle/MSSQL -> MySQL: AWS DMS (yönetilen) en yaygın yol\n# veya kaynağa özel dışa aktarımı MySQL'e uyarlama:\n#   pg_dump --inserts ... | (tip/söz dizimi düzeltmeleri) | mysql magaza\n\n# MySQL <-> MariaDB (uyumlu): mysqldump çıktısı doğrudan yüklenir\nmysqldump --single-transaction magaza | mysql -h hedef_mariadb magaza","note":"MySQL'e diğer motorlardan taşımada tek egemen açık araç yoktur; en yaygın çözüm AWS DMS (yönetilen, CDC destekli) ya da kaynağın dökümünü söz dizimi/tip açısından uyarlayıp mysql istemcisine yüklemektir. MySQL ile MariaDB büyük ölçüde uyumludur, mysqldump çıktısı çoğunlukla doğrudan taşınır.","danger":"caution","priv":"hedefte CREATE, INSERT"},"mssql":{"command":"# SQL Server -> PostgreSQL: pgloader ile\npgloader mssql://kullanici:parola@kaynak/magaza \\\n         postgresql://kullanici:parola@hedef/magaza\n\n# SQL Server -> PostgreSQL uyumluluk katmanı: Babelfish for Aurora PostgreSQL\n# (T-SQL'i ve TDS protokolünü PostgreSQL üstünde çalıştırır)\n# Diğer hedeflere: SSMA (SQL Server Migration Assistant) veya AWS DMS","note":"SQL Server'dan PostgreSQL'e taşımada pgloader (mssql:// kaynağı) kullanılır; uygulamayı değiştirmeden T-SQL'i sürdürmek istenirse Babelfish for Aurora PostgreSQL bir uyumluluk katmanı sunar. Microsoft'un SSMA aracı ise diğer motorlardan (Oracle, MySQL, DB2) SQL Server'a taşımayı otomatikleştirir. Online geçişte AWS DMS.","danger":"caution","priv":"kaynakta SELECT; hedefte CREATE"},"mongodb":{"command":"# İlişkisel <-> MongoDB dönüşümü şema-eşleme (ETL) gerektirir:\n#   - Relational Migrator (MongoDB resmi aracı): tabloları belge modeline eşler\n#   - veya kaynaktan JSON üret -> mongoimport ile yükle\nmongoexport --db=magaza --collection=musteri --type=csv --fields=id,ad > c.csv\n# (SQL hedefe: mongoexport CSV -> ilişkisel COPY/LOAD DATA)","note":"MongoDB ile SQL motorları arasındaki taşıma satır<->belge model dönüşümü (ETL) gerektirir; otomatik tek komut yoktur. SQL'den MongoDB'ye MongoDB Relational Migrator tabloları belge şemasına eşler; basit durumda kaynaktan CSV/JSON üretip mongoimport ile yüklenir. Ters yönde mongoexport çıktısı hedef ilişkisel tabloya COPY/LOAD DATA ile alınır.","danger":"caution","priv":"kaynakta okuma, hedefte yazma"},"redis":{"command":"# RIOT (Redis Input/Output Tools) ile başka kaynaklardan Redis'e/Redis'ten:\n#   İlişkisel -> Redis:\nriot db-import --jdbc-url \"jdbc:postgresql://host/magaza\" \\\n  --sql \"SELECT * FROM musteri\" hset --keyspace musteri --keys id\n#   Redis -> başka Redis / dosya:  riot replicate / riot file-export","note":"Redis heterojen taşımada hedef/kaynak olarak genelde önbellek katmanıdır; ilişkisel veya dosya kaynaklarından Redis'e veri almak için Redis'in resmi RIOT aracı kullanılır (db-import ile SQL sonucunu HSET/SET yapılarına eşler). Redis'ten Redis'e veya dosyaya için riot replicate / file-export komutları vardır.","danger":"caution"},"elasticsearch":{"command":"# İlişkisel/diğer kaynak -> Elasticsearch: Logstash (JDBC girişi)\n# logstash.conf: input { jdbc { statement => \"SELECT * FROM musteri\" } }\n#                output { elasticsearch { index => \"musteri\" } }\n\n# ES -> ES (sürüm/küme yükseltme): uzak kaynaktan yeniden indeksleme\nPOST _reindex\n{ \"source\": { \"remote\": { \"host\": \"http://eski:9200\" }, \"index\": \"musteri\" },\n  \"dest\": { \"index\": \"musteri\" } }","note":"Başka veritabanlarından Elasticsearch'e taşımada en yaygın araç Logstash'tir (JDBC/dosya girişi -> elasticsearch çıkışı); Elastic'in kendi bağlayıcıları/Beats de kullanılır. Eski bir Elasticsearch kümesinden yenisine geçişte remote reindex (_reindex kaynağı 'remote') yaygındır; hedefte reindex.remote.whitelist tanımlı olmalıdır.","danger":"caution","priv":"hedefte write/create_index"}}},{"id":"setup-cdc-replication","title":"Sürekli çoğaltma / CDC kur (kesintisiz geçiş)","aliases":["cdc","replication","çoğaltma","kesintisiz geçiş","canlı taşıma","change data capture"],"engines":{"oracle":{"command":"# Oracle GoldenGate ile CDC tabanlı çoğaltma (özet akış)\n# 1) Kaynakta supplemental logging aç:\nALTER DATABASE ADD SUPPLEMENTAL LOG DATA;\n# 2) Extract (redo'dan değişiklik yakala) ve Replicat (hedefe uygula) süreçleri:\n#   GGSCI> ADD EXTRACT ext1, INTEGRATED TRANLOG, BEGIN NOW\n#   GGSCI> ADD REPLICAT rep1, INTEGRATED\n# Alternatif: Data Pump ile ilk yük + GoldenGate ile artımlı yakalama","note":"Oracle'da kesintisiz/heterojen CDC için standart araç Oracle GoldenGate'tir: Extract süreci redo loglarından değişiklikleri yakalar, Replicat hedefe uygular; supplemental logging açık olmalıdır. Tipik göç: Data Pump ile ilk yük alınır, aradan itibaren GoldenGate değişiklikleri hedefe akıtarak neredeyse sıfır kesintiyle geçişi sağlar.","danger":"caution","priv":"GoldenGate yönetici ayrıcalıkları, supplemental logging"},"postgres":{"command":"-- Kaynak (publisher): yayın oluştur (wal_level=logical olmalı)\nCREATE PUBLICATION goc_yayin FOR ALL TABLES;\n\n-- Hedef (subscriber): abonelik oluştur (ilk kopya + sürekli akış)\nCREATE SUBSCRIPTION goc_abone\n  CONNECTION 'host=kaynak dbname=magaza user=repl password=***'\n  PUBLICATION goc_yayin;","note":"PostgreSQL yerleşik logical replication ile CDC sağlar: kaynakta CREATE PUBLICATION, hedefte CREATE SUBSCRIPTION. Abonelik başlarken var olan veriyi kopyalar (initial copy) sonra WAL'den değişiklikleri sürekli akıtır; wal_level=logical gerekir. Büyük/karmaşık senaryolarda pglogical veya Debezium tercih edilir.","danger":"caution","priv":"kaynakta REPLICATION rolü; hedefte CREATE SUBSCRIPTION için superuser (PG16+ pg_create_subscription rolü de yeterli)","minver":"10 (logical replication)"},"mysql":{"command":"-- Kaynak: binlog açık ve ROW formatında olmalı (log_bin, binlog_format=ROW)\n-- Replikasyon kullanıcısı ver: GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';\n\n-- Hedefte kaynağı tanımla (ilk yükteki binlog konumundan başla):\nCHANGE REPLICATION SOURCE TO\n  SOURCE_HOST='kaynak', SOURCE_USER='repl', SOURCE_PASSWORD='***',\n  SOURCE_LOG_FILE='binlog.000001', SOURCE_LOG_POS=1547;\nSTART REPLICA;","note":"MySQL'de kesintisiz geçiş binlog tabanlı replikasyonla yapılır. İlk yük mysqldump --source-data ile alınıp binlog konumu/GTID öğrenilir; hedefte CHANGE REPLICATION SOURCE TO ile bu konumdan başlatılır (8.0.23+ söz dizimi; eski adı CHANGE MASTER TO). START REPLICA ile değişiklikler sürekli uygulanır. GTID tabanlı kurulum daha güvenlidir.","danger":"caution","priv":"REPLICATION SLAVE (repl kullanıcısı), REPLICATION CLIENT","minver":"8.0.23 (CHANGE REPLICATION SOURCE)"},"mssql":{"command":"-- Seçenek A: Transactional Replication (yayıncı->dağıtıcı->abone) — SSMS sihirbazı\n\n-- Seçenek B: Change Data Capture (değişiklikleri tablo olarak izle)\nEXEC sys.sp_cdc_enable_db;              -- veritabanı düzeyinde CDC aç\nEXEC sys.sp_cdc_enable_table\n  @source_schema = N'dbo', @source_name = N'musteri',\n  @role_name = NULL;                    -- tablo düzeyinde CDC aç\n-- Değişiklikler cdc.dbo_musteri_CT tablosundan okunup hedefe taşınır.","note":"SQL Server'da sürekli çoğaltma için iki ana yol vardır: hedefe doğrudan akış isteniyorsa Transactional Replication (yayıncı/abone) kurulur; değişiklikleri kendi ETL'inizle taşıyacaksanız Change Data Capture açılır (sp_cdc_enable_db + sp_cdc_enable_table) ve _CT tablolarından okunur. Heterojen hedeflerde CDC + AWS DMS/Debezium birlikte kullanılır.","danger":"caution","priv":"sysadmin (CDC etkinleştirme); SQL Server Agent çalışıyor olmalı"},"mongodb":{"command":"// Change Streams ile değişiklikleri canlı izle (replica set/sharded gerekir)\nconst cs = db.musteri.watch([], { fullDocument: \"updateLookup\" });\nwhile (cs.hasNext()) { printjson(cs.next()); }  // hedefe uygula\n\n// Küme-küme yönetilen çoğaltma/geçiş için resmi araç: mongosync\n// mongosync --cluster0 \"mongodb://kaynak\" --cluster1 \"mongodb://hedef\"","note":"MongoDB'de CDC için Change Streams kullanılır: db.collection.watch() oplog üzerinden ekleme/güncelleme/silme olaylarını canlı akıtır ve hedefe uygulanır (replica set şarttır). Tam küme-küme sürekli geçiş/çoğaltma için MongoDB'nin resmi Cluster-to-Cluster Sync aracı mongosync (Atlas'a özgü değildir; self-managed kümelerde de çalışır) ilk yük + sürekli senkronizasyonu yönetir.","danger":"caution","priv":"changeStream (read); mongosync için clusterAdmin"},"redis":{"command":"# Hedef instance'ı kaynağın replikası yap (canlı senkronizasyon)\n# Hedef Redis'te:\nREPLICAOF kaynak_host 6379\n# Senkron durumunu izle:\nINFO replication   # master_link_status:up olmalı\n\n# Geçişi tamamlayınca hedefi bağımsızlaştır:\nREPLICAOF NO ONE","note":"Redis'te kesintisiz geçiş yerel replikasyonla yapılır: hedef sunucuda REPLICAOF <kaynak host port> (eski adı SLAVEOF) çalıştırılır; hedef önce tam RDB'yi alır sonra komut akışıyla sürekli senkron kalır. INFO replication ile master_link_status:up doğrulanır, geçiş tamamlanınca REPLICAOF NO ONE ile hedef bağımsız hale getirilir.","danger":"caution"},"elasticsearch":{"command":"# Aynı sürüm ailesinde eski kümeden yeniye artımlı yeniden indeksleme\nPOST _reindex?wait_for_completion=false\n{ \"source\": { \"remote\": { \"host\": \"http://eski:9200\" }, \"index\": \"musteri\",\n    \"query\": { \"range\": { \"guncelleme\": { \"gt\": \"<son-cursor>\" } } } },\n  \"dest\": { \"index\": \"musteri\" } }\n\n# Lisanslı özellik: Cross-Cluster Replication (CCR) — sürekli takip\n# Hedef (follower) kümede: PUT /musteri/_ccr/follow { \"remote_cluster\": \"eski\", \"leader_index\": \"musteri\" }","note":"Elasticsearch'te gerçek sürekli çoğaltma özelliği Cross-Cluster Replication'dır (CCR): hedef küme kaynaktaki leader index'i takip ederek değişiklikleri sürekli çeker (ticari/Platinum lisans gerektirir). Lisanssız senaryoda periyodik remote reindex ile (bir zaman/sıra alanına göre artımlı) yaklaşık sürekli senkron sağlanır.","danger":"caution","priv":"CCR için manage/read_ccr; remote reindex için whitelist"}}},{"id":"verify-migration","title":"Taşıma sonrası doğrulama (satır sayısı/checksum)","aliases":["verify","doğrulama","satır sayısı","checksum","row count","tutarlılık kontrol"],"engines":{"oracle":{"command":"-- Kaynak ve hedefte satır sayılarını karşılaştır\nSELECT 'musteri' tablo, COUNT(*) adet FROM musteri;\n\n-- İçerik farkını nesne düzeyinde bulmak için DBMS_COMPARISON (db link ile)\nBEGIN DBMS_COMPARISON.CREATE_COMPARISON(\n  comparison_name => 'KARSILASTIR_MUSTERI',\n  schema_name => 'MAGAZA', object_name => 'MUSTERI',\n  dblink_name => 'HEDEF_DB'); END;\n/\n-- SELECT DBMS_COMPARISON.COMPARE('KARSILASTIR_MUSTERI', scan_info) FROM dual;","note":"En hızlı kontrol her iki tarafta tablo bazında COUNT(*) karşılaştırmaktır. Satır düzeyinde gerçek içerik farkını bulmak için DBMS_COMPARISON paketi kullanılır: database link üzerinden kaynak ve hedef tabloyu satır satır karşılaştırır ve farkları raporlar/yakınsatabilir. Sağlama için ORA_HASH veya STANDARD_HASH ile kolon özeti alınabilir.","danger":"safe","readonly":true,"priv":"her iki tarafta SELECT; DBMS_COMPARISON için EXECUTE"},"postgres":{"command":"-- Satır sayısı\nSELECT count(*) FROM musteri;\n\n-- Tüm tablo içeriğinin sıralı özeti (sağlama) — iki tarafta karşılaştır\nSELECT md5(string_agg(t.satir, '' ORDER BY t.satir)) AS ozet\nFROM (SELECT md5(musteri::text) AS satir FROM musteri) t;","note":"İlk adım her tabloda count(*) karşılaştırmaktır. İçerik doğrulaması için satırların metin gösterimlerini md5'leyip sıralı olarak birleştirip tekrar özetlemek, iki taraf arasında satır-bağımsız bir sağlama sağlar. Büyük veride yalnızca değişebilir/anahtar kolonlar seçilerek özet alınır; PK'ye göre sıralama tekrarlanabilirlik için önemlidir.","danger":"safe","readonly":true,"priv":"SELECT on tablo"},"mysql":{"command":"-- Tablonun yerleşik sağlaması (iki sunucuda çalıştırıp karşılaştır)\nCHECKSUM TABLE musteri;\n\n-- Satır sayısı\nSELECT COUNT(*) FROM musteri;\n\n-- Canlı/büyük ortamda tercih edilen araç (satır bloklarını online karşılaştırır):\n-- pt-table-checksum h=kaynak,D=magaza  (Percona Toolkit)","note":"MySQL'de CHECKSUM TABLE tablo içeriğinin tek bir sağlamasını verir; kaynak ve hedefte çalıştırılıp karşılaştırılır (motor/sürüm aynı olmalı). Satır sayısı için COUNT(*). Canlı üretimde ve replikasyon tutarlılığında endüstri standardı Percona Toolkit'in pt-table-checksum aracıdır; blok blok, online ve düşük etkiyle karşılaştırır.","danger":"safe","readonly":true,"priv":"SELECT on tablo"},"mssql":{"command":"-- Satır düzeyi tam karşılaştırma (fark üreten resmi araç)\ntablediff -sourceserver S1 -sourcedatabase magaza -sourcetable musteri \\\n  -destinationserver S2 -destinationdatabase magaza -destinationtable musteri\n\n-- Hızlı toplu sağlama (tek sorguyla, iki tarafta karşılaştır):\nSELECT COUNT_BIG(*) adet, CHECKSUM_AGG(BINARY_CHECKSUM(*)) ozet FROM dbo.musteri;","note":"SQL Server'da satır düzeyinde farkı bulan resmi komut satırı aracı tablediff'tir (hangi satırların eklendiğini/değiştiğini üretir, opsiyonel -f ile onarım betiği yazar). Hızlı bütünsel kontrol için CHECKSUM_AGG(BINARY_CHECKSUM(*)) tek bir tablo özeti verir; COUNT_BIG(*) ile birlikte iki taraf karşılaştırılır (satır sırasından bağımsızdır).","danger":"safe","readonly":true,"priv":"SELECT on her iki tablo"},"mongodb":{"command":"// Belge sayısını karşılaştır (kaynak ve hedefte)\ndb.musteri.countDocuments({});\n\n// İçerik sağlaması için dbHash (koleksiyon/DB düzeyinde md5 özeti):\ndb.runCommand({ dbHash: 1, collections: [\"musteri\"] });\n// -> md5 alanı iki ortamda karşılaştırılır.","note":"İlk kontrol her iki tarafta countDocuments() ile belge sayısını karşılaştırmaktır (estimatedDocumentCount hızlıdır ama metadata'ya dayanır, kesin sayım için countDocuments). İçerik doğrulaması için dbHash komutu koleksiyon/veritabanı düzeyinde bir md5 özeti üretir; iki ortamın hash'leri karşılaştırılır. Index'ler ayrıca getIndexes() ile denetlenir.","danger":"safe","readonly":true,"priv":"read (dbHash için erişim)"},"redis":{"command":"# Anahtar sayısını karşılaştır (kaynak ve hedefte)\nredis-cli DBSIZE\n\n# Bellek/veri özeti ve anahtar tipi dağılımı için:\nredis-cli INFO keyspace     # db0:keys=... bilgisi\n# Tam içerik doğrulaması için: her anahtarda DUMP alıp hedefle karşılaştır\n# (ör. redis-cli --scan | xargs -I{} redis-cli DUMP {})","note":"Redis'te temel doğrulama DBSIZE ile toplam anahtar sayısını karşılaştırmaktır; veritabanı bazında dağılım INFO keyspace ile görülür. Redis'te yerleşik tablo-checksum yoktur; birebir içerik doğrulaması gerekiyorsa anahtar başına DUMP serileştirmesi alınıp iki taraf karşılaştırılır (TTL farkları göz önünde tutulmalı). riot compare aracı da kullanılabilir.","danger":"safe","readonly":true},"elasticsearch":{"command":"# Belge sayısını karşılaştır (kaynak ve hedef kümede)\nGET musteri/_count\n\n# Ayrıntı: sağlık/segment/depolama karşılaştırması için\nGET _cat/indices/musteri?v&h=index,docs.count,store.size\n# Örnekleme ile içerik: aynı _id'lerde GET musteri/_doc/<id> karşılaştır","note":"Elasticsearch'te temel doğrulama her iki kümede GET <index>/_count ile belge sayısını karşılaştırmaktır (_cat/indices docs.count da hızlı özet verir). Karşılaştırmada _count esas alınmalı: _cat/indices docs.count Lucene düzeyinde sayar (nested alt belgeler dahil, ör. iki nested öğeli tek belge 3 sayılır); bu yüzden _count'tan farklı olabilir. İçerik doğrulaması için aynı _id kümesinde belgeler örneklenerek veya bir hash alanı üzerinden karşılaştırılır.","danger":"safe","readonly":true,"priv":"read / monitor on index"}}}]},"rosetta/tuning.json":{"category":"Performans Tuning","categoryId":"tuning","order":16,"concepts":[{"id":"plan-baseline","title":"Sorgu planını sabitle / zorla (plan baseline / hint)","aliases":["plan baseline","force plan","plan sabitle","hint","plan kararlilik","query store force"],"engines":{"oracle":{"command":"-- Cursor cache'teki iyi planı baseline olarak yükle:\nDECLARE n NUMBER; BEGIN\n  n := DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE(sql_id => '&sql_id');\nEND;\n/","note":"SQL Plan Management planı kilitler; regresyona karşı en güçlü koruma. Hint için /*+ ... */ da kullanılabilir.","danger":"caution","priv":"ADMINISTER SQL MANAGEMENT OBJECT"},"postgres":{"command":"-- Yerleşik plan sabitleme yoktur; pg_hint_plan eklentisi:\n/*+ IndexScan(musteri musteri_il_idx) */ SELECT ... ;","note":"Alternatif: enable_seqscan gibi ayarlarla oturum düzeyinde yönlendir; kalıcı sabitleme için pg_hint_plan.","danger":"caution"},"mysql":{"command":"SELECT /*+ INDEX(musteri musteri_il_idx) */ * FROM musteri WHERE il='Ankara';","note":"Optimizer hint'leri sorguya gömülür. Kalıcı yeniden yazım için query rewrite plugin.","danger":"safe"},"mssql":{"command":"-- Query Store'da iyi planı zorla:\nEXEC sp_query_store_force_plan @query_id = 42, @plan_id = 17;","note":"Query Store açık olmalı. Ayrıca OPTION (USE PLAN N'...') veya plan guide.","danger":"caution","priv":"ALTER on database"},"mongodb":{"command":"// Sorguya indeks zorla:\ndb.musteri.find({ il: \"Ankara\" }).hint({ il: 1 })\n// Kalıcı: db.musteri.getPlanCache() / index filter","note":"hint belirli index'i zorlar; planCacheClear ile bayat planı temizle.","danger":"safe"},"redis":{"command":"# Uygulanamaz: sorgu planlayıcı yoktur.","note":"Performans veri yapısı ve komut karmaşıklığından gelir.","danger":"safe"},"elasticsearch":{"command":"# Plan sabitleme yoktur; sorguyu/indeksi ve routing'i optimize edin.\nGET <index>/_search { \"profile\": true, \"query\": {...} }","note":"profile ile hangi sorgunun pahalı olduğunu görün; shard/routing ile yönlendirin.","danger":"safe"}}},{"id":"gather-stats-advanced","title":"İstatistikleri gelişmiş seçeneklerle topla (histogram vb.)","aliases":["gather stats","histogram","istatistik","analyze advanced","method_opt","estimate percent"],"engines":{"oracle":{"command":"EXEC DBMS_STATS.GATHER_TABLE_STATS(\n  ownname=>'HR', tabname=>'CALISAN',\n  estimate_percent=>DBMS_STATS.AUTO_SAMPLE_SIZE,\n  method_opt=>'FOR ALL COLUMNS SIZE AUTO', degree=>4);","note":"method_opt histogramları, degree paralelliği kontrol eder. Kilitli istatistik için LOCK_TABLE_STATS.","danger":"safe"},"postgres":{"command":"ALTER TABLE musteri ALTER COLUMN il SET STATISTICS 500;\nANALYZE musteri;","note":"Kolon başına hedef örnekleme; default_statistics_target genel varsayılanı belirler.","danger":"safe"},"mysql":{"command":"ANALYZE TABLE musteri UPDATE HISTOGRAM ON il WITH 32 BUCKETS;","note":"MySQL 8.0 histogram desteği; seçici olmayan ama filtrelenen kolonlarda faydalı.","danger":"safe"},"mssql":{"command":"UPDATE STATISTICS dbo.musteri WITH FULLSCAN;\n-- Filtrelenmiş istatistik: CREATE STATISTICS ... WHERE ...","note":"FULLSCAN en doğru; büyük tabloda SAMPLE. Auto update için AUTO_UPDATE_STATISTICS.","danger":"safe"},"mongodb":{"command":"// Manuel istatistik yoktur; planlayıcı çalışma zamanında ölçer.\ndb.musteri.getPlanCache().clear()","note":"Bayat plan önbelleğini temizlemek dışında elle istatistik gerekmez.","danger":"safe"},"redis":{"command":"# Uygulanamaz.","note":"İstatistik/optimizer yoktur.","danger":"safe"},"elasticsearch":{"command":"# İstatistik toplama yoktur; aranabilirliği tazele:\nPOST <index>/_refresh","note":"Alan verisi ve doc değerleri sorgu anında kullanılır; force merge segmentleri azaltır.","danger":"safe"}}},{"id":"perf-report","title":"Performans raporu üret (AWR / ASH ve muadili)","aliases":["awr","ash","performans raporu","performance report","profile","workload report"],"engines":{"oracle":{"command":"-- AWR raporu (SQL*Plus):\n@?/rdbms/admin/awrrpt.sql\n-- ASH raporu: @?/rdbms/admin/ashrpt.sql\n-- Canlı: SELECT * FROM v$active_session_history WHERE sample_time > SYSDATE-1/24;","note":"AWR/ASH Diagnostics Pack lisansı ister. Statspack lisanssız muadilidir.","danger":"safe","priv":"SELECT_CATALOG_ROLE"},"postgres":{"command":"-- pg_stat_statements özet + pg_profile/pgBadger:\nSELECT queryid, calls, total_exec_time, mean_exec_time, query\nFROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 20;","note":"AWR muadili için pg_profile eklentisi (dönemsel snapshot) veya pgBadger log analizi.","danger":"safe"},"mysql":{"command":"-- sys şeması özetleri:\nSELECT * FROM sys.statement_analysis LIMIT 20;\nSELECT * FROM sys.io_global_by_file_by_bytes LIMIT 10;","note":"sys şeması performance_schema'yı okunur raporlara çevirir; Enterprise Monitor daha kapsamlı.","danger":"safe"},"mssql":{"command":"-- Query Store raporları (SSMS) veya:\nSELECT TOP 20 * FROM sys.query_store_runtime_stats ORDER BY avg_duration DESC;","note":"Query Store zaman içindeki plan/performansı tutar; sp_BlitzFirst (topluluk) hızlı teşhis verir.","danger":"safe"},"mongodb":{"command":"# Kabuktan canlı: mongostat --rowcount 10 ; mongotop\n// veya Atlas Performance Advisor / profiler:\ndb.system.profile.find().sort({millis:-1}).limit(20)","note":"mongostat/mongotop anlık yük; profiler yavaş işlemleri kaydeder.","danger":"safe"},"redis":{"command":"INFO stats\nredis-cli --latency-history\nSLOWLOG GET 20","note":"--latency ve --latency-history gecikme profilini verir; INFO tüm sayaçları.","danger":"safe"},"elasticsearch":{"command":"GET _nodes/stats\nGET _cat/thread_pool?v&h=node_name,name,active,queue,rejected\nGET _nodes/hot_threads","note":"hot_threads en pahalı thread'leri; _nodes/stats bütünsel metrikleri verir. Monitoring (Kibana) tarihsel.","danger":"safe"}}},{"id":"optimizer-params","title":"Optimizer / paralellik ayarlarını gör-değiştir","aliases":["optimizer","paralellik","parallel","maxdop","optimizer_switch","cost","planlayici ayar"],"engines":{"oracle":{"command":"SHOW PARAMETER optimizer;\n-- Oturum: ALTER SESSION SET optimizer_mode = FIRST_ROWS_10;\n-- Paralellik: ALTER SESSION FORCE PARALLEL QUERY PARALLEL 4;","note":"optimizer_index_cost_adj, parallel_degree_policy gibi ayarlar plan seçimini etkiler; dikkatli değiştirin.","danger":"caution"},"postgres":{"command":"SHOW random_page_cost;\nSHOW max_parallel_workers_per_gather;\n-- Oturum: SET enable_seqscan = off;","note":"SSD'de random_page_cost ~1.1 önerilir. enable_* bayrakları teşhis içindir, kalıcı çözüm değil.","danger":"caution"},"mysql":{"command":"SELECT @@optimizer_switch;\nSET SESSION optimizer_switch='index_merge=off';","note":"optimizer_switch tek tek optimizasyonları açar/kapatır; oturum düzeyinde test edin.","danger":"caution"},"mssql":{"command":"-- Örnek düzeyinde MAXDOP ve maliyet eşiği:\nEXEC sp_configure 'max degree of parallelism', 8; RECONFIGURE;\n-- Veritabanı düzeyinde: ALTER DATABASE SCOPED CONFIGURATION SET MAXDOP = 8;","note":"MAXDOP=0 sınırsız; OLTP'de genelde 4-8. 'cost threshold for parallelism' varsayılan 5 çoğu için düşüktür.","danger":"caution"},"mongodb":{"command":"# Optimizer parametresi yoktur; indeks ve sorgu şekli belirleyicidir.\ndb.musteri.find({...}).explain('allPlansExecution')","note":"allPlansExecution planlayıcının değerlendirdiği tüm planları gösterir.","danger":"safe"},"redis":{"command":"# Uygulanamaz.","note":"Planlayıcı yoktur; io-threads ve veri yapısı seçimi performansı belirler.","danger":"safe"},"elasticsearch":{"command":"GET <index>/_settings?include_defaults=true\n# search.max_buckets, index.max_result_window gibi arama sınırları","note":"Optimizer yok; shard sayısı, routing ve sorgu yapısı performansı belirler.","danger":"safe"}}},{"id":"sql-monitor","title":"Çalışan/son SQL'i gerçek zamanlı izle","aliases":["sql monitor","canli izle","real time sql","live query","current sql","aktif sorgu izle"],"engines":{"oracle":{"command":"SET LONG 1000000 LONGCHUNKSIZE 1000000 LINESIZE 250 PAGESIZE 0\nSELECT DBMS_SQLTUNE.REPORT_SQL_MONITOR(sql_id=>'&sql_id', type=>'TEXT') AS rapor FROM dual;\n-- veya: SELECT sql_id, status, elapsed_time FROM v$sql_monitor WHERE status='EXECUTING';","note":"Real-Time SQL Monitoring uzun/paralel sorguları canlı gösterir (Tuning Pack).","danger":"safe"},"postgres":{"command":"SELECT pid, now()-query_start AS dur, state, wait_event, query\nFROM pg_stat_activity WHERE state='active' ORDER BY query_start;","note":"auto_explain ile yavaş sorguların planı otomatik loglanabilir.","danger":"safe"},"mysql":{"command":"SELECT thread_id, event_name, timer_wait/1e9 AS ms, sql_text\nFROM performance_schema.events_statements_current;","note":"events_statements_current o an çalışan ifadeleri gösterir.","danger":"safe"},"mssql":{"command":"SELECT r.session_id, r.status, r.wait_type, r.percent_complete, t.text\nFROM sys.dm_exec_requests r JOIN sys.dm_exec_sessions s ON s.session_id = r.session_id CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) t\nWHERE s.is_user_process = 1;","note":"SSMS'te 'Live Query Statistics' plan ilerlemesini canlı gösterir.","danger":"safe"},"mongodb":{"command":"db.currentOp({ active: true, secs_running: { $gt: 1 } })","note":"Uzun süren işlemleri canlı gösterir; killOp ile sonlandırılabilir.","danger":"safe"},"redis":{"command":"MONITOR","note":"TÜM komutları canlı akıtır — üretimde performansı etkiler, kısa süre kullanın. Yerine SLOWLOG tercih edin.","danger":"caution"},"elasticsearch":{"command":"GET _tasks?detailed=true&group_by=parents","note":"Çalışan görevleri canlı gösterir; uzun görev POST _tasks/<id>/_cancel ile iptal edilir.","danger":"safe"}}}]},"rosetta/tuning-adv.json":{"category":"İleri Tuning","categoryId":"tuning-adv","order":17,"concepts":[{"id":"parallel-query","title":"Paralel sorgu çalıştır / paralelliği ayarla","aliases":["parallel","paralel","dop","degree of parallelism","paralel sorgu"],"engines":{"oracle":{"command":"-- Sorgu düzeyinde hint ile:\nSELECT /*+ PARALLEL(t, 4) */ * FROM buyuk_tablo t;\n-- Oturum düzeyinde zorla:\nALTER SESSION FORCE PARALLEL QUERY PARALLEL 4;","note":"PARALLEL hint tabloya paralel tarama uygular; degree=DOP. Aşırı DOP sunucu kaynaklarını tüketir, dikkatli seçin. parallel_degree_policy=AUTO otomatik yönetir.","danger":"caution"},"postgres":{"command":"-- Oturumda paralel işçi sayısını ayarla:\nSET max_parallel_workers_per_gather = 4;\n-- Planlayıcı Gather/Gather Merge düğümü ekler:\nEXPLAIN (ANALYZE) SELECT count(*) FROM buyuk_tablo;","note":"Planda Gather/Parallel Seq Scan görünürse paralellik devrede. max_parallel_workers ve min_parallel_table_scan_size de etkiler.","danger":"safe"},"mysql":{"command":"-- InnoDB sınırlı paralellik (yalnız belirli işlemler):\nSET GLOBAL innodb_parallel_read_threads = 4;\n-- COUNT(*) ve birincil anahtar taramalarında etkilidir.","note":"MySQL genel paralel sorgu yürütmesi sunmaz; innodb_parallel_read_threads yalnız clustered index taramalarını (ör. COUNT(*)) paralelleştirir. Karmaşık JOIN'ler tek thread'dir.","danger":"safe"},"mssql":{"command":"-- Sorgu düzeyinde MAXDOP hint:\nSELECT * FROM dbo.buyuk_tablo OPTION (MAXDOP 4);\n-- Örnek düzeyi: sp_configure 'max degree of parallelism', 4;","note":"MAXDOP paralel işlem sayısını sınırlar; MAXDOP 1 paralelliği kapatır. 'cost threshold for parallelism' eşiği aşılınca plan paralelleşir.","danger":"safe"},"mongodb":{"command":"// Büyük aggregation'da disk kullanımına izin ver:\ndb.satis.aggregate([ { $group: { _id: \"$il\", t: { $sum: \"$tutar\" } } } ], { allowDiskUse: true })\n// Sharded küme her shard'ı paralel işler.","note":"Sharded kümede sorgu her shard üzerinde paralel çalışır; tek düğümde aggregation aşamaları çoğunlukla sıralıdır. allowDiskUse bellek sınırını aşan işlemlere olanak tanır.","danger":"safe"},"redis":{"command":"# Uygulanamaz: sorgu paralelliği kavramı yoktur.","note":"Komut yürütme tek thread'lidir; ölçek için Cluster (sharding) veya io-threads ile ağ I/O paralelliği kullanılır.","danger":"safe"},"elasticsearch":{"command":"# Shard sayısı = paralellik birimidir; sorgu shard'lar arasında paralel çalışır.\n# Tek shard içinde parçalayarak paralellik (scroll/PIT ile):\nGET <index>/_search\n{ \"slice\": { \"id\": 0, \"max\": 4 }, \"query\": { \"match_all\": {} } }","note":"Arama tüm ilgili shard'larda eşzamanlı çalışır; primary shard sayısı temel paralellik seviyesini belirler. slices büyük scroll/reindex işlemlerini böler.","danger":"safe"}}},{"id":"bind-variables","title":"Bind değişken / parametre sniffing yönet","aliases":["bind","bind variable","parametre","parameter sniffing","cursor sharing","prepared statement"],"engines":{"oracle":{"command":"-- Literal yerine bind kullan (plan paylaşımı için):\nSELECT * FROM musteri WHERE il = :il;\n-- Literal içeren eski kodları paylaştır:\nALTER SESSION SET cursor_sharing = FORCE;","note":"Bind değişken hard parse'ı azaltır. Adaptive Cursor Sharing, dengesiz dağılımlı bind değerlerinde birden çok plan tutarak sniffing sorunlarını hafifletir. cursor_sharing=FORCE dikkatli kullanılmalı.","danger":"caution"},"postgres":{"command":"-- Prepared statement ile parametreleştir:\nPREPARE q (text) AS SELECT * FROM musteri WHERE il = $1;\nEXECUTE q('Ankara');\n-- Plan önbelleği davranışını ayarla:\nSET plan_cache_mode = force_custom_plan;","note":"plan_cache_mode=auto generic/custom plan arasında seçim yapar; force_custom_plan her yürütmede parametreye özel plan üretir (sniffing benzeri sorunlara çözüm).","danger":"safe"},"mysql":{"command":"-- Sunucu tarafı prepared statement:\nPREPARE stmt FROM 'SELECT * FROM musteri WHERE il = ?';\nSET @il = 'Ankara';\nEXECUTE stmt USING @il;\nDEALLOCATE PREPARE stmt;","note":"Prepared statement SQL enjeksiyonunu önler ve ayrıştırma maliyetini düşürür. MySQL sürücü düzeyinde de parametreleştirmeyi destekler.","danger":"safe"},"mssql":{"command":"-- Parametreli sorgu (sp_executesql):\nEXEC sp_executesql N'SELECT * FROM dbo.musteri WHERE il = @il', N'@il nvarchar(50)', @il = N'Ankara';\n-- Sniffing sorununu hint ile yönet:\nSELECT ... OPTION (RECOMPILE);\n-- veya OPTION (OPTIMIZE FOR (@il = 'Ankara'));","note":"OPTION(RECOMPILE) her çalıştırmada parametreye özel plan üretir (CPU maliyetli). OPTIMIZE FOR belirli/tipik değere göre plan sabitler; OPTIMIZE FOR UNKNOWN ortalama seçicilik kullanır.","danger":"caution"},"mongodb":{"command":"// Sorgu şekli (query shape) plan önbelleğinin anahtarıdır:\ndb.musteri.find({ il: \"Ankara\" }).explain(\"queryPlanner\")\n// Bayat planı temizle:\ndb.musteri.getPlanCache().clear()","note":"Aynı şekle sahip sorgular (aynı alanlar/operatörler) önbellekteki planı paylaşır; farklı literal değerler yeni plan üretmez. Değer dağılımı çok dengesizse planCacheClear ile sıfırlayın.","danger":"safe"},"redis":{"command":"# Uygulanamaz: sorgu planlayıcı ve parametre sniffing yoktur.","note":"Komutlar doğrudan yürütülür; parametreleştirme yerine anahtar tasarımı performansı belirler.","danger":"safe"},"elasticsearch":{"command":"# Parametreli search template ile sorguyu yeniden kullan:\nPOST _scripts/musteri_il\n{ \"script\": { \"lang\": \"mustache\", \"source\": { \"query\": { \"term\": { \"il\": \"{{il}}\" } } } } }\nGET <index>/_search/template\n{ \"id\": \"musteri_il\", \"params\": { \"il\": \"Ankara\" } }","note":"Search template (Mustache) sorgu gövdesini parametreleştirir; uygulama sabit şablonu farklı değerlerle çağırır, sorgu tutarlılığı ve önbellek kullanımını artırır.","danger":"safe"}}},{"id":"partition-pruning","title":"Partition pruning'i (bölüm budama) doğrula","aliases":["partition pruning","bolum budama","partition","pruning","pstart pstop"],"engines":{"oracle":{"command":"EXPLAIN PLAN FOR\nSELECT * FROM satis WHERE satis_tarihi = DATE '2026-01-15';\nSELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);\n-- Planda 'PARTITION RANGE ITERATOR/SINGLE' ve Pstart/Pstop sütunlarına bakın.","note":"Pstart/Pstop yalnız ilgili bölümlerin okunduğunu gösterir (KEY yerine sayı ideal). Bölüm anahtarına fonksiyon/örtük dönüşüm uygulamak budamayı engeller.","danger":"safe"},"postgres":{"command":"SET enable_partition_pruning = on;\nEXPLAIN (ANALYZE)\nSELECT * FROM satis WHERE satis_tarihi = DATE '2026-01-15';\n-- Planda yalnız ilgili partition'ın (alt tablo) tarandığını doğrulayın.","note":"enable_partition_pruning açıkken planda yalnızca eşleşen bölümler görünür; diğerleri 'never executed' olur. Sabit değerlerde plan zamanı, parametrede çalışma zamanı budama olur.","danger":"safe"},"mysql":{"command":"-- Hangi bölümlerin tarandığını göster:\nEXPLAIN SELECT * FROM satis WHERE satis_tarihi = '2026-01-15';\n-- 5.7 ve öncesi: EXPLAIN PARTITIONS SELECT ... (8.0'da kaldırıldı)","note":"MySQL 5.7+ düz EXPLAIN çıktısında 'partitions' sütunu taranacak bölümleri listeler (EXPLAIN PARTITIONS sözdizimi 8.0'da kaldırıldı); yalnız ilgili bölüm(ler) görünmelidir. Tüm bölümler listeleniyorsa budama gerçekleşmiyordur.","danger":"safe"},"mssql":{"command":"-- Bir değerin hangi bölüme düştüğünü bul:\nSELECT $PARTITION.pf_satis_tarihi('2026-01-15') AS bolum_no;\n-- Gerçek plandaki 'Actual Partition Count' ve 'Actual Partitions Accessed' değerlerini inceleyin.","note":"$PARTITION fonksiyonu bir değerin bölüm numarasını verir. Gerçek yürütme planında erişilen bölüm sayısı 1'e yakınsa budama etkindir; tüm bölümler taranıyorsa predicate uyumsuzdur.","danger":"safe"},"mongodb":{"command":"// Sharded kümede shard key ile hedefli sorgu (targeted query):\ndb.satis.find({ magaza_id: 42 }).explain(\"executionStats\")\n// explain'de 'shards' altında yalnız ilgili shard görünmeli.","note":"Sorgu shard key içeriyorsa mongos yalnız ilgili shard'a yönlendirir (targeted); içermiyorsa tüm shard'lara yayılır (scatter-gather). explain çıktısında erişilen shard'ları doğrulayın.","danger":"safe"},"redis":{"command":"# Uygulanamaz: tablo/bölüm kavramı yoktur.","note":"Veri dağıtımı Cluster hash slot'ları ile yapılır; sorgu budama yerine anahtar erişimi doğrudandır.","danger":"safe"},"elasticsearch":{"command":"# Routing ile ilgili shard'a yönlendir:\nGET <index>/_search?routing=musteri42\n{ \"query\": { \"term\": { \"musteri_id\": 42 } } }\n# Zaman bazlı index pattern ile yalnız ilgili indeksleri sorgula:\nGET satis-2026-01/_search","note":"custom routing sorguyu tek shard'a indirger (budama benzeri). Zaman serisi verisinde tarih desenli index adı (satis-2026-01) yalnız ilgili index'lerin taranmasını sağlar; wildcard yerine dar desen kullanın.","danger":"safe"}}},{"id":"result-cache","title":"Sonuç / sorgu önbelleği kullan","aliases":["result cache","sonuc onbellek","query cache","sorgu onbellegi","request cache"],"engines":{"oracle":{"command":"-- Sorgu düzeyinde sonuç önbelleği:\nSELECT /*+ RESULT_CACHE */ il, COUNT(*) FROM musteri GROUP BY il;\n-- Genel mod: ALTER SYSTEM SET result_cache_mode = FORCE;","note":"Server Result Cache sonucu SGA'da tutar; temel tablolar değişince otomatik geçersiz kılınır. RESULT_CACHE_MODE=FORCE tüm uygun sorgulara uygular, MANUAL yalnız hint ile. Sık değişen tablolarda faydası azdır.","danger":"caution"},"postgres":{"command":"-- Yerleşik sonuç önbelleği yoktur.\n-- Materialized view ile önceden hesapla:\nCREATE MATERIALIZED VIEW mv_il_ozet AS\n  SELECT il, COUNT(*) FROM musteri GROUP BY il;\nREFRESH MATERIALIZED VIEW mv_il_ozet;","note":"PostgreSQL sorgu sonucu önbelleği sunmaz; materialized view (elle/planlı REFRESH) veya uygulama katmanı önbelleği (Redis) kullanılır. Not: Memoize düğümü nested loop içinde satır düzeyi önbellek sağlar, sorgu sonucu değil.","danger":"safe"},"mysql":{"command":"-- Query Cache MySQL 8.0'da KALDIRILDI.\n-- Alternatif: materyalize özet tablo veya uygulama önbelleği:\nCREATE TABLE il_ozet AS SELECT il, COUNT(*) c FROM musteri GROUP BY il;","note":"Eski query_cache_type MySQL 8.0 ile tamamen kaldırıldı (ölçeklenme sorunları nedeniyle). Yerine InnoDB buffer pool, özet tablolar veya harici önbellek (Redis/Memcached) kullanın.","danger":"safe"},"mssql":{"command":"-- Yerleşik sorgu sonucu önbelleği yoktur.\n-- Indexed (materialized) view ile önceden hesapla:\nCREATE VIEW dbo.vw_il_ozet WITH SCHEMABINDING AS\n  SELECT il, COUNT_BIG(*) c FROM dbo.musteri GROUP BY il;\nCREATE UNIQUE CLUSTERED INDEX ix ON dbo.vw_il_ozet(il);","note":"SQL Server sonuç önbelleği tutmaz (plan önbelleği tutar). Tekrarlı toplamalar için indexed view otomatik güncellenir; planlarda otomatik eşleştirme yalnızca Enterprise (ve Developer) sürümündedir, Standard'da view WITH (NOEXPAND) hint'iyle sorgulanmalıdır; ayrıca buffer pool sık okunan sayfaları bellekte tutar.","danger":"safe"},"mongodb":{"command":"// Yerleşik sorgu sonucu önbelleği yoktur.\n// Önceden toplayıp koleksiyona yaz ($merge):\ndb.satis.aggregate([\n  { $group: { _id: \"$il\", t: { $sum: \"$tutar\" } } },\n  { $merge: \"il_ozet\" }\n])","note":"MongoDB sonuç önbelleği sunmaz; WiredTiger sık erişilen veriyi bellekte tutar. Pahalı toplamalar için $merge/$out ile önceden hesaplanmış özet koleksiyon veya uygulama önbelleği (Redis) kullanın.","danger":"safe"},"redis":{"command":"# Redis zaten bir önbellek katmanıdır; sonucu elle önbelleğe alın:\nSET sorgu:il_ozet \"{...}\" EX 300\nGET sorgu:il_ozet\n# Hesaplanmışsa GET ile döndür, yoksa hesaplayıp SET ile yaz.","note":"Yaygın cache-aside deseni: anahtar varsa GET ile hızlı döndür; yoksa kaynaktan hesaplayıp EX (TTL) ile SET yap. Redis genellikle diğer veritabanları için sonuç önbelleği görevi görür.","danger":"safe"},"elasticsearch":{"command":"# Shard request cache (varsayılan olarak size:0 toplamalarda etkin):\nGET <index>/_search?request_cache=true\n{ \"size\": 0, \"aggs\": { \"il\": { \"terms\": { \"field\": \"il\" } } } }\n# Ayar: PUT <index>/_settings { \"index.requests.cache.enable\": true }","note":"Shard request cache, size:0 (yalnız toplama) isteklerinin shard başına sonuçlarını önbelleğe alır; index tazelenince (refresh) geçersiz kılınır. size>0 (hit döndüren) sorgular varsayılan olarak önbelleğe alınmaz.","danger":"safe"}}}]},"rosetta/advanced-features.json":{"category":"İleri Özellikler","categoryId":"advanced-features","order":18,"concepts":[{"id":"full-text-search","title":"Tam metin arama (full-text search)","aliases":["full text","tam metin","fts","arama","metin arama"],"engines":{"oracle":{"command":"-- Oracle Text: CONTEXT indeksi oluştur\nCREATE INDEX makale_idx ON makale(icerik) INDEXTYPE IS CTXSYS.CONTEXT;\n-- CONTAINS ile ara (3. parametre 1, SCORE(1) için etikettir):\nSELECT id, SCORE(1) FROM makale\nWHERE CONTAINS(icerik, 'veritabanı AND performans', 1) > 0\nORDER BY SCORE(1) DESC;","note":"Oracle Text (eski adıyla interMedia) CONTEXT index'i ile dil bilinçli tam metin arama sağlar. CONTAINS operatörü AND/OR/NEAR gibi arama operatörlerini destekler. Index CTX_DDL.SYNC_INDEX veya otomatik SYNC ile güncellenir.","danger":"safe"},"postgres":{"command":"-- tsvector/tsquery ile arama, GIN indeksiyle hızlandır:\nCREATE INDEX makale_fts_idx ON makale\n  USING GIN (to_tsvector('turkish', icerik));\nSELECT id, ts_rank(to_tsvector('turkish', icerik), q) AS skor\nFROM makale, to_tsquery('turkish', 'veritabanı & performans') q\nWHERE to_tsvector('turkish', icerik) @@ q\nORDER BY skor DESC;","note":"PostgreSQL yerleşik tam metin arama tsvector (belge) ile tsquery (sorgu) türlerini @@ operatörüyle eşleştirir. GIN index'i büyük metinlerde aramayı hızlandırır. Dil sözlüğü ('turkish') kök bulma (stemming) ve stop-word işleme yapar.","danger":"safe"},"mysql":{"command":"-- FULLTEXT indeks oluştur (InnoDB/MyISAM):\nALTER TABLE makale ADD FULLTEXT INDEX ft_icerik (icerik);\n-- Doğal dil / boolean modda ara:\nSELECT id, MATCH(icerik) AGAINST('veritabanı performans') AS skor\nFROM makale\nWHERE MATCH(icerik) AGAINST('+veritabanı +performans' IN BOOLEAN MODE);","note":"MySQL FULLTEXT index'i MATCH ... AGAINST söz dizimiyle sorgulanır. IN NATURAL LANGUAGE MODE alaka skoru döndürür; IN BOOLEAN MODE +/-/* operatörleriyle hassas denetim sağlar. InnoDB tam metin aramayı 5.6'dan itibaren destekler.","since":"MySQL 5.6","xnote":"InnoDB tam metin araması MySQL 5.6 ile geldi; öncesi yalnız MyISAM'de vardı.","danger":"safe"},"mssql":{"command":"-- Full-Text Catalog ve indeks oluştur:\nCREATE FULLTEXT CATALOG ft_katalog;\nCREATE FULLTEXT INDEX ON dbo.makale(icerik)\n  KEY INDEX PK_makale ON ft_katalog;\n-- CONTAINS / FREETEXT ile ara:\nSELECT id FROM dbo.makale\nWHERE CONTAINS(icerik, '\"veritabanı\" AND \"performans\"');","note":"SQL Server Full-Text Search için önce Full-Text Catalog, sonra tablo üzerinde Full-Text Index gerekir (benzersiz KEY INDEX zorunlu). CONTAINS kesin/yakın arama ve mantıksal operatörleri, FREETEXT anlamsal (dil bazlı) aramayı destekler. Full-Text Search bileşeni kurulu olmalıdır.","danger":"safe"},"mongodb":{"command":"// Metin (text) indeksi oluştur:\ndb.makale.createIndex({ icerik: \"text\" })\n// $text ile ara ve alaka skoruna göre sırala:\ndb.makale.find(\n  { $text: { $search: \"veritabanı performans\" } },\n  { skor: { $meta: \"textScore\" } }\n).sort({ skor: { $meta: \"textScore\" } })","note":"MongoDB text index'i $text operatörüyle tam metin arama sağlar; koleksiyon başına yalnız bir text index'i olabilir. textScore meta alanı alaka düzeyini verir. Daha gelişmiş arama için Atlas Search ($search, Lucene tabanlı) kullanılır.","danger":"safe"},"redis":{"command":"# RediSearch modülü (Redis Stack) gerektirir.\n# İndeks tanımla:\nFT.CREATE makale_idx ON HASH PREFIX 1 makale: SCHEMA icerik TEXT\n# Tam metin ara:\nFT.SEARCH makale_idx \"veritabanı performans\"","note":"Çekirdek Redis tam metin arama sunmaz; RediSearch modülü (Redis Stack ile gelir) FT.CREATE ile index, FT.SEARCH ile arama sağlar. Kök bulma, fuzzy arama, filtreleme ve sıralama desteklenir. Modül kurulu değilse özellik kullanılamaz.","danger":"safe"},"elasticsearch":{"command":"# Elasticsearch doğal olarak tam metin arama motorudur.\n# match sorgusu (analiz edilmiş metin araması):\nGET makale/_search\n{\n  \"query\": {\n    \"match\": { \"icerik\": \"veritabanı performans\" }\n  }\n}","note":"Elasticsearch temelde Lucene üzerine kurulu bir tam metin arama motorudur; text alanları indekslenirken analiz edilir (tokenizasyon, kök bulma). match sorgusu alaka skoruna (_score) göre sıralanmış sonuç döndürür. Türkçe için 'turkish' analyzer atanabilir.","danger":"safe"}}},{"id":"json-query","title":"JSON verisi sorgula","aliases":["json","json sorgu","json query","jsonb","document query"],"engines":{"oracle":{"command":"-- JSON_VALUE ile skaler değer çıkar:\nSELECT JSON_VALUE(veri, '$.musteri.il') AS il FROM siparis;\n-- JSON_TABLE ile satırlara aç:\nSELECT t.urun, t.adet\nFROM siparis s,\n     JSON_TABLE(s.veri, '$.kalemler[*]'\n       COLUMNS (urun VARCHAR2(50) PATH '$.urun',\n                adet NUMBER PATH '$.adet')) t;","note":"Oracle (12c+) JSON verisini SQL/JSON yol ifadeleriyle sorgular. JSON_VALUE tek skaler değer, JSON_QUERY nesne/dizi parçası, JSON_TABLE ise JSON'u ilişkisel satır-sütun yapısına dönüştürür. 21c+ yerel JSON veri tipini destekler.","since":"Oracle 12c","xnote":"SQL/JSON sorguları Oracle 12c, yerel JSON veri tipi 21c ile geldi.","danger":"safe"},"postgres":{"command":"-- jsonb operatörleri:\nSELECT veri->'musteri'->>'il' AS il FROM siparis;\n-- İçerme (@>) ve GIN indeksi:\nCREATE INDEX ix ON siparis USING GIN (veri);\nSELECT * FROM siparis\nWHERE veri @> '{\"durum\": \"onaylandi\"}';","note":"PostgreSQL jsonb türü zengin operatörler sunar: -> (json nesne/eleman), ->> (metin değer), #> (yol), @> (içerme), ? (anahtar var mı). GIN index'i @> ve ? sorgularını hızlandırır. jsonb_path_query ile SQL/JSON yol sorguları da yapılabilir.","since":"PostgreSQL 9.4","xnote":"json tipi PostgreSQL 9.2, jsonb tipi 9.4 ile geldi.","danger":"safe"},"mysql":{"command":"-- JSON_EXTRACT veya kısayol operatörleri:\nSELECT JSON_EXTRACT(veri, '$.musteri.il') AS il FROM siparis;\n-- ->> tırnaksız metin döndürür:\nSELECT veri->>'$.musteri.il' AS il FROM siparis\nWHERE veri->>'$.durum' = 'onaylandi';","note":"MySQL (5.7+) yerel JSON tipini JSON_EXTRACT() ile sorgular; -> operatörü JSON_EXTRACT'in, ->> ise JSON_UNQUOTE(JSON_EXTRACT())'in kısayoludur. Generated (üretilen) sütun + index ile JSON alanları üzerinde arama hızlandırılabilir.","since":"MySQL 5.7","xnote":"Yerel JSON veri tipi MySQL 5.7 ile geldi.","danger":"safe"},"mssql":{"command":"-- JSON_VALUE ile skaler değer çıkar:\nSELECT JSON_VALUE(veri, '$.musteri.il') AS il FROM siparis;\n-- OPENJSON ile satırlara aç:\nSELECT k.urun, k.adet\nFROM siparis s\nCROSS APPLY OPENJSON(s.veri, '$.kalemler')\n  WITH (urun NVARCHAR(50) '$.urun', adet INT '$.adet') k;","note":"SQL Server (2016+) JSON'u NVARCHAR sütununda tutar. JSON_VALUE skaler değer, JSON_QUERY nesne/dizi, OPENJSON ise JSON'u tablo biçimine dönüştürür. ISJSON() geçerlilik denetimi yapar. JSON yolları üzerinde hesaplanan sütun + index ile hızlandırma yapılabilir.","since":"SQL Server 2016","xnote":"JSON fonksiyonları (JSON_VALUE/OPENJSON) SQL Server 2016 ile geldi.","danger":"safe"},"mongodb":{"command":"// MongoDB yerel olarak belge (BSON/JSON) veritabanıdır.\n// İç içe alanlara nokta gösterimiyle eriş:\ndb.siparis.find({ \"musteri.il\": \"Ankara\" })\n// Dizi elemanı ve projeksiyon:\ndb.siparis.find(\n  { \"kalemler.urun\": \"kalem\" },\n  { \"kalemler.$\": 1 }\n)","note":"MongoDB verinin tamamını belge (JSON benzeri BSON) olarak saklar; sorgulama doğaldır. Nokta gösterimi iç içe alanlara ve dizi elemanlarına erişir. Aggregation Pipeline ile karmaşık dönüşümler, indeksleme ile iç içe alanlarda hızlı arama yapılır.","danger":"safe"},"redis":{"command":"# RedisJSON modülü (Redis Stack) gerektirir.\n# JSON belge yaz:\nJSON.SET siparis:1 $ '{\"musteri\":{\"il\":\"Ankara\"},\"durum\":\"onaylandi\"}'\n# JSONPath ile değer oku:\nJSON.GET siparis:1 $.musteri.il","note":"Çekirdek Redis'te JSON tipi yoktur; RedisJSON modülü (Redis Stack) JSON.SET/JSON.GET ile JSONPath tabanlı okuma-yazma sağlar. RediSearch ile birlikte JSON belgeleri indekslenip sorgulanabilir. Modül yoksa JSON string olarak saklanıp uygulamada ayrıştırılır.","danger":"safe"},"elasticsearch":{"command":"# Belgeler zaten JSON'dur; alanlara doğrudan sorgu:\nGET siparis/_search\n{ \"query\": { \"term\": { \"musteri.il\": \"Ankara\" } } }\n# İç içe dizi için nested tip ve nested sorgu:\nGET siparis/_search\n{ \"query\": { \"nested\": { \"path\": \"kalemler\",\n  \"query\": { \"match\": { \"kalemler.urun\": \"kalem\" } } } } }","note":"Elasticsearch belgeleri yerel JSON olarak saklar ve indeksler. İç içe nesne dizilerinde eleman bağlarını korumak için 'nested' alan tipi ve nested sorgu kullanılır; aksi halde object tipinde diziler düzleştirilir (çapraz eşleşme riski). object ve nested ayrımı doğruluk için kritiktir.","danger":"safe"}}},{"id":"spatial-geo","title":"Coğrafi / spatial sorgu","aliases":["spatial","coğrafi","geo","gis","konum","harita"],"engines":{"oracle":{"command":"-- Oracle Spatial: SDO_GEOMETRY sütunu ve spatial indeks\nCREATE INDEX konum_sidx ON magaza(konum)\n  INDEXTYPE IS MDSYS.SPATIAL_INDEX;\n-- 5 km içindeki mağazalar:\nSELECT ad FROM magaza\nWHERE SDO_WITHIN_DISTANCE(konum,\n  SDO_GEOMETRY(2001, 4326,\n    SDO_POINT_TYPE(32.85, 39.92, NULL), NULL, NULL),\n  'distance=5 unit=KM') = 'TRUE';","note":"Oracle Spatial coğrafi veriyi SDO_GEOMETRY tipiyle saklar; USER_SDO_GEOM_METADATA kaydı ve spatial index gerekir. SDO_WITHIN_DISTANCE, SDO_RELATE, SDO_NN gibi operatörler mesafe/kesişim/en yakın komşu sorgularını çözer. SRID 4326 WGS84 (enlem/boylam) sistemidir.","danger":"safe"},"postgres":{"command":"-- PostGIS eklentisi:\nCREATE EXTENSION IF NOT EXISTS postgis;\nCREATE INDEX konum_gix ON magaza USING GIST (konum);\n-- 5 km içindeki mağazalar (geography, metre):\nSELECT ad FROM magaza\nWHERE ST_DWithin(konum,\n  ST_SetSRID(ST_MakePoint(32.85, 39.92), 4326)::geography,\n  5000);","note":"PostGIS, PostgreSQL'i tam donanımlı bir coğrafi veritabanına dönüştürür. geometry (düzlemsel) ve geography (küresel) tipleri, ST_Distance/ST_DWithin/ST_Intersects/ST_Contains gibi yüzlerce ST_ fonksiyonu sağlar. GiST/SP-GiST index'i spatial sorguları hızlandırır.","danger":"safe"},"mysql":{"command":"-- Spatial (SRID'li) sütun ve SPATIAL indeks:\nALTER TABLE magaza MODIFY konum POINT NOT NULL SRID 4326;\nALTER TABLE magaza ADD SPATIAL INDEX (konum);\n-- Mesafe hesapla (metre, geography):\nSELECT ad,\n  ST_Distance(konum,\n    ST_SRID(POINT(32.85, 39.92), 4326)) AS mesafe\nFROM magaza\nORDER BY mesafe LIMIT 10;","note":"MySQL (5.7+) OGC uyumlu spatial veri tiplerini (POINT, POLYGON vb.) ve ST_ fonksiyonlarını destekler. SPATIAL index (R-tree) yalnız InnoDB/MyISAM'de ve NOT NULL sütunlarda kurulur; optimizer'ın kullanması için sütun SRID özniteliğiyle (SRID 4326) tanımlanmalıdır. SRID 4326 ile ST_Distance metre cinsinden jeodezik mesafe döndürür. POINT(x, y) + ST_SRID'de x boylam, y enlemdir; WKT girdisinde (ST_GeomFromText) SRID 4326 için sıra enlem-boylamdır.","danger":"safe"},"mssql":{"command":"-- geography tipi ve spatial indeks:\nCREATE SPATIAL INDEX konum_sidx ON dbo.magaza(konum);\n-- 5 km içindeki mağazalar (STDistance metre döndürür):\nSELECT ad FROM dbo.magaza\nWHERE konum.STDistance(\n  geography::Point(39.92, 32.85, 4326)) <= 5000;","note":"SQL Server iki spatial tip sunar: geography (küresel, enlem/boylam) ve geometry (düzlemsel). STDistance, STIntersects, STContains gibi metotlar sorguları çözer. Spatial index (grid tabanlı) performansı artırır. geography::Point(enlem, boylam, SRID) sırasına dikkat edilmelidir.","danger":"safe"},"mongodb":{"command":"// 2dsphere indeksi (GeoJSON için):\ndb.magaza.createIndex({ konum: \"2dsphere\" })\n// Belirli noktaya en yakın mağazalar ($near):\ndb.magaza.find({\n  konum: {\n    $near: {\n      $geometry: { type: \"Point\", coordinates: [32.85, 39.92] },\n      $maxDistance: 5000\n    }\n  }\n})","note":"MongoDB coğrafi veriyi GeoJSON biçiminde saklar ve 2dsphere index'iyle küresel sorgular yapar. $near (mesafeye göre sıralı), $geoWithin (alan içinde), $geoIntersects operatörleri desteklenir. Koordinatlar [boylam, enlem] sırasındadır; $maxDistance metre cinsindendir.","danger":"safe"},"redis":{"command":"# Yerleşik geospatial komutlar (sorted set üzerine kurulu):\nGEOADD magazalar 32.85 39.92 \"kizilay\"\nGEOADD magazalar 32.86 39.93 \"cankaya\"\n# Bir noktanın 5 km çevresini ara:\nGEOSEARCH magazalar FROMLONLAT 32.85 39.92\n  BYRADIUS 5 km ASC","note":"Redis coğrafi konumları GEOADD ile sorted set içinde saklar (boylam enlem üye). GEOSEARCH (Redis 6.2+, eski GEORADIUS yerine) yarıçap veya kutu içindeki üyeleri mesafeye göre sıralı döndürür. GEODIST iki nokta arası mesafeyi verir. Çekirdek özelliktir, modül gerekmez.","danger":"safe"},"elasticsearch":{"command":"# Alanı geo_point olarak eşle:\nPUT magaza\n{ \"mappings\": { \"properties\": { \"konum\": { \"type\": \"geo_point\" } } } }\n# 5 km çevresini sorgula:\nGET magaza/_search\n{ \"query\": { \"geo_distance\": {\n  \"distance\": \"5km\",\n  \"konum\": { \"lat\": 39.92, \"lon\": 32.85 } } } }","note":"Elasticsearch geo_point (nokta) ve geo_shape (çokgen/çizgi) alan tiplerini destekler. geo_distance (yarıçap), geo_bounding_box (kutu), geo_polygon sorgularıyla filtreleme; geo_distance ile sıralama ve geohash_grid/geotile_grid ile toplama yapılır. Koordinat lat/lon veya [lon, lat] dizisi olarak verilir.","danger":"safe"}}},{"id":"window-functions-adv","title":"Pencere fonksiyonları (ROW_NUMBER/RANK/LAG)","aliases":["window function","pencere fonksiyon","row_number","rank","lag","over","analytic"],"engines":{"oracle":{"command":"-- Her il içinde satışa göre sırala ve önceki değeri getir:\nSELECT il, ad, tutar,\n  ROW_NUMBER() OVER (PARTITION BY il ORDER BY tutar DESC) AS sira,\n  RANK()       OVER (PARTITION BY il ORDER BY tutar DESC) AS rutbe,\n  LAG(tutar)   OVER (PARTITION BY il ORDER BY tarih)      AS onceki\nFROM satis;","note":"Oracle analitik (pencere) fonksiyonlarının öncüsüdür; ROW_NUMBER, RANK, DENSE_RANK, LAG, LEAD, SUM/AVG OVER, NTILE, FIRST_VALUE tam desteklenir. OVER içinde PARTITION BY grupları, ORDER BY sıralamayı, çerçeve (ROWS/RANGE BETWEEN) kayan pencereyi tanımlar.","since":"Oracle 8i","danger":"safe"},"postgres":{"command":"-- OVER() ile pencere fonksiyonları:\nSELECT il, ad, tutar,\n  ROW_NUMBER() OVER (PARTITION BY il ORDER BY tutar DESC) AS sira,\n  RANK()       OVER (PARTITION BY il ORDER BY tutar DESC) AS rutbe,\n  LAG(tutar)   OVER (PARTITION BY il ORDER BY tarih)      AS onceki\nFROM satis;","note":"PostgreSQL pencere fonksiyonlarını standart SQL söz dizimiyle tam destekler. ROW_NUMBER/RANK/DENSE_RANK, LAG/LEAD, toplama OVER, NTILE, FIRST_VALUE/LAST_VALUE kullanılabilir. Tekrar eden pencere tanımları WINDOW yan tümcesiyle adlandırılıp paylaşılabilir.","since":"PostgreSQL 8.4","danger":"safe"},"mysql":{"command":"-- MySQL 8.0+ pencere fonksiyonları:\nSELECT il, ad, tutar,\n  ROW_NUMBER() OVER (PARTITION BY il ORDER BY tutar DESC) AS sira,\n  RANK()       OVER (PARTITION BY il ORDER BY tutar DESC) AS rutbe,\n  LAG(tutar)   OVER (PARTITION BY il ORDER BY tarih)      AS onceki\nFROM satis;","note":"MySQL pencere fonksiyonlarını 8.0 sürümüyle ekledi (MariaDB 10.2+ da destekler). ROW_NUMBER, RANK, DENSE_RANK, LAG, LEAD, NTILE ve toplama OVER kullanılabilir. 8.0 öncesi sürümlerde bu fonksiyonlar yoktur; kullanıcı değişkenleriyle taklit edilirdi.","since":"MySQL 8.0","xnote":"MySQL 8.0 öncesi pencere fonksiyonu yoktu; kullanıcı değişkenleriyle taklit edilirdi.","danger":"safe"},"mssql":{"command":"-- OVER() ile pencere fonksiyonları:\nSELECT il, ad, tutar,\n  ROW_NUMBER() OVER (PARTITION BY il ORDER BY tutar DESC) AS sira,\n  RANK()       OVER (PARTITION BY il ORDER BY tutar DESC) AS rutbe,\n  LAG(tutar)   OVER (PARTITION BY il ORDER BY tarih)      AS onceki\nFROM dbo.satis;","note":"SQL Server pencere fonksiyonlarını 2005'ten (ROW_NUMBER/RANK) ve 2012'den (LAG/LEAD, çerçeve, toplama OVER) itibaren destekler. PARTITION BY, ORDER BY ve ROWS/RANGE çerçevesi tam kullanılabilir. Sayfalama için OFFSET/FETCH veya ROW_NUMBER yaygındır.","since":"SQL Server 2005","xnote":"Sıralama fonksiyonları 2005, LAG/LEAD ve çerçeve 2012 ile geldi.","danger":"safe"},"mongodb":{"command":"// $setWindowFields ile pencere hesaplamaları:\ndb.satis.aggregate([\n  { $setWindowFields: {\n      partitionBy: \"$il\",\n      sortBy: { tutar: -1 },\n      output: {\n        sira: { $documentNumber: {} },\n        rutbe: { $rank: {} },\n        onceki: { $shift: { output: \"$tutar\", by: -1 } }\n      }\n  } }\n])","note":"MongoDB 5.0 ile gelen $setWindowFields aggregation aşaması pencere fonksiyonlarını sağlar: $documentNumber (ROW_NUMBER), $rank/$denseRank, $shift (LAG/LEAD), toplama fonksiyonları ve kayan pencere (window: { documents/range }). partitionBy ve sortBy SQL'deki PARTITION/ORDER BY karşılığıdır.","since":"MongoDB 5.0","xnote":"$setWindowFields aşaması MongoDB 5.0 ile geldi.","danger":"safe"},"redis":{"command":"# Uygulanamaz: SQL benzeri pencere fonksiyonu yoktur.","note":"Redis anahtar-değer deposudur; analitik pencere fonksiyonları içermez. Sıralı sonuçlar için Sorted Set (ZADD/ZRANGE ile sıra ve rütbe benzeri erişim) kullanılabilir; ancak PARTITION BY/LAG gibi ilişkisel pencere işlemleri uygulama katmanında yapılır.","danger":"safe"},"elasticsearch":{"command":"# Uygulanamaz: SQL benzeri pencere fonksiyonu yoktur.\n# En yakın karşılık: koleksiyon toplama (aggregation).\nGET satis/_search\n{ \"size\": 0, \"aggs\": { \"il_bazli\": {\n  \"terms\": { \"field\": \"il\" },\n  \"aggs\": { \"toplam\": { \"sum\": { \"field\": \"tutar\" } } } } } }","note":"Elasticsearch klasik pencere fonksiyonları (ROW_NUMBER/RANK/LAG) sunmaz. Gruplama ve sıralama aggregation çerçevesiyle yapılır: terms toplaması PARTITION BY'a, top_hits en iyi kayıtlara, derivative/serial_diff (pipeline aggregation) ise LAG benzeri ardışık fark hesabına yakındır.","danger":"safe"}}},{"id":"columnstore-analytics","title":"Sütun-tabanlı depolama / analitik","aliases":["columnstore","sütun tabanlı","column store","analitik","olap","columnar"],"engines":{"oracle":{"command":"-- Database In-Memory: tabloyu sütunsal olarak bellekte tut\nALTER TABLE satis INMEMORY;\n-- Öncelik ve sıkıştırma ile:\nALTER TABLE satis INMEMORY PRIORITY HIGH\n  MEMCOMPRESS FOR QUERY HIGH;","note":"Oracle Database In-Memory (12.1.0.2+) tabloları bellekte sütunsal (In-Memory Column Store, IM) biçimde tutarak analitik sorguları hızlandırır; disk satır biçimini korur (çift format). INMEMORY ayrı lisanslı bir seçenektir. inmemory_size parametresi IM alanını belirler.","since":"Oracle 12.1.0.2","xnote":"Database In-Memory sütun deposu Oracle 12.1.0.2 ile geldi (ayrı lisans).","danger":"caution"},"postgres":{"command":"-- Çekirdek PostgreSQL satır tabanlıdır; sütunsal için eklenti:\n-- Citus columnar erişim yöntemi:\nCREATE EXTENSION IF NOT EXISTS citus;\nCREATE TABLE satis_kolon (...) USING columnar;\n-- Alternatif: Hydra/cstore_fdw uzantıları.","note":"Çekirdek PostgreSQL yalnız satır tabanlı (heap) depolama sunar. Sütunsal depolama için Citus 'columnar' erişim yöntemi (USING columnar), Hydra veya eski cstore_fdw eklentileri kullanılır; bunlar analitik/veri ambarı yükleri için sıkıştırma ve tarama hızı sağlar.","danger":"safe"},"mysql":{"command":"-- Uygulanamaz: çekirdek InnoDB sütunsal depolama sunmaz.\n-- Analitik için: MySQL HeatWave (bulut, bellek-içi sütunsal)\n-- veya harici ClickHouse/Apache Doris entegrasyonu.","note":"Standart MySQL (InnoDB) satır tabanlıdır ve yerleşik columnstore içermez. Analitik hızlandırma için MySQL HeatWave (Oracle bulutunda bellek-içi sütunsal hızlandırıcı) kullanılır; kurulum içi çözümlerde ClickHouse veya Apache Doris gibi harici sütunsal motorlar tercih edilir.","danger":"safe"},"mssql":{"command":"-- Clustered columnstore indeksi (analitik tablolar için):\nCREATE CLUSTERED COLUMNSTORE INDEX cci_satis ON dbo.satis;\n-- Satır tablosuna nonclustered columnstore (HTAP):\nCREATE NONCLUSTERED COLUMNSTORE INDEX ncci_satis\n  ON dbo.satis (il, urun, tutar, tarih);","note":"SQL Server columnstore index'leri (2012'de salt okunur nonclustered; 2014'te güncellenebilir clustered; 2016'da güncellenebilir nonclustered) veriyi sütun bazlı ve yüksek sıkıştırmalı saklar; toplama/tarama ağırlıklı analitik sorgularda batch mode ile büyük hızlanma sağlar. Clustered columnstore veri ambarları, nonclustered columnstore ise HTAP için uygundur.","since":"SQL Server 2012","xnote":"Columnstore index'i 2012 (salt okunur), güncellenebilir clustered columnstore 2014, güncellenebilir nonclustered columnstore 2016 ile geldi.","danger":"safe"},"mongodb":{"command":"-- Uygulanamaz: MongoDB belge (satır benzeri) tabanlıdır.\n-- Analitik için: Atlas'ta ayrı Analytics Node'lar\n-- veya kolonsal biçime ($out) aktarım/harici motor.","note":"MongoDB belgeleri satır benzeri BSON olarak saklar; yerleşik sütunsal (columnstore) depolama yoktur. Analitik yükler için Atlas replica set'te ayrılmış Analytics Node'lar, Atlas Data Federation veya verinin sütunsal bir sisteme (ör. Parquet) aktarımı kullanılır.","danger":"safe"},"redis":{"command":"-- Uygulanamaz: sütun tabanlı depolama kavramı yoktur.","note":"Redis bellek-içi anahtar-değer deposudur; satır/sütun depolama ayrımı yoktur. Analitik toplamalar Sorted Set, HyperLogLog (yaklaşık sayım) veya RedisTimeSeries gibi özel yapılarla yapılır; büyük ölçekli OLAP için uygun değildir.","danger":"safe"},"elasticsearch":{"command":"# doc_values: alanlar disk üzerinde sütunsal saklanır (varsayılan açık).\n# Sıralama/toplama için gereklidir; text dışı alanlarda etkindir.\nPUT satis\n{ \"mappings\": { \"properties\":\n  { \"tutar\": { \"type\": \"double\", \"doc_values\": true } } } }","note":"Elasticsearch, sıralama ve toplama (aggregation) için alanları doc_values adı verilen disk tabanlı sütunsal yapıda tutar (sayısal/keyword/tarih alanlarında varsayılan açık). Bu sütunsal düzen analitik/toplama sorgularını hızlandırır; text alanlarında varsayılan kapalıdır.","danger":"safe"}}},{"id":"in-memory","title":"Bellek-içi tablo / hızlandırma","aliases":["in memory","bellek içi","memory table","hızlandırma","in-memory oltp"],"engines":{"oracle":{"command":"-- Database In-Memory ile tabloyu bellekte tut:\nALTER TABLE siparis INMEMORY;\n-- Bellek boyutu (init parametresi):\nALTER SYSTEM SET inmemory_size = 4G SCOPE=SPFILE;","note":"Oracle Database In-Memory sık sorgulanan tabloları bellekte sütunsal biçimde tutarak analitiği hızlandırır (ayrı lisans). OLTP için ayrıca Buffer Cache ve KEEP pool sık erişilen bloğu bellekte tutar. Bellek-içi çözüm kalıcılığı diskteki satır biçimiyle korur.","danger":"caution"},"postgres":{"command":"-- Kalıcılığı olmayan hızlı tablo (WAL yazmaz):\nCREATE UNLOGGED TABLE gecici_hesap (id int, veri text);\n-- Oturuma özel geçici tablo (bellekte tutulmaya yatkın):\nCREATE TEMP TABLE oturum_veri (id int) ON COMMIT DELETE ROWS;","note":"PostgreSQL adanmış bellek-içi tablo motoru sunmaz; UNLOGGED tablo WAL yazmayı atlayarak yazmayı hızlandırır (çökmede içerik kaybolur, kalıcı değildir). TEMP tablolar oturum ömürlüdür ve temp_buffers ile bellekte tutulmaya çalışılır. Sıcak veri shared_buffers'ta önbelleklenir.","danger":"caution"},"mysql":{"command":"-- MEMORY (HEAP) depolama motoruyla tablo:\nCREATE TABLE onbellek (\n  id INT PRIMARY KEY,\n  veri VARCHAR(100)\n) ENGINE=MEMORY;","note":"MySQL MEMORY (eski adıyla HEAP) depolama motoru tablo verisini tamamen RAM'de tutar; çok hızlıdır ancak sunucu yeniden başlayınca veri kaybolur (yapı kalır). BLOB/TEXT desteklemez ve sabit satır boyutu kullanır. Kalıcı sıcak veri için InnoDB buffer pool tercih edilir.","danger":"caution"},"mssql":{"command":"-- In-Memory OLTP: bellek-optimize tablo\nCREATE TABLE dbo.oturum (\n  id INT NOT NULL PRIMARY KEY NONCLUSTERED,\n  veri NVARCHAR(100)\n) WITH (MEMORY_OPTIMIZED = ON, DURABILITY = SCHEMA_AND_DATA);","note":"SQL Server In-Memory OLTP (Hekaton) bellek-optimize tablolar (MEMORY_OPTIMIZED=ON) ve kilitsiz (latch-free) yapılarla yüksek eşzamanlı OLTP sağlar. DURABILITY=SCHEMA_AND_DATA veriyi kalıcı, SCHEMA_ONLY yalnız şemayı korur. Bellek-optimize dosya grubu gerektirir.","since":"SQL Server 2014","xnote":"In-Memory OLTP (Hekaton) SQL Server 2014 ile geldi.","danger":"caution"},"mongodb":{"command":"-- Sıcak veri WiredTiger önbelleğinde otomatik tutulur.\n-- Önbellek boyutunu ayarla (varsayılan RAM'in ~%50'si):\n// mongod --wiredTigerCacheSizeGB 8\n// veya yapılandırma: storage.wiredTiger.engineConfig.cacheSizeGB","note":"MongoDB'nin ayrı bir bellek-içi tablo tipi yoktur (eski In-Memory Storage Engine yalnız Enterprise'daydı ve kullanımdan kalktı). Varsayılan WiredTiger motoru sık erişilen veriyi ve index'leri bellek önbelleğinde (cache) tutarak okuma hızını artırır; işletim sistemi dosya önbelleği de katkı sağlar.","danger":"safe"},"redis":{"command":"# Redis zaten tümüyle bellek-içi çalışır; ek işlem gerekmez.\n# Kalıcılık ve bellek politikası ayarları:\nCONFIG SET maxmemory 4gb\nCONFIG SET maxmemory-policy allkeys-lru","note":"Redis veriyi tümüyle RAM'de tutar; bu tasarımı gereği yüksek hızının kaynağıdır. Kalıcılık RDB (snapshot) ve/veya AOF (komut log'u) ile sağlanır. maxmemory sınırı ve eviction politikası (LRU/LFU/random) bellek dolduğunda davranışı belirler.","danger":"safe"},"elasticsearch":{"command":"-- Uygulanamaz: tümüyle bellek-içi tablo modu yoktur.\n# Sıcak/soğuk mimari ile sıcak veriyi hızlı düğümlere yerleştir:\nPUT satis/_settings\n{ \"index.routing.allocation.require.data\": \"hot\" }","note":"Elasticsearch veriyi disk üzerinde (Lucene segmentleri) saklar; adanmış bellek-içi tablo motoru sunmaz. Hız için işletim sistemi dosya önbelleği (page cache), doc_values ve sıcak/ılık/soğuk (hot-warm-cold) mimarisi kullanılır. Yeterli RAM ve heap ayarı performans için kritiktir.","danger":"safe"}}},{"id":"time-series","title":"Zaman-serisi verisi","aliases":["time series","zaman serisi","timeseries","iot","metrik","sensör"],"engines":{"oracle":{"command":"-- Tarihe göre aralık bölümleme (range partitioning):\nCREATE TABLE olcum (\n  ts TIMESTAMP, sensor_id NUMBER, deger NUMBER)\nPARTITION BY RANGE (ts)\nINTERVAL (NUMTODSINTERVAL(1,'DAY'))\n( PARTITION p0 VALUES LESS THAN (TIMESTAMP '2026-01-01 00:00:00') );","note":"Oracle'da zaman serisi verisi genellikle RANGE (INTERVAL) bölümleme ile yönetilir; yeni bölümler otomatik oluşur ve eski bölümler kolayca düşürülür (bölüm budama sorguyu hızlandırır). Ayrıca sıkıştırma (ILM/ADO) ve materialized view ile toplama yapılır.","danger":"safe"},"postgres":{"command":"-- TimescaleDB eklentisi ile hypertable:\nCREATE EXTENSION IF NOT EXISTS timescaledb;\nCREATE TABLE olcum (ts TIMESTAMPTZ, sensor_id INT, deger DOUBLE PRECISION);\nSELECT create_hypertable('olcum', 'ts');\n-- Sürekli toplama (continuous aggregate) ile özetle.","note":"PostgreSQL yerel bölümleme (PARTITION BY RANGE) ile zaman serisi tutabilir; TimescaleDB eklentisi ise hypertable ile otomatik zaman-bazlı chunk'lara bölme, sıkıştırma, saklama politikası ve sürekli toplamalar (continuous aggregates) sağlar. Büyük IoT/metrik yükleri için yaygın çözümdür.","danger":"safe"},"mysql":{"command":"-- Tarihe göre RANGE bölümleme:\nCREATE TABLE olcum (\n  ts DATETIME, sensor_id INT, deger DOUBLE,\n  PRIMARY KEY (ts, sensor_id))\nPARTITION BY RANGE (TO_DAYS(ts)) (\n  PARTITION p2026_01 VALUES LESS THAN (TO_DAYS('2026-02-01')),\n  PARTITION pmax VALUES LESS THAN MAXVALUE);","note":"MySQL özel bir zaman serisi motoru sunmaz; RANGE bölümleme (TO_DAYS/UNIX_TIMESTAMP ile) eski verinin hızlı düşürülmesini ve bölüm budamayı sağlar. Yüksek hacimli zaman serisi için genellikle harici çözümler (TimescaleDB, InfluxDB) veya özet tablolar tercih edilir.","danger":"safe"},"mssql":{"command":"-- Bölümlenmis tablo (partition function + scheme) veya\n-- sistem sürümlü temporal tablo (geçmiş kaydı otomatik):\nCREATE TABLE dbo.olcum (\n  id INT PRIMARY KEY, deger DECIMAL(10,2),\n  gecerli_baslangic DATETIME2 GENERATED ALWAYS AS ROW START,\n  gecerli_bitis DATETIME2 GENERATED ALWAYS AS ROW END,\n  PERIOD FOR SYSTEM_TIME (gecerli_baslangic, gecerli_bitis))\nWITH (SYSTEM_VERSIONING = ON);","note":"SQL Server zaman serisini partition function/scheme ile bölümleyerek yönetir; büyük tarih aralıklı verilerde budama ve hızlı arşivleme sağlar. Ayrıca sistem sürümlü temporal tablolar (SYSTEM_VERSIONING) satır değişiklik geçmişini otomatik saklayarak zaman içinde sorgulamaya (FOR SYSTEM_TIME) izin verir.","since":"SQL Server 2016","xnote":"Sistem sürümlü temporal tablolar SQL Server 2016 ile geldi.","danger":"safe"},"mongodb":{"command":"// Zaman serisi koleksiyonu (MongoDB 5.0+):\ndb.createCollection(\"olcum\", {\n  timeseries: {\n    timeField: \"ts\",\n    metaField: \"sensor_id\",\n    granularity: \"seconds\"\n  }\n})","note":"MongoDB 5.0 ile gelen time-series koleksiyonları veriyi zaman ve meta alanına göre otomatik olarak sütun benzeri (bucketing) sıkıştırılmış biçimde saklar; disk ve index kullanımını azaltıp aralık sorgularını hızlandırır. timeField zorunlu, metaField (kaynak/etiket) ve granularity performansı belirler.","since":"MongoDB 5.0","xnote":"Zaman serisi koleksiyonları MongoDB 5.0 ile geldi.","danger":"safe"},"redis":{"command":"# RedisTimeSeries modülü (Redis Stack) gerektirir.\n# Seri oluştur ve saklama süresi ver:\nTS.CREATE sensor:1 RETENTION 86400000 LABELS tip sicaklik\n# Örnek ekle (otomatik zaman damgasıyla):\nTS.ADD sensor:1 * 23.5","note":"Çekirdek Redis'te zaman serisi tipi yoktur; RedisTimeSeries modülü (Redis Stack) TS.CREATE/TS.ADD ile yüksek hızlı örnek alımı, otomatik saklama (RETENTION), downsampling (TS.CREATERULE) ve TS.RANGE/TS.MRANGE ile etiket bazlı aralık sorguları sağlar. Modül yoksa Sorted Set ile taklit edilir.","danger":"safe"},"elasticsearch":{"command":"# Data stream: zaman serisi için otomatik rolling indeks\nPUT _index_template/olcum-tpl\n{ \"index_patterns\": [\"olcum*\"], \"data_stream\": {},\n  \"template\": {\n    \"settings\": { \"index.mode\": \"time_series\", \"index.routing_path\": [\"sensor_id\"] },\n    \"mappings\": { \"properties\": {\n      \"@timestamp\": { \"type\": \"date\" },\n      \"sensor_id\": { \"type\": \"keyword\", \"time_series_dimension\": true },\n      \"sicaklik\": { \"type\": \"double\", \"time_series_metric\": \"gauge\" } } } } }\nPUT _data_stream/olcum","note":"Elasticsearch zaman serisi verisini data stream ile yönetir; arkada zamana göre yeni index'ler (backing index) otomatik oluşturulur (rollover) ve ILM ile eski veri sıcak/ılık/soğuk katmanlara taşınıp silinir. TSDS (index.mode: time_series) metrik verisi için özel depolama optimizasyonu sağlar; en az bir time_series_dimension alanı, bunu gösteren index.routing_path ve @timestamp alanı zorunludur (aksi halde şablon reddedilir).","danger":"safe"}}},{"id":"vector-search","title":"Vektör arama (AI/embedding)","aliases":["vector search","vektör arama","embedding","ai","semantic search","knn"],"engines":{"oracle":{"command":"-- Oracle 23ai yerel VECTOR tipi:\nCREATE TABLE belge (id NUMBER, icerik CLOB, gomme VECTOR);\n-- Benzerlik araması (kosinüs mesafesi):\nSELECT id FROM belge\nORDER BY VECTOR_DISTANCE(gomme, :sorgu_vektor, COSINE)\nFETCH FIRST 5 ROWS ONLY;","note":"Oracle Database 23ai yerel VECTOR veri tipini ve AI Vector Search özelliğini sunar. VECTOR_DISTANCE fonksiyonu COSINE/EUCLIDEAN/DOT metrikleriyle benzerlik hesaplar; yaklaşık arama için HNSW ve IVF vektör index'leri desteklenir. Embedding'ler kurum içinde veya harici modellerle üretilir.","since":"Oracle 23ai","xnote":"Yerel VECTOR tipi ve AI Vector Search Oracle 23ai ile geldi.","danger":"safe"},"postgres":{"command":"-- pgvector eklentisi:\nCREATE EXTENSION IF NOT EXISTS vector;\nCREATE TABLE belge (id int, gomme vector(1536));\nCREATE INDEX ON belge USING hnsw (gomme vector_cosine_ops);\n-- En yakın 5 komşu (<-> öklit, <=> kosinüs):\nSELECT id FROM belge ORDER BY gomme <=> :sorgu LIMIT 5;","note":"pgvector eklentisi PostgreSQL'e vector tipi ve benzerlik operatörleri ekler: <-> (L2/öklit), <=> (kosinüs), <#> (iç çarpım). HNSW veya IVFFlat index'leri yaklaşık en yakın komşu (ANN) aramasını hızlandırır. RAG ve anlamsal arama uygulamalarında yaygın kullanılır.","xnote":"Çekirdek PostgreSQL'de vektör tipi yoktur; pgvector eklentisi gerekir.","danger":"safe"},"mysql":{"command":"-- MySQL 9.0+ yerel VECTOR tipi:\nCREATE TABLE belge (id INT, gomme VECTOR(1536));\n-- Kosinüs mesafesi (DISTANCE yalnız HeatWave'de):\nSELECT id, DISTANCE(gomme, :sorgu, 'COSINE') AS d\nFROM belge ORDER BY d LIMIT 5;","note":"MySQL 9.0 yerel VECTOR veri tipini ve STRING_TO_VECTOR/VECTOR_TO_STRING, VECTOR_DIM fonksiyonlarını ekledi (Community'de de vardır). DISTANCE() fonksiyonu ve ölçekli yaklaşık vektör araması ise yalnız Oracle bulutundaki MySQL HeatWave'de vardır; Community/Enterprise'da mesafe uygulamada veya harici vektör deposunda hesaplanır. Kurum içi eski sürümlerde harici vektör deposu gerekir.","since":"MySQL 9.0","xnote":"Yerel VECTOR veri tipi MySQL 9.0 ile geldi.","danger":"safe"},"mssql":{"command":"-- SQL Server 2025 yerel vector tipi:\nCREATE TABLE belge (id INT, gomme VECTOR(1536));\n-- Kosinüs mesafesiyle en yakın komşular:\nSELECT TOP 5 id,\n  VECTOR_DISTANCE('cosine', gomme, @sorgu) AS mesafe\nFROM dbo.belge ORDER BY mesafe;","note":"SQL Server 2025 (ve Azure SQL) yerel vector veri tipini ve VECTOR_DISTANCE fonksiyonunu (cosine/euclidean/dot) sunar; yaklaşık en yakın komşu için DiskANN tabanlı vektör index'leri geliştirilmektedir. Embedding'ler Azure OpenAI gibi harici modellerle üretilip saklanır.","since":"SQL Server 2025","xnote":"Yerel vector veri tipi SQL Server 2025 ile geldi.","danger":"safe"},"mongodb":{"command":"// Atlas Vector Search ($vectorSearch aggregation aşaması):\ndb.belge.aggregate([\n  { $vectorSearch: {\n      index: \"vektor_idx\",\n      path: \"gomme\",\n      queryVector: [0.12, 0.87, /* ... */],\n      numCandidates: 100,\n      limit: 5\n  } }\n])","note":"MongoDB Atlas Vector Search, embedding'leri $vectorSearch aggregation aşamasıyla sorgular; arka planda HNSW tabanlı yaklaşık en yakın komşu araması yapar. Vektör index'i Atlas Search index'i olarak tanımlanır. Bu özellik yönetilen Atlas hizmetine özgüdür (kurum içi topluluk sürümünde yoktur).","danger":"safe"},"redis":{"command":"# RediSearch (Redis Stack) VECTOR alan tipi gerektirir.\n# HNSW vektör indeksi tanımla:\nFT.CREATE belge_idx ON HASH PREFIX 1 belge: SCHEMA\n  gomme VECTOR HNSW 6 TYPE FLOAT32 DIM 1536 DISTANCE_METRIC COSINE\n# KNN araması (sorgu vektörü ile):\nFT.SEARCH belge_idx \"*=>[KNN 5 @gomme $vec]\" PARAMS 2 vec \"...\"","note":"Redis vektör aramayı RediSearch modülü (Redis Stack) ile sağlar; VECTOR alan tipi FLAT (kesin) veya HNSW (yaklaşık) index, COSINE/L2/IP metriklerini destekler. FT.SEARCH içinde KNN söz dizimiyle en yakın komşular getirilir. Düşük gecikmeli anlamsal arama ve RAG için kullanılır.","danger":"safe"},"elasticsearch":{"command":"# dense_vector alanı ve kNN araması:\nPUT belge\n{ \"mappings\": { \"properties\": { \"gomme\":\n  { \"type\": \"dense_vector\", \"dims\": 1536, \"similarity\": \"cosine\" } } } }\nGET belge/_search\n{ \"knn\": { \"field\": \"gomme\", \"query_vector\": [0.12, 0.87],\n  \"k\": 5, \"num_candidates\": 100 } }","note":"Elasticsearch dense_vector alan tipi ve yerleşik knn araması ile yaklaşık en yakın komşu (HNSW) sorgularını destekler; similarity cosine/dot_product/l2_norm olabilir. Vektör aramayı klasik metin sorgusuyla birleştirerek (hybrid search / RRF) alaka düzeyini artırmak mümkündür.","since":"Elasticsearch 8.0","xnote":"Yerleşik dense_vector kNN araması Elasticsearch 8.x ile geldi.","danger":"safe"}}},{"id":"cdc-change-tracking","title":"Değişiklik takibi (CDC / change tracking)","aliases":["cdc","change data capture","değişiklik takibi","change tracking","replication feed","binlog"],"engines":{"oracle":{"command":"-- LogMiner ile redo log'lardan değişiklik oku:\n-- 1) İncelenecek arşiv/redo log dosyasını ekle:\nEXECUTE DBMS_LOGMNR.ADD_LOGFILE(\n  LOGFILENAME => '/u01/arch/1_1234_1122334455.arc',\n  OPTIONS => DBMS_LOGMNR.NEW);\n-- 2) Oturumu başlat:\nEXECUTE DBMS_LOGMNR.START_LOGMNR(\n  OPTIONS => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG);\nSELECT sql_redo, sql_undo FROM V$LOGMNR_CONTENTS\nWHERE seg_name = 'SIPARIS';\n-- 3) Bitirince: EXECUTE DBMS_LOGMNR.END_LOGMNR;\n-- Kurumsal CDC/çoğaltma için Oracle GoldenGate kullanılır.","note":"Oracle değişiklik takibini redo log tabanlı yapar. LogMiner redo/arşiv log'larını SQL'e çevirerek geçmiş DML'i inceler; incelenecek log dosyaları DBMS_LOGMNR.ADD_LOGFILE ile eklenir. Anlamlı sonuç için en az minimal supplemental logging açık olmalıdır (ALTER DATABASE ADD SUPPLEMENTAL LOG DATA). Sürekli, düşük gecikmeli CDC ve heterojen çoğaltma için Oracle GoldenGate (ayrı ürün) standarttır; eski Streams/Change Data Capture özellikleri kullanımdan kalkmıştır.","danger":"caution"},"postgres":{"command":"-- Mantıksal çoğaltma (logical decoding) yuvası oluştur:\nSELECT * FROM pg_create_logical_replication_slot(\n  'cdc_slot', 'wal2json');\n-- Değişiklikleri JSON olarak tüket:\nSELECT data FROM pg_logical_slot_get_changes('cdc_slot', NULL, NULL);","note":"PostgreSQL logical decoding, WAL kayıtlarını bir çıktı eklentisi (wal2json, pgoutput, test_decoding) aracılığıyla okunabilir değişiklik akışına çevirir; replication slot değişikliklerin kaybolmamasını sağlar. wal_level=logical olmalıdır. Debezium bu mekanizmayı kullanarak kurumsal CDC sunar.","danger":"caution"},"mysql":{"command":"-- Satır tabanlı binlog CDC kaynağıdır (binlog_format=ROW):\nSHOW BINARY LOGS;\nSHOW BINLOG EVENTS IN 'binlog.000042';\n-- Genellikle Debezium/Maxwell binlog'u okuyup akışa çevirir.","note":"MySQL'de CDC kaynağı binary log'dur. binlog_format=ROW ile her satır değişikliği kaydedilir. Debezium veya Maxwell gibi araçlar binlog'u replika gibi okuyup Kafka'ya olay akışı üretir. GTID etkinleştirmek konumu güvenilir izlemeyi kolaylaştırır.","danger":"caution"},"mssql":{"command":"-- Change Data Capture'ı veritabanı ve tabloda etkinleştir:\nEXEC sys.sp_cdc_enable_db;\nEXEC sys.sp_cdc_enable_table\n  @source_schema = N'dbo', @source_name = N'siparis',\n  @role_name = NULL;\n-- Hafif izleme için: ALTER DATABASE ... SET CHANGE_TRACKING = ON;","note":"SQL Server iki mekanizma sunar: Change Data Capture (CDC) transaction log'dan tüm DML'i (eski/yeni değerlerle) değişiklik tablolarına yazar; SQL Server Agent gerektirir. Change Tracking ise yalnız hangi satırın değiştiğini (net değişiklik) hafifçe izler, tam veri geçmişi tutmaz.","since":"SQL Server 2008","xnote":"CDC ve Change Tracking SQL Server 2008 ile geldi.","danger":"caution"},"mongodb":{"command":"// Change Streams ile değişiklikleri gerçek zamanlı izle:\nconst akis = db.siparis.watch([\n  { $match: { operationType: { $in: [\"insert\", \"update\"] } } }\n]);\nwhile (akis.hasNext()) { printjson(akis.next()); }","note":"MongoDB Change Streams, oplog üzerine kurulu olarak koleksiyon/veritabanı/küme düzeyinde ekleme, güncelleme, silme olaylarını gerçek zamanlı akış olarak sunar. Replica set veya sharded küme gerektirir. resumeToken ile kesintiden sonra kaldığı yerden devam edilebilir; CDC entegrasyonlarının temelidir.","since":"MongoDB 3.6","xnote":"Change Streams MongoDB 3.6 ile geldi.","danger":"safe"},"redis":{"command":"# Keyspace notifications ile anahtar değişikliklerini dinle:\nCONFIG SET notify-keyspace-events KEA\n# Değişen anahtarları Pub/Sub ile abone ol:\nPSUBSCRIBE __keyevent@0__:set\nPSUBSCRIBE __keyevent@0__:expired","note":"Redis keyspace notifications, anahtarlar üzerindeki olayları (SET, DEL, EXPIRE vb.) Pub/Sub kanalları üzerinden yayınlar; notify-keyspace-events ayarıyla açılır (K=keyspace, E=keyevent, A=tüm olaylar). Güvenilir, kalıcı bir değişiklik akışı için ise Redis Streams (XADD/XREAD) tercih edilir.","danger":"safe"},"elasticsearch":{"command":"-- Uygulanamaz: yerleşik CDC/değişiklik akışı yoktur.\n# En yakın karşılık: zaman damgası alanına göre artımlı sorgu:\nGET siparis/_search\n{ \"query\": { \"range\": { \"guncelleme_ts\": { \"gt\": \"2026-07-05T00:00:00\" } } },\n  \"sort\": [ { \"guncelleme_ts\": \"asc\" } ] }","note":"Elasticsearch değişiklik veri yakalama (CDC) akışı sunmaz; bir belgenin ne zaman değiştiğini yerel olarak yayınlamaz. Yaygın yaklaşım her belgeye guncelleme_ts alanı koyup zaman damgasına göre artımlı sorgu (range + sort) yapmaktır. Genellikle kaynak veritabanının CDC'si Elasticsearch'e beslenir.","danger":"safe"}}}]},"rosetta/sql-syntax.json":{"category":"SQL Sözdizimi & Anahtar Kelimeler","categoryId":"sql-syntax","order":19,"concepts":[{"id":"with-cte","title":"WITH (Common Table Expression / CTE)","aliases":["with","cte","common table expression","gecici sorgu","gecici tablo"],"engines":{"oracle":{"command":"WITH bolge AS (\n  SELECT il, COUNT(*) AS n\n  FROM musteri\n  GROUP BY il\n)\nSELECT il, n FROM bolge WHERE n > 10;","note":"WITH bir sorgunun içinde adlandırılmış geçici sonuç kümesi (CTE) tanımlar; alt sorguyu tekrar tekrar yazmak yerine bir kez tanımlayıp isimle kullanmanızı sağlar. Karmaşık sorguları okunur parçalara böler. Oracle 9i'den beri desteklenir.","since":"Oracle 9i","danger":"safe"},"postgres":{"command":"WITH bolge AS (\n  SELECT il, COUNT(*) AS n\n  FROM musteri\n  GROUP BY il\n)\nSELECT il, n FROM bolge WHERE n > 10;","note":"CTE karmaşık sorguları adlandırılmış bloklara ayırır. PostgreSQL 12 öncesinde CTE bir optimizasyon sınırıydı (materyalize edilirdi); 12+ sürümde satır içine alınabilir, istenirse WITH ... AS MATERIALIZED ile eski davranış zorlanabilir.","danger":"safe"},"mysql":{"command":"WITH bolge AS (\n  SELECT il, COUNT(*) AS n\n  FROM musteri\n  GROUP BY il\n)\nSELECT il, n FROM bolge WHERE n > 10;","note":"CTE sorgu içinde geçici adlandırılmış sonuç kümesi tanımlar ve okunabilirliği artırır. MySQL 8.0 (ve MariaDB 10.2) ile desteklenir; daha eski sürümlerde türetilmiş tablo (FROM içinde alt sorgu) kullanmak gerekir.","since":"MySQL 8.0","xnote":"MySQL 8.0 öncesi CTE yoktu; türetilmiş tablo (FROM içi alt sorgu) ile aynı iş yapılırdı.","danger":"safe"},"mssql":{"command":"WITH bolge AS (\n  SELECT il, COUNT(*) AS n\n  FROM musteri\n  GROUP BY il\n)\nSELECT il, n FROM bolge WHERE n > 10;","note":"CTE adlandırılmış geçici sonuç kümesidir. SQL Server'da CTE'den hemen önceki ifade noktalı virgülle bitmelidir; bu yüzden WITH çoğu zaman ';WITH' biçiminde yazılır. Tek bir deyim (SELECT/INSERT/UPDATE/DELETE) süresince geçerlidir.","danger":"safe"},"mongodb":{"command":"// En yakın karşılık: aggregation pipeline aşamaları\ndb.musteri.aggregate([\n  { $group: { _id: \"$il\", n: { $sum: 1 } } },\n  { $match: { n: { $gt: 10 } } }\n])","note":"MongoDB'de SQL/CTE yoktur; aynı işi aggregation pipeline aşamaları yapar. Her aşama bir önceki aşamanın çıktısını girdi alır, böylece CTE zincirlerine benzer adım adım işleme sağlanır. Ara sonuçlar için $facet veya $lookup da kullanılabilir.","danger":"safe"},"redis":{"command":"# Uygulanamaz: Redis'te SQL ve CTE kavramı yoktur.","note":"Redis bir anahtar-değer veri deposudur, sorgu dili yoktur. Geçici hesaplama sonuçlarını istemci tarafında birleştirir veya sunucu tarafı mantık için Lua script (EVAL) kullanırsınız.","danger":"safe"},"elasticsearch":{"command":"# Elasticsearch SQL kullanımında CTE desteklenmez.\nPOST _sql\n{ \"query\": \"SELECT il, COUNT(*) n FROM musteri GROUP BY il HAVING COUNT(*) > 10\" }","note":"Elasticsearch SQL (_sql API) WITH/CTE söz dizimini desteklemez; gruplama ve süzme tek SELECT ile yazılır. Yerel yaklaşımda ise aynı iş 'terms' agregasyonu ve 'bucket_selector' pipeline agregasyonu ile yapılır.","danger":"safe"}}},{"id":"recursive-cte","title":"Özyinelemeli CTE (WITH RECURSIVE)","aliases":["recursive","ozyineleme","with recursive","connect by","hiyerarsi","agac sorgu"],"engines":{"oracle":{"command":"-- CONNECT BY ile hiyerarşi:\nSELECT id, ad, yonetici_id, LEVEL\nFROM calisan\nSTART WITH yonetici_id IS NULL\nCONNECT BY PRIOR id = yonetici_id;\n\n-- Alternatif (11gR2+): standart özyinelemeli WITH (RECURSIVE anahtar kelimesi yazılmaz)\nWITH agac (id, ad, yonetici_id) AS (\n  SELECT id, ad, yonetici_id FROM calisan WHERE yonetici_id IS NULL\n  UNION ALL\n  SELECT c.id, c.ad, c.yonetici_id\n  FROM calisan c JOIN agac a ON c.yonetici_id = a.id\n)\nSELECT * FROM agac;","note":"Hiyerarşik (ağaç) veriyi gezmek için kullanılır: organizasyon şeması, ürün ağacı gibi. Oracle'ın klasik yolu CONNECT BY / PRIOR ve LEVEL sözde sütunudur; START WITH kök satırı belirler. 11gR2 sonrası standart özyinelemeli CTE de desteklenir.","since":"Oracle 11gR2","xnote":"CONNECT BY klasik yöntemdir; standart özyinelemeli WITH (RECURSIVE anahtar kelimesi olmadan) Oracle 11gR2 ile geldi.","danger":"safe"},"postgres":{"command":"WITH RECURSIVE agac (id, ad, yonetici_id, seviye) AS (\n  SELECT id, ad, yonetici_id, 1\n  FROM calisan WHERE yonetici_id IS NULL\n  UNION ALL\n  SELECT c.id, c.ad, c.yonetici_id, a.seviye + 1\n  FROM calisan c JOIN agac a ON c.yonetici_id = a.id\n)\nSELECT * FROM agac ORDER BY seviye;","note":"WITH RECURSIVE bir başlangıç (anchor) sorgusu ile bir özyineli parçayı UNION ALL ile birleştirir; özyineli parça sonuç boşalana kadar tekrar çalışır. Hiyerarşi ve grafik yürüyüşü için idealdir. Sonsuz döngüye karşı UNION (ALL yerine) veya döngü koruması kullanın.","since":"PostgreSQL 8.4","danger":"safe"},"mysql":{"command":"WITH RECURSIVE agac (id, ad, yonetici_id, seviye) AS (\n  SELECT id, ad, yonetici_id, 1\n  FROM calisan WHERE yonetici_id IS NULL\n  UNION ALL\n  SELECT c.id, c.ad, c.yonetici_id, a.seviye + 1\n  FROM calisan c JOIN agac a ON c.yonetici_id = a.id\n)\nSELECT * FROM agac ORDER BY seviye;","note":"MySQL 8.0 (ve MariaDB 10.2+) WITH RECURSIVE söz dizimini standarda uygun destekler. Özyineleme derinliği cte_max_recursion_depth sistem değişkeniyle sınırlanır (varsayılan 1000). Eski sürümlerde stored procedure ile döngü yazmak gerekirdi.","since":"MySQL 8.0","xnote":"MySQL 8.0 (MariaDB 10.2) öncesi özyinelemeli sorgu yoktu; stored procedure ile döngü yazılırdı.","danger":"safe"},"mssql":{"command":"WITH agac (id, ad, yonetici_id, seviye) AS (\n  SELECT id, ad, yonetici_id, 1\n  FROM calisan WHERE yonetici_id IS NULL\n  UNION ALL\n  SELECT c.id, c.ad, c.yonetici_id, a.seviye + 1\n  FROM calisan c JOIN agac a ON c.yonetici_id = a.id\n)\nSELECT * FROM agac ORDER BY seviye\nOPTION (MAXRECURSION 100);","note":"SQL Server'da özyinelemeli CTE için RECURSIVE anahtar kelimesi yazılmaz; UNION ALL içeren CTE otomatik özyineli sayılır. Varsayılan özyineleme sınırı 100'dür; OPTION (MAXRECURSION n) ile değiştirilir (0 = sınırsız, dikkatli kullanın).","since":"SQL Server 2005","danger":"safe"},"mongodb":{"command":"// En yakın karşılık: $graphLookup aşaması\ndb.calisan.aggregate([\n  { $match: { yonetici_id: null } },\n  { $graphLookup: {\n      from: \"calisan\",\n      startWith: \"$id\",\n      connectFromField: \"id\",\n      connectToField: \"yonetici_id\",\n      as: \"astlar\"\n  } }\n])","note":"MongoDB'de özyinelemeli CTE yoktur; hiyerarşik gezinme için $graphLookup aggregation aşaması kullanılır. connectFromField/connectToField bağlantı alanlarını, maxDepth ise derinlik sınırını belirler. Ağaç ve grafik ilişkilerini tek sorguda çözer.","danger":"safe"},"redis":{"command":"# Uygulanamaz: Redis'te özyinelemeli sorgu yoktur.","note":"Redis sorgu dili sunmaz. Hiyerarşi/graf gezintisi uygulama kodunda ya da sunucu tarafında Lua betiğiyle yapılır; çekirdek Redis'te ağaç yürüyüşü istemci tarafında yazılır. (Eskiden kullanılan RedisGraph modülünün desteği 2023'te sona erdi.)","danger":"safe"},"elasticsearch":{"command":"# Uygulanamaz: özyinelemeli sorgu desteklenmez.\n# Yaklaşım: parent-child (join alanı) veya nested ile modelleme,\n# derin hiyerarşiler uygulama tarafında dolaşılır.","note":"Elasticsearch özyinelemeli sorgu (WITH RECURSIVE / CONNECT BY karşılığı) sunmaz. Hiyerarşik ilişkiler 'join' (parent/child) alan tipiyle veya ağaç yolunu (materialized path) bir alanda saklayarak modellenir; çok seviyeli gezinme genelde uygulamada yapılır.","danger":"safe"}}},{"id":"joins","title":"JOIN türleri (INNER/LEFT/RIGHT/FULL/CROSS)","aliases":["join","inner join","left join","right join","full join","cross join","birlestir","tablo birlestir"],"engines":{"oracle":{"command":"-- INNER: eşleşen satırlar\nSELECT m.ad, s.tutar\nFROM musteri m JOIN siparis s ON m.id = s.musteri_id;\n-- LEFT: siparişi olmayan müşteriler de gelir\nSELECT m.ad, s.tutar\nFROM musteri m LEFT JOIN siparis s ON m.id = s.musteri_id;\n-- CROSS: kartezyen çarpım\nSELECT r.ad, u.ad FROM renk r CROSS JOIN urun u;","note":"JOIN iki tabloyu belirtilen koşula göre birleştirir. INNER yalnız eşleşenleri; LEFT/RIGHT bir taraftaki tüm satırları (eşleşme yoksa NULL); FULL her iki taraftakileri; CROSS tüm kombinasyonları döndürür. Oracle standart ANSI JOIN yanında eski (+) dış birleştirme söz dizimini de destekler.","danger":"safe"},"postgres":{"command":"SELECT m.ad, s.tutar\nFROM musteri m INNER JOIN siparis s ON m.id = s.musteri_id;\n\nSELECT m.ad, s.tutar\nFROM musteri m LEFT JOIN siparis s ON m.id = s.musteri_id;\n\nSELECT m.ad, s.tutar\nFROM musteri m FULL OUTER JOIN siparis s ON m.id = s.musteri_id;","note":"PostgreSQL tüm standart JOIN türlerini (INNER, LEFT/RIGHT/FULL OUTER, CROSS) tam destekler. USING(sutun) ortak adlı sütunlarda kısa yazım, NATURAL JOIN ise aynı adlı tüm sütunlarda otomatik birleştirme sağlar (dikkatli kullanın).","danger":"safe"},"mysql":{"command":"SELECT m.ad, s.tutar\nFROM musteri m INNER JOIN siparis s ON m.id = s.musteri_id;\n\nSELECT m.ad, s.tutar\nFROM musteri m LEFT JOIN siparis s ON m.id = s.musteri_id;\n\n-- MySQL'de FULL OUTER JOIN yoktur:\nSELECT m.ad, s.tutar FROM musteri m LEFT JOIN siparis s ON m.id = s.musteri_id\nUNION\nSELECT m.ad, s.tutar FROM musteri m RIGHT JOIN siparis s ON m.id = s.musteri_id;","note":"MySQL/MariaDB INNER, LEFT, RIGHT ve CROSS JOIN'i destekler ama FULL OUTER JOIN'i doğrudan sunmaz; LEFT ve RIGHT sonuçlarını UNION ile birleştirerek taklit edilir. Virgülle yazılan eski birleştirme kartezyen çarpım üretir, ON/WHERE ile kısıtlanmalıdır.","danger":"safe"},"mssql":{"command":"SELECT m.ad, s.tutar\nFROM musteri m INNER JOIN siparis s ON m.id = s.musteri_id;\n\nSELECT m.ad, s.tutar\nFROM musteri m LEFT JOIN siparis s ON m.id = s.musteri_id;\n\nSELECT m.ad, s.tutar\nFROM musteri m FULL OUTER JOIN siparis s ON m.id = s.musteri_id;","note":"SQL Server tüm standart JOIN türlerini destekler. Eski *= / =* dış birleştirme operatörleri artık kaldırılmıştır; ANSI JOIN söz dizimi kullanılmalıdır. APPLY (CROSS/OUTER APPLY) ise satır bazlı ilişkili alt sorgular için ek bir birleştirme biçimidir.","danger":"safe"},"mongodb":{"command":"// En yakın karşılık: $lookup (sol dış birleştirme)\ndb.musteri.aggregate([\n  { $lookup: {\n      from: \"siparis\",\n      localField: \"id\",\n      foreignField: \"musteri_id\",\n      as: \"siparisler\"\n  } }\n])","note":"MongoDB'de klasik JOIN yoktur; $lookup aggregation aşaması bir koleksiyondan eşleşen belgeleri dizi olarak getirir (sol dış birleştirmeye benzer). INNER benzeri sonuç için sonrasında $match ile boş dizileri süzer, $unwind ile diziyi satırlara açarsınız.","danger":"safe"},"redis":{"command":"# Uygulanamaz: Redis'te tablo ve JOIN yoktur.","note":"Redis ilişkisel birleştirme sunmaz; veriler genelde denormalize edilir veya ilişkiler istemci tarafında birden çok anahtarı okuyarak kurulur. Sınırlı birleştirme benzeri sorgular için RediSearch (FT.AGGREGATE) kullanılabilir; RedisGraph modülünün desteği 2023'te sona erdi.","danger":"safe"},"elasticsearch":{"command":"# Uygulanamaz: dağıtık yapıda genel JOIN yoktur.\n# Sınırlı seçenekler: nested, parent/child (join alanı),\n# terms lookup. Genelde veri indeksleme sırasında denormalize edilir.","note":"Elasticsearch dağıtık mimarisi nedeniyle rastgele tablolar arası JOIN sunmaz. Sınırlı ilişki için tek index içinde 'nested' ve aynı shard'da 'join' (parent/child) alan tipleri vardır. En yaygın çözüm veriyi indeksleme aşamasında denormalize etmektir.","danger":"safe"}}},{"id":"window-functions","title":"Pencere fonksiyonları (OVER / PARTITION BY)","aliases":["window","pencere","over","partition by","row_number","rank","lag","lead","analitik fonksiyon"],"engines":{"oracle":{"command":"SELECT ad, departman, maas,\n  ROW_NUMBER() OVER (PARTITION BY departman ORDER BY maas DESC) AS sira,\n  RANK()       OVER (PARTITION BY departman ORDER BY maas DESC) AS derece,\n  LAG(maas)    OVER (PARTITION BY departman ORDER BY maas)      AS onceki\nFROM calisan;","note":"Pencere fonksiyonları satırları gruplamadan (satır sayısını azaltmadan) her satır için bir 'pencere' üzerinde hesap yapar. PARTITION BY pencereyi böler, ORDER BY sıralar. Oracle bu analitik fonksiyonların öncüsüdür; ROW_NUMBER, RANK, DENSE_RANK, LAG/LEAD, SUM() OVER gibi zengin bir set sunar.","since":"Oracle 8i","danger":"safe"},"postgres":{"command":"SELECT ad, departman, maas,\n  ROW_NUMBER() OVER w AS sira,\n  RANK()       OVER w AS derece,\n  LEAD(maas)   OVER w AS sonraki\nFROM calisan\nWINDOW w AS (PARTITION BY departman ORDER BY maas DESC);","note":"PostgreSQL tüm standart pencere fonksiyonlarını destekler ve tekrar eden pencere tanımını WINDOW ... AS ile adlandırmaya izin verir. ROWS/RANGE/GROUPS çerçeve (frame) tanımıyla hareketli toplam, kayan ortalama gibi hesaplar yapılır.","since":"PostgreSQL 8.4","danger":"safe"},"mysql":{"command":"SELECT ad, departman, maas,\n  ROW_NUMBER() OVER (PARTITION BY departman ORDER BY maas DESC) AS sira,\n  DENSE_RANK() OVER (PARTITION BY departman ORDER BY maas DESC) AS derece,\n  LAG(maas)    OVER (PARTITION BY departman ORDER BY maas)      AS onceki\nFROM calisan;","note":"MySQL 8.0 (ve MariaDB 10.2+) pencere fonksiyonlarını destekler; öncesinde kullanıcı değişkenleri veya alt sorgularla taklit edilirdi. ROW_NUMBER, RANK, DENSE_RANK, NTILE, LAG/LEAD, FIRST_VALUE/LAST_VALUE ve toplama fonksiyonlarının OVER biçimi kullanılabilir.","since":"MySQL 8.0","xnote":"MySQL 8.0 öncesi pencere fonksiyonu yoktu; değişken/self-join ile taklit edilirdi.","danger":"safe"},"mssql":{"command":"SELECT ad, departman, maas,\n  ROW_NUMBER() OVER (PARTITION BY departman ORDER BY maas DESC) AS sira,\n  RANK()       OVER (PARTITION BY departman ORDER BY maas DESC) AS derece,\n  SUM(maas)    OVER (PARTITION BY departman) AS dept_toplam\nFROM calisan;","note":"SQL Server 2005'ten beri sıralama pencere fonksiyonlarını, 2012'den beri çerçeveli toplama ve LAG/LEAD gibi fonksiyonları destekler. ROW_NUMBER genelde sayfalama (OFFSET/FETCH ile) ve grup içi ilk N kaydı bulmada kullanılır.","since":"SQL Server 2005","xnote":"Sıralama pencere fonksiyonları 2005, çerçeve ve LAG/LEAD 2012 ile geldi.","danger":"safe"},"mongodb":{"command":"// En yakın karşılık: $setWindowFields (MongoDB 5.0+)\ndb.calisan.aggregate([\n  { $setWindowFields: {\n      partitionBy: \"$departman\",\n      sortBy: { maas: -1 },\n      output: { sira: { $rank: {} },\n                onceki: { $shift: { output: \"$maas\", by: -1 } } }\n  } }\n])","note":"MongoDB 5.0+ $setWindowFields aşaması SQL pencere fonksiyonlarının karşılığıdır: partitionBy ve sortBy ile pencere tanımlanır, $rank/$denseRank/$documentNumber, $shift (LAG/LEAD), kayan toplam gibi çıktılar üretilir. Eski sürümlerde $group + kod ile çözülürdü.","danger":"safe"},"redis":{"command":"# Uygulanamaz: Redis'te pencere fonksiyonu yoktur.","note":"Redis analitik pencere fonksiyonu sunmaz. Sıralı sonuç ve derecelendirme için Sorted Set (ZSET) yapısı kullanılır: ZADD ile skor verir, ZRANK/ZREVRANK ile sıra, ZRANGE ile aralık okunur. Karmaşık analitik uygulamada yapılır.","danger":"safe"},"elasticsearch":{"command":"# En yakın karşılık: top_hits ve pipeline agregasyonları\nGET calisan/_search\n{\n  \"size\": 0,\n  \"aggs\": { \"dept\": { \"terms\": { \"field\": \"departman\" },\n    \"aggs\": { \"en_yuksek\": { \"top_hits\": {\n      \"sort\": [ { \"maas\": \"desc\" } ], \"size\": 3 } } } } }\n}","note":"Elasticsearch'te doğrudan pencere fonksiyonu yoktur. Grup içi ilk N kayıt için 'top_hits' alt agregasyonu, kayan/kümülatif hesaplar için 'derivative', 'cumulative_sum', 'moving_fn' gibi pipeline agregasyonları kullanılır. Sıralama ve bölme terms agregasyonuyla yapılır.","danger":"safe"}}},{"id":"group-rollup","title":"GROUP BY, HAVING, ROLLUP/CUBE/GROUPING SETS","aliases":["group by","having","rollup","cube","grouping sets","grupla","ara toplam","alt toplam"],"engines":{"oracle":{"command":"-- Temel gruplama + HAVING\nSELECT il, COUNT(*) AS n\nFROM musteri\nGROUP BY il\nHAVING COUNT(*) > 5;\n\n-- ROLLUP ile ara toplam ve genel toplam\nSELECT il, ilce, SUM(bakiye)\nFROM musteri\nGROUP BY ROLLUP(il, ilce);","note":"GROUP BY satırları belirtilen sütunlara göre gruplayıp toplama fonksiyonu uygular; HAVING gruplanmış sonucu süzer (WHERE gruplamadan önce satırları süzer). ROLLUP hiyerarşik ara toplam + genel toplam, CUBE tüm kombinasyonları, GROUPING SETS ise seçilen grupları üretir. Oracle üçünü de destekler.","danger":"safe"},"postgres":{"command":"SELECT il, ilce, SUM(bakiye)\nFROM musteri\nGROUP BY GROUPING SETS ((il, ilce), (il), ());\n\n-- CUBE tüm alt küme kombinasyonlarını üretir\nSELECT il, ilce, SUM(bakiye)\nFROM musteri\nGROUP BY CUBE(il, ilce);","note":"PostgreSQL 9.5+ ROLLUP, CUBE ve GROUPING SETS'i standarda uygun destekler. GROUPING() fonksiyonu bir sütunun toplam satırında (NULL) olup olmadığını ayırt etmeye yarar. HAVING toplama sonrası, WHERE toplama öncesi süzme yapar.","since":"PostgreSQL 9.5","xnote":"ROLLUP, CUBE ve GROUPING SETS PostgreSQL 9.5 ile geldi.","danger":"safe"},"mysql":{"command":"SELECT il, COUNT(*) AS n\nFROM musteri\nGROUP BY il\nHAVING n > 5;\n\n-- MySQL'de ROLLUP:\nSELECT il, ilce, SUM(bakiye)\nFROM musteri\nGROUP BY il, ilce WITH ROLLUP;","note":"MySQL/MariaDB GROUP BY ... WITH ROLLUP söz dizimiyle ara/genel toplam üretir; CUBE ve GROUPING SETS'i desteklemez. HAVING ifadesinde SELECT'teki takma adlar kullanılabilir (bu Oracle/SQL Server'da genelde geçmez). ROLLUP satırlarında gruplanan sütun NULL görünür.","danger":"safe"},"mssql":{"command":"SELECT il, COUNT(*) AS n\nFROM musteri\nGROUP BY il\nHAVING COUNT(*) > 5;\n\n-- ROLLUP / CUBE / GROUPING SETS\nSELECT il, ilce, SUM(bakiye)\nFROM musteri\nGROUP BY ROLLUP(il, ilce);","note":"SQL Server GROUP BY yanında ROLLUP(), CUBE() ve GROUPING SETS'i (2008+) modern söz dizimiyle destekler; eski WITH ROLLUP/WITH CUBE biçimi kullanımdan kalkmıştır. GROUPING() ve GROUPING_ID() toplam satırlarını ayırt etmede yardımcı olur.","since":"SQL Server 2008","xnote":"Modern GROUPING SETS söz dizimi SQL Server 2008 ile geldi.","danger":"safe"},"mongodb":{"command":"// En yakın karşılık: $group + $sum\ndb.musteri.aggregate([\n  { $group: { _id: \"$il\", n: { $sum: 1 } } },\n  { $match: { n: { $gt: 5 } } }\n])\n// ROLLUP benzeri çok seviyeli toplam için $facet kullanılır","note":"MongoDB'de $group SQL GROUP BY karşılığıdır; _id gruplama anahtarını, akümülatörler ($sum, $avg, $max) toplamları belirler. Gruplama sonrası süzme $match ile yapılır (HAVING'e karşılık). ROLLUP/CUBE gibi çok düzeyli toplamlar $facet ile birden çok pipeline çalıştırılarak elde edilir.","danger":"safe"},"redis":{"command":"# Uygulanamaz: çekirdek Redis'te GROUP BY yoktur.\n# RediSearch ile toplama:\nFT.AGGREGATE musteri_idx \"*\" GROUPBY 1 @il REDUCE COUNT 0 AS n","note":"Çekirdek Redis gruplama sunmaz; RediSearch modülünün FT.AGGREGATE komutu GROUPBY ve REDUCE (COUNT, SUM, AVG) ile SQL benzeri toplama yapar. FILTER aşaması HAVING gibi gruplanmış sonucu süzer. Modül yoksa toplama uygulamada yapılır.","danger":"safe"},"elasticsearch":{"command":"GET musteri/_search\n{\n  \"size\": 0,\n  \"aggs\": {\n    \"il_bazinda\": { \"terms\": { \"field\": \"il\" },\n      \"aggs\": { \"toplam\": { \"sum\": { \"field\": \"bakiye\" } } } }\n  }\n}","note":"Elasticsearch'te gruplama 'terms' bucket agregasyonu, toplama ise metric agregasyonlarıyla (sum, avg, cardinality) yapılır. HAVING benzeri süzme için 'bucket_selector' pipeline agregasyonu kullanılır. Çok düzeyli ara toplam iç içe agregasyonlarla kurulur.","danger":"safe"}}},{"id":"case-expr","title":"CASE ifadesi (koşullu değer)","aliases":["case","kosullu","when","then","decode","if then","sartli deger"],"engines":{"oracle":{"command":"-- Aranan (searched) CASE\nSELECT ad,\n  CASE WHEN maas >= 20000 THEN 'yuksek'\n       WHEN maas >= 10000 THEN 'orta'\n       ELSE 'dusuk' END AS kademe\nFROM calisan;\n\n-- Oracle'a özel kısa yol: DECODE (eşitlik karşılaştırması)\nSELECT ad, DECODE(durum, 'A', 'Aktif', 'P', 'Pasif', 'Bilinmiyor') FROM calisan;","note":"CASE bir ifadeyi koşullara göre farklı değerlere çevirir; hem basit (CASE sutun WHEN deger) hem aranan (CASE WHEN kosul) biçimi vardır. Oracle'a özgü DECODE benzer iş yapar ama yalnız eşitlik karşılaştırır ve NULL'ı eşit sayar; taşınabilirlik için CASE tercih edilir.","danger":"safe"},"postgres":{"command":"SELECT ad,\n  CASE WHEN maas >= 20000 THEN 'yuksek'\n       WHEN maas >= 10000 THEN 'orta'\n       ELSE 'dusuk' END AS kademe\nFROM calisan;","note":"PostgreSQL standart CASE ifadesini tam destekler ve bir değer üreten her yerde (SELECT, WHERE, ORDER BY, GROUP BY) kullanılabilir. Oracle'ın DECODE'u yoktur; onun yerine CASE veya kısa koşullar için COALESCE/NULLIF kullanılır.","danger":"safe"},"mysql":{"command":"SELECT ad,\n  CASE WHEN maas >= 20000 THEN 'yuksek'\n       WHEN maas >= 10000 THEN 'orta'\n       ELSE 'dusuk' END AS kademe\nFROM calisan;\n\n-- Kısa koşul için IF():\nSELECT ad, IF(aktif = 1, 'Evet', 'Hayir') FROM calisan;","note":"MySQL/MariaDB standart CASE ifadesini destekler; ayrıca iki dallı hızlı koşul için IF(kosul, dogru, yanlis) fonksiyonu vardır (SQL Server'ın IIF'ine benzer). CASE her ifade bağlamında kullanılabilir.","danger":"safe"},"mssql":{"command":"SELECT ad,\n  CASE WHEN maas >= 20000 THEN 'yuksek'\n       WHEN maas >= 10000 THEN 'orta'\n       ELSE 'dusuk' END AS kademe\nFROM calisan;\n\n-- Kısa yol: IIF() (2012+)\nSELECT ad, IIF(aktif = 1, 'Evet', 'Hayir') FROM calisan;","note":"SQL Server standart CASE'i destekler; 2012'den beri iki dallı koşul için IIF() ve çoklu eşleşme için CHOOSE() kısa yolları vardır. IIF aslında CASE'e çevrilir. CASE ORDER BY ve hesaplanan sütunlarda da kullanılabilir.","danger":"safe"},"mongodb":{"command":"// En yakın karşılık: $switch veya $cond\ndb.calisan.aggregate([\n  { $project: { ad: 1, kademe: {\n      $switch: { branches: [\n        { case: { $gte: [\"$maas\", 20000] }, then: \"yuksek\" },\n        { case: { $gte: [\"$maas\", 10000] }, then: \"orta\" } ],\n        default: \"dusuk\" } } } }\n])","note":"MongoDB aggregation'da CASE karşılığı $switch (çok dallı) ve $cond (üç argümanlı if-then-else) operatörleridir. $project veya $addFields içinde koşullu türetilmiş alanlar oluşturmak için kullanılır.","danger":"safe"},"redis":{"command":"# Uygulanamaz: Redis'te sorgu içi koşul ifadesi yoktur.","note":"Redis'te CASE gibi bir sorgu ifadesi yoktur. Koşullu mantık uygulama kodunda veya sunucu tarafı Lua script (EVAL) içinde yazılır. RediSearch FT.AGGREGATE içinde APPLY ile sınırlı ifade değerlendirmesi mümkündür.","danger":"safe"},"elasticsearch":{"command":"# En yakın karşılık: runtime field veya script içinde koşul\nGET calisan/_search\n{\n  \"runtime_mappings\": { \"kademe\": { \"type\": \"keyword\",\n    \"script\": \"if (doc['maas'].value >= 20000) emit('yuksek'); else if (doc['maas'].value >= 10000) emit('orta'); else emit('dusuk');\" } },\n  \"fields\": [\"kademe\"]\n}","note":"Elasticsearch'te sorgu içi CASE mantığı Painless script'iyle (runtime field, script_fields veya scripted metric) yazılır. if/else akışı Painless dilinde tanımlanır. Kategorilere ayırma için 'range' agregasyonu da CASE benzeri bucket'lar üretebilir.","danger":"safe"}}},{"id":"union-set","title":"UNION / UNION ALL / INTERSECT / EXCEPT (MINUS)","aliases":["union","union all","intersect","except","minus","kume","birlestir","kesisim","fark"],"engines":{"oracle":{"command":"-- Tekrarsız birleşim\nSELECT il FROM musteri\nUNION\nSELECT il FROM tedarikci;\n\n-- Kesişim ve fark (Oracle'da EXCEPT yerine MINUS)\nSELECT il FROM musteri INTERSECT SELECT il FROM tedarikci;\nSELECT il FROM musteri MINUS SELECT il FROM tedarikci;","note":"Küme operatörleri iki sorgunun sonuç kümelerini birleştirir. UNION tekrarları eler (yavaş), UNION ALL hepsini korur (hızlı), INTERSECT ortak satırları, fark operatörü yalnız ilk kümedeki satırları döndürür. Oracle fark için standart EXCEPT yerine MINUS kelimesini kullanır (21c'den beri EXCEPT de vardır).","danger":"safe"},"postgres":{"command":"SELECT il FROM musteri\nUNION\nSELECT il FROM tedarikci;\n\nSELECT il FROM musteri INTERSECT SELECT il FROM tedarikci;\nSELECT il FROM musteri EXCEPT SELECT il FROM tedarikci;","note":"PostgreSQL standart UNION, UNION ALL, INTERSECT ve EXCEPT'i tam destekler (fark için MINUS değil EXCEPT). Her operatörün ALL biçimi (INTERSECT ALL, EXCEPT ALL) tekrar sayısını koruyarak çalışır. Sütun sayısı ve tipleri uyumlu olmalıdır.","danger":"safe"},"mysql":{"command":"SELECT il FROM musteri\nUNION\nSELECT il FROM tedarikci;\n\n-- INTERSECT/EXCEPT MySQL 8.0.31+ ve MariaDB 10.3+ ile gelir\nSELECT il FROM musteri INTERSECT SELECT il FROM tedarikci;","note":"MySQL uzun süre yalnız UNION / UNION ALL destekledi; INTERSECT ve EXCEPT ancak MySQL 8.0.31 (MariaDB 10.3) ile eklendi. Eski sürümlerde kesişim için INNER JOIN/EXISTS, fark için LEFT JOIN ... IS NULL veya NOT EXISTS kullanılır.","since":"MySQL 8.0.31","xnote":"INTERSECT/EXCEPT MySQL 8.0.31 (MariaDB 10.3) ile geldi; öncesi JOIN/EXISTS ile çözülürdü.","danger":"safe"},"mssql":{"command":"SELECT il FROM musteri\nUNION\nSELECT il FROM tedarikci;\n\nSELECT il FROM musteri INTERSECT SELECT il FROM tedarikci;\nSELECT il FROM musteri EXCEPT SELECT il FROM tedarikci;","note":"SQL Server standart UNION, UNION ALL, INTERSECT ve EXCEPT'i (2005+) destekler; fark operatörü EXCEPT'tir (MINUS değil). INTERSECT/EXCEPT NULL değerleri eşit kabul ederek satır karşılaştırması yapar.","since":"SQL Server 2005","danger":"safe"},"mongodb":{"command":"// En yakın karşılık: $unionWith (MongoDB 4.4+)\ndb.musteri.aggregate([\n  { $project: { il: 1, _id: 0 } },\n  { $unionWith: { coll: \"tedarikci\",\n      pipeline: [ { $project: { il: 1, _id: 0 } } ] } },\n  { $group: { _id: \"$il\" } }  // UNION (tekrarsız) etkisi\n])","note":"MongoDB 4.4+ $unionWith aşaması iki koleksiyonun sonuçlarını birleştirir (UNION ALL benzeri). Tekrarları elemek için sonrasında $group ile teklenir. INTERSECT/EXCEPT'in doğrudan karşılığı yoktur; $lookup veya küme operatörleriyle ($setIntersection, $setDifference) modellenir.","danger":"safe"},"redis":{"command":"# Set veri tipiyle küme işlemleri:\nSUNION il_musteri il_tedarikci    # birleşim\nSINTER il_musteri il_tedarikci    # kesişim\nSDIFF  il_musteri il_tedarikci    # fark","note":"Redis'te SQL yoktur ama Set (küme) veri tipi doğal küme işlemleri sunar: SUNION (birleşim), SINTER (kesişim), SDIFF (fark) ve bunların sonucu saklayan STORE biçimleri. Bu, sorgu sonuçlarını değil önceden kümelenmiş üyeleri işler.","danger":"safe"},"elasticsearch":{"command":"# Doğrudan küme operatörü yoktur.\n# Birleşim için tek sorguda çoklu indeks aranır:\nGET musteri,tedarikci/_search\n{ \"query\": { \"match_all\": {} } }","note":"Elasticsearch UNION/INTERSECT/EXCEPT sunmaz. Birleşim etkisi birden çok index'i virgülle sorgulayarak elde edilir; kesişim ve fark için bool sorgusunun must/should/must_not koşulları veya uygulama tarafı küme mantığı kullanılır.","danger":"safe"}}},{"id":"exists-in","title":"EXISTS / IN / NOT EXISTS (alt sorgu)","aliases":["exists","in","not exists","not in","alt sorgu","subquery","iliskili alt sorgu"],"engines":{"oracle":{"command":"-- Siparişi olan müşteriler (EXISTS)\nSELECT ad FROM musteri m\nWHERE EXISTS (SELECT 1 FROM siparis s WHERE s.musteri_id = m.id);\n\n-- IN ile liste üyeliği\nSELECT ad FROM musteri\nWHERE il IN ('Ankara', 'Izmir');\n\n-- Hiç siparişi olmayanlar (NOT EXISTS)\nSELECT ad FROM musteri m\nWHERE NOT EXISTS (SELECT 1 FROM siparis s WHERE s.musteri_id = m.id);","note":"EXISTS ilişkili alt sorgunun en az bir satır döndürüp döndürmediğini kontrol eder (ilk eşleşmede durur, hızlıdır). IN bir değerin listede/alt sorgu sonucunda olup olmadığına bakar. Dikkat: alt sorgu NULL üretebiliyorsa NOT IN beklenmedik sonuç verir; NOT EXISTS daha güvenlidir. Oracle optimizer ikisini çoğu zaman aynı plana çevirir.","danger":"safe"},"postgres":{"command":"SELECT ad FROM musteri m\nWHERE EXISTS (SELECT 1 FROM siparis s WHERE s.musteri_id = m.id);\n\nSELECT ad FROM musteri\nWHERE il IN (SELECT il FROM hedef_iller);\n\nSELECT ad FROM musteri m\nWHERE NOT EXISTS (SELECT 1 FROM siparis s WHERE s.musteri_id = m.id);","note":"PostgreSQL EXISTS/IN/NOT EXISTS'i tam destekler. NOT IN ile alt sorgu NULL içeriyorsa tüm sonuç boşalabileceği için NOT EXISTS ya da LEFT JOIN ... IS NULL önerilir. Planlayıcı IN ve EXISTS'i çoğu durumda semi-join olarak eşdeğer işler.","danger":"safe"},"mysql":{"command":"SELECT ad FROM musteri m\nWHERE EXISTS (SELECT 1 FROM siparis s WHERE s.musteri_id = m.id);\n\nSELECT ad FROM musteri\nWHERE il IN ('Ankara', 'Izmir');\n\nSELECT ad FROM musteri m\nWHERE NOT EXISTS (SELECT 1 FROM siparis s WHERE s.musteri_id = m.id);","note":"MySQL/MariaDB EXISTS/IN/NOT EXISTS'i destekler. MySQL 5.6 öncesinde ilişkili alt sorgular yavaş çalışabiliyordu; 5.6+ semi-join ve materyalizasyon optimizasyonlarıyla IN alt sorgularını hızlandırdı. NOT IN + NULL tuzağı burada da geçerlidir.","danger":"safe"},"mssql":{"command":"SELECT ad FROM musteri m\nWHERE EXISTS (SELECT 1 FROM siparis s WHERE s.musteri_id = m.id);\n\nSELECT ad FROM musteri\nWHERE il IN (SELECT il FROM hedef_iller);\n\nSELECT ad FROM musteri m\nWHERE NOT EXISTS (SELECT 1 FROM siparis s WHERE s.musteri_id = m.id);","note":"SQL Server EXISTS/IN/NOT EXISTS'i destekler ve iyileştirici bunları çoğunlukla semi/anti-join olarak işler. NOT IN alt sorgusunda NULL varsa sonuç beklenmedik biçimde boşalabilir; NOT EXISTS güvenli tercihtir. INTERSECT/EXCEPT de benzer üyelik mantığı için kullanılabilir.","danger":"safe"},"mongodb":{"command":"// IN karşılığı: $in operatörü\ndb.musteri.find({ il: { $in: [\"Ankara\", \"Izmir\"] } })\n\n// EXISTS karşılığı: $lookup + $match ile eşleşme kontrolü\ndb.musteri.aggregate([\n  { $lookup: { from: \"siparis\", localField: \"id\",\n      foreignField: \"musteri_id\", as: \"s\" } },\n  { $match: { \"s.0\": { $exists: true } } }  // en az bir sipariş\n])","note":"MongoDB'de değer listesi üyeliği $in / $nin operatörleriyle yapılır. Alt sorgu EXISTS'in karşılığı $lookup ile eşleşen belge dizisini getirip dizinin boş olup olmadığını süzmektir. Alan varlığı kontrolü ise ayrı bir { alan: { $exists: true } } operatörüdür (satır ilişkisi değil, alanın mevcudiyeti).","danger":"safe"},"redis":{"command":"# Üyelik kontrolü Set/Hash ile:\nSISMEMBER hedef_iller \"Ankara\"   # kümede var mı? (IN benzeri)\nEXISTS musteri:1                 # anahtar mevcut mu?","note":"Redis'te alt sorgu yoktur. Değer üyeliği için Set üzerinde SISMEMBER (IN benzeri) kullanılır. EXISTS komutu ise bir alt sorgu değil, belirtilen anahtarın var olup olmadığını döndürür. İlişkisel varlık kontrolleri uygulama tarafında birden çok anahtar okunarak yapılır.","danger":"safe"},"elasticsearch":{"command":"# IN karşılığı: terms sorgusu\nGET musteri/_search\n{ \"query\": { \"terms\": { \"il\": [\"Ankara\", \"Izmir\"] } } }\n\n# Alanın varlığı: exists sorgusu\nGET musteri/_search\n{ \"query\": { \"exists\": { \"field\": \"telefon\" } } }","note":"Elasticsearch'te IN karşılığı 'terms' sorgusu (birden çok değerden biriyle eşleşme), NOT IN ise bool must_not içinde terms'tir. 'exists' sorgusu SQL EXISTS'e değil, bir alanın belgede değeri olup olmadığına bakar. Tablolar arası ilişkili EXISTS için genelde denormalizasyon gerekir.","danger":"safe"}}},{"id":"limit-paging","title":"Satır sınırlama / sayfalama (LIMIT/OFFSET, FETCH, ROWNUM, TOP)","aliases":["limit","offset","fetch","rownum","top","sayfalama","paging","pagination","satir sinirla"],"engines":{"oracle":{"command":"-- 12c+ standart: OFFSET/FETCH\nSELECT ad, maas FROM calisan\nORDER BY maas DESC\nOFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;\n\n-- Eski sürümler: ROWNUM ile\nSELECT * FROM (\n  SELECT ad, maas FROM calisan ORDER BY maas DESC\n) WHERE ROWNUM <= 10;","note":"Sonuç kümesini sınırlamak/sayfalamak için kullanılır. Oracle 12c'den beri standart OFFSET n ROWS FETCH NEXT m ROWS ONLY desteklenir. Öncesinde ROWNUM sözde sütunu kullanılırdı; ROWNUM sıralamadan önce atandığı için ORDER BY'lı alt sorgu sarmalamak zorunludur.","since":"Oracle 12c","xnote":"Oracle 12c öncesi satır sınırlama ROWNUM ile yapılırdı.","danger":"safe"},"postgres":{"command":"-- LIMIT/OFFSET\nSELECT ad, maas FROM calisan\nORDER BY maas DESC\nLIMIT 10 OFFSET 20;\n\n-- Standart eşdeğeri: FETCH\nSELECT ad, maas FROM calisan\nORDER BY maas DESC\nOFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;","note":"PostgreSQL hem LIMIT n OFFSET m hem de standart OFFSET ... FETCH biçimini destekler. Büyük OFFSET değerleri yavaştır; derin sayfalamada anahtar tabanlı (keyset / 'WHERE id > son_id') sayfalama daha verimlidir. Sıralamasız LIMIT sonuç sırasını garanti etmez.","danger":"safe"},"mysql":{"command":"-- LIMIT [offset,] adet\nSELECT ad, maas FROM calisan\nORDER BY maas DESC\nLIMIT 10 OFFSET 20;\n\n-- Kısa biçim: LIMIT offset, adet\nSELECT ad, maas FROM calisan ORDER BY maas DESC LIMIT 20, 10;","note":"MySQL/MariaDB LIMIT anahtar kelimesini kullanır; iki biçimi vardır: LIMIT adet OFFSET baslangic ya da LIMIT baslangic, adet. MySQL 8.0.19+ standart FETCH söz dizimini de kabul eder. Derin OFFSET performansı için keyset sayfalama önerilir.","danger":"safe"},"mssql":{"command":"-- TOP ile ilk N\nSELECT TOP 10 ad, maas FROM calisan ORDER BY maas DESC;\n\n-- Sayfalama için OFFSET/FETCH (2012+), ORDER BY zorunlu\nSELECT ad, maas FROM calisan\nORDER BY maas DESC\nOFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;","note":"SQL Server ilk N satır için TOP n (TOP (n) PERCENT / WITH TIES varyantlarıyla), sayfalama için 2012'den beri OFFSET ... FETCH kullanır. OFFSET/FETCH'in çalışması için ORDER BY zorunludur. LIMIT anahtar kelimesi SQL Server'da yoktur.","since":"SQL Server 2012","xnote":"OFFSET/FETCH sayfalama 2012 ile geldi; öncesi TOP veya ROW_NUMBER ile yapılırdı.","danger":"safe"},"mongodb":{"command":"// skip/limit ile sayfalama\ndb.calisan.find()\n  .sort({ maas: -1 })\n  .skip(20)\n  .limit(10)","note":"MongoDB'de limit() döndürülecek belge sayısını, skip() atlanacak belge sayısını belirler; sort() ile birlikte sayfalama yapılır. Büyük skip değerleri maliyetlidir; derin sayfalama için son görülen değere göre aralık sorgusu (range/keyset) tercih edilir.","danger":"safe"},"redis":{"command":"# Sıralı küme (ZSET) üzerinde aralık okuma:\nZREVRANGE maas_sirali 20 29    # 21-30. sıradaki üyeler\n# Liste üzerinde aralık:\nLRANGE kuyruk 0 9              # ilk 10 eleman","note":"Redis'te SQL LIMIT yoktur ama aralık okuma komutları vardır: Sorted Set için ZRANGE/ZREVRANGE start stop (indeks bazlı) veya ZRANGEBYSCORE ... LIMIT offset count; List için LRANGE. Bu komutlar sayfalama benzeri erişim sağlar.","danger":"safe"},"elasticsearch":{"command":"GET calisan/_search\n{\n  \"from\": 20,\n  \"size\": 10,\n  \"sort\": [ { \"maas\": \"desc\" } ]\n}","note":"Elasticsearch'te 'size' döndürülecek isabet sayısını, 'from' atlanacak sayıyı belirler (LIMIT/OFFSET karşılığı). from+size en fazla index.max_result_window (varsayılan 10.000) kadar olabilir; derin sayfalama için 'search_after' (keyset) veya PIT (point-in-time) kullanılır.","danger":"safe"}}},{"id":"merge-upsert","title":"MERGE / UPSERT (varsa güncelle yoksa ekle)","aliases":["merge","upsert","on conflict","on duplicate key","insert or update","varsa guncelle"],"engines":{"oracle":{"command":"MERGE INTO musteri m\nUSING (SELECT 1 AS id, 'Ali' AS ad, 500 AS bakiye FROM dual) k\nON (m.id = k.id)\nWHEN MATCHED THEN\n  UPDATE SET m.ad = k.ad, m.bakiye = k.bakiye\nWHEN NOT MATCHED THEN\n  INSERT (id, ad, bakiye) VALUES (k.id, k.ad, k.bakiye);","note":"MERGE (upsert) bir kaynak ile hedefi eşleştirip eşleşen satırları günceller, eşleşmeyenleri ekler; toplu veri senkronizasyonu için idealdir. Oracle MERGE'i güçlü destekler: WHEN MATCHED ... DELETE ve koşullu güncelleme de yazılabilir. Tek satırlık kaynak için dual tablosu kullanılır.","since":"Oracle 9i","danger":"caution"},"postgres":{"command":"-- PostgreSQL yolu: INSERT ... ON CONFLICT\nINSERT INTO musteri (id, ad, bakiye)\nVALUES (1, 'Ali', 500)\nON CONFLICT (id) DO UPDATE\n  SET ad = EXCLUDED.ad, bakiye = EXCLUDED.bakiye;","note":"PostgreSQL'in klasik upsert yolu INSERT ... ON CONFLICT (benzersiz sütun) DO UPDATE / DO NOTHING'dir; çakışan satırın yeni değerlerine EXCLUDED takma adıyla erişilir. PostgreSQL 15'ten beri standart MERGE deyimi de desteklenir. ON CONFLICT tek tabloda atomik ve yaygındır.","since":"PostgreSQL 15","xnote":"Standart MERGE deyimi PostgreSQL 15 ile geldi; öncesi upsert INSERT ... ON CONFLICT (9.5) ile yapılırdı.","danger":"caution"},"mysql":{"command":"INSERT INTO musteri (id, ad, bakiye)\nVALUES (1, 'Ali', 500)\nON DUPLICATE KEY UPDATE\n  ad = VALUES(ad), bakiye = VALUES(bakiye);","note":"MySQL/MariaDB upsert için INSERT ... ON DUPLICATE KEY UPDATE kullanır; unique key veya primary key çakışırsa satır güncellenir. Yeni değerlere VALUES(sutun) (8.0.19+ 'new.sutun' takma adı) ile erişilir. INSERT IGNORE ise çakışmada satırı sessizce atlar. MySQL'de standart MERGE yoktur.","danger":"caution"},"mssql":{"command":"MERGE INTO musteri AS m\nUSING (VALUES (1, 'Ali', 500)) AS k(id, ad, bakiye)\nON m.id = k.id\nWHEN MATCHED THEN\n  UPDATE SET m.ad = k.ad, m.bakiye = k.bakiye\nWHEN NOT MATCHED THEN\n  INSERT (id, ad, bakiye) VALUES (k.id, k.ad, k.bakiye);","note":"SQL Server 2008'den beri MERGE deyimini destekler; WHEN NOT MATCHED BY SOURCE ile hedefte fazlalık satırları silme gibi ek dallar sunar. MERGE deyiminin sonu noktalı virgülle bitmelidir. Not: bazı köşe durum hataları nedeniyle basit upsert'lerde INSERT/UPDATE ayrı yazımı da tercih edilebilir.","since":"SQL Server 2008","danger":"caution"},"mongodb":{"command":"// upsert:true ile bul-güncelle veya ekle\ndb.musteri.updateOne(\n  { id: 1 },\n  { $set: { ad: \"Ali\", bakiye: 500 } },\n  { upsert: true }\n)","note":"MongoDB'de upsert doğal bir seçenektir: updateOne/updateMany/findOneAndUpdate çağrısına { upsert: true } eklenirse eşleşen belge güncellenir, yoksa yeni belge oluşturulur. Toplu senkronizasyon için aggregation $merge aşaması (hedef koleksiyona yaz/güncelle) SQL MERGE'e daha yakındır.","danger":"caution"},"redis":{"command":"# SET doğal upsert'tir: anahtar varsa üzerine yazar, yoksa oluşturur.\nSET musteri:1 '{\"ad\":\"Ali\",\"bakiye\":500}'\n# Hash alanı güncelle/ekle:\nHSET musteri:1 ad Ali bakiye 500","note":"Redis'te yazma komutları doğası gereği upsert'tir: SET/HSET anahtar veya alan varsa günceller, yoksa oluşturur. Yalnızca yokken yazmak için SET ... NX, yalnızca varken için XX seçeneği kullanılır. 'varsa güncelle yoksa ekle' ayrımı çoğu komutta zaten varsayılan davranıştır.","danger":"safe"},"elasticsearch":{"command":"# Belge id'siyle index çağrısı upsert gibidir (varsa değiştirir):\nPUT musteri/_doc/1\n{ \"ad\": \"Ali\", \"bakiye\": 500 }\n# Kısmi güncelleme + yoksa ekleme:\nPOST musteri/_update/1\n{ \"doc\": { \"bakiye\": 500 }, \"doc_as_upsert\": true }","note":"Elasticsearch'te aynı _id ile index (PUT) çağrısı belge varsa tümüyle değiştirir, yoksa oluşturur (upsert benzeri). Kısmi güncelleme ve belge yoksa ekleme için _update API'sinde 'doc_as_upsert': true veya 'upsert' bloğu kullanılır. Script'li upsert de mümkündür.","danger":"caution"}}},{"id":"returning-output","title":"Değiştirilen satırı döndür (RETURNING / OUTPUT)","aliases":["returning","output","inserted","deleted","donen deger","degistirilen satir"],"engines":{"oracle":{"command":"-- Tek satır: RETURNING ... INTO (PL/SQL bind variable)\nUPDATE calisan SET maas = maas * 1.1\nWHERE id = 5\nRETURNING maas INTO :yeni_maas;\n\n-- INSERT ile üretilen anahtarı geri al\nINSERT INTO calisan (ad) VALUES ('Ayse')\nRETURNING id INTO :yeni_id;","note":"RETURNING, INSERT/UPDATE/DELETE ile değiştirilen satırların değerlerini (ör. otomatik üretilen kimlik) ayrı bir SELECT'e gerek kalmadan geri döndürür. Oracle'da tek satır için RETURNING ... INTO bind variable'a, çok satır için RETURNING ... BULK COLLECT INTO koleksiyona yazılır.","danger":"safe"},"postgres":{"command":"INSERT INTO calisan (ad, maas)\nVALUES ('Ayse', 15000)\nRETURNING id, ad;\n\nUPDATE calisan SET maas = maas * 1.1\nWHERE departman = 'BT'\nRETURNING id, maas;","note":"PostgreSQL'in RETURNING yan tümcesi çok esnektir: INSERT, UPDATE, DELETE ve MERGE deyimlerinden etkilenen satırların herhangi bir sütununu (hesaplanmış ifadeler dahil) doğrudan sonuç kümesi olarak döndürür. Üretilen seri/kimlik değerlerini almanın en temiz yoludur.","since":"PostgreSQL 8.2","danger":"safe"},"mysql":{"command":"-- MySQL'de RETURNING yoktur; üretilen anahtar ayrı alınır:\nINSERT INTO calisan (ad, maas) VALUES ('Ayse', 15000);\nSELECT LAST_INSERT_ID();\n\n-- MariaDB 10.5+ INSERT ... RETURNING destekler:\nINSERT INTO calisan (ad) VALUES ('Ayse') RETURNING id;","note":"MySQL standart RETURNING'i desteklemez; INSERT sonrası üretilen otomatik artan anahtar LAST_INSERT_ID() ile alınır, güncellenen değerler ayrı SELECT ile okunur. MariaDB ise 10.5'ten beri INSERT ... RETURNING, 10.0'dan beri DELETE ... RETURNING sunar.","danger":"safe"},"mssql":{"command":"INSERT INTO calisan (ad, maas)\nOUTPUT INSERTED.id, INSERTED.ad\nVALUES ('Ayse', 15000);\n\nUPDATE calisan SET maas = maas * 1.1\nOUTPUT DELETED.maas AS eski, INSERTED.maas AS yeni\nWHERE id = 5;","note":"SQL Server'ın karşılığı OUTPUT yan tümcesidir: INSERTED (yeni değerler) ve DELETED (eski değerler) sözde tablolarına erişir; UPDATE'te ikisi de kullanılabilir. OUTPUT ... INTO ile sonuçlar bir tabloya/tablo değişkenine yazdırılabilir. Değişiklikleri denetim (audit) tablosuna aktarmak için idealdir.","since":"SQL Server 2005","xnote":"OUTPUT yan tümcesi SQL Server 2005 ile geldi.","danger":"safe"},"mongodb":{"command":"// findOneAndUpdate değiştirilen belgeyi döndürür\ndb.calisan.findOneAndUpdate(\n  { id: 5 },\n  { $mul: { maas: 1.1 } },\n  { returnDocument: \"after\" }   // güncel hali döndür\n)","note":"MongoDB'de findOneAndUpdate / findOneAndDelete / findOneAndReplace komutları etkilenen belgeyi tek atomik işlemde geri döndürür. returnDocument: 'before' değişiklikten önceki, 'after' sonraki hali verir. insertOne çağrısı ise eklenen belgenin _id değerini döndürür.","danger":"safe"},"redis":{"command":"# Bazı komutlar eski/yeni değeri doğrudan döndürür:\nSET sayac 0 GET       # (6.2+) eski değeri döndürüp yeni değeri yazar (GETSET'in yerine)\nINCR ziyaret          # artırıp yeni değeri döndürür","note":"Redis'te ayrı bir RETURNING yoktur ama birçok yazma komutu sonucu doğrudan döndürür: INCR/INCRBY yeni değeri, SET ... GET eski değeri (GETSET 6.2'den beri deprecated), LPOP/RPOP çıkarılan elemanı verir. Atomik oku-yaz için bu davranış RETURNING'in yerini tutar.","danger":"safe"},"elasticsearch":{"command":"# _update yanıtı sonucu döndürebilir:\nPOST calisan/_update/5\n{\n  \"script\": { \"source\": \"ctx._source.maas *= 1.1\" },\n  \"_source\": true\n}\n# Yanıtta get._source ile güncel belge döner","note":"Elasticsearch'te index/update işlemleri sonuç meta bilgisini (_id, _version, result) döndürür. Güncellenmiş belgenin gövdesini almak için _update isteğine '_source': true eklenir; yanıttaki get alanında güncel _source yer alır. Ayrı bir GET çağrısına gerek kalmaz.","danger":"safe"}}},{"id":"lateral-apply","title":"LATERAL / CROSS APPLY (satır bazlı alt sorgu)","aliases":["lateral","cross apply","outer apply","satir bazli alt sorgu","iliskili tablo fonksiyonu"],"engines":{"oracle":{"command":"-- Her müşterinin en son 3 siparişi (LATERAL, 12c+)\nSELECT m.ad, s.tarih, s.tutar\nFROM musteri m,\n     LATERAL (SELECT tarih, tutar FROM siparis\n              WHERE musteri_id = m.id\n              ORDER BY tarih DESC FETCH FIRST 3 ROWS ONLY) s;\n\n-- Alternatif: CROSS APPLY (12c+)\nSELECT m.ad, s.tutar\nFROM musteri m\nCROSS APPLY (SELECT tutar FROM siparis WHERE musteri_id = m.id) s;","note":"LATERAL/APPLY, FROM içindeki bir alt sorgunun soldaki tablonun sütunlarına başvurabilmesini sağlar; böylece 'her satır için ilk N kayıt' gibi ilişkili birleştirmeler yazılır. Oracle 12c hem ANSI LATERAL hem de CROSS/OUTER APPLY söz dizimini destekler.","since":"Oracle 12c","xnote":"LATERAL ve CROSS/OUTER APPLY Oracle 12c ile geldi.","danger":"safe"},"postgres":{"command":"SELECT m.ad, s.tarih, s.tutar\nFROM musteri m\nCROSS JOIN LATERAL (\n  SELECT tarih, tutar FROM siparis\n  WHERE musteri_id = m.id\n  ORDER BY tarih DESC LIMIT 3\n) s;","note":"PostgreSQL LATERAL anahtar kelimesiyle (JOIN LATERAL / CROSS JOIN LATERAL / LEFT JOIN LATERAL) soldaki satıra bağlı alt sorgular yazılır. 'Her grup için ilk N' (top-N-per-group) ve set döndüren fonksiyonlarla satır genişletme için çok kullanışlıdır. CROSS APPLY söz dizimi yoktur; LATERAL kullanılır.","since":"PostgreSQL 9.3","xnote":"LATERAL PostgreSQL 9.3 ile geldi.","danger":"safe"},"mysql":{"command":"-- MySQL 8.0.14+ LATERAL destekler\nSELECT m.ad, s.tutar\nFROM musteri m\nJOIN LATERAL (\n  SELECT tutar FROM siparis\n  WHERE musteri_id = m.id\n  ORDER BY tarih DESC LIMIT 3\n) s ON true;","note":"MySQL 8.0.14'ten beri LATERAL türetilmiş tabloları destekler; alt sorgu dıştaki tablonun sütunlarına başvurabilir. Öncesinde ve CROSS APPLY için karşılık yoktu; 'her grup için ilk N' pencere fonksiyonları veya ilişkili alt sorgularla çözülürdü. MariaDB'de LATERAL henüz yoktur.","since":"MySQL 8.0.14","xnote":"LATERAL türetilmiş tablolar MySQL 8.0.14 ile geldi; MariaDB'de yoktur.","danger":"safe"},"mssql":{"command":"SELECT m.ad, s.tarih, s.tutar\nFROM musteri m\nCROSS APPLY (\n  SELECT TOP 3 tarih, tutar FROM siparis\n  WHERE musteri_id = m.id\n  ORDER BY tarih DESC\n) s;\n-- Eşleşme olmayanları da döndürmek için OUTER APPLY","note":"SQL Server'ın LATERAL karşılığı APPLY operatörüdür: CROSS APPLY (INNER JOIN LATERAL gibi, eşleşmeyeni eler) ve OUTER APPLY (LEFT JOIN LATERAL gibi, eşleşmeyende NULL). Tablo değerli fonksiyonları her satır için çağırmakta ve top-N-per-group sorgularında yaygındır.","since":"SQL Server 2005","xnote":"CROSS/OUTER APPLY operatörü SQL Server 2005 ile geldi.","danger":"safe"},"mongodb":{"command":"// En yakın karşılık: alt pipeline'lı $lookup\ndb.musteri.aggregate([\n  { $lookup: {\n      from: \"siparis\",\n      let: { mid: \"$id\" },\n      pipeline: [\n        { $match: { $expr: { $eq: [\"$musteri_id\", \"$$mid\"] } } },\n        { $sort: { tarih: -1 } }, { $limit: 3 }\n      ],\n      as: \"son3\"\n  } }\n])","note":"MongoDB'de LATERAL/APPLY karşılığı, alt pipeline ve let değişkenleri olan $lookup biçimidir: dıştaki belgenin alanları let ile $$degisken olarak alt pipeline'a taşınır ve orada eşleşme/sıralama/sınırlama yapılır. Bu, 'her belge için ilgili ilk N' desenini çözer.","danger":"safe"},"redis":{"command":"# Uygulanamaz: Redis'te alt sorgu / LATERAL yoktur.","note":"Redis satır bazlı ilişkili alt sorgu sunmaz. 'Her öğe için ilgili ilk N' deseni uygulama tarafında döngüyle (her anahtar için ayrı ZRANGE gibi) veya sunucu tarafı Lua script ile çözülür.","danger":"safe"},"elasticsearch":{"command":"# En yakın karşılık: terms + top_hits alt agregasyonu\nGET siparis/_search\n{\n  \"size\": 0,\n  \"aggs\": { \"musteriye_gore\": { \"terms\": { \"field\": \"musteri_id\" },\n    \"aggs\": { \"son3\": { \"top_hits\": {\n      \"sort\": [ { \"tarih\": \"desc\" } ], \"size\": 3 } } } } }\n}","note":"Elasticsearch'te LATERAL/APPLY yoktur; 'her grup için ilk N kayıt' deseni terms agregasyonu içine yerleştirilmiş top_hits alt agregasyonuyla elde edilir. Bu, ilişkili alt sorgu yerine tek index üzerinde gruplama artı grup içi örnekleme yaklaşımıdır.","danger":"safe"}}},{"id":"pivot","title":"PIVOT / UNPIVOT (satır↔sütun)","aliases":["pivot","unpivot","crosstab","capraz tablo","satir sutun","coz"],"engines":{"oracle":{"command":"-- Aylara göre satışları sütunlara çevir\nSELECT * FROM (\n  SELECT ay, tutar FROM satis\n)\nPIVOT (SUM(tutar) FOR ay IN ('Oca' AS ocak, 'Sub' AS subat, 'Mar' AS mart));\n\n-- UNPIVOT: sütunları tekrar satıra çevir\nSELECT urun, ay, tutar\nFROM satis_genis\nUNPIVOT (tutar FOR ay IN (ocak AS 'Oca', subat AS 'Sub'));","note":"PIVOT satırlardaki farklı değerleri sütunlara (çapraz tablo), UNPIVOT ise sütunları tekrar satırlara çevirir; özet/rapor tablolarında kullanılır. Oracle 11g'den beri yerleşik PIVOT/UNPIVOT operatörlerini sunar; sütun listesi statik olmalıdır (dinamik için PIVOT XML veya kod gerekir).","since":"Oracle 11g","xnote":"Yerleşik PIVOT/UNPIVOT operatörleri Oracle 11g ile geldi.","danger":"safe"},"postgres":{"command":"-- crosstab için tablefunc eklentisi\nCREATE EXTENSION IF NOT EXISTS tablefunc;\nSELECT * FROM crosstab(\n  'SELECT urun, ay, tutar FROM satis ORDER BY 1,2'\n) AS ct(urun text, ocak numeric, subat numeric, mart numeric);\n\n-- Eklentisiz yol: koşullu toplama\nSELECT urun,\n  SUM(tutar) FILTER (WHERE ay = 'Oca') AS ocak,\n  SUM(tutar) FILTER (WHERE ay = 'Sub') AS subat\nFROM satis GROUP BY urun;","note":"PostgreSQL'de yerleşik PIVOT operatörü yoktur. İki yol vardır: tablefunc eklentisinin crosstab() fonksiyonu veya taşınabilir olan koşullu toplama (SUM(...) FILTER (WHERE ...) ya da CASE ile). FILTER yan tümcesi PostgreSQL'e özgü şık bir pivot yöntemidir.","danger":"safe"},"mysql":{"command":"-- PIVOT yoktur; manuel CASE ile koşullu toplama\nSELECT urun,\n  SUM(CASE WHEN ay = 'Oca' THEN tutar ELSE 0 END) AS ocak,\n  SUM(CASE WHEN ay = 'Sub' THEN tutar ELSE 0 END) AS subat,\n  SUM(CASE WHEN ay = 'Mar' THEN tutar ELSE 0 END) AS mart\nFROM satis\nGROUP BY urun;","note":"MySQL/MariaDB'de PIVOT/UNPIVOT operatörü yoktur; çapraz tablo GROUP BY ile birlikte her hedef sütun için SUM(CASE WHEN ... THEN ... END) yazılarak elle kurulur. Sütunlar dinamikse sorgu, prepared statement ile string olarak üretilir.","danger":"safe"},"mssql":{"command":"SELECT * FROM (\n  SELECT urun, ay, tutar FROM satis\n) src\nPIVOT (\n  SUM(tutar) FOR ay IN ([Oca], [Sub], [Mar])\n) pvt;\n\n-- UNPIVOT ile geri çevirme de desteklenir","note":"SQL Server 2005'ten beri PIVOT ve UNPIVOT operatörlerini yerleşik olarak destekler. PIVOT sütun listesi statik köşeli parantezli değerlerle verilir; dinamik sütunlar için sorgu dinamik SQL ile oluşturulur. Küçük özetlerde koşullu toplama (CASE) da alternatiftir.","since":"SQL Server 2005","xnote":"PIVOT/UNPIVOT operatörleri SQL Server 2005 ile geldi.","danger":"safe"},"mongodb":{"command":"// PIVOT karşılığı: $group içinde koşullu toplama\ndb.satis.aggregate([\n  { $group: {\n      _id: \"$urun\",\n      ocak: { $sum: { $cond: [ { $eq: [\"$ay\", \"Oca\"] }, \"$tutar\", 0 ] } },\n      subat: { $sum: { $cond: [ { $eq: [\"$ay\", \"Sub\"] }, \"$tutar\", 0 ] } }\n  } }\n])","note":"MongoDB'de PIVOT operatörü yoktur; çapraz tablo $group aşamasında her hedef sütun için $sum + $cond (koşullu toplama) ile kurulur. Ters yön (UNPIVOT) için $objectToArray ve $unwind ile alanlar satırlara açılır.","danger":"safe"},"redis":{"command":"# Uygulanamaz: Redis'te pivot/çapraz tablo yoktur.","note":"Redis'te satır-sütun döndürme kavramı yoktur. Özet/çapraz tablolar uygulama tarafında hesaplanır; sık istenen özetler önceden hesaplanıp Hash alanlarında (her sütun bir alan) saklanabilir. RediSearch FT.AGGREGATE ile gruplu toplama yapılabilir ama gerçek pivot değildir.","danger":"safe"},"elasticsearch":{"command":"# En yakın karşılık: iç içe terms agregasyonları\nGET satis/_search\n{\n  \"size\": 0,\n  \"aggs\": { \"urun\": { \"terms\": { \"field\": \"urun\" },\n    \"aggs\": { \"ay\": { \"terms\": { \"field\": \"ay\" },\n      \"aggs\": { \"toplam\": { \"sum\": { \"field\": \"tutar\" } } } } } }\n}","note":"Elasticsearch'te PIVOT operatörü yoktur; çapraz özet iç içe terms agregasyonlarıyla (dış anahtar / iç anahtar) kurulur, sonuç sütun değil iç içe bucket olarak döner ve istemcide tabloya çevrilir. Transform işi ise gruplu pivot benzeri hedef index üretebilir.","danger":"safe"}}},{"id":"coalesce-null","title":"NULL yönetimi (COALESCE/NVL/NULLIF/IS NULL)","aliases":["coalesce","nvl","nullif","is null","ifnull","isnull","null yonetimi","bos deger"],"engines":{"oracle":{"command":"-- COALESCE: ilk NULL olmayanı döndürür (standart)\nSELECT ad, COALESCE(telefon, cep, 'yok') AS iletisim FROM musteri;\n\n-- Oracle'a özgü NVL / NVL2\nSELECT NVL(bakiye, 0) FROM musteri;\nSELECT NVL2(indirim, 'var', 'yok') FROM siparis;\n\n-- NULLIF ve IS NULL\nSELECT NULLIF(a, b) FROM t;   -- a=b ise NULL\nSELECT ad FROM musteri WHERE telefon IS NULL;","note":"NULL (bilinmeyen değer) yönetimi için: COALESCE listedeki ilk NULL olmayanı döndürür (standart, çok argümanlı). Oracle'a özgü NVL(a,b) iki argümanlı karşılıktır; NVL2 NULL/ dolu durumuna göre farklı değer verir. NULLIF(a,b) eşitse NULL üretir. NULL testi daima IS NULL / IS NOT NULL ile yapılır (= NULL çalışmaz).","danger":"safe"},"postgres":{"command":"SELECT ad, COALESCE(telefon, cep, 'yok') AS iletisim FROM musteri;\nSELECT NULLIF(bolen, 0) FROM t;   -- 0'a bölmeyi engelle\nSELECT ad FROM musteri WHERE telefon IS NULL;\n-- Oracle NVL karşılığı COALESCE'tir","note":"PostgreSQL standart COALESCE, NULLIF ve IS NULL/IS NOT NULL sunar; Oracle'ın NVL'si yerine COALESCE kullanılır. NULL karşılaştırması için = değil IS kullanılır; iki NULL'ı eşit saymak gerekirse 'IS NOT DISTINCT FROM' operatörü işe yarar.","danger":"safe"},"mysql":{"command":"SELECT ad, COALESCE(telefon, cep, 'yok') AS iletisim FROM musteri;\n\n-- MySQL kısayolu: IFNULL (iki argüman)\nSELECT IFNULL(bakiye, 0) FROM musteri;\nSELECT NULLIF(a, b) FROM t;\nSELECT ad FROM musteri WHERE telefon IS NULL;","note":"MySQL/MariaDB standart COALESCE ve NULLIF'i destekler; iki argümanlı kısayol olarak IFNULL(a,b) vardır (Oracle NVL benzeri). NULL-güvenli eşitlik için <=> operatörü kullanılır (iki NULL'ı eşit sayar). NULL testi IS NULL / IS NOT NULL ile yapılır.","danger":"safe"},"mssql":{"command":"SELECT ad, COALESCE(telefon, cep, 'yok') AS iletisim FROM musteri;\n\n-- SQL Server kısayolu: ISNULL (iki argüman)\nSELECT ISNULL(bakiye, 0) FROM musteri;\nSELECT NULLIF(a, b) FROM t;\nSELECT ad FROM musteri WHERE telefon IS NULL;","note":"SQL Server standart COALESCE (çok argümanlı, veri tipini yükselterek) ve iki argümanlı ISNULL(a,b) sunar; ikisi ince farklarla ayrışır (COALESCE standart ve tip önceliği daha esnektir). NULLIF ve IS NULL da desteklenir. ISNULL Oracle NVL'nin karşılığıdır (isim benzerdir).","danger":"safe"},"mongodb":{"command":"// COALESCE karşılığı: $ifNull\ndb.musteri.aggregate([\n  { $project: { ad: 1,\n      iletisim: { $ifNull: [\"$telefon\", \"$cep\", \"yok\"] } } }\n])\n// NULL / alan yok kontrolü:\ndb.musteri.find({ telefon: { $in: [null] } })","note":"MongoDB aggregation'da COALESCE karşılığı $ifNull operatörüdür (birden çok argüman, ilk null/eksik olmayanı döndürür). Sorguda { alan: null } hem değeri null olan hem de alanı hiç olmayan belgeleri eşler; ayrımı { alan: { $type: 'null' } } veya $exists ile netleştirirsiniz.","danger":"safe"},"redis":{"command":"# Redis'te NULL yerine 'anahtar/alan yok' kavramı vardır:\nEXISTS musteri:1              # anahtar var mı?\nHGET musteri:1 telefon        # alan yoksa nil döner\nGET yok_olan                  # (nil)","note":"Redis'te SQL anlamında NULL yoktur; karşılığı 'anahtar yok' veya Hash alanının bulunmaması durumudur ve komutlar bu durumda nil döndürür. Varsayılan değer mantığı (COALESCE gibi) uygulama tarafında nil kontrolüyle uygulanır. Alan varlığı HEXISTS ile denetlenir.","danger":"safe"},"elasticsearch":{"command":"# Alan yoksa varsayılan atama (missing bucket / null_value)\n# Sorguda alanı olmayanları bulma:\nGET musteri/_search\n{ \"query\": { \"bool\": { \"must_not\": { \"exists\": { \"field\": \"telefon\" } } } } }\n# Mapping'de null_value ile boşları belirli değere eşle","note":"Elasticsearch'te null veya eksik alanlar 'exists' sorgusuyla denetlenir (must_not exists = alanı olmayanlar). COALESCE benzeri varsayılan için mapping'de 'null_value' tanımlanır ya da agregasyonlarda 'missing' parametresiyle boşlara bir değer atanır. Runtime/script ile de varsayılan üretilebilir.","danger":"safe"}}}]},"rosetta/overlay-elasticsearch.json":{"engineId":"elasticsearch","byConcept":{"active-sessions":{"command":"GET _tasks?detailed=true&actions=*search*\n# Düğüm baskısını görmek için: GET _nodes/hot_threads","note":"Task API o an çalışan görevleri (arama, reindex, bulk) verir. Anlık CPU yoğunluğu için hot_threads en aktif thread'leri gösterir.","danger":"safe"},"blocking-sessions":{"command":"# Uygulanamaz: Elasticsearch'te satır/belge kilidi ve bloklama kavramı yoktur.\n# En yakın teşhis: uzun süren görevleri bul\nGET _tasks?detailed=true","note":"Bloklama yerine yavaşlık genelde uzun süren görevlerden (büyük arama, reindex) kaynaklanır. running_time_in_nanos alanı ile süreyi değerlendirin.","danger":"safe"},"kill-session":{"command":"POST _tasks/<task_id>/_cancel\n# task_id biçimi: nodeId:taskNumber (ör. oTUltX4IQMOUUVeiohTt8A:12345)","note":"task_id değerini GET _tasks çıktısından alın. Yalnızca iptal edilebilir (cancellable:true) görevler durdurulabilir.","danger":"danger"},"connection-count":{"command":"GET _nodes/stats/http","note":"current_open anlık açık HTTP bağlantısını, total_opened düğüm açılışından beri toplam bağlantıyı verir. HTTP bağlantı üst sınırı için http.max_content_length değil, işletim sistemi/soket limitleri belirleyicidir.","danger":"safe"},"database-size":{"command":"GET _cluster/stats\n# Sade özet için: GET _cat/indices?v&h=index,store.size","note":"_cluster/stats indices.store.size_in_bytes ile tüm kümenin toplam disk kullanımını verir. _cat/indices index başına boyutu insana okunur biçimde listeler.","danger":"safe"},"largest-tables":{"command":"GET _cat/indices?v&s=store.size:desc&h=index,docs.count,store.size","note":"Elasticsearch'te \"tablo\" karşılığı index'tir. s=store.size:desc en büyük index'leri en üste sıralar.","danger":"safe"},"free-space":{"command":"GET _cat/allocation?v","note":"disk.used, disk.avail ve disk.percent sütunları düğüm başına disk doluluğunu verir. Watermark eşikleri (%85/%90/%95) aşılınca shard tahsisi durur.","danger":"safe"},"row-count":{"command":"GET <index>/_count\n# Kısa yol: GET _cat/count/<index>?v","note":"_count belge sayısını hızlıca verir. Filtreli sayım için gövdede sorgu geçilebilir: GET <index>/_count {\"query\":{\"term\":{\"durum\":\"aktif\"}}}","danger":"safe"},"top-slow-queries":{"command":"PUT <index>/_settings\n{\n  \"index.search.slowlog.threshold.query.warn\": \"1s\",\n  \"index.search.slowlog.threshold.query.info\": \"500ms\",\n  \"index.search.slowlog.threshold.fetch.warn\": \"1s\"\n}\n# Eşik aşan sorgular <cluster>_index_search_slowlog.json log dosyasına yazılır","note":"Elasticsearch'te merkezi bir yavaş sorgu tablosu yoktur; search slowlog eşiği aşan sorguları düğüm log dosyalarına döker. Logları oradan okuyun.","danger":"caution"},"explain-plan":{"command":"GET <index>/_search\n{\n  \"profile\": true,\n  \"query\": { \"match\": { \"baslik\": \"deneme\" } }\n}\n# Sorgunun geçerliliğini/çözümlenmesini görmek için:\n# GET <index>/_validate/query?explain=true","note":"profile:true her sorgu bileşeninin ve toplama adımının süresini kırar. _validate/query?explain sorgunun Lucene karşılığını ve neden ret aldığını gösterir.","danger":"safe"},"unused-indexes":{"command":"# Uygulanamaz: ES'te ikincil indeks kavramı ilişkisel veritabanlarından farklıdır.\n# En yakın: az kullanılan/erişilmeyen indeksleri boyut ve arama sayısıyla değerlendir\nGET _cat/indices?v&h=index,docs.count,store.size\nGET <index>/_stats/search","note":"Kullanılmayan alan index'leri yerine, düşük arama sayısına (search.query_total) sahip veya artık sorgulanmayan index'leri _stats/search ile tespit edip kapatabilir/silebilirsiniz.","danger":"safe"},"cache-hit-ratio":{"command":"GET _nodes/stats/indices/query_cache\n# Oran = hit_count / (hit_count + miss_count)","note":"query_cache filtre bağlamındaki (filter) sonuçları önbelleğe alır. request_cache için GET _nodes/stats/indices/request_cache ayrıca incelenir.","danger":"safe"},"logical-dump":{"command":"# Önce depo tanımla (bir kez): PUT _snapshot/<repo> {\"type\":\"fs\",\"settings\":{\"location\":\"/mnt/backups\"}}\nPUT _snapshot/<repo>/<snapshot_1>?wait_for_completion=true\n{\n  \"indices\": \"*\",\n  \"include_global_state\": true\n}","note":"Elasticsearch'te mantıksal dökümün karşılığı snapshot API'sidir. wait_for_completion=true işlem bitene kadar bekler; büyük snapshot'larda false bırakıp durumu ayrıca sorgulayın.","danger":"safe"},"restore-dump":{"command":"POST _snapshot/<repo>/<snapshot_1>/_restore\n{\n  \"indices\": \"*\",\n  \"rename_pattern\": \"(.+)\",\n  \"rename_replacement\": \"restored_$1\"\n}","note":"Var olan bir index'i geri yüklemek için önce onu kapatın (POST <index>/_close) veya rename_pattern ile yeni ada geri yükleyin. Açık index'in üstüne restore yapılamaz.","danger":"danger"},"last-backup-status":{"command":"GET _snapshot/<repo>/_all\n# Devam eden/son snapshot detayları için:\n# GET _snapshot/<repo>/<snapshot_1>/_status","note":"state alanı SUCCESS / IN_PROGRESS / PARTIAL / FAILED değerlerini alır. _status shard bazında ayrıntılı ilerleme verir.","danger":"safe"},"list-users":{"command":"GET _security/user","note":"X-Pack Security etkin olmalıdır. Tek kullanıcı için GET _security/user/<kullanici>. Yerleşik (built-in) kullanıcılar da listede görünür.","danger":"safe"},"create-user-grant":{"command":"# 1) Rol oluştur\nPOST _security/role/<rol>\n{\n  \"cluster\": [\"monitor\"],\n  \"indices\": [ { \"names\": [\"log-*\"], \"privileges\": [\"read\"] } ]\n}\n# 2) Kullanıcı oluştur ve role ata\nPOST _security/user/<kullanici>\n{\n  \"password\": \"GucluParola123\",\n  \"roles\": [\"<rol>\"]\n}","note":"Yetkilendirme rol tabanlıdır: önce index/cluster ayrıcalıklarını içeren rolü tanımlayın, sonra kullanıcıya atayın. Parola en az 6 karakter olmalıdır.","danger":"caution"},"show-privileges":{"command":"GET _security/user/<kullanici>\nGET _security/role/<rol>\n# Belirli ayrıcalığa sahip mi diye kontrol:\n# POST _security/user/<kullanici>/_has_privileges { \"index\": [ { \"names\": [\"log-*\"], \"privileges\": [\"read\"] } ] }","note":"Kullanıcının rollerini _security/user ile, rolün içerdiği ayrıcalıkları _security/role ile görürsünüz. _has_privileges belirli bir eylemin izinli olup olmadığını doğrular.","danger":"safe"},"change-password":{"command":"POST _security/user/<kullanici>/_password\n{\n  \"password\": \"YeniGucluParola123\"\n}","note":"Kendi parolanızı değiştiriyorsanız POST _security/user/_password (kullanıcı adı olmadan) yeterlidir. Yerleşik elastic kullanıcısı için bin/elasticsearch-reset-password aracı da kullanılabilir.","danger":"caution"},"update-statistics":{"command":"# Uygulanamaz: Elasticsearch'te maliyet tabanlı optimizer ve tablo istatistiği toplama yoktur.\n# En yakın: yeni yazılan belgeleri aranabilir yap\nPOST <index>/_refresh","note":"Lucene segment tabanlı çalışır; ayrı istatistik güncelleme adımı gerekmez. _refresh henüz aranabilir olmayan belgeleri hemen aranabilir hale getirir (varsayılan 1sn'de otomatik olur).","danger":"safe"},"rebuild-index":{"command":"POST _reindex\n{\n  \"source\": { \"index\": \"eski_index\" },\n  \"dest\":   { \"index\": \"yeni_index\" }\n}\n# Büyük veride: POST _reindex?wait_for_completion=false ile arka planda çalıştırın","note":"Mapping değişikliği veya bozuk index'i yeniden kurmak için reindex kullanılır. Kesintisiz geçiş için yeni index'e bir alias yönlendirin.","danger":"caution"},"reclaim-space":{"command":"POST <index>/_forcemerge?only_expunge_deletes=true\n# Salt-okunur/eski indekslerde tam birleştirme: POST <index>/_forcemerge?max_num_segments=1","note":"Silinen/güncellenen belgeler segmentlerde tombstone olarak kalır; forcemerge bu alanı geri kazanır. Aktif yazılan index'lerde maliyetlidir, yoğun olmayan saatlerde çalıştırın.","danger":"caution"},"version-uptime":{"command":"GET /\n# Uptime (JVM açık kalma süresi):\n# GET _nodes/stats/jvm\n# Kısa özet: GET _cat/nodes?v&h=name,uptime,version","note":"GET / kök uç noktası sürüm, Lucene sürümü ve küme adını verir. jvm.uptime_in_millis düğümün açık kalma süresidir.","danger":"safe"},"show-config-param":{"command":"GET _cluster/settings?include_defaults=true&flat_settings=true","note":"include_defaults=true varsayılan değerleri de gösterir. persistent ve transient ayarlar ayrı bölümlerde döner; düğüm bazlı ayarlar için GET _nodes/settings.","danger":"safe"},"list-tables":{"command":"GET _cat/indices?v","note":"Elasticsearch'te ilişkisel tablonun karşılığı index'tir. health, status, docs.count ve store.size sütunlarıyla özet verir. Varsayılan çıktı açık ve kapalı index'leri gösterir, gizli (hidden) index'leri (ör. .ds- backing index'leri, sistem index'leri) göstermez; bunları da görmek için &expand_wildcards=all, yalnız açık index'ler için &expand_wildcards=open kullan.","danger":"safe"},"describe-table":{"command":"GET <index>/_mapping","note":"Mapping, alanların (field) tiplerini ve analiz ayarlarını verir; DESCRIBE TABLE karşılığıdır. Tek alan için GET <index>/_mapping/field/<alan>.","danger":"safe"},"list-indexes":{"command":"GET <index>/_mapping","note":"ES'te alanlar varsayılan olarak index'lidir; ayrı bir ikincil index tablosu yoktur. Mapping'te \"index\": false olan alanlar aranamaz. Küme genelindeki index'ler (tablolar) için GET _cat/indices?v.","danger":"safe"},"create-index":{"command":"PUT <index>\n{\n  \"settings\": { \"number_of_shards\": 1, \"number_of_replicas\": 1 },\n  \"mappings\": {\n    \"properties\": {\n      \"baslik\": { \"type\": \"text\" },\n      \"olusturma\": { \"type\": \"date\" }\n    }\n  }\n}\n# Sonradan alan eklemek için: PUT <index>/_mapping {\"properties\":{...}}","note":"Index oluşturulduktan sonra primary shard sayısı yerinde değiştirilemez (replica sayısı dinamik değişir); gerekirse _split / _shrink API'leriyle ya da _reindex ile yeni bir index üretilir. Var olan alanın tipi değiştirilemez; yeni alan eklenebilir.","danger":"caution"},"show-ddl":{"command":"GET <index>","note":"Tek çağrı hem settings hem mappings hem aliases'i döndürür; bu üçü birlikte index'in \"DDL\" karşılığıdır. Aynı çıktıyı yeni bir PUT <index> gövdesi olarak kullanabilirsiniz.","danger":"safe"},"replication-status":{"command":"GET _cluster/health\n# Devam eden shard kopyalama/kurtarma için: GET _cat/recovery?v&active_only=true\n# Çapraz küme replikasyonu (CCR) için: GET <index>/_ccr/stats","note":"status yeşil/sarı/kırmızı shard sağlığını özetler; sarı = replica atanmamış. active_shards_percent tamamlanma oranını verir.","danger":"safe"},"list-replicas":{"command":"GET _cat/shards?v&h=index,shard,prirep,state,node\n# Düğümlerin rolleri için: GET _cat/nodes?v","note":"prirep sütunu p (primary) veya r (replica) değerini alır; shard'ların düğümlere dağılımını ve durumunu (STARTED/RELOCATING) gösterir.","danger":"safe"},"promote-failover":{"command":"# Master seçimi otomatiktir; manuel promote gerekmez.\n# CCR follower'ı bağımsız (yazılabilir) indekse dönüştürmek için:\nPOST <index>/_ccr/pause_follow\nPOST <index>/_close\nPOST <index>/_ccr/unfollow\nPOST <index>/_open","note":"Elasticsearch düğüm arızasında master ve primary shard'ları otomatik yeniden seçer/atar. Manuel devralma yalnızca CCR follower index'ini liderden koparıp yazılabilir yapmak için gerekir.","danger":"danger"},"open-transactions":{"command":"# Uygulanamaz: Elasticsearch'te çok-belge transaction (BEGIN/COMMIT) yoktur.\n# İşlemler belge düzeyinde atomiktir; en yakın teşhis çalışan görevlerdir:\nGET _tasks?detailed=true","note":"Tek belgeye yazma atomiktir ve versiyonlanır (optimistic concurrency: if_seq_no / if_primary_term). Açık transaction takibi kavramı yoktur.","danger":"safe"},"connect-cli":{"command":"curl -u kullanici:parola -k https://host:9200\n# Kibana Dev Tools konsolu (önerilen): Kibana > Management > Dev Tools\n# API anahtarıyla: curl -H \"Authorization: ApiKey <base64key>\" https://host:9200","note":"REST tabanlıdır; ayrı bir CLI istemcisi yerine curl veya Kibana Dev Tools kullanılır. -k self-signed TLS sertifikasını atlar (üretimde CA kullanın).","danger":"safe"},"list-databases":{"command":"GET _cat/indices?v\n# Takma adlar (mantıksal görünümler) için: GET _aliases","note":"Elasticsearch'te ayrı \"veritabanı\" katmanı yoktur; en yakın kavram index'ler ve onları gruplayan alias'lardır. Data stream'ler için GET _data_stream.","danger":"safe"},"switch-database":{"command":"# Uygulanamaz: hedef indeks doğrudan istek yolunda belirtilir, oturum bağlamı değişmez.\nGET <index>/_search\n# Kibana'da varsayılan görünüm için data view (index pattern) seçilir","note":"USE <db> benzeri bir komut yoktur; her istekte hedef index/alias yolda verilir. Birden çok index'te arama için virgülle ayırın: GET log-2024,log-2025/_search.","danger":"safe"}}},"errors/oracle.json":{"engineId":"oracle","engine":"Oracle","order":1,"errors":[{"code":"ORA-00001","title":"Unique constraint violated","severity":"caution","meaning":"Bir tabloya eklenen veya güncellenen satır, UNIQUE ya da PRIMARY KEY constraint'ini ihlal ediyor. Yani aynı değer zaten mevcut.","cause":"Aynı anahtar değeriyle tekrar INSERT yapılması, benzersiz olması gereken bir sütuna mükerrer veri girilmesi veya çoğaltma/yeniden çalıştırma sırasında aynı kaydın iki kez işlenmesi.","fix":"Hata mesajındaki constraint adından hangi sütunun ihlal edildiğini bulun: SELECT column_name FROM all_cons_columns WHERE constraint_name = 'KISIT_ADI'. Mükerrer veriyi bulmak için GROUP BY ... HAVING COUNT(*) > 1 kullanın. Uygulamada var olan kayıt için INSERT yerine UPDATE ya da MERGE kullanın. Sıra (sequence) değeri geride kaldıysa ALTER SEQUENCE ile ilerletin.","tags":["unique","benzersiz","constraint","kısıt","primary key","duplicate","mükerrer","insert"]},{"code":"ORA-00054","title":"Resource busy and acquire with NOWAIT specified or timeout expired","severity":"caution","meaning":"Kilitlenmek istenen kaynak (satır ya da tablo) başka bir oturum tarafından kilitli olduğu için, NOWAIT belirtildiğinden veya DDL_LOCK_TIMEOUT süresi dolduğundan hemen alınamadı.","cause":"Genellikle bir DDL (ALTER TABLE, DROP, CREATE INDEX) çalıştırmaya çalışırken tablonun başka bir transaction tarafından kilitli olması; ya da SELECT ... FOR UPDATE NOWAIT kullanımı sırasında satırın kilitli olması.","fix":"Lock'u tutan oturumu bulun: SELECT * FROM v$locked_object. Engelleyen oturumu tespit için v$session ve v$lock birleştirilebilir. Transaction'ın bitmesini bekleyin veya gerekirse ALTER SYSTEM KILL SESSION ile sonlandırın. DDL için bekleme süresi tanımlayabilirsiniz: ALTER SESSION SET DDL_LOCK_TIMEOUT = 60; Yoğun olmayan bakım pencerelerinde DDL çalıştırın.","tags":["lock","kilit","ddl","nowait","busy","meşgul","timeout"]},{"code":"ORA-00060","title":"Deadlock detected while waiting for resource","severity":"danger","meaning":"İki veya daha fazla oturum, birbirinin tuttuğu kaynağı beklerken karşılıklı kilitlenmiş (deadlock). Oracle döngüyü tespit edip kurbanı seçer ve o oturumun ifadesini geri alır.","cause":"Row lock'larının farklı sıralarda alınması, aynı satırların farklı transaction'lar tarafından çapraz güncellenmesi, index'siz foreign key'ler nedeniyle üst tablo güncellemelerinde table lock oluşması veya bitmap index üzerinde eşzamanlı DML.","fix":"Alert log'da oluşan deadlock trace (graph) dosyasını inceleyerek çakışan SQL'leri ve satırları bulun. Uygulamada tablolara/satırlara her zaman aynı sırada erişin. Foreign key sütunlarına index ekleyin (index'siz FK klasik deadlock nedenidir). Transaction'ları kısa tutun ve commit sıklığını gözden geçirin. Deadlock'a düşen transaction'ı uygulamada yakalayıp yeniden deneyin.","tags":["deadlock","ölümcül kilit","lock","kilit","tx","transaction"]},{"code":"ORA-01017","title":"Invalid username/password; logon denied","severity":"caution","meaning":"Veritabanına bağlanırken verilen kullanıcı adı veya parola yanlış olduğu için oturum açma reddedildi.","cause":"Hatalı parola, yanlış kullanıcı adı, büyük/küçük harfe duyarlı parola ayarının (SEC_CASE_SENSITIVE_LOGON) beklenenden farklı olması, parolanın değişmiş olması veya uygulama bağlantı dizesindeki kimlik bilgilerinin eskimesi.","fix":"Kullanıcı adı ve parolayı doğrulayın. Gerekirse DBA olarak parolayı sıfırlayın: ALTER USER kullanici IDENTIFIED BY yeni_parola. Kullanıcının var ve kilitli olmadığını kontrol edin: SELECT username, account_status FROM dba_users. 12c+ parola hash sürümlerinde 11g istemcisi bağlanırken sorun olabilir; SQLNET.ALLOWED_LOGON_VERSION_SERVER ayarını gözden geçirin.","tags":["auth","kimlik","parola","password","logon","giriş","yetki"]},{"code":"ORA-01555","title":"Snapshot too old: rollback segment number too small","severity":"danger","meaning":"Uzun süren bir sorgu, başladığı andaki tutarlı görüntüyü (read consistency) oluşturmak için gereken eski undo verisine erişemedi; çünkü o undo bilgisi üzerine yazılmış.","cause":"Undo tablespace'inin küçük olması, UNDO_RETENTION süresinin kısa olması, aynı anda çok yoğun DML çalışırken uzun süren sorgular olması veya bir sorgu içinde aynı tabloya commit yapan bir döngü (fetch across commit) bulunması.","fix":"UNDO_RETENTION değerini artırın ve undo tablespace'ini büyütün, mümkünse otomatik yönetimde bırakın (AUTOEXTEND açık). Uzun sorguları küçük parçalara bölün veya yoğun olmayan zamanda çalıştırın. RETENTION GUARANTEE ayarını değerlendirin: ALTER TABLESPACE undotbs1 RETENTION GUARANTEE. Döngü içinde commit eden uygulama mantığını düzeltin.","tags":["undo","snapshot","rollback","read consistency","tutarlılık","uzun sorgu"]},{"code":"ORA-01652","title":"Unable to extend temp segment by N in tablespace","severity":"danger","meaning":"Oracle bir geçici (temp) segmenti büyütmek için tablespace'te yeterli boş alan bulamadı. Genellikle sıralama, hash join veya global geçici tablo işlemleri sırasında oluşur.","cause":"TEMP tablespace'inin dolması; büyük ORDER BY, GROUP BY, DISTINCT, hash join veya index oluşturma işlemlerinin PGA belleğine sığmayıp diske taşması; datafile'ların AUTOEXTEND kapalı olması veya disk alanının bitmesi.","fix":"TEMP kullanımını izleyin: SELECT * FROM v$sort_usage / v$tempseg_usage. TEMP tablespace'ine dosya ekleyin ya da büyütün: ALTER TABLESPACE temp ADD TEMPFILE '...' SIZE 2G AUTOEXTEND ON. Kalıcı bir tablespace doluysa datafile ekleyin. Sorguyu optimize ederek disk sıralamasını azaltın (uygun index, PGA_AGGREGATE_TARGET artırımı).","tags":["temp","tablespace","alan","space","sort","sıralama","extend"]},{"code":"ORA-04031","title":"Unable to allocate N bytes of shared memory","severity":"danger","meaning":"Oracle, paylaşımlı bellek havuzunda (genellikle shared pool ya da large pool) istenen boyutta ardışık bellek ayıramadı. SGA'daki bir bileşen bellek baskısı altında.","cause":"Bind değişkeni kullanılmayan (literal dolu) çok sayıda benzersiz SQL nedeniyle shared pool'un parçalanması, yetersiz SHARED_POOL_SIZE, çok fazla eşzamanlı bağlantı, büyük PL/SQL paketleri veya ASMM/AMM yanlış boyutlandırması.","fix":"Hata mesajındaki alanın hangi havuz olduğuna bakın (shared pool, large pool vb.). Kısa vadede: ALTER SYSTEM FLUSH SHARED_POOL (dikkat: üretimde tüm SQL'lerin yeniden parse edilmesine, yani geçici hard parse fırtınasına yol açar ve parçalanmayı kalıcı olarak çözmez). Kalıcı çözüm: bind değişkeni kullanımını zorlayın (CURSOR_SHARING dahil), SGA_TARGET / SHARED_POOL_SIZE / LARGE_POOL_SIZE değerlerini artırın. Sık kullanılan paketleri DBMS_SHARED_POOL.KEEP ile bellekte tutun. V$SGASTAT ile bellek dağılımını inceleyin.","tags":["memory","bellek","shared pool","sga","ora-4031","bind"]},{"code":"ORA-12154","title":"TNS: could not resolve the connect identifier specified","severity":"caution","meaning":"Bağlantıda kullanılan servis adı (connect identifier / TNS alias) çözümlenemedi. Oracle Net, verilen adı bir sunucu/servis bilgisine eşleyemiyor.","cause":"tnsnames.ora dosyasında ilgili alias'ın bulunmaması, TNS_ADMIN ortam değişkeninin yanlış dizini göstermesi, alias adında yazım hatası, EZConnect/LDAP ad çözümleme yapılandırmasının eksikliği veya sqlnet.ora'daki NAMES.DIRECTORY_PATH sıralamasının hatalı olması.","fix":"tnsnames.ora içinde kullandığınız alias'ın tanımlı olduğunu doğrulayın. Bağlantıyı test edin: tnsping servis_adi. TNS_ADMIN'in doğru klasörü gösterdiğinden emin olun. Alternatif olarak EZConnect deneyin: kullanici/parola@host:1521/servis_adi. sqlnet.ora'da NAMES.DIRECTORY_PATH = (TNSNAMES, EZCONNECT) satırını kontrol edin.","tags":["tns","connect","bağlantı","network","ağ","tnsnames","servis"]},{"code":"ORA-12514","title":"TNS: listener does not currently know of service requested in connect descriptor","severity":"caution","meaning":"Listener çalışıyor ancak istenen servis adını tanımıyor; yani o servis listener'a kayıtlı değil.","cause":"Veritabanı örneğinin (instance) tam açık olmaması, servisin listener'a henüz kaydolmamış olması (12c+ LREG, 11g ve öncesinde PMON kayıt gecikmesi), yanlış SERVICE_NAME kullanılması veya SID ile servis adının karıştırılması.","fix":"Listener'ın bildiği servisleri görün: lsnrctl status ve lsnrctl services. Veritabanının OPEN durumda olduğunu doğrulayın. Servis kaydını tetikleyin: SQL'de ALTER SYSTEM REGISTER. LOCAL_LISTENER parametresini ve doğru SERVICE_NAME kullanımını kontrol edin. Pluggable veritabanında PDB'nin OPEN olduğundan emin olun.","tags":["tns","listener","servis","service_name","bağlantı","network","ağ"]},{"code":"ORA-00942","title":"Table or view does not exist","severity":"caution","meaning":"Sorguda başvurulan tablo ya da view mevcut değil ya da erişen kullanıcı için görünür değil.","cause":"Nesnenin gerçekten olmaması, farklı bir şemada bulunması ve şema öneki verilmemesi, kullanıcının nesne üzerinde yetkisinin (SELECT gibi) olmaması, eş adının (synonym) eksik olması veya nesne adının yazımının hatalı olması.","fix":"Nesnenin varlığını ve sahibini kontrol edin: SELECT owner, object_type FROM all_objects WHERE object_name = 'TABLO_ADI'. Erişimi başka şemadaysa şema.tablo şeklinde tam nitelendirin veya GRANT SELECT ON sema.tablo TO kullanici verin. Gerekirse public/private synonym oluşturun: CREATE SYNONYM tablo FOR sema.tablo. Büyük/küçük harf ve tırnaklı tanımlayıcılara dikkat edin.","tags":["table","tablo","view","görünüm","grant","yetki","synonym","eşad"]},{"code":"ORA-01031","title":"Insufficient privileges","severity":"caution","meaning":"Kullanıcı, yapmaya çalıştığı işlem için gerekli yetkiye (system ya da object privilege) sahip değil.","cause":"Gerekli sistem veya nesne yetkisinin verilmemiş olması, yetkinin sadece bir rol üzerinden gelmesi (rol devre dışıysa PL/SQL blokları içinde geçerli olmaz), SYSDBA/SYSOPER olmadan yönetimsel bir işlem denenmesi veya definer-rights prosedürlerinde doğrudan grant eksikliği.","fix":"Eksik yetkiyi verin, örneğin: GRANT CREATE TABLE TO kullanici veya GRANT SELECT ON sema.tablo TO kullanici. Named PL/SQL nesnelerinde yetkilerin rol üzerinden değil doğrudan verilmesi gerektiğini unutmayın. SYSDBA gerektiren işlemler için doğru kimlik bilgisiyle bağlanın. Mevcut yetkileri kontrol edin: SELECT * FROM session_privs / user_sys_privs.","tags":["privilege","yetki","grant","izin","auth","rol","role"]},{"code":"ORA-00257","title":"Archiver error. Connect internal only, until freed","severity":"danger","meaning":"Arşivleyici (ARCH) süreci redo log'ları arşivleyemiyor; genellikle arşiv hedefi (FRA veya archive log destination) dolu. Veritabanı yeni işlemleri askıya alır.","cause":"Flash Recovery Area (DB_RECOVERY_FILE_DEST) veya arşiv log hedefinin dolması, disk alanının bitmesi, RMAN yedeklerinin arşiv log'ları silmemesi ya da DB_RECOVERY_FILE_DEST_SIZE sınırına ulaşılması.","fix":"Alanı boşaltın: eski arşiv log'ları RMAN ile FRA dışındaki bir hedefe yedekleyip silin: RMAN> BACKUP ARCHIVELOG ALL FORMAT '/backup/arc_%U' DELETE INPUT (FRA doluyken yedeği FRA'ya yazmaya çalışmak başarısız olur). Data Guard varsa, standby'a gönderilmemiş veya uygulanmamış arşivleri silmeyin; aksi halde standby'da gap oluşur (CONFIGURE ARCHIVELOG DELETION POLICY TO APPLIED ON ALL STANDBY). FRA kullanımını görün: SELECT * FROM v$recovery_file_dest / v$flash_recovery_area_usage. Geçici olarak DB_RECOVERY_FILE_DEST_SIZE değerini artırın veya hedefi daha büyük bir diske taşıyın. Disk düzeyinde boş alan kontrolü yapın. Düzenli arşiv temizleme politikası kurun.","tags":["archive","arşiv","archiver","fra","disk","alan","redo"]},{"code":"ORA-01000","title":"Maximum open cursors exceeded","severity":"caution","meaning":"Bir oturum, OPEN_CURSORS parametresiyle izin verilenden fazla cursor açtı. Yeni cursor açılamıyor.","cause":"Uygulamanın açtığı Statement/ResultSet nesnelerini kapatmaması (cursor leak), OPEN_CURSORS değerinin iş yüküne göre düşük ayarlanması veya döngü içinde sürekli yeni hazır ifadeler (prepared statement) hazırlanıp kapatılmaması.","fix":"Açık cursor'ları izleyin: SELECT * FROM v$open_cursor WHERE sid = ...  ve oturum başına sayıyı v$sesstat üzerinden görün. Asıl çözüm uygulamada her Statement/ResultSet'i finally bloğunda kapatmaktır (cursor leak giderme). Geçici çözüm olarak OPEN_CURSORS değerini artırın: ALTER SYSTEM SET OPEN_CURSORS = 1000. JDBC statement cache boyutunu gözden geçirin.","tags":["cursor","imleç","open_cursors","leak","sızıntı","jdbc"]},{"code":"ORA-00018","title":"Maximum number of sessions exceeded","severity":"danger","meaning":"Veritabanı, SESSIONS parametresiyle izin verilen en fazla oturum sayısına ulaştı; yeni oturum açılamıyor.","cause":"SESSIONS/PROCESSES parametresinin iş yükünün altında kalması, bağlantı havuzunun (connection pool) çok büyük yapılandırılması, bağlantı sızıntısı ya da kapanmayan oturumların birikmesi.","fix":"Mevcut oturum sayısını görün: SELECT COUNT(*) FROM v$session. Sınırları kontrol edin: SELECT * FROM v$resource_limit WHERE resource_name IN ('sessions','processes'). PROCESSES ve dolaylı SESSIONS değerini artırın (SPFILE ile, yeniden başlatma gerekir): ALTER SYSTEM SET PROCESSES = 500 SCOPE=SPFILE. Bağlantı havuzu boyutlarını ve sızıntıları uygulamada gözden geçirin.","tags":["session","oturum","sessions","processes","connection","bağlantı","limit"]},{"code":"ORA-28000","title":"The account is locked","severity":"caution","meaning":"Bağlanmaya çalışılan veritabanı kullanıcı hesabı kilitli olduğu için oturum açılamıyor.","cause":"Profil ayarındaki FAILED_LOGIN_ATTEMPTS sınırının aşılması (art arda hatalı parola), hesabın DBA tarafından elle kilitlenmesi (ALTER USER ... ACCOUNT LOCK). Hatalı giriş kilidi PASSWORD_LOCK_TIME süresi sonunda kendiliğinden kalkar. Not: PASSWORD_LIFE_TIME dolması hesabı kilitlemez; hesap EXPIRED / EXPIRED(GRACE) durumuna geçer ve ORA-28001/ORA-28002 verir.","fix":"Hesabın durumunu görün: SELECT username, account_status, lock_date FROM dba_users WHERE username = 'KULLANICI'. Kilidi açın: ALTER USER kullanici ACCOUNT UNLOCK. Tekrarlanmaması için hatalı giriş kaynağını bulun ve gerekirse profilde FAILED_LOGIN_ATTEMPTS değerini gözden geçirin. Parola süresi dolduysa yeni parola atayın.","tags":["account","hesap","locked","kilitli","auth","parola","profile"]},{"code":"ORA-01578","title":"Oracle data block corrupted (file #, block #)","severity":"danger","meaning":"Belirtilen datafile'daki bir veri bloğu bozulmuş; Oracle bloğun tutarlılık kontrolünden (checksum) geçemediğini bildiriyor. Fiziksel bozulma söz konusu.","cause":"Disk/donanım arızası, depolama katmanı hataları, işletim sistemi ya da denetleyici sorunları, güç kesintisi sonucu yarım yazılmış bloklar veya bozuk yedek/geri yükleme.","fix":"Bozulmayı doğrulayın ve kapsamını görün: RMAN> VALIDATE DATABASE / VALIDATE CHECK LOGICAL DATAFILE n; ayrıca DBVERIFY (dbv) çalıştırın ve v$database_block_corruption'a bakın. Yedek varsa blok düzeyinde kurtarın: RMAN> RECOVER DATAFILE n BLOCK m; ya da listedeki tüm bloklar için RMAN> RECOVER CORRUPTION LIST; (eski BLOCKRECOVER komutu 11g'den beri deprecated'dır). Index bloğuysa index'i yeniden oluşturun. Donanım/disk sağlığını mutlaka kontrol edin; kök neden genelde depolamadır.","tags":["corruption","bozulma","block","blok","datafile","rman","disk"]},{"code":"ORA-01722","title":"Invalid number","severity":"safe","meaning":"Sayısal bir bağlama gereken yerde, sayıya dönüştürülemeyen bir karakter dizisi kullanıldı. Örtük veya açık dönüşüm başarısız oldu.","cause":"Sayısal sütunla metin karşılaştırması (örn. WHERE num_col = 'ABC'), sayısal alana harf içeren değer eklenmesi, TO_NUMBER için uygun olmayan biçim, ya da ondalık ayıracı/binlik ayıracı uyuşmazlığı (virgül-nokta).","fix":"Hatalı dönüşümün olduğu ifadeyi bulun; genellikle bir WHERE koşulu veya INSERT değeridir. Metin ve sayı karşılaştırmalarında tür uyumunu sağlayın, gerekirse açık dönüşüm kullanın: TO_NUMBER(sutun) ya da metin tarafı için TO_CHAR. Sayısal sütuna sayı olmayan veri girişini uygulama katmanında engelleyin. NLS_NUMERIC_CHARACTERS ayarına dikkat edin.","tags":["number","sayı","conversion","dönüşüm","to_number","datatype","veri tipi"]},{"code":"ORA-02049","title":"Timeout: distributed transaction waiting for lock","severity":"danger","meaning":"Dağıtık (distributed) bir transaction, uzak veritabanındaki bir lock için beklerken DISTRIBUTED_LOCK_TIMEOUT süresi doldu. Transaction zaman aşımına uğradı.","cause":"Database link üzerinden yürüyen bir transaction'ın, uzak taraftaki kilitli satırı beklemesi; uzak oturumdaki uzun transaction'lar, ağ gecikmeleri veya iki uçta da tutulan çakışan lock'lar.","fix":"Uzak veritabanında engelleyen lock'u ve oturumu bulup çözün (v$lock, v$session). Dağıtık transaction'ları kısa tutun ve gerekli lock'ları en sona bırakın. Gerekirse DISTRIBUTED_LOCK_TIMEOUT değerini iş yüküne göre artırın (SPFILE, yeniden başlatma gerekir). Askıda kalan (in-doubt) dağıtık transaction'lar için DBA_2PC_PENDING view'ını inceleyin ve gerekirse elle çözün.","tags":["distributed","dağıtık","dblink","lock","kilit","timeout","2pc"]},{"code":"enq: TX - row lock contention","title":"Wait: oturum, başka bir transaction'ın tuttuğu row-level lock'ı bekliyor","severity":"caution","meaning":"Bir oturum, başka bir işlemin tuttuğu row lock'un serbest kalmasını bekliyor. Klasik uygulama düzeyi lock wait event'idir.","cause":"Aynı satırı güncellemeye çalışan eşzamanlı transaction'lar, uzun süre commit edilmeyen transaction'lar, index'siz foreign key nedeniyle geniş kilitlenme veya sıralı anahtar (hot block) üzerinde yoğunlaşma.","fix":"Engelleyen ve engellenen oturumları bulun: SELECT * FROM v$session WHERE blocking_session IS NOT NULL; ayrıca v$lock ile eşleştirin. Kök nedeni uzun transaction'lar ise commit stratejisini gözden geçirin. Foreign key sütunlarına index ekleyin. Hot row'lar için tasarımı (sequence, hash) yeniden düşünün. Gerektiğinde engelleyen oturumu sonlandırın.","tags":["wait","bekleme","enq","row lock","satır kilidi","tx","contention","kilit"]},{"code":"log file sync","title":"Wait: oturum, commit'te LGWR'ın redo'yu diske yazmasını bekliyor","severity":"caution","meaning":"Bir oturum COMMIT yaptığında, LGWR'nin redo kayıtlarını redo log dosyalarına yazmasını (flush) bekler. Bu bekleme yüksekse commit gecikmesi vardır.","cause":"Yavaş redo log diskleri (yüksek I/O gecikmesi), aşırı sık commit yapan uygulama (satır satır commit), LGWR süreci üzerindeki CPU baskısı veya redo hacminin çok yüksek olması.","fix":"Ortalama bekleme süresini AWR/Statspack ile ölçün. Redo log dosyalarını hızlı, düşük gecikmeli disklere (SSD) taşıyın. Uygulamada gereksiz commit sıklığını azaltın, toplu işlemleri gruplayın. Gerekirse COMMIT_LOGGING/COMMIT_WAIT (commit_write) seçeneklerini iş gereksinimine göre değerlendirin; UYARI: NOWAIT/BATCH dayanıklılığı (durability) azaltır, çökme anında commit edilmiş görünen transaction'lar kaybolabilir. Yalnızca kaybın tolere edilebildiği işlerde, oturum ya da ifade düzeyinde kullanın; sistem genelinde açmayın. LGWR ve depolama gecikmesini birlikte inceleyin.","tags":["wait","bekleme","log file sync","commit","lgwr","redo","gecikme"]},{"code":"db file sequential read","title":"Wait: tek bloklu fiziksel okuma; genellikle index ya da tablo erişimi","severity":"caution","meaning":"Bir oturum, disk üzerinden tek bir bloğun okunmasını bekler. Genellikle index erişimi veya ROWID ile tekil blok okumalarında görülür; normalde beklenen bir olaydır.","cause":"Buffer cache'te bulunmayan blokların diskten okunması, seçici olmayan ya da yanlış index kullanımı, yetersiz buffer cache veya yavaş depolama katmanı.","fix":"Yüksekse en çok okuma yapan SQL'leri bulun (AWR Top SQL, v$sql). Sorguları uygun index ve doğru erişim yoluyla iyileştirin, gereksiz nested loop'ları azaltın. Buffer cache boyutunu (DB_CACHE_SIZE) değerlendirin. Depolama I/O gecikmesini kontrol edin. Bu olay çoğu zaman normaldir; anormal yüksekse SQL ayarına odaklanın.","tags":["wait","bekleme","db file sequential read","io","gç","index","indeks","single block"]},{"code":"db file scattered read","title":"Wait: çok bloklu fiziksel okuma; genellikle full table scan ya da index fast full scan","severity":"caution","meaning":"Bir oturum, birden çok bloğun (multiblock) diskten okunmasını bekler. Genellikle tam tablo taraması (full table scan) veya index fast full scan sırasında oluşur.","cause":"Uygun index bulunmaması nedeniyle full table scan, güncel olmayan istatistikler yüzünden yanlış plan, çok büyük tabloların taranması veya seçilen erişim yolunun tablo taramasına düşmesi.","fix":"Full scan yapan SQL'leri belirleyin ve gerekli index'leri ekleyin ya da mevcut index'in kullanılmasını sağlayın. İstatistikleri güncelleyin: DBMS_STATS.GATHER_TABLE_STATS. Gerçekten büyük tarama gerekiyorsa paralel sorgu veya bölümleme (partitioning) değerlendirin. DB_FILE_MULTIBLOCK_READ_COUNT ve depolama verimini gözden geçirin.","tags":["wait","bekleme","db file scattered read","full scan","tam tarama","io","gç","multiblock"]},{"code":"buffer busy waits","title":"Wait: başka bir oturumun okuduğu ya da değiştirdiği buffer üzerinde contention","severity":"caution","meaning":"Bir oturum, başka bir oturumun aynı anda okuduğu veya değiştirdiği bir buffer bloğuna erişmek için bekliyor. Bellek içi blok çekişmesidir.","cause":"Hot block'lar üzerinde yoğunlaşma, artan sıralı anahtarlı index'lerin sağ ucunda çekişme, yetersiz freelist/ASSM olmayan segmentler veya aynı bloğa yoğun eşzamanlı DML.","fix":"Hangi segment ve blok sınıfının etkilendiğini bulun (v$session, v$segment_statistics, ASH). Hot index block'ları için ters anahtarlı (reverse key) veya hash bölümlü index düşünün. ASSM (Automatic Segment Space Management) kullanın. Yüksek eşzamanlılıkta INITRANS/PCTFREE değerlerini artırın. Uygulama erişim desenini dağıtın.","tags":["wait","bekleme","buffer busy","hot block","sıcak blok","contention","çekişme"]},{"code":"gc buffer busy","title":"Wait (RAC): instance'lar arasında taşınan cache fusion block'u üzerinde contention","severity":"caution","meaning":"RAC ortamında bir oturum, başka bir örnek (instance) ile cache fusion üzerinden aktarılan ya da o örnek tarafından meşgul edilen global bir bloğa erişmek için bekliyor.","cause":"RAC düğümleri arasında aynı hot block'ların paylaşılması (cross-instance hot block), interconnect gecikmesi/darboğazı, sıralı anahtarlı index'lerde düğümler arası çekişme veya dengesiz iş yükü dağılımı.","fix":"Etkilenen segmentleri v$segment_statistics ve GV$ view'larıyla bulun. Interconnect sağlığını ve gecikmesini kontrol edin (özel, hızlı ağ). Hot index'ler için reverse key veya hash bölümleme kullanın. İş yükünü hizmet (service) bazında düğümlere ayırarak aynı blokların düğümler arası çekişmesini azaltın.","tags":["wait","bekleme","rac","gc buffer busy","cache fusion","interconnect","global"]},{"code":"library cache lock","title":"Wait: library cache nesne handle'ı üzerinde contention (parse/DDL sıralaması)","severity":"caution","meaning":"Bir oturum, library cache'teki bir nesnenin (SQL, PL/SQL, tablo tanımı) lock'unu bekliyor. Genellikle ayrıştırma (parse) ve DDL işlemlerinin seri hale gelmesiyle oluşur.","cause":"Çok kullanılan nesneler üzerinde çalışan DDL (ALTER/CREATE), sık yeniden derlenen (invalidation) PL/SQL nesneleri, aşırı hard parse, bağımlı nesnelerin geçersizleşmesi veya yoğun eşzamanlı bağlantı fırtınaları.","fix":"Engelleyen oturumu ve nesneyi bulun (v$session, ASH, gerekirse library cache lock tanılaması). Yoğun saatlerde çok kullanılan nesnelere DDL çalıştırmaktan kaçının. Bağımlılık zincirini azaltıp gereksiz yeniden derlemeleri önleyin. Bind değişkeni kullanarak hard parse'ı düşürün. Bağlantı fırtınalarını connection pool ile yumuşatın.","tags":["wait","bekleme","library cache lock","parse","ayrıştırma","ddl","hard parse"]}]},"errors/postgres.json":{"engineId":"postgres","engine":"PostgreSQL","order":2,"errors":[{"code":"23505","title":"unique_violation","severity":"caution","meaning":"Eklenen ya da güncellenen satır, bir UNIQUE constraint'ini veya primary key'i ihlal ediyor; aynı değer tabloda zaten var.","cause":"Aynı unique key ile tekrar INSERT yapılması, benzersiz sütuna mükerrer veri girilmesi, sequence değerinin manuel eklemeler yüzünden geride kalması veya eşzamanlı iki isteğin aynı anahtarı eklemesi.","fix":"Hata detayındaki constraint adı ve anahtar değeri hangi satırın çakıştığını gösterir. Var olan kaydı güncellemek için INSERT ... ON CONFLICT (sutun) DO UPDATE veya DO NOTHING kullanın. Mükerrerleri bulmak için: SELECT sutun, COUNT(*) FROM tablo GROUP BY sutun HAVING COUNT(*) > 1. Sequence geride kaldıysa: SELECT setval('seq_adi', (SELECT MAX(id) FROM tablo)).","tags":["unique","benzersiz","constraint","kısıt","duplicate","mükerrer","23505","primary key"]},{"code":"23503","title":"foreign_key_violation","severity":"caution","meaning":"Bir foreign key constraint'i ihlal edildi. Eklenen/güncellenen satırın işaret ettiği üst kayıt yok ya da silinmek istenen üst kayda bağlı alt kayıtlar var.","cause":"Var olmayan bir üst anahtara referans veren INSERT/UPDATE, hâlâ referans alınan bir üst satırı silme/güncelleme denemesi veya verilerin yanlış sırayla yüklenmesi (önce çocuk, sonra ebeveyn).","fix":"Önce ilgili üst kaydı ekleyin, sonra alt kaydı ekleyin. Silme için kaskad davranışı gerekiyorsa constraint'i ON DELETE CASCADE veya ON DELETE SET NULL ile tanımlayın. Toplu yüklemede veriyi ebeveyn-çocuk sırasına göre yükleyin. Referans veren satırları bulun: SELECT * FROM cocuk WHERE fk_sutun = deger.","tags":["foreign key","yabancı anahtar","fk","constraint","kısıt","referans","23503"]},{"code":"23502","title":"not_null_violation","severity":"caution","meaning":"NOT NULL constraint'i olan bir sütuna NULL değer eklenmeye ya da o sütun NULL yapılmaya çalışıldı.","cause":"Zorunlu bir sütunu INSERT'te atlamak, açıkça NULL atamak, sütunun varsayılan değeri (DEFAULT) olmaması veya uygulamadan boş/eksik değer gelmesi.","fix":"İlgili sütuna geçerli bir değer verin veya sütuna makul bir DEFAULT tanımlayın: ALTER TABLE tablo ALTER COLUMN sutun SET DEFAULT deger. Sütunun gerçekten zorunlu olması gerekmiyorsa constraint'i kaldırın: ALTER TABLE tablo ALTER COLUMN sutun DROP NOT NULL. Uygulama katmanında eksik veri kontrolü ekleyin.","tags":["not null","null","constraint","kısıt","zorunlu","23502","insert"]},{"code":"40P01","title":"deadlock_detected","severity":"danger","meaning":"İki veya daha fazla transaction, birbirinin tuttuğu lock'ları karşılıklı bekleyerek deadlock'a girdi. PostgreSQL döngüyü tespit edip transaction'lardan birini iptal eder.","cause":"Lock'ların farklı sıralarda alınması, aynı satırların çapraz güncellenmesi, uzun transaction'lar veya foreign key kontrolleri sırasında oluşan çakışan lock'lar.","fix":"Sunucu loglarındaki deadlock detayı çakışan sorguları gösterir. Tüm transaction'larda tablo/satırlara aynı sırada erişin. İşlemleri kısa tutun. İptal edilen transaction'ı uygulamada yakalayıp yeniden deneyin (retry). Lock'ları incelemek için pg_locks ile pg_stat_activity'yi birleştirin. Gerekirse SELECT ... FOR UPDATE ile lock sırasını belirginleştirin.","tags":["deadlock","ölümcül kilit","lock","kilit","40P01","tx","transaction"]},{"code":"40001","title":"serialization_failure","severity":"caution","meaning":"SERIALIZABLE ya da REPEATABLE READ izolasyon seviyesinde, transaction eşzamanlı değişikliklerle çakıştığı için seri hale getirilemedi ve iptal edildi. Veri tutarlılığını korumak için beklenen bir durumdur.","cause":"Aynı verilere eşzamanlı erişen işlemlerin serileştirilebilir bir sıraya oturtulamaması, yüksek eşzamanlılık altında yazma çakışmaları veya SSI (Serializable Snapshot Isolation) tarafından tespit edilen tehlikeli bağımlılıklar.","fix":"Bu bir hata değil, beklenen bir sinyaldir: işlemi olduğu gibi yeniden deneyin (retry). Uygulamaya otomatik yeniden deneme mantığı ekleyin. Çakışmaları azaltmak için transaction'ları kısaltın ve gerçekten gerekmiyorsa daha düşük izolasyon (READ COMMITTED) kullanın. Hot row'larda çekişmeyi azaltacak tasarım yapın.","tags":["serialization","serileştirme","isolation","izolasyon","retry","yeniden deneme","40001","mvcc"]},{"code":"53300","title":"too_many_connections","severity":"danger","meaning":"Sunucu, max_connections ile izin verilen en fazla eşzamanlı bağlantı sayısına ulaştı; yeni bağlantı kabul edilemiyor.","cause":"Bağlantı havuzu kullanılmaması ya da yanlış boyutlandırılması, bağlantı sızıntıları, çok sayıda kısa ömürlü bağlantı açan uygulamalar veya max_connections değerinin iş yükünün altında olması.","fix":"Bağlantı kaynağını görün: SELECT usename, state, COUNT(*) FROM pg_stat_activity GROUP BY 1,2. Uzun süredir boşta kalan istemci bağlantılarını hedefli olarak sonlandırın (filtresiz toplu sonlandırma tüm uygulamaları ve havuzları etkiler): SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE state = 'idle' AND backend_type = 'client backend' AND usename = 'uygulama_kullanici' AND state_change < now() - interval '10 minutes' AND pid <> pg_backend_pid(). Asıl çözüm PgBouncer gibi bir bağlantı havuzu kullanmaktır. max_connections'ı artırmak bellek maliyetlidir; havuzlamayı tercih edin. superuser için ayrılan bağlantılar sayesinde yönetim erişimi kalır.","tags":["connection","bağlantı","max_connections","too many","53300","pool","havuz","pgbouncer"]},{"code":"53100","title":"disk_full","severity":"danger","meaning":"Sunucu bir dosyaya yazamadı çünkü disk dolu. Veri dizini, WAL ya da geçici dosyaların bulunduğu diskte alan kalmadı.","cause":"Veri büyümesi, kontrol edilmeyen WAL birikmesi (arşivleme/replikasyon slot'u geride kalması), büyük geçici dosyalar (dev sıralamalar), log dosyalarının şişmesi veya table/index bloat.","fix":"Disk kullanımını inceleyin ve gereksiz dosyaları temizleyin. WAL birikmesine bakın: pg_stat_replication ve pg_replication_slots (kullanılmayan slot'ları drop edin, geride kalanlar WAL'ı tutar). Disk doluyken VACUUM FULL veya REINDEX çalıştırmayın: tabloyu yeniden yazdıkları için tablo boyutu kadar ek alan gerektirir ve durumu kötüleştirebilir; normal VACUUM da alanı işletim sistemine (neredeyse) geri vermez. pg_wal dizinindeki dosyaları ASLA elle silmeyin. Önce WAL/slot, log ve temp kaynağını çözüp alan açın; log ve temp yerleşimini gözden geçirin. Kalıcı çözüm için disk kapasitesini artırın ve izleme/uyarı kurun.","tags":["disk","alan","space","full","dolu","wal","53100","vacuum"]},{"code":"57014","title":"query_canceled","severity":"safe","meaning":"Sorgu iptal edildi. Genellikle statement_timeout süresinin dolması ya da kullanıcının veya istemcinin iptali (pg_cancel_backend, sürücü iptali) nedeniyle oluşur.","cause":"statement_timeout aşımı, pg_cancel_backend ile iptal veya uygulama/istemci tarafından gönderilen iptal isteği. Benzer durumların farklı kodları vardır: lock_timeout aşımı 55P03, idle_in_transaction_session_timeout 25P03 (FATAL), hot standby'da replikasyon çakışmasıyla iptal 40001 (bazı durumlarda 40P01) döner.","fix":"Sorgu gerçekten uzun sürüyorsa iyileştirin (EXPLAIN ANALYZE, index, plan). Zaman aşımı çok düşükse ilgili oturum/rol için statement_timeout değerini ayarlayın. Kasıtlı iptallerde ek işlem gerekmez. Lock ve standby çakışması kaynaklı iptaller için 55P03 ve 40001 kayıtlarına bakın.","tags":["cancel","iptal","timeout","zaman aşımı","statement_timeout","57014","standby"]},{"code":"42P01","title":"undefined_table","severity":"caution","meaning":"Sorguda başvurulan tablo (ya da view) mevcut değil veya arama yolunda (search_path) bulunamıyor.","cause":"Tablonun gerçekten olmaması, yanlış şemada bulunup search_path'te olmaması, tablo adında yazım/harf hatası, tırnaklı tanımlayıcılarda büyük-küçük harf uyuşmazlığı veya nesnenin henüz oluşturulmamış/silinmiş olması.","fix":"Tablonun varlığını ve şemasını doğrulayın: SELECT schemaname, tablename FROM pg_tables WHERE tablename = 'tablo'. Farklı şemadaysa şema.tablo şeklinde nitelendirin ya da search_path'i ayarlayın: SET search_path TO sema, public. Tırnaksız tanımlayıcıların küçük harfe çevrildiğini unutmayın; oluşturulurken tırnak kullanıldıysa aynı biçimde çağırın.","tags":["table","tablo","undefined","42P01","search_path","schema","şema"]},{"code":"42703","title":"undefined_column","severity":"caution","meaning":"Sorguda başvurulan sütun, ilgili tabloda ya da geçerli kapsamda mevcut değil.","cause":"Sütun adında yazım hatası, sütunun silinmiş/yeniden adlandırılmış olması, yanlış tabloya referans, tırnaklı tanımlayıcı büyük-küçük harf uyuşmazlığı veya birden çok tablolu sorguda belirsiz/yanlış nitelendirme.","fix":"Sütunları listeleyin: \\d tablo veya SELECT column_name FROM information_schema.columns WHERE table_name = 'tablo'. Adı ve doğru tabloyu düzeltin, JOIN'lerde sütunu tablo.sutun biçiminde nitelendirin. Oluşturulurken tırnak kullanıldıysa aynı büyük-küçük harfle çağırın.","tags":["column","sütun","undefined","42703","yazım","typo","schema"]},{"code":"42501","title":"insufficient_privilege","severity":"caution","meaning":"Rol, yapmaya çalıştığı işlem için gerekli ayrıcalığa (privilege) sahip değil.","cause":"Tablo/şema/veritabanı üzerinde gerekli GRANT'in verilmemiş olması, şema üzerinde USAGE eksikliği, nesnenin farklı bir role ait olması veya satır güvenliği (RLS) politikalarının erişimi engellemesi.","fix":"Eksik ayrıcalığı verin: GRANT SELECT, INSERT ON tablo TO rol; şema için GRANT USAGE ON SCHEMA sema TO rol. Toplu için GRANT ... ON ALL TABLES IN SCHEMA ve gelecekteki nesneler için ALTER DEFAULT PRIVILEGES kullanın. Mevcut yetkileri görün: \\dp tablo. RLS aktifse ilgili policy'leri inceleyin.","tags":["privilege","ayrıcalık","yetki","grant","42501","izin","rls"]},{"code":"28P01","title":"invalid_password","severity":"caution","meaning":"Kimlik doğrulama sırasında verilen parola yanlış; rol için oturum açma reddedildi.","cause":"Hatalı parola, parolanın değişmiş olması, uygulama bağlantı dizesindeki kimlik bilgisinin eskimesi veya pg_hba.conf'ta beklenen kimlik doğrulama yöntemiyle (scram-sha-256, md5) uyumsuzluk.","fix":"Parolayı doğrulayın; gerekirse sıfırlayın: ALTER ROLE rol WITH PASSWORD 'yeni_parola'. pg_hba.conf'taki yöntemin istemciyle uyumlu olduğundan emin olun (eski istemciler scram-sha-256 ile sorun yaşayabilir). Değişiklik sonrası SELECT pg_reload_conf() ile yapılandırmayı yeniden yükleyin.","tags":["auth","kimlik","parola","password","28P01","scram","md5","hba"]},{"code":"08006","title":"connection_failure","severity":"danger","meaning":"İstemci ile sunucu arasındaki bağlantı kurulamadı veya beklenmedik biçimde koptu.","cause":"Sunucunun çalışmaması ya da yeniden başlaması, ağ/güvenlik duvarı sorunları, yanlış host/port, listen_addresses ayarının erişime kapalı olması, boşta bağlantının ağ tarafından düşürülmesi veya sunucunun aşırı yüklenmesi.","fix":"Sunucunun ayakta olduğunu ve doğru host/port dinlediğini kontrol edin (pg_isready host port). postgresql.conf'ta listen_addresses ve pg_hba.conf erişim kurallarını doğrulayın. Ağ/güvenlik duvarı ve DNS ayarlarını kontrol edin. Bağlantı havuzunda TCP keepalive ve zaman aşımı ayarlarını gözden geçirin. Sunucu loglarında çökme/yeniden başlatma izlerine bakın.","tags":["connection","bağlantı","network","ağ","08006","failure","kopma"]},{"code":"55P03","title":"lock_not_available","severity":"caution","meaning":"İstenen lock hemen alınamadı. Genellikle NOWAIT ile lock istenip başkasının o lock'u tutması ya da lock_timeout süresinin dolması sonucu oluşur.","cause":"SELECT ... FOR UPDATE NOWAIT veya LOCK TABLE ... NOWAIT kullanımı sırasında satır/tablonun kilitli olması; ya da lock_timeout değerinin dolması. Çoğu zaman lock'u tutan uzun bir transaction vardır.","fix":"Engelleyen oturumu bulun: pg_locks ve pg_stat_activity'yi birleştirin (waiting/blocking ilişkisi). Uzun transaction'ı bitirin veya gerekirse pg_terminate_backend(pid) ile sonlandırın. NOWAIT yerine makul bir lock_timeout ile bekleyip yeniden deneme mantığı kurun. Transaction'ları kısaltarak lock tutma süresini azaltın.","tags":["lock","kilit","nowait","lock_timeout","55P03","not available","meşgul"]},{"code":"54000","title":"program_limit_exceeded","severity":"caution","meaning":"PostgreSQL'in bir uygulama/format sınırı aşıldı; örneğin bir satırın ya da alanın izin verilen en büyük boyutu, index satır boyutu ya da sorgudaki parametre/sütun sayısı sınırı.","cause":"Çok büyük bir değerin (örn. 1 GB'ı aşan alan) saklanmaya çalışılması, indekslenen değerin B-tree sayfa sınırını (yaklaşık 2704 bayt) aşması, aşırı çok sütun ya da sorgu parametresi kullanılması.","fix":"Aşılan sınırı belirleyin (mesaj genelde neyin aşıldığını söyler). Çok büyük metin/veri için yapıyı gözden geçirin ya da parçalayın. Uzun metin sütunlarını B-tree yerine hash index ya da ifade/parçalı index ile indeksleyin. Sorgudaki parametre/sütun sayısını azaltın veya toplu işlemi bölün.","tags":["limit","sınır","program_limit","54000","index size","boyut","row size"]},{"code":"22001","title":"string_data_right_truncation","severity":"caution","meaning":"Bir metnin uzunluğu, hedef sütunun tanımlı uzunluğunu (örn. VARCHAR(n)) aştığı için değer kesilecekti; PostgreSQL bunu reddeder ve hata verir.","cause":"VARCHAR(n)/CHAR(n) sütuna, n'den uzun bir metin eklenmesi veya güncellenmesi; uygulama tarafında beklenenden uzun veri gelmesi ya da sütun uzunluğunun ihtiyaca göre dar tanımlanması.","fix":"Ekleyeceğiniz değeri sütuna sığacak şekilde kısaltın veya sütun uzunluğunu artırın: ALTER TABLE tablo ALTER COLUMN sutun TYPE VARCHAR(500). Sınırsız metin gerekiyorsa TEXT türünü kullanın. Uygulamada uzunluk doğrulaması yapın. Bilinçli kısaltma istiyorsanız açıkça LEFT(deger, n) uygulayın.","tags":["truncation","kesilme","varchar","string","metin","22001","length","uzunluk"]},{"code":"25P02","title":"in_failed_sql_transaction","severity":"caution","meaning":"Transaction içinde daha önce bir hata oluştu; bu transaction'da artık hiçbir komut çalıştırılamaz. Transaction iptal (abort) durumundadır ve yalnızca ROLLBACK kabul edilir.","cause":"Bir transaction bloğunda önceki bir ifadenin hata vermesi (örn. constraint ihlali) ve buna rağmen aynı işlemde yeni komutlar gönderilmeye devam edilmesi. Uygulamanın hatayı yakalamayıp işleme devam etmesi.","fix":"Transaction'ı geri alın: ROLLBACK, sonra yeniden başlatın. Bir bloğun hatasını izole edip devam etmek istiyorsanız SAVEPOINT kullanıp ROLLBACK TO SAVEPOINT ile o noktaya dönün. Uygulamada her ifadenin hatasını yakalayıp transaction'ı doğru yönetin (commit/rollback kararını netleştirin).","tags":["transaction","işlem","aborted","iptal","25P02","rollback","savepoint"]},{"code":"53200","title":"out_of_memory","severity":"danger","meaning":"Sunucu bir işlem için gereken belleği ayıramadı. Bir backend süreci ya da tüm sunucu bellek baskısı altında.","cause":"work_mem/maintenance_work_mem değerlerinin çok yüksek ayarlanıp yüksek eşzamanlılıkla çarpılması, tek sorguda çok fazla hash/sıralama işlemi, aşırı bağlantı sayısı, bellek sızıntısı ya da işletim sistemi OOM killer baskısı.","fix":"Sunucu loglarındaki bellek bağlamına ve OOM killer izlerine bakın. work_mem'i sorgu ve eşzamanlılık sayısını hesaba katarak makul ayarlayın (her sıralama/hash başına ayrı ayrılır). Bağlantı sayısını havuzlama ile sınırlayın. İşletim sistemi bellek/overcommit ayarlarını gözden geçirin. Ağır sorguları optimize edip bellek gereksinimini düşürün.","tags":["memory","bellek","out of memory","53200","work_mem","oom"]}]},"errors/mysql.json":{"engineId":"mysql","engine":"MySQL","order":3,"errors":[{"code":"1045","title":"Access denied for user (using password: YES/NO)","severity":"caution","meaning":"Kullanıcı adı, parola ya da bağlandığınız host için yetkilendirme başarısız oldu; giriş reddedildi.","cause":"Yanlış parola, kullanıcının bağlandığı host'tan (user@host) yetkisinin olmaması, hesabın var olmaması, kimlik doğrulama eklentisi uyuşmazlığı (caching_sha2_password vs mysql_native_password) veya bağlantı dizesindeki kimlik bilgilerinin eskimesi.","fix":"Kullanıcı ve host eşleşmesini kontrol edin: SELECT user, host, plugin FROM mysql.user. Doğru host için yetki verin (örn. 'kullanici'@'%'). Parolayı sıfırlayın: ALTER USER 'kullanici'@'host' IDENTIFIED BY 'yeni_parola'; (ALTER USER/GRANT anında etkilidir; FLUSH PRIVILEGES yalnızca grant tablolarına doğrudan DML yapıldıysa gerekir). 'using password: NO' görüyorsanız istemci parolayı hiç göndermiyor demektir. Eklenti uyumsuzluğunda kimlik doğrulama eklentisini gözden geçirin: MySQL 8.4'te mysql_native_password eklentisi varsayılan olarak devre dışıdır (yalnızca --mysql-native-password=ON ile yüklenir); bu eklentiyi kullanan eski hesaplar ve eski istemciler bağlanamaz. Hesabı ALTER USER ... IDENTIFIED WITH caching_sha2_password BY '...'; ile taşıyın ve istemci sürücüsünü güncelleyin.","tags":["auth","kimlik","access denied","erişim","parola","password","1045","yetki"]},{"code":"1062","title":"Duplicate entry for key","severity":"caution","meaning":"Eklenen ya da güncellenen satır, bir UNIQUE index'i veya PRIMARY KEY'i ihlal ediyor; aynı anahtar değeri zaten var.","cause":"Aynı unique key ile tekrar INSERT, mükerrer veri girişi, AUTO_INCREMENT sayacının geride kalması veya var olan bir tabloya benzersiz index eklerken zaten mükerrer bulunan satırlar.","fix":"Hata mesajı çakışan anahtar değerini ve index adını gösterir. Var olan kaydı güncellemek için INSERT ... ON DUPLICATE KEY UPDATE veya INSERT IGNORE / REPLACE değerlendirin. Mükerrerleri bulun: SELECT sutun, COUNT(*) FROM tablo GROUP BY sutun HAVING COUNT(*) > 1. Benzersiz index ekleyemiyorsanız önce mükerrerleri temizleyin.","tags":["duplicate","mükerrer","unique","benzersiz","1062","primary key","insert"]},{"code":"1213","title":"Deadlock found when trying to get lock; try restarting transaction","severity":"danger","meaning":"InnoDB, iki veya daha fazla transaction'ın birbirinin lock'unu beklediği deadlock'u tespit etti ve transaction'lardan birini geri alarak döngüyü kırdı.","cause":"Row lock'larının farklı sıralarda alınması, aynı satırların çapraz güncellenmesi, index eksikliği nedeniyle geniş satır aralıklarının (gap lock) kilitlenmesi veya foreign key kontrolleri sırasında oluşan çakışmalar.","fix":"Son deadlock ayrıntısını görün: SHOW ENGINE INNODB STATUS (LATEST DETECTED DEADLOCK bölümü). Tüm transaction'larda satır/tablolara aynı sırada erişin, transaction'ları kısaltın. Uygun index'ler ekleyerek kilitlenen aralığı daraltın. İptal edilen transaction'ı uygulamada yakalayıp yeniden deneyin (retry mantığı).","tags":["deadlock","ölümcül kilit","lock","kilit","innodb","1213","tx","transaction"]},{"code":"1205","title":"Lock wait timeout exceeded; try restarting transaction","severity":"danger","meaning":"Bir transaction, ihtiyaç duyduğu row lock'u innodb_lock_wait_timeout süresi boyunca bekledi ama alamadı ve zaman aşımına uğradı.","cause":"Lock'u uzun süre tutan, commit ya da rollback edilmeyen başka bir transaction; boşta (idle) kalan açık transaction'lar, uzun süren toplu güncellemeler veya çekişmeli hot row'lar.","fix":"Engelleyen transaction'ı bulun: performance_schema.data_lock_waits ile data_locks'u birleştirin (eski sürümlerde information_schema.innodb_lock_waits/innodb_trx). Engelleyen transaction'ı commit/rollback edin veya gerekirse KILL <trx_mysql_thread_id> ile sonlandırın. Transaction'ları kısaltın, boşta transaction bırakmayın (autocommit/uygulama mantığı). Gerekirse innodb_lock_wait_timeout değerini iş yüküne göre ayarlayın.","tags":["lock","kilit","timeout","zaman aşımı","innodb","1205","wait","bekleme"]},{"code":"1040","title":"Too many connections","severity":"danger","meaning":"Sunucu, max_connections ile izin verilen en fazla eşzamanlı bağlantı sayısına ulaştı; yeni bağlantılar reddediliyor.","cause":"Bağlantı havuzunun yanlış boyutlandırılması, bağlantı sızıntıları, çok sayıda kısa ömürlü bağlantı, uzun süre uyuyan (Sleep) bağlantılar veya max_connections değerinin iş yükünün altında kalması.","fix":"Bağlantıları inceleyin: SHOW PROCESSLIST veya SELECT * FROM performance_schema.processlist. Uyuyan gereksiz bağlantıları KILL ile kapatın. max_connections'ı artırın: SET GLOBAL max_connections = 500 (kalıcı için my.cnf). Kök çözüm bağlantı havuzu kullanmak ve wait_timeout ile boşta bağlantıları kapatmaktır. SUPER/CONNECTION_ADMIN yetkisiyle acil yönetim bağlantısı ayrılıdır.","tags":["connection","bağlantı","too many","max_connections","1040","pool","havuz"]},{"code":"1064","title":"You have an error in your SQL syntax","severity":"safe","meaning":"SQL ifadesinde sözdizimi (syntax) hatası var; sunucu ifadeyi ayrıştıramadı. Mesaj hatanın yakınındaki metni gösterir.","cause":"Yazım hatası, eksik/fazla virgül veya parantez, ayrılmış sözcüğün (reserved word) tırnaksız sütun/tablo adı olarak kullanılması, MySQL sürümünün desteklemediği söz dizimi veya tırnak/kaçış hataları.","fix":"Mesajdaki 'near ...' ifadesi hatanın başladığı yeri gösterir; hemen öncesine bakın. Ayrılmış sözcükleri ters tırnak ile kullanın: `order`, `group`. Parantez ve virgülleri dengeleyin. Sürüme uygun söz dizimi kullandığınızı doğrulayın. Dinamik SQL üretiyorsanız oluşan tam sorguyu loglayıp inceleyin.","tags":["syntax","sözdizimi","1064","parse","ayrıştırma","reserved word","ayrılmış sözcük"]},{"code":"1146","title":"Table doesn't exist","severity":"caution","meaning":"Sorguda başvurulan tablo mevcut değil ya da geçerli veritabanında bulunamıyor.","cause":"Tablonun gerçekten olmaması, yanlış veritabanının seçili olması, tablo adında yazım hatası, Linux'ta tablo adı büyük-küçük harf duyarlılığı (lower_case_table_names) veya InnoDB tablo dosyasının (.ibd) eksik/bozuk olması (5.7 ve öncesinde ayrıca .frm tanım dosyası; 8.0'da tanımlar veri sözlüğündedir).","fix":"Tabloyu doğrulayın: SHOW TABLES; ve doğru veritabanını seçin: USE veritabani. Büyük-küçük harf duyarlılığına dikkat edin (özellikle Linux). Tablo adını ve şemayı SELECT ... FROM information_schema.tables ile kontrol edin. InnoDB dosya sorunu varsa geri yükleme/onarım gerekebilir.","tags":["table","tablo","doesn't exist","yok","1146","schema","veritabanı"]},{"code":"1054","title":"Unknown column in field list","severity":"caution","meaning":"Sorguda başvurulan sütun, ilgili tabloda ya da geçerli kapsamda mevcut değil.","cause":"Sütun adında yazım hatası, sütunun silinmiş/yeniden adlandırılmış olması, yanlış tabloya referans, JOIN'de belirsiz/yanlış nitelendirme veya metin değerin tırnaksız yazılıp sütun sanılması (WHERE ad = deger yerine WHERE ad = 'deger').","fix":"Sütunları listeleyin: SHOW COLUMNS FROM tablo veya DESCRIBE tablo. Sütun adını düzeltin ve JOIN'lerde tablo.sutun biçiminde nitelendirin. Metin sabitlerini tek tırnak içine alın; ters tırnak yalnızca tanımlayıcılar içindir. information_schema.columns ile kontrol edebilirsiniz.","tags":["column","sütun","unknown","bilinmeyen","1054","typo","yazım"]},{"code":"2002","title":"Can't connect to local MySQL server through socket","severity":"danger","meaning":"İstemci, yerel MySQL sunucusuna Unix soketi üzerinden bağlanamadı. Genellikle sunucu çalışmıyor veya soket yolu yanlış.","cause":"MySQL/MariaDB servisinin çalışmaması ya da çökmesi, socket dosyası yolunun (örn. /var/run/mysqld/mysqld.sock) istemci ve sunucuda farklı olması, izin sorunları veya sunucunun başlamamış olması.","fix":"Servisin durumunu kontrol edin ve başlatın (systemctl status mysql / start mysql). Doğru soket yolunu doğrulayın: SHOW VARIABLES LIKE 'socket' ve my.cnf'teki socket ayarı. Yol farklıysa --socket ile açıkça belirtin ya da TCP kullanın: mysql -h 127.0.0.1 -P 3306. Sunucu loglarında başlatma/çökme hatalarına bakın.","tags":["connection","bağlantı","socket","soket","2002","server","local","yerel"]},{"code":"2003","title":"Can't connect to MySQL server (TCP/IP)","severity":"danger","meaning":"İstemci, MySQL sunucusuna belirtilen host ve port üzerinden TCP/IP ile bağlanamadı.","cause":"Sunucunun çalışmaması, yanlış host/port, güvenlik duvarının 3306 portunu engellemesi, sunucunun yalnızca localhost'a bağlanması (bind-address = 127.0.0.1) veya skip-networking'in açık olması.","fix":"Sunucunun ayakta ve doğru portu dinlediğini kontrol edin. Uzaktan erişim için my.cnf'te bind-address = 0.0.0.0 (ya da uygun IP) yapın ve skip-networking kapalı olsun. Güvenlik duvarında 3306 portunu açın. Host/port bilgisini doğrulayın: mysql -h host -P 3306 -u kullanici -p. Kullanıcının uzak host'tan yetkisi olduğundan emin olun.","tags":["connection","bağlantı","tcp","port","2003","network","ağ","bind-address"]},{"code":"2006","title":"MySQL server has gone away","severity":"caution","meaning":"İstemci ile sunucu arasındaki bağlantı, komut sırasında koptu. Sunucu bağlantıyı kapatmış veya paket reddedilmiş olabilir.","cause":"wait_timeout/interactive_timeout dolduğu için boşta bağlantının kapatılması, max_allowed_packet'ten büyük bir sorgu/veri gönderilmesi, sunucunun yeniden başlaması ya da çökmesi veya ağ kesintisi.","fix":"Boşta bağlantı sorunuysa bağlantı havuzunda doğrulama (validation) kullanın ve wait_timeout değerini gözden geçirin. Büyük veri gönderiyorsanız max_allowed_packet değerini artırın (örn. SET GLOBAL max_allowed_packet = 64*1024*1024, kalıcı için my.cnf). Sunucu loglarında yeniden başlatma/çökme ve OOM izlerine bakın. Uygulamada koptuğunda yeniden bağlanma mantığı ekleyin.","tags":["connection","bağlantı","gone away","kopma","2006","timeout","max_allowed_packet"]},{"code":"1114","title":"The table is full","severity":"danger","meaning":"Tabloya daha fazla veri yazılamıyor çünkü bir depolama sınırına ya da alan sonuna ulaşıldı.","cause":"Disk alanının dolması, MEMORY tablolarında max_heap_table_size sınırına ulaşılması, geçici tablolarda tmp_table_size aşımı, innodb_data_file_path ile sabit boyutlu tablespace'in dolması veya dosya sistemi/tabloya özgü boyut sınırları.","fix":"Öncelikle disk boş alanını kontrol edin ve boşaltın. MEMORY/temp tabloları için max_heap_table_size ve tmp_table_size değerlerini artırın. InnoDB için innodb_data_file_path'in autoextend olduğundan emin olun ya da alan ekleyin. Büyük geçici sonuçları diske alan işlemlerde sorguyu optimize edin. Kalıcı çözüm için depolama kapasitesini artırın.","tags":["table full","tablo dolu","disk","alan","1114","space","memory","innodb"]},{"code":"1215","title":"Cannot add foreign key constraint","severity":"caution","meaning":"Tanımlanmak istenen foreign key constraint'i oluşturulamıyor; MySQL constraint'i ekleyemiyor.","cause":"Ana ve referans sütunların veri türü/uzunluk/işaret (signed-unsigned) ya da karakter kümesi/collation uyuşmazlığı, referans edilen sütunda uygun bir index/PRIMARY KEY olmaması, tabloların farklı depolama motoru (biri MyISAM) kullanması veya referans tablonun henüz olmaması.","fix":"İki tarafın sütun türlerinin BİREBİR aynı olduğundan emin olun (örn. ikisi de INT UNSIGNED). Referans edilen sütunun bir index ile (genelde PRIMARY KEY veya UNIQUE) desteklendiğini doğrulayın. Her iki tablonun da InnoDB olduğundan emin olun. String anahtarlarda aynı charset/collation kullanın. Ayrıntı için: SHOW ENGINE INNODB STATUS (LATEST FOREIGN KEY ERROR).","tags":["foreign key","yabancı anahtar","fk","1215","constraint","kısıt","innodb","tür"]},{"code":"1451","title":"Cannot delete or update a parent row: a foreign key constraint fails","severity":"caution","meaning":"Bir üst (parent) satırı silmeye ya da anahtarını değiştirmeye çalıştınız, ancak ona bağlı alt (child) satırlar bulunduğu için foreign key constraint'i buna izin vermiyor.","cause":"Referans alınan üst satırın hâlâ çocuk kayıtlara sahip olması ve constraint'in ON DELETE/UPDATE için RESTRICT/NO ACTION davranışında olması.","fix":"Önce bağlı alt kayıtları silin ya da başka bir üst kayda taşıyın, sonra üst satırı silin. Otomatik davranış istiyorsanız constraint'i ON DELETE CASCADE veya ON DELETE SET NULL ile yeniden tanımlayın. Bağlı satırları bulun: SELECT * FROM cocuk_tablo WHERE fk_sutun = deger.","tags":["foreign key","yabancı anahtar","fk","1451","parent","üst","delete","referans"]},{"code":"1452","title":"Cannot add or update a child row: a foreign key constraint fails","severity":"caution","meaning":"Bir alt (child) satırı ekliyor ya da güncelliyorsunuz, ama işaret ettiği üst (parent) anahtar değeri referans tabloda yok; foreign key constraint'i reddediyor.","cause":"Var olmayan bir üst anahtara referans veren INSERT/UPDATE, verilerin yanlış sırayla yüklenmesi (önce çocuk) veya üst kaydın silinmiş olması.","fix":"Önce ilgili üst kaydı ekleyin, sonra alt kaydı ekleyin. Referans değerinin var olduğunu doğrulayın: SELECT * FROM ust_tablo WHERE anahtar = deger. Toplu yüklemede ebeveyn-çocuk sırasını koruyun. Yalnızca kontrollü bakım işlemlerinde SET FOREIGN_KEY_CHECKS=0 kullanın ve iş bitince tekrar 1 yapın.","tags":["foreign key","yabancı anahtar","fk","1452","child","alt","referans","insert"]},{"code":"1366","title":"Incorrect string/integer value for column","severity":"caution","meaning":"Bir sütuna, o sütunun türü ya da karakter kümesiyle uyumsuz bir değer eklenmeye çalışıldı. Genellikle karakter kodlaması ya da tür uyuşmazlığı kaynaklıdır.","cause":"Sütun latin1 iken 4 baytlık emoji/karakter (utf8mb4) yazılması, sayısal sütuna sayı olmayan metin girilmesi, yanlış connection charset'i veya beklenenden farklı türde değer gönderilmesi.","fix":"Karakter sorununda sütunu/tabloyu utf8mb4 yapın: ALTER TABLE tablo CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ve bağlantı charset'ini utf8mb4 ayarlayın. Sayısal alanlarda uygulama tarafında tür doğrulaması yapın. Sunucunun katı SQL modunda (STRICT) çalıştığını unutmayın; kök neden verinin türü/kodlamasıdır.","tags":["charset","karakter","incorrect value","1366","utf8mb4","encoding","tür","collation"]},{"code":"1044","title":"Access denied for user to database","severity":"caution","meaning":"Kullanıcı doğru kimlik doğrulasa da, belirtilen veritabanı üzerinde işlem yapma yetkisine sahip değil.","cause":"Kullanıcıya ilgili veritabanı için GRANT verilmemiş olması, yanlış veritabanı adı, yetkinin farklı bir host (user@host) için tanımlı olması veya veritabanının olmaması.","fix":"Kullanıcının yetkilerini görün: SHOW GRANTS FOR 'kullanici'@'host'. Gerekli yetkiyi verin: GRANT ALL PRIVILEGES ON veritabani.* TO 'kullanici'@'host'; (GRANT anında etkilidir, FLUSH PRIVILEGES gerekmez). Doğru host eşleşmesini ve veritabanı adını doğrulayın. En az ayrıcalık ilkesiyle yalnızca gereken hakları verin.","tags":["access denied","erişim","database","veritabanı","1044","grant","yetki","izin"]},{"code":"1264","title":"Out of range value for column","severity":"caution","meaning":"Bir sayısal ya da tarih sütununa, o türün izin verdiği aralığın dışında bir değer eklenmeye çalışıldı. Katı SQL modunda bu hata verilir.","cause":"TINYINT/INT gibi türlerin sınırının aşılması (örn. TINYINT'e 200 veya negatif değerin UNSIGNED sütuna girilmesi), tarih/sayı taşması ya da beklenenden büyük değerin gönderilmesi.","fix":"Sütun türünü ihtiyaca göre büyütün (örn. TINYINT yerine INT, INT yerine BIGINT) ya da işaret ayarını (SIGNED/UNSIGNED) düzeltin. Uygulamada değer aralığı doğrulaması yapın. Sessiz kırpma davranışı istiyorsanız (önerilmez) sql_mode'dan STRICT kaldırmak yerine veriyi türle uyumlu hale getirin.","tags":["out of range","aralık dışı","1264","değer","int","tinyint","unsigned","taşma"]}]},"errors/mssql.json":{"engineId":"mssql","engine":"SQL Server","order":4,"errors":[{"code":"1205","title":"Transaction (Process ID) was deadlocked on lock resources with another process and has been chosen as the deadlock victim","severity":"danger","meaning":"İki veya daha fazla transaction birbirinin tuttuğu lock'ları karşılıklı beklerken kilitlenir (deadlock). SQL Server bu döngüyü kırmak için transaction'lardan birini kurban seçip geri alır (rollback).","cause":"Transaction'ların tabloları/satırları farklı sıralarda kilitlemesi, uzun süren transaction'lar, eksik index'ler yüzünden geniş taramalar, lock escalation ve yüksek eşzamanlılık tipik nedenlerdir.","fix":"Uygulamada 1205 hatasını yakalayıp işlemi otomatik yeniden deneyin (retry). Tüm transaction'larda nesnelere aynı sırada erişin, transaction'ları kısa tutun. Deadlock grafiğini inceleyin: Extended Events (system_health oturumu) veya trace flag 1222 ile ayrıntıyı görün. Uygun index ekleyerek tarama ve kilitlenmeyi azaltın. Gerekirse READ COMMITTED SNAPSHOT (RCSI) yalıtım düzeyini değerlendirin.","tags":["deadlock","lock","kilit","victim","rollback","1205","retry"]},{"code":"2627","title":"Violation of PRIMARY KEY / UNIQUE KEY constraint. Cannot insert duplicate key in object","severity":"caution","meaning":"Bir PRIMARY KEY veya UNIQUE constraint tarafından korunan sütun(lar)a, zaten var olan bir değer eklemeye/güncellemeye çalıştınız. Duplicate key kabul edilmez.","cause":"Aynı benzersiz değerin ikinci kez INSERT edilmesi, UPDATE ile mevcut bir değere çakışma, eksik benzersizlik kontrolü veya eşzamanlı iki isteğin aynı kaydı üretmesi.","fix":"Eklemeden önce kaydın var olup olmadığını kontrol edin veya MERGE / IF NOT EXISTS kullanın. Idempotent ekleme için \"INSERT ... WHERE NOT EXISTS\" kalıbını uygulayın. Hatayı yakalayıp anlamlı mesaj döndürün. Gerçekten yinelenen veri hedefliyorsanız constraint'i gözden geçirin. Kimlik üretiminde çakışmayı önlemek için IDENTITY veya SEQUENCE kullanın.","tags":["unique","primary key","benzersiz","duplicate","constraint","kisit","2627"]},{"code":"2601","title":"Cannot insert duplicate key row in object with unique index. The duplicate key value is ...","severity":"caution","meaning":"Benzersiz bir index (UNIQUE INDEX) duplicate key değeri nedeniyle satır eklenmesine izin vermedi. 2627 constraint için, 2601 ise benzersiz index için üretilir.","cause":"UNIQUE INDEX ile korunan sütun(lar)a mevcut değerin tekrar yazılması, eşzamanlı eklemeler veya filtrelenmiş benzersiz index'in kapsadığı satırlarda çakışma.","fix":"Yinelenen değeri kaldırın veya güncelleyin. Yinelenenleri tolere etmeniz gerekiyorsa IGNORE_DUP_KEY = ON seçeneğini değerlendirin (yinelenenler sessizce atlanır). Ekleme öncesi NOT EXISTS kontrolü ekleyin. Filtrelenmiş index varsa WHERE koşulunu ve çakışmayı doğrulayın.","tags":["unique index","duplicate key","benzersiz indeks","yinelenen","2601","index"]},{"code":"547","title":"The INSERT/UPDATE/DELETE statement conflicted with the FOREIGN KEY / CHECK constraint","severity":"caution","meaning":"İşlem bir FOREIGN KEY veya CHECK constraint'ini ihlal etti. Ya var olmayan bir üst kayda referans verildi ya da bir CHECK kuralına uymayan değer yazıldı ya da hâlâ referans verilen bir üst kayıt silinmeye çalışıldı.","cause":"FK: eklenen alt satırın işaret ettiği üst kayıt yok. DELETE/UPDATE: silinmek/değişmek istenen üst satıra bağlı alt satırlar var. CHECK: sütun değeri tanımlı koşulu sağlamıyor.","fix":"Önce ilgili üst (parent) kaydı ekleyin, sonra alt kaydı ekleyin. Silme için önce bağımlı satırları temizleyin veya uygunsa ON DELETE CASCADE tanımlayın. CHECK ihlalinde değeri kurala uygun hâle getirin. Hangi constraint'in ihlal edildiğini hata metnindeki constraint adından belirleyin.","tags":["foreign key","yabanci anahtar","check","constraint","kisit","referential","547"]},{"code":"18456","title":"Login failed for user","severity":"danger","meaning":"Bir oturum açma girişimi kimlik doğrulama aşamasında reddedildi. Kullanıcı adı/parola hatalı olabilir, hesap devre dışı olabilir veya kullanıcının o veritabanına erişimi olmayabilir.","cause":"Yanlış parola, var olmayan login, devre dışı/kilitli hesap, yalnızca Windows kimlik doğrulaması açıkken SQL login kullanımı, varsayılan veritabanına erişim yokluğu. Hata metnindeki State kodu asıl nedeni belirtir (State 5: login yok, State 7: login devre dışı ve parola da yanlış, State 8: parola yanlış (en sık), State 18: parola değiştirilmeli, State 38: belirtilen veritabanı açılamıyor, State 58: sunucu yalnızca Windows kimlik doğrulamasında iken SQL login denemesi).","fix":"SQL Server error log'undaki State değerine bakarak kök nedeni bulun (istemciye güvenlik için ayrıntı verilmez). Kullanıcı adı/parolayı doğrulayın. Sunucunun 'SQL Server and Windows Authentication Mode' (mixed mode) ile çalıştığını kontrol edin; değiştirdiyseniz servisi yeniden başlatın. Login'in ilgili veritabanında kullanıcı eşlemesi ve erişim iznini doğrulayın.","tags":["login","oturum","authentication","kimlik dogrulama","parola","18456","state"]},{"code":"8152","title":"String or binary data would be truncated","severity":"caution","meaning":"Bir sütuna, o sütunun tanımlı uzunluğundan daha uzun veri yazmaya çalıştınız. SQL Server veri kaybını önlemek için işlemi durdurur (2628 aynı durumun yeni, sütun/değer bilgisi veren sürümüdür).","cause":"Örneğin VARCHAR(10) sütuna 15 karakter yazmak, hedef sütunun kaynaktan dar olması, veri tipi/uzunluk uyumsuzluğu, ETL/aktarımda alan boyutu yetersizliği.","fix":"Sütun uzunluğunu veriye göre büyütün (ALTER TABLE ... ALTER COLUMN) veya veriyi kısaltın. SQL Server 2019+ ile hangi tablo/sütun/değerin taştığını gösteren 2628 hatasını kullanın; eski sürümlerde sütunları tek tek LEN() ile kontrol edip taşan kaydı bulun. Aktarımlarda kaynak ve hedef şemalarının uzunluklarını eşitleyin.","tags":["truncation","kesme","taşma","varchar","length","uzunluk","8152","2628"]},{"code":"2628","title":"String or binary data would be truncated in table, column ...; truncated value","severity":"caution","meaning":"8152'nin gelişmiş sürümüdür (SQL Server 2019 ve sonrası). Hangi tablo, hangi sütun ve hangi kesilecek değerin soruna yol açtığını açıkça belirtir.","cause":"Hedef sütunun tanımlı uzunluğundan daha uzun bir metin/binary değeri yazma. Genellikle şema uyumsuzluğu veya beklenmedik uzunlukta veri girişi.","fix":"Hata metnindeki tablo ve sütun adına bakın; ya sütun boyutunu büyütün ya da kaynak değeri kısaltın. SQL Server 2019'da 2628 varsayılan olarak yalnızca uyumluluk seviyesi 150+ iken gelir; daha düşük seviyede ALTER DATABASE SCOPED CONFIGURATION SET VERBOSE_TRUNCATION_WARNINGS = ON veya trace flag 460 ile açılır. SQL Server 2016 SP2 CU6 ve 2017 CU12'den itibaren trace flag 460 ile aynı ayrıntılı mesaj alınabilir. Aktarım katmanında alan uzunluklarını hedefle hizalayın.","tags":["truncation","kesme","taşma","column","sutun","length","2628","460"]},{"code":"1222","title":"Lock request time out period exceeded","severity":"caution","meaning":"Bir sorgu, ihtiyaç duyduğu lock'u almak için beklerken tanımlı zaman aşımı süresi doldu. Başka bir transaction gerekli kaynağı uzun süre kilitli tuttuğu için istek iptal edildi.","cause":"SET LOCK_TIMEOUT ile belirlenmiş bekleme süresinin aşılması, uzun süren bloklayıcı transaction'lar, commit edilmeyen açık transaction'lar, uzun taramalar ve lock çakışmaları.","fix":"Bloklayan transaction'ı bulun: sys.dm_exec_requests, sys.dm_tran_locks ve blocking_session_id sütununu inceleyin veya sp_who2 / sp_whoisactive kullanın. Uzun transaction'ları kısaltın ve commit edin. Gerekirse LOCK_TIMEOUT değerini ayarlayın. Okuma yoğun sistemlerde RCSI/snapshot yalıtımıyla okuyucu-yazıcı çakışmasını azaltın.","tags":["lock timeout","kilit zaman asimi","blocking","engelleme","1222","lock_timeout"]},{"code":"9002","title":"The transaction log for database is full due to ...","severity":"danger","meaning":"Veritabanının transaction log dosyası doldu ve yeni transaction'lar kaydedilemiyor. Veritabanı yazma işlemlerini reddeder, salt okunur benzeri duruma düşebilir.","cause":"FULL recovery modelinde log yedeği alınmaması, uzun süre açık kalan transaction, replikasyon/AlwaysOn gecikmesi, log'un büyüyememesi (autogrow kapalı veya disk dolu). Nedeni log_reuse_wait_desc gösterir.","fix":"sys.databases içindeki log_reuse_wait_desc değerine bakın. FULL modelde LOG_BACKUP bekliyorsa log yedeği alın (BACKUP LOG). ACTIVE_TRANSACTION varsa açık transaction'ı bulup commit/rollback yapın (DBCC OPENTRAN). Diskte yer açın veya log dosyasının autogrow ayarını düzeltin. Log gerçekten büyümüşse yedek sonrası DBCC SHRINKFILE ile küçültün. Log'a ihtiyacınız yoksa recovery modelini gözden geçirin.","tags":["transaction log","log dolu","log full","9002","backup log","recovery model"]},{"code":"1105","title":"Could not allocate space for object in database because the filegroup is full","severity":"danger","meaning":"Data file'ın bulunduğu filegroup doldu ve yeni veri için yer ayrılamıyor. Ekleme/güncelleme işlemleri başarısız olur.","cause":"Data file'ın büyüyememesi (autogrowth kapalı veya MAXSIZE sınırına ulaşılmış), diskte boş alan kalmaması, PRIMARY filegroup'un tükenmesi veya dosya boyut sınırı.","fix":"Diskte yer açın ya da yeni disk/dosya ekleyin. Data file'a autogrowth verin veya boyutunu büyütün (ALTER DATABASE ... MODIFY FILE). Filegroup'a yeni dosya ekleyin. Gereksiz/eski verileri arşivleyip temizleyin. tempdb için ise tempdb dosyalarını ve diskini kontrol edin.","tags":["filegroup full","dosya dolu","allocate space","disk","autogrow","1105"]},{"code":"208","title":"Invalid object name","severity":"safe","meaning":"Sorguda başvurulan tablo, view veya nesne bulunamadı. SQL Server belirtilen adı çözümleyemedi.","cause":"Nesne adının yanlış yazımı, yanlış veritabanı/şema bağlamı (dbo yerine farklı şema), nesnenin gerçekten var olmaması veya henüz oluşturulmamış olması, iki parçalı ad (schema.tablo) eksikliği.","fix":"Nesne adını ve şemayı doğru yazın; tam ad kullanın (ör. dbo.Musteriler). Doğru veritabanına bağlı olduğunuzdan emin olun (USE). Nesnenin varlığını kontrol edin: SELECT * FROM sys.objects WHERE name = 'AdSizeAd'. Geçici tabloları oturum içinde oluşturduğunuzdan emin olun.","tags":["invalid object","gecersiz nesne","table not found","tablo yok","schema","sema","208"]},{"code":"229","title":"The SELECT/EXECUTE permission was denied on the object","severity":"caution","meaning":"Kullanıcının, ilgili nesne üzerinde istenen işlemi (SELECT, INSERT, EXECUTE vb.) yapma izni yok. Erişim güvenlik nedeniyle reddedildi.","cause":"Kullanıcıya/role gerekli iznin verilmemiş olması, yanlış şema sahipliği (ownership chaining kırılması), nesneye açık DENY uygulanmış olması veya kullanıcının yeterli role üye olmaması.","fix":"Gerekli izni verin: GRANT SELECT ON dbo.Tablo TO KullaniciAdi (veya GRANT EXECUTE ON dbo.Prosedur TO ...). Kullanıcıyı uygun bir role ekleyin (ör. db_datareader). Açık bir DENY varsa kaldırın. En az ayrıcalık ilkesine uyacak şekilde izinleri düzenleyin. sys.database_permissions ile mevcut izinleri denetleyin.","tags":["permission denied","izin reddedildi","grant","yetki","security","guvenlik","229"]},{"code":"4060","title":"Cannot open database requested by the login. The login failed","severity":"danger","meaning":"Oturum açma başarılı olabilir ancak istenen veritabanı açılamadığı için bağlantı reddedildi. Genellikle 18456 ile birlikte görülür.","cause":"Veritabanının var olmaması, OFFLINE/SINGLE_USER/RESTORING/SUSPECT durumunda olması, login'in o veritabanında kullanıcı eşlemesi olmaması veya bağlantı dizesindeki varsayılan veritabanının erişilemez olması.","fix":"Veritabanının var olduğunu ve ONLINE olduğunu doğrulayın: SELECT name, state_desc FROM sys.databases. Login için veritabanında kullanıcı oluşturup izin verin. Bağlantı dizesindeki Initial Catalog/Database değerini kontrol edin. Veritabanı RESTORING/SUSPECT ise onarım/geri yükleme adımlarını uygulayın.","tags":["cannot open database","veritabani acilamiyor","4060","login","state","offline"]},{"code":"233","title":"A connection was successfully established with the server, but then an error occurred (no process is on the other end of the pipe)","severity":"danger","meaning":"İstemci sunucuya ulaştı ama el sıkışma (handshake) sırasında bağlantı koptu. Genellikle Named Pipes/TCP yapılandırması, protokol veya sunucu tarafı reddi kaynaklıdır. 10054 (connection forcibly closed) ile ilişkilidir.","cause":"Shared Memory/Named Pipes/TCP protokollerinin kapalı olması, uzak bağlantıların izinli olmaması, kullanıcı hesabının login olamaması (bkz. 18456), güvenlik duvarı/ağ kesintisi veya sunucunun bağlantıyı zorla kapatması (10054).","fix":"SQL Server Configuration Manager'da TCP/IP ve gerekiyorsa Named Pipes protokollerini etkinleştirin ve servisi yeniden başlatın. Uzak bağlantıya izin verildiğini doğrulayın. Güvenlik duvarında SQL portunu (varsayılan 1433) açın. Kimlik doğrulama sorunları için error log'daki 18456 State kodunu inceleyin. Ağ kararlılığını ve TLS/şifreleme ayarlarını kontrol edin.","tags":["connection","baglanti","pipe","10054","tcp","named pipes","233","network"]},{"code":"823","title":"The operating system returned error to SQL Server during a read/write at offset in file (I/O error)","severity":"danger","meaning":"SQL Server bir veri/log dosyasına okuma-yazma yaparken işletim sistemi düzeyinde bir I/O hatası aldı. Bu, disk donanımı veya depolama alt sistemi sorununa işaret eden ciddi bir bütünlük uyarısıdır.","cause":"Bozuk disk sektörleri, arızalı denetleyici/sürücü, depolama/SAN sorunları, dosya sistemi hataları veya sayfanın tümüyle okunamaması (hard I/O error). Genellikle donanım kaynaklıdır.","fix":"Hemen sağlam bir yedek alın (mümkünse). Windows Event Log ve depolama loglarını inceleyin, donanım/disk sağlığını test edin. DBCC CHECKDB ile bütünlük kontrolü yapın. suspect_pages tablosunu (msdb.dbo.suspect_pages) kontrol edin. Bozulma varsa sağlam yedekten geri yükleyin veya sayfa düzeyinde restore uygulayın. Donanımı değiştirin/onarın.","tags":["io error","g/c hatasi","disk","corruption","bozulma","823","checkdb"]},{"code":"824","title":"SQL Server detected a logical consistency-based I/O error (page corruption)","severity":"danger","meaning":"SQL Server bir sayfayı okudu ancak sayfanın içeriği mantıksal olarak tutarsız (yanlış checksum, torn page veya hatalı sayfa kimliği). Veri sayfası bozulmuş demektir.","cause":"Depolama alt sistemi hataları, ani güç kesintisi/torn page, denetleyici veya sürücü sorunları, PAGE_VERIFY CHECKSUM ile yakalanan sessiz bozulmalar. 823 gibi çoğunlukla donanım/depolama kaynaklıdır.","fix":"DBCC CHECKDB çalıştırıp bozulmanın kapsamını belirleyin. En son sağlam yedekten geri yükleyin veya etkilenen sayfaları page-level restore ile onarın. msdb.dbo.suspect_pages kaydını inceleyin. PAGE_VERIFY = CHECKSUM ayarının açık olduğundan emin olun. Donanımı/depolamayı denetleyin. REPAIR_ALLOW_DATA_LOSS son çare olmalıdır ve veri kaybına yol açar.","tags":["page corruption","sayfa bozulmasi","consistency","824","checkdb","checksum","torn page"]},{"code":"701","title":"There is insufficient system memory in resource pool to run this query","severity":"danger","meaning":"SQL Server, sorguyu çalıştırmak için gerekli belleği ilgili kaynak havuzundan (resource pool) ayıramadı. Bellek baskısı nedeniyle işlem başarısız oldu.","cause":"Yetersiz sunucu belleği, düşük max server memory ayarı, bellek tüketen büyük sorgular (geniş sıralama/hash), bellek sızıntısı, çok sayıda eşzamanlı istek veya Resource Governor havuz sınırları.","fix":"max server memory ayarını gözden geçirin ve sunucuya yeterli fiziksel RAM sağlayın. Bellek tüketen sorguları optimize edin (uygun index, daha az sıralama/hash). Bellek durumunu izleyin: sys.dm_os_memory_clerks, DBCC MEMORYSTATUS, Perfmon bellek sayaçları. Resource Governor havuz sınırlarını ayarlayın. Gerekirse eşzamanlılığı azaltın.","tags":["memory","bellek","insufficient memory","resource pool","701","oom"]},{"code":"845","title":"Time-out occurred while waiting for buffer latch","severity":"danger","meaning":"Bir veri sayfası için buffer latch beklerken zaman aşımı oluştu. SQL Server bir sayfaya erişmek için gereken kısa süreli latch'i makul sürede alamadı; genellikle ağır I/O veya bellek baskısı belirtisidir.","cause":"Yavaş/aşırı yüklü disk alt sistemi, bellek baskısı nedeniyle sayfaların diskten sürekli okunması, donanım sorunları, aşırı sayfa değişimi (paging) veya bir depolama tıkanıklığı.","fix":"Disk I/O gecikmelerini ölçün (sys.dm_io_virtual_file_stats, Perfmon disk latency). Depolama performansını ve donanım sağlığını kontrol edin. Bellek yeterliliğini ve max server memory ayarını gözden geçirin. Bekleme türlerini inceleyin (sys.dm_os_wait_stats, PAGEIOLATCH bekleri). Depolama darboğazını giderin; gerekirse daha hızlı disk/daha fazla RAM sağlayın.","tags":["buffer latch","latch timeout","845","io","pageiolatch","memory","bellek"]},{"code":"3201","title":"Cannot open backup device. Operating system error (backup device error)","severity":"caution","meaning":"Yedekleme veya geri yükleme sırasında hedef yedek aygıtı/dosyası açılamadı. SQL Server belirtilen yola erişemedi.","cause":"Yanlış/var olmayan klasör yolu, SQL Server servis hesabının hedef klasörde yazma izni olmaması, ağ paylaşımına (UNC) erişememe, disk dolu olması veya dosyanın başka bir süreç tarafından kilitli olması.","fix":"Yedek yolunun var olduğunu ve doğru yazıldığını doğrulayın. SQL Server servis hesabına hedef klasörde yazma izni verin. UNC paylaşımlarında servis hesabının erişimini kontrol edin. Diskte yeterli boş alan olduğundan emin olun. Yerel yol için sürücü harfinin sunucudan görünür olduğunu doğrulayın (istemci sürücüsü değil).","tags":["backup device","yedek","backup","restore","3201","izin","permission","os error"]}]},"errors/mongodb.json":{"engineId":"mongodb","engine":"MongoDB","order":5,"errors":[{"code":"E11000","title":"E11000 duplicate key error collection","severity":"caution","meaning":"Benzersiz bir index'in (unique index) koruduğu alan(lar)a, koleksiyonda zaten var olan bir değer eklenmeye/güncellenmeye çalışıldı. MongoDB duplicate key'i reddeder.","cause":"_id çakışması, unique index'li bir alana aynı değerin ikinci kez yazılması, upsert sırasında yarış durumu (race condition), veya null değerlerin unique index'te birden fazla belge için çakışması (sparse olmayan index).","fix":"Yazmadan önce belgenin var olup olmadığını kontrol edin veya upsert kullanın: db.koleksiyon.updateOne(filtre, {$set:{...}}, {upsert:true}). Hata mesajındaki index adı ve dup key değerine bakın. Gerçekten benzersizlik gerekmiyorsa index'i kaldırın; null'lar sorun oluyorsa partial/sparse index kullanın. Uygulamada hatayı yakalayıp yeniden deneyin veya kullanıcıya bildirin.","tags":["duplicate key","yinelenen anahtar","unique index","benzersiz","e11000","upsert","_id"]},{"code":"11000","title":"DuplicateKey (error code 11000)","severity":"caution","meaning":"Duplicate key hatasının sayısal kodudur (E11000 metniyle birlikte döner). Bir yazma işlemi benzersiz index constraint'ini ihlal etti.","cause":"Aynı benzersiz alana tekrar yazma, eşzamanlı upsert'lerin aynı anahtarı üretmesi, veya toplu yazmada (bulk write) yinelenen belgeler.","fix":"Uygulama kodunda hata kodu 11000'i yakalayın ve idempotent davranış uygulayın (varsa güncelle, yoksa ekle). Bulk işlemlerde ordered:false kullanarak yinelenenler dışındaki belgelerin yazılmasına izin verebilirsiniz. Benzersizlik kuralını ve index tanımını gözden geçirin.","tags":["duplicatekey","11000","yinelenen","unique","benzersiz","bulk write","write error"]},{"code":"13","title":"Unauthorized (error code 13)","severity":"caution","meaning":"Kimliği doğrulanmış kullanıcının, denenen işlem veya kaynak için yetkisi yok. Kullanıcı oturum açmış ancak rolleri bu eylemi kapsamıyor.","cause":"Kullanıcıya gerekli rolün (ör. readWrite, dbAdmin) atanmamış olması, yanlış veritabanı üzerinde işlem, veya yönetimsel bir komut için yetersiz ayrıcalık. RBAC yapılandırmasının eksikliği.","fix":"Kullanıcının rollerini kontrol edin: db.getUser(\"kullanici\"). Gerekli rolü verin: db.grantRolesToUser(\"kullanici\", [{role:\"readWrite\", db:\"veritabani\"}]). İşlemin doğru veritabanında yapıldığından emin olun. En az ayrıcalık ilkesine göre uygun yerleşik veya özel rol atayın. Bağlantı dizesindeki authSource değerini doğrulayın.","tags":["unauthorized","yetkisiz","authorization","rol","role","rbac","13","izin"]},{"code":"18","title":"AuthenticationFailed (error code 18)","severity":"caution","meaning":"Kimlik doğrulama başarısız oldu. Sağlanan kullanıcı adı, parola veya kimlik doğrulama bilgileri geçersiz; kullanıcı sisteme giriş yapamadı.","cause":"Yanlış kullanıcı adı/parola, yanlış authSource veritabanı, uyumsuz kimlik doğrulama mekanizması (SCRAM-SHA-1/SCRAM-SHA-256), kullanıcının belirtilen veritabanında tanımlı olmaması.","fix":"Kullanıcı adı ve parolayı doğrulayın. Bağlantı dizesinde doğru authSource'u belirtin (kullanıcının oluşturulduğu veritabanı, çoğunlukla admin): ...?authSource=admin. Kimlik doğrulama mekanizmasının sunucuyla uyumlu olduğunu kontrol edin. Kullanıcıyı doğru veritabanında oluşturduğunuzdan emin olun. Parolada özel karakter varsa URL-encode edin.","tags":["authentication failed","kimlik dogrulama","parola","password","authsource","18","scram"]},{"code":"11600","title":"InterruptedAtShutdown (error code 11600)","severity":"danger","meaning":"İşlem, sunucu kapanmaya başladığı için yarıda kesildi. mongod süreci kapandığından devam eden operasyon tamamlanamadı.","cause":"mongod'un yeniden başlatılması/kapatılması, replica set primary'nin adım indirmesi (stepdown) sırasında kapanma, planlı bakım, çökme veya OOM killer tarafından sürecin sonlandırılması.","fix":"Sunucunun tekrar ayağa kalkmasını bekleyip işlemi yeniden deneyin (retry). Uygulamada geçici (transient) hataları yakalayıp otomatik yeniden deneme uygulayın; retryable writes özelliğini etkinleştirin. Beklenmedik kapanmalarda mongod loglarını ve sistem loglarını (OOM, çökme) inceleyin. Replica set kullanarak yüksek erişilebilirlik sağlayın.","tags":["interrupted","shutdown","kapanma","kesinti","11600","retry","replica set"]},{"code":"50","title":"MaxTimeMSExpired (error code 50)","severity":"caution","meaning":"İşlem, maxTimeMS ile belirlenen zaman sınırını aştığı için sunucu tarafından iptal edildi. Sorgu belirlenen süre içinde tamamlanamadı.","cause":"Uzun süren sorgular, eksik index nedeniyle koleksiyon taraması (COLLSCAN), büyük veri hacmi, ağır toplama (aggregation) işlemleri veya sunucunun yüksek yükü.","fix":"Sorguyu optimize edin: explain() ile plan inceleyin ve uygun index ekleyin. Gerçekten daha uzun süre gerekiyorsa maxTimeMS değerini artırın. Ağır aggregation'ları basitleştirin veya $match ile erken filtreleyin. Sonuçları sayfalama (pagination) ile bölün. Sunucu yükünü ve kaynak yeterliliğini kontrol edin.","tags":["maxtimems","timeout","zaman asimi","50","slow query","yavas sorgu","index"]},{"code":"251","title":"NoSuchTransaction (error code 251)","severity":"caution","meaning":"Başvurulan multi-document transaction bulunamadı. Transaction zaten sonlanmış, zaman aşımına uğramış veya geçersiz bir transaction numarası kullanılmıştır.","cause":"Transaction'ın transactionLifetimeLimitSeconds süresini aşıp otomatik iptal edilmesi, session sona ermesi, yanlış/eski txnNumber, veya bir hata sonrası zaten abort edilmiş işleme devam etme.","fix":"Transaction'ı baştan başlatın (yeni session ile yeniden başlatın). Transaction'ları kısa tutun; varsayılan yaşam süresi (60 sn) içinde tamamlanacak şekilde tasarlayın. TransientTransactionError etiketli hatalarda tüm transaction'ı güvenle yeniden deneyin. Uzun transaction'lar gerekiyorsa transactionLifetimeLimitSeconds ayarını gözden geçirin.","tags":["nosuchtransaction","transaction","islem","251","session","abort","retry"]},{"code":"112","title":"WriteConflict (error code 112)","severity":"caution","meaning":"İki eşzamanlı transaction aynı belge(ler)i değiştirmeye çalıştığında oluşan yazma çakışmasıdır. WiredTiger, iyimser eşzamanlılık kontrolü (optimistic concurrency) nedeniyle transaction'lardan birini geri alır.","cause":"Aynı belgelere yüksek eşzamanlı yazma, uzun süren transaction'lar sırasında çakışan güncellemeler, hot document üzerinde yoğun rekabet.","fix":"İşlemi yeniden deneyin; WriteConflict genellikle geçicidir ve retry ile çözülür (TransientTransactionError olarak işaretlenir). Transaction'ları kısa tutun ve dokunulan belge sayısını azaltın. Aynı belgeye yönelik çekişmeyi azaltacak şekilde veri modelini gözden geçirin. Uygulamada üstel geri çekilmeli (exponential backoff) yeniden deneme uygulayın.","tags":["writeconflict","yazma cakismasi","112","concurrency","eszamanlilik","retry","wiredtiger"]},{"code":"133","title":"FailedToSatisfyReadPreference (error code 133)","severity":"danger","meaning":"Belirtilen read preference'ı (örn. primary, secondary) karşılayacak uygun bir replica set üyesi bulunamadı. Sürücü isteği yönlendirebileceği bir düğüm seçemedi.","cause":"Replica set üyelerinin erişilemez/aşağıda olması, primary seçimi (election) devam ederken primary olmaması, ağ bölünmesi (partition), tag set kriterlerine uyan üye bulunmaması veya çoğunluğun (quorum) sağlanamaması.","fix":"Replica set durumunu kontrol edin: rs.status(). Düğümlerin sağlığını ve ağ bağlantısını doğrulayın. Primary seçiminin tamamlanmasını bekleyip yeniden deneyin. Read preference ayarınızı gözden geçirin; gerekiyorsa daha esnek bir tercih (ör. primaryPreferred) kullanın. Tag set kullanıyorsanız eşleşen üye olduğundan emin olun.","tags":["read preference","readpreference","133","replica set","election","secondary","primary"]},{"code":"6","title":"HostUnreachable (error code 6)","severity":"danger","meaning":"Sürücü/istemci hedef MongoDB sunucusuna (host) ulaşamadı. Ağ düzeyinde bağlantı kurulamadı.","cause":"Sunucunun kapalı olması, yanlış host/port, güvenlik duvarı engellemesi, DNS çözümleme sorunu, ağ kesintisi veya bind IP yapılandırmasının istemciyi dışarıda bırakması.","fix":"Host adı ve portun doğruluğunu kontrol edin (varsayılan 27017). mongod servisinin çalıştığını doğrulayın. Güvenlik duvarı ve ağ erişimini test edin (ping/telnet). mongod.conf içindeki bindIp ayarının istemci erişimine izin verdiğinden emin olun. DNS/SRV kayıtlarını doğrulayın (mongodb+srv bağlantılarında).","tags":["hostunreachable","host","baglanti","network","ag","6","firewall","bindip"]},{"code":"89","title":"NetworkTimeout (error code 89)","severity":"danger","meaning":"Sunucuyla iletişim sırasında ağ işlemi belirlenen süre içinde tamamlanamadı ve zaman aşımına uğradı. Bağlantı kuruldu ancak yanıt zamanında gelmedi.","cause":"Yavaş veya kararsız ağ, aşırı yüklü sunucu, uzun süren işlemin yanıtı geciktirmesi, düşük ayarlanmış socket/connect timeout değerleri veya ağ tıkanıklığı.","fix":"Ağ gecikmesini ve kararlılığını ölçün. Sunucu yükünü ve kaynaklarını kontrol edin. Sürücüdeki connectTimeoutMS ve socketTimeoutMS değerlerini gerçekçi biçimde ayarlayın. Geçici hataları yakalayıp yeniden deneyin. Yavaş sorguları optimize ederek yanıt süresini kısaltın.","tags":["networktimeout","ag zaman asimi","89","timeout","socket","network","retry"]},{"code":"262","title":"ExceededTimeLimit (error code 262)","severity":"caution","meaning":"İşlem, sunucu tarafında izin verilen süre sınırını aştı ve sonlandırıldı. maxTimeMS veya iç zaman sınırlarının aşılması bu hataya yol açabilir.","cause":"Uzun süren sorgu/komut, eksik index nedeniyle yavaş çalışma, ağır aggregation, büyük veri kümesi taraması veya sunucunun yoğun yükü.","fix":"Sorguyu explain() ile inceleyip uygun index ekleyin. İşlemi daha küçük parçalara bölün. maxTimeMS değerini gerçek ihtiyaca göre ayarlayın. Aggregation pipeline'ında erken $match/$project ile veriyi azaltın. Sunucu kaynaklarının yeterli olduğunu doğrulayın.","tags":["exceededtimelimit","zaman siniri","262","timeout","maxtimems","slow","index"]},{"code":"292","title":"QueryExceededMemoryLimitNoDiskUseAllowed (error code 292)","severity":"caution","meaning":"Bir sorgu veya aggregation aşaması, izin verilen bellek sınırını (varsayılan 100 MB) aştı ve diske yazmaya izin verilmediği için başarısız oldu. Genellikle sıralama (sort) veya gruplama (group) aşamalarında görülür.","cause":"Index'siz büyük veri üzerinde bellekte sıralama, geniş $group/$sort aggregation aşamaları, çok büyük ara sonuç kümeleri, allowDiskUse:false ayarı.","fix":"Aggregation'da allowDiskUse:true seçeneğini kullanarak diske taşmaya izin verin: db.koleksiyon.aggregate(pipeline, {allowDiskUse:true}). Sıralama yapılan alanlara index ekleyerek belleği düşürün. Pipeline'ı erken $match ile filtreleyip işlenen veriyi azaltın. Gerekiyorsa sonuçları sayfalayın. MongoDB 6.0+ sürümünde disk kullanımı çoğu durumda varsayılan açıktır.","tags":["memory limit","bellek siniri","292","allowdiskuse","sort","aggregation","group"]},{"code":"26","title":"NamespaceNotFound (error code 26)","severity":"safe","meaning":"Başvurulan namespace (veritabanı.koleksiyon) bulunamadı. Belirtilen koleksiyon veya index mevcut değil.","cause":"Koleksiyon adının yanlış yazımı, henüz oluşturulmamış koleksiyon, yanlış veritabanı bağlamı, veya var olmayan bir koleksiyon üzerinde drop/index işlemi denemek.","fix":"Koleksiyon adını ve veritabanını doğrulayın: show collections. Adın büyük/küçük harf duyarlı olduğunu unutmayın. Koleksiyonu ilk yazma işleminde MongoDB otomatik oluşturur; gerekiyorsa db.createCollection() ile açıkça oluşturun. drop gibi işlemlerde koleksiyonun varlığını önceden kontrol edin.","tags":["namespacenotfound","namespace","koleksiyon yok","26","collection","not found","bulunamadi"]},{"code":"43","title":"CursorNotFound (error code 43)","severity":"caution","meaning":"Sunucu tarafındaki cursor artık mevcut değil. İstemci bir sonraki batch'i (getMore) istediğinde cursor bulunamadığı için hata döner.","cause":"Cursor'ın zaman aşımına uğraması (varsayılan 10 dakika hareketsizlik), batch'ler arasında çok uzun bekleme, sunucunun yeniden başlaması, veya cursor'ın açıkça kapatılmış olması.","fix":"Cursor sonuçlarını daha hızlı işleyin; batch'ler arasında uzun bekleme yapmayın. Uzun süren işlemlerde noCursorTimeout seçeneğini (mongosh: cursor.noCursorTimeout(); PyMongo: no_cursor_timeout=True) dikkatli kullanın ve cursor'ı mutlaka kapatın; bir oturum (session) içindeki cursor bu seçenekle bile oturum zaman aşımında (localLogicalSessionTimeoutMinutes, varsayılan 30 dk) kapanır. Büyük sonuç kümelerinde daha küçük batchSize ile ilerleyin veya aralık tabanlı sayfalama (range-based pagination) kullanın. İşlemi baştan başlatıp yeniden sorgulayın.","tags":["cursornotfound","cursor","imlec","43","getmore","timeout","batch","pagination"]},{"code":"211","title":"KeyNotFound (error code 211)","severity":"caution","meaning":"Beklenen bir anahtar/değer bulunamadı. Genellikle iç anahtar yönetimi, oturum anahtarları veya oplog/keys koleksiyonuyla ilgili bir tutarsızlığa işaret eder.","cause":"admin.system.keys koleksiyonunda eksik/silinmiş imzalama anahtarları, replica set/sharded küme zaman senkronizasyonu sorunları, keyfile/anahtar rotasyonu problemleri veya bozulmuş iç durum.","fix":"Replica set üyeleri arasında saat senkronizasyonunu (NTP) doğrulayın. admin.system.keys içeriğini ve anahtar üretimini kontrol edin. Küme durumunu (rs.status(), sh.status()) inceleyin. Kalıcıysa mongod loglarını analiz edin ve keyfile/kimlik yapılandırmasını gözden geçirin. Anahtarların yeniden üretilmesi için primary'nin sağlıklı çalıştığından emin olun.","tags":["keynotfound","anahtar","211","keys","session","ntp","cluster","kume"]}]},"errors/redis.json":{"engineId":"redis","engine":"Redis","order":6,"errors":[{"code":"WRONGTYPE","title":"WRONGTYPE Operation against a key holding the wrong kind of value","severity":"caution","meaning":"Bir anahtar üzerinde, o anahtarın veri tipine uygun olmayan bir komut çalıştırıldı. Örneğin string tutan bir anahtara liste (LPUSH) veya hash (HSET) komutu uygulamak.","cause":"Anahtarın beklenenden farklı bir tipte olması, aynı anahtar adının farklı veri tipleriyle kullanılması, uygulama mantığında tip karışıklığı veya eski/kalıntı bir anahtarın üzerine yazma.","fix":"Anahtarın tipini kontrol edin: TYPE anahtar. Komutu anahtarın gerçek tipine göre seçin. Anahtar isimlendirmede tip ayrımı yapın (ör. user:1:tags için set, user:1:name için string). Gerekiyorsa eski anahtarı silip (DEL) doğru tiple yeniden oluşturun. Uygulama katmanında tip tutarlılığını sağlayın.","tags":["wrongtype","yanlis tip","type","veri tipi","key","anahtar"]},{"code":"OOM","title":"OOM command not allowed when used memory > 'maxmemory'","severity":"danger","meaning":"Redis'in kullandığı bellek maxmemory sınırına ulaştı ve eviction politikası yeni veri için yer açamadığından yazma komutları reddediliyor. Bellek dolu, yazma yapılamıyor.","cause":"maxmemory sınırının aşılması, noeviction politikasının seçili olması (hiçbir anahtar silinmez), TTL'siz sürekli büyüyen veri, bellek sızıntısı veya sınıra göre yetersiz RAM.","fix":"Bellek kullanımını inceleyin: INFO memory ve MEMORY USAGE. Uygun bir eviction politikası seçin (ör. allkeys-lru veya volatile-lru): CONFIG SET maxmemory-policy allkeys-lru. Anahtarlara TTL vererek otomatik temizlenmelerini sağlayın. maxmemory değerini/RAM'i artırın. Büyük anahtarları bulup küçültün (redis-cli --bigkeys). Gereksiz verileri temizleyin.","tags":["oom","out of memory","bellek","maxmemory","eviction","memory","danger"]},{"code":"NOAUTH","title":"NOAUTH Authentication required","severity":"caution","meaning":"Redis kimlik doğrulama gerektiriyor ancak istemci henüz kimlik doğrulaması yapmadan komut çalıştırmaya çalıştı. Önce AUTH ile giriş yapılmalı.","cause":"Sunucuda requirepass/ACL parolası tanımlı olması, istemcinin AUTH komutunu göndermemesi, bağlantı dizesinde parolanın eksik olması veya bağlantının yeniden kurulmasından sonra AUTH tekrarlanmaması.","fix":"Komutlardan önce kimlik doğrulaması yapın: AUTH parola (ACL kullanıyorsanız AUTH kullanici parola). İstemci/bağlantı dizesine parolayı ekleyin. Bağlantı havuzu kullanıyorsanız her yeni bağlantıda AUTH yapıldığından emin olun. Parolayı güvenli biçimde saklayın (ortam değişkeni/gizli anahtar yöneticisi).","tags":["noauth","authentication","kimlik dogrulama","auth","parola","requirepass","acl"]},{"code":"WRONGPASS","title":"WRONGPASS invalid username-password pair or user is disabled","severity":"caution","meaning":"AUTH komutunda verilen kullanıcı adı/parola çifti geçersiz ya da ilgili ACL kullanıcısı devre dışı. Kimlik doğrulama reddedildi.","cause":"Yanlış parola, yanlış ACL kullanıcı adı, kullanıcının ACL'de disabled olması, requirepass değerinin değişmiş olması veya parolada kaçış/kodlama sorunu.","fix":"Doğru kullanıcı adı ve parolayı girin. ACL kullanıcısını denetleyin: ACL LIST ve ACL GETUSER kullanici. Kullanıcı devre dışıysa etkinleştirin (ACL SETUSER kullanici on ...). requirepass ile ayarlanan parolayı doğrulayın (CONFIG GET requirepass). Parolayı sıfırlarken tüm istemcilerin güncellendiğinden emin olun.","tags":["wrongpass","parola","invalid password","auth","acl","kullanici","gecersiz"]},{"code":"READONLY","title":"READONLY You can't write against a read only replica","severity":"caution","meaning":"Bir replica (slave) düğümüne yazma komutu gönderildi. Replica'lar varsayılan olarak salt okunurdur; yazma işlemleri yalnızca master üzerinde yapılabilir.","cause":"İstemcinin master yerine replica'ya bağlanması, failover sonrası eski master'ın replica'ya dönüşmesi, Sentinel/Cluster'da yanlış düğüme yönlendirme veya yük dengeleyicinin yazmayı replica'ya iletmesi.","fix":"Yazma isteklerini master düğümüne yönlendirin. Sentinel kullanıyorsanız güncel master'ı Sentinel'den sorgulayın (SENTINEL get-master-addr-by-name). Cluster'da doğru shard master'ına yazın. İstemci kütüphanesinde okuma/yazma ayrımını yapılandırın. Failover'dan sonra bağlantıları yenileyerek yeni master'a yönelin.","tags":["readonly","salt okunur","replica","slave","write","yazma","master","failover"]},{"code":"MASTERDOWN","title":"MASTERDOWN Link with MASTER is down and replica-serve-stale-data is set to 'no'","severity":"danger","meaning":"Replica ile master arasındaki bağlantı koptu ve replica-serve-stale-data 'no' olarak ayarlı olduğundan replica eski (stale) veriyle istekleri yanıtlamayı reddediyor.","cause":"Master düğümünün çökmesi veya erişilemez olması, ağ kesintisi/bölünmesi, master-replica replikasyon bağlantısının kopması veya master'ın aşırı yük altında yanıt verememesi.","fix":"Master düğümünün durumunu ve ağ bağlantısını kontrol edin. Replikasyon durumunu inceleyin: INFO replication. Master'ı ayağa kaldırın veya Sentinel/Cluster ile failover'ın gerçekleşmesini sağlayın. Eski veriyle hizmet vermeyi kabul ediyorsanız replica-serve-stale-data yes ayarını değerlendirin (tutarlılık riskine dikkat). Yüksek erişilebilirlik için Sentinel/Cluster kullanın.","tags":["masterdown","master down","replikasyon","replication","stale","failover","sentinel","danger"]},{"code":"CLUSTERDOWN","title":"CLUSTERDOWN The cluster is down / Hash slot not served","severity":"danger","meaning":"Redis Cluster tam olarak çalışır durumda değil. Bazı hash slot'lar herhangi bir düğüm tarafından sunulamıyor, bu yüzden küme istekleri reddediyor.","cause":"Yeterli master düğümünün erişilebilir olmaması, bir veya daha fazla slot'un atanmamış/kapsanmamış olması, çoğunluğun (quorum) kaybı, düğüm çökmeleri veya cluster-require-full-coverage yes iken bazı slot'ların erişilemez olması.","fix":"Küme durumunu kontrol edin: CLUSTER INFO ve CLUSTER NODES. Aşağıda olan master'ları ayağa kaldırın veya replica'ların promote olmasını sağlayın. Atanmamış slot'ları yeniden atayın (redis-cli --cluster fix veya CLUSTER ADDSLOTS). Tüm slot'ların kapsandığını doğrulayın. Kısmi çalışmayı kabul ediyorsanız cluster-require-full-coverage no ayarını değerlendirin.","tags":["clusterdown","cluster","kume","hash slot","slot","quorum","coverage","danger"]},{"code":"LOADING","title":"LOADING Redis is loading the dataset in memory","severity":"caution","meaning":"Redis başlatılıyor ve veri kümesini (RDB/AOF) diskten belleğe yüklüyor. Yükleme tamamlanana kadar çoğu komut geçici olarak reddedilir.","cause":"Sunucunun yeni başlatılmış olması, büyük bir RDB/AOF dosyasının yüklenmesi, replica'nın master'dan tam senkronizasyon (full sync) yapması veya yeniden başlatma sonrası kurtarma süreci.","fix":"Yükleme bitene kadar bekleyin; süre veri boyutuna bağlıdır. Durumu izleyin: INFO persistence (loading:1 iken beklenir, 0 olunca hazır). Uygulamada bu geçici hatayı yakalayıp kısa aralıklarla yeniden deneyin. Yükleme süresini kısaltmak için veri kümesini/persistans stratejisini (RDB vs AOF) gözden geçirin. Yeterli RAM ve hızlı disk sağlayın.","tags":["loading","yukleniyor","startup","baslatma","rdb","aof","sync","persistence"]},{"code":"BUSY","title":"BUSY Redis is busy running a script. You can only call SCRIPT KILL or SHUTDOWN NOSAVE","severity":"caution","meaning":"Uzun süren bir Lua script veya fonksiyon çalışıyor ve busy-reply-threshold süresini (Redis 7 öncesindeki adıyla lua-time-limit; varsayılan 5000 ms) aştı. Redis tek thread'li olduğundan bu süre boyunca başka komut işleyemez; yalnızca SCRIPT KILL (fonksiyonlar için FUNCTION KILL) veya SHUTDOWN NOSAVE kabul edilir.","cause":"Sonsuz döngü veya çok uzun süren Lua script/fonksiyon, ağır hesaplama, büyük veri üzerinde döngüsel işlem yapan script veya kötü yazılmış EVAL çağrısı.","fix":"Script veri değiştirmediyse durdurun: SCRIPT KILL. Eğer script zaten yazma yaptıysa SCRIPT KILL çalışmaz; veri tutarlılığını korumak için son çare olarak SHUTDOWN NOSAVE gerekebilir (kaydedilmemiş veriler kaybolur, dikkatli olun). Script'leri kısa ve deterministik yazın. Uzun işlemleri parçalara bölün. busy-reply-threshold (eski adıyla lua-time-limit) ayarını gözden geçirin.","tags":["busy","mesgul","lua","script","script kill","eval","time limit"]},{"code":"MISCONF","title":"MISCONF Redis is configured to save RDB snapshots, but it's currently unable to persist to disk","severity":"danger","meaning":"Redis RDB snapshot'ı almak üzere yapılandırılmış ancak diske yazamıyor. Bu durumda stop-writes-on-bgsave-error açıksa Redis tüm yazma komutlarını reddeder.","cause":"Disk dolu olması, dosya sistemi izin sorunları, dizinin yazılamaz olması, arka plan kaydetme (BGSAVE) hataları, yetersiz bellek nedeniyle fork başarısızlığı veya disk donanım sorunu.","fix":"Diskte boş alan açın ve RDB dizininin (dir) yazma iznini kontrol edin. En son BGSAVE hatasını inceleyin: INFO persistence ve Redis loglarına bakın. Sorunu çözene kadar geçici olarak yazmaları açmak için stop-writes-on-bgsave-error no ayarlanabilir (kalıcılık riskine dikkat). fork için yeterli belleği ve vm.overcommit_memory=1 ayarını sağlayın. Persistans yapılandırmasını (save/appendonly) doğrulayın.","tags":["misconf","persist","kalicilik","rdb","bgsave","disk","snapshot","danger"]},{"code":"CROSSSLOT","title":"CROSSSLOT Keys in request don't hash to the same slot","severity":"caution","meaning":"Redis Cluster'da, birden fazla anahtar içeren bir komut (ör. MGET, MSET, SUNION) kullanıldı ancak anahtarlar farklı hash slot'lara düşüyor. Çok anahtarlı işlemler tüm anahtarların aynı slot'ta olmasını gerektirir.","cause":"Cluster modunda birden çok anahtara aynı anda erişen komutların, farklı slot'lara dağılmış anahtarlarla çağrılması. Anahtarların hash tag kullanmaması nedeniyle farklı düğümlere dağılması.","fix":"İlgili anahtarları aynı slot'a düşürmek için hash tag kullanın: anahtar adının bir bölümünü küme paranteziyle sabitleyin (ör. {user1}:profil ve {user1}:ayarlar aynı slot'a gider). Çok anahtarlı komutları yalnızca aynı hash tag'e sahip anahtarlarla kullanın. Alternatif olarak işlemleri tek anahtarlı komutlara bölün.","tags":["crossslot","cross slot","cluster","kume","hash tag","slot","mget","mset"]},{"code":"MOVED","title":"MOVED slot ip:port (cluster redirect)","severity":"safe","meaning":"Redis Cluster'da, istenen anahtarın bulunduğu hash slot başka bir düğüme aittir. Sunucu istemciyi kalıcı olarak doğru düğüme yönlendirir. Bu bir hatadan çok bir yönlendirmedir.","cause":"Cluster-aware olmayan bir istemcinin yanlış düğüme istek göndermesi, slot'ların düğümler arasında yeniden dağıtılmış olması (resharding) veya istemcinin önbelleğe aldığı slot haritasının güncel olmaması.","fix":"Cluster'ı destekleyen (cluster-aware) bir istemci kütüphanesi kullanın; bunlar MOVED yanıtını otomatik izleyip doğru düğüme yönlendirir ve slot haritasını günceller. redis-cli ile bağlanırken -c bayrağını kullanın. İstemcinizin slot topolojisini periyodik olarak yenilediğinden emin olun (CLUSTER SLOTS/SHARDS).","tags":["moved","cluster","kume","yonlendirme","redirect","slot","resharding"]},{"code":"ASK","title":"ASK slot ip:port (cluster redirect)","severity":"safe","meaning":"Redis Cluster'da, bir slot başka bir düğüme taşınma (migration) sürecindedir ve istenen anahtar geçici olarak hedef düğümde olabilir. Sunucu istemciyi yalnızca bu istek için hedef düğüme yönlendirir (geçici yönlendirme).","cause":"Slot'ların düğümler arasında taşınması (resharding) sırasında, taşınmakta olan bir slot'taki henüz aktarılmış bir anahtara erişim. MOVED'in aksine kalıcı değildir; yalnızca o an geçerlidir.","fix":"Cluster-aware istemciler ASK yönlendirmesini otomatik yönetir: hedef düğüme ASKING komutunu gönderip isteği tekrarlar, ancak slot haritasını kalıcı olarak güncellemez. Uygun bir istemci kütüphanesi ve redis-cli için -c bayrağı kullanın. Resharding tamamlandığında yönlendirmeler MOVED'e dönüşerek kalıcılaşır.","tags":["ask","asking","cluster","kume","migration","tasima","redirect","yonlendirme"]},{"code":"NOSCRIPT","title":"NOSCRIPT No matching script. Please use EVAL","severity":"caution","meaning":"EVALSHA ile çağrılan Lua script'in SHA1 özeti sunucunun script önbelleğinde bulunamadı. Redis bu hash'e karşılık gelen bir script tanımıyor.","cause":"Sunucunun yeniden başlatılması veya SCRIPT FLUSH ile script önbelleğinin temizlenmesi, script'in hiç yüklenmemiş olması, failover sonrası yeni düğümde önbelleğin boş olması.","fix":"Script'i EVAL ile tam gövdesiyle çalıştırın (Redis otomatik önbelleğe alır) veya önce SCRIPT LOAD ile yükleyip dönen SHA'yı EVALSHA'da kullanın. Uygulamada NOSCRIPT hatasını yakalayıp EVALSHA yerine EVAL'a düşen (fallback) mantık uygulayın. Bu, birçok Redis istemci kütüphanesinde otomatik yapılır.","tags":["noscript","script","evalsha","eval","lua","sha","script load","onbellek"]},{"code":"EXECABORT","title":"EXECABORT Transaction discarded because of previous errors","severity":"caution","meaning":"MULTI/EXEC bloğundaki bir transaction, kuyruğa alma (queue) aşamasında oluşan hatalar nedeniyle iptal edildi. EXEC hiçbir komutu çalıştırmadan işlemi reddeder.","cause":"MULTI ile EXEC arasında bir komutun sözdizimi hatası içermesi, var olmayan bir komut adı, yanlış argüman sayısı gibi kuyruğa alma sırasında yakalanan hatalar. Bu tür hatalar tüm transaction'ı geçersiz kılar.","fix":"MULTI bloğundaki komutları sözdizimi ve argüman açısından düzeltin. Komutları kuyruğa alırken dönen hataları kontrol edin; QUEUED yerine hata dönen komut varsa transaction EXEC'te iptal edilir. Transaction'ı geçerli komutlarla yeniden oluşturun. Not: Redis transaction'ları rollback yapmaz; yalnızca kuyruk hataları EXECABORT'a yol açar, çalışma zamanı hataları diğer komutları durdurmaz.","tags":["execabort","transaction","islem","multi","exec","discard","queue","kuyruk"]}]},"errors/elasticsearch.json":{"engineId":"elasticsearch","engine":"Elasticsearch","order":7,"errors":[{"code":"cluster_block_exception","title":"ClusterBlockException[blocked by: [TOO_MANY_REQUESTS/12/disk usage exceeded flood-stage watermark, index has read-only-allow-delete block]] (7.x öncesi: FORBIDDEN/12/index read-only / allow delete (api))","severity":"danger","meaning":"Disk kullanımı flood stage watermark (varsayılan %95; büyük disklerde max_headroom ile belirlenir) eşiğini aştığı için Elasticsearch, diskin tamamen dolmasını önlemek amacıyla ilgili düğümde shard'ı bulunan index'lere read_only_allow_delete bloğu koydu. Bu blok yüzünden index'e yazma (index/update/delete belge) yapılamıyor; yalnızca index'in kendisini silmeye izin veriliyor. ES 8.x bu hatayı HTTP 429 ile döndürür.","cause":"Düğümlerden en az birinde disk doluluğu cluster.routing.allocation.disk.watermark.flood_stage eşiğini geçmesi. Blok elle kaldırılsa bile disk hâlâ doluysa Elasticsearch bloğu tekrar koyar. Log rotasyonu yapılmayan büyük index'ler, snapshot'ların temizlenmemesi veya yetersiz disk kapasitesi tipik nedenlerdir.","fix":"Önce diskte yer açın: eski/gereksiz index'leri silin (DELETE /eski-index), snapshot alıp index'leri kaldırın veya diski büyütün. 7.4+ sürümlerde disk kullanımı high watermark'ın altına indiğinde blok otomatik kaldırılır; beklemeden hemen açmak isterseniz manuel kaldırın: PUT /_all/_settings {\"index.blocks.read_only_allow_delete\": null}. Kalıcı çözüm için ILM (Index Lifecycle Management) ile eski verileri otomatik silin/arşivleyin ve watermark ayarlarını (disk.watermark.low/high/flood_stage) gözden geçirin.","tags":["disk","read-only","watermark","flood-stage","cluster-block","danger"]},{"code":"index_read_only_allow_delete","title":"TOO_MANY_REQUESTS/12/disk usage exceeded flood-stage watermark, index has read-only-allow-delete block (eski: FORBIDDEN/12/index read-only / allow delete (api))","severity":"danger","meaning":"index.blocks.read_only_allow_delete ayarı true olduğu için index salt okunurdur; yeni belge yazılamaz, güncellenemez, yalnızca index silinebilir. Bu ayar genellikle disk flood stage watermark aşıldığında Elasticsearch tarafından otomatik konulur; ES 8.x yazma isteklerine HTTP 429 döndürür.","cause":"Disk doluluğunun flood stage eşiğini geçmesi ile otomatik blok konması veya ayarın manuel olarak true yapılmış olması. Disk boşaltılmadan blok kaldırılırsa Elasticsearch bloğu yeniden uygular.","fix":"Diskte yeterli alan açın. 7.4+ sürümlerde otomatik konan blok, disk kullanımı high watermark'ın altına inince kendiliğinden kalkar; elle konmuş bir blok ya da beklemeden açmak için bloğu temizleyin: PUT /_all/_settings {\"index.blocks.read_only_allow_delete\": null}. Tek bir index için: PUT /index-adi/_settings {\"index.blocks.read_only_allow_delete\": null}. Sürekli tekrarlıyorsa disk kapasitesini artırın, ILM politikası kurun ve _cat/allocation ile hangi düğümün dolduğunu izleyin.","tags":["read-only","disk","forbidden","watermark","block","danger"]},{"code":"high_disk_watermark_exceeded","title":"high disk watermark [90%] exceeded / flood stage disk watermark [95%] exceeded","severity":"danger","meaning":"Bir düğümün disk doluluğu high watermark (varsayılan %90) veya flood stage (varsayılan %95) eşiğini aştı. High watermark aşıldığında Elasticsearch o düğümden shard'ları başka düğümlere taşımaya çalışır; flood stage aşıldığında index'leri salt okunur yapar.","cause":"Diskin dolması: log/metrik index'lerinin sürekli büyümesi, silinmeyen eski index'ler, temizlenmeyen snapshot repository'si, yetersiz disk boyutu veya dengesiz shard dağılımı nedeniyle tek düğümün aşırı dolması.","fix":"Disk kullanımını inceleyin: GET _cat/allocation?v. Eski index'leri silin veya snapshot alıp kaldırın, diski büyütün. Geçici olarak eşikleri yükseltebilirsiniz (dikkatli; 8.x'te max_headroom doğrulaması nedeniyle üç eşiği birlikte verin): PUT _cluster/settings {\"persistent\":{\"cluster.routing.allocation.disk.watermark.low\":\"88%\",\"cluster.routing.allocation.disk.watermark.high\":\"93%\",\"cluster.routing.allocation.disk.watermark.flood_stage\":\"96%\"}}. Sorun çözülünce aynı ayarlara null vererek varsayılana dönün (transient ayarlar deprecated'dır, kullanmayın). Kalıcı çözüm: ILM ile yaşam döngüsü yönetimi, düzenli index temizliği ve kapasite planlaması. Flood stage nedeniyle read-only olduysa bloğu ayrıca kaldırın.","tags":["disk","watermark","flood-stage","allocation","kapasite","danger"]},{"code":"circuit_breaking_exception","title":"CircuitBreakingException[[parent] Data too large, data for [<...>] would be [...], which is larger than the limit of [...]]","severity":"danger","meaning":"Bir istek, heap circuit breaker sınırını aşacağı için reddedildi. Elasticsearch, OutOfMemoryError ile düğümün çökmesini önlemek amacıyla isteği önceden durdurur. [parent] breaker tüm bellek kullanımını, [fielddata] breaker text alanları üzerindeki fielddata belleğini korur.","cause":"Yetersiz JVM heap, çok büyük/karmaşık agregasyonlar, geniş sonuç kümeleri, büyük bulk istekleri, text alanlara fielddata yüklenmesi veya aynı anda çok sayıda ağır sorgunun heap'i doldurması. Genellikle heap baskısının (heap pressure) belirtisidir.","fix":"Sorguları küçültün: agregasyon boyutunu, bulk batch boyutunu ve döndürülen alanları azaltın. Text alanlar üzerinde fielddata yerine keyword alt-alanı (.keyword) ile agregasyon yapın. JVM heap'i artırın (sunucu RAM'inin ~%50'si, en fazla ~31GB). Heap baskısını izleyin: GET _cat/nodes?v&h=name,heap.percent. Breaker limitlerini geçici artırmak yerine kök nedeni (bellek/sorgu) çözün. GET _nodes/stats/breaker ile hangi breaker'ın tetiklendiğine bakın.","tags":["circuit-breaker","data-too-large","heap","bellek","fielddata","oom","danger"]},{"code":"mapper_parsing_exception","title":"mapper_parsing_exception: failed to parse field [...] of type [...]","severity":"caution","meaning":"Bir belge indekslenirken, gönderilen alan değeri o alanın mapping'de tanımlı tipiyle uyuşmadı ve ayrıştırılamadı. Örneğin integer tanımlı bir alana metin, date tanımlı bir alana geçersiz tarih formatı gönderilmesi.","cause":"Alan tipi uyumsuzluğu (sayı alanına string, tarih alanına hatalı format), beklenen date formatına uymayan tarih, bozuk/eksik JSON, dinamik olarak yanlış tiplenmiş alanlar veya nesne (object) beklenen yere skaler değer gönderilmesi.","fix":"Hata mesajındaki alan adını ve beklenen tipi kontrol edin: GET /index-adi/_mapping. Gönderilen belgedeki değeri alanın tipine uygun hale getirin veya mapping'i doğru tiple yeniden tanımlayın. Tarih alanları için format parametresini belge biçimiyle eşleştirin. Var olan bir alanın tipi değiştirilemez; gerekirse yeni index oluşturup _reindex ile taşıyın. Uygulama katmanında veri doğrulaması yapın.","tags":["mapping","parse","mapper","alan-tipi","indeksleme","caution"]},{"code":"strict_dynamic_mapping_exception","title":"strict_dynamic_mapping_exception: mapping set to strict, dynamic introduction of [...] within [...] is not allowed","severity":"caution","meaning":"Index veya nesne mapping'i \"dynamic\": \"strict\" olarak ayarlı olduğu için, mapping'de tanımlı olmayan yeni bir alan içeren belge reddedildi. Strict mod, şema dışı alanların sessizce eklenmesini önler.","cause":"Belgede mapping'de bulunmayan bir alanın gönderilmesi (yazım hatası, yeni alan, beklenmeyen alan) ve mapping'in dynamic:strict olması. Genellikle şema kontrolünü sıkı tutmak için bilinçli konulan bir korumadır.","fix":"Belgedeki fazladan/yazımı hatalı alanı düzeltin veya kaldırın. Alan gerçekten gerekliyse önce mapping'e ekleyin: PUT /index-adi/_mapping {\"properties\": {\"yeni_alan\": {\"type\": \"...\"}}}. Yeni alanların otomatik eklenmesini istiyorsanız dynamic ayarını \"true\" veya kaydedilip indekslenmeyecekse \"false\" yapın. Şema disiplinini korumak için strict modu bilinçli kullanın.","tags":["mapping","strict","dynamic","sema","alan","caution"]},{"code":"illegal_argument_exception_fielddata","title":"illegal_argument_exception: Fielddata is disabled on text fields by default. Set fielddata=true on [your_field] in order to load fielddata in memory","severity":"caution","meaning":"Analiz edilen (analyzed) bir text alanı üzerinde aggregation, sorting veya scripting yapılmaya çalışıldı. Text alanlarda bu işlemler bellekte pahalı fielddata gerektirdiğinden varsayılan olarak kapalıdır.","cause":"Bir text alanına doğrudan agregasyon/sıralama uygulanması. Elasticsearch'te tam metin arama için text, tam-değer agregasyon/sıralama için keyword tipi kullanılır; ikisi karıştırıldığında bu hata çıkar.","fix":"Agregasyon/sıralama için alanın keyword alt-alanını kullanın (ör. \"my_field.keyword\"). Alan yalnızca text ise mapping'e bir keyword alt-alanı ekleyin (multi-field) ve _reindex yapın. Fielddata'yı text alanda açmak (fielddata=true) mümkündür ama yüksek bellek tüketimi ve circuit breaker riski nedeniyle önerilmez; yalnızca zorunlu durumlarda kullanın.","tags":["fielddata","text","keyword","aggregation","sorting","mapping","caution"]},{"code":"search_phase_execution_exception","title":"search_phase_execution_exception: all shards failed / Failed to execute phase [query]","severity":"danger","meaning":"Bir arama isteği, gerekli shard'ların bir veya tümünde başarısız oldu. Bu, altında yatan gerçek nedeni saran genel bir arama hatasıdır; \"caused by\" bölümünde asıl sorun (parse hatası, breaker, uygun olmayan alan tipi, shard erişilemez vb.) belirtilir.","cause":"Geçersiz sorgu sözdizimi, yanlış alan tipine agregasyon, too_many_clauses, circuit breaker tetiklenmesi, atanmamış/erişilemez shard, sorgu zaman aşımı veya bir düğümün çökmesi. Kök neden yanıttaki iç istisnadadır.","fix":"Yanıttaki \"caused by\" / \"failed_shards\" ayrıntılarına bakarak asıl istisnayı bulun ve ona göre düzeltin (sorgu düzeltme, keyword alanı kullanma, breaker/heap ayarı, shard atama). Küme sağlığını kontrol edin: GET _cluster/health ve GET _cat/shards?v. Kısmi sonuçlara izin veriliyorsa ve bazı shard'lar başarısızsa allow_partial_search_results davranışını gözden geçirin.","tags":["search","shard","arama","all-shards-failed","query","danger"]},{"code":"too_many_clauses","title":"too_many_clauses: maxClauseCount is set to 1024 (query contains too many clauses)","severity":"caution","meaning":"Bir sorgu, izin verilen maksimum Lucene clause sayısını aştı. ES 8.x'te bu sınır sabit değildir; düğümün heap boyutu ve search thread sayısına göre otomatik hesaplanır (küçük heap'li düğümlerde 1024'e kadar düşebilir) ve hata mesajında o anki değer yazar. Aşırı büyük bool sorguları ve çok sayıda terime genişleyen sorgular bunu tetikler.","cause":"Programatik olarak üretilen, binlerce should/must maddesi içeren bool sorguları; çok sayıda terime genişleyen wildcard/prefix/fuzzy/query_string sorguları; derin iç içe bool yapıları. Not: terms sorgusu (tek alanda değer listesi) bu sınıra takılmaz; onun üst sınırı index.max_terms_count'tur (varsayılan 65.536).","fix":"Sorguyu sadeleştirin: tek alandaki çok sayıda term maddesini tek bir terms sorgusuna (veya büyük listelerde terms lookup'a) dönüştürün. Wildcard/prefix yerine daha spesifik sorgu tipleri ya da index_prefixes/keyword alanları kullanın. ES 8.x'te indices.query.bool.max_clause_count ayarı deprecated'dır ve yok sayılır; sınırı yükseltmenin yolu düğüm heap'ini artırmaktır. Sorgu üretim mantığını gözden geçirin.","tags":["too-many-clauses","max-clause-count","bool","terms","query","caution"]},{"code":"version_conflict_engine_exception","title":"version_conflict_engine_exception: [_doc][id]: version conflict, current version [x] is different than the one provided [y] (HTTP 409)","severity":"caution","meaning":"Optimistic concurrency control (iyimser eşzamanlılık) nedeniyle bir belge güncelleme/silme isteği reddedildi. Belgenin sürümü (veya _seq_no/_primary_term) istekte verilenle eşleşmiyor; yani belge, siz okuduktan sonra başkası tarafından değiştirilmiş. HTTP 409 döner.","cause":"Aynı belgenin eşzamanlı güncellenmesi, eski version/seq_no ile yazma denemesi, create (op_type=create) ile zaten var olan belgeyi oluşturma girişimi veya _bulk sırasında yarış koşulu.","fix":"Belgeyi yeniden okuyup güncel _seq_no ve _primary_term (veya version) ile isteği tekrarlayın (read-modify-write döngüsü). Otomatik yeniden deneme için _update isteğinde retry_on_conflict parametresini kullanın; _update_by_query/_delete_by_query'de çakışan belgeleri atlayıp devam etmek için conflicts=proceed verin. Yalnızca oluşturma amaçlıysa çakışma normaldir; uygulamada 409'u yakalayıp uygun şekilde ele alın (yeniden dene veya atla).","tags":["version-conflict","409","concurrency","optimistic","seq-no","caution"]},{"code":"document_missing_exception","title":"document_missing_exception: [_doc][id]: document missing","severity":"caution","meaning":"Güncellenmek (_update) istenen belge index'te bulunamadı. Update işlemi var olan bir belgeyi gerektirir; belge yoksa bu istisna oluşur.","cause":"Belgenin daha önce silinmiş olması, hiç oluşturulmamış olması, yanlış _id kullanımı, yanlış index'e istek gönderilmesi veya özel routing ile yazılmış bir belgeye routing verilmeden erişilmesi. (GET ve _update gerçek zamanlıdır; refresh gecikmesi bu hataya yol açmaz.)","fix":"_id ve hedef index'in doğru olduğunu doğrulayın: GET /index-adi/_doc/id. Belge yoksa ve varsa güncelle/yoksa oluştur davranışı istiyorsanız _update isteğinde upsert (veya doc_as_upsert:true) kullanın. Belgeyi doğrudan index (PUT) ile oluşturun. Uygulamada bu istisnayı yakalayıp upsert mantığına düşürün.","tags":["document-missing","update","upsert","belge","not-found","caution"]},{"code":"index_not_found_exception","title":"index_not_found_exception: no such index [index_name] (HTTP 404)","severity":"caution","meaning":"İstenen index (veya alias) mevcut değil. Belirtilen ada sahip bir index bulunamadığı için işlem HTTP 404 ile reddedildi.","cause":"Index'in hiç oluşturulmamış olması, silinmiş olması, index/alias adında yazım hatası, yanlış ortama (cluster) bağlanma veya action.auto_create_index kapalıyken var olmayan index'e yazma denemesi.","fix":"Var olan index'leri listeleyin: GET _cat/indices?v. Adı ve alias'ı doğrulayın: GET _alias. Index'i oluşturun: PUT /index-adi (gerekli mapping/settings ile) veya bir index template ile otomatik oluşturmayı yapılandırın. Otomatik oluşturma isteniyorsa action.auto_create_index ayarını kontrol edin. Yanlış cluster'a bağlanmadığınızı doğrulayın.","tags":["index-not-found","404","indeks","alias","not-found","caution"]},{"code":"resource_already_exists_exception","title":"resource_already_exists_exception: index [index_name/uuid] already exists (HTTP 400)","severity":"safe","meaning":"Oluşturulmak istenen index (veya kaynak) zaten var. Aynı ada sahip bir index bulunduğu için oluşturma isteği reddedildi. Eski sürümlerde index_already_exists_exception olarak da görülür.","cause":"Aynı index'i iki kez oluşturmaya çalışmak, idempotent olmayan kurulum scriptleri, eşzamanlı oluşturma istekleri veya aynı adı farklı ayarlarla yeniden oluşturma girişimi.","fix":"Index zaten varsa oluşturmaya gerek yoktur; devam edin. Yeniden oluşturmak gerekiyorsa önce silin (DELETE /index-adi) sonra oluşturun (dikkat: veri kaybı). Kurulum scriptlerini idempotent yapın: önce GET _cat/indices ile varlığını kontrol edin. Şema yönetimi için index template veya ILM/rollover kullanarak çakışmaları önleyin.","tags":["already-exists","resource-already-exists","index","create","idempotent","safe"]},{"code":"cluster_health_red","title":"cluster health status: RED / unassigned shards","severity":"danger","meaning":"Küme sağlığı RED demektir: en az bir primary shard atanmamış (unassigned) ve erişilemez durumda. Bu, bazı verilerin okunamadığı/yazılamadığı, kısmi veri kaybı riski olan kritik bir durumdur. (YELLOW ise yalnızca replica'lar atanmamıştır, primary'ler sağlamdır.)","cause":"Bir düğümün çökmesi/ayrılması ve o düğümdeki primary shard'ların kopyasız kalması, disk watermark nedeniyle allocation engellenmesi, bozuk shard, snapshot geri yükleme sırasında hata veya allocation ayarlarının shard atamayı engellemesi.","fix":"Atanmamış shard'ların nedenini görün: GET _cluster/allocation/explain veya GET _cat/shards?v&h=index,shard,prirep,state,unassigned.reason. Çökmüş düğümleri geri getirin; disk sorunuysa yer açın (watermark). Atama geçici engellendiyse yeniden atamayı tetikleyin: POST _cluster/reroute?retry_failed=true. Primary tamamen kaybolduysa snapshot'tan geri yükleyin. RED durumda önce primary'leri kurtarmaya odaklanın.","tags":["cluster-health","red","unassigned","shard","primary","danger"]},{"code":"no_shard_available_action_exception","title":"no_shard_available_action_exception: No shard available for [...]","severity":"danger","meaning":"Bir isteği karşılayabilecek hiçbir aktif shard kopyası bulunamadı. İlgili shard atanmamış, kurtarılıyor veya barındıran düğüm erişilemez olduğundan istek yerine getirilemiyor.","cause":"Düğüm çökmesi/ağ bölünmesi, atanmamış (unassigned) shard'lar, devam eden shard recovery süreci, disk watermark nedeniyle atama engeli veya kümenin RED/YELLOW durumda olması.","fix":"Küme ve shard durumunu inceleyin: GET _cluster/health ve GET _cat/shards?v. Atanmamış shard nedenini görün: GET _cluster/allocation/explain. Çökmüş düğümleri geri getirin, disk sorununu çözün, recovery'nin bitmesini bekleyin: GET _cat/recovery?v&active_only=true. Gerekirse POST _cluster/reroute?retry_failed=true ile yeniden atamayı deneyin.","tags":["no-shard-available","shard","unassigned","recovery","cluster","danger"]},{"code":"es_rejected_execution_exception","title":"es_rejected_execution_exception: rejected execution of ... on ... (queue capacity ...) (HTTP 429)","severity":"danger","meaning":"Bir işlem, ilgili thread pool'un (search, write/bulk vb.) kuyruk kapasitesi dolduğu için reddedildi. Elasticsearch aşırı yük altında kendini korumak için istekleri geri çevirir (backpressure) ve HTTP 429 (Too Many Requests) döner.","cause":"Çok yüksek eşzamanlı istek hacmi, çok büyük veya çok sık bulk istekleri, ağır agregasyon/arama yükü, yetersiz düğüm/CPU kaynağı veya thread pool kuyruk boyutunun iş yüküne göre küçük kalması.","fix":"İstemci tarafında üstel geri çekilme (exponential backoff) ile yeniden deneyin; 429 normalde geçicidir. Bulk batch boyutunu küçültün ve gönderim hızını düşürün, eşzamanlılığı azaltın. Reddedilen işlemleri izleyin: GET _cat/thread_pool?v&h=node_name,name,active,queue,rejected. Kalıcı yük için düğüm/kaynak ekleyin (yatay ölçekleme). Kuyruk boyutunu artırmak son çaredir; kök neden kapasitedir.","tags":["rejected-execution","429","thread-pool","queue","bulk","backpressure","danger"]},{"code":"master_not_discovered_exception","title":"master_not_discovered_exception / MasterNotDiscoveredException","severity":"danger","meaning":"Küme aktif bir master düğümü seçemedi/bulamadı. Master olmadan shard atama, mapping değişikliği ve küme durumu güncellemeleri yapılamaz; küme işlem alamaz duruma gelir.","cause":"Master adayı (master-eligible) düğümlerin çoğunluğunun (quorum) erişilemez olması, ağ bölünmesi (split brain önleme), yanlış discovery.seed_hosts / cluster.initial_master_nodes yapılandırması, yeni kurulumda bootstrap yapılmaması veya master adayı düğüm sayısının yetersizliği.","fix":"Master adayı düğümlerin çalıştığını ve birbirini görebildiğini doğrulayın: GET _cat/nodes?v ve GET _cluster/state. discovery.seed_hosts ve cluster.initial_master_nodes ayarlarını (ilk kurulumda) kontrol edin. Ağ/güvenlik duvarı ve düğümler arası (transport 9300) bağlantıyı doğrulayın. Yeterli sayıda master adayı düğüm (tercihen 3) çalışır durumda tutun. Logları master seçim mesajları için inceleyin.","tags":["master","discovery","quorum","split-brain","cluster","danger"]},{"code":"security_exception","title":"security_exception: unable to authenticate / action [...] is unauthorized for user [...] (HTTP 401/403)","severity":"danger","meaning":"Kimlik doğrulama (401 Unauthorized) veya yetkilendirme (403 Forbidden) başarısız oldu. 401 kimlik bilgilerinin eksik/yanlış olduğunu; 403 kullanıcının doğrulandığını ama bu işlem/index için yeterli role/izne sahip olmadığını gösterir.","cause":"Yanlış kullanıcı adı/parola veya API key, eksik Authorization başlığı, süresi dolmuş/geçersiz token, kullanıcının ilgili index veya cluster ayrıcalığına sahip olmaması ya da rol atamasının eksik/hatalı olması.","fix":"401 için: doğru kimlik bilgilerini/API key'i gönderin ve Authorization başlığını kontrol edin. 403 için: kullanıcının rollerini ve ayrıcalıklarını inceleyin (GET _security/user/kullanici, GET _security/role/rol) ve gerekli index/cluster ayrıcalıklarını ekleyin. En az yetki (least privilege) ilkesine uyun. API key kullanıyorsanız süresini ve izinlerini doğrulayın.","tags":["security","401","403","authentication","authorization","guvenlik","danger"]},{"code":"validation_exception","title":"validation_exception / illegal_argument_exception: Validation Failed: ...","severity":"caution","meaning":"Bir isteğin parametreleri veya ayarları doğrulamadan geçemedi. Elasticsearch, geçersiz ya da tutarsız değer içeren isteği çalıştırmadan reddetti (ör. geçersiz shard sayısı, uyumsuz ayar kombinasyonu, eksik zorunlu alan).","cause":"Geçersiz index ayarı (ör. negatif/sıfır number_of_shards), var olan index'te değiştirilemez ayarı güncelleme denemesi, uyumsuz parametre kombinasyonu, eksik zorunlu alan veya sınır dışı değer.","fix":"Hata mesajındaki doğrulama ayrıntısını okuyun; hangi parametrenin neden geçersiz olduğu açıkça belirtilir. İlgili değeri geçerli aralığa/biçime getirin. Değiştirilemez (static) ayarları var olan index'te değil, yeni index oluştururken belirtin (gerekirse _reindex). API'nin beklediği zorunlu alanları tamamlayın. İlgili ayarın belgelenmiş geçerli değerlerini doğrulayın.","tags":["validation","dogrulama","settings","illegal-argument","gecersiz","caution"]},{"code":"task_cancelled_exception","title":"task_cancelled_exception: Task was cancelled / TaskCancelledException","severity":"caution","meaning":"Çalışan bir görev (arama, _reindex, _update_by_query vb.) iptal edildi. İptal, kullanıcının _tasks/_cancel isteğiyle, istemcinin HTTP bağlantısını kapatmasıyla (istemci timeout/abort; Elasticsearch bağlı aramayı otomatik iptal eder) veya üst (parent) görevin ya da süresi dolan async search'ün iptaliyle gerçekleşebilir.","cause":"Kullanıcının görevi POST _tasks/<task_id>/_cancel ile iptal etmesi (X-Opaque-Id yalnız görevi tanımlamaya ve bulmaya yarar, iptal etmez), istemci timeout'unun bağlantıyı kesmesi, uzun süren pahalı sorgular veya adaptif kaynak yönetiminin ağır görevi durdurması.","fix":"Görev beklenmedik şekilde iptal olduysa istemci timeout ve bağlantı ayarlarını gözden geçirin; ağır sorguyu optimize edin (daha az veri, daha spesifik filtre). Uzun işlemler için _reindex/_update_by_query'yi asenkron (wait_for_completion=false) çalıştırıp GET _tasks ile izleyin. Aktif görevleri görüntüleyin: GET _tasks?detailed=true. Gerekirse pahalı sorguları parçalayın veya scroll/PIT kullanın.","tags":["task-cancelled","gorev","timeout","reindex","cancel","caution"]}]},"errors/oracle-more.json":{"engineId":"oracle","engine":"Oracle","order":1,"errors":[{"code":"ORA-00604","title":"error occurred at recursive SQL level","severity":"danger","meaning":"Oracle'ın arka planda kendi çalıştırdığı özyinelemeli (recursive) SQL sırasında bir hata oluştu. Bu asıl hatayı gizleyen bir sarmalayıcı (üst) hatadır; gerçek sebep hemen altında listelenen ikinci hata kodunda yer alır.","cause":"Sözlük (data dictionary) erişimi, bir DDL trigger'ının hata vermesi, sistem tablespace'inin dolması, geçici alan yetersizliği, bozuk bir veri sözlüğü nesnesi veya oturum açılışında çalışan LOGON trigger'ının başarısız olması.","fix":"Hata stack'inde ORA-00604'ten hemen sonra gelen ikinci satırı okuyun; asıl neden odur ve onu çözün. Örneğin ORA-01653 görürseniz tablespace genişletin. Şüpheli bir DDL/LOGON trigger varsa geçici olarak devre dışı bırakın: ALTER TRIGGER trigger_adi DISABLE; SYSTEM ve TEMP tablespace doluluğunu DBA_FREE_SPACE ile kontrol edin.","tags":["recursive","ozyineleme","dictionary","sozluk","trigger","wrapper"]},{"code":"ORA-01438","title":"value larger than specified precision allowed for this column","severity":"caution","meaning":"Bir NUMBER sütununa, tanımlanan hassasiyet (precision) ve ölçek (scale) sınırlarını aşan bir sayı yazılmaya çalışıldı. Örneğin NUMBER(4,2) sütununa tam kısmı 3 basamaklı bir değer sığmaz.","cause":"Sütunun NUMBER(p,s) tanımının veriye göre çok dar olması; hesaplama sonucu beklenenden büyük çıkması; ondalık ölçek nedeniyle tam kısım için kalan basamak sayısının azalması (NUMBER(5,3) yalnızca 2 tam basamağa izin verir).","fix":"Sütunun kapasitesini gerçek veri aralığına göre genişletin: ALTER TABLE tablo MODIFY (sutun NUMBER(12,2)); Uygulama tarafında değeri yuvarlayın ya da ROUND/TRUNC ile ölçeğe uydurun. Hangi satırın taştığını bulmak için sorgunuzu daraltarak test edin ve giriş doğrulaması ekleyin.","tags":["number","precision","hassasiyet","scale","olcek","overflow","sayi"]},{"code":"ORA-01400","title":"cannot insert NULL into (column)","severity":"caution","meaning":"NOT NULL constraint'i bulunan bir sütuna NULL değer eklenmeye ya da o sütun NULL yapılmaya çalışıldı. Zorunlu bir alan boş bırakılamaz.","cause":"INSERT ifadesinde zorunlu sütuna değer verilmemesi, UPDATE ile sütunun NULL'a çekilmesi, sütun için DEFAULT tanımlı olmaması veya alt sorgudan/uygulamadan boş değer gelmesi.","fix":"Hata mesajındaki sütun adına geçerli bir değer girin. Sütuna makul bir varsayılan tanımlayın: ALTER TABLE tablo MODIFY (sutun DEFAULT 0); (DEFAULT yalnızca sütun INSERT'te hiç belirtilmediğinde devreye girer; açıkça NULL gönderilen değerler için 12c+ DEFAULT ON NULL kullanın: ALTER TABLE tablo MODIFY (sutun DEFAULT ON NULL 0);) Kural gerçekten zorunlu değilse constraint'i kaldırın: ALTER TABLE tablo MODIFY (sutun NULL); Uygulamada boş değerleri gönderilmeden önce doğrulayın.","tags":["not null","null","bos","insert","constraint","kisit","zorunlu"]},{"code":"ORA-02291","title":"integrity constraint violated - parent key not found","severity":"danger","meaning":"Foreign key constraint'i ihlal edildi. Alt (child) tabloya eklenen değere karşılık gelen bir üst (parent) satır bulunamadı; yani referans verilen kayıt mevcut değil.","cause":"Var olmayan bir üst kayda referans veren INSERT/UPDATE, üst tablo satırının henüz eklenmemiş olması, yükleme sırasının yanlış olması (önce alt sonra üst) veya büyük/küçük harf ya da boşluk farkı nedeniyle eşleşmenin tutmaması.","fix":"Önce üst tabloya ilgili kaydı ekleyin, sonra alt tabloya. Referansın var olup olmadığını doğrulayın: SELECT * FROM parent_tablo WHERE anahtar = deger; Toplu yüklemede tabloları doğru sırada (önce parent) işleyin. İhlal eden satırı bulmak için alt tablodaki değeri üst tabloyla NOT IN / anti-join ile karşılaştırın.","tags":["fk","foreign key","yabanci anahtar","constraint","kisit","parent","referans"]},{"code":"ORA-02292","title":"integrity constraint violated - child record found","severity":"danger","meaning":"Bir üst (parent) satır silinmeye ya da anahtarı değiştirilmeye çalışıldı, ancak ona bağlı alt (child) kayıtlar bulunduğu için foreign key constraint'i buna izin vermedi.","cause":"Alt tabloda kayıtları olan bir üst satırı DELETE etmeye çalışmak; FK'nın ON DELETE CASCADE olmadan tanımlı olması; bağımlı kayıtların önce temizlenmemesi.","fix":"Önce bağımlı alt kayıtları silin ya da başka bir üst kayda taşıyın, ardından üst satırı silin. İş kuralı uygunsa foreign key'i ON DELETE CASCADE olacak şekilde yeniden oluşturun: ALTER TABLE alt DROP CONSTRAINT fk_ad; ALTER TABLE alt ADD CONSTRAINT fk_ad FOREIGN KEY (sutun) REFERENCES ust(anahtar) ON DELETE CASCADE; Bağlı satırları bulmak için alt tabloyu üst anahtara göre sorgulayın.","tags":["fk","foreign key","yabanci anahtar","child","alt kayit","delete","cascade"]},{"code":"ORA-00979","title":"not a GROUP BY expression","severity":"caution","meaning":"SELECT listesinde bir toplama (aggregate) fonksiyonu (SUM, COUNT vb.) ile birlikte toplanmayan bir sütun kullanıldı ama bu sütun GROUP BY yan tümcesine eklenmedi. Oracle bu sütunu nasıl gruplayacağını bilemez.","cause":"SELECT'te yer alan ancak GROUP BY'da olmayan bir sütun; toplama fonksiyonu içinde olmayan ifadelerin GROUP BY listesinden eksik kalması; HAVING veya seçim ifadelerindeki tutarsızlık.","fix":"Toplanmayan tüm sütunları GROUP BY listesine ekleyin: SELECT bolum, COUNT(*) FROM calisan GROUP BY bolum; Alternatif olarak o sütunu da bir toplama fonksiyonuna (MAX, MIN) alın ya da analitik fonksiyon (OVER()) kullanarak gruplamayı yeniden tasarlayın.","tags":["group by","gruplama","aggregate","toplama","sum","count","sorgu"]},{"code":"ORA-00918","title":"column ambiguously defined","severity":"caution","meaning":"Sorguda birden fazla tabloda aynı ada sahip bir sütun bulunuyor ve bu sütun tablo/alias öneki olmadan kullanıldığından Oracle hangi tabloya ait olduğunu belirleyemiyor.","cause":"JOIN edilen iki tabloda da aynı isimli sütun olması (örn. her ikisinde de ID); SELECT, WHERE ya da ORDER BY'da sütunun niteliksiz (öneksiz) kullanılması.","fix":"Belirsiz her sütunu tablo adı veya alias ile nitelendirin: SELECT a.id, b.id FROM tabloA a JOIN tabloB b ON a.id = b.a_id; Tablolara kısa alias verip tüm sütunlara önek ekleyerek okunabilirliği ve netliği artırın.","tags":["ambiguous","belirsiz","column","sutun","join","alias","sorgu"]},{"code":"ORA-06550","title":"line/column PLS-... PL/SQL compilation error","severity":"caution","meaning":"Bir PL/SQL bloğu, prosedür ya da anonim blok derlenirken sözdizimi veya anlamsal bir hata bulundu. Kod çalıştırılamadan derleme aşamasında başarısız oldu.","cause":"Yazım hataları, tanımlanmamış değişken veya nesne referansı, yanlış parametre sayısı/türü ile çağrı, eksik noktalı virgül, var olmayan bir prosedür/paket çağrısı ya da yetki eksikliği.","fix":"Hata mesajındaki satır ve sütun numarasına gidin; PLS-XXXX alt kodunu okuyun. Derleme hatalarının tamamını görmek için: SHOW ERRORS; veya SELECT * FROM user_errors WHERE name = 'NESNE_ADI'; Nesne adlarını, parametre imzalarını ve gerekli GRANT'leri doğrulayın, ardından yeniden derleyin.","tags":["plsql","compilation","derleme","pls","syntax","prosedur","kod"]},{"code":"ORA-04068","title":"existing state of packages has been discarded","severity":"caution","meaning":"Çalışmakta olan bir oturum, bir paketin (package) durumunu (state) kullanırken paket yeniden derlendiği için o durum geçersiz kılındı. Oturumun elindeki paket örneği artık geçerli değildir.","cause":"Bir paketin gövdesi ya da başlığı, ona bağlı oturumlar aktifken ALTER/CREATE OR REPLACE ile yeniden derlenmesi; genellikle canlı sistemde uygulama dağıtımı sırasında oluşur. ORA-04061/04065 ile birlikte görülür.","fix":"Genellikle çağrıyı yeniden çalıştırmak (retry) sorunu çözer; ikinci denemede paket yeni haliyle yüklenir. Uygulamada ORA-04068'i yakalayıp otomatik yeniden deneme yapın. Paket değişikliklerini kullanıcıların yoğun olmadığı bakım pencerelerinde uygulayın. Durum tutmayan (stateless) paket tasarımı bu sorunu azaltır.","tags":["package","paket","state","durum","recompile","derleme","retry"]},{"code":"ORA-01427","title":"single-row subquery returns more than one row","severity":"caution","meaning":"Tek bir satır dönmesi beklenen bir alt sorgu (subquery) birden fazla satır döndürdü. Örneğin bir eşitlik (=) karşılaştırmasının sağındaki alt sorgu birden çok değer üretti.","cause":"= veya bir atama beklendiği yerde birden çok satır dönen alt sorgu; yeterince daraltılmamış WHERE koşulu; ilişkilendirmede (correlation) benzersiz olmayan eşleşme; SELECT listesindeki skaler alt sorgunun birden çok satır getirmesi.","fix":"Alt sorguyu tek satır dönecek şekilde daraltın (ek WHERE, unique key). Gerçekten birden çok değer bekleniyorsa = yerine IN kullanın: WHERE id IN (SELECT id FROM ...). Ya da alt sorguya toplama ekleyin (MAX, MIN) veya ROWNUM = 1 ile tek satıra indirin. Önce alt sorguyu tek başına çalıştırıp kaç satır döndüğünü kontrol edin.","tags":["subquery","alt sorgu","single row","tek satir","in","scalar","sorgu"]},{"code":"ORA-12899","title":"value too large for column","severity":"caution","meaning":"Bir karakter/veri sütununa, tanımlı maksimum uzunluğundan daha uzun bir değer yazılmaya çalışıldı. Örneğin VARCHAR2(10) sütununa 15 karakterlik metin sığmaz.","cause":"Sütun genişliğinin veriye göre yetersiz olması; çok baytlı karakter kümesinde (UTF8) karakter sayısının bayt sınırını aşması (BYTE semantiği); veri göçünde farklı karakter kümesi; birleştirme (concat) sonucunun uzaması.","fix":"Sütunu genişletin: ALTER TABLE tablo MODIFY (sutun VARCHAR2(100)); Çok baytlı içerik için CHAR semantiği kullanın: sutun VARCHAR2(100 CHAR). Uzun değerleri kısaltmak gerekiyorsa SUBSTR ile budayın. Hata mesajı gerçek ve izin verilen uzunluğu verir; hangi kaydın taştığını LENGTH/LENGTHB ile bulun.","tags":["varchar2","length","uzunluk","too large","column","sutun","charset"]},{"code":"ORA-30926","title":"unable to get a stable set of rows in the source tables","severity":"danger","meaning":"Bir MERGE (veya güncellenebilir join) ifadesinde, kaynak (source) tarafı hedefteki (target) aynı satır için birden fazla eşleşen satır üretti. Oracle hangi kaynak değeriyle güncelleyeceğine karar veremediği için işlemi durdurdu.","cause":"MERGE ... USING kaynağının, ON koşulu için mükerrer (duplicate) eşleşmeler içermesi; kaynak sorgusunun hedef anahtarına göre benzersiz olmaması; birden çok kaynak satırının aynı hedef satıra denk gelmesi.","fix":"Kaynak sorgusunu hedef anahtarına göre benzersiz hale getirin. Mükerrer eşleşmeleri bulun: SELECT anahtar, COUNT(*) FROM (kaynak_sorgu) GROUP BY anahtar HAVING COUNT(*) > 1; Kaynağı DISTINCT ya da bir toplama/analitik (ROW_NUMBER) ile tekilleştirin, sonra MERGE'i tekrar çalıştırın. ON koşulunun yeterince ayırt edici olduğundan emin olun.","tags":["merge","birlestir","duplicate","mukerrer","source","kaynak","stable"]},{"code":"ORA-08103","title":"object no longer exists","severity":"danger","meaning":"Bir sorgu çalışırken eriştiği nesne (tablo, index, LOB segmenti) artık mevcut değil ya da fiziksel yapısı değişti. Genellikle sorgu devam ederken nesnenin altında bir DDL/TRUNCATE gerçekleşmesidir.","cause":"Sorgu açıkken aynı nesnenin TRUNCATE/DROP/SHRINK edilmesi; taşıma (MOVE) veya bölüm (partition) bakımı; bozuk index/segment; LOB segmentine erişilirken alttaki yapının kaybolması; eşzamanlı DDL çakışması.","fix":"Nesnenin hâlâ var ve geçerli olduğunu doğrulayın: SELECT status FROM user_objects WHERE object_name = 'AD'; İlgili index/nesneyi yeniden oluşturun (REBUILD) veya sorguyu tekrar çalıştırın. Uzun süren sorgular çalışırken ilgili nesnelerde TRUNCATE/DROP yapmaktan kaçının. Bozukluk şüphesinde ANALYZE ... VALIDATE STRUCTURE ile kontrol edin.","tags":["object","nesne","truncate","drop","ddl","corruption","segment"]},{"code":"ORA-01843","title":"not a valid month","severity":"caution","meaning":"Bir metin, tarihe (DATE) dönüştürülürken ay bölümü geçerli bir ay olarak yorumlanamadı. Genellikle tarih biçimi (format) ile verinin biçimi uyuşmuyordur.","cause":"TO_DATE'e format maskesi verilmemesi ve oturumun NLS_DATE_FORMAT değerinin veriyle uyuşmaması; gün ile ayın yer değiştirmesi (DD/MM ile MM/DD karışması); dil/locale farkı (ay adlarında); bozuk ya da beklenmeyen tarih metni.","fix":"TO_DATE çağrısında her zaman açık bir format verin: TO_DATE('2026-07-04', 'YYYY-MM-DD'). Ay adı içeren metinlerde dili belirtin: TO_DATE(str, 'DD-MON-YYYY', 'NLS_DATE_LANGUAGE=TURKISH'). Oturum biçimini gerekiyorsa ayarlayın: ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD'. Geçersiz tarih metinlerini yüklemeden önce doğrulayın.","tags":["date","tarih","to_date","nls","format","month","ay"]},{"code":"ORA-14400","title":"inserted partition key does not map to any partition","severity":"danger","meaning":"Eklenen satırdaki bölümleme (partition) anahtarı değeri, tabloda tanımlı hiçbir bölüme denk gelmiyor. Değeri karşılayacak bir aralık (range) ya da liste (list) bölümü mevcut değil.","cause":"RANGE bölümlemede en yüksek aralığın üstünde bir tarih/değer eklenmesi ve MAXVALUE bölümünün olmaması; LIST bölümlemede tanımlı olmayan yeni bir değer; ay/yıl geçişinde yeni bölümün önceden oluşturulmamış olması.","fix":"Eksik bölümü ekleyin: ALTER TABLE tablo ADD PARTITION p_2026_08 VALUES LESS THAN (TO_DATE('2026-09-01','YYYY-MM-DD')); RANGE için güvenlik amacıyla MAXVALUE bölümü ekleyin. Beklenmedik değerleri yakalamak için LIST'e DEFAULT bölümü tanımlayın. Otomatik bölümleme (INTERVAL partitioning) kullanarak yeni bölümlerin kendiliğinden oluşmasını sağlayın.","tags":["partition","bolum","partition key","range","list","maxvalue","insert"]},{"code":"ORA-01536","title":"space quota exceeded for tablespace","severity":"danger","meaning":"Kullanıcının belirtilen tablespace üzerindeki alan kotası (quota) doldu. Tablespace'te boş yer olsa bile kullanıcıya tanınan sınır aşıldığı için yeni alan ayrılamıyor.","cause":"Kullanıcıya sınırlı kota verilmiş olması (UNLIMITED değil); veri büyümesiyle kotanın dolması; bir tabloya/index'e aşırı yükleme; yanlış tablespace'e yazma; segmentlerin beklenenden hızlı büyümesi.","fix":"Kullanıcının kotasını artırın: ALTER USER kullanici QUOTA UNLIMITED ON tablespace_adi; veya belirli bir değer verin: QUOTA 500M ON users. Mevcut kullanımı görün: SELECT * FROM dba_ts_quotas WHERE username = 'KULLANICI'. Gereksiz büyük segmentleri arşivleyin/temizleyin veya nesneleri uygun tablespace'e taşıyın.","tags":["quota","kota","tablespace","space","alan","user","kullanici"]},{"code":"direct path read","title":"Wait: oturum, buffer cache'i atlayıp blokları doğrudan PGA'ya okuyor","severity":"caution","meaning":"Oturum, blokları veritabanı buffer cache üzerinden değil doğrudan PGA belleğine okurken bu wait event'inde zaman harcıyor. Genellikle büyük tam tablo taramaları (full table scan) ve paralel sorgularla ilişkilidir.","cause":"Büyük tabloların tam taranması, paralel sorgular, geçici tablespace'e taşan sıralama/hash işlemleri, seri tam tarama için doğrudan okuma kararı (serial direct path read) ve index kullanılamayan sorgular nedeniyle çok sayıda bloğun diskten okunması.","fix":"Ağır tam tarama yapan SQL'leri AWR/ASH ile tespit edin ve uygun index'ler ekleyin. Gereksiz büyük tabloların taranmasını sorgu ayarıyla azaltın. Depolama gecikmesini (I/O) inceleyin, gerekirse daha hızlı disklere geçin. Paralel derecesini gözden geçirin. TEMP'e taşan işlemler için PGA_AGGREGATE_TARGET boyutunu değerlendirin.","tags":["wait","bekleme","direct path read","full scan","tam tarama","io","pga"]},{"code":"latch: cache buffers chains","title":"Wait: cache buffers chains latch üzerinde contention","severity":"danger","meaning":"Buffer cache içindeki blokları koruyan cache buffers chains (CBC) latch'i üzerinde çekişme (contention) yaşanıyor. Birçok oturum aynı sık erişilen (hot) bloklara ulaşmaya çalıştığında bu bekleme artar.","cause":"Sık okunan hot block'lar; verimsiz, yüksek mantıksal okuma (logical read) üreten SQL'ler; nested loop join'lerde aynı index köklerine tekrar tekrar erişim; eşit dağılmayan yoğun eşzamanlı erişim; küçük ama çok okunan tablolar.","fix":"En çok mantıksal okuma üreten SQL'leri bulun (V$SQL, ASH) ve index/erişim planını iyileştirerek buffer erişimini azaltın. Hot block'ları belirleyin (X$BH / ilgili view'lar). Gereksiz nested loop'ları hash join'e çevirmeyi değerlendirin. Yoğun okunan küçük referans tablolarında erişim desenini dağıtın veya önbellekleyin.","tags":["latch","cache buffers chains","cbc","contention","cekisme","hot block","wait","bekleme"]}]},"errors/postgres-more.json":{"engineId":"postgres","engine":"PostgreSQL","order":2,"errors":[{"code":"42883","title":"undefined_function","severity":"caution","meaning":"Sorguda çağrılan fonksiyon (ya da operatör) bu ad ve argüman tipleriyle bulunamadı. PostgreSQL fonksiyonları hem ada hem de argüman tiplerine göre çözer; imza eşleşmezse bu hata çıkar.","cause":"Fonksiyon adının yanlış yazılması; argüman tiplerinin tanımlı imzayla uyuşmaması (örn. metin yerine sayı); gerekli açık tür dönüşümünün (cast) yapılmaması; fonksiyonun bulunduğu şemanın search_path içinde olmaması; eklentinin (extension) kurulu olmaması.","fix":"Fonksiyonun var olduğunu ve imzasını doğrulayın: \\df fonksiyon_adi. Argümanları açıkça dönüştürün: SELECT fn(deger::text). Şema önekini ekleyin ya da search_path ayarlayın. Eklenti gerekiyorsa kurun: CREATE EXTENSION eklenti_adi; Operatör hatasında iki tarafın tiplerini eşitleyin.","tags":["function","fonksiyon","undefined","operator","cast","donusum","42883"]},{"code":"42804","title":"datatype_mismatch","severity":"caution","meaning":"Beklenen veri tipi ile sağlanan veri tipi uyuşmuyor. Örneğin bir sütuna yanlış tipte değer atanması, CASE dallarının farklı tip döndürmesi ya da UNION taraflarının tiplerinin tutmaması.","cause":"Sütun tipiyle uyuşmayan atama; CASE/COALESCE dallarının farklı tip üretmesi; UNION sorgularında karşılık gelen sütunların tiplerinin farklı olması; fonksiyon dönüş tipiyle RETURN edilen değerin uyuşmaması; boolean beklenen yerde başka tip.","fix":"İlgili ifadeyi doğru tipe dönüştürün: deger::integer veya CAST(deger AS numeric). CASE tüm dallarının aynı tipi döndürmesini sağlayın. UNION'da her iki tarafta karşılıklı sütun tiplerini eşitleyin. WHERE koşulunun boolean üretmesine dikkat edin.","tags":["type","tip","mismatch","uyusmazlik","cast","union","42804"]},{"code":"22P02","title":"invalid_text_representation","severity":"caution","meaning":"Bir metin değeri, hedef veri tipine dönüştürülürken geçerli bir gösterim değildi. Örneğin 'abc' metnini integer'a çevirmeye çalışmak bu hatayı üretir.","cause":"Sayısal bir sütuna/parametreye sayı olmayan metin gönderilmesi; boş dize ('') değerinin sayı/tarih olarak dönüştürülmesi; UUID ya da enum için geçersiz metin; yanlış biçimli JSON; giriş verisinin beklenen formatta olmaması.","fix":"Dönüştürülen değerin gerçekten geçerli olduğunu doğrulayın. Uygulamada tip dönüşümünden önce giriş doğrulaması yapın. Boş dizeleri NULL'a çevirin: NULLIF(deger, ''). Güvenli dönüşüm için PostgreSQL 16+ sürümünde pg_input_is_valid('abc', 'integer') ile değeri önceden sınayın, hata ayrıntısı için pg_input_error_info() kullanın; eski sürümlerde bir doğrulama sorgusu (regex) değerlendirin. Hangi satırın bozuk olduğunu daraltarak bulun.","tags":["cast","donusum","invalid text","gecersiz","integer","uuid","22P02"]},{"code":"22003","title":"numeric_value_out_of_range","severity":"caution","meaning":"Bir sayısal değer, hedef tipin izin verdiği aralığın dışında. Örneğin bir integer sütununa 2 milyardan büyük bir değer ya da numeric(5,2) sütununa çok büyük bir sayı yazmaya çalışmak.","cause":"smallint/integer/bigint sınırlarının aşılması; numeric(p,s) hassasiyet/ölçek sınırının aşılması; aritmetik taşma (overflow); toplama/çarpma sonucunun tip kapasitesini geçmesi; sequence'in tip üst sınırına ulaşması.","fix":"Sütun/parametre tipini daha geniş bir tiple değiştirin (integer yerine bigint, numeric hassasiyetini artırın): ALTER TABLE tablo ALTER COLUMN sutun TYPE bigint; Değeri iş kuralına göre yuvarlayın (ROUND) ya da doğrulayın. Ara hesap taşıyorsa ifadeyi numeric'e çevirerek hesaplayın. Sequence taşmasında tipi büyütün.","tags":["numeric","sayi","out of range","overflow","tasma","integer","22003"]},{"code":"23514","title":"check_violation","severity":"caution","meaning":"Bir CHECK constraint'i ihlal edildi. Eklenen ya da güncellenen satır, tabloda tanımlı bir mantıksal koşulu (örn. fiyat > 0) sağlamıyor.","cause":"İş kuralını ihlal eden veri (negatif fiyat, geçersiz durum kodu, tarih aralığı ihlali); uygulama tarafında doğrulama yapılmaması; constraint'in veriye göre çok katı olması; toplu yüklemede kurala uymayan kayıtlar.","fix":"Hata mesajındaki constraint adına bakarak hangi koşulun ihlal edildiğini bulun; tanımı görün: \\d tablo_adi. İhlal eden satırları koşulu tersine çevirerek sorgulayın. Veriyi düzeltin ya da kural gerçekten değiştiyse constraint'i güncelleyin: ALTER TABLE tablo DROP CONSTRAINT ad; ALTER TABLE tablo ADD CONSTRAINT ad CHECK (yeni_kosul);","tags":["check","constraint","kisit","violation","ihlal","validation","23514"]},{"code":"22012","title":"division_by_zero","severity":"caution","meaning":"Bir aritmetik ifadede sıfıra bölme (ya da sıfırla modulo) yapılmaya çalışıldı. PostgreSQL sıfıra bölmeye izin vermez ve sorguyu durdurur.","cause":"Bölen sütun/ifadenin değerinin 0 olması; oran/yüzde hesabında paydanın sıfır çıkması; COUNT ya da SUM sonucunun sıfır olduğu bir bölme; filtrelenmemiş veride beklenmedik sıfır değerler.","fix":"Payda sıfır olduğunda NULL döndürmek için NULLIF kullanın: pay / NULLIF(payda, 0). Sonucu isterseniz COALESCE ile varsayılana çevirin: COALESCE(pay / NULLIF(payda,0), 0). Ya da CASE WHEN payda = 0 THEN NULL ELSE pay/payda END kullanın. Verideki sıfır durumlarını önceden filtreleyin.","tags":["division","bolme","zero","sifir","nullif","arithmetic","22012"]},{"code":"42601","title":"syntax_error","severity":"caution","meaning":"SQL ifadesinde bir sözdizimi (syntax) hatası bulundu. PostgreSQL sorguyu ayrıştıramadı ve hatanın yaklaşık konumunu (position) belirtir.","cause":"Eksik/fazla virgül veya parantez; ayrılmış bir anahtar kelimenin (user, order gibi) tırnaksız sütun adı olarak kullanılması; eksik nokta/virgül; yanlış yazılmış komut; string tırnaklarının kapanmaması; sürüme özgü sözdizimi kullanımı.","fix":"Hata mesajındaki 'position' değerine bakarak sorunlu noktayı bulun; oradan hemen önceki kısmı inceleyin. Ayrılmış kelimeleri çift tırnakla nitelendirin: \"order\". Parantez ve tırnak dengesini kontrol edin. Karmaşık sorguyu parçalara bölerek test edin. Doğru sözdizimi için sürüm belgelerine bakın.","tags":["syntax","sozdizimi","parse","ayristirma","keyword","position","42601"]},{"code":"42P07","title":"duplicate_table","severity":"caution","meaning":"Oluşturulmaya çalışılan tablo (ya da benzeri nesne) zaten mevcut. Aynı ada sahip bir nesne bulunduğu için CREATE başarısız oldu.","cause":"CREATE TABLE ile zaten var olan bir tablonun yeniden oluşturulması; betiğin (script) iki kez çalıştırılması; migrasyonların tekrar uygulanması; aynı isimli bir view/sequence/index çakışması.","fix":"Nesne zaten varsa oluşturmayı atlamak için IF NOT EXISTS kullanın: CREATE TABLE IF NOT EXISTS tablo (...). Gerçekten yeniden oluşturmak istiyorsanız önce silin: DROP TABLE IF EXISTS tablo; Migrasyonların tekrar çalışmaya (idempotent) dayanıklı olmasını sağlayın. Var olan nesneyi \\dt ile kontrol edin.","tags":["duplicate","mukerrer","table","tablo","create","already exists","42P07"]},{"code":"42701","title":"duplicate_column","severity":"caution","meaning":"Bir tablo tanımında ya da ALTER işleminde aynı sütun adı birden fazla kez kullanıldı veya zaten var olan bir sütun tekrar eklenmeye çalışıldı.","cause":"CREATE TABLE içinde aynı sütun adının iki kez yazılması; ALTER TABLE ADD COLUMN ile hâlihazırda var olan bir sütunun eklenmesi; kopyala-yapıştır hatası; migrasyonun tekrar çalışması.","fix":"Tablo tanımındaki mükerrer sütun adını kaldırın ya da yeniden adlandırın. Var olan sütunu tekrar eklemekten kaçınmak için önce kontrol edin: \\d tablo_adi. Sürüm destekliyorsa güvenli ekleme yapın: ALTER TABLE tablo ADD COLUMN IF NOT EXISTS sutun tip; Migrasyonların idempotent olduğundan emin olun.","tags":["duplicate","mukerrer","column","sutun","alter","add column","42701"]},{"code":"3D000","title":"invalid_catalog_name","severity":"danger","meaning":"Bağlanılmak ya da erişilmek istenen veritabanı (database) mevcut değil. Belirtilen adla bir veritabanı bulunamadı.","cause":"Bağlantı dizesinde veritabanı adının yanlış yazılması; veritabanının henüz oluşturulmamış ya da silinmiş olması; büyük/küçük harf duyarlılığı; yanlış sunucuya bağlanma; ortam (env) yapılandırmasında hatalı isim.","fix":"Var olan veritabanlarını listeleyin: psql -l ya da SELECT datname FROM pg_database. Bağlantı dizesindeki veritabanı adını düzeltin. Gerekliyse oluşturun: CREATE DATABASE veritabani_adi; Doğru sunucuya/porta bağlandığınızı doğrulayın. Uygulama yapılandırmasındaki DB adını kontrol edin.","tags":["database","veritabani","catalog","does not exist","yok","connection","3D000"]},{"code":"3F000","title":"invalid_schema_name","severity":"caution","meaning":"Başvurulan şema (schema) mevcut değil ya da search_path içinde bulunamadı. Belirtilen şema adıyla bir şema yok.","cause":"Şema adının yanlış yazılması; şemanın oluşturulmamış olması; search_path'in ilgili şemayı içermemesi; büyük/küçük harf farkı; nesneye şema önekiyle erişilirken yanlış önek kullanılması.","fix":"Var olan şemaları listeleyin: \\dn ya da SELECT schema_name FROM information_schema.schemata. Şema adını düzeltin. Gerekliyse oluşturun: CREATE SCHEMA sema_adi; search_path'i ayarlayın: SET search_path TO sema_adi, public; Nesnelere doğru şema önekiyle erişin.","tags":["schema","sema","search_path","does not exist","yok","invalid","3F000"]},{"code":"0A000","title":"feature_not_supported","severity":"caution","meaning":"Kullanılmaya çalışılan özellik bu bağlamda ya da bu PostgreSQL sürümünde desteklenmiyor. İstenen işlem geçerli olsa da mevcut durumda uygulanamaz.","cause":"Sürümde henüz bulunmayan bir sözdizimi/özellik; belirli sütun/tablo tipinde desteklenmeyen bir ALTER; foreign data wrapper (FDW) tarafından desteklenmeyen işlem; mantıksal replikasyon/constraint kombinasyonlarının kısıtları; belirli veri tiplerinde izin verilmeyen dönüşümler.","fix":"Hata mesajının tamamını okuyun; genellikle neyin desteklenmediğini açıkça belirtir. Alternatif bir yaklaşım kullanın (örn. sütun tipini doğrudan değiştirmek yerine yeni sütun + kopyalama + yeniden adlandırma). Özellik daha yeni bir sürümde geldiyse yükseltmeyi değerlendirin. FDW/eklenti sınırlarına takıldıysanız belgeleri kontrol edin.","tags":["not supported","desteklenmiyor","feature","ozellik","version","surum","0A000"]},{"code":"57P03","title":"cannot_connect_now","severity":"danger","meaning":"Sunucu şu anda bağlantı kabul edemiyor; genellikle veritabanı henüz başlatılma (starting up) aşamasında ya da kurtarma (recovery) yapıyor. Sistem hazır olduğunda bağlantılar açılabilir.","cause":"PostgreSQL'in yeni başlatılıp henüz açılış (startup/recovery) sürecinde olması; çökme sonrası kurtarma; yedekten geri yükleme sırasında; standby sunucunun henüz sorgu kabul edecek duruma gelmemesi; kapanış (shutdown) sürecinde olması.","fix":"Kısa bir süre bekleyip yeniden bağlanın; başlatma tamamlanınca sunucu bağlantı kabul eder. Sunucu log'larını inceleyerek kurtarma ilerlemesini izleyin. Uzun sürüyorsa büyük WAL yeniden oynatma (replay) ya da kurtarma sorunu olabilir. Uygulamada yeniden deneme (retry) mantığı ekleyin.","tags":["connection","baglanti","starting up","baslatma","recovery","kurtarma","57P03"]},{"code":"2BP01","title":"dependent_objects_still_exist","severity":"caution","meaning":"Silinmeye çalışılan nesneye başka nesneler bağımlı olduğu için silme işlemi engellendi. Bağımlı nesneler var oldukça DROP başarısız olur.","cause":"Bir tabloya bağlı view/foreign key/fonksiyon varken tabloyu silmeye çalışmak; bir tipe ya da şemaya bağımlı nesnelerin bulunması; CASCADE belirtilmeden yapılan DROP; başka nesnelerin referans verdiği bir sütun/sequence.","fix":"Bağımlı nesneleri önce kaldırın ya da CASCADE ile birlikte silin: DROP TABLE tablo CASCADE; (CASCADE'in bağımlı nesneleri de sileceğini unutmayın, dikkatli olun). Bağımlılıkları görmek için hata detayına (DETAIL satırı) bakın veya pg_depend/ilgili katalogları inceleyin. Silme sırasını doğru planlayın.","tags":["dependency","bagimlilik","cascade","drop","objects","nesne","2BP01"]},{"code":"55006","title":"object_in_use","severity":"danger","meaning":"İşlem yapılmak istenen nesne (genellikle bir veritabanı) başka oturumlar tarafından kullanıldığı için üzerinde bu işlem gerçekleştirilemiyor. Örneğin aktif bağlantısı olan bir veritabanı silinemez.","cause":"DROP DATABASE denenirken o veritabanına açık bağlantıların bulunması; kullanımda olan bir nesne üzerinde özel (exclusive) lock gerektiren işlem; başka bir oturumun nesneyi tutması.","fix":"Hedef veritabanına açık bağlantıları bulun ve sonlandırın: SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = 'db_adi' AND pid <> pg_backend_pid(); Yeni bağlantıları engelleyin (gerekirse). PostgreSQL 13+ ile bağlantıları zorla kapatarak silin: DROP DATABASE db_adi WITH (FORCE);","tags":["in use","kullanimda","object","nesne","drop database","connection","55006"]},{"code":"22007","title":"invalid_datetime_format","severity":"caution","meaning":"Bir metin, tarih/saat (date, time, timestamp) tipine dönüştürülürken geçerli bir biçimde değildi. Değer beklenen tarih-zaman formatına uymuyor.","cause":"Beklenenden farklı biçimde tarih metni (gün/ay/yıl sırası karışıklığı); geçersiz gün/saat değerleri; boş dize ('') tarihe dönüştürme; eksik ya da fazla bileşen; locale/format uyuşmazlığı; to_timestamp/to_date için hatalı format maskesi.","fix":"Tarih metnini doğru formatla dönüştürün: to_date('2026-07-04', 'YYYY-MM-DD') veya to_timestamp(str, 'YYYY-MM-DD HH24:MI:SS'). ISO 8601 biçimini (YYYY-MM-DD) tercih edin. Boş değerleri NULLIF(deger,'') ile NULL yapın. Giriş verisini yüklemeden önce doğrulayın; hatalı satırı daraltarak bulun.","tags":["date","tarih","datetime","format","timestamp","to_date","22007"]}]},"errors/mysql-more.json":{"engineId":"mysql","engine":"MySQL","order":3,"errors":[{"code":"1052","title":"Column 'x' in field list is ambiguous","severity":"caution","meaning":"Sorguda birden fazla tabloda aynı ada sahip bir sütun bulunuyor ve bu sütun tablo/alias öneki olmadan kullanıldığından MySQL hangi tabloya ait olduğunu belirleyemiyor.","cause":"JOIN edilen iki tabloda da aynı isimli sütun olması (örn. her ikisinde de id); SELECT, WHERE, ON, GROUP BY ya da ORDER BY'da sütunun niteliksiz (öneksiz) yazılması.","fix":"Belirsiz her sütunu tablo adı ya da alias ile nitelendirin: SELECT a.id, b.id FROM a JOIN b ON a.id = b.a_id; Tablolara kısa alias verip tüm çakışan sütunlara önek ekleyin. USING(sutun) ile ortak sütunlu join'lerde belirsizliği azaltın.","tags":["ambiguous","belirsiz","column","sutun","join","alias","1052"]},{"code":"1136","title":"Column count doesn't match value count","severity":"caution","meaning":"INSERT ifadesindeki sütun sayısı ile VALUES listesindeki değer sayısı birbirini tutmuyor. Her sütuna karşılık bir değer verilmelidir.","cause":"INSERT'te sütun listesiyle değer listesinin farklı uzunlukta olması; sütun listesi belirtilmeden yapılan INSERT'te tablo sütun sayısıyla değerlerin uyuşmaması; eksik/fazla virgül; tablo yapısının değişmesiyle betiğin güncellenmemesi.","fix":"Sütun sayısı ile değer sayısını eşitleyin. Her zaman açık sütun listesi kullanın: INSERT INTO tablo (a, b, c) VALUES (1, 2, 3); Tablo yapısını kontrol edin: DESCRIBE tablo; Değer sayısını sütunlara birebir denk getirin ve fazladan/eksik virgülleri düzeltin.","tags":["column count","sutun sayisi","insert","values","mismatch","uyusmazlik","1136"]},{"code":"1048","title":"Column 'x' cannot be null","severity":"caution","meaning":"NOT NULL tanımlı bir sütuna NULL değer eklenmeye ya da o sütun NULL yapılmaya çalışıldı. Zorunlu bir alan boş bırakılamaz.","cause":"INSERT'te zorunlu sütuna değer verilmemesi; UPDATE ile sütunun NULL'a çekilmesi; sütun için DEFAULT olmaması; uygulamadan/alt sorgudan boş değer gelmesi; strict SQL modunda boş değerin sessizce doldurulmaması.","fix":"Zorunlu sütuna geçerli bir değer girin. Sütuna makul bir varsayılan tanımlayın: ALTER TABLE tablo MODIFY sutun INT NOT NULL DEFAULT 0; Kural gereksizse NULL'a izin verin: ALTER TABLE tablo MODIFY sutun INT NULL; Uygulamada boş değerleri göndermeden önce doğrulayın.","tags":["not null","null","bos","insert","cannot be null","zorunlu","1048"]},{"code":"1292","title":"Incorrect datetime value / truncated incorrect value","severity":"caution","meaning":"Bir değer, hedef sütun tipine (özellikle tarih/saat ya da sayı) dönüştürülürken geçersiz ya da hatalı biçimliydi. Strict modda MySQL bunu hata olarak reddeder.","cause":"Geçersiz veya '0000-00-00' gibi tarih değerleri; yanlış tarih formatı; sayısal sütuna sayı olmayan metin; strict SQL modunun (STRICT_TRANS_TABLES) aktif olması; farklı karakter kümesi/karşılaştırma (collation) kaynaklı dönüşüm sorunları.","fix":"Değeri sütun tipine uygun geçerli biçime getirin (tarih için 'YYYY-MM-DD'). Boş/hatalı tarihler yerine NULL kullanın. Gerekirse STR_TO_DATE ile açık format verin: STR_TO_DATE(str, '%Y-%m-%d'). Geçici tolerans gerekiyorsa sql_mode'u gözden geçirin ama tercihen veriyi düzeltin. Hatalı satırı daraltarak bulun.","tags":["datetime","tarih","truncated","incorrect value","strict mode","format","1292"]},{"code":"1406","title":"Data too long for column","severity":"caution","meaning":"Bir sütuna, tanımlı maksimum uzunluğundan daha uzun bir değer yazılmaya çalışıldı. Örneğin VARCHAR(10) sütununa 20 karakterlik metin sığmaz.","cause":"Sütun genişliğinin veriye göre yetersiz olması; çok baytlı karakter kümesinde (utf8mb4) karakterlerin beklenenden fazla yer kaplaması; birleştirme sonucunun uzaması; strict SQL modunun aktif olması (aksi halde sessizce kırpılır).","fix":"Sütunu genişletin: ALTER TABLE tablo MODIFY sutun VARCHAR(255); Çok uzun içerik için TEXT tipini değerlendirin. Değeri kısaltmak gerekiyorsa uygulamada ya da SUBSTRING ile budayın. Hangi kaydın taştığını bulun: SELECT * FROM tablo WHERE CHAR_LENGTH(sutun) > 10; Giriş doğrulaması ekleyin.","tags":["data too long","uzunluk","varchar","column","sutun","truncate","1406"]},{"code":"1071","title":"Specified key was too long; max key length is 767 bytes","severity":"caution","meaning":"Oluşturulmaya çalışılan index (ya da anahtar), izin verilen maksimum bayt uzunluğunu aştı. Özellikle çok baytlı karakter kümelerinde VARCHAR index'leri hızla bu sınıra ulaşır.","cause":"utf8mb4 (karakter başına 4 bayt) ile geniş VARCHAR sütununa index; eski InnoDB satır formatı (REDUNDANT/COMPACT; 5.7 ve öncesinde ayrıca devre dışı innodb_large_prefix); çok sütunlu bileşik index'in toplam uzunluğunun sınırı aşması; büyük primary key.","fix":"İndekslenen sütun uzunluğunu kısaltın ya da öntakı (prefix) index kullanın: CREATE INDEX idx ON tablo (sutun(191)); DYNAMIC/COMPRESSED satır formatıyla 3072 bayt sınırına çıkın (MySQL 8.0'da DYNAMIC varsayılandır; innodb_large_prefix 8.0'da kaldırıldı, yalnızca 5.7 ve öncesinde gerekir). Gerekirse sütunun karakter kümesini/uzunluğunu gözden geçirin.","tags":["index","indeks","key too long","anahtar","prefix","utf8mb4","1071"]},{"code":"1050","title":"Table already exists","severity":"caution","meaning":"Oluşturulmaya çalışılan tablo zaten mevcut. Aynı ada sahip bir tablo bulunduğu için CREATE TABLE başarısız oldu.","cause":"Zaten var olan bir tablonun yeniden oluşturulması; betiğin iki kez çalıştırılması; migrasyonların tekrar uygulanması; farklı bir nesnenin (view) aynı adı kullanması.","fix":"Tablo yoksa oluşturmak için IF NOT EXISTS kullanın: CREATE TABLE IF NOT EXISTS tablo (...); Gerçekten yeniden oluşturmak istiyorsanız önce silin: DROP TABLE IF EXISTS tablo; Var olan tabloları listeleyin: SHOW TABLES; Migrasyonların tekrar çalışmaya dayanıklı (idempotent) olmasını sağlayın.","tags":["table exists","tablo var","duplicate","mukerrer","create table","1050"]},{"code":"1051","title":"Unknown table 'x'","severity":"caution","meaning":"Başvurulan tablo mevcut değil. Silme, değiştirme ya da sorgulama sırasında belirtilen adla bir tablo bulunamadı.","cause":"Tablo adının yanlış yazılması; tablonun hiç oluşturulmamış ya da daha önce silinmiş olması; yanlış veritabanının (schema) seçili olması; büyük/küçük harf duyarlılığı (Linux'ta tablo adları duyarlıdır); DROP TABLE ile var olmayan tabloyu silmeye çalışmak.","fix":"Var olan tabloları listeleyin: SHOW TABLES; ve doğru veritabanını seçin: USE veritabani; Tablo adını ve harf durumunu düzeltin. Silmede hatayı önlemek için: DROP TABLE IF EXISTS tablo; Farklı bir şemadaysa şema.tablo biçiminde nitelendirin.","tags":["unknown table","bilinmeyen tablo","yok","drop","not exists","1051"]},{"code":"1091","title":"Can't DROP 'x'; check that column/key exists","severity":"caution","meaning":"ALTER TABLE ile silinmeye çalışılan sütun, index ya da foreign key mevcut değil. Var olmayan bir nesne düşürülemez.","cause":"DROP COLUMN/INDEX/FOREIGN KEY ile var olmayan bir nesne adı verilmesi; adın yanlış yazılması; nesnenin daha önce silinmiş olması; foreign key adı ile index adının karıştırılması; migrasyonun ikinci kez çalışması.","fix":"Nesnenin gerçek adını doğrulayın: SHOW CREATE TABLE tablo; ya da SHOW INDEX FROM tablo; Doğru adı kullanarak silin. Foreign key için sembol (symbol) adını kullanın: ALTER TABLE tablo DROP FOREIGN KEY fk_ad; MySQL'de DROP COLUMN IF EXISTS sözdizimi yoktur (yalnızca MariaDB'de vardır); idempotent migrasyonlarda önce information_schema.columns ile sütunun varlığını kontrol edin: SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'tablo' AND column_name = 'sutun';","tags":["cant drop","silinemiyor","column","index","foreign key","alter","1091"]},{"code":"1093","title":"You can't specify target table 'x' for update in FROM clause","severity":"caution","meaning":"Bir UPDATE ya da DELETE ifadesinde, güncellenen/silinen tablonun kendisi doğrudan bir alt sorguda (FROM içinde) kaynak olarak kullanılamaz. MySQL aynı tabloyu hem hedef hem de kaynak olarak bu şekilde kullanmaya izin vermez.","cause":"UPDATE tablo ... WHERE id IN (SELECT ... FROM tablo ...) gibi, alt sorgunun doğrudan aynı hedef tabloyu okuması; DELETE'te aynı tabloya referans veren alt sorgu.","fix":"Alt sorguyu bir türetilmiş tabloya (derived table) sarıp yeni bir alias verin; böylece MySQL onu ayrı bir kopya olarak ele alır: UPDATE tablo SET c = 1 WHERE id IN (SELECT id FROM (SELECT id FROM tablo WHERE kosul) AS t); Alternatif olarak self-join biçiminde yazın: UPDATE tablo a JOIN tablo b ON ... SET a.c = ...;","tags":["update","delete","target table","hedef tablo","subquery","alt sorgu","1093"]},{"code":"1305","title":"PROCEDURE does not exist","severity":"caution","meaning":"Çağrılan stored procedure ya da fonksiyon, belirtilen veritabanında bulunamadı. Bu adla tanımlı bir yordam yok.","cause":"Yordam adının yanlış yazılması; yordamın yanlış veritabanında olması ya da hiç oluşturulmamış olması; USE ile yanlış şemanın seçili olması; yordamı çağırmak için EXECUTE yetkisinin bulunmaması; büyük/küçük harf duyarlılığı.","fix":"Yordamın var olduğunu ve hangi şemada olduğunu doğrulayın: SHOW PROCEDURE STATUS WHERE Db = 'veritabani'; Doğru veritabanını seçin: USE veritabani; ya da tam nitelikli çağırın: CALL veritabani.yordam(...); Gerekli yetkileri verin: GRANT EXECUTE ON PROCEDURE veritabani.yordam TO kullanici;","tags":["procedure","yordam","does not exist","yok","stored procedure","call","1305"]},{"code":"1227","title":"Access denied; you need (at least one of) the PRIVILEGE","severity":"danger","meaning":"Kullanıcının yapmaya çalıştığı işlem için gerekli yetki (privilege) yok. İşlem, hesaba tanımlı izinlerin ötesinde bir hak gerektiriyor.","cause":"SUPER, PROCESS, RELOAD, CREATE USER gibi yönetimsel bir yetkinin eksik olması; global bir view'ı/tabloyu okumak için gereken iznin verilmemiş olması; belirli bir işlemin (SET GLOBAL, binlog erişimi) yükseltilmiş yetki istemesi.","fix":"Mevcut yetkileri görün: SHOW GRANTS FOR CURRENT_USER(); Yetkili bir hesapla gerekli izni verin: GRANT PROCESS ON *.* TO 'kullanici'@'host'; (GRANT anında etkilidir, FLUSH PRIVILEGES gerekmez). Mümkünse SUPER yerine dinamik ayrıcalıkları (örn. SYSTEM_VARIABLES_ADMIN) kullanın. En az ayrıcalık ilkesine uyun.","tags":["access denied","yetki","privilege","izin","grant","erisim","1227"]},{"code":"3730","title":"Cannot drop table referenced by a foreign key constraint","severity":"danger","meaning":"Silinmeye çalışılan tabloya başka bir tablonun foreign key'i referans verdiği için tablo düşürülemiyor. Referans var oldukça DROP engellenir.","cause":"Bir üst (parent) tabloyu, ona FK ile bağlı alt tablolar hâlâ mevcutken silmeye çalışmak; bağımlılık sırasının gözetilmemesi; foreign key'lerin önce kaldırılmaması.","fix":"Önce referans veren foreign key'i kaldırın: ALTER TABLE alt_tablo DROP FOREIGN KEY fk_ad; sonra tabloyu silin. Bağımlı tabloları/constraint'leri bulun: SELECT * FROM information_schema.KEY_COLUMN_USAGE WHERE REFERENCED_TABLE_NAME = 'tablo'; Toplu işlemlerde geçici olarak SET FOREIGN_KEY_CHECKS = 0; kullanılabilir ama dikkatli olun ve sonra tekrar 1 yapın.","tags":["foreign key","yabanci anahtar","drop table","referenced","referans","constraint","3730"]},{"code":"2013","title":"Lost connection to MySQL server during query","severity":"danger","meaning":"Sorgu çalışırken istemci ile MySQL sunucusu arasındaki bağlantı koptu. Sunucu yanıt veremeden ya da sonuç dönmeden bağlantı kesildi.","cause":"Uzun süren sorgunun net_read_timeout/net_write_timeout sınırını aşması; sunucunun bellek yetersizliğinden (OOM) sorguyu/bağlantıyı sonlandırması; ağ kesintisi; max_allowed_packet aşımı; sunucunun çökmesi ya da yeniden başlaması; çok büyük sonuç kümesi.","fix":"Ağ kararlılığını ve sunucu error log'larını kontrol edin; OOM ya da çökme olup olmadığını görün. Zaman aşımlarını artırın: SET GLOBAL net_read_timeout = 120; Büyük sorguları parçalayın (batch). max_allowed_packet değerini büyütün. Uygulamada bağlantı yeniden deneme (retry) mantığı ekleyin. Uzun sorguları optimize edin.","tags":["lost connection","baglanti koptu","timeout","network","ag","oom","2013"]},{"code":"1153","title":"Got a packet bigger than 'max_allowed_packet' bytes","severity":"danger","meaning":"İstemci veya sunucu, izin verilen maksimum paket boyutundan (max_allowed_packet) daha büyük bir veri paketi göndermeye çalıştı. Bu genellikle büyük BLOB/TEXT değerleri ya da çok büyük toplu INSERT'lerde olur.","cause":"Çok büyük BLOB/TEXT verisi ekleme; devasa tek bir INSERT ya da çok satırlı toplu INSERT; büyük sonuç döndüren sorgu; max_allowed_packet değerinin küçük olması; mysqldump ile büyük satırların içe aktarılması.","fix":"max_allowed_packet değerini büyütün (hem sunucuda hem istemcide): SET GLOBAL max_allowed_packet = 67108864; (64MB) ve bağlantıyı yeniden açın. Kalıcı olması için my.cnf içine [mysqld] altında max_allowed_packet = 64M ekleyin. Büyük toplu işlemleri daha küçük gruplara bölün. Çok büyük değerleri gerçekten saklamanız gerekip gerekmediğini değerlendirin.","tags":["max_allowed_packet","packet","paket","blob","buyuk veri","insert","1153"]},{"code":"1969","title":"MariaDB: Query execution was interrupted (max_statement_time exceeded)","severity":"caution","meaning":"MariaDB'ye özgüdür (ER_STATEMENT_TIMEOUT): sorgu, max_statement_time ile tanımlı azami çalışma süresini aştığı için yarıda kesildi. MySQL'de bu kod yoktur; MySQL karşılığı 3024 (ER_QUERY_TIMEOUT, max_execution_time) hatasıdır.","cause":"MariaDB'de oturum/global max_statement_time sınırının ya da SET STATEMENT max_statement_time=N FOR ... ile konulan limitin aşılması; verimsiz plan, eksik index, büyük veri taraması veya lock beklemeleri.","fix":"Sorguyu EXPLAIN ile analiz edip index ekleyerek ve planı iyileştirerek hızlandırın. Gerçekten uzun sürmesi gereken bir sorguysa MariaDB'de limiti artırın: SET SESSION max_statement_time = 60; (saniye) ya da SET STATEMENT max_statement_time = 60 FOR SELECT ...; MySQL kullanıyorsanız 3024 kaydına bakın (max_execution_time, milisaniye; MAX_EXECUTION_TIME hint). Büyük işlemleri parçalayın.","tags":["timeout","zaman asimi","interrupted","kesildi","max_execution_time","query","1969"]}]},"errors/mssql-more.json":{"engineId":"mssql","engine":"SQL Server","order":4,"errors":[{"code":"8134","title":"Divide by zero error encountered","severity":"caution","meaning":"Bir aritmetik ifadede bölen sıfır olduğu için sıfıra bölme hatası oluştu. SQL Server bölmeyi tamamlayamaz ve sorguyu durdurur.","cause":"Bölen olarak kullanılan sütun veya ifadenin 0 değeri alması, ortalama/oran hesaplarında paydanın sıfır olması, NULLIF kullanılmadan sabit bir değere bölme veya beklenmedik sıfır veriler.","fix":"Paydayı NULLIF ile koruyun (ör. deger / NULLIF(payda, 0)); sonuç NULL olur, ISNULL/COALESCE ile varsayılan verilebilir. CASE WHEN payda = 0 THEN NULL ELSE deger/payda END kullanın. Bölmeden önce WHERE ile sıfır değerleri filtreleyin. Gerekiyorsa SET ARITHABORT/ANSI_WARNINGS davranışını değerlendirin.","tags":["math","aritmetik","divide by zero","sifira bolme","8134"]},{"code":"245","title":"Conversion failed when converting the value to data type","severity":"caution","meaning":"Bir değer hedef veri tipine dönüştürülemedi. Örneğin metin bir değeri int veya date tipine çevirmeye çalışırken uygun olmayan içerik nedeniyle örtük/açık dönüşüm başarısız oldu.","cause":"Sayısal olmayan metnin int/decimal'e çevrilmesi, geçersiz tarih biçimi, kolon karşılaştırmalarında örtük tip dönüşümü, WHERE veya JOIN koşulunda uyumsuz tipler ya da hatalı biçimlendirilmiş girdi verisi.","fix":"Dönüşümü güvenli sürümlerle yapın: TRY_CAST veya TRY_CONVERT (başarısızlıkta NULL döner). Verideki bozuk kayıtları ISNUMERIC/TRY_CONVERT ile tespit edin. Kolon tiplerini eşleştirin ve örtük dönüşümü ortadan kaldırın. Girdi doğrulaması yapın ve tarih için kesin biçim (ör. CONVERT stili) kullanın.","tags":["conversion","donusum","cast","convert","veri tipi","245"]},{"code":"515","title":"Cannot insert the value NULL into column","severity":"caution","meaning":"NOT NULL tanımlı bir sütuna NULL değer eklenmeye veya güncellenmeye çalışıldı. Sütun boş değere izin vermediği için işlem reddedildi.","cause":"INSERT ifadesinde zorunlu bir sütunun atlanması, kaynak veride eksik/boş alan, varsayılan değeri olmayan NOT NULL kolon veya uygulama tarafından NULL gönderilmesi.","fix":"Zorunlu sütunlara geçerli bir değer verin. Uygun kolonlara DEFAULT constraint'i ekleyin. Kaynak veriyi eksik alanlar için doğrulayın ve ISNULL/COALESCE ile varsayılan atayın. Sütunun gerçekten zorunlu olması gerekmiyorsa NULL'a izin verecek şekilde şemayı gözden geçirin.","tags":["null","not null","insert","constraint","kisit","515"]},{"code":"8115","title":"Arithmetic overflow error converting expression to data type","severity":"caution","meaning":"Bir aritmetik işlem veya dönüşüm sonucunda üretilen değer, hedef veri tipinin taşıyabileceği aralığı aştı. Sayı çok büyük olduğu için taşma (overflow) oluştu.","cause":"int aralığını aşan toplam/çarpım (SUM), küçük tipli bir kolona büyük değer atanması, decimal ölçek/kesinlik yetersizliği veya IDENTITY değerinin tip sınırına ulaşması.","fix":"Ara hesaplar için daha geniş bir tip kullanın (ör. CAST(kolon AS bigint) ile SUM). decimal precision/scale değerlerini artırın. Kolon tipini veriye uygun büyütün. Taşma riski olan ifadeleri önceden dönüştürerek hesaplayın ve girdi aralıklarını sınırlayın.","tags":["overflow","tasma","aritmetik","math","int","bigint","8115"]},{"code":"512","title":"Subquery returned more than 1 value","severity":"caution","meaning":"Tek değer bekleyen bir bağlamda (=, <, >, karşılaştırma veya atama) kullanılan alt sorgu birden fazla satır döndürdü. SQL Server tek skaler değer beklerken çoklu değerle karşılaştı.","cause":"Karşılaştırma yerine tek değer üreteceği varsayılan bir alt sorgunun birden çok satır getirmesi, benzersiz olmayan eşleşme koşulu, eksik filtre veya yanlış kurgulanmış ilişkisel sorgu.","fix":"Alt sorguyu tek satıra indirin (ör. TOP 1, MAX/MIN veya uygun bir GROUP BY). Çoklu değer bekleniyorsa = yerine IN veya EXISTS kullanın. JOIN ile yeniden yazın. Alt sorgunun neden çoklu döndüğünü inceleyerek filtre/anahtar koşullarını düzeltin.","tags":["subquery","alt sorgu","more than one","512","in","exists"]},{"code":"207","title":"Invalid column name","severity":"caution","meaning":"Sorguda başvurulan sütun adı ilgili tabloda/view'da bulunamadı. Belirtilen isimde bir kolon yok veya kapsam dışında.","cause":"Yazım/harf hatası, yanlış tablo takma adı (alias), yeni eklenmemiş veya adı değişmiş kolon, yanlış şema/tablo bağlamı ya da tırnak yerine köşeli parantez kullanımının atlanması.","fix":"Sütun adını ve tabloyu doğrulayın (sys.columns veya nesne gezgininden bakın). Doğru takma adı ve şemayı kullanın. Yeni eklenen kolonlar için nesnenin güncel olduğundan emin olun; gerekiyorsa stored procedure'ü yeniden derleyin. Boşluk/özel karakter içeren adlarda köşeli parantez kullanın.","tags":["column","kolon","invalid column","gecersiz sutun","alias","207"]},{"code":"156","title":"Incorrect syntax near the keyword","severity":"caution","meaning":"Bir anahtar kelimenin (keyword) yakınında sözdizimi hatası var. SQL Server ifadeyi ayrıştıramadı çünkü ayrılmış bir kelime beklenmedik bir konumda kullanılmış.","cause":"Ayrılmış kelimenin (ör. ORDER, USER, TABLE) sütun/nesne adı olarak parantezsiz kullanılması, eksik virgül/parantez, yanlış sıralanmış cümlecikler veya cümleciklerin (WHERE, GROUP BY) hatalı konumu.","fix":"Hatanın işaret ettiği anahtar kelime çevresini inceleyin. Ayrılmış kelimeleri nesne adı olarak kullanıyorsanız köşeli parantezle sarın (ör. [User]). Eksik virgül, parantez ve cümlecik sırasını düzeltin. Sorguyu parçalara bölerek sözdizimini test edin.","tags":["syntax","sozdizimi","keyword","anahtar kelime","156"]},{"code":"2812","title":"Could not find stored procedure","severity":"caution","meaning":"EXEC ile çağrılan stored procedure mevcut veritabanı/şema kapsamında bulunamadı. Belirtilen isimde bir yordam yok.","cause":"Yordam adında yazım hatası, yanlış şema öneki eksikliği (ör. dbo. yazılmaması), yordamın farklı bir veritabanında olması, henüz oluşturulmamış olması veya izin nedeniyle görünmemesi.","fix":"Yordam adını ve şemayı doğrulayın; çağrıda tam ad kullanın (ör. EXEC dbo.YordamAdi). Doğru veritabanında olduğunuzdan emin olun (USE VeritabaniAdi). Yordamın varlığını kontrol edin (sys.procedures / OBJECT_ID). Gerekli EXECUTE iznini verin ve dağıtım betiğinin çalıştığını doğrulayın.","tags":["stored procedure","saklinyordam","sp","not found","bulunamadi","2812"]},{"code":"8623","title":"The query processor ran out of internal resources and could not produce a query plan","severity":"danger","meaning":"Sorgu işlemcisi, aşırı karmaşık bir sorgu için iç kaynaklarını tüketti ve bir yürütme planı üretemedi. Sorgu çok büyük/karmaşık olduğundan optimize edilemiyor.","cause":"Çok uzun IN listeleri veya çok sayıda OR/UNION içeren sorgular, aşırı JOIN sayısı, otomatik üretilmiş devasa sorgular, çok fazla parametreli sorgu veya aşırı derin ifade ağaçları.","fix":"Sorguyu basitleştirin: uzun IN listelerini geçici tablo/tablo değerli parametreye taşıyın, OR koşullarını UNION ALL veya yeniden yazımla azaltın, karmaşık sorguyu parçalara bölün. JOIN sayısını düşürün. Otomatik üretilen sorguları toplu (batch) hale getirin. Gerektiğinde index'leri ve sorgu tasarımını gözden geçirin.","tags":["query processor","internal resources","plan","karmasik sorgu","8623","danger"]},{"code":"4104","title":"The multi-part identifier could not be bound","severity":"caution","meaning":"Nokta ile ayrılmış çok parçalı bir tanımlayıcı (ör. tablo.kolon veya alias.kolon) çözümlenemedi. SQL Server bu adı sorgudaki bir tabloya/kolona bağlayamadı.","cause":"Yanlış veya tanımsız tablo takma adı, FROM/JOIN'de bulunmayan tabloya referans, kolonun yanlış tabloya atfedilmesi, alias tanımlandıktan sonra gerçek tablo adının kullanılması veya yazım hatası.","fix":"Kullanılan alias'ların FROM/JOIN cümleciğinde tanımlı olduğunu doğrulayın. Kolonu doğru tablo/alias ile niteleyin. Bir tabloya alias verdiyseniz her yerde alias'ı kullanın (gerçek adı değil). JOIN'e eksik tabloyu ekleyin ve isimleri denetleyin.","tags":["identifier","multi-part","tanimlayici","bind","alias","4104"]},{"code":"2714","title":"There is already an object named in the database","severity":"caution","meaning":"Oluşturulmak istenen nesne (tablo, view, yordam vb.) ile aynı ada sahip bir nesne veritabanında zaten var. CREATE ifadesi ad çakışması nedeniyle başarısız oldu.","cause":"Aynı CREATE betiğinin ikinci kez çalıştırılması, var olan nesnenin önce silinmemesi, farklı şema varsayımı, dağıtım/migrasyon betiklerinin idempotent olmaması veya adlandırma çakışması.","fix":"Nesne varsa önce kontrol edin: IF OBJECT_ID('dbo.Ad') IS NULL ile koşullu oluşturun veya CREATE OR ALTER kullanın (yordam/view/fonksiyon için). Gerekirse mevcut nesneyi DROP edip yeniden oluşturun. Migrasyon betiklerini idempotent yazın. Doğru şema/veritabanında çalıştığınızı doğrulayın.","tags":["already exists","zaten var","create","object","nesne","2714"]},{"code":"601","title":"Could not continue scan with NOLOCK due to data movement","severity":"caution","meaning":"NOLOCK (READ UNCOMMITTED) ile yapılan bir tarama sırasında, eşzamanlı veri hareketi (page split/taşınma) nedeniyle tarama devam edemedi. Kilitsiz okuma tutarsız bir duruma denk geldi.","cause":"NOLOCK hint'i veya READ UNCOMMITTED izolasyon seviyesi altında okuma yaparken, aynı anda gerçekleşen güncelleme/silme/page split'ler nedeniyle taranan sayfaların yer değiştirmesi.","fix":"Sorguyu yeniden çalıştırın (genellikle geçici bir durumdur). Mümkünse NOLOCK hint'inden kaçının; tutarlılık için READ COMMITTED SNAPSHOT (RCSI) izolasyonunu kullanarak kilitsiz ama tutarlı okuma sağlayın. Yoğun yazma yapılan tablolarda dirty read yerine snapshot izolasyonunu tercih edin.","tags":["nolock","scan","data movement","601","izolasyon","read uncommitted"]},{"code":"50000","title":"Custom error raised with RAISERROR","severity":"caution","meaning":"Bir mesaj kimliği belirtilmeden RAISERROR ile üretilen özel (kullanıcı tanımlı) hataların varsayılan numarasıdır (50000). Uygulama/yordam mantığı kasıtlı olarak bir hata fırlattı.","cause":"Stored procedure veya betikte iş kuralı ihlali durumunda RAISERROR ya da THROW ile özel hata fırlatılması, doğrulama başarısızlığı, kasıtlı akış kontrolü veya özel istisna mesajları.","fix":"RAISERROR/THROW mesaj metnini okuyarak asıl iş kuralı ihlalini anlayın. Uygulama tarafında bu hatayı TRY...CATCH ile yakalayın ve ERROR_MESSAGE()/ERROR_NUMBER() ile detay alın. Özel hatalarınıza anlamlı numaralar vermek için sp_addmessage ile mesaj tanımlayın. İş mantığındaki tetikleyen koşulu düzeltin.","tags":["raiserror","custom error","ozel hata","throw","50000","try catch"]},{"code":"3902","title":"The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION","severity":"caution","meaning":"Bir COMMIT TRANSACTION çalıştırıldı ancak ona karşılık gelen açık bir BEGIN TRANSACTION yok. Transaction sayacı (@@TRANCOUNT) sıfır olduğundan commit edilecek bir transaction bulunamadı.","cause":"Dengesiz BEGIN/COMMIT/ROLLBACK kullanımı, hata sonrası transaction'ın zaten geri alınmış olması, iç içe transaction sayımının hatalı yönetilmesi veya CATCH bloğunda ROLLBACK sonrası tekrar COMMIT çağrılması.","fix":"BEGIN ve COMMIT sayısını dengeleyin. Commit'ten önce @@TRANCOUNT değerini kontrol edin (IF @@TRANCOUNT > 0 COMMIT). TRY...CATCH içinde hata olduğunda XACT_STATE()/@@TRANCOUNT'a göre ROLLBACK yapın ve gereksiz COMMIT'i önleyin. İç içe transaction mantığını gözden geçirin.","tags":["transaction","commit","begin","trancount","islem","3902"]}]},"errors/mongodb-more.json":{"engineId":"mongodb","engine":"MongoDB","order":5,"errors":[{"code":"121","title":"DocumentValidationFailure","severity":"caution","meaning":"Eklenmek veya güncellenmek istenen belge, koleksiyon üzerinde tanımlı JSON Schema doğrulama kurallarını (validator) karşılamadığı için reddedildi.","cause":"Belgenin şemaya uymaması: eksik zorunlu alan, yanlış BSON tipi, izin verilen aralık/desen dışı değer, ek (additional) alanların yasak olması veya validationAction 'error' iken kural ihlali.","fix":"Hata detayındaki (errInfo) hangi kuralın ihlal edildiğini inceleyin. Belgeyi şemaya uygun hale getirin: zorunlu alanları ekleyin, tipleri düzeltin. Koleksiyon doğrulayıcısını collMod ile gözden geçirin. Geçici olarak validationLevel/validationAction ayarlanabilir ancak veri kalitesi için kuralları korumak tercih edilir.","tags":["validation","dogrulama","schema","sema","121","document"]},{"code":"40","title":"ConflictingUpdateOperators","severity":"caution","meaning":"Bir güncelleme işleminde aynı alana (path) çakışan birden fazla güncelleme operatörü uygulandı. MongoDB tek işlemde aynı yolu iki kez değiştiremez.","cause":"Aynı update belgesinde aynı alanı hedefleyen çakışan operatörler (ör. hem $set hem $inc ya da üst ve alt yolun aynı anda değiştirilmesi), yanlış kurgulanmış güncelleme veya iç içe yol çakışması.","fix":"Aynı alana yönelik çakışan operatörleri tek bir operatörde birleştirin veya güncellemeyi ayrı işlemlere bölün. Üst ve alt yolları (ör. a ve a.b) aynı anda değiştirmeyin. Güncelleme belgesini gözden geçirerek her alanın yalnızca bir kez değiştirildiğinden emin olun.","tags":["update","guncelleme","operator","conflict","cakisma","40"]},{"code":"66","title":"ImmutableField (cannot update _id)","severity":"caution","meaning":"Değiştirilemez (immutable) bir alan, özellikle belgenin _id alanı güncellenmeye çalışıldı. _id belge oluşturulduktan sonra değiştirilemez.","cause":"Update işleminde _id alanının değiştirilmeye çalışılması, shard key alanının izin verilmeyen biçimde güncellenmesi veya değişmez kabul edilen bir alanın yeni değerle set edilmesi.","fix":"_id değerini güncellemeyin; farklı bir _id gerekiyorsa belgeyi yeni _id ile ekleyip eskisini silin (insert + delete). Shard key güncellemelerinde MongoDB kurallarına uyun. Güncelleme belgesinden değişmez alanları çıkarın ve yalnızca değiştirilebilir alanları set edin.","tags":["immutable","_id","degismez","update","shard key","66"]},{"code":"2","title":"BadValue","severity":"caution","meaning":"Bir komuta veya sorguya geçersiz ya da beklenmeyen bir değer verildi. MongoDB argümanı kabul edilebilir bir değer olarak yorumlayamadı.","cause":"Geçersiz operatör argümanı, aralık dışı sayı, desteklenmeyen seçenek değeri, hatalı sıralama (sort) belirtimi, yanlış biçimli sorgu ifadesi veya uygun olmayan parametre kombinasyonu.","fix":"Hata mesajındaki alan/değer ipucuna göre argümanı düzeltin. Komut ve sorgu seçeneklerini dokümantasyona göre doğrulayın. Sort/projection/aggregate ifadelerinin biçimini kontrol edin. Değer aralıklarını ve tiplerini geçerli hale getirin.","tags":["badvalue","gecersiz deger","argument","2","query"]},{"code":"14","title":"TypeMismatch","severity":"caution","meaning":"Beklenen BSON tipi ile sağlanan değerin tipi uyuşmuyor. Bir alan veya argüman için farklı bir veri tipi bekleniyordu.","cause":"Sayı beklenen yere metin verilmesi, tarih yerine string kullanılması, dizi beklenirken tek değer gönderilmesi, aggregate/sorgu operatörüne yanlış tipte argüman ya da şemadaki tip tutarsızlığı.","fix":"İlgili alan/argüman için doğru BSON tipini sağlayın. Uygulama katmanında verileri kaydetmeden önce tip dönüşümü yapın (ör. sayıları gerçekten Number olarak yazın). Sorgu ve aggregate operatörlerinin beklediği tipleri doğrulayın. Şema doğrulayıcı ile tip tutarlılığını zorlayın.","tags":["typemismatch","tip uyumsuzlugu","bson","type","14"]},{"code":"10334","title":"BSONObjectTooLarge","severity":"danger","meaning":"Bir BSON belgesi izin verilen maksimum boyutu (16 MB) aştı. MongoDB tek bir belgeyi bu sınırın üzerinde saklayamaz veya döndüremez.","cause":"Belgeye sürekli veri/dizi eklenerek 16 MB sınırının aşılması, gömülü (embedded) çok büyük diziler, aggregate sonucunda oluşan devasa belgeler veya büyük ikili verinin doğrudan belgeye konması.","fix":"Veri modelini gözden geçirin: büyük dizileri ayrı koleksiyonlara bölerek referans (referencing) modeli kullanın. Büyük ikili dosyalar için GridFS kullanın. Sınırsız büyüyen dizileri sınırlayın (ör. kapaklı/bucket deseni). Aggregate aşamalarında belge boyutunu kontrol altında tutun.","tags":["bson","16mb","too large","buyuk belge","gridfs","10334","danger"]},{"code":"46","title":"LockBusy","severity":"caution","meaning":"İstenen lock ya da kaynak o anda başka bir işlem tarafından tutulduğu için hemen alınamadı ve işlem beklemek yerine reddedildi. Zaman aşımıyla biten lock beklemeleri ayrı bir koddur (24 LockTimeout).","cause":"Aynı koleksiyon veya veritabanı üzerinde eşzamanlı çalışan yönetim/DDL işlemleri (ör. aynı anda iki index oluşturma, collMod, drop ya da rename), devam eden bir bakım işlemiyle çakışma veya lock'u kısa süreliğine bile bekleyemeyen bir iç işlemin meşgul kaynağa denk gelmesi.","fix":"Çakışan işlemi bulun: db.currentOp() ile aynı namespace üzerinde çalışan DDL veya bakım işlemlerini inceleyin. Çakışan işlem bittikten sonra komutu yeniden deneyin (retry). Yönetim/DDL işlemlerini sıraya koyun ve aynı koleksiyon üzerinde paralel çalıştırmayın. Kalıcıysa mongod loglarında kaynağı tutan işlemi araştırın.","tags":["lock","kilit","lockbusy","mesgul","ddl","46"]},{"code":"96","title":"OperationFailed","severity":"danger","meaning":"Genel bir işlem başarısızlığı; komut çalıştırılırken beklenmedik bir hata oluştu ve işlem tamamlanamadı. Daha spesifik bir kodun bulunmadığı genel hata durumudur.","cause":"Sunucu tarafında iç hata, kaynak yetersizliği, tutarsız durum, alt sistem hatası (depolama, replikasyon) veya belirli komuta özgü çeşitli başarısızlık koşulları.","fix":"Hata mesajının tam metnini ve sunucu loglarını (mongod.log) inceleyerek asıl nedeni belirleyin. İşlemi yeniden deneyin; geçici bir durum olabilir. Kaynak (disk, bellek) ve replica set sağlığını kontrol edin. Sorun tekrar ediyorsa ilgili komutu ve girdi verisini gözden geçirin.","tags":["operationfailed","islem basarisiz","genel hata","96","danger"]},{"code":"72","title":"InvalidOptions","severity":"caution","meaning":"Bir komuta geçersiz veya birbiriyle uyumsuz seçenekler (options) verildi. Belirtilen seçenek kombinasyonu bu komut için desteklenmiyor.","cause":"Desteklenmeyen seçenek adı, birbirini dışlayan seçeneklerin birlikte kullanılması, yanlış sürüm için geçerli olmayan seçenek, hatalı write concern/read concern kombinasyonu veya index/collation seçenek çakışması.","fix":"Komutun kabul ettiği seçenekleri dokümantasyondan doğrulayın ve uyumsuz olanları kaldırın. Sürümünüzün ilgili seçeneği desteklediğinden emin olun. write/read concern ve collation ayarlarını gözden geçirin. Yalnızca geçerli seçenek kombinasyonlarını kullanın.","tags":["invalidoptions","gecersiz secenek","options","72","command"]},{"code":"9","title":"FailedToParse","severity":"caution","meaning":"Sunucu, gönderilen komutu, sorguyu veya ifadeyi ayrıştıramadı (parse edemedi). Yapı sözdizimsel olarak geçersiz veya beklenen biçimde değil.","cause":"Hatalı JSON/BSON yapısı, eksik veya fazla alan, yanlış operatör kullanımı, geçersiz aggregate pipeline sözdizimi ya da beklenen biçime uymayan komut belgesi.","fix":"Komut/sorgu/pipeline yapısını dokümantasyona göre düzeltin. JSON yapısını doğrulayın (eksik parantez/virgül, yanlış alan adları). Aggregate aşamalarının söz dizimini kontrol edin. Operatörlerin doğru kullanıldığından ve beklenen argüman biçiminin sağlandığından emin olun.","tags":["failedtoparse","parse","ayristirma","sozdizimi","9","query"]},{"code":"134","title":"ReadConcernMajorityNotAvailableYet","severity":"caution","meaning":"majority read concern ile okuma istendi ancak çoğunluk (majority) tarafından onaylanmış (committed) bir snapshot henüz mevcut değil. Sunucu bu tutarlılık düzeyini şu an sağlayamıyor.","cause":"Replica set'in yeni başlaması veya kararsız olması, çoğunluk yazımların henüz commit edilmemesi, replikasyon gecikmesi, yeterli sayıda düğümün erişilebilir olmaması veya küme başlangıç aşaması.","fix":"Kısa bir süre bekleyip işlemi yeniden deneyin; majority snapshot'ı hazır olduğunda okuma başarılı olur. Replica set sağlığını ve replikasyon gecikmesini kontrol edin (rs.status()). Yeterli düğümün ayakta olduğundan emin olun. Gerekmiyorsa daha düşük bir read concern (ör. local) değerlendirin.","tags":["readconcern","majority","cogunluk","replica","134","tutarlilik"]},{"code":"202","title":"NetworkInterfaceExceededTimeLimit","severity":"danger","meaning":"Bir ağ isteği (ör. düğümler arası iletişim veya istemci bağlantısı) belirlenen zaman sınırını aştı. İşlem ağ zaman aşımı nedeniyle tamamlanamadı.","cause":"Ağ gecikmesi/kesintisi, hedef düğümün yavaş veya erişilemez olması, aşırı yük, yanlış yapılandırılmış zaman aşımı değerleri, DNS/bağlantı sorunları veya coğrafi olarak uzak düğümler.","fix":"Ağ bağlantısını ve gecikmeyi kontrol edin; düğümler arası erişilebilirliği doğrulayın. Hedef düğümün sağlığını ve yükünü inceleyin. Zaman aşımı ayarlarını (connect/socket timeout) ortamınıza göre yapılandırın. Yeniden deneme (retry) mantığı ekleyin. Kalıcıysa altyapı/ağ yapılandırmasını gözden geçirin.","tags":["network","ag","timeout","zaman asimi","202","danger"]}]},"errors/redis-more.json":{"engineId":"redis","engine":"Redis","order":6,"errors":[{"code":"NOPERM","title":"NOPERM this user has no permissions to run the command or access one of the keys","severity":"caution","meaning":"Kimliği doğrulanmış ACL kullanıcısı, çalıştırmak istediği komuta veya eriştiği anahtara yetkili değil. Redis, ACL kurallarına göre işlemi reddediyor.","cause":"ACL kullanıcısının komut/kategori iznine sahip olmaması, anahtar deseninin (key pattern) izin listesinde bulunmaması, kanal (pub/sub) kısıtı veya kullanıcıya dar kapsamlı yetki verilmiş olması.","fix":"Kullanıcının izinlerini inceleyin: ACL GETUSER kullanici. Gerekli komut/kategori ve anahtar desenlerini ekleyin (ör. ACL SETUSER kullanici +get +set ~app:*). En az ayrıcalık ilkesine göre yalnızca gereken izinleri verin. Doğru kullanıcı ile bağlandığınızı doğrulayın.","tags":["noperm","acl","yetki","izin","permission","kullanici"]},{"code":"ERR value is not an integer or out of range","title":"ERR value is not an integer or out of range","severity":"caution","meaning":"Tamsayı bekleyen bir komuta (ör. INCR, EXPIRE, LPOP count) sayısal olmayan veya izin verilen aralığın dışında bir değer verildi. Redis değeri tamsayı olarak yorumlayamadı.","cause":"INCR/DECR uygulanan anahtarın metin (integer olmayan) değer tutması, argümanın sayı yerine metin olması, aralık dışı çok büyük/küçük sayı veya negatif olmaması gereken bir yere negatif değer verilmesi.","fix":"Anahtarın değerini kontrol edin: GET anahtar ve TYPE anahtar. Sayısal işlemler için anahtarın tamsayı bir değer tuttuğundan emin olun. Argümanların geçerli tamsayı ve doğru aralıkta olduğunu doğrulayın. Gerekirse değeri sıfırlayın (SET anahtar 0) veya doğru tiple yeniden oluşturun.","tags":["err","integer","tamsayi","aralik","incr","value"]},{"code":"ERR value is not a valid float","title":"ERR value is not a valid float","severity":"caution","meaning":"Ondalık (float) sayı bekleyen bir komuta (ör. INCRBYFLOAT, ZADD skoru) geçerli bir kayan noktalı sayı olmayan bir değer verildi. Redis değeri float olarak ayrıştıramadı.","cause":"INCRBYFLOAT uygulanan anahtarın geçerli bir float tutmaması, argümanın sayısal olmaması, yanlış ondalık ayırıcı (virgül yerine nokta gerekir) veya biçimsel olarak bozuk sayı.","fix":"Anahtarın değerini GET ile kontrol edin ve geçerli bir float içerdiğinden emin olun. Ondalık ayırıcı olarak nokta kullanın (ör. 3.14). Argümanın sayısal ve doğru biçimde olduğunu doğrulayın. Gerekiyorsa değeri geçerli bir float ile yeniden ayarlayın.","tags":["err","float","ondalik","incrbyfloat","zadd","value"]},{"code":"ERR increment or decrement would overflow","title":"ERR increment or decrement would overflow","severity":"caution","meaning":"Bir INCR/DECR (veya INCRBY/DECRBY) işlemi, sonucu 64-bit işaretli tamsayı sınırının dışına taşıracağı için reddedildi. Değer üst veya alt sınırı aşacaktı.","cause":"Anahtar değerinin int64 sınırına (yaklaşık 9.2 kentilyon) çok yakın olması ve artış/azalışın taşmaya yol açması, çok büyük INCRBY argümanı veya sayacın kontrolsüz büyümesi.","fix":"Sayaç değerlerini int64 sınırları içinde tutacak şekilde tasarlayın. Büyük sayımlar için ölçekleme veya periyodik sıfırlama uygulayın. Artış miktarını (INCRBY argümanını) makul aralıkta tutun. Çok büyük değerler gerekiyorsa uygulama katmanında farklı bir sayım stratejisi kullanın.","tags":["err","overflow","tasma","incr","decr","int64"]},{"code":"ERR max number of clients reached","title":"ERR max number of clients reached","severity":"danger","meaning":"Sunucuya bağlı istemci sayısı maxclients sınırına ulaştı ve yeni bağlantılar kabul edilemiyor. Redis daha fazla istemci bağlantısını reddediyor.","cause":"Bağlantı sızıntısı (kapatılmayan bağlantılar), yetersiz maxclients değeri, bağlantı havuzunun (pool) yanlış yapılandırılması, ani istemci artışı veya işletim sistemi dosya tanıtıcısı (file descriptor) sınırının düşük olması.","fix":"Mevcut bağlantıları inceleyin: CLIENT LIST ve INFO clients. Bağlantı sızıntılarını giderin; istemci havuzunu doğru boyutlandırın ve bağlantıları yeniden kullanın. Gerekiyorsa maxclients değerini artırın (CONFIG SET maxclients) ve OS ulimit (dosya tanıtıcı) sınırını yükseltin. Boşta bağlantılar için zaman aşımı ayarlayın.","tags":["err","maxclients","baglanti","client","limit","danger"]},{"code":"BUSYKEY","title":"BUSYKEY Target key name already exists","severity":"caution","meaning":"RESTORE (veya benzeri) komutu, hedef anahtar zaten var olduğu için başarısız oldu. Redis mevcut anahtarın üzerine varsayılan olarak yazmaz.","cause":"RESTORE ile geri yüklenen anahtar adının veritabanında zaten bulunması, önceki bir verinin temizlenmemiş olması veya aynı anahtara birden fazla geri yükleme denemesi.","fix":"Var olan anahtarın üzerine yazmak istiyorsanız RESTORE komutuna REPLACE seçeneğini ekleyin. Alternatif olarak hedef anahtarı önce silin (DEL anahtar) veya farklı bir anahtar adı kullanın. İşlem öncesi EXISTS anahtar ile varlığı kontrol edin.","tags":["busykey","restore","zaten var","anahtar","replace","key"]},{"code":"ERR no such key","title":"ERR no such key","severity":"caution","meaning":"İşlem yapılmak istenen anahtar veritabanında bulunamadı. RENAME, DUMP, MOVE gibi mevcut bir anahtar gerektiren komutlar var olmayan anahtar üzerinde çalışmaz.","cause":"Anahtarın hiç oluşturulmamış olması, TTL nedeniyle süresinin dolup silinmesi, yanlış anahtar adı/yazımı, yanlış veritabanı (SELECT) indeksi veya anahtarın daha önce DEL ile silinmiş olması.","fix":"Anahtarın varlığını kontrol edin: EXISTS anahtar. Doğru anahtar adını ve doğru veritabanını (SELECT db) kullandığınızdan emin olun. RENAME için kaynak anahtarın var olması gerekir. TTL ile süresi dolan anahtarlar için mantığı gözden geçirin. Anahtarı gerekiyorsa yeniden oluşturun.","tags":["err","no such key","anahtar yok","rename","dump","key"]},{"code":"ERR DUMP payload version or checksum are wrong","title":"ERR DUMP payload version or checksum are wrong","severity":"caution","meaning":"RESTORE komutuna verilen serileştirilmiş veri (DUMP çıktısı) geçersiz; sürüm uyumsuz veya sağlama (checksum) doğrulaması başarısız. Redis veriyi güvenle geri yükleyemiyor.","cause":"DUMP verisinin bozulması/değiştirilmesi, farklı ve uyumsuz Redis sürümleri arasında taşıma, verinin kodlama/kod çözme sırasında bozulması (ör. yanlış byte işleme) veya eksik/kırpılmış payload.","fix":"DUMP verisini bozmadan (ikili güvenli biçimde) taşıdığınızdan emin olun; metin kodlaması yerine ham byte olarak aktarın. Kaynak ve hedef Redis sürümlerinin uyumlu olduğunu doğrulayın. Veriyi yeniden DUMP alıp aktarın. Taşıma için RESTORE yerine MIGRATE komutunu değerlendirin.","tags":["err","dump","restore","checksum","saglama","version"]},{"code":"NOREPLICAS","title":"NOREPLICAS Not enough good replicas to write","severity":"danger","meaning":"min-replicas-to-write ayarı nedeniyle, yeterli sayıda sağlıklı replica bulunmadığından yazma işlemleri reddediliyor. Redis veri güvenliği için yazmayı engelliyor.","cause":"Yeterli replica'nın bağlı/güncel olmaması, replica çökmeleri, replikasyon gecikmesinin min-replicas-max-lag sınırını aşması, ağ sorunları veya failover sonrası replica eksikliği.","fix":"Replika durumunu kontrol edin: INFO replication. Aşağıda olan replica'ları ayağa kaldırın ve replikasyon gecikmesini azaltın. Ağ bağlantısını düzeltin. min-replicas-to-write / min-replicas-max-lag ayarlarını ortamınıza göre gözden geçirin (dayanıklılık ile erişilebilirlik dengesi). Yeterli replica sağlayın.","tags":["noreplicas","replica","yazma","min-replicas","replication","danger"]},{"code":"ERR This instance has cluster support disabled","title":"ERR This instance has cluster support disabled","severity":"caution","meaning":"Bir cluster (CLUSTER ...) komutu çalıştırılmaya çalışıldı ancak bu Redis örneği cluster modunda başlatılmamış. Cluster desteği kapalı olduğundan komut reddedildi.","cause":"cluster-enabled yes ayarının yapılmamış olması, örneğin bağımsız (standalone) modda çalışması, cluster komutlarının standalone bir sunucuya gönderilmesi veya yanlış sunucuya bağlanma.","fix":"Cluster özelliklerini kullanmak istiyorsanız örneği cluster modunda başlatın: yapılandırmada cluster-enabled yes ayarlayıp yeniden başlatın ve düğümleri kümede oluşturun. Standalone modda kalacaksanız cluster komutlarını kullanmayın. Doğru (cluster) sunucuya bağlandığınızı doğrulayın.","tags":["err","cluster","kume","disabled","standalone","config"]},{"code":"ERR unknown subcommand","title":"ERR unknown subcommand or wrong number of arguments","severity":"caution","meaning":"Bir üst komuta (ör. CONFIG, CLIENT, ACL, XINFO) geçersiz bir alt komut (subcommand) verildi ya da alt komuta yanlış sayıda argüman gönderildi. Redis alt komutu tanımadı.","cause":"Alt komut adında yazım hatası, kullanılan Redis sürümünde bulunmayan bir alt komut, yanlış/eksik argüman sayısı veya alt komut söz diziminin hatalı olması.","fix":"Doğru alt komut adını ve argümanları kullanın; ilgili komutun HELP alt komutuna bakın (ör. CONFIG HELP, CLIENT HELP). Redis sürümünüzün o alt komutu desteklediğini doğrulayın. Argüman sayısını ve söz dizimini dokümantasyona göre düzeltin.","tags":["err","subcommand","alt komut","argument","config","client"]},{"code":"ERR Client sent AUTH, but no password is set","title":"ERR AUTH <password> called without any password configured for the default user (Redis 6+) / ERR Client sent AUTH, but no password is set (Redis <6)","severity":"caution","meaning":"İstemci AUTH komutuyla kimlik doğrulaması yapmaya çalıştı ancak sunucuda herhangi bir parola (requirepass) veya ACL parolası tanımlı değil. Doğrulanacak bir kimlik bilgisi olmadığından AUTH reddedildi. Redis 6+ bu durumda \"ERR AUTH <password> called without any password configured for the default user. Are you sure your configuration is correct?\" döndürür; \"Client sent AUTH, but no password is set\" Redis 6 öncesi mesajdır.","cause":"Sunucuda requirepass ayarının boş olması, istemcinin gereksiz yere AUTH göndermesi, bağlantı dizesinde parola tanımlıyken sunucuda parola olmaması veya yapılandırma uyumsuzluğu.","fix":"Sunucu parola gerektirmiyorsa istemciden AUTH komutunu/parola ayarını kaldırın. Parola ile koruma istiyorsanız sunucuda requirepass ayarlayın (CONFIG SET requirepass parola) veya ACL kullanıcısına parola tanımlayın. İstemci ve sunucu yapılandırmasını tutarlı hale getirin.","tags":["err","auth","parola","requirepass","kimlik dogrulama","acl"]}]},"errors/elasticsearch-more.json":{"engineId":"elasticsearch","engine":"Elasticsearch","order":7,"errors":[{"code":"action_request_validation_exception","title":"action_request_validation_exception","severity":"caution","meaning":"Gönderilen istek, çalıştırılmadan önce yapılan doğrulamayı geçemedi. İstekte zorunlu bir alan eksik veya alanlar geçersiz olduğundan Elasticsearch işlemi reddediyor.","cause":"Zorunlu parametrelerin eksik olması (ör. index adı belirtilmemesi), boş gövde, geçersiz alan kombinasyonu veya bulk/index isteğinde gerekli bilgilerin sağlanmaması.","fix":"Hata mesajındaki eksik/geçersiz alan listesini inceleyin ve zorunlu alanları sağlayın. İstek gövdesini ve parametreleri API dokümantasyonuna göre tamamlayın. Bulk isteklerinde her işlem satırının doğru meta ve gövde içerdiğini doğrulayın.","tags":["validation","dogrulama","request","istek","action"]},{"code":"index_closed_exception","title":"index_closed_exception","severity":"caution","meaning":"İşlem yapılmak istenen index kapalı (closed) durumda. Kapalı bir index okuma/yazma isteklerine hizmet vermediğinden işlem gerçekleştirilemedi.","cause":"Index'in daha önce close API ile kapatılmış olması, bakım/ILM işlemleri sırasında kapatılması veya kaynak tasarrufu için pasif hale getirilmesi.","fix":"Index'i yeniden açın: POST /index_adi/_open. Açıldıktan sonra shard'ların atanmasını (green/yellow) bekleyin. Index'in neden kapatıldığını (ILM politikası, manuel işlem) inceleyin. Sık erişilmeyen index'ler için kapalı tutma stratejisini gözden geçirin.","tags":["index closed","kapali index","open","index","closed"]},{"code":"unavailable_shards_exception","title":"unavailable_shards_exception","severity":"danger","meaning":"İşlem için gereken bir veya daha fazla shard erişilebilir değil, bu yüzden istek (genellikle yazma) tamamlanamadı. Yeterli aktif shard kopyası bulunamadı.","cause":"Node çökmesi/ayrılması nedeniyle atanmamış (unassigned) shard'lar, disk watermark aşımı, replika eksikliği, wait_for_active_shards koşulunun sağlanamaması veya küme sağlığının kırmızı olması.","fix":"Küme ve shard sağlığını kontrol edin: GET _cluster/health ve GET _cat/shards?v. Atanmamış shard nedenini inceleyin: GET _cluster/allocation/explain. Aşağıda olan node'ları ayağa kaldırın, disk alanı açın (watermark), replika ayarlarını gözden geçirin. Gerekiyorsa wait_for_active_shards değerini uygun ayarlayın.","tags":["shard","unavailable","erisilemez","cluster","allocation","danger"]},{"code":"query_shard_exception","title":"query_shard_exception","severity":"caution","meaning":"Bir sorgu, belirli bir shard üzerinde çalıştırılırken hata verdi. Genellikle sorgunun mapping ile uyumsuz olması veya geçersiz bir sorgu yapısı nedeniyle oluşur.","cause":"Var olmayan veya yanlış tipteki alana sorgu, metin (text) alanında agregasyon/sıralama denenmesi (fielddata kapalı), geçersiz sorgu söz dizimi, yanlış analiz veya uyumsuz alan tipi.","fix":"Hata detayındaki alan/nedeni inceleyin. Sorguladığınız alanın mapping'ini kontrol edin: GET /index/_mapping. Sıralama/agregasyon için text yerine keyword alt alanını (field.keyword) kullanın. Sorgu söz dizimini düzeltin ve alan tiplerinin sorguyla uyumlu olduğundan emin olun.","tags":["query","sorgu","shard","mapping","fielddata","query shard"]},{"code":"script_exception","title":"script_exception","severity":"caution","meaning":"Bir script (genellikle Painless) derlenirken veya çalıştırılırken hata oluştu. Script hatalı yazılmış ya da çalışma zamanında bir istisna fırlattı.","cause":"Painless söz dizimi hatası, null değere erişim, tip uyumsuzluğu, var olmayan alan/değişken kullanımı, script derleme sınırının (compilation limit) aşılması veya izin verilmeyen API çağrısı.","fix":"Hata mesajındaki derleme/çalışma zamanı ayrıntısını inceleyin. Script söz dizimini ve alan erişimlerini düzeltin; null kontrolü ekleyin (ör. doc['alan'].size() > 0). Sık kullanılan script'leri parametreli (stored/params) hale getirerek derleme sınırını aşmayın. Doğru alan adları ve tipleri kullanın.","tags":["script","painless","derleme","runtime","script exception"]},{"code":"number_format_exception","title":"number_format_exception","severity":"caution","meaning":"Sayısal olması gereken bir değer sayıya dönüştürülemedi. Bir alana veya parametreye sayı beklenirken geçersiz/sayısal olmayan bir metin verildi.","cause":"numeric (integer/long/double) tipli alana sayısal olmayan metin gönderilmesi, boş string'in sayıya çevrilmeye çalışılması, yanlış ondalık biçimi veya mapping ile uyumsuz girdi verisi.","fix":"İlgili alana geçerli sayısal değerler gönderin. Kaynak veriyi indekslemeden önce doğrulayın/dönüştürün. Boş değerler için null kullanın veya ilgili alanı atlayın. Mapping'de coerce ayarını ve alan tipini gözden geçirin. Ondalık ayırıcı olarak nokta kullanın.","tags":["number format","sayi","donusum","numeric","format"]},{"code":"connect_transport_exception","title":"connect_transport_exception","severity":"danger","meaning":"Bir node'a transport (9300) katmanı üzerinden bağlanılamadı. Düğümler arası veya istemci-küme iletişimi kurulamadığından işlem gerçekleştirilemedi.","cause":"Hedef node'un kapalı/erişilemez olması, ağ/güvenlik duvarı sorunları, yanlış transport adresi/portu, TLS yapılandırma uyumsuzluğu, DNS sorunu veya küme adı/sürüm uyumsuzluğu.","fix":"Hedef node'un çalıştığını ve transport portuna (varsayılan 9300) ağdan erişilebildiğini doğrulayın. Güvenlik duvarı/ağ kurallarını ve discovery yapılandırmasını kontrol edin. TLS/sertifika ayarlarının tüm düğümlerde uyumlu olduğundan emin olun. Node loglarını inceleyin ve cluster.name/sürüm uyumunu doğrulayın.","tags":["transport","baglanti","connect","network","node","danger"]},{"code":"repository_missing_exception","title":"repository_missing_exception","severity":"caution","meaning":"Snapshot/restore işleminde başvurulan snapshot deposu (repository) bulunamadı. Belirtilen isimde kayıtlı bir depo yok.","cause":"Deponun hiç kaydedilmemiş olması, ad yazım hatası, deponun silinmiş olması, farklı bir kümede tanımlı olması veya küme durumunun sıfırlanması sonrası deponun yeniden kaydedilmemesi.","fix":"Kayıtlı depoları listeleyin: GET _snapshot/_all. Depoyu doğru ad ve ayarlarla yeniden kaydedin: PUT _snapshot/depo_adi (type ve settings ile). Depo adını doğru yazdığınızdan emin olun. Paylaşımlı depo (fs/s3 vb.) erişiminin tüm düğümlerde geçerli olduğunu doğrulayın.","tags":["repository","depo","snapshot","missing","yedek","restore"]},{"code":"concurrent_snapshot_execution_exception","title":"concurrent_snapshot_execution_exception","severity":"caution","meaning":"Aynı anda çakışan bir snapshot işlemi olduğu için yeni snapshot/restore isteği kabul edilmedi. İlgili depo veya index üzerinde başka bir snapshot işlemi hâlâ sürüyor.","cause":"Önceki bir snapshot'ın hâlâ devam etmesi, aynı index'i etkileyen eşzamanlı snapshot/restore çakışması, SLM (snapshot lifecycle) politikasıyla manuel snapshot'ın çakışması veya kısa aralıklı tetiklemeler.","fix":"Devam eden snapshot'ları kontrol edin: GET _snapshot/depo/_current ve GET _snapshot/_status. Mevcut işlem bitene kadar bekleyin veya gerekirse iptal edin: DELETE _snapshot/depo/snapshot_adi. Snapshot zamanlamalarını çakışmayacak şekilde ayarlayın. SLM ile manuel işlemleri koordine edin.","tags":["snapshot","concurrent","cakisma","eszamanli","slm","yedek"]},{"code":"invalid_index_name_exception","title":"invalid_index_name_exception","severity":"caution","meaning":"Verilen index adı Elasticsearch adlandırma kurallarına uymuyor. Ad geçersiz karakterler içeriyor veya biçim kurallarını ihlal ediyor.","cause":"Büyük harf kullanımı, izin verilmeyen karakterler (\\ / * ? \" < > | boşluk , #), adın _, - veya + ile başlaması, çok uzun ad (255 bayt üstü) veya . / .. gibi ayrılmış adların kullanılması. (Nokta ile başlayan adlar yasak değildir ama gizli/sistem index'lerine ayrılmıştır ve uyarı üretir.)","fix":"Index adını kurallara uygun yapın: yalnızca küçük harf kullanın; yasak karakterlerden kaçının; ad _, - veya + ile başlamasın ve nokta ile başlayan adları sistem/gizli index'ler dışında kullanmayın. Adı 255 baytın altında tutun. Uygulamada index adlarını oluştururken bu kuralları zorunlu kılın.","tags":["index name","index adi","invalid","gecersiz","naming"]},{"code":"resource_not_found_exception","title":"resource_not_found_exception","severity":"caution","meaning":"İstenen kaynak (belge, index, task, pipeline, model vb.) bulunamadı. Belirtilen kimlik/ada karşılık gelen bir kaynak mevcut değil.","cause":"Var olmayan belge id'si, silinmiş veya hiç oluşturulmamış index/pipeline, yanlış ad yazımı, henüz tamamlanmamış/temizlenmiş task veya yanlış kümeye istek gönderme.","fix":"Kaynağın adını/kimliğini ve var olduğunu doğrulayın (ör. GET /index/_doc/id, GET _ingest/pipeline/ad). Doğru index ve kümeye istek attığınızdan emin olun. Silme/oluşturma sırasını gözden geçirin. Task için _tasks API ile durumu kontrol edin.","tags":["not found","bulunamadi","resource","kaynak","404"]},{"code":"process_cluster_event_timeout_exception","title":"process_cluster_event_timeout_exception","severity":"danger","meaning":"Bir küme durumu (cluster state) güncelleme işlemi (ör. index oluşturma, mapping değişikliği) belirlenen süre içinde tamamlanamadı ve zaman aşımına uğradı. Master node güncellemeyi zamanında işleyemedi.","cause":"Master node'un aşırı yük altında olması, çok büyük/karmaşık cluster state, sık ve yoğun mapping/şablon değişiklikleri, yavaş master veya master seçim (election) sorunları.","fix":"Master node'un yükünü ve sağlığını inceleyin: GET _cluster/health, GET _cat/master, pending görevler için GET _cluster/pending_tasks. Cluster state'i küçültün (gereksiz index/mapping/şablonları azaltın, dinamik mapping patlamasını önleyin). Yoğun DDL benzeri işlemleri toplu ve düşük yoğunluklu zamanlarda yapın. Gerekiyorsa master kaynaklarını artırın.","tags":["cluster event","timeout","zaman asimi","master","cluster state","danger"]}]},"errors/oracle-more2.json":{"engineId":"oracle","engine":"Oracle","order":1,"errors":[{"code":"ORA-00955","title":"name is already used by an existing object","severity":"caution","meaning":"Oluşturmaya çalıştığınız nesnenin (tablo, index, view, sequence, synonym vb.) adı, aynı şemada zaten var olan başka bir nesne tarafından kullanılıyor. Oracle'da nesne adları bir şema içinde tekildir ve tablo, view, sequence gibi farklı türler bile aynı ad alanını paylaşır.","cause":"CREATE komutunda seçilen ad, mevcut bir nesneyle çakışıyor. Sık görülen bir tuzak: bir tablo ile aynı adı taşıyan bir sequence veya view oluşturmaya çalışmak; ya da otomatik oluşturulan bir index adının (ör. primary key index'i) sizin verdiğiniz adla çakışması.","fix":"Farklı bir ad seçin veya çakışan nesneyi kaldırın. Hangi nesnenin adı kullandığını bulmak için: SELECT object_type, object_name FROM user_objects WHERE object_name = 'ADINIZ'; Gerçekten değiştirmek istiyorsanız eski nesneyi DROP edin (verisini önce yedekleyin). CREATE OR REPLACE view, synonym, type ve PL/SQL nesneleri (procedure, function, package, trigger) için geçerlidir; tablo, index ve sequence için yoktur.","tags":["ddl","create","isim","cakisma","duplicate","object"]},{"code":"ORA-02449","title":"unique/primary keys in table referenced by foreign keys","severity":"caution","meaning":"Silmek istediğiniz tablonun primary key ya da unique key'ine, başka tablolardaki foreign key'ler referans veriyor. Oracle, bu bağımlılıkları önce kaldırmadan tabloyu düşürmenize izin vermez.","cause":"Başka tablolar bu tabloya FK ile bağlıyken CASCADE CONSTRAINTS eklemeden DROP TABLE çalıştırdınız. Referans bütünlüğünü koruyan Oracle, orphan foreign key oluşmasını engeller.","fix":"Bağımlı foreign key'lerle birlikte silmek için: DROP TABLE tablo_adi CASCADE CONSTRAINTS; Bu, diğer tablolardaki ilgili FK constraint'lerini da kaldırır (o tablolardaki veriyi silmez). Hangi constraint'lerin bağlı olduğunu görmek için: SELECT table_name, constraint_name FROM all_constraints WHERE r_constraint_name IN (SELECT constraint_name FROM user_constraints WHERE table_name = 'TABLO_ADI');","tags":["drop","foreign key","yabanci anahtar","constraint","cascade","referans"]},{"code":"ORA-01950","title":"no privileges on tablespace 'name'","severity":"danger","meaning":"Kullanıcının, veri yazmaya çalıştığı tablespace üzerinde kotası (quota) yok. Oracle'da bir nesneye yer ayırabilmek için kullanıcının ilgili tablespace'te tanımlı kota hakkı olması gerekir.","cause":"Kullanıcıya ilgili tablespace'te kota verilmemiş; genellikle UNLIMITED TABLESPACE sistem yetkisi olmayan yeni bir kullanıcı, varsayılan tablespace'ine tablo/index oluşturmaya ya da veri eklemeye çalışıyor. INSERT, CREATE TABLE veya index büyümesi sırasında ortaya çıkar.","fix":"DBA olarak kullanıcıya kota verin: ALTER USER kullanici QUOTA UNLIMITED ON tablespace_adi; ya da belirli bir sınır: ALTER USER kullanici QUOTA 500M ON users; Alternatif olarak (dikkatli kullanın) GRANT UNLIMITED TABLESPACE TO kullanici; verilebilir ancak bu tüm tablespace'lere sınırsız hak tanır ve genelde önerilmez.","tags":["tablespace","quota","kota","yetki","privilege","insert"]},{"code":"ORA-01110","title":"data file N: 'path'","severity":"danger","meaning":"Belirtilen numaralı ve yollu datafile ile ilgili bir sorun olduğunu gösteren tamamlayıcı (ikincil) bir mesajdır. Tek başına gelmez; kendisinden önce asıl hatayı bildiren başka bir ORA hatası bulunur ve bu satır sadece hangi datafile'ın etkilendiğini söyler.","cause":"Genellikle datafile'ın offline olması (ORA-00376), medya kurtarma gerektirmesi (ORA-01113), bloklarda bozulma (ORA-01578) veya dosyanın okunamaması gibi bir üst hataya eşlik eder. Disk arızası, yanlışlıkla silme, dosyanın taşınması ya da yedekten eksik geri yükleme tetikleyebilir.","fix":"Bu satırdan önceki asıl ORA hatasını okuyun ve onu çözün. Etkilenen dosyayı doğrulayın: SELECT file#, name, status FROM v$datafile; Kurtarma gerekiyorsa: RECOVER DATAFILE 'yol'; ardından ALTER DATABASE DATAFILE 'yol' ONLINE; Dosya fiziksel olarak kayıpsa RMAN ile geri yükleyip kurtarın: RESTORE DATAFILE N; RECOVER DATAFILE N;","tags":["datafile","veri dosyasi","recovery","kurtarma","offline","rman"]},{"code":"ORA-16038","title":"log N sequence# M cannot be archived","severity":"danger","meaning":"Oracle, bir online redo log dosyasını arşivleyemiyor ve bu yüzden o log grubunu yeniden kullanamıyor. ARCHIVELOG modunda arşivleme takıldığında veritabanı yeni işlem yazmayı durdurabilir ve askıya girebilir.","cause":"Genellikle arşiv hedefi (archive log destination) veya Fast Recovery Area (FRA) doludur; disk alanı bitmiştir; arşiv hedefi erişilemez durumdadır ya da bir izin/mount sorunu vardır. Sıklıkla ORA-19809 (kurtarma dosyası limiti aşıldı) veya ORA-00312 ile birlikte görülür.","fix":"Arşiv hedefinde/FRA'da yer açın: eski arşiv loglarını RMAN ile FRA dışındaki bir hedefe yedekleyip silin (DELETE ARCHIVELOG ALL COMPLETED BEFORE ...; Data Guard varsa standby'a gönderilmemiş/uygulanmamış arşivleri silmeyin) ya da db_recovery_file_dest_size değerini büyütün. Hedef durumunu kontrol edin: ARCHIVE LOG LIST; ve SELECT dest_name, status, error FROM v$archive_dest WHERE status != 'INACTIVE'; Sorun giderilince arşivleme kaldığı yerden devam eder.","tags":["archivelog","arsiv","redo","fra","recovery area","asilma"]},{"code":"ORA-19809","title":"limit exceeded for recovery files","severity":"danger","meaning":"Fast Recovery Area (FRA) için ayrılan alan (db_recovery_file_dest_size) dolmuştur. Arşiv logları, flashback logları ve yedekler için başka yer kalmadığından Oracle yeni kurtarma dosyası oluşturamaz ve veritabanı askıya girebilir.","cause":"FRA'daki arşiv logları düzenli olarak yedeklenip temizlenmediği için birikmiş; flashback log kullanımı artmış; veya ayrılan boyut gerçek iş yüküne göre küçük kalmıştır. ORA-16038 gibi arşivleme hatalarıyla birlikte görülür.","fix":"FRA kullanımını inceleyin: SELECT * FROM v$recovery_file_dest; ve SELECT * FROM v$flash_recovery_area_usage; Gereksiz arşiv loglarını RMAN ile silin: DELETE ARCHIVELOG ALL BACKED UP 1 TIMES TO DISK; (Data Guard varsa önce standby'da uygulandıklarını doğrulayın; CONFIGURE ARCHIVELOG DELETION POLICY TO APPLIED ON ALL STANDBY önerilir) veya kalıcı çözüm olarak boyutu artırın: ALTER SYSTEM SET db_recovery_file_dest_size = 50G SCOPE=BOTH; Arşiv loglarını düzenli yedekleyen bir RMAN işi kurun.","tags":["fra","recovery area","db_recovery_file_dest_size","archivelog","alan","rman"]},{"code":"ORA-00376","title":"file N cannot be read at this time","severity":"danger","meaning":"Belirtilen numaralı datafile şu an okunamıyor; çünkü offline durumda ya da erişilemez halde. İlgili tablespace'teki verilere ulaşmaya çalışan sorgular ve işlemler bu hatayla başarısız olur.","cause":"Datafile bir hata sonrası otomatik olarak veya elle offline alınmış; medya kurtarma bekliyor; disk erişilemez hale gelmiş ya da NOARCHIVELOG modunda kurtarılamayan bir dosya offline bırakılmıştır. Genellikle ORA-01110 satırıyla birlikte hangi dosya olduğunu gösterir.","fix":"Dosya durumunu görün: SELECT file#, name, status FROM v$datafile WHERE status != 'ONLINE'; Kurtarıp online alın: RECOVER DATAFILE N; ardından ALTER DATABASE DATAFILE N ONLINE; Fiziksel bozulma/kayıp varsa RMAN ile geri yükleyip kurtarın: RESTORE DATAFILE N; RECOVER DATAFILE N; Disk/donanım sorununu da mutlaka giderin.","tags":["datafile","veri dosyasi","offline","recovery","kurtarma","read"]},{"code":"ORA-12520","title":"TNS:listener could not find available handler for requested type of server","severity":"danger","meaning":"Listener, istenen bağlantı türü (dedicated veya shared) için hizmet verecek uygun bir sunucu süreci (handler) bulamadı. İstemci listener'a ulaşabiliyor ama bağlantı bir işlem sürecine yönlendirilemiyor.","cause":"Örnek (instance) listener'a kayıtlı değil ya da kaydı bozulmuş; PROCESSES/SESSIONS parametre limiti dolmuş ve yeni dedicated süreç açılamıyor; shared server yapılandırmasında dispatcher yok/yetersiz; ya da örnek yeni başlamış ve henüz kendini listener'a kaydetmemiştir.","fix":"Listener'ın gördüğü hizmetleri kontrol edin: lsnrctl services (handler sayısı ve durumları). Örneği listener'a yeniden kaydedin: ALTER SYSTEM REGISTER; PROCESSES limitini kontrol edin: SELECT resource_name, current_utilization, max_utilization, limit_value FROM v$resource_limit WHERE resource_name IN ('processes','sessions'); Gerekirse ALTER SYSTEM SET processes=... SCOPE=SPFILE; ile artırıp örneği yeniden başlatın.","tags":["listener","tns","baglanti","handler","processes","dispatcher"]},{"code":"ORA-28001","title":"the password has expired","severity":"caution","meaning":"Bağlanmaya çalıştığınız veritabanı kullanıcısının parolası, atandığı profildeki PASSWORD_LIFE_TIME süresi dolduğu için süresi geçmiş durumda. Parola değiştirilene kadar oturum açılamaz.","cause":"Kullanıcının profilinde tanımlı parola ömrü sona ermiş ve zorunlu değiştirme süresi (grace period) de dolmuştur. Oracle 11g ve sonrasında varsayılan (DEFAULT) profilde parolalar 180 günde bir süre dolar; bu durum özellikle uzun ömürlü uygulama servis hesaplarında beklenmedik kesintiye yol açar.","fix":"Parolayı yenileyin: ALTER USER kullanici IDENTIFIED BY yeni_parola; Uygulama hesaplarında sürekli sorun yaşamamak için parola süresini kaldıran bir profil kullanın: CREATE PROFILE uygulama_profili LIMIT PASSWORD_LIFE_TIME UNLIMITED; sonra ALTER USER kullanici PROFILE uygulama_profili; Süre dolmadan uyaran bir izleme kurmak da faydalıdır. DBA_USERS içindeki ACCOUNT_STATUS ile durumu görebilirsiniz.","tags":["password","parola","expired","profile","hesap","login"]},{"code":"ORA-38029","title":"object statistics are locked","severity":"caution","meaning":"Bir tablo (veya şema) üzerindeki optimizer istatistikleri kilitli olduğu için istatistik toplama/silme işlemi reddedildi. Kilitli istatistikler, DBMS_STATS ile yeniden hesaplanmaya karşı korunur.","cause":"Daha önce DBMS_STATS.LOCK_TABLE_STATS veya LOCK_SCHEMA_STATS çağrılmış (örneğin istatistiklerin sabit kalması istendiği için) ya da Data Pump import (özellikle CONTENT=METADATA_ONLY) istatistikleri istemeden kilitli bırakmıştır. Kilitliyken GATHER_TABLE_STATS çalıştırmak bu hatayı verir.","fix":"İstatistik kilidini açın: EXEC DBMS_STATS.UNLOCK_TABLE_STATS('SEMA','TABLO'); veya şema düzeyinde DBMS_STATS.UNLOCK_SCHEMA_STATS('SEMA'); Kilidin kaldırılmasını istemiyor ama yine de toplamak istiyorsanız FORCE=>TRUE kullanın: EXEC DBMS_STATS.GATHER_TABLE_STATS('SEMA','TABLO', force=>TRUE); Kilit durumunu görmek için: SELECT table_name, stattype_locked FROM dba_tab_statistics WHERE stattype_locked IS NOT NULL;","tags":["statistics","istatistik","dbms_stats","locked","kilit","optimizer"]}]},"errors/postgres-more2.json":{"engineId":"postgres","engine":"PostgreSQL","order":2,"errors":[{"code":"54001","title":"statement_too_complex","severity":"caution","meaning":"Sorgu ifadesi PostgreSQL'in işleyebileceğinden daha karmaşık; genellikle çok derin iç içe ifadeler veya çok sayıda birleşik (nested) operatör nedeniyle ifade ağacı ayrıştırıcı/planlayıcı stack sınırını aşıyor. Class 54 (program_limit_exceeded) sınıfına aittir.","cause":"Aşırı derin parantez/iç içe alt sorgu veya OR/AND zincirleri; otomatik üretilmiş devasa WHERE ... IN (...) listeleri; ya da özyinelemeli view'lardan doğan çok büyük ifade ağaçları. max_stack_depth sınırına ulaşılır.","fix":"Sorguyu sadeleştirin: uzun IN listelerini geçici bir tabloya veya VALUES kümesine alıp JOIN yapın; iç içe ifadeleri parçalayın; ORM tarafından üretilen dev sorguları gözden geçirin. Gerçekten gerekliyse ve işletim sistemi stack sınırınız uygunsa max_stack_depth değerini dikkatle artırın (ör. SET max_stack_depth = '4MB';) ancak bunu OS ulimit'inin altında tutun.","tags":["program_limit","karmasik","stack","nested","sorgu","max_stack_depth"]},{"code":"58030","title":"io_error","severity":"danger","meaning":"PostgreSQL bir dosyayı okurken veya yazarken işletim sistemi düzeyinde bir girdi/çıktı (I/O) hatasıyla karşılaştı. Bu, veritabanı dosyalarına erişimde fiziksel veya dosya sistemi kaynaklı bir sorunu gösterir. Class 58 (system_error) sınıfındadır.","cause":"Disk arızası veya bozuk sektörler; dolu disk; dosya sistemi hataları; ağ üzerinden bağlı depolamada (NFS/SAN) kesinti; izin sorunları; ya da işletim sisteminin dosya tanıtıcısı/inode limitlerinin dolması.","fix":"Disk sağlığını ve boş alanı kontrol edin (df -h, dmesg, SMART verileri). PostgreSQL loglarında hangi dosyanın etkilendiğine bakın. Dosya sistemi hatalarını giderin; gerekiyorsa donanımı değiştirin. Veri bozulması şüphesi varsa son sağlıklı yedekten geri dönmeyi planlayın ve gelecekte checksum'ları açık tutun (initdb --data-checksums).","tags":["system_error","io","disk","donanim","dosya","bozulma"]},{"code":"22004","title":"null_value_not_allowed","severity":"caution","meaning":"NULL değerin kabul edilmediği bir yere NULL geçildi. Bu, sütun NOT NULL constraint'inden (23502) farklıdır; genellikle bir fonksiyon veya prosedür bağlamında, NULL kabul etmeyen bir parametreye ya da işleme NULL verilmesinden kaynaklanır. Class 22 (data_exception) sınıfındadır.","cause":"PL/pgSQL içinde NOT NULL tanımlı bir değişkene NULL atanması; EXECUTE'a NULL sorgu metni verilmesi; ya da NULL kabul etmeyen yerleşik fonksiyon argümanlarına NULL geçilmesi. Not: STRICT işaretli bir fonksiyon NULL girdide hata vermez, çalışmadan NULL döner.","fix":"Hatanın çıktığı satırı (CONTEXT) bulun ve oraya gelen değeri NULL kontrolünden geçirin ya da COALESCE ile varsayılan verin: COALESCE(deger, varsayilan). PL/pgSQL'de NOT NULL değişkenlere atama yapmadan önce değeri doğrulayın; dinamik SQL'de EXECUTE'a verilen metnin NULL olmadığından emin olun. Uygulama katmanında zorunlu alanların NULL gönderilmesini engelleyin.","tags":["data_exception","null","fonksiyon","strict","parametre","coalesce"]},{"code":"42P18","title":"indeterminate_datatype","severity":"caution","meaning":"PostgreSQL, bir ifadenin veya parametrenin veri tipini bağlamdan çıkaramadı. En sık, tipi belirsiz bir yer tutucu ($1 gibi) ya da tek başına NULL kullanıldığında ve etrafında tip ipucu olmadığında görülür.","cause":"Hazırlanmış ifadelerde tipi belirtilmemiş parametreler; \"WHERE $1 = $2\" gibi her iki tarafı da belirsiz karşılaştırmalar; ya da NULL/dizi literallerinin bağlamsız kullanımı. Planlayıcı hangi tipin kullanılacağına karar veremez.","fix":"Belirsiz ifadeye açık tip dönüşümü (cast) ekleyin: $1::text, $1::integer, NULL::date gibi. Örneğin: SELECT $1::int + 1; Sürücü/ORM parametrelerinde tipleri belirtin. Sütun karşılaştırmalarında en az bir tarafın bilinen tipte olmasını sağlayın.","tags":["syntax","tip","belirsiz","cast","parametre","prepared"]},{"code":"42P02","title":"undefined_parameter","severity":"caution","meaning":"Sorguda var olmayan bir parametreye başvuruldu. PostgreSQL, referans verilen konumsal parametrenin (ör. $2) tanımlı olmadığını bildiriyor. Class 42 (syntax_error_or_access_rule_violation) sınıfındadır.","cause":"PREPARE ile hazırlanmış bir ifadede sağlanandan fazla parametreye atıfta bulunmak (ör. iki parametre gönderip $3 kullanmak); parametre numaralandırmasının atlanması; ya da dinamik olarak birleştirilen SQL'de yanlış $N indeksleri kullanılması.","fix":"Parametre numaralarının sağladığınız değer sayısıyla eşleştiğinden emin olun; $1'den başlayıp boşluksuz devam ettiğini doğrulayın. PREPARE ifadesinde parametre tiplerini eksiksiz tanımlayın: PREPARE p(int, text) AS SELECT ... WHERE a=$1 AND b=$2; ORM/sürücü kullanıyorsanız bağlanan parametre sayısını sorgudaki yer tutucularla karşılaştırın.","tags":["syntax","parametre","prepared","tanimsiz","placeholder","sql"]},{"code":"2F003","title":"prohibited_sql_statement_attempted","severity":"caution","meaning":"Bir SQL fonksiyonunun/rutininin içinde, o bağlamda yasak olan bir ifade çalıştırılmaya çalışıldı. Class 2F (sql_routine_exception) sınıfındadır. Örneğin salt-okunur olması beklenen bir fonksiyonun veri değiştirmeye kalkması.","cause":"Çekirdek PostgreSQL bu kodu nadiren üretir; genellikle eklenti veya prosedürel dil kodundan gelir. Not: IMMUTABLE/STABLE işaretli bir fonksiyonun INSERT/UPDATE/DELETE çalıştırması 2F003 değil, 0A000 (feature_not_supported) koduyla '... is not allowed in a non-volatile function' hatası verir.","fix":"Hata mesajında hangi ifadenin yasaklandığını okuyun ve ilgili rutin/eklenti belgesine bakın. Non-volatile fonksiyon hatası (0A000) alıyorsanız veri değiştiren fonksiyonu VOLATILE olarak tanımlayın (bu varsayılandır): CREATE FUNCTION ... LANGUAGE plpgsql VOLATILE. Salt-okunur olması gereken yerlerde (index ifadeleri, constraint kontrolleri) veri değiştiren çağrıları kaldırın.","tags":["sql_routine","fonksiyon","volatile","yasak","immutable","yan etki"]},{"code":"40003","title":"statement_completion_unknown","severity":"danger","meaning":"Transaction'ın sonucu belirsiz; sunucuyla bağlantı, transaction'ın tamamlanıp tamamlanmadığı belli olmadan (özellikle COMMIT sırasında) koptu. İstemci, değişikliklerin kalıcı olup olmadığını kesin bilemez. Class 40 (transaction_rollback) sınıfındadır.","cause":"COMMIT komutu gönderildikten sonra yanıt gelmeden ağın kopması, sunucunun çökmesi veya failover yaşanması. Transaction sunucuda tamamlanmış da olabilir, geri alınmış da olabilir.","fix":"İşlemi körlemesine tekrar denemeyin; önce gerçekten uygulanıp uygulanmadığını doğrulayın (ör. beklenen kaydın var olup olmadığını sorgulayarak). İşlemleri idempotent (tekrar edilebilir) tasarlayın; benzersiz iş anahtarları/idempotency key kullanın. Bağlantı havuzunda sağlam yeniden bağlanma ve doğrulama mantığı uygulayın.","tags":["transaction","commit","belirsiz","baglanti","idempotent","failover"]},{"code":"08003","title":"connection_does_not_exist","severity":"danger","meaning":"Var olmayan (zaten kapanmış) bir veritabanı bağlantısı üzerinde işlem yapılmaya çalışıldı. Uygulama, geçerli olmayan bir bağlantı tanıtıcısını kullanarak sorgu göndermeye kalktı. Class 08 (connection_exception) sınıfındadır.","cause":"Bağlantı zaman aşımı, sunucu tarafından kapatılma, ağ kesintisi veya havuzdan alınan bir bağlantının aslında ölü olması; ya da uygulama kodunda close() edilmiş bir bağlantının yeniden kullanılması.","fix":"Bağlantı havuzunda canlılık kontrolü (validation query / keepalive) açın; ölü bağlantıları havuzdan çıkaracak ayarları yapın (ör. HikariCP'de connectionTestQuery/maxLifetime). Uygulamada bağlantıyı kullanmadan önce açık olduğundan emin olun ve kesildiğinde otomatik yeniden bağlanma uygulayın. TCP keepalive ve idle_in_transaction_session_timeout değerlerini gözden geçirin.","tags":["connection","baglanti","kapali","pool","havuz","timeout"]},{"code":"25006","title":"read_only_sql_transaction","severity":"caution","meaning":"Salt-okunur bir transaction içinde veri değiştiren bir komut (INSERT/UPDATE/DELETE/DDL) çalıştırılmaya çalışıldı. Transaction yalnızca okuma yapabilecek şekilde ayarlanmış. Class 25 (invalid_transaction_state) sınıfındadır.","cause":"SET TRANSACTION READ ONLY veya default_transaction_read_only=on ayarı; ya da en yaygın olarak bir okuma replikasına (hot standby / streaming replica) yazma denemesi. Standby sunucular tanımı gereği salt-okunurdur.","fix":"Yazma işlemlerini primary sunucuya yönlendirin; okuma/yazma ayrımı yapan bağlantı yönlendirmenizi kontrol edin. Yanlışlıkla ayarlandıysa: SET TRANSACTION READ WRITE; veya sunucu genelinde default_transaction_read_only=off. Uygulamanızda okuma-yazma trafiğini doğru düğüme gönderdiğinizden emin olun.","tags":["transaction","read only","salt okunur","replica","standby","primary"]},{"code":"21000","title":"cardinality_violation","severity":"caution","meaning":"Tek satır beklenen bir yerde birden fazla satır döndü. Skaler bir alt sorgunun (scalar subquery) birden çok satır döndürmesi ya da MERGE/ON CONFLICT DO UPDATE'in aynı hedef satırı ikinci kez etkilemeye çalışması durumudur. Class 21 sınıfındadır.","cause":"SELECT listesinde ya da WHERE = (alt sorgu) biçiminde kullanılan bir alt sorgunun birden çok satır döndürmesi; INSERT ... ON CONFLICT DO UPDATE'te aynı komutta aynı çakışma anahtarının birden çok kez önerilmesi ('cannot affect row a second time'); ya da MERGE'de bir hedef satıra birden çok kaynak satırın eşleşmesi. UPDATE ... FROM'da çoklu eşleşme hata vermez; hedef satır kaynak satırlardan yalnızca biriyle, öngörülemez biçimde güncellenir.","fix":"Alt sorgunun tek satır döndürdüğünden emin olun: LIMIT 1 ekleyin, bir toplama (MAX/MIN) kullanın ya da eşleşmeyi tekilleştiren bir koşul verin. MERGE ve ON CONFLICT kalıplarında kaynak tarafı DISTINCT ON/aggregate ile tekilleştirin; aynısını sessiz yanlış sonuçlara karşı UPDATE ... FROM için de yapın. Beklenmedik çoklu eşleşmeleri bulmak için alt sorguyu tek başına çalıştırıp satır sayısını kontrol edin.","tags":["cardinality","subquery","alt sorgu","tek satir","join","scalar"]}]},"errors/mysql-more2.json":{"engineId":"mysql","engine":"MySQL","order":3,"errors":[{"code":"1927","title":"MariaDB: ER_CONNECTION_KILLED: Connection was killed","severity":"danger","meaning":"MariaDB'ye özgüdür: çalışmakta olan bağlantı/thread sunucu tarafından sonlandırıldı, devam eden sorgu yarıda kesildi ve istemci bağlantısı düşürüldü. MySQL'de bu kod yoktur; MySQL'de aynı durum sorgu kesildiğinde 1317 (ER_QUERY_INTERRUPTED), bağlantı koptuğunda istemci tarafında 2013 (Lost connection) olarak görülür.","cause":"Bir yönetici veya izleme aracının KILL komutu göndermesi; sunucunun kapanma (shutdown) sürecine girmesi; MariaDB'de idle_transaction_timeout/wait_timeout gibi boşta bağlantı sınırları; ya da kaynak baskısı altında sunucunun bağlantıyı düşürmesi. Bulut/proxy ortamlarında bakım sırasında da görülür.","fix":"Sorgunun neden öldürüldüğünü araştırın: uzun süren sorgular için SHOW PROCESSLIST ve slow query log; sunucu bakım/yeniden başlatma zamanlamaları; connection kill politikaları. Uygulamada bu hatayı yakalayıp güvenli biçimde (idempotent ise) yeniden deneyin. Uzun sorguları optimize edip parçalayın; bağlantı havuzunda otomatik yeniden bağlanma kullanın.","tags":["connection","baglanti","kill","thread","shutdown","retry"]},{"code":"1290","title":"ER_OPTION_PREVENTS_STATEMENT: running with the --read-only option","severity":"caution","meaning":"MySQL sunucusu --read-only veya --super-read-only seçeneğiyle çalıştığı için veri değiştiren komutu (INSERT/UPDATE/DELETE/DDL) reddetti. read_only'de CONNECTION_ADMIN/SUPER yetkili kullanıcılar yazabilir; super_read_only açıkken onlar da yazamaz ve mesaj '--super-read-only option' olarak gelir.","cause":"read_only=ON ya da super_read_only=ON ayarı; çoğunlukla bir replika (replica) sunucusuna yanlışlıkla yazma denemesi. Replikalar ve Group Replication secondary'leri veri tutarlılığı için salt-okunur tutulur; failover otomasyonları eski primary'yi super_read_only'ye alır. Failover/switchover sırasında yanlış düğüme yazmak da tetikler.","fix":"Yazma işlemlerini primary (source) sunucuya yönlendirin. Bu sunucu gerçekten yeni primary olmalıysa: SET GLOBAL read_only = OFF; (read_only'yi kapatmak super_read_only'yi de otomatik kapatır; super_read_only'yi açmak da read_only'yi açar). HA aracınızın (Orchestrator/Group Replication/InnoDB Cluster) yönettiği düğümlerde elle değiştirmeyin. Durumu görmek için: SELECT @@read_only, @@super_read_only;","tags":["read only","super_read_only","salt okunur","replica","primary","yazma","failover","1290"]},{"code":"1836","title":"ER_READ_ONLY_MODE: Running in read-only mode","severity":"caution","meaning":"InnoDB salt okunur modda çalışıyor (innodb_read_only=ON) ya da veri dizini/medya salt okunur; InnoDB tablolarında yazma ve DDL reddediliyor. Not: read_only/super_read_only açıkken yazma denemesi bu kodu değil 1290 (ER_OPTION_PREVENTS_STATEMENT) hatasını verir.","cause":"Sunucunun innodb_read_only=ON ile başlatılması (ör. salt okunur medya, paylaşılan veri dizini, analiz amaçlı kopya); bu modda InnoDB tablolarına INSERT/UPDATE/DELETE, CREATE/DROP/ALTER TABLE gibi değişiklikler yapılamaz.","fix":"Yazma gerekiyorsa sunucuyu innodb_read_only olmadan başlatın: my.cnf'den innodb_read_only=ON satırını kaldırıp yeniden başlatın (bu değişken dinamik değildir, restart gerektirir). Durumu görmek için: SELECT @@innodb_read_only; Veri dizininin ve dosya sisteminin yazılabilir olduğunu doğrulayın. Bir replika/HA secondary'sine yazıyorsanız (1290) yazmayı primary'ye yönlendirin.","tags":["innodb_read_only","read only","salt okunur","innodb","1836"]},{"code":"3819","title":"ER_CHECK_CONSTRAINT_VIOLATED: Check constraint is violated","severity":"caution","meaning":"Eklemeye veya güncellemeye çalıştığınız satır, tabloda tanımlı bir CHECK constraint'ini ihlal ediyor. MySQL 8.0.16 ve sonrasında CHECK constraint'leri gerçekten uygulanır (önceki sürümlerde yok sayılıyordu).","cause":"Sütun değeri, CHECK ifadesinde tanımlı koşulu sağlamıyor (ör. CHECK (fiyat >= 0) varken negatif fiyat girilmesi). Eski MySQL sürümlerinden 8.0.16+ sürümüne geçtikten sonra, önceden yok sayılan constraint'lerin artık zorlanmasıyla beklenmedik biçimde ortaya çıkabilir.","fix":"Girilen değerin constraint koşulunu sağladığından emin olun; uygulama tarafında doğrulama ekleyin. Constraint'in tanımını görmek için: SHOW CREATE TABLE tablo; Constraint gerçekten gereksizse: ALTER TABLE tablo DROP CHECK kisit_adi; ya da geçici olarak ALTER TABLE tablo ALTER CHECK kisit_adi NOT ENFORCED; Yanlış verinin kaynağını da düzeltin.","tags":["check","constraint","kisit","dogrulama","8.0","violation"]},{"code":"1118","title":"ER_TOO_BIG_ROWSIZE: Row size too large","severity":"caution","meaning":"Tanımlamaya çalıştığınız tablonun satır boyutu, kullanılan depolama motorunun izin verdiği en büyük satır boyutunu aşıyor. BLOB/TEXT dışı sütunlar için satır boyutu üst sınırı 65535 bayttır; InnoDB'de sayfa boyutuna bağlı ek sınırlar da vardır.","cause":"Çok sayıda geniş sütun (özellikle uzun VARCHAR/CHAR) tanımlamak; utf8mb4 gibi çok baytlı karakter setlerinde her karakterin 4 bayta kadar yer tutması; ya da InnoDB'nin COMPACT/REDUNDANT satır formatında büyük sütunların satır içinde saklanması.","fix":"Bazı büyük sütunları TEXT/BLOB tipine çevirin (bunlar satır dışında saklanabilir); gereksiz veya çok geniş sütunları küçültün ya da tabloyu ikiye bölün. InnoDB'de ROW_FORMAT=DYNAMIC veya COMPRESSED kullanmak büyük sütunları satır dışına taşıyarak yardımcı olur: ALTER TABLE tablo ROW_FORMAT=DYNAMIC; Ayrıca innodb_page_size'ı da göz önünde bulundurun.","tags":["row size","satir boyutu","innodb","varchar","row_format","limit"]},{"code":"1170","title":"ER_BLOB_KEY_WITHOUT_LENGTH: BLOB/TEXT column used in key specification without a key length","severity":"caution","meaning":"Bir BLOB veya TEXT sütununu index/anahtar tanımında, önek uzunluğu (prefix length) belirtmeden kullandınız. Bu tiplerin tamamı indekslenemez; yalnızca ilk N karakteri/baytı indekslenebilir.","cause":"CREATE TABLE veya CREATE INDEX içinde bir TEXT/BLOB sütununa uzunluk vermeden INDEX/UNIQUE/PRIMARY KEY tanımlamak. MySQL, potansiyel olarak çok büyük bu değerlerin tamamını indeksleyemeyeceği için önek uzunluğu ister.","fix":"Index'te önek uzunluğu belirtin: INDEX (aciklama(255)) gibi. Örnek: ALTER TABLE tablo ADD INDEX idx_aciklama (aciklama(191)); (utf8mb4'te InnoDB anahtar önek sınırı nedeniyle 191 sık kullanılır). Tam metin araması gerekiyorsa FULLTEXT index düşünün. Kısa ve tekil olması gereken alanlarda sütunu VARCHAR'a çevirmek daha uygun olabilir.","tags":["index","indeks","blob","text","prefix","onek uzunlugu"]},{"code":"1592","title":"ER_BINLOG_UNSAFE_STATEMENT: Unsafe statement written to the binary log","severity":"caution","meaning":"STATEMENT tabanlı binlog formatı kullanılırken, sonucu deterministik olmayan (replikada farklı sonuç üretebilecek) bir ifade çalıştırıldı. MySQL bunu binlog'a yazarken uyarı verir; çünkü kaynak ve replika arasında veri tutarsızlığı riski vardır.","cause":"binlog_format=STATEMENT iken UUID(), SYSDATE(), USER() gibi deterministik olmayan fonksiyonlar (NOW() ise STATEMENT'ta güvenle çoğaltılır), LIMIT'li ORDER BY olmayan UPDATE/DELETE, AUTO_INCREMENT ile karışık INSERT, ya da bazı kullanıcı tanımlı/sistem fonksiyonlarını kullanmak. Bu ifadeler her sunucuda aynı sonucu vermeyebilir.","fix":"Binlog formatını satır tabanlıya çevirin (önerilen; MySQL 5.7.7'den beri varsayılan ROW'dur): my.cnf'de binlog_format=ROW ya da SET PERSIST binlog_format = ROW; (binlog_format değişkeni 8.0.34'ten beri deprecated'dır; değişiklik yeni oturumlarda geçerli olur). ROW formatı deterministik olmayan ifadeleri güvenle çoğaltır. STATEMENT'ta kalmanız gerekiyorsa deterministik olmayan fonksiyon/ifadeleri sabit değerlerle değiştirin ve LIMIT'li DML'lere belirleyici ORDER BY ekleyin.","tags":["binlog","replication","unsafe","statement","row","deterministik"]},{"code":"3140","title":"ER_INVALID_JSON_TEXT: Invalid JSON text","severity":"caution","meaning":"Bir JSON sütununa ya da JSON fonksiyonuna geçerli olmayan (sözdizimi bozuk) JSON metni verildi. MySQL, değeri JSON olarak ayrıştıramadığı için işlemi reddeder.","cause":"Kapanmamış tırnak/parantez, sondaki fazladan virgül, tek tırnak kullanımı, kaçış karakteri hataları ya da düz metnin JSON sütununa gönderilmesi. JSON_SET, JSON_INSERT gibi fonksiyonlara veya JSON tipli sütuna hatalı metin girildiğinde ortaya çıkar.","fix":"JSON metnini geçerli sözdizimine göre düzeltin: çift tırnak kullanın, sondaki virgülleri kaldırın, kaçışları doğrulayın. Metnin geçerli olup olmadığını test edin: SELECT JSON_VALID('{...}'); (1 döndürürse geçerlidir). Uygulama katmanında JSON'u serileştirirken güvenilir bir kütüphane kullanın ve sunucuya göndermeden önce doğrulayın.","tags":["json","gecersiz","sozdizimi","json_valid","parse","veri"]},{"code":"1526","title":"ER_NO_PARTITION_FOR_GIVEN_VALUE: Table has no partition for value","severity":"caution","meaning":"Eklemeye çalıştığınız satırın bölümleme (partition) anahtarı değeri, tanımlı hiçbir bölüme uymuyor. RANGE veya LIST bölümlemede, gelen değeri kapsayan bir bölüm bulunmadığı için ekleme başarısız olur.","cause":"RANGE bölümlemede en üst sınırın ötesinde bir değer eklemek ve MAXVALUE bölümünün tanımlı olmaması (ör. gelecekteki bir tarih); LIST bölümlemede listelenmemiş bir değerin gelmesi. Zamana göre bölümlenmiş tablolarda yeni dönem bölümü zamanında eklenmediğinde sık yaşanır.","fix":"Değeri kapsayan bir bölüm ekleyin. RANGE için yeni üst bölüm: ALTER TABLE tablo ADD PARTITION (PARTITION p2026 VALUES LESS THAN (2027)); Genel bir yakalama bölümü için RANGE'de MAXVALUE, LIST'te ilgili değerleri tanımlayın. Zaman bazlı tablolarda bölümleri otomatik ekleyen bir bakım işi (event/scheduler) kurun.","tags":["partition","bolumleme","range","list","maxvalue","insert"]}]},"errors/mssql-more2.json":{"engineId":"mssql","engine":"SQL Server","order":4,"errors":[{"code":"1101","title":"Could not allocate a new page because of insufficient disk space in filegroup","severity":"danger","meaning":"SQL Server, bir nesneye yeni sayfa ayırmak istedi ancak ilgili dosya grubunda (filegroup) yeterli disk alanı yok. Data file'lar ne büyüyebiliyor ne de yeni sayfa bulabiliyor; bu yüzden veri yazma işlemi başarısız oluyor.","cause":"Data file'ın bulunduğu disk dolmuş; dosya otomatik büyümeye (autogrow) kapalı ya da MAXSIZE sınırına ulaşmış; veya dosya grubundaki tüm dosyalar tavan boyutlarına dayanmış. Büyük INSERT/index oluşturma işlemleri sırasında sık görülür.","fix":"İlgili diskte yer açın veya dosya grubuna alan ekleyin. Dosyayı büyütün ya da otomatik büyümeyi açın: ALTER DATABASE db MODIFY FILE (NAME = mantiksal_ad, SIZE = 20GB, MAXSIZE = UNLIMITED, FILEGROWTH = 512MB); Alternatif olarak dosya grubuna yeni bir dosya ekleyin (başka bir diskte). Dosya kullanımını görmek için sys.database_files ve DBCC SQLPERF ile boş alanı kontrol edin.","tags":["disk","filegroup","dosya grubu","autogrow","alan","allocation"]},{"code":"3729","title":"Cannot DROP because it is being referenced by object","severity":"caution","meaning":"Silmek istediğiniz nesne (tablo, tip, fonksiyon vb.), başka bir nesne tarafından referans veriliyor ve bu bağımlılık silmeyi engelliyor. Özellikle şemaya bağlı (schema-bound) nesneler bu koruma altındadır.","cause":"SCHEMABINDING ile oluşturulmuş bir view'ın veya fonksiyonun temel aldığı tabloyu/nesneyi düşürmeye çalışmak; foreign key ile referans verilen bir tabloyu silmeye çalışmak; ya da kullanıcı tanımlı bir tipi, onu kullanan tablo/parametre varken kaldırmak.","fix":"Önce referans veren nesneleri düşürün veya bağımlılığı kaldırın. Bağımlılıkları bulmak için: SELECT referencing_schema_name, referencing_entity_name FROM sys.dm_sql_referencing_entities('sema.nesne', 'OBJECT'); Şemaya bağlı view'larda önce ALTER VIEW ile SCHEMABINDING'i kaldırın ya da view'ı düşürün, sonra tabloyu silin.","tags":["drop","referans","schemabinding","view","bagimlilik","dependency"]},{"code":"3961","title":"Snapshot isolation transaction failed because the object was modified by a DDL statement","severity":"caution","meaning":"Snapshot yalıtım düzeyinde çalışan transaction, eriştiği nesnenin başka bir eşzamanlı transaction'daki bir DDL komutuyla (şema değişikliği) değiştirilmesi nedeniyle başarısız oldu. Meta veri sürümlenmediği için snapshot transaction'ı bu durumda devam edemez.","cause":"SNAPSHOT yalıtım düzeyinde (SET TRANSACTION ISOLATION LEVEL SNAPSHOT) başlamış bir transaction sürerken, başka bir oturumun eriştiği tabloda ALTER TABLE/CREATE INDEX gibi DDL çalıştırması. Snapshot transaction'ları veri sürümlerini görebilir ama şema sürümlerini göremez. READ COMMITTED SNAPSHOT (RCSI) altında bu hata oluşmaz; RCSI her ifade için yeni bir snapshot alır.","fix":"İşlemi yeniden deneyin; DDL tamamlandıktan sonra genellikle başarılı olur. Kalıcı çözüm için şema değişikliklerini (DDL) yoğun snapshot iş yükünün olmadığı bakım pencerelerinde yapın. Uygulamada bu hatayı yakalayıp otomatik yeniden deneme (retry) mantığı uygulayın. Uzun süren snapshot işlemlerini kısaltın.","tags":["snapshot","yalitim","ddl","eszamanlilik","retry","isolation"]},{"code":"1785","title":"Introducing FOREIGN KEY constraint may cause cycles or multiple cascade paths","severity":"caution","meaning":"Eklemeye çalıştığınız foreign key, cascade (ON DELETE/UPDATE CASCADE) işlemlerinde döngü ya da aynı tabloya birden fazla basamaklı silme/güncelleme yolu oluşturabilir. SQL Server, belirsiz cascade davranışını önlemek için bunu reddeder.","cause":"Cascade eylemli bir FK'nin, tablolar arasında dairesel bir referans (A->B->A) ya da bir tabloya birden çok cascade yolu yaratması. SQL Server, cascade sırasının belirsizleşmesini ve sonsuz döngüyü engellemek için buna izin vermez.","fix":"Foreign key'i ON DELETE NO ACTION / ON UPDATE NO ACTION olarak tanımlayın (cascade'i kaldırın): ALTER TABLE cocuk ADD CONSTRAINT fk ... FOREIGN KEY (...) REFERENCES ebeveyn(...) ON DELETE NO ACTION; İhtiyaç duyulan basamaklı silmeyi bir INSTEAD OF DELETE trigger'ıyla uygulayın: trigger önce alt satırları, sonra üst satırı silsin (ör. DELETE c FROM cocuk c JOIN deleted d ON c.ebeveyn_id = d.id; DELETE e FROM ebeveyn e JOIN deleted d ON e.id = d.id;). AFTER DELETE trigger'ı işe yaramaz; FK kontrolü trigger'dan önce çalıştığı için silme 547 hatasıyla reddedilir. Veri modelinde döngüsel bağımlılıkları gözden geçirin.","tags":["foreign key","yabanci anahtar","cascade","dongu","cycle","constraint"]},{"code":"9421","title":"XML parsing: illegal xml character","severity":"caution","meaning":"SQL Server bir metni XML olarak ayrıştırırken izin verilmeyen (geçersiz) bir karakterle karşılaştı. XML tipine dönüştürme veya XML sütununa/değişkenine değer atama işlemi bu karakter nedeniyle başarısız oldu.","cause":"Metinde XML 1.0'da yasak kontrol karakterleri (ör. 0x00-0x1F aralığındaki bazı karakterler), yanlış kodlama (encoding uyuşmazlığı), ya da başka bir kaynaktan gelen bozuk/temizlenmemiş veri. Genellikle CAST(... AS XML) veya XML sütununa INSERT sırasında ortaya çıkar.","fix":"Metni XML'e dönüştürmeden önce geçersiz karakterlerden temizleyin. Kaynağın kodlamasını (UTF-8/UTF-16) hedefle uyumlu hale getirin; XML bildiriminde doğru encoding belirtin. Kontrol karakterlerini REPLACE/NCHAR ile ayıklayabilir ya da uygulama katmanında XML'i standart bir kütüphaneyle üretip doğrulayabilirsiniz. Ham metni saklamanız gerekiyorsa NVARCHAR(MAX) kullanmayı değerlendirin.","tags":["xml","parse","karakter","encoding","gecersiz","cast"]},{"code":"15151","title":"Cannot find the object/principal because it does not exist or you do not have permission","severity":"caution","meaning":"Başvurduğunuz nesne veya güvenlik asıl adı (principal: kullanıcı, rol, oturum) ya gerçekten yok ya da erişmek/işlem yapmak için yeterli izniniz yok. SQL Server, güvenlik nedeniyle bu iki durumu tek mesajda birleştirir.","cause":"GRANT/ALTER/DROP gibi bir komutta var olmayan bir kullanıcı, rol, şema ya da nesne adı yazmak; yanlış veritabanı bağlamında çalışmak (nesne başka bir DB'de); ya da işlemi yapmaya yetkiniz olmaması. İsim yazım hataları ve büyük/küçük harf/şema önekleri sık nedendir.","fix":"Nesne/asıl adının doğru yazıldığını ve doğru veritabanında olduğunuzu doğrulayın. Kullanıcılar için: SELECT name, type_desc FROM sys.database_principals; nesneler için sys.objects sorgulayın. İşlemi yapan hesabın gerekli izinlere (ör. ALTER ANY USER, CONTROL) sahip olduğundan emin olun. Doğru şema önekini kullanın (dbo.nesne gibi).","tags":["permission","principal","yetki","bulunamadi","grant","guvenlik"]},{"code":"4834","title":"You do not have permission to use the bulk load statement","severity":"caution","meaning":"BULK INSERT (veya OPENROWSET BULK) ile toplu veri yükleme çalıştırmak için gerekli izne sahip değilsiniz. Toplu yükleme, doğrudan dosya sistemine ve sunucu kaynaklarına eriştiği için ayrı bir yetki gerektirir.","cause":"Login'in sunucu düzeyindeki ADMINISTER BULK OPERATIONS yetkisi yok ya da bulkadmin sunucu rolüne üye değil (Azure SQL Database'de bunun yerine veritabanı düzeyindeki ADMINISTER DATABASE BULK OPERATIONS gerekir). Ayrıca hedef tabloda INSERT izni ve SQL Server hizmet hesabının kaynak dosyaya okuma erişimi gerekir.","fix":"Gerekli yetkiyi verin: GRANT ADMINISTER BULK OPERATIONS TO oturum; (sunucu düzeyinde) ya da kullanıcıyı ilgili role ekleyin. Azure SQL DB'de ADMINISTER DATABASE BULK OPERATIONS kullanılır. Ayrıca SQL Server hizmet hesabının hedef dosya/paylaşım üzerinde okuma iznine sahip olduğundan emin olun. En az ayrıcalık ilkesine göre yalnızca gereken hesaplara verin.","tags":["bulk insert","yetki","permission","toplu yukleme","bulkadmin","dosya"]},{"code":"10928","title":"Resource limit for the database has been reached (Azure SQL)","severity":"danger","meaning":"Azure SQL Database'te veritabanının kaynak sınırına (eşzamanlı istek/işlem veya oturum sayısı gibi) ulaşıldı ve yeni istek reddedildi. Seçilen hizmet katmanının (service tier/DTU veya vCore) tavanına dayanıldığını gösterir.","cause":"Seçili katmanın izin verdiği maksimum eşzamanlı istek (worker) ya da oturum sınırının aşılması; ani yük artışı; verimsiz/uzun süren sorguların çalışan işçileri (worker threads) tüketmesi; ya da bağlantı havuzunun aşırı büyümesi.","fix":"Eşzamanlılığı azaltın: sorguları optimize edip süreleri kısaltın, gereksiz açık transaction'ları kapatın, bağlantı havuzu boyutunu makul tutun. Kalıcı yük için hizmet katmanını yükseltin (daha yüksek DTU/vCore). Kaynak kullanımını sys.dm_db_resource_stats ile izleyin. Yeniden denenebilir hatalar için uygulamada geri çekilmeli (exponential backoff) retry uygulayın.","tags":["azure","limit","kaynak","dtu","vcore","eszamanlilik"]},{"code":"40544","title":"The database has reached its size quota (Azure SQL)","severity":"danger","meaning":"Azure SQL Database, hizmet katmanı için belirlenen maksimum veri boyutu kotasına ulaştı. Veritabanı daha fazla büyüyemediği için yeni veri yazma işlemleri başarısız oluyor.","cause":"Verinin katman sınırına dayanacak kadar büyümesi; büyük index'lerin/log'un yer kaplaması; ya da seçili katmanın (ör. Basic/Standard S-serisi) izin verdiği MAXSIZE değerinin küçük olması. Arşivlenmeyen geçmiş veri de kotayı hızla doldurur.","fix":"Yer açın: gereksiz veriyi silin/arşivleyin, kullanılmayan index'leri kaldırın, tabloları sıkıştırın (data compression). Kalıcı çözüm için MAXSIZE'ı büyütün ya da daha yüksek bir hizmet katmanına geçin: ALTER DATABASE db MODIFY (MAXSIZE = 250 GB); Boyut kullanımını sys.database_files ve ilgili DMV'lerle izleyin. Büyüme trendine göre önden ölçekleme planlayın.","tags":["azure","boyut","kota","maxsize","size quota","olceklendirme"]},{"code":"40613","title":"Database is not currently available (Azure SQL)","severity":"danger","meaning":"Azure SQL'de hedef veritabanı o an erişilebilir değil. Genellikle geçici bir durumdur; platformun veritabanını taşıması, yeniden yapılandırması (reconfiguration) veya kurtarması sırasında kısa süreli olarak ortaya çıkar.","cause":"Azure tarafında otomatik ölçekleme/failover, yama, yük dengeleme veya kaynak yeniden konumlandırma; nadiren daha uzun süren bir platform olayı. Bağlantı, veritabanı online olana kadar reddedilir.","fix":"İşlemi biraz bekleyip yeniden deneyin; bu, geçici (transient) bir hatadır. Uygulamada üstel geri çekilmeli otomatik yeniden deneme (exponential backoff retry) uygulayın; Azure SDK/retry kütüphaneleri bu hata kodunu geçici olarak tanır. Sorun uzarsa Azure hizmet durumunu (Service Health) ve bölge olaylarını kontrol edin. Yüksek erişilebilirlik için geo-replikasyon/failover grubu düşünün.","tags":["azure","gecici","transient","erisim","retry","failover"]}]},"errors/mongodb-more2.json":{"engineId":"mongodb","engine":"MongoDB","order":5,"errors":[{"code":"31 RoleNotFound","title":"Role not found","severity":"caution","meaning":"Başvurulan rol MongoDB'de tanımlı değil. Bir kullanıcıya rol atarken, rolü güncellerken ya da rolün ayrıcalıklarını sorgularken var olmayan bir rol adı kullanıldı.","cause":"grantRolesToUser/createUser sırasında yanlış yazılmış ya da hiç oluşturulmamış bir rol adı; rolün yanlış veritabanında aranması (roller belirli bir DB'ye bağlıdır); ya da yerleşik olmayan özel bir rolün henüz createRole ile tanımlanmamış olması.","fix":"Rol adını ve bağlı olduğu veritabanını doğrulayın. Mevcut rolleri listeleyin: db.getRoles({showBuiltinRoles: false}) veya tüm DB'ler için ilgili admin sorgusu. Özel rol yoksa önce oluşturun: db.createRole({role:'okuyucu', privileges:[...], roles:[]}). Rol atarken doğru db'yi belirtin: db.grantRolesToUser('kullanici', [{role:'okuyucu', db:'uygulama'}]).","tags":["role","rol","authorization","yetkilendirme","createrole","user"]},{"code":"263 OperationNotSupportedInTransaction","title":"Operation not supported inside a multi-document transaction","severity":"caution","meaning":"Çok belgeli bir transaction içinde, o bağlamda desteklenmeyen bir işlem çalıştırılmaya çalışıldı. Bazı komutlar (özellikle bazı DDL ve meta veri işlemleri) transaction içinde çalışamaz.","cause":"Transaction içinde koleksiyon/index oluşturma gibi (sürüme bağlı olarak) desteklenmeyen işlemler; sayım/liste türü bazı komutlar; ya da doğrudan işlem oturumuna uygun olmayan yönetim komutları. Eski MongoDB sürümlerinde transaction içinde DDL desteklenmez (4.4+ ile bir kısmı gelmiştir).","fix":"Desteklenmeyen işlemi transaction'ın dışına alın (ör. gerekli koleksiyon/index'leri transaction başlamadan önce oluşturun). MongoDB sürümünüzü kontrol edin; 4.4+ bazı DDL'leri transaction içinde destekler. Sürücüde işlemi ayrı bir oturumda çalıştırın. Transaction'ı yalnızca desteklenen CRUD işlemleriyle sınırlayın.","tags":["transaction","islem","ddl","desteklenmeyen","session","crud"]},{"code":"20 IllegalOperation","title":"Illegal operation","severity":"caution","meaning":"İstenen işlem, sunucunun o anki durumu veya hedef nesnenin türü için geçersiz/yasak. MongoDB, mantıksal olarak izin verilmeyen bir eylemi reddettiğinde bu genel hatayı döndürür.","cause":"Bir view üzerinde yalnızca koleksiyonlarda çalışan bir işlem denemek; iki veritabanı arasında geçersiz bir yeniden adlandırma; sistem koleksiyonları üzerinde yasak bir değişiklik; ya da replica set/sharding yapılandırmasının izin vermediği bir yönetim eylemi. Bağlama göre değişir.","fix":"Hata mesajının ayrıntısını okuyun; hangi işlemin neden yasaklandığını genellikle açıkça belirtir. İşlemi hedef nesnenin türüne uygun hale getirin (ör. view yerine temel koleksiyonda çalışın). Yeniden adlandırma/taşıma gibi işlemlerde MongoDB'nin kısıtlarını gözden geçirin (aynı DB içinde renameCollection gibi). Küme durumunu (replica set/sharding) kontrol edin.","tags":["illegal","gecersiz","islem","view","rename","sistem"]},{"code":"48 NamespaceExists","title":"Namespace (collection) already exists","severity":"safe","meaning":"Oluşturmaya çalıştığınız koleksiyon (namespace) zaten var. MongoDB, aynı ad ve seçeneklerle yeni bir koleksiyon oluşturmanıza gerek olmadan mevcut olduğunu bildirir.","cause":"createCollection ile zaten var olan bir koleksiyonu (belki farklı seçeneklerle) yeniden oluşturmaya çalışmak; şema/kurulum betiklerinin birden çok kez çalıştırılması; ya da kapasiteli (capped) koleksiyon veya özel seçeneklerle var olan bir adı yeniden tanımlama denemesi.","fix":"Genellikle güvenle yok sayılabilir; koleksiyon zaten mevcut demektir. Kurulum betiklerinizi idempotent yapın: oluşturmadan önce varlığı kontrol edin (db.getCollectionNames().includes('ad')). Seçenekleri değiştirmek istiyorsanız koleksiyonu düşürüp yeniden oluşturmanız gerekir (veriyi önce yedekleyin): db.koleksiyon.drop() sonra createCollection.","tags":["namespace","collection","koleksiyon","createcollection","mevcut","idempotent"]},{"code":"11601 Interrupted","title":"Operation was interrupted","severity":"caution","meaning":"Çalışmakta olan işlem yarıda kesildi. MongoDB, bir dış müdahale veya sunucu durumu değişikliği nedeniyle işlemi tamamlamadan sonlandırdı.","cause":"Bir yöneticinin/aracın db.killOp() ile işlemi öldürmesi; sunucunun kapanma sürecine girmesi; replica set'te primary değişimi (stepdown/failover). (maxTimeMS aşımı bu hatayı değil 50 MaxTimeMSExpired hatasını verir.) Uzun süren sorgular bu şekilde durdurulabilir.","fix":"İşlemin neden kesildiğini araştırın: currentOp/killOp geçmişi, failover olayları, sunucu bakımı. İşlem idempotent ise güvenle yeniden deneyin. Uzun sorguları optimize edip kısaltın; uygun index'ler ekleyin. Sürücüde geçici (transient) hata retry mantığı kullanın; replica set failover'larında otomatik yeniden bağlanma sağlayın.","tags":["interrupted","kesinti","killop","failover","stepdown","retry"]},{"code":"85 IndexOptionsConflict","title":"Index already exists with different options / different name","severity":"caution","meaning":"Oluşturmaya çalıştığınız index, mevcut bir index ile çakışıyor: aynı ada sahip index farklı seçenekler taşıyor ya da aynı anahtar ve seçeneklere sahip eşdeğer bir index başka bir adla zaten var. MongoDB, çakışan tanımla aynı index'i yeniden oluşturmanıza izin vermez.","cause":"Aynı ad ve anahtarla farklı seçeneklerle (ör. expireAfterSeconds, partialFilterExpression, collation) index oluşturmaya çalışmak; ya da var olan bir index'in eşdeğerini farklı bir adla yeniden tanımlamak ('Index already exists with a different name'). Uygulama/migration betiklerinde index tanımının zamanla değişmesi tipik nedendir. Aynı ad ama farklı anahtar ise 86 IndexKeySpecsConflict verir.","fix":"Var olan index'i görün: db.koleksiyon.getIndexes(). Seçenekleri gerçekten değiştirmek istiyorsanız eski index'i düşürüp yenisini oluşturun: db.koleksiyon.dropIndex('indeks_adi') sonra createIndex(...). Aksi halde tanımı mevcut index ile birebir eşleştirin ya da yeni index'e farklı bir ad verin. Migration betiklerini idempotent yapın.","tags":["index","indeks","options","cakisma","unique","createindex"]},{"code":"67 CannotCreateIndex","title":"Cannot create index","severity":"caution","meaning":"Index oluşturma işlemi bir kısıt veya sınır nedeniyle başarısız oldu. MongoDB, istenen index'i mevcut veriler ya da yapılandırma nedeniyle kuramadı.","cause":"Bir koleksiyonda izin verilen maksimum index sayısının (64) aşılması; anahtarın çok büyük olması; ya da uyumsuz seçenek kombinasyonları (ör. TTL index'i için uygun olmayan alan tipi). Not: Mevcut veride tekrarlı değer varken unique index oluşturmak bu kodu değil E11000 DuplicateKey hatasını verir.","fix":"Index sayısı sınırına ulaştıysanız kullanılmayan index'leri kaldırın ($indexStats ile kullanım analizi yapın). Anahtar boyutu/tip uyumunu ve seçenek kombinasyonunu kontrol edin. Büyük koleksiyonlarda index'i düşük yük anında oluşturun (4.2+ index oluşturma zaten yazmaları uzun süre engellemez; background seçeneği yok sayılır).","tags":["index","indeks","unique","duplicate","limit","ttl"]},{"code":"27 IndexNotFound","title":"Index not found","severity":"safe","meaning":"Başvurduğunuz index koleksiyonda bulunamadı. Genellikle var olmayan bir index'i düşürmeye ya da yeniden adlandırmaya çalışırken ortaya çıkar.","cause":"dropIndex/hideIndex gibi bir komutta yanlış index adı ya da yanlış anahtar tanımı vermek; index'in daha önce silinmiş olması; ya da otomatik oluşturulan index adının beklenenden farklı olması (MongoDB alan_1_alan2_-1 gibi adlar üretir).","fix":"Mevcut index'leri ve tam adlarını listeleyin: db.koleksiyon.getIndexes(). Doğru adı veya anahtar dokümanını kullanarak işlemi tekrarlayın: db.koleksiyon.dropIndex({alan: 1}) ya da db.koleksiyon.dropIndex('alan_1'). Silme betiklerini, index yoksa hata vermeyecek şekilde (varlık kontrolüyle) yazın.","tags":["index","indeks","dropindex","bulunamadi","getindexes","isim"]},{"code":"79 UnknownReplWriteConcern","title":"Unknown replica set write concern","severity":"caution","meaning":"Belirtilen yazma güvencesi (write concern) tanınmıyor. İşlemde kullanılan w değeri (özel/etiketli bir write concern adı veya sayısal değer), replica set yapılandırmasında tanımlı değil.","cause":"getLastErrorModes içinde tanımlanmamış özel bir write concern adının (ör. 'majority' yerine yazım hatası veya özel bir etiket adı) kullanılması. Yapılandırma ile istek uyuşmuyor. Not: Oy veren üye sayısının üstünde bir sayısal w değeri istemek ayrı bir hatadır (100 UnsatisfiableWriteConcern).","fix":"Kullandığınız write concern adının replica set ayarında tanımlı olduğundan emin olun. Mevcut yapılandırmayı görün: rs.conf() (settings.getLastErrorModes). Özel bir mod kullanacaksanız önce tanımlayın ya da standart değerlere geçin ('majority' veya geçerli bir sayısal w). Sürücü/uygulama bağlantı dizesindeki writeConcern ayarını gözden geçirin.","tags":["write concern","yazma guvencesi","replica set","majority","getlasterrormodes","config"]}]},"errors/redis-more2.json":{"engineId":"redis","engine":"Redis","order":6,"errors":[{"code":"ERR DEBUG command not allowed","title":"DEBUG command not allowed","severity":"caution","meaning":"DEBUG komutunu çalıştırmaya çalıştınız ancak sunucu bunu izin vermiyor. DEBUG, düşük seviyeli ve tehlikeli bir tanılama komutudur; güvenlik nedeniyle yeni Redis sürümlerinde varsayılan olarak kapalı ya da kısıtlıdır.","cause":"Redis 7+ sürümlerinde DEBUG alt komutları enable-debug-command yapılandırması olmadan çalışmaz; yönetilen bulut Redis servislerinde bu komut çoğunlukla tamamen devre dışıdır; ya da komut ACL ile yasaklanmıştır. Test/tanılama betikleri (ör. DEBUG SLEEP, DEBUG OBJECT) bu hataya sık düşer.","fix":"Üretimde DEBUG kullanmaktan kaçının. Yerel/test ortamında gerçekten gerekiyorsa yapılandırmada açın: redis.conf içinde enable-debug-command yes (ya da 'local'). Bulut serviste bu komut genellikle hiç açılamaz; eşdeğer bilgi için MEMORY USAGE, OBJECT ENCODING, INFO gibi güvenli komutları kullanın. ACL kısıtlaması varsa yetkiyi gözden geçirin.","tags":["debug","komut","yasak","guvenlik","acl","config"]},{"code":"ERR Can't save in background: fork failed","title":"Background save failed: fork failed","severity":"danger","meaning":"Redis, arka planda RDB snapshot'ı veya AOF yeniden yazımı için alt süreç oluştururken (fork) başarısız oldu. Kalıcılık işlemi yapılamadığından veri diske yazılamıyor.","cause":"İşletim sistemi fork için yeterli bellek ayıramıyor; genellikle overcommit_memory ayarı kapalı ve Redis'in kullandığı belleğin yaklaşık bir kopyasını ayırmaya çalışırken sistem reddediyor. Fiziksel/sanal bellek yetersizliği veya süreç sayısı limitleri de neden olabilir.","fix":"Linux'ta bellek overcommit'i açın: sysctl vm.overcommit_memory=1 (kalıcı için /etc/sysctl.conf'a ekleyin). Sunucuya bellek ekleyin veya Redis bellek kullanımını (maxmemory) düşürün. Yeterli takas (swap) alanı sağlayın. Süreç/dosya tanıtıcısı limitlerini (ulimit) kontrol edin. Kalıcılık kritikse bu ayarları yapmadan üretime almayın.","tags":["fork","rdb","aof","kalicilik","overcommit","bellek"]},{"code":"NOPROTO unsupported protocol version","title":"Unsupported RESP protocol version","severity":"caution","meaning":"İstemci, sunucunun desteklemediği bir RESP protokol sürümünü istedi. Genellikle HELLO komutuyla RESP3 (sürüm 3) istenirken sunucunun yalnızca RESP2 desteklemesi durumunda döner.","cause":"HELLO 3 komutu gönderilmesi ama sunucunun eski bir Redis sürümü (6.0 öncesi) olması ya da RESP3'ü desteklememesi; istemci kütüphanesinin varsayılan olarak RESP3 istemesi ama sunucunun eski olması. Sürüm uyumsuzluğudur.","fix":"İstemcinizi RESP2 kullanacak şekilde ayarlayın veya HELLO ile geçerli bir sürüm isteyin (HELLO 2). Sunucuyu RESP3 destekleyen bir sürüme (Redis 6+) yükseltin. Kullandığınız istemci kütüphanesinin protokol sürümü ayarını gözden geçirin; çoğu kütüphane otomatik olarak RESP2'ye düşebilir. Sunucu sürümünü doğrulayın: INFO server (redis_version).","tags":["resp","protokol","hello","resp3","surum","uyumluluk"]},{"code":"ERR Unknown option or number of arguments for CONFIG SET","title":"Unknown option or number of arguments for CONFIG SET (eski sürümlerde: Unsupported CONFIG parameter)","severity":"caution","meaning":"CONFIG SET ile değiştirmeye çalıştığınız yapılandırma parametresi bu Redis sürümünde tanınmıyor ya da argüman sayısı hatalı. Redis 7'de tam mesaj \"ERR Unknown option or number of arguments for CONFIG SET - '<ad>'\" biçimindedir; eski sürümler \"ERR Unsupported CONFIG parameter\" döndürür. CONFIG GET bilinmeyen bir parametre için hata vermez, boş liste döner.","cause":"Parametre adının yanlış yazılması; farklı bir Redis sürümüne ait bir parametreyi kullanmak (parametreler sürümler arasında eklenip kaldırılabilir); ya da yönetilen bulut servisinde belirli parametrelerin değiştirilmesine izin verilmemesi. Eski betiklerin yeni/eski sürümlerde çalıştırılması tipik nedendir.","fix":"Geçerli parametre adını doğrulayın. Mevcut ayarları desenle listeleyin: CONFIG GET 'maxmemory*' gibi. Redis sürümünüzün dokümantasyonundaki parametre listesini kontrol edin; INFO server ile sürümü görün. Bulut serviste kısıtlıysa sağlayıcının izin verdiği parametre kümesini kullanın. Betiklerinizi hedef sürüme göre güncelleyin.","tags":["config","parametre","unsupported","surum","config set","config get"]},{"code":"ERR MULTI calls can not be nested","title":"MULTI calls can not be nested","severity":"caution","meaning":"Zaten açık bir MULTI (transaction) bloğu varken tekrar MULTI komutu gönderildi. Redis, iç içe (nested) transaction bloklarını desteklemez; bir seferde yalnızca bir MULTI aktif olabilir.","cause":"Uygulama mantığında EXEC/DISCARD ile kapatılmadan yeni bir MULTI başlatılması; bağlantı havuzunda transaction durumu düzgün sıfırlanmadan aynı bağlantının yeniden kullanılması; ya da kütüphane sarmalayıcısının farkında olmadan iki kez MULTI çağırması.","fix":"Her MULTI bloğunu tek bir EXEC (veya iptal için DISCARD) ile kapatın ve yeni bloğu ancak öncekini bitirdikten sonra açın. Kod akışında transaction başlangıç/bitişini net ayırın. Bağlantı havuzunda bir bağlantıyı iade etmeden önce açık transaction kalmadığından emin olun. İç içe mantık gerekiyorsa Lua script (EVAL) ile atomik işlem yapmayı değerlendirin.","tags":["multi","transaction","nested","ic ice","exec","discard"]},{"code":"ERR Lua script attempted to access nonexistent global variable","title":"Lua script attempted to access a nonexistent global variable","severity":"caution","meaning":"EVAL/EVALSHA ile çalıştırılan Lua betiği, tanımlı olmayan bir global değişkene erişmeye çalıştı. Redis, betik ortamını korumak için genel değişken oluşturmayı/okumayı kısıtlar ve bu erişimi hata olarak döndürür.","cause":"Betikte yerel (local) yerine yanlışlıkla global değişken kullanmak (local anahtar kelimesini unutmak); yazım hatası nedeniyle tanımsız bir isme erişmek; ya da global bir değişken üzerinden durum saklamaya çalışmak. Redis'in korumalı Lua ortamı bunlara izin vermez.","fix":"Betikteki tüm değişkenleri local ile tanımlayın: local x = ... Yazım hatalarını düzeltin; kullanmadan önce her değişkenin tanımlandığından emin olun. Betikler durumsuz (stateless) olmalı; kalıcı durum için Redis anahtarlarını (KEYS/redis.call) kullanın, global Lua değişkenleri değil. Betiği kısa ve deterministik tutun.","tags":["lua","eval","script","global","degisken","local"]},{"code":"ERR unknown command","title":"Unknown command","severity":"caution","meaning":"Gönderdiğiniz komutu Redis tanımıyor. Komut adı hatalı, bu sürümde mevcut değil ya da devre dışı bırakılmış/yeniden adlandırılmış olabilir.","cause":"Komut adının yanlış yazılması; komutun daha yeni bir Redis sürümünde eklenmiş olması (eski sunucuda yok); bir modül (ör. RedisJSON, RediSearch) gerektiren komutun modül yüklü olmadan çağrılması; ya da rename-command/ACL ile komutun kapatılması. Bazen istemcinin yanlış argüman ayrımı da komut adının bozuk görünmesine yol açar.","fix":"Komut adını ve söz dizimini doğrulayın (COMMAND DOCS komut veya belgeler). Sunucu sürümünü kontrol edin: INFO server. Modül komutuysa modülün yüklü olduğunu doğrulayın: MODULE LIST. Komut rename-command ile gizlenmişse yapılandırmayı gözden geçirin. İstemci kütüphanenizin komutu doğru şekilde kodladığından emin olun.","tags":["komut","unknown","bilinmeyen","surum","modul","acl"]},{"code":"TRYAGAIN Multiple keys request during rehashing of slot","title":"Multiple keys request during rehashing of slot (cluster)","severity":"caution","meaning":"Redis Cluster'da, bir hash slot'u düğümler arasında taşınırken (rehashing/resharding) aynı slot'a ait birden çok anahtarı içeren bir istek yapıldı ve anahtarların bir kısmı henüz taşınmış, bir kısmı taşınmamış durumda. Sunucu, işlemi biraz sonra tekrar denemenizi ister.","cause":"Slot geçişi (migration) sürerken çok anahtarlı bir komut (MGET, MSET, çoklu anahtarlı Lua, transaction) çalıştırmak. Taşınan slot'ta bazı anahtarlar kaynak düğümde, bazıları hedef düğümde olduğundan komut atomik olarak yürütülemez.","fix":"İstemcide bu hatayı yakalayıp kısa bir bekleme ile yeniden deneyin (TRYAGAIN geçici bir durumdur; resharding bitince düzelir). Çok anahtarlı işlemlerde tüm anahtarların aynı slot'ta olmasını hash tag ile garantileyin: {kullanici123}.profil, {kullanici123}.ayarlar gibi. Cluster resharding işlemlerini düşük trafik anında yapın.","tags":["cluster","slot","rehash","resharding","tryagain","hash tag"]},{"code":"ERR DISCARD without MULTI","title":"DISCARD without MULTI","severity":"caution","meaning":"Açık bir MULTI bloğu yokken DISCARD komutu gönderildi. DISCARD yalnızca devam eden bir transaction'ı iptal etmek için kullanılır; ortada iptal edilecek bir transaction olmadığında bu hatayı verir.","cause":"MULTI çağrılmadan ya da transaction zaten EXEC/DISCARD ile kapatıldıktan sonra tekrar DISCARD çağırmak; hata işleme (error handling) kodunda koşulsuz DISCARD çağrısı; ya da bağlantı durumunun beklenenden farklı olması (havuzdan gelen bağlantıda MULTI açık değil).","fix":"DISCARD'ı yalnızca gerçekten açık bir MULTI varken çağırın; transaction durumunu koddan takip edin. Hata işleyicilerinde DISCARD çağırmadan önce bir transaction açık mı diye kontrol edin. Kütüphanenizin transaction sarmalayıcısını kullanarak durumu otomatik yönetmesini sağlayın. Bağlantı havuzunda temiz durum garantisi verin.","tags":["discard","multi","transaction","iptal","durum","hata isleme"]}]},"errors/elasticsearch-more2.json":{"engineId":"elasticsearch","engine":"Elasticsearch","order":7,"errors":[{"code":"search_context_missing_exception","title":"No search context found for id (scroll expired)","severity":"caution","meaning":"Bir scroll (kaydırma) sorgusu için kullanılan arama bağlamı (search context) artık sunucuda yok. Genellikle scroll bağlamının zaman aşımına uğraması veya temizlenmesi nedeniyle, saklanan scroll_id ile devam etmeye çalışırken ortaya çıkar.","cause":"Scroll için belirtilen keep-alive süresinin dolması (isteklerin arasında çok uzun beklemek); bağlamın manuel olarak temizlenmesi (clear scroll); ya da bir düğüm yeniden başladığında bağlamın kaybolması. Scroll bağlamları düğüm belleğinde tutulduğu için sınırlı ömürlüdür.","fix":"Her scroll isteğinde yeterli keep-alive verin (ör. scroll=5m) ve sayfalar arasında gecikmeyi kısaltın. Modern Elasticsearch'te derin sayfalama için scroll yerine search_after + Point in Time (PIT) kullanmanız önerilir; bu daha ölçeklenebilir ve tavsiye edilen yöntemdir. İşiniz bitince bağlamları serbest bırakın (clear scroll) ki bellek boşa dolmasın.","tags":["scroll","search_after","pit","context","zaman asimi","sayfalama"]},{"code":"aliases_not_found_exception","title":"Aliases missing","severity":"safe","meaning":"İşlem yapmaya çalıştığınız takma ad (alias) mevcut değil. Genellikle var olmayan bir alias'ı kaldırmaya ya da ona göre işlem yapmaya çalışırken döner.","cause":"Alias adının yanlış yazılması; alias'ın daha önce silinmiş olması; ya da _aliases API'sinde bir remove eylemi için henüz bağlanmamış bir alias adı vermek. Kalıp (wildcard) ile eşleşen alias bulunamadığında da görülür.","fix":"Mevcut alias'ları listeleyin: GET _alias veya belirli bir index için GET indeks/_alias. Doğru adı kullanarak işlemi tekrarlayın. Silme betiklerinizi, alias yoksa hata vermeyecek şekilde yazın; _aliases toplu işleminde eylemleri koşullu ele alın. Alias'ları atomik olarak yeniden yönlendirmek için _aliases API'sinde add ve remove'u tek istekte kullanın.","tags":["alias","takma ad","bulunamadi","aliases","indeks","yonlendirme"]},{"code":"snapshot_missing_exception","title":"Snapshot is missing","severity":"caution","meaning":"Başvurduğunuz snapshot belirtilen depoda (repository) bulunamadı. Geri yükleme, silme ya da durum sorgulama sırasında var olmayan bir snapshot adı kullanıldığını gösterir.","cause":"Snapshot adının yanlış yazılması; snapshot'ın daha önce silinmiş olması; yanlış depoya (repository) bakılması; ya da yedekleme sürecinin hiç tamamlanmamış olması. Depo tanımı değişmiş veya erişilemez olduğunda da benzer sonuç doğar.","fix":"İlgili depodaki snapshot'ları listeleyin: GET _snapshot/depo_adi/_all (ya da belirli bir ad için GET _snapshot/depo_adi/snapshot_adi). Doğru depo ve snapshot adıyla işlemi tekrarlayın. Depo tanımını kontrol edin: GET _snapshot/depo_adi. Yedekleme politikanızın (SLM) başarıyla çalıştığını ve snapshot ürettiğini doğrulayın.","tags":["snapshot","yedek","repository","depo","restore","bulunamadi"]},{"code":"index_template_missing_exception","title":"Index template is missing","severity":"safe","meaning":"Başvurduğunuz index şablonu (index template) bulunamadı. Şablonu almaya, silmeye ya da ona dayalı bir işlem yapmaya çalışırken var olmayan bir şablon adı kullanıldı.","cause":"Şablon adının yanlış yazılması; şablonun daha önce silinmiş olması; legacy (eski) template API'si ile composable (yeni) index template API'sini karıştırmak; ya da şablonun hiç oluşturulmamış olması. Kurulum betiği tamamlanmadığında da görülür.","fix":"Mevcut şablonları listeleyin. Yeni (composable) şablonlar için: GET _index_template ya da GET _index_template/ad. Eski şablonlar için: GET _template. Doğru API ve adla işlemi tekrarlayın. Şablon yoksa oluşturun: PUT _index_template/ad {...}. Silme/güncelleme betiklerinizi, şablon yoksa hata vermeyecek biçimde idempotent yapın.","tags":["index template","sablon","composable","legacy","bulunamadi","mapping"]},{"code":"settings_exception","title":"Invalid settings","severity":"caution","meaning":"Verilen ayar (setting) geçersiz olduğu için işlem reddedildi. Index veya küme ayarlarını uygularken ayarın adı, değeri ya da o bağlamda değiştirilebilirliği ile ilgili bir sorun var.","cause":"Bilinmeyen/yanlış yazılmış bir ayar adı; ayar değerinin geçersiz tipte ya da izin verilen aralık dışında olması; yalnızca index oluşturulurken atanabilen statik bir ayarı çalışan index'te değiştirmeye çalışmak (ör. number_of_shards); veya kaldırılmış/yeniden adlandırılmış bir ayarı kullanmak.","fix":"Ayar adını ve değerini dokümantasyona göre doğrulayın. Dinamik olarak değiştirilebilen ayarları çalışan index'te güncelleyin: PUT indeks/_settings {\"index.number_of_replicas\": 2}. Statik ayarlar (ör. number_of_shards) yalnızca oluşturma sırasında verilir; değiştirmek için yeniden indeksleme (reindex) gerekir. Mevcut ayarları görün: GET indeks/_settings.","tags":["settings","ayar","gecersiz","static","dynamic","reindex"]},{"code":"shard_not_found_exception","title":"Shard not found","severity":"danger","meaning":"İşlem yapılmak istenen shard (parça) bulunamadı. Elasticsearch, belirtilen index'in ilgili shard'ına ulaşamadığı için isteği tamamlayamadı.","cause":"Shard'ın henüz atanmamış (unassigned) veya kurtarma (recovery) aşamasında olması; bir düğümün küme dışına çıkması nedeniyle shard'ın geçici olarak kaybolması; ya da doğrudan bir shard'a yönlendirilen düşük seviyeli bir isteğin artık geçerli olmayan yönlendirme (routing) bilgisi taşıması. Küme sağlığının bozulduğu durumlarda görülür.","fix":"Küme ve shard sağlığını kontrol edin: GET _cluster/health ve GET _cat/shards?v. Atanmamış shard'ların nedenini görün: GET _cluster/allocation/explain. Düğüm kaybı varsa düğümü geri getirin; disk/allocation ayarlarını (watermark) gözden geçirin. Kurtarma sürüyorsa tamamlanmasını bekleyin. Replika sayısını uygun tutarak tek düğüm kaybında veri erişilebilirliğini koruyun.","tags":["shard","parca","unassigned","atanmamis","recovery","cluster health"]},{"code":"not_x_content_exception","title":"Compressor detection error / body is not valid content","severity":"caution","meaning":"Elasticsearch, istek gövdesini geçerli bir yapılandırılmış içerik (JSON gibi XContent) olarak tanıyamadı. Gönderilen veri beklenen biçimde değil veya bozuk.","cause":"İstek gövdesinin geçersiz JSON olması; yanlış ya da eksik Content-Type başlığı (application/json gönderilmemesi); gövdenin yanlışlıkla sıkıştırılmış/ikili gönderilmesi; ya da _bulk gibi satır-ayrımlı (NDJSON) beklenen uçlara düz JSON göndermek. Kaçış/kodlama hataları da tetikler.","fix":"İstek gövdesinin geçerli JSON olduğunu doğrulayın ve Content-Type: application/json başlığını gönderin. _bulk ucunda her satırın ayrı JSON ve son satırın yeni satırla bittiği NDJSON biçimini kullanın (Content-Type: application/x-ndjson). İstemci kütüphanenizin gövdeyi doğru serileştirdiğinden emin olun. Sıkıştırma kullanıyorsanız uygun Content-Encoding başlığını verin.","tags":["json","xcontent","content-type","bulk","ndjson","govde"]},{"code":"document_source_missing_exception","title":"Document source is missing","severity":"caution","meaning":"İşlem, belgenin _source alanına ihtiyaç duyuyor ancak bu alan saklanmıyor. Kaynak (source) devre dışı bırakılmış bir index'te, _source gerektiren bir işlem (ör. kısmi update, source getirme) yapılmaya çalışıldı.","cause":"Index mapping'inde _source: {enabled: false} ayarlanmış olması; bu durumda belgenin orijinal JSON'u saklanmadığından kısmi güncelleme (partial update), reindex ya da _source dönen sorgular çalışamaz. Yer kazanmak için source'u kapatan yapılandırmalar bu soruna yol açar.","fix":"_source'u gerektiren işlemler için mapping'de kaynağın etkin olması gerekir. Yeni bir index oluştururken _source'u açık bırakın (varsayılan etkindir). Var olan index'te _source kapalıysa, güncelleme yerine belgenin tamamını yeniden indeksleyin (index API ile üzerine yazın). Yer tasarrufu için source'u tamamen kapatmak yerine _source içerik filtreleme (includes/excludes) veya synthetic _source gibi seçenekleri değerlendirin.","tags":["_source","source","update","mapping","reindex","kaynak"]}]},"errors/oracle-more3.json":{"engineId":"oracle","engine":"Oracle","order":1,"errors":[{"code":"ORA-00845","title":"MEMORY_TARGET not supported on this system","severity":"danger","meaning":"Örnek (instance) başlatılamıyor çünkü MEMORY_TARGET / MEMORY_MAX_TARGET ile istenen otomatik bellek yönetimi, işletim sisteminin paylaşımlı bellek (shared memory) yapılandırmasıyla desteklenmiyor. Linux'ta bu genellikle /dev/shm alanının, istenen bellek hedefinden küçük olmasından kaynaklanır.","cause":"MEMORY_TARGET, tmpfs olarak bağlanan /dev/shm boyutundan büyük ayarlanmış; ya da HugePages etkinken MEMORY_TARGET (AMM) kullanılmaya çalışılıyor; AMM HugePages ile uyumlu değildir, ASMM (SGA_TARGET) ise uyumludur. Oracle Automatic Memory Management, /dev/shm üzerinde dosya oluşturarak çalışır ve bu alan yetersizse örnek açılmaz.","fix":"/dev/shm boyutunu MEMORY_TARGET'ten büyük yapın: tmpfs'i yeniden bağlayın (mount -o remount,size=8G /dev/shm) ve /etc/fstab içinde kalıcılaştırın. Alternatif olarak AMM yerine ayrık ayarları kullanın: MEMORY_TARGET ve MEMORY_MAX_TARGET'i 0 yapıp SGA_TARGET ve PGA_AGGREGATE_TARGET tanımlayın. HugePages kullanıyorsanız AMM'yi devre dışı bırakıp ASMM (SGA_TARGET) tercih edin.","tags":["memory_target","bellek","amm","dev/shm","hugepages","startup"]},{"code":"ORA-27102","title":"out of memory","severity":"danger","meaning":"Oracle örneği başlarken işletim sisteminden istediği paylaşımlı bellek (SGA) segmentini ayıramadı. Genellikle ORA-27102 ile birlikte alt seviyede bir OSD/Linux hata koduyla (ör. Linux-x86_64 Error: 28: No space left on device) görülür.","cause":"SGA için istenen bellek, çekirdeğin izin verdiği paylaşımlı bellek limitlerini (shmmax, shmall) aşıyor; sunucuda yeterli fiziksel RAM/swap yok; ya da HugePages yapılandırması eksik/yetersiz olduğu için büyük SGA ayrılamıyor. SGA_MAX_SIZE artırıldıktan sonra sık görülür.","fix":"Çekirdek paylaşımlı bellek parametrelerini artırın: /etc/sysctl.conf içinde kernel.shmmax ve kernel.shmall değerlerini SGA'yı kapsayacak şekilde ayarlayıp sysctl -p çalıştırın. HugePages kullanıyorsanız vm.nr_hugepages değerini SGA'ya göre hesaplayıp ayarlayın. Sunucudaki toplam RAM ve swap'i kontrol edin; gerekiyorsa SGA_MAX_SIZE / SGA_TARGET değerlerini düşürün.","tags":["sga","bellek","shmmax","hugepages","startup","osd"]},{"code":"ORA-04030","title":"out of process memory when trying to allocate N bytes","severity":"danger","meaning":"Bir sunucu süreci (server process), PGA'sında (Program Global Area) yani süreç özel belleğinde yer ayıramadı. SGA'daki paylaşımlı bellekten farklı olarak bu, tek bir oturumun/sürecin kendi belleğinin tükenmesidir.","cause":"Çok büyük sıralama/hash işlemleri, aşırı büyük PL/SQL koleksiyonları, denetimsiz döngülerde biriken değişkenler ya da işletim sistemi süreç bellek limitleri (ulimit -v/-d, vm.max_map_count, adres alanı) süreç belleğini tüketmiştir. 32-bit örneklerde adres alanı sınırı da tetikleyebilir.","fix":"Hataya eşlik eden ikinci satırdaki ayırma kategorisini (ör. 'pga heap', 'koh-kghu sessi') inceleyerek belleği kimin tükettiğini bulun. PGA_AGGREGATE_LIMIT / PGA_AGGREGATE_TARGET ayarlarını gözden geçirin. İşletim sistemi limitlerini kontrol edin (ulimit -a; oracle kullanıcısı için memlock, as, stack). Sorguyu/PL/SQL'i optimize edip toplu (bulk) işleme aralıklarını küçültün. Gerekirse trace dosyasıyla Oracle Support'a başvurun.","tags":["pga","process memory","bellek","ulimit","sirala","plsql"]},{"code":"ORA-12537","title":"TNS:connection closed","severity":"danger","meaning":"İstemci ile sunucu arasındaki TNS bağlantısı, elde tutulan iletişim kanalı beklenmedik biçimde kapandığı için sonlandı. Bağlantı kurulurken ya da kurulduktan hemen sonra oturum düşer.","cause":"Listener istemciyi bir sunucu sürecine yönlendirdi ancak süreç oluşturulamadı ya da hemen sonlandı: örnek çökmesi, PROCESSES limiti dolması, işletim sistemi kaynak yetersizliği, güvenlik duvarı/ara katman bağlantıyı kesmesi ya da sqlnet.ora'daki TCP.VALIDNODE_CHECKING/TCP.INVITED_NODES kuralının istemciyi reddetmesi. Bazen istemci ile sunucu arasındaki idle firewall bağlantıyı düşürür.","fix":"listener.log ve sqlnet.log dosyalarını inceleyin. PROCESSES/SESSIONS limitlerini kontrol edin: SELECT * FROM v$resource_limit WHERE resource_name IN ('processes','sessions'); Sunucu tarafı sqlnet.ora içindeki TCP.INVITED_NODES/TCP.EXCLUDED_NODES listelerinin istemci IP'sini reddetmediğini doğrulayın (logon sürümü uyumsuzluğu bu hatayı değil ORA-28040'ı verir). Güvenlik duvarında idle timeout'u yükseltin veya SQLNET.EXPIRE_TIME ile keepalive gönderin. Örnek çökme kayıtlarını (alert.log) doğrulayın.","tags":["tns","baglanti","listener","processes","firewall","sqlnet"]},{"code":"ORA-03135","title":"connection lost contact","severity":"danger","meaning":"Daha önce kurulmuş ve çalışan bir oturum, sunucuyla iletişimi kaybetti. Uzun süren bir sorgu ya da boşta bekleyen bir bağlantı, karşılıklı haber alınamadığı için koptu.","cause":"Sunucu süreci beklenmedik şekilde sonlandı (ORA-00600/07445, kill, kaynak limiti); RESOURCE_LIMIT profili oturumu kesti; boştaki bağlantı bir güvenlik duvarı/yük dengeleyici tarafından düşürüldü; ya da ağda kesinti/paket kaybı yaşandı. Genellikle uzun sürede yanıt vermeyen sorgularda ya da idle bağlantılarda ortaya çıkar.","fix":"alert.log ve ilgili trace dosyalarında sürecin neden öldüğünü arayın (ORA-00600/ORA-07445 var mı). Ağ tarafında güvenlik duvarı idle timeout'unu artırın ve sqlnet.ora'da SQLNET.EXPIRE_TIME ile dead connection detection açın. Kullanıcı profilindeki CONNECT_TIME/IDLE_TIME limitlerini kontrol edin. Sunucu kaynak baskısını (bellek, CPU, PROCESSES) inceleyin.","tags":["baglanti","sqlnet","idle","firewall","dead connection","network"]},{"code":"ORA-01033","title":"ORACLE initialization or shutdown in progress","severity":"danger","meaning":"Bağlanmaya çalıştığınız veritabanı örneği şu anda açılışın (mount/open) ortasında ya da kapanma sürecinde. Bu ara durumda normal kullanıcı bağlantıları kabul edilmez.","cause":"Örnek NOMOUNT/MOUNT aşamasında takılı kalmış (ör. medya kurtarma bekliyor), SHUTDOWN devam ediyor, ya da veritabanı OPEN olamadan bir hata nedeniyle askıda. Yeni başlatılan bir örneğe açılış tamamlanmadan bağlanmaya çalışmak da bu hatayı verir.","fix":"SYSDBA olarak bağlanıp durumu görün: sqlplus / as sysdba; ardından SELECT status FROM v$instance; ve SELECT open_mode FROM v$database; Örneği açmayı deneyin: ALTER DATABASE OPEN; Kurtarma bekleniyorsa RECOVER DATABASE; sonra açın. alert.log'da açılışı engelleyen asıl hatayı bulun (eksik/bozuk datafile, redo). Kapanma askıda kaldıysa SHUTDOWN ABORT sonrası STARTUP deneyin.","tags":["startup","shutdown","mount","open","recovery","instance"]},{"code":"ORA-00600","title":"internal error code, arguments: [...]","severity":"danger","meaning":"Oracle çekirdeğinde bir iç tutarlılık kontrolü (internal consistency check) başarısız oldu. Bu, çekirdek kodunun beklemediği bir durumla karşılaştığını gösteren genel bir iç hata olup köşeli parantezlerdeki argümanlar hangi kod yolunun tetiklendiğini belirtir.","cause":"Blok/veri bozulması, çözülmemiş bir Oracle yazılım hatası (bug), uyumsuz yama seviyeleri, bellek/donanım sorunları ya da beklenmeyen kenar durumları tetikleyebilir. İlk argüman (ör. [ktbdchk1]) sorunun hangi katmanla ilgili olduğunu gösterir ve destek analizinde anahtardır.","fix":"Bu hata neredeyse her zaman Oracle Support ile ele alınmalıdır. Üretilen trace dosyasını ve alert.log kaydını saklayın; ilk argümanı My Oracle Support'ta ORA-600 Troubleshooter ve 'ORA-600 Lookup Tool' ile aratın. Uygun yama/PSU/RU'yu uygulayın. Bozulma şüphesi varsa DBVERIFY/RMAN VALIDATE ile blok bütünlüğünü doğrulayın. Kritik ortamda SR açmadan üretimde deneme yapmayın.","tags":["internal","ora-600","cekirdek","bug","trace","support"]},{"code":"ORA-07445","title":"exception encountered: core dump","severity":"danger","meaning":"Bir Oracle sunucu süreci, işletim sistemi düzeyinde bir istisna (ör. SIGSEGV segmentasyon hatası, erişim ihlali) alarak beklenmedik şekilde çöktü ve bir çekirdek dökümü (core dump) üretti. ORA-00600'den farkı, hatanın işletim sisteminden gelen bir sinyalle tetiklenmesidir.","cause":"Genellikle bir Oracle yazılım hatası (bug), bellek bozulması, bozuk veri/index blokları, uyumsuz kütüphaneler veya donanım/bellek arızası. Mesajdaki fonksiyon adı ve sinyal türü (ör. SIGSEGV) çöken kod yolunu gösterir.","fix":"Üretilen trace ve incident dosyalarını, alert.log'u koruyun ve fonksiyon adı + sinyal ile birlikte My Oracle Support'ta arayın; genellikle bir yama gerekir. Donanım/bellek testleri yapın, işletim sistemi ve Oracle yama seviyelerini eşitleyin. Bozulma şüphesinde RMAN VALIDATE / DBVERIFY çalıştırın. Tekrarlıyorsa SR açıp core dump'ı destek ekibine iletin.","tags":["ora-7445","core dump","sigsegv","cekirdek","bug","trace"]},{"code":"ORA-01102","title":"cannot mount database in EXCLUSIVE mode","severity":"danger","meaning":"Veritabanı EXCLUSIVE modda mount edilemiyor çünkü başka bir örnek (ya da eski bir örneğin artık dosyaları) veritabanını hâlâ kilitli tutuyor gibi görünüyor. Örnek MOUNT aşamasında durur.","cause":"Önceki örnek düzgün kapanmadı ve kilit dosyaları ($ORACLE_HOME/dbs altındaki lk<SID> ya da paylaşımlı bellek/semafor kalıntıları) kaldı; aynı veritabanına başka bir örnek zaten bağlı; ya da RAC dışı bir kurulumda ikinci bir örnek başlatılmaya çalışıldı. Önceki örnekten kalan süreç/paylaşımlı bellek kalıntıları ya da lk<SID> dosyası artığı en sık nedendir.","fix":"Gerçekten çalışan başka bir örnek olmadığını doğrulayın: ps -ef | grep pmon ve ipcs -m (paylaşımlı bellek segmentleri). Kalıntı varsa örneği ABORT edip temizleyin, gerekiyorsa ipcrm ile artık segment/semaforları kaldırın. $ORACLE_HOME/dbs altındaki lk<SID> kilit dosyasını (örnek kesinlikle kapalıysa) silin. Ardından STARTUP MOUNT deneyin. RAC ise CLUSTER_DATABASE ve düğüm durumlarını kontrol edin.","tags":["mount","exclusive","lock","startup","pmon","instance"]},{"code":"ORA-29913","title":"error in executing ODCIEXTTABLEOPEN callout","severity":"caution","meaning":"Bir dış tabloya (external table) erişilirken, kaynak dosyanın okunması/ayrıştırılması sırasında hata oluştu. Oracle, dış tablo verilerini almak için çağırdığı erişim sürücüsü (ORACLE_LOADER / ORACLE_DATAPUMP) rutininde başarısız oldu.","cause":"Genellikle DIRECTORY nesnesinin gösterdiği yolda dosyanın bulunmaması, Oracle işletim sistemi kullanıcısının dosya/dizin üzerinde okuma iznine sahip olmaması, log/bad dosyaları için yazma izni olmaması ya da erişim parametrelerindeki (alan ayracı, kayıt biçimi) hatalar. Sıklıkla ORA-29400 ve KUP-04xxx gibi alt hatalarla birlikte gelir.","fix":"Alt hataları (KUP-xxxx) okuyup asıl nedeni belirleyin. DIRECTORY yolunu ve dosyanın varlığını doğrulayın: SELECT directory_name, directory_path FROM all_directories; Dosya ve dizin üzerinde Oracle OS kullanıcısına okuma, log/bad dizinine yazma izni verin. Dış tablo tanımındaki ACCESS PARAMETERS bölümünü kaynak dosya biçimiyle eşleştirin. Gerekirse DIRECTORY üzerinde READ/WRITE grant kontrolü yapın.","tags":["external table","dis tablo","directory","oracle_loader","izin","kup"]}]},"errors/postgres-more3.json":{"engineId":"postgres","engine":"PostgreSQL","order":2,"errors":[{"code":"08001","title":"sqlclient_unable_to_establish_sqlconnection","severity":"danger","meaning":"İstemci, PostgreSQL sunucusuyla bir bağlantı kuramadı. Bağlantı henüz oturuma dönüşmeden, ağ/adres seviyesinde başarısız oldu.","cause":"Yanlış host/port; sunucunun dinlemediği bir adres (listen_addresses = 'localhost' iken uzaktan bağlanma); sunucunun kapalı/erişilemez olması; güvenlik duvarının portu (varsayılan 5432) engellemesi; ya da DNS çözümleme hatası. Bağlantı havuzunda (pool) yanlış yapılandırma da tetikleyebilir.","fix":"Sunucunun ayakta ve doğru adreste dinlediğini doğrulayın: postgresql.conf içindeki listen_addresses = '*' (veya ilgili IP) ve port ayarını kontrol edin, ardından sunucuyu yeniden başlatın (listen_addresses ve port restart gerektirir; reload yetmez). İstemciden erişimi test edin: psql -h host -p 5432 -U kullanici. Güvenlik duvarında 5432/tcp'yi açın. Host/port/DNS değerlerini ve bağlantı dizesini gözden geçirin.","tags":["baglanti","connection","network","listen_addresses","port","firewall"]},{"code":"08004","title":"sqlserver_rejected_establishment_of_sqlconnection","severity":"danger","meaning":"Sunucuya ulaşıldı ancak sunucu bağlantı kurulmasını reddetti. Ağ erişimi vardır fakat sunucu bu bağlantıyı politika gereği kabul etmemiştir.","cause":"PostgreSQL sunucusu bu kodu nadiren üretir; çoğunlukla istemci sürücüsü veya bağlantı havuzu tarafından raporlanır. Benzer reddetmelerin sunucudaki asıl kodları farklıdır: pg_hba.conf reddi ('no pg_hba.conf entry for host', reject yöntemi) 28000 (invalid_authorization_specification), max_connections dolması 53300 (too_many_connections), başlatma/kapatma sırasında bağlantı reddi 57P03 olarak döner.","fix":"Sunucu loglarında reddin gerçek SQLSTATE'ini ve gerekçesini okuyun. pg_hba reddi (28000) ise istemci IP'si, kullanıcı ve veritabanı için uygun bir satır (ör. host all all 10.0.0.0/24 scram-sha-256) ekleyin ve SELECT pg_reload_conf(); ile yeniden yükleyin. Bağlantı doygunluğu (53300) için SELECT count(*) FROM pg_stat_activity WHERE backend_type = 'client backend'; ile istemci bağlantılarını max_connections değeriyle karşılaştırın.","tags":["baglanti","pg_hba","reddedildi","authentication","max_connections","reject"]},{"code":"57P01","title":"admin_shutdown","severity":"danger","meaning":"Aktif bağlantınız, bir yönetici komutu nedeniyle sonlandırıldı. Sunucu kapatılırken ya da oturumunuz elle sonlandırıldığında istemci bu hatayı alır ('terminating connection due to administrator command').","cause":"Bir DBA pg_terminate_backend() ile oturumu kesti; sunucu fast/immediate shutdown ile kapatılıyor (smart shutdown oturumları kesmez, bitmelerini bekler); ya da yapılandırma değişikliği/planlı bakım için mevcut bağlantılar düşürüldü. Bazı failover senaryolarında da eski primary bağlantıları böyle keser.","fix":"Genellikle kalıcı bir hata değildir; uygulamanın bağlantıyı yeniden kurması (retry) gerekir. Beklenmedikse sunucu loglarında kapatma/terminate nedenini inceleyin. Planlı bakım için uygulamada otomatik yeniden bağlanma ve bağlantı havuzu sağlığı (health check) uygulayın. Sonlandırmayı kimin yaptığını sunucu logu doğrudan göstermez; pg_terminate_backend çağrısını izlemek için log_statement (veya pgaudit) ile denetim kaydı tutun.","tags":["shutdown","terminate","baglanti","bakim","failover","retry"]},{"code":"53400","title":"configuration_limit_exceeded","severity":"danger","meaning":"Bir yapılandırma limiti aşıldığı için işlem başarısız oldu. Sunucu, tanımlı bir sınır (ör. temp_file_limit, replication slot veya WAL sender sayısı) nedeniyle isteği reddetti.","cause":"Tipik örnekler: bir sorgunun geçici dosya kullanımının temp_file_limit değerini aşması ('temporary file size exceeds temp_file_limit'); tüm replication slot'larının dolu olması ('all replication slots are in use', max_replication_slots); max_wal_senders sınırının aşılması. Not: max_prepared_transactions dolması 53200, prepared transaction'ların kapalı olması (değer 0) ise 55000 koduyla döner.","fix":"Hata mesajı hangi limitin aşıldığını söyler. temp_file_limit aşımında sorguyu optimize edin (EXPLAIN ANALYZE ile diske taşan sort/hash adımlarını bulun), gerekirse work_mem'i oturum düzeyinde artırın ya da limiti bilinçli olarak yükseltin. Slot doluysa kullanılmayan slot'ları sahiplerini doğrulayarak temizleyin: SELECT slot_name, slot_type, active FROM pg_replication_slots; ya da max_replication_slots / max_wal_senders değerini artırıp sunucuyu yeniden başlatın.","tags":["limit","temp_file_limit","replication slot","max_wal_senders","yapilandirma","kaynak"]},{"code":"XX001","title":"data_corrupted","severity":"danger","meaning":"PostgreSQL, bir tablo/heap sayfasında veri bozulması tespit etti. Okunan bloğun içeriği tutarsız olduğu için sorgu güvenli biçimde tamamlanamaz ('invalid page in block').","cause":"Disk/depolama arızası, dosya sistemi bozulması, ani güç kaybı sırasında fsync güvencesinin sağlanamaması, hatalı donanım (RAM/denetleyici) ya da nadiren bir yazılım hatası. checksum'lar açıksa bozulma daha erken yakalanır.","fix":"Önce donanım/depolamayı doğrulayın ve mümkünse hemen fiziksel yedekten (PITR) geri dönmeyi planlayın. Sağlam bir yedek varsa geri yükleyin. Kurtarma için VERİYİ RİSKE ATARAK yalnızca son çare olarak zero_damaged_pages = on ile bozuk sayfaları sıfırlayıp okunabilen veriyi dışa aktarabilirsiniz (bu veri kaybına yol açar). data_checksums'ı etkinleştirin (mevcut kümede PG12+ ile sunucu kapalıyken pg_checksums --enable), RAM testleri yapın ve düzenli PITR yedekleri alın.","tags":["corruption","bozulma","checksum","sayfa","donanim","pitr"]},{"code":"XX002","title":"index_corrupted","severity":"danger","meaning":"Bir index yapısında bozulma saptandı. Index'in işaret ettiği veri, heap'teki gerçek satırlarla tutarsız olduğu için index kullanan sorgular hatalı sonuç verebilir ya da başarısız olur.","cause":"Donanım/depolama hatası, işletim sistemi (glibc/ICU) yükseltmelerinde collation (harf sıralama kuralı) değişmesi nedeniyle B-tree sırasının bozulması, ya da ani kesinti. Özellikle işletim sistemi collation güncellemeleri metin index'lerinde sinsi bozulmaya yol açar.","fix":"Bozulan index'i yeniden oluşturun: REINDEX INDEX indeks_adi; veya REINDEX TABLE tablo; Büyük tablolarda lock'u azaltmak için REINDEX INDEX CONCURRENTLY kullanın. Collation kaynaklı ise etkilenen tüm metin index'lerini yeniden oluşturun ve amcheck eklentisiyle (bt_index_check) doğrulayın. Kök neden donanımsa depolamayı değiştirin.","tags":["index","indeks","corruption","reindex","collation","amcheck"]},{"code":"25001","title":"active_sql_transaction","severity":"caution","meaning":"Yalnızca bir transaction'ın dışında ya da başlangıcında çalışabilen bir komut, aktif bir transaction devam ederken çağrıldı. Bazı komutlar bir transaction bloğu içindeyken çalışmaz.","cause":"SET TRANSACTION ISOLATION LEVEL gibi ayarlar, blokta ilk sorgudan önce yapılmalıdır ('SET TRANSACTION ISOLATION LEVEL must be called before any query'). Benzer şekilde bazı komutlar açık bir BEGIN/transaction içinde reddedilir. Genellikle uygulamanın autocommit'i kapatıp sessiz bir transaction başlatmasından kaynaklanır.","fix":"Transaction düzeyi ayarlarını transaction'ın en başında, herhangi bir sorgu çalıştırılmadan yapın: BEGIN; SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; ... İstemci kütüphanesinin örtük bir transaction açıp açmadığını kontrol edin (autocommit ayarı). Bir transaction bloğu içinde çalışamayan komutlar için önce COMMIT/ROLLBACK ile mevcut transaction'ı kapatın.","tags":["transaction","islem","isolation","set transaction","autocommit","begin"]},{"code":"42P16","title":"invalid_table_definition","severity":"caution","meaning":"Bir tablo tanımı geçersiz olduğu için DDL komutu reddedildi. İstenen tablo/sütun yapısı PostgreSQL kurallarına aykırıdır.","cause":"Birden fazla primary key tanımlamak ('multiple primary keys for table are not allowed'), miras (inheritance) ile çelişen tanımlar, generated/identity sütun constraint'leri, ya da ALTER TABLE ile oluşturulamayacak bir yapıya geçiş gibi durumlar. Otomatik üretilen migration betiklerinde sık görülür.","fix":"Hata mesajındaki spesifik nedeni okuyun. Yalnızca tek bir PRIMARY KEY tanımlayın; çoklu sütunlu anahtar gerekiyorsa PRIMARY KEY (a, b) biçiminde birleşik anahtar kullanın. Identity/generated sütun kurallarını gözden geçirin. Mevcut tablo tanımını \\d tablo ile kontrol edip migration betiğini düzeltin.","tags":["ddl","tablo","primary key","tanim","alter table","migration"]},{"code":"P0001","title":"raise_exception","severity":"caution","meaning":"Bir PL/pgSQL fonksiyonu ya da trigger, RAISE EXCEPTION ile bilinçli olarak bir hata fırlattı. Bu, veritabanı motorunun değil, sizin (ya da bir kütüphanenin) yazdığı iş kuralı kodunun ürettiği bir hatadır.","cause":"İş mantığı bir doğrulamayı geçemediğinde geliştirici RAISE EXCEPTION 'mesaj' USING ERRCODE = ...; çağırmıştır. Örneğin bir trigger, izin verilmeyen bir güncellemeyi engellemek ya da tutarlılık kuralını dayatmak için özel hata fırlatır.","fix":"Hata mesajı ve varsa HINT/DETAIL alanları, fonksiyonun neyi reddettiğini açıklar; iş kuralını buna göre karşılayın. Kaynağı bulmak için ilgili fonksiyon/trigger kodunu inceleyin (RAISE ifadeleri). Özel bir SQLSTATE gerekiyorsa RAISE ... USING ERRCODE ile standart olmayan P0001 yerine anlamlı bir kod atayın; böylece uygulama tarafında ayırt edilebilir.","tags":["plpgsql","raise","trigger","fonksiyon","is kurali","exception"]}]},"errors/mysql-more3.json":{"engineId":"mysql","engine":"MySQL","order":3,"errors":[{"code":"1049","title":"Unknown database 'name'","severity":"caution","meaning":"Bağlanmaya ya da kullanmaya çalıştığınız veritabanı (şema) sunucuda bulunmuyor. USE komutu ya da bağlantı dizesindeki varsayılan veritabanı adı, var olmayan bir şemayı işaret ediyor.","cause":"Veritabanı hiç oluşturulmamış, adı yanlış yazılmış (büyük/küçük harf duyarlılığı işletim sistemine göre değişebilir), silinmiş ya da uygulama yanlış ortama (dev/prod) bağlanıyor. Yeni bir sunucuya geçişte şemaların taşınmamış olması da sık nedendir.","fix":"Mevcut veritabanlarını listeleyin: SHOW DATABASES; Adın doğru yazıldığından ve büyük/küçük harf uyumundan emin olun (lower_case_table_names ayarı önemlidir). Yoksa oluşturun: CREATE DATABASE veritabani_adi CHARACTER SET utf8mb4; ya da yedekten geri yükleyin. Uygulamanın bağlantı yapılandırmasındaki hedef ortamı doğrulayın.","tags":["database","veritabani","schema","use","isim","baglanti"]},{"code":"1364","title":"Field 'name' doesn't have a default value","severity":"caution","meaning":"NOT NULL olarak tanımlı ve varsayılan değeri (DEFAULT) olmayan bir sütuna değer verilmeden satır eklenmeye çalışıldı. Strict SQL modunda MySQL, eksik zorunlu sütunu otomatik dolduramadığı için hata verir.","cause":"INSERT ifadesinde zorunlu (NOT NULL, DEFAULT'suz) sütun atlanmış; sql_mode içinde STRICT_TRANS_TABLES/STRICT_ALL_TABLES etkin. Eski, gevşek modda çalışan bir uygulama, strict mod açık bir sunucuya taşındığında bu hatayı yaşar.","fix":"INSERT'e eksik sütun için değer ekleyin ya da sütuna mantıklı bir DEFAULT tanımlayın: ALTER TABLE tablo MODIFY sutun ... NOT NULL DEFAULT 'deger'; Sütun gerçekten opsiyonelse NULL'a izin verin. Geçici/uyumluluk çözümü olarak sql_mode gevşetilebilir ancak veri kalitesi açısından strict modu korumak önerilir.","tags":["insert","not null","default","strict mode","sql_mode","sutun"]},{"code":"1206","title":"The total number of locks exceeds the lock table size","severity":"danger","meaning":"InnoDB, tuttuğu lock'lar için ayrılan bellek (buffer pool içindeki lock yapısı) alanını tüketti. Tek bir transaction çok fazla row/range lock biriktirdiğinde ortaya çıkar ve transaction geri alınır.","cause":"Çok büyük tek işlemler: milyonlarca satırı tek seferde UPDATE/DELETE etmek, WHERE koşulunun index'siz olup tüm tabloyu kilitlemesi, ya da innodb_buffer_pool_size'ın iş yüküne göre küçük olması. Büyük toplu (batch) işlemler klasik tetikleyicidir.","fix":"Büyük DML'i küçük partilere bölün (ör. LIMIT ile döngüde 10.000'er satır silin/güncelleyin ve her partiden sonra COMMIT edin). WHERE koşullarını indeksleyerek kilitlenen satır sayısını azaltın. Kalıcı çözüm olarak innodb_buffer_pool_size değerini artırın (lock yapıları buradan beslenir). Gereksiz uzun transaction'lardan kaçının.","tags":["innodb","lock","kilit","buffer pool","batch","bellek"]},{"code":"1236","title":"Got fatal error 1236 from master when reading data from binary log","severity":"danger","meaning":"Bir replika (slave/replica) sunucu, kaynağın (master/source) binary log'undan veri okurken ölümcül bir hata aldı ve replikasyon durdu. Replika, kaynağın binlog'undaki beklediği konumu bulamıyor.","cause":"İhtiyaç duyulan binary log dosyaları kaynakta silinmiş (binlog_expire_logs_seconds — 8.0 öncesinde expire_logs_days, 8.4'te kaldırıldı — ya da PURGE BINARY LOGS ile); GTID boşluğu/uyumsuzluğu; kaynak çökmesi sonrası binlog konumunun bozulması; ya da replika çok geride kalıp artık var olmayan log'u istemesi. 'Could not find first log file name in binary log index file' tipik alt mesajdır.","fix":"Replikasyon durumunu inceleyin: SHOW REPLICA STATUS\\G (8.0.22+; daha eski sürümlerde SHOW SLAVE STATUS, 8.4'te eski sözdizimi kaldırıldı). Kaynaktaki mevcut binlog'ları görün: SHOW BINARY LOGS; Eksik log silinmişse replikayı yeni bir yedek/GTID konumundan yeniden kurmanız gerekir (mysqldump --source-data — 8.0.26 öncesinde --master-data, 8.0.26+'da deprecated takma ad — ya da CLONE eklentisi). Kaynakta binlog saklama süresini iş yüküne göre artırın; GTID kullanıyorsanız gtid boşluklarını doğrulayın.","tags":["replication","replikasyon","binlog","master","gtid","slave"]},{"code":"1129","title":"Host 'host' is blocked because of many connection errors","severity":"danger","meaning":"Bir istemci host'undan gelen art arda bağlantı hataları belirlenen eşiği (max_connect_errors) aşınca MySQL o host'u engelledi. O ana kadar başarısız olan handshake'ler yüzünden host kara listeye alındı.","cause":"Bir yük dengeleyici/monitör aracı TCP portuna eksik/hatalı handshake gönderiyor; ağ sorunları bağlantıları yarıda kesiyor; ya da yanlış yapılandırılmış bir istemci sürekli başarısız bağlantı deniyor. Hata sayacı max_connect_errors'a ulaşınca host bloklanır.","fix":"Engeli hemen kaldırın: SQL ile TRUNCATE TABLE performance_schema.host_cache; (8.0.23+; FLUSH HOSTS 8.0.23'te deprecated oldu, 8.4'te kaldırıldı) ya da komut satırından mysqladmin flush-hosts. Engellenen host'ları görmek için: SELECT host, ip, sum_connect_errors FROM performance_schema.host_cache; Kök nedeni giderin: health check/monitör aracını tam bir MySQL handshake yapacak şekilde ayarlayın, ağ kararlılığını kontrol edin. Sağlıklı ortamlarda toleransı artırmak için max_connect_errors değerini yükseltebilirsiniz, ancak asıl bağlantı hatalarını çözmek esastır.","tags":["baglanti","host blocked","max_connect_errors","flush hosts","handshake","network"]},{"code":"1194","title":"Table 'name' is marked as crashed and should be repaired","severity":"danger","meaning":"Genellikle MyISAM (MariaDB'de ayrıca Aria) motoruyla saklanan bir tablo bozuk/çökük olarak işaretlenmiş ve onarılana kadar kullanılamaz. Tabloya erişen sorgular bu hatayla başarısız olur.","cause":"Ani sunucu çökmesi/güç kaybı sırasında MyISAM tablosunun düzgün kapatılamaması, disk dolması, donanım hatası ya da mysqld süreci öldürülmesi. MyISAM transaction ve crash güvenliği sunmadığından bu durum InnoDB'ye kıyasla çok daha sık görülür.","fix":"Tabloyu onarın: REPAIR TABLE tablo_adi; ya da offline olarak myisamchk -r ile. Onarım öncesi mutlaka data file'ları yedekleyin. Kalıcı çözüm için tabloları InnoDB'ye taşıyın: ALTER TABLE tablo ENGINE=InnoDB; böylece crash-safe olur. Disk sağlığını ve myisam_recover_options ayarını kontrol edin.","tags":["myisam","crashed","repair","corruption","bozulma","innodb"]},{"code":"1615","title":"Prepared statement needs to be re-prepared","severity":"caution","meaning":"Sunucu tarafında hazırlanmış (prepared) bir ifadenin çalıştırılması, dayandığı meta verilerin (tablo/view tanımı) değişmesi nedeniyle geçersiz kaldığı için reddedildi. İfadenin yeniden hazırlanması gerekir.","cause":"Prepared statement hazırlandıktan sonra ilgili tabloda DDL yapılması (ALTER TABLE), tablonun yeniden oluşturulması, metadata cache'in dolup girdinin atılması ya da table_definition_cache/table_open_cache limitlerinin küçük olması. Yoğun DDL ile çalışan sistemlerde ve bazı ORM/pool senaryolarında sık görülür.","fix":"Çoğu istemci kütüphanesi bu durumu yakalayıp ifadeyi otomatik yeniden hazırlar; uygulamada bu hatayı yakalayıp prepare + execute'u tekrarlayın (retry). Sık tekrarlıyorsa table_definition_cache ve table_open_cache değerlerini artırın. Uygulama trafiği sırasında gereksiz DDL yapmaktan kaçının.","tags":["prepared statement","re-prepare","ddl","metadata","cache","retry"]},{"code":"1553","title":"Cannot drop index needed in a foreign key constraint","severity":"caution","meaning":"Bir index'i düşürmeye çalışıyorsunuz ama bu index, bir foreign key constraint'i tarafından zorunlu olarak kullanılıyor. InnoDB, FK'nın dayandığı index'i kaldırmanıza izin vermez.","cause":"InnoDB'de her foreign key, referans verdiği sütun(lar) üzerinde bir index gerektirir. DROP INDEX ile bu index'i silmeye çalışmak, FK constraint'ini dayanaksız bırakacağı için reddedilir. Genellikle bir tabloyu yeniden düzenlerken (index temizliği) ortaya çıkar.","fix":"Önce ilgili foreign key constraint'ini kaldırın, sonra index'i düşürün: ALTER TABLE tablo DROP FOREIGN KEY fk_adi; ardından DROP INDEX indeks_adi ON tablo; Gerekiyorsa FK'yı başka uygun bir index'e dayanacak şekilde yeniden oluşturun. Mevcut FK'ları görmek için: SELECT constraint_name, table_name FROM information_schema.key_column_usage WHERE referenced_table_name IS NOT NULL;","tags":["foreign key","yabanci anahtar","index","drop index","innodb","constraint"]},{"code":"3948","title":"Loading local data is disabled; this must be enabled on both the client and server sides","severity":"caution","meaning":"LOAD DATA LOCAL INFILE ile istemci tarafındaki bir dosyadan veri yüklemeye çalıştınız, ancak bu özellik istemci ve/veya sunucu tarafında kapalı. Güvenlik nedeniyle MySQL 8'de LOCAL varsayılan olarak devre dışıdır.","cause":"Sunucuda local_infile sistem değişkeni kapalı (OFF) ve/veya istemci sürücüsü LOCAL INFILE'ı etkinleştirmemiş. Bu özellik, kötü niyetli bir sunucunun istemci dosyalarını okumasına yol açabildiği için varsayılan olarak kısıtlanmıştır.","fix":"Gerçekten gerekiyorsa iki tarafta da etkinleştirin: sunucuda SET GLOBAL local_infile = 1; istemci tarafında sürücünün LOCAL INFILE bayrağını açın (ör. bağlantı seçeneği allowLoadLocalInfile / --local-infile=1). Güvenlik açısından tercih edilen yol, dosyayı sunucuya koyup LOCAL olmadan LOAD DATA INFILE kullanmak ya da toplu INSERT/import araçlarıdır. İşiniz bitince local_infile'ı tekrar kapatın.","tags":["load data","local infile","local_infile","guvenlik","import","yukleme"]},{"code":"1075","title":"Incorrect table definition; there can be only one auto column and it must be defined as a key","severity":"caution","meaning":"Tablo tanımı geçersiz çünkü AUTO_INCREMENT kuralları çiğnendi: bir tabloda yalnızca tek bir otomatik artan sütun olabilir ve bu sütun bir anahtarın (PRIMARY KEY ya da UNIQUE/index) parçası olmak zorundadır.","cause":"Birden fazla AUTO_INCREMENT sütunu tanımlamak; ya da AUTO_INCREMENT sütununu herhangi bir anahtara (index) dahil etmeden bırakmak. CREATE TABLE veya ALTER TABLE sırasında ortaya çıkar.","fix":"Tek bir AUTO_INCREMENT sütunu bırakın ve onu bir anahtarın parçası yapın: CREATE TABLE t (id INT AUTO_INCREMENT PRIMARY KEY, ...); Var olan tabloda düzeltmek için önce sütunu anahtara ekleyin: ALTER TABLE t ADD PRIMARY KEY (id); ardından AUTO_INCREMENT tanımlayın. Birden fazla otomatik sütun gerekiyorsa tasarımı gözden geçirin; MySQL bunu desteklemez.","tags":["auto_increment","tablo","primary key","key","ddl","tanim"]}]},"errors/mssql-more3.json":{"engineId":"mssql","engine":"SQL Server","order":4,"errors":[{"code":"102","title":"Incorrect syntax near 'token'","severity":"caution","meaning":"Transact-SQL ayrıştırıcısı, belirtilen token'ın yakınında geçersiz bir sözdizimi buldu ve komutu derleyemedi. Sorgu hiç çalıştırılamadan reddedilir.","cause":"Yazım hatası, eksik virgül/parantez, ayrılmış bir anahtar kelimenin (ör. USER, ORDER) köşeli parantezsiz kullanılması, dize tırnaklarının kapatılmaması ya da farklı bir SQL lehçesinden kopyalanmış uyumsuz sözdizimi. Dinamik SQL'de birleştirme hataları da sık tetikler.","fix":"Belirtilen token'ın çevresini dikkatle inceleyin; genelde hata bir önceki satırdadır. Ayrılmış kelimeleri köşeli parantezle sarın ([Order]), parantez/virgül dengesini kontrol edin. Dinamik SQL kuruyorsanız PRINT @sql ile oluşan metni görüp çalıştırın. Sürüm farklarında desteklenmeyen sözdizimini (uyumluluk düzeyi) doğrulayın.","tags":["syntax","sozdizimi","parse","tsql","dynamic sql","keyword"]},{"code":"8114","title":"Error converting data type X to Y","severity":"caution","meaning":"Bir değer, bir veri türünden diğerine dönüştürülürken uyumsuzluk nedeniyle çevrilemedi. 245 hatasından farklı olarak bu, genellikle parametre/ifade düzeyinde tür dönüşümünün (ör. varchar'dan numeric'e) başarısız olmasıdır.","cause":"Sayısal bir sütuna/parametreye sayısal olmayan ya da biçimi bozuk bir metin göndermek; ölçek/hassasiyet taşması; boş dize ('') değerini numeric'e çevirmeye çalışmak; ya da parametrelenmiş sorguda yanlış türde argüman geçmek. ORM'lerin ürettiği örtük dönüşümlerde sık görülür.","fix":"Dönüştürülen değerlerin hedef türe uygun olduğunu doğrulayın. Güvenli dönüşüm için TRY_CONVERT / TRY_CAST kullanın; başarısızsa NULL döner ve WHERE ile ayıklayabilirsiniz. Parametre türlerini sütun türleriyle eşleştirin. Sorunlu satırları bulmak için ISNUMERIC/TRY_CAST ile veriyi tarayın; boş dizeleri temizleyin.","tags":["convert","cast","veri turu","donusum","numeric","try_convert"]},{"code":"1204","title":"The instance of the SQL Server Database Engine cannot obtain a LOCK resource","severity":"danger","meaning":"SQL Server, lock yöneticisinin ihtiyaç duyduğu bellek kaynağını ayıramadı ve daha fazla lock oluşturamadı. Lock bellek havuzu tükendiği için işlem başarısız olur.","cause":"Aynı anda çok sayıda ince taneli (satır/sayfa) lock tutulması: büyük, index'siz veya toplu DML işlemleri; lock escalation'ın engellenmiş olması; sunucuda genel bellek baskısı; ya da uzun süre açık kalan transaction'lar. Nadiren dışsal bellek baskısı da tetikler.","fix":"Büyük transaction'ları küçük partilere bölerek eşzamanlı lock sayısını azaltın. Uygun index'lerle taranan/kilitlenen satır sayısını düşürün. Lock escalation'ı kapatan yapılandırmaları gözden geçirin: trace flag 1211/1224 ve ALTER TABLE ... SET (LOCK_ESCALATION = DISABLE); kontrol için SELECT name, lock_escalation_desc FROM sys.tables; ve DBCC TRACESTATUS(-1); Sunucu belleğini ve max server memory ayarını kontrol edin; bellek baskısını giderin.","tags":["lock","kilit","bellek","lock escalation","batch","resource"]},{"code":"3906","title":"Failed to update database because the database is read-only","severity":"caution","meaning":"Salt okunur (read-only) olarak işaretlenmiş bir veritabanında veri değiştirmeye (INSERT/UPDATE/DELETE/DDL) çalıştınız. SQL Server yazma işlemini reddetti.","cause":"Veritabanı READ_ONLY moduna alınmış; bir Availability Group'ta secondary replikaya bağlanılmış (okuma amaçlı); veritabanı bir snapshot ya da geri yükleme sonrası read-only kalmış; ya da dosya sistemi salt okunur. Uygulamanın yanlışlıkla secondary replikaya yönlendirilmesi tipik nedendir.","fix":"Gerçekten yazılabilir olması gerekiyorsa: ALTER DATABASE veritabani SET READ_WRITE; Availability Group'ta ise uygulamayı primary replikaya yönlendirin (ReadWrite bağlantı yönlendirmesi/uygulama amacını kontrol edin). Salt okunur bir snapshot ise yazma yapılamaz; ana veritabanını hedefleyin. Dosya izinlerini/ dosya sistemini de doğrulayın.","tags":["read only","salt okunur","availability group","replica","read_write","yazma"]},{"code":"15023","title":"User already exists in the current database","severity":"caution","meaning":"Veritabanına yeni bir kullanıcı eklerken, aynı ada sahip bir kullanıcının o veritabanında zaten var olduğu belirlendi. Ayrıca bir login'i mevcut bir kullanıcıya bağlarken de görülür (orphaned users).","cause":"Genellikle bir veritabanı yedekten farklı bir sunucuya geri yüklendiğinde login SID'leri ile veritabanı kullanıcıları eşleşmez (orphaned users). CREATE USER ile aynı adı yeniden eklemeye çalışmak ya da login-kullanıcı eşlemesini elle kurmaya çalışmak bu hatayı verir.","fix":"Orphan user'ı mevcut login'e yeniden eşleyin: ALTER USER kullanici WITH LOGIN = login_adi; (eski yöntem sp_change_users_login yerine önerilir). Kullanıcı gerçekten fazlaysa: DROP USER kullanici; Orphan user'ları bulmak için: SELECT dp.name FROM sys.database_principals dp LEFT JOIN sys.server_principals sp ON dp.sid = sp.sid WHERE sp.sid IS NULL AND dp.type IN ('S','U');","tags":["user","kullanici","login","orphaned","restore","yetim"]},{"code":"18452","title":"Login failed. The login is from an untrusted domain and cannot be used with Windows authentication","severity":"danger","meaning":"Windows kimlik doğrulamasıyla oturum açma girişimi, kaynak güvenilmez bir etki alanından geldiği (ya da SQL kimlik doğrulaması gerektiği halde Windows kullanıldığı) için reddedildi. Sunucu bu kimliği güvenilir kabul etmiyor.","cause":"İstemci, SQL Server'ın güvenmediği bir etki alanından/çalışma grubundan Windows kimliğiyle bağlanmaya çalışıyor; makineler farklı/güvenilmeyen domain'lerde; Kerberos/SPN yapılandırması hatalı; ya da SQL kimlik doğrulaması beklenirken bağlantı dizesi Integrated Security kullanıyor. Mixed mode kapalıyken SQL login denemesi de benzer belirti verir.","fix":"SQL kimlik doğrulaması gerekiyorsa sunucuyu Mixed Mode'a alın ve bağlantı dizesinde kullanıcı adı/parola kullanın (Integrated Security=false). Windows kimliği gerekiyorsa domain güven ilişkisini (trust) ve DNS/Kerberos SPN yapılandırmasını doğrulayın. İstemci ve sunucunun aynı ya da güvenilen etki alanında olduğundan emin olun. Error log'lardaki 'state' değeriyle nedeni daraltın.","tags":["login","authentication","windows","domain","kerberos","mixed mode"]},{"code":"605","title":"Attempt to fetch logical page belongs to a different allocation unit","severity":"danger","meaning":"SQL Server, bir sayfayı okurken beklediği nesneye/tahsis birimine (allocation unit) değil, başka bir nesneye ait bir sayfa buldu. Bu, ciddi bir fiziksel/mantıksal veritabanı bozulmasının güçlü göstergesidir.","cause":"Depolama/disk arızası, denetleyici veya sürücü hatası, ani güç kaybı sırasında yazma önbelleğinin bozulması ya da dosya sistemi hasarı sonucu sayfa bağlantılarının bozulması. Bazen 'transient 605' geçici I/O sorunlarından da doğabilir ancak kalıcı olanlar gerçek bozulmadır.","fix":"Hemen DBCC CHECKDB ('veritabani') WITH NO_INFOMSGS, ALL_ERRORMSGS çalıştırıp hasarın kapsamını belirleyin. Mümkünse sağlam bir yedekten geri yükleyin (veri kaybını en aza indiren PITR tercih edilir). Depolama/donanımı test edin, PAGE_VERIFY CHECKSUM ayarını doğrulayın. REPAIR seçenekleri veri kaybına yol açabileceğinden son çare olarak ve yedek aldıktan sonra kullanın; kritik ortamda Microsoft desteğine başvurun.","tags":["corruption","bozulma","page","allocation unit","dbcc checkdb","storage"]},{"code":"4922","title":"ALTER TABLE ALTER COLUMN failed because one or more objects access this column","severity":"caution","meaning":"Bir sütunun türünü/özelliğini değiştirmeye çalıştınız ancak bu sütuna bağımlı nesneler (index, constraint, hesaplanmış sütun, istatistik, şemaya bağlı view vb.) buna izin vermedi. Bağımlılıklar temizlenmeden sütun değiştirilemez.","cause":"Sütun bir index'te, PRIMARY KEY/UNIQUE/CHECK/DEFAULT constraint'inde, hesaplanan sütun ifadesinde, WITH SCHEMABINDING tanımlı bir view/fonksiyonda ya da bir istatistikte kullanılıyor. Tür/boyut değişimi bu nesneleri geçersiz kılacağından ALTER reddedilir.","fix":"Önce bağımlı nesneleri bulup geçici olarak kaldırın veya devre dışı bırakın, sütunu değiştirin, sonra yeniden oluşturun. Bağımlılıkları görmek için sys.sql_expression_dependencies ve sys.indexes/sys.default_constraints sorgulayın. Tipik sıra: DROP CONSTRAINT/INDEX -> ALTER COLUMN -> yeniden CREATE. Şemaya bağlı view'lerde SCHEMABINDING'i geçici kaldırıp geri ekleyin.","tags":["alter column","bagimlilik","index","constraint","schemabinding","ddl"]},{"code":"7202","title":"Could not find server 'name' in sys.servers","severity":"caution","meaning":"Sorguda bağlı sunucu (linked server) veya dört parçalı ad (server.database.schema.object) ile başvurulan sunucu adı, yapılandırılmış bağlı sunucular arasında bulunamadı. SQL Server bu adı çözemedi.","cause":"Bağlı sunucu hiç tanımlanmamış; adı yanlış yazılmış; farklı bir ortamda (dev/prod) var olan bir linked server üretimde bulunmuyor; ya da OPENQUERY/dört parçalı ad yanlış sunucu adına işaret ediyor. Betiklerin sunucular arası taşınmasında sık görülür.","fix":"Tanımlı bağlı sunucuları listeleyin: SELECT name FROM sys.servers; ya da EXEC sp_linkedservers. Gerekliyse ekleyin: EXEC sp_addlinkedserver @server='SUNUCU', ...; ve kimlik eşlemesini sp_addlinkedsrvlogin ile yapın. Sorgudaki dört parçalı adın doğru linked server adını kullandığını doğrulayın; yalnızca yerel nesneye erişiyorsanız sunucu önekini kaldırın.","tags":["linked server","bagli sunucu","sys.servers","openquery","dort parcali ad","yapilandirma"]},{"code":"40501","title":"The service is currently busy. Retry the request after 10 seconds","severity":"danger","meaning":"Azure SQL Database'de hizmet, kaynak baskısı (engine throttling) nedeniyle isteği geçici olarak reddetti. Sistem meşgul olduğu için istemcinin kısa bir süre sonra yeniden denemesi beklenir.","cause":"CPU, bağlantı, transaction log yazma hızı ya da worker sayısı gibi bir kaynağın seçilen hizmet katmanı (DTU/vCore) sınırına dayanması; ani yük artışı; ya da uzun süren/verimsiz sorguların kaynağı tüketmesi. Hata koduna eşlik eden 'reason code' hangi kaynağın kısıtlandığını gösterir.","fix":"Uygulamada üstel geri çekilmeli yeniden deneme (exponential backoff retry) mantığı uygulayın; bu geçici (transient) hatalar için beklenen davranıştır. Kaynak kullanımını inceleyin: sys.dm_db_resource_stats ve Azure portalı ölçümleri. Sorguları/index'leri optimize edin, gereksiz eşzamanlılığı azaltın. Kalıcı doygunluk varsa hizmet katmanını (DTU/vCore) yükseltin.","tags":["azure","throttling","busy","retry","resource","dtu"]}]},"errors/mongodb-more3.json":{"engineId":"mongodb","engine":"MongoDB","order":5,"errors":[{"code":"10107 NotWritablePrimary","title":"not master / not writable primary","severity":"danger","meaning":"Bir yazma (ya da primary gerektiren) işlemi, replica set'te şu anda primary olmayan bir düğüme gönderildi. Yalnızca primary yazma kabul ettiği için işlem reddedildi.","cause":"Uygulama, secondary bir düğüme yazmaya çalışıyor; bir failover (election) sırasında eski primary secondary hâline gelmiş ve istemci hâlâ ona bağlı; ya da sürücünün read/write preference ve topoloji bilgisi güncel değil. Bağlantı dizesinde replicaSet parametresinin eksik olması tipik nedendir.","fix":"Sürücüyü tüm küme üyeleriyle ve replicaSet adıyla yapılandırın (bağlantı dizesinde replicaSet=... ve tüm host'lar); böylece sürücü primary'yi otomatik bulur ve failover'da yönünü değiştirir. Yazma işlemlerini primary'ye yönlendiren varsayılan read/write preference kullanın. Geçici bir hata olduğundan uygulamada yeniden deneme (retryable writes) etkinleştirin. rs.status() ile hangi düğümün PRIMARY olduğunu doğrulayın.","tags":["replica set","primary","failover","yazma","election","retryable"]},{"code":"91 ShutdownInProgress","title":"The server is in the process of shutting down","severity":"danger","meaning":"İşlem, sunucu (mongod/mongos) kapanma sürecine girdiği için tamamlanamadı. Kapanmakta olan bir düğüm yeni istekleri reddeder ve devam eden işlemleri sonlandırır.","cause":"Planlı bir yeniden başlatma/bakım, replica set'te primary'nin adım geri atması (stepdown) öncesi kapanma, konteyner/orkestratör tarafından gönderilen sonlandırma sinyali ya da kaynak yetersizliği nedeniyle sürecin durdurulması. Yuvarlanan (rolling) yükseltmelerde beklenen bir durumdur.","fix":"Genellikle geçici bir hatadır; uygulamada yeniden deneme mantığı ve replica set bağlantısı ile başka bir sağlıklı düğüme yönlenmeyi sağlayın. Beklenmedikse mongod loglarında kapanma nedenini (sinyal, OOM killer, kaynak) inceleyin. Yuvarlanan bakımda kapanmadan önce primary'yi düzgün stepdown edin (rs.stepDown()).","tags":["shutdown","kapanma","bakim","stepdown","replica set","retry"]},{"code":"189 PrimarySteppedDown","title":"Primary stepped down while operation was in progress","severity":"danger","meaning":"İşlem sürerken primary primary rolünü bıraktı (stepped down) ve artık yazma kabul etmiyor. Bu nedenle devam eden komut yarıda kaldı.","cause":"Replica set'te bir seçim (election) tetiklendi: primary bakım için elle stepdown edildi, çoğunluk (majority) ile iletişimini kaybetti, öncelik (priority) değişikliği ya da ağ bölünmesi yaşandı. Failover anında uçuşan (in-flight) işlemler bu hatayı alır.","fix":"Bu tipik olarak yeniden denenebilir (retryable) bir hatadır; sürücüde retryable writes/reads açıkken işlem yeni primary'ye otomatik yönlenebilir. Uygulamada bu hatayı yakalayıp yeniden deneyin. Sık yaşanıyorsa küme sağlığını inceleyin: rs.status() ile üye durumları, ağ gecikmesi ve oplog gecikmesini kontrol edin, gereksiz seçimleri (heartbeat/timeout ayarları) azaltın.","tags":["stepdown","election","failover","primary","replica set","retry"]},{"code":"24 LockTimeout","title":"Operation exceeded time limit waiting for a lock","severity":"caution","meaning":"Bir işlem, ihtiyaç duyduğu lock'u (ör. veritabanı/koleksiyon düzeyinde) beklerken tanımlı süreyi aştı ve iptal edildi. Lock zamanında elde edilemedi.","cause":"Uzun süren bir işlem ya da DDL komutu (ör. bir koleksiyon üzerinde çakışan yönetim işlemleri) gerekli lock'u tutuyor; yoğun eşzamanlı yazma; ya da maxTimeMS ile sınırlanmış bir işlemin lock beklerken süresinin dolması. Çakışan index/collection işlemlerinde görülür.","fix":"Lock'u uzun tutan işlemi bulun: db.currentOp() ile aktif ve bekleyen işlemleri inceleyin; gerekiyorsa db.killOp() ile sonlandırın. Çakışan yönetim komutlarını (index oluşturma, collMod, compact) yoğun olmayan zamanlara alın. İşlemleri kısa tutun ve gereksiz uzun transaction'lardan kaçının. Gerekiyorsa maxTimeMS değerini iş yüküne göre ayarlayın.","tags":["lock","kilit","timeout","currentop","ddl","concurrency"]},{"code":"7 HostNotFound","title":"Could not find host","severity":"danger","meaning":"MongoDB, bağlanmaya çalıştığı bir host adını ağ üzerinde çözemedi/bulamadı. Sürücü ya da bir küme üyesi, belirtilen host'a ulaşamadığı için bağlantı kurulamıyor.","cause":"DNS çözümleme hatası, bağlantı dizesinde yanlış/eski host adı, replica set yapılandırmasındaki (rs.conf) üye host adlarının istemci tarafından çözülememesi ya da ağ/erişim sorunu. Konteyner ortamlarında iç host adlarının dışarıdan çözülememesi tipik nedendir.","fix":"Host adının doğru ve çözülebilir olduğunu doğrulayın (ping/nslookup ile DNS testi). Bağlantı dizesindeki host'ları güncelleyin. Replica set üye adlarının hem istemci hem üyeler tarafından çözülebildiğinden emin olun; gerekiyorsa rs.conf() içindeki host adlarını erişilebilir FQDN/IP ile güncelleyin. SRV (mongodb+srv) kullanıyorsanız DNS SRV kayıtlarını kontrol edin.","tags":["host","dns","baglanti","replica set","network","srv"]},{"code":"175 QueryPlanKilled","title":"Query plan killed during execution","severity":"caution","meaning":"Yürütülmekte olan bir sorgunun planı, altındaki verinin/koleksiyonun değişmesi nedeniyle geçersiz kalıp sonlandırıldı. Sorgu güvenle devam edemediği için iptal edildi.","cause":"Sorgu (özellikle bir cursor açıkken) çalışırken koleksiyonun düşürülmesi (drop), üzerinde kullanılan index'in silinmesi ya da bir yeniden adlandırma/yeniden yapılandırma işlemi. Uzun süren getMore çağrılarında altyapının değişmesi tipik tetikleyicidir.","fix":"Sorguyu/cursor'ı yeniden başlatın (retry). Sorgu çalışırken ilgili koleksiyon veya index üzerinde yıkıcı DDL (drop, dropIndex, rename) yapılmadığından emin olun; bu tür bakımları sorgu trafiğinin dışına alın. Uzun süren okuma işlemlerini kısaltın ve gerekli index'lerin kalıcı olduğundan emin olun.","tags":["query","cursor","getmore","drop","indeks","plan"]},{"code":"11602 InterruptedDueToReplStateChange","title":"Operation interrupted due to a replication state change","severity":"danger","meaning":"İşlem, replica set'in durumu değiştiği (ör. primary'nin değişmesi) için kesildi. Devam eden komut, yeni topolojide güvenle tamamlanamayacağından sonlandırıldı.","cause":"Bir seçim (election), primary'nin stepdown olması, üyelerin rol değiştirmesi ya da yapılandırma değişikliği sırasında uçuşan işlemlerin kesilmesi. 189 PrimarySteppedDown ile benzer kökten gelir ve genellikle failover anlarında görülür.","fix":"Bu yeniden denenebilir bir hatadır; sürücüde retryable writes/reads açıkken işlem yeni primary'ye yönlenerek tekrarlanabilir. Uygulamada bu hatayı yakalayıp yeniden deneyin. Sık tekrarlıyorsa seçimlerin nedenini araştırın: ağ kararsızlığı, heartbeat zaman aşımı, aşırı yük ya da oplog gecikmesi. rs.status() ile küme sağlığını izleyin.","tags":["replica set","election","failover","interrupted","retry","state change"]},{"code":"136 CappedPositionLost","title":"Capped collection position lost","severity":"caution","meaning":"Bir capped (sabit boyutlu) koleksiyon üzerinde okuma yapan bir imlecin (özellikle tailable cursor) izlediği konum kayboldu. Okuduğu belge, koleksiyonun döngüsel olarak üzerine yazması nedeniyle artık mevcut değil.","cause":"Capped koleksiyon dolunca en eski belgeler otomatik olarak silinip üzerine yazılır; tailable bir cursor, tüketebileceğinden daha hızlı yazılan bir koleksiyonu takip ederken izlediği konumun üzerine yazılır ve geride kalır. Oplog gibi capped yapıları takip eden tüketicilerde görülür.","fix":"Cursor'ı yeniden konumlandırarak (yeni bir tailable cursor açarak) takibi baştan başlatın; uygulamada bu hatayı yakalayıp okumayı yenileyin. Tüketicinin yazma hızına yetişememesi kök nedense: capped koleksiyon/oplog boyutunu artırın ya da tüketiciyi hızlandırın. Değişiklikleri güvenilir izlemek için mümkünse tailable cursor yerine change streams kullanın.","tags":["capped","tailable cursor","oplog","imlec","position","change stream"]},{"code":"28 PathNotViable","title":"Cannot use the part of the path to traverse the element","severity":"caution","meaning":"Bir güncelleme (update), noktalı bir alan yolunu (ör. a.b.c) izlemeye çalıştı ancak yolun bir parçası, alt alan içeremeyen bir türe (skaler değer ya da yanlış türde bir eleman) denk geldi. Bu nedenle yol geçilemedi.","cause":"Belgede 'a' alanı bir nesne/dizi değil de bir skaler (ör. sayı/dize) iken a.b.c gibi iç içe bir yola yazmaya çalışmak; ya da bir dizi indeksi beklenirken nesne bulunmak gibi tür uyumsuzlukları. Şema tutarsız belgelerde ($set ile derin yol güncellerken) sık görülür.","fix":"Güncellemeden önce ilgili yolun beklenen türde (nesne/dizi) olduğundan emin olun. Uyumsuz belgeleri düzeltin ya da güncellemeyi belge yapısına göre koşullandırın. Gerekirse önce alanı doğru türe dönüştürün (ör. skaler değeri bir nesneyle değiştirin) sonra iç alanı yazın. Şema tutarlılığı için doğrulama (schema validation) uygulamayı değerlendirin.","tags":["update","path","dotted","tur","set","schema"]}]},"errors/redis-more3.json":{"engineId":"redis","engine":"Redis","order":6,"errors":[{"code":"BUSYGROUP Consumer Group name already exists","title":"Consumer group already exists","severity":"caution","meaning":"Bir stream üzerinde XGROUP CREATE ile tüketici grubu (consumer group) oluşturmaya çalıştınız ancak aynı adlı bir grup o stream'de zaten var. Redis, mevcut grubun üzerine yazmaz.","cause":"Uygulama başlangıçta grubu koşulsuz oluşturmaya çalışıyor ve grup önceki çalıştırmadan kalmış; ya da birden fazla örnek aynı grubu paralel oluşturmaya çalışıyor. Idempotent olmayan başlatma mantığında tipik olarak görülür.","fix":"Grubu güvenle oluşturmak için idempotent yaklaşın: hatayı yakalayıp yok sayın (grup zaten varsa sorun değildir). Stream henüz yoksa otomatik oluşturması için XGROUP CREATE stream grup $ MKSTREAM kullanın. Mevcut grupları görmek için XINFO GROUPS stream çalıştırın. Gerçekten sıfırlamak istiyorsanız önce XGROUP DESTROY stream grup ile silin.","tags":["stream","consumer group","xgroup","busygroup","idempotent","mkstream"]},{"code":"NOGROUP No such key or consumer group","title":"No such key or consumer group in stream","severity":"caution","meaning":"Bir stream tüketim komutu (XREADGROUP, XACK, XCLAIM vb.) çalıştırdınız ancak belirtilen anahtar (stream) ya da tüketici grubu mevcut değil. İşlem yapılacak grup/akış bulunamadı.","cause":"Grup hiç oluşturulmamış (XGROUP CREATE atlanmış); stream anahtarı silinmiş ya da hiç yazılmamış; grup adı/anahtar yanlış yazılmış; ya da grup XGROUP DESTROY ile kaldırılmış. Tüketiciler grup oluşturulmadan başlatıldığında sık görülür.","fix":"Önce stream ve grubun var olduğundan emin olun: XINFO STREAM stream ve XINFO GROUPS stream. Grup yoksa oluşturun: XGROUP CREATE stream grup $ MKSTREAM (gerekirse akışı da oluşturur). Uygulama başlangıcında grubu (BUSYGROUP'u yok sayarak) oluşturan bir adım ekleyin. Anahtar ve grup adlarının doğru yazıldığını doğrulayın.","tags":["stream","consumer group","nogroup","xreadgroup","xgroup","key"]},{"code":"NOTBUSY No scripts in execution right now","title":"No scripts in execution right now","severity":"safe","meaning":"SCRIPT KILL ya da FUNCTION KILL komutu gönderdiniz ancak şu anda çalışan (ve öldürülebilecek) bir Lua betiği/fonksiyon yok. Sonlandırılacak bir işlem bulunmadığı için komut reddedildi.","cause":"Uzun süren bir betiği durdurmaya çalışırken betik zaten bitmiş; yanlış düğüme (betik başka bir örnekte çalışıyorken) SCRIPT KILL gönderilmiş; ya da BUSY durumu SCRIPT KILL'den önce kendiliğinden çözülmüş. Genellikle zamanlama meselesidir.","fix":"Gerçekten takılı bir betik yoksa yapılacak bir şey yoktur; bu güvenli/bilgilendirici bir yanıttır. BUSY hatası alıyorsanız (bir betik busy-reply-threshold süresini, Redis 7 öncesindeki adıyla lua-time-limit, aşmış) SCRIPT KILL'i (fonksiyonlar için FUNCTION KILL) o betiğin çalıştığı doğru düğümde deneyin. Betik veri değiştirmişse SCRIPT KILL çalışmaz; o durumda son çare SHUTDOWN NOSAVE gerekebilir. Uzun betikleri parçalayıp süre limitini gözetin.","tags":["lua","script kill","notbusy","busy","betik","function"]},{"code":"DENIED Redis is running in protected mode","title":"Redis is running in protected mode","severity":"danger","meaning":"Redis korumalı modda (protected mode) çalışıyor ve dışarıdan (loopback olmayan bir adresten) parolasız bağlantıyı reddetti. Güvenlik amacıyla, kimlik doğrulaması olmayan uzak erişim engellenir.","cause":"Redis, herhangi bir arabirime bağlıyken (ya da bind ayarı gevşekken) parola (requirepass) ayarlanmadan bir dış istemciden bağlantı aldı. protected-mode varsayılan olarak açıktır ve bu durumda loopback dışı istekleri engeller. Yanlışlıkla internete açık, güvenliksiz bir Redis'i işaret eder.","fix":"Doğru çözüm güvenliği sağlamaktır: requirepass ile güçlü bir parola (ya da ACL kullanıcıları) tanımlayın ve bind ile yalnızca güvenilir arabirimleri dinleyin. Uzaktan erişim gerekiyorsa parola/TLS ile koruyun ve güvenlik duvarıyla 6379 portunu kısıtlayın. Yalnızca kapalı/güvenli bir ağda geçici olarak protected-mode no yapılabilir, ancak internete açık kurulumlarda ASLA önerilmez.","tags":["protected mode","guvenlik","denied","requirepass","bind","auth"]},{"code":"ERR Can't execute '<cmd>': only (P|S)SUBSCRIBE / (P|S)UNSUBSCRIBE / PING / QUIT / RESET are allowed in this context","title":"Command not allowed in subscribe context","severity":"caution","meaning":"Bağlantı Pub/Sub abonelik (subscribe) moduna girdikten sonra, bu modda izin verilmeyen normal bir komut (ör. GET/SET) çalıştırmaya çalıştınız. Abonelik modundaki bir bağlantı yalnızca sınırlı komutları kabul eder. Eski sürümlerde mesaj \"ERR only (P)SUBSCRIBE / (P)UNSUBSCRIBE / PING / QUIT allowed in this context\" biçimindeydi.","cause":"SUBSCRIBE/PSUBSCRIBE/SSUBSCRIBE ile aboneliğe geçmiş bir bağlantı üzerinden veri komutu göndermek. RESP2 protokolünde abone olmuş bir bağlantı yalnızca (P|S)SUBSCRIBE, (P|S)UNSUBSCRIBE, PING, QUIT ve RESET komutlarına izin verir. Tek bir bağlantıyı hem pub/sub hem normal işler için paylaşmak tipik hatadır.","fix":"Pub/Sub için ayrı bir bağlantı kullanın; normal komutlar için başka bir bağlantı açın (çoğu istemci kütüphanesi bunu otomatik yapar). Abonelikten çıkmak için UNSUBSCRIBE/PUNSUBSCRIBE gönderin, ardından normal komutlar çalışır. RESP3 protokolünde (HELLO 3) abone bağlantı üzerinde diğer komutlara da izin verilir; sürücünüz destekliyorsa RESP3'e geçebilirsiniz.","tags":["pubsub","subscribe","context","resp","baglanti","hello"]},{"code":"ERR SELECT is not allowed in cluster mode","title":"SELECT is not allowed in cluster mode","severity":"caution","meaning":"Redis Cluster modunda SELECT komutuyla farklı bir mantıksal veritabanına (DB indeksi) geçmeye çalıştınız. Küme modu yalnızca 0 numaralı veritabanını destekler; birden fazla DB kullanılamaz.","cause":"Tekil (standalone) Redis'te SELECT ile 0-15 arası DB değiştiren bir uygulamanın, Redis Cluster'a taşındığında aynı komutu göndermeye devam etmesi. Küme mimarisi veriyi slot'lara göre dağıttığından çoklu DB kavramı desteklenmez.","fix":"Küme modunda SELECT çağrılarını kaldırın; yalnızca DB 0 kullanılır. Farklı mantıksal ayrımlar gerekiyorsa anahtar öneki (namespace) kullanın (ör. uygulama1:key). Aynı anahtarların birlikte işlenmesi gerekiyorsa hash tag ile ({kullanici123}) aynı slot'a düşmelerini sağlayın. Uygulama yapılandırmasını küme uyumlu hale getirin.","tags":["cluster","select","database","namespace","hash tag","slot"]},{"code":"ERR wrong number of arguments for command","title":"Wrong number of arguments for command","severity":"caution","meaning":"Bir Redis komutuna, beklenenden az ya da fazla argüman gönderildi. Komut sözdizimi karşılanmadığı için işlenmeden reddedildi.","cause":"Eksik/fazla parametre (ör. SET key değer yerine sadece SET key); değişkenlerin boş/undefined olarak geçmesi; komut adının yanlış argüman düzeniyle çağrılması; ya da istemci kütüphanesinde dizi/argüman açılımının (spread) hatalı yapılması. Dinamik olarak kurulan komutlarda sık görülür.","fix":"Komutun doğru imzasını kontrol edin (ör. SET anahtar değer [seçenekler]); resmi komut referansına bakın. İstemci kodunda argümanların (özellikle diziden gelenlerin) boş/eksik olmadığını doğrulayın. Kullanıcı girdisinden komut kuruyorsanız argüman sayısını önceden doğrulayın. Komutu redis-cli ile elle deneyip beklenen argüman sayısını teyit edin.","tags":["syntax","arguments","arguman","komut","sozdizimi","cli"]},{"code":"ERR Background save already in progress","title":"Background save already in progress","severity":"caution","meaning":"Yeni bir arka plan kaydetme (BGSAVE) ya da AOF yeniden yazma işlemi başlatmaya çalıştınız, ancak zaten devam eden bir arka plan kaydetme işlemi var. Redis aynı anda ikinci bir kayıt sürecine izin vermez.","cause":"Önceki BGSAVE/BGREWRITEAOF henüz tamamlanmadan yeni bir tane tetiklenmesi; büyük veri kümesinde fork/kaydetme uzun sürerken izleme betiklerinin ya da uygulamanın tekrar tekrar BGSAVE çağırması. Yavaş disk ya da büyük RDB dosyası süreci uzatır.","fix":"Devam eden kaydın bitmesini bekleyin; durumu kontrol edin: INFO persistence içindeki rdb_bgsave_in_progress ve aof_rewrite_in_progress alanları ile LASTSAVE zaman damgası. Uygulama/otomasyon mantığını, önceki kayıt bitmeden yeni BGSAVE tetiklemeyecek biçimde koşullandırın. Kayıt çok uzuyorsa disk hızını ve RDB boyutunu inceleyin.","tags":["bgsave","persistence","rdb","aof","background save","fork"]},{"code":"ERR bit offset is not an integer or out of range","title":"Bit offset is not an integer or out of range","severity":"caution","meaning":"SETBIT/GETBIT/BITCOUNT gibi bit işlemlerinde verilen bit ofseti geçersiz: tamsayı değil ya da izin verilen aralığın dışında. Redis, bu ofsette bir bit işlemi yapamaz.","cause":"Ofset olarak sayısal olmayan bir değer geçmek; negatif ofset kullanmak; ya da izin verilen üst sınırı (bit dizisi 512 MB'a, yani yaklaşık 2^32 bit'e kadar) aşan çok büyük bir ofset vermek. Bit alanı (bitmap) tabanlı sayaç/işaretleme yapılarında hesaplama hatasıyla oluşur.","fix":"Ofsetin negatif olmayan bir tamsayı ve izin verilen aralıkta (0 ile ~2^32-1 arası, dizeler en çok 512 MB) olduğundan emin olun. Ofset hesaplamalarını (ör. kullanıcı kimliğinden türetilenleri) taşma/negatiflik açısından doğrulayın. Çok büyük ofsetler gerekiyorsa veriyi birden fazla anahtara bölerek (sharding) tasarlayın.","tags":["bitmap","setbit","offset","integer","range","bit"]}]},"errors/elasticsearch-more3.json":{"engineId":"elasticsearch","engine":"Elasticsearch","order":7,"errors":[{"code":"node_not_connected_exception","title":"Node is not connected","severity":"danger","meaning":"Bir düğüm, iletişim kurması gereken başka bir düğüme şu anda bağlı değil. Küme içi (transport katmanı) bağlantı koptuğu için istek hedef düğüme iletilemedi.","cause":"Ağ kesintisi ya da paket kaybı, hedef düğümün çökmesi/yeniden başlaması, güvenlik duvarı/port (varsayılan 9300 transport portu) engeli, GC duraklamaları nedeniyle düğümün geçici yanıtsız kalması ya da DNS/host çözümleme sorunu. Yuvarlanan yeniden başlatmalarda geçici olarak görülebilir.","fix":"Küme ve düğüm sağlığını inceleyin: GET _cluster/health ve GET _cat/nodes?v ile hangi düğümün eksik olduğunu görün. Transport portu (9300) için düğümler arası ağ erişimini ve güvenlik duvarını doğrulayın. İlgili düğümün loglarında çökme/GC duraklaması/OOM olup olmadığını kontrol edin. Ağ kararlılığını ve discovery/seed host yapılandırmasını gözden geçirin.","tags":["transport","node","baglanti","network","9300","cluster"]},{"code":"receive_timeout_transport_exception","title":"Request timed out waiting for a response from another node","severity":"danger","meaning":"Bir düğüm, başka bir düğüme istek gönderdi ancak yanıt belirlenen süre içinde gelmedi ve istek zaman aşımına uğradı. Düğümler arası (transport) çağrı tamamlanamadı.","cause":"Hedef düğümün aşırı yük altında olması, uzun GC duraklamaları, yavaş disk/CPU baskısı, ağ gecikmesi/paket kaybı ya da hedef düğümün yanıt veremeyecek kadar meşgul olması. Ağır sorgular, büyük toplu (bulk) işlemler ve shard rebalancing sırasında sık görülür.","fix":"İlgili düğümlerin kaynak durumunu inceleyin: GET _nodes/stats ile JVM heap, GC ve thread pool doygunluğuna bakın. GET _cat/thread_pool?v ile reddedilen/kuyruğa alınan görevleri kontrol edin. Ağ gecikmesini ölçün. Yükü azaltın (sorgu/bulk boyutunu küçültün), heap ve donanım kaynaklarını gözden geçirin. Kalıcıysa düğüm ekleyerek yükü dağıtın.","tags":["transport","timeout","gc","yuk","network","thread pool"]},{"code":"routing_missing_exception","title":"Routing value is required for this document","severity":"caution","meaning":"Belgeye erişim/indeksleme için bir yönlendirme (routing) değeri zorunlu olduğu halde sağlanmadı. Elasticsearch, belgenin hangi shard'a ait olduğunu routing olmadan belirleyemedi.","cause":"Index mapping'inde _routing required=true olarak tanımlı; parent-join (parent/child) ilişkisi kullanılıyor ve child belgeler için routing gerekiyor; ya da index/get/update/delete isteğinde routing parametresi atlanmış. Özel routing ile yazılan belgeleri routing vermeden okumaya çalışmak tipik nedendir.","fix":"İstekte routing değerini açıkça belirtin (ör. index/get/update/delete çağrılarında ?routing=deger). Parent-join kullanıyorsanız child belgelerde ebeveynin id'sini routing olarak geçirin. Belge yazılırken hangi routing kullanıldıysa okuma/güncelleme/silmede de aynısını kullanın. Mapping'de _routing gereksinimini (required) gözden geçirin.","tags":["routing","shard","parent-child","join","mapping","index"]},{"code":"too_many_buckets_exception","title":"Trying to create too many buckets","severity":"caution","meaning":"Bir toplama (aggregation) sorgusu, izin verilen üst sınırdan (search.max_buckets, varsayılan 65.536) daha fazla bucket üretmeye çalıştı. Bellek korunması için sorgu reddedildi.","cause":"Yüksek kardinaliteli alanlarda terms/date_histogram gibi toplamaların çok büyük boyutta (size) ya da çok ince aralıkla çalıştırılması; iç içe (nested) toplamaların bucket sayısını çarpması. Aşırı bucket üretimi düğüm belleğini tüketebileceğinden sınır uygulanır.","fix":"Üretilen bucket sayısını azaltın: terms toplamalarında size değerini düşürün, date_histogram aralığını genişletin, gereksiz iç içe toplamaları kaldırın. Çok sonuç gerekiyorsa composite aggregation ile sayfalama (paging) kullanın. Sınırı yükseltmek son çare olmalıdır ve bellek riski taşır: PUT _cluster/settings ile search.max_buckets değiştirilebilir ancak dikkatli olun.","tags":["aggregation","bucket","max_buckets","terms","composite","bellek"]},{"code":"shard_lock_obtain_failed_exception","title":"Obtaining shard lock timed out","severity":"danger","meaning":"Elasticsearch, bir shard üzerinde işlem yapmak için gereken yerel shard lock'unu zaman aşımı süresi içinde alamadı. Shard başlatılamadı ya da yeniden atanamadı.","cause":"Aynı shard'ın önceki bir örneğinin (kapanma/yeniden konumlanma sonrası) lock'u hâlâ bırakmamış olması; yavaş/askıda kalan I/O; disk sorunları; ya da düğüm hızlı yeniden başladığında eski shard kaydının temizlenememesi. Genellikle geçicidir ama kalıcı olursa shard UNASSIGNED kalır.","fix":"Atanmamış shard nedenini görün: GET _cluster/allocation/explain. Çoğu durumda lock kısa sürede serbest kalır; küme tekrar denemeyi kendi yapar, gerekirse POST _cluster/reroute?retry_failed=true ile yeniden atamayı tetikleyin. Kalıcıysa ilgili düğümün loglarında I/O/disk hatalarını inceleyin; disk sağlığını doğrulayın. Sorunlu düğümü düzgün yeniden başlatmak lock'u temizleyebilir.","tags":["shard","lock","unassigned","allocation","io","reroute"]},{"code":"parsing_exception","title":"Failed to parse the search request / query DSL","severity":"caution","meaning":"Gönderilen sorgu gövdesi (query DSL) ayrıştırılamadı. İstek JSON yapısı ya da sorgu sözdizimi Elasticsearch'ün beklediği biçime uymadığı için sorgu çalıştırılamadı.","cause":"Geçersiz JSON, yanlış yerleştirilmiş/bilinmeyen sorgu anahtarları, bir sorgu tipinin (ör. bool, range) yanlış yapı ile kullanılması, sürümler arası kaldırılmış/değişmiş bir alan adı ya da fazladan/eksik parantez. Elle ya da dinamik olarak kurulan sorgularda sık görülür.","fix":"Hata mesajındaki satır/konum ipucuyla sorgu gövdesini kontrol edin; JSON'un geçerli olduğunu doğrulayın. Query DSL yapısını resmi referansla karşılaştırın (bool/must/filter yerleşimi vb.). Sürüm yükseltmelerinde kaldırılan sözdizimini güncelleyin. Sorguyu kademeli olarak sadeleştirip hatalı bölümü izole edin; mümkünse istemci kütüphanesinin sorgu oluşturucusunu kullanın.","tags":["query dsl","parse","json","sozdizimi","search","bool"]},{"code":"max_bytes_length_exceeded_exception","title":"Document contains at least one immense term that is too long","severity":"caution","meaning":"İndekslenmeye çalışılan bir belgede, bir terim (özellikle keyword/analiz edilmemiş bir alan değeri) izin verilen maksimum bayt uzunluğunu (32766 bayt) aştı. Lucene bu kadar uzun bir terimi indeksleyemez.","cause":"Çok uzun bir metin değerinin keyword tipi bir alana (tam metin olarak) yazılması; ör. tüm bir belge gövdesinin, base64 verinin ya da uzun bir URL/kimliğin keyword alanına konması. keyword alanları analiz edilmediğinden değer tek bir terim olarak indekslenir ve sınırı aşar.","fix":"Uzun metin için text tipi (analiz edilen) alan kullanın; keyword yalnızca kısa, tam eşleşme gereken değerler içindir. Değeri kısaltmak istiyorsanız mapping'de ignore_above ayarını kullanın (bu uzunluğu aşan değerler indekslenmez ama saklanır). Gerekmiyorsa çok uzun alanları index:false yapın. Alan tasarımını (text vs keyword) veri türüne göre yeniden değerlendirin.","tags":["keyword","term","ignore_above","lucene","mapping","uzunluk"]},{"code":"illegal_argument_exception_total_fields","title":"Limit of total fields has been exceeded","severity":"caution","meaning":"Bir index'in mapping'indeki toplam alan sayısı, izin verilen üst sınırı (index.mapping.total_fields.limit, varsayılan 1000) aştı. Yeni alanlar eklenemediği için indeksleme başarısız olur.","cause":"Genellikle mapping explosion: dynamic mapping açıkken, yapılandırılmamış/değişken anahtarlı JSON belgelerinin (ör. anahtarları kullanıcı verisinden gelen nesneler) her yeni alanı mapping'e eklemesi. Zamanla alan sayısı hızla artarak sınıra dayanır.","fix":"Kök nedeni çözmek için değişken anahtarlı verileri flattened tipi alanla ya da nesne yerine anahtar-değer dizisiyle modelleyin; dynamic mapping'i kısıtlayın (dynamic: false ya da strict). Gerçekten daha fazla alan gerekiyorsa limiti dikkatle artırın: PUT indeks/_settings {\"index.mapping.total_fields.limit\": 2000}. Mapping explosion'ı izlemek için GET indeks/_mapping ile alan sayısını denetleyin.","tags":["mapping","total_fields","dynamic mapping","flattened","limit","alan"]},{"code":"verification_exception","title":"verification_exception: Found N problem(s) — Unknown column / Unknown index (ES|QL, SQL, EQL)","severity":"caution","meaning":"ES|QL (_query), SQL (_sql) veya EQL sorgusu sözdizimsel olarak ayrıştırıldı ancak anlamsal doğrulamadan geçemedi: başvurulan index, alan (column) ya da fonksiyon bulunamadı veya tipler uyumsuz. Hata metni sorunlu satır/sütun konumunu verir (ör. \"line 1:18: Unknown column [alan]\"). Snapshot deposu doğrulama hatası bu kod değil, repository_verification_exception'dır.","cause":"Sorguda yanlış yazılmış veya mapping'de olmayan alan adı; var olmayan ya da hiçbir index ile eşleşmeyen index deseni; text alanında desteklenmeyen işlem (ör. keyword alt alanı yerine text üzerinde gruplama); uyumsuz tipte karşılaştırma veya bilinmeyen fonksiyon.","fix":"Hata mesajındaki satır:sütun bilgisine göre sorguyu düzeltin. Alan adlarını ve tiplerini doğrulayın: GET indeks/_mapping (SQL için DESCRIBE indeks / SHOW COLUMNS). Index desenini GET _cat/indices ile kontrol edin. Gruplama/sıralama için keyword alt alanını (alan.keyword) kullanın; tip uyumsuzluklarında açık dönüşüm (ES|QL: TO_STRING, TO_INTEGER vb.) uygulayın.","tags":["esql","sql","eql","verification","unknown column","query"]}]},"errors/oracle-more4.json":{"engineId":"oracle","engine":"Oracle","order":1,"errors":[{"code":"ORA-19804","title":"cannot reclaim N bytes disk space from M bytes limit","severity":"danger","meaning":"Oracle, Hızlı Kurtarma Alanı (Fast Recovery Area / FRA) içinde yeni bir dosya (arşiv log, yedek, flashback log) için yer açmaya çalıştı ancak DB_RECOVERY_FILE_DEST_SIZE ile tanımlanan mantıksal limit dolduğu için gereken alanı geri kazanamadı.","cause":"FRA boyutu (DB_RECOVERY_FILE_DEST_SIZE) fiziksel diskten bağımsız bir üst sınırdır ve arşiv loglar, RMAN yedekleri veya flashback loglar bu sınırı doldurmuştur. Genellikle arşiv logların düzenli olarak yedeklenip silinmemesi ya da eski yedeklerin (obsolete) temizlenmemesi kök nedendir.","fix":"FRA kullanımını inceleyin: SELECT * FROM v$recovery_area_usage; ve SELECT * FROM v$recovery_file_dest; Arşiv logları FRA dışındaki bir hedefe yedekleyip silin (RMAN: BACKUP ARCHIVELOG ALL FORMAT '/backup/arc_%U' DELETE INPUT;) veya artık gereksiz yedekleri temizleyin (RMAN: DELETE OBSOLETE;). Data Guard varsa standby'da henüz uygulanmamış arşivleri silmeyin. Kalıcı çözüm için DB_RECOVERY_FILE_DEST_SIZE değerini diskte yer varsa artırın. Flashback gereksizse kapatmayı değerlendirin.","tags":["fra","recovery area","arsiv log","rman","db_recovery_file_dest_size","disk"]},{"code":"ORA-00494","title":"enqueue held for too long by 'inst N, osid M'","severity":"danger","meaning":"Kritik bir kaynak lock'u (enqueue, ör. CF - control file enqueue) bir süreç tarafından izin verilenden çok daha uzun süre tutuldu ve Oracle sistemin kilitlenmesini önlemek için o süreci öldürdü. alert.log içinde 'killing enqueue blocker' kaydıyla birlikte görülür.","cause":"Bir arka plan ya da kullanıcı süreci I/O darboğazı, aşırı CPU baskısı ya da işletim sistemi askıya alması (swap, disk yavaşlığı) nedeniyle önemli bir enqueue'yu izin verilen sürenin ötesinde elinde tuttu; control file (CF) enqueue için bu süre _controlfile_enqueue_timeout ile belirlenir (varsayılan 900 sn). Gizli (underscore) parametreler yalnızca Oracle Support yönlendirmesiyle değiştirilmelidir. Genellikle depolama gecikmeleri ya da LGWR/CKPT gibi süreçlerin yavaşlamasıyla tetiklenir.","fix":"alert.log ve öldürülen sürecin trace dosyasını inceleyip hangi enqueue'nun (çoğunlukla control file) ve hangi arka plan sürecinin sorumlu olduğunu belirleyin. Asıl neden genellikle depolama/G-Ç gecikmesidir: disk yanıt sürelerini, çoklu yol (multipath) ve denetim (controller) sağlığını kontrol edin. CPU/bellek baskısını ve swap kullanımını azaltın. Tekrar ederse Oracle Support ile trace analizini paylaşın.","tags":["enqueue","control file","g-c","depolama","hang","arka plan surec"]},{"code":"ORA-04021","title":"timeout occurred while waiting to lock object","severity":"caution","meaning":"Bir nesne (paket, prosedür, tip vb.) üzerinde library cache lock'u/pini almak için beklenirken zaman aşımına uğradı. Genellikle bir PL/SQL nesnesini derlemeye ya da değiştirmeye çalışırken, o nesne başka bir oturum tarafından çalıştırılıyor veya kilitleniyor olduğunda ortaya çıkar.","cause":"Değiştirilmek/derlenmek istenen nesne başka bir oturumda etkin olarak yürütülüyor ya da başka bir DDL tarafından kilitlenmiş durumda; bu yüzden özel (exclusive) library cache lock'u alınamıyor. Uzun süren bir prosedür çağrısı veya asılı kalmış bir oturum lock'u elde tutuyor olabilir.","fix":"Nesneyi kilitleyen oturumu bulun: SELECT * FROM dba_kgllock WHERE kgllkhdl IN (SELECT p1raw FROM v$session WHERE event LIKE 'library cache%'); ya da v$access ve v$session ile nesneyi kullanan oturumu tespit edin. İş yükünün düşük olduğu bir bakım penceresinde DDL/derlemeyi tekrarlayın. Gerekirse ilgili oturumu güvenle sonlandırın. Uygulamayı kısa süreliğine durdurmak lock'u almayı kolaylaştırır.","tags":["library cache","kilit","plsql","ddl","derleme","timeout"]},{"code":"ORA-04061","title":"existing state of package/procedure has been invalidated","severity":"caution","meaning":"Çağrılan bir PL/SQL nesnesinin (paket, prosedür, fonksiyon) mevcut durumu (state), bağımlı olduğu bir nesne değiştiği için geçersiz kılındı. ORA-04068'in eşlik ettiği durum bilgisi kaybının bir varyantıdır; oturumun tuttuğu paket durumu artık geçerli değildir.","cause":"Bir oturum bir paketi kullanırken, o pakete ya da bağımlılıklarına (tablo yapısı değişimi, yeniden derleme, grant değişikliği) DDL uygulandı. Böylece oturumdaki mevcut paket durumu geçersizleşti. Sık deploy yapılan ortamlarda uygulama çalışırken şema değişikliği yapılınca görülür.","fix":"Genellikle aynı çağrı ikinci kez yeniden denendiğinde (durum sıfırlandığı için) başarılı olur; uygulama tarafında bu hatayı yakalayıp güvenli biçimde yeniden deneyin. Şema değişikliklerini uygulama trafiği düşükken/bakım penceresinde yapın. Geçersiz nesneleri toplu derleyin: EXEC DBMS_UTILITY.COMPILE_SCHEMA('SEMA'); Paket durumunu (global değişkenler) minimize eden tasarımlar bu etkiyi azaltır.","tags":["plsql","paket","invalidate","ddl","state","yeniden derleme"]},{"code":"ORA-01466","title":"unable to read data - table definition has changed","severity":"caution","meaning":"Geçmiş bir zamandan veri okuyan bir sorgu (Flashback Query, AS OF, ya da tutarlı okuma) başarısız oldu çünkü sorgulanan geçmiş zaman ile şimdi arasında tablonun tanımı (DDL) değişmiş. Oracle o zaman noktasındaki veriyi güncel tanımla güvenle okuyamıyor.","cause":"Flashback/AS OF sorgusunun hedeflediği zaman damgasından sonra tabloya bir DDL (kolon ekleme/silme, tip değişimi) uygulandı. Ayrıca istemci ile sunucu arasındaki saat farkı ya da yakın geçmişteki (birkaç saniyelik) sorgular da SCN/zaman çözünürlüğü nedeniyle bu hatayı verebilir.","fix":"Flashback sorgusunu, tablonun DDL değişikliğinden önceki bir zamana/SCN'e göre çalıştırın. Mümkünse zaman damgası yerine kesin SCN kullanın (AS OF SCN). Çok yakın geçmiş sorgularında birkaç saniye geri gidin. Kalıcı geçmiş erişim gerekiyorsa DDL yerine sürümleme (versiyonlama) veya arşiv tablosu tasarımını değerlendirin.","tags":["flashback","as of","ddl","tutarli okuma","scn","sorgu"]},{"code":"ORA-08176","title":"consistent read failure; rollback data not available","severity":"danger","meaning":"Bir sorgu tutarlı okuma (consistent read) görüntüsü oluşturmaya çalışırken, undo üretmeyen bir işlemle değiştirilmiş bloklarla karşılaştı; bu bloklar için geri alma (undo/rollback) verisi olmadığından tutarlı görüntü kurulamadı. ORA-01555'ten farkı, undo'nun üzerine yazılmış olması değil hiç üretilmemiş olmasıdır. (Serializable izolasyon hatası ayrı bir koddur: ORA-08177.)","cause":"Sorgu devam ederken aynı nesnede undo üretmeyen bir işlemin çalışması: direct-path yükleme (INSERT /*+ APPEND */, SQL*Loader DIRECT=TRUE), CREATE INDEX / index yeniden oluşturma veya discrete transaction gibi işlemler.","fix":"Sorguyu, ilgili direct-path yükleme ya da index işlemi bittikten sonra yeniden çalıştırın (retry). Uzun raporları ve direct-path yükleme / index bakım işlerini aynı nesne üzerinde aynı zaman dilimine planlamayın. Tekrarlıyorsa çakışan işi alert log ve ASH ile tespit edip zamanlamayı ayırın.","tags":["undo","tutarli okuma","direct path","append","create index","retry"]},{"code":"ORA-00020","title":"maximum number of processes (N) exceeded","severity":"danger","meaning":"Örneğe ait süreç sayısı, PROCESSES başlatma parametresiyle tanımlanan üst sınıra ulaştı ve yeni bağlantı/süreç oluşturulamıyor. Yeni oturumlar bağlanamaz; hatta yönetici bile bağlanamayabilir.","cause":"Uygulama bağlantı havuzunun aşırı büyümesi, kapanmayan (sızan) bağlantılar, beklenenden fazla eşzamanlı kullanıcı ya da PROCESSES parametresinin düşük ayarlanması sınırın aşılmasına yol açar. Bazen asılı kalan arka plan işleri ya da paralel sorgu süreçleri de tüketir.","fix":"sqlplus -prelim / as sysdba ile bağlanılabilir ancak bu bağlantı SQL çalıştıramaz (v$session sorgulanamaz); yalnızca oradebug (ör. hanganalyze) ve SHUTDOWN ABORT için kullanılır. Yer açmak için işletim sisteminde atıl uygulama sunucu süreçlerini (ps -ef | grep 'LOCAL=NO') dikkatle sonlandırın; ardından normal SYSDBA bağlantısıyla v$session/v$process üzerinden sızan oturumları bulup ALTER SYSTEM KILL SESSION ile kapatın. Kalıcı çözüm için PROCESSES değerini artırıp örneği yeniden başlatın (SESSIONS spfile'da açıkça ayarlanmışsa yeniden türetilmez, onu da güncelleyin). Uygulama tarafında bağlantı havuzu üst sınırını ve idle bağlantı temizliğini düzeltin.","tags":["processes","surec","baglanti","limit","havuz","startup parametre"]},{"code":"ORA-01113","title":"file N needs media recovery","severity":"danger","meaning":"Bir datafile online hale getirilmeye ya da veritabanı açılmaya çalışılıyor ancak dosya tutarsız durumda; devam edebilmek için önce medya kurtarma (media recovery) uygulanması gerekiyor. Dosya, control file'ın beklediğinden daha eski/tutarsız bir SCN'de.","cause":"Datafile eski bir yedekten geri yüklendi, offline iken redo uygulanmadı ya da örnek/depolama çökmesi sonrası dosya güncel değil. Tipik olarak bir restore işleminin ardından recover adımının atlanması ya da bir dosyanın uzun süre offline kalması nedeniyle oluşur.","fix":"Dosyayı ya da veritabanını kurtarın: RECOVER DATAFILE N; ya da RECOVER DATABASE; ardından ALTER DATABASE DATAFILE N ONLINE; veya ALTER DATABASE OPEN; Gereken arşiv logların erişilebilir olduğundan emin olun. RMAN ile: RESTORE gerektiyse yaptıktan sonra RECOVER DATAFILE N; çalıştırın. alert.log'da hangi logların istendiğini takip edin.","tags":["media recovery","datafile","redo","restore","recover","scn"]},{"code":"ORA-02393","title":"exceeded call limit on CPU usage","severity":"caution","meaning":"Oturuma atanmış bir kaynak profilinde (resource profile) tanımlı, tek bir çağrı (call) için izin verilen CPU süresi (CPU_PER_CALL) aşıldı ve Oracle o çağrıyı sonlandırdı. Kaynak sınırlaması amaçlı devreye giren bir korumadır.","cause":"Kullanıcının profilinde CPU_PER_CALL limiti tanımlı ve RESOURCE_LIMIT=TRUE; çalıştırılan tek bir SQL/PLSQL çağrısı bu CPU eşiğini aştı. Genellikle verimsiz/kontrolsüz bir sorgunun beklenenden çok daha fazla CPU tüketmesiyle tetiklenir.","fix":"Sorguyu optimize edin (uygun index, doğru plan, gereksiz tam tablo taramalarını kaldırma) ki CPU tüketimi limitin altına insin. İş gereksinimi meşruysa profildeki CPU_PER_CALL değerini uygun kullanıcı için artırın ya da UNLIMITED yapın: ALTER PROFILE ... LIMIT CPU_PER_CALL ...; Kaynak yönetimini profil yerine Database Resource Manager ile daha esnek yönetmeyi değerlendirin.","tags":["profile","cpu_per_call","resource_limit","kaynak","sorgu","optimizasyon"]},{"code":"ORA-12801","title":"error signaled in parallel query server Pnnn","severity":"danger","meaning":"Paralel çalıştırılan bir sorguda, paralel yürütme sunucularından (parallel query slave) biri bir hatayla karşılaştı ve bu hata koordinatöre iletildi. ORA-12801 bir sarmalayıcıdır; asıl hata onu izleyen ikinci satırda yer alır.","cause":"Paralel bir işlem sırasında bir slave süreci gerçek bir hataya düştü: TEMP tablespace yetersizliği (ORA-01652), PGA belleği tükenmesi (ORA-04030), veri bozulması, paralel süreç limitleri ya da altta yatan başka bir SQL hatası. ORA-12801 yalnızca bunun paralel bağlamda gerçekleştiğini bildirir.","fix":"ORA-12801'in hemen ardından gelen asıl hata koduna odaklanın ve onu giderin (ör. TEMP alanı büyütme, PGA ayarı, bozuk blok onarımı). Gerekirse sorguyu PARALLEL hint'lerini kaldırarak ya da paralellik derecesini düşürerek seri çalıştırıp asıl hatayı yalıtın. PARALLEL_MAX_SERVERS ve kaynak kullanımını gözden geçirin.","tags":["paralel","parallel query","slave","temp","pga","sarmalayici"]}]},"errors/postgres-more4.json":{"engineId":"postgres","engine":"PostgreSQL","order":2,"errors":[{"code":"23P01","title":"exclusion_violation","severity":"danger","meaning":"Bir EXCLUDE constraint'i (exclusion constraint) ihlal edildi. Bu constraint türü, iki satırın belirli operatörlere (ör. aralık çakışması &&) göre çakışmasını engeller; eklenen/güncellenen satır mevcut bir satırla çakıştığı için reddedildi.","cause":"Genellikle GiST tabanlı bir EXCLUDE constraint'i (ör. randevu/oda rezervasyonu için tstzrange && ile zaman çakışması yasağı) tanımlıdır ve eklenen kayıt mevcut bir kayıtla çakışan bir aralığa/değere sahiptir. Eşzamanlı iki işlem çakışan aralıklar eklediğinde de görülebilir.","fix":"Eklemeden önce çakışmayı sorguyla kontrol edin ya da hatayı uygulamada yakalayıp kullanıcıya anlamlı bir mesaj gösterin. Çakışan mevcut kaydı bulmak için ilgili aralık/koşulu sorgulayın. İş kuralı çakışmaya izin veriyorsa constraint'i gevşetin; aksi halde girişi düzeltin. Eşzamanlılıkta seri hale gelme için işlemi güvenle yeniden deneyin.","tags":["exclude","kisit","gist","aralik","cakisma","constraint"]},{"code":"23001","title":"restrict_violation","severity":"danger","meaning":"SQL standardındaki restrict_violation kodudur. Önemli: PostgreSQL, ON DELETE/ON UPDATE RESTRICT ya da NO ACTION tanımlı bir foreign key'in ihlalini bu kodla değil, 23503 (foreign_key_violation) koduyla raporlar; bu kodu çekirdek PostgreSQL'de pratikte görmezsiniz.","cause":"Bağlı çocuk kayıtları olan bir üst kayıt silinmeye ya da anahtarı değiştirilmeye çalışıldığında PostgreSQL 23503 döndürür. 23001 genellikle başka bir veritabanından taşınan uygulama kodunda ya da bir eklentinin özel hatasında karşınıza çıkar. RESTRICT, NO ACTION'dan farklı olarak denetimi transaction sonuna erteleyemez ve hemen hata verir.","fix":"Önce bağlı alt kayıtları silin/güncelleyin ya da başka bir üst kayda taşıyın; ardından üst kaydı işleyin. İş kuralı izin veriyorsa foreign key'i ON DELETE CASCADE ya da SET NULL ile yeniden tanımlamayı değerlendirin. Toplu silmelerde silme sırasını (önce çocuk, sonra ebeveyn) doğru kurgulayın.","tags":["foreign key","restrict","yabanci anahtar","silme","referans","constraint"]},{"code":"42P17","title":"invalid_object_definition","severity":"danger","meaning":"Bir nesnenin (fonksiyon, sıralama/collation, trigger, kural vb.) tanımı geçersiz. PostgreSQL, verilen tanımın kendi içinde tutarsız veya kabul edilemez olduğunu belirtir; nesne bu haliyle oluşturulamaz/değiştirilemez.","cause":"Sık görülen nedenler: bir fonksiyonda çelişkili özellik kombinasyonları (ör. IMMUTABLE olarak işaretlenmiş ama volatile davranan), geçersiz bir collation/karakter kümesi tanımı, ya da trigger/kural için uygunsuz tanım. Ayrıca satır güvenliği (RLS) ve bazı DDL'lerde tutarsız seçenekler de tetikleyebilir.","fix":"Hata mesajının ayrıntısını (DETAIL/HINT) okuyup tanımın hangi parçasının reddedildiğini belirleyin. Fonksiyon uçarlık (volatility) etiketlerini gerçek davranışla uyumlu hale getirin (VOLATILE/STABLE/IMMUTABLE). Collation adının pg_collation içinde var olduğunu doğrulayın. Tanımı belgelenmiş sözdizimi/kurallara göre düzeltip yeniden çalıştırın.","tags":["fonksiyon","collation","tanim","volatility","ddl","nesne"]},{"code":"42710","title":"duplicate_object","severity":"caution","meaning":"Oluşturulmaya çalışılan nesne (rol, tip, constraint, uzantı, şema, index adı vb.) zaten mevcut. PostgreSQL aynı ada/tanıma sahip ikinci bir nesne oluşturulmasına izin vermez.","cause":"CREATE ROLE, CREATE TYPE, CREATE EXTENSION, ADD CONSTRAINT gibi bir komut, aynı adlı bir nesne halihazırda varken çalıştırıldı. Genellikle betiğin iki kez çalıştırılması, idempotent olmayan migration'lar ya da eşzamanlı iki oturumun aynı nesneyi oluşturmaya çalışması nedeniyle olur.","fix":"Nesnenin var olup olmadığını kontrol edin (rol için pg_roles, tip için pg_type, uzantı için pg_extension). Migration'ları idempotent yazın: mümkün olan yerde CREATE ... IF NOT EXISTS kullanın ya da önce DROP ... IF EXISTS yapın. Constraint çakışmasında mevcut constraint'i yeniden adlandırın veya kaldırıp yeniden oluşturun.","tags":["duplicate","rol","tip","extension","kisit","migration"]},{"code":"22008","title":"datetime_field_overflow","severity":"caution","meaning":"Bir tarih/zaman değeri hesaplanırken ya da ayrıştırılırken, alanlardan biri geçerli aralığın dışına taştı. Örneğin ay 13, gün 32 gibi olanaksız bir bileşen ya da desteklenen zaman aralığını aşan bir sonuç üretildi.","cause":"Geçersiz bir tarih girişi (ör. '2026-02-30'), aralık dışı bir bileşen, ya da bir INTERVAL toplaması sonucu desteklenen tarih aralığının aşılması. Yanlış biçim/locale ile ayrıştırma ya da kullanıcı girdisinin doğrulanmadan eklenmesi tipik nedendir.","fix":"Uygulama tarafında tarih girdilerini eklemeden önce doğrulayın ve doğru biçimde (tercihen ISO 8601: YYYY-MM-DD) gönderin. Ayrıştırma için TO_DATE/TO_TIMESTAMP kullanırken biçim maskesini girdilerle eşleştirin. Aritmetik sonuçların desteklenen tarih aralığında kalmasını sağlayın; şüpheli değerleri sınır kontrolünden geçirin.","tags":["tarih","zaman","overflow","interval","dogrulama","bicim"]},{"code":"22026","title":"string_data_length_mismatch","severity":"caution","meaning":"Bir bit dizisinin uzunluğu, işlemin gerektirdiği sabit uzunlukla uyuşmuyor. PostgreSQL'de en sık sabit uzunluklu bit(n) türüne farklı uzunlukta bir bit dizisi yazıldığında ya da farklı uzunluktaki bit dizileri arasında bit düzeyinde AND/OR/XOR yapıldığında ortaya çıkar.","cause":"bit(n) sütununa n'den kısa/uzun bir bit dizisi yazılması (ör. bit(4) sütununa B'101': 'bit string length 3 does not match type bit(4)') ya da farklı uzunluktaki bit dizileriyle &, |, # işlemleri ('cannot AND bit strings of different sizes'). Metin veya karakter kodlaması kaynaklı değildir; char(n)/varchar(n) için fazla uzun değer 22001 verir.","fix":"Değeri hedef uzunluğa getirin: açık dönüşüm kullanın (B'101'::bit(4) sağdan sıfırla doldurur, fazlasını kırpar) ya da uzunluk değişebiliyorsa sütunu bit varying(n) olarak tanımlayın. Bit düzeyinde işlemlerden önce işlenenleri aynı uzunluğa dönüştürün; uzunluğu length() ile kontrol edin.","tags":["bit","uzunluk","bit string","varbit","donusum","dogrulama"]},{"code":"2201B","title":"invalid_regular_expression","severity":"caution","meaning":"Bir düzenli ifade (regular expression) işlemi (~, ~*, SIMILAR TO, regexp_matches, substring vb.) sırasında verilen desen geçersiz. PostgreSQL deseni derleyemedi çünkü sözdizimi hatalı.","cause":"Dengesiz parantezler, geçersiz karakter sınıfları, hatalı kaçış (escape) dizileri ya da desteklenmeyen bir yapı içeren bir regex deseni. Sık görülen bir neden, kullanıcı girdisinin doğrudan desen olarak kullanılması ve girdideki özel karakterlerin kaçırılmamasıdır.","fix":"Regex desenini POSIX/ARE sözdizimine göre düzeltin; parantez, köşeli parantez ve kaçış dizilerini denetleyin. Kullanıcı girdisini desen olarak değil düz metin olarak arayacaksanız: PostgreSQL'de yerleşik bir regexp_quote fonksiyonu yoktur; özel karakterleri regexp_replace ile önlerine ters bölü ekleyerek kaçırın ya da regex kullanmadan strpos()/position() veya LIKE ... ESCAPE ile arayın. Deseni ayrı bir araçta test ederek doğrulayın.","tags":["regex","duzenli ifade","desen","similar to","kacis","sozdizimi"]},{"code":"44000","title":"with_check_option_violation","severity":"danger","meaning":"WITH CHECK OPTION tanımlı bir view üzerinden yapılan INSERT/UPDATE, ortaya çıkan satırın view'ın WHERE koşulunu artık sağlamaması nedeniyle reddedildi. View, kendi filtresi dışına düşecek satırların yazılmasını engeller.","cause":"Güncellenebilir bir view WITH CHECK OPTION ile tanımlanmış ve yapılan yazma işlemi sonucunda satır, view'ın tanım koşulunun dışına çıkıyor (ör. view status='aktif' filtreliyken satırı 'pasif' yapmak). Satır güvenliği (RLS) politikalarında da benzer bir denetim tetiklenebilir.","fix":"Yazılan değerlerin view'ın WHERE koşulunu sağladığından emin olun ya da işlemi view yerine doğrudan temel tablo üzerinde yapın (yetkiler elveriyorsa). İş kuralı satırın filtre dışına çıkmasına izin veriyorsa view'ı WITH CHECK OPTION olmadan yeniden tanımlayın. RLS ise ilgili policy WITH CHECK ifadesini gözden geçirin.","tags":["view","check option","gorunum","rls","insert","update"]},{"code":"40002","title":"transaction_integrity_constraint_violation","severity":"danger","meaning":"SQL standardında, transaction sonunda denetlenen bir bütünlük constraint'inin COMMIT anında ihlal edilmesini ifade eden koddur. Önemli: PostgreSQL bu kodu pratikte üretmez; ertelenmiş (DEFERRED) constraint ihlallerini COMMIT'te constraint'in kendi koduyla döndürür: foreign key için 23503, benzersizlik için 23505.","cause":"DEFERRABLE INITIALLY DEFERRED tanımlı bir foreign key ya da benzersizlik constraint'i, transaction içindeki ara adımlarda geçici olarak bozuldu ve COMMIT anına kadar düzeltilmedi; PostgreSQL'de bu durum 23503/23505 olarak raporlanır. Örneğin karşılıklı referanslı satırların yanlış sırayla eklenip düzeltilmemesi bu durumu doğurur.","fix":"Transaction mantığını, COMMIT'ten önce tüm ertelenmiş constraint'lerin sağlanacağı şekilde düzeltin (eksik referansları ekleyin, çakışmaları giderin). Gerekirse SET CONSTRAINTS ... IMMEDIATE ile constraint'i transaction içinde erken denetleyerek sorunlu adımı erkenden yakalayın. Karşılıklı referanslarda ekleme/güncelleme sırasını yeniden düzenleyin.","tags":["deferred","kisit","commit","foreign key","islem","constraint"]}]},"errors/mysql-more4.json":{"engineId":"mysql","engine":"MySQL","order":3,"errors":[{"code":"1055","title":"Expression not in GROUP BY (only_full_group_by)","severity":"caution","meaning":"SELECT listesinde ya da HAVING/ORDER BY içinde, GROUP BY'a dahil olmayan ve toplama fonksiyonuna sarılmamış bir sütun kullanıldı. ONLY_FULL_GROUP_BY SQL modu etkin olduğu için MySQL bu belirsiz (nondeterministik) ifadeyi reddediyor.","cause":"Sorgu, gruplanan sütunlar dışında bir sütunu doğrudan seçiyor ancak o sütun her grup için tek bir değere sahip olmayabilir. MySQL 5.7+ sürümlerinde ONLY_FULL_GROUP_BY varsayılan olarak açıktır; eski, gevşek GROUP BY davranışına dayanan sorgular bu hatayı verir.","fix":"İlgili sütunu ya GROUP BY listesine ekleyin ya da bir toplama fonksiyonuyla sarın (MAX(), MIN(), ANY_VALUE()). Değerin gerçekten grup içinde tekil olduğunu biliyorsanız ANY_VALUE() belirsizliği bilinçli olarak bastırır. Sorguyu düzeltmek yerine modu kapatmak (sql_mode'dan ONLY_FULL_GROUP_BY çıkarmak) yanlış sonuç riskini geri getirir; tercih edilmemelidir.","tags":["group by","only_full_group_by","sql_mode","any_value","toplama","sorgu"]},{"code":"1267","title":"Illegal mix of collations","severity":"caution","meaning":"Bir karşılaştırma ya da birleştirme (JOIN, WHERE, UNION, CONCAT) işleminde, farklı collation'lara sahip iki dize bir araya getirildi ve MySQL hangi collation kurallarının uygulanacağını belirleyemedi.","cause":"Genellikle farklı karakter kümesi/collation'a sahip sütunların (ör. utf8mb4_general_ci ile utf8mb4_unicode_ci, ya da latin1 ile utf8mb4) karşılaştırılması ya da bir sütun ile bağlantı (connection) collation'ı arasındaki uyumsuzluk. Farklı tablolar/veritabanları farklı varsayılanlarla oluşturulduğunda sık görülür.","fix":"Karşılaştırılan tarafları aynı collation'a getirin: ifadeye COLLATE ile açık collation belirtin (ör. col1 = col2 COLLATE utf8mb4_unicode_ci) veya CONVERT(... USING ...) kullanın. Kalıcı çözüm için ilgili sütunları/tabloları tek bir tutarlı karakter kümesi ve collation'a dönüştürün. Bağlantı collation'ını (collation_connection) da hizalayın.","tags":["collation","harmanlama","karakter kumesi","join","utf8mb4","convert"]},{"code":"1030","title":"Got error N from storage engine","severity":"danger","meaning":"Depolama motoru (InnoDB/MyISAM) bir işlemi tamamlayamadı ve alt seviye bir hata koduyla döndü. Bu, üst katmanı aşan; disk, dosya sistemi ya da motor içi bir sorunun genel bildirimidir. Parantez/mesajdaki alt kod asıl nedeni gösterir.","cause":"Sık nedenler: diskin/temp alanının dolması (ör. errno 28 - No space left on device), dosya izin sorunları, bozuk tablo dosyaları, InnoDB tablespace sorunları ya da işletim sistemi düzeyinde I/O hataları. Büyük geçici tablolar üreten sıralama/gruplama sorguları da tetikleyebilir.","fix":"Alt hata kodunu çözümleyin (perror N komutu Linux'ta anlamını verir, ör. perror 28). Disk doluluğunu ve tmpdir alanını kontrol edin; yer açın. Dosya sahiplik/izinlerini doğrulayın. InnoDB için error log'daki ayrıntıları inceleyin; bozulma şüphesinde CHECK TABLE / gerekiyorsa kurtarma yapın. Devasa geçici sonuç üreten sorguları optimize edin.","tags":["storage engine","innodb","disk","errno","tmpdir","g-c"]},{"code":"1197","title":"Multi-statement transaction required more than 'max_binlog_cache_size'","severity":"danger","meaning":"Tek bir transaction'ın ürettiği binlog verisi, max_binlog_cache_size ile tanımlanan bellek/önbellek sınırını aştı. Transaction binary log'a sığmadığı için başarısız oldu ve geri alındı.","cause":"Çok büyük bir işlem (milyonlarca satırlık tek bir INSERT/UPDATE/DELETE ya da devasa bir toplu yükleme) binlog önbelleğini doldurdu. Binary logging etkinken (replikasyon/point-in-time recovery) büyük işlemler bu sınırı kolayca aşabilir.","fix":"Büyük transaction'ı daha küçük parçalara (batch) bölerek işleyin; her partiden sonra COMMIT edin. Gerçekten büyük transaction'lar kaçınılmazsa max_binlog_cache_size değerini (ve gerekirse binlog_cache_size) artırın. ETL/toplu yüklemelerde parçalı yükleme ve ara COMMIT stratejisi hem bu hatayı hem de uzun lock'ları önler.","tags":["binlog","max_binlog_cache_size","islem","batch","replikasyon","toplu"]},{"code":"1785","title":"Statement violates GTID consistency","severity":"danger","meaning":"GTID (Global Transaction Identifier) tabanlı replikasyon etkinken, çalıştırılan ifade GTID tutarlılık kurallarını ihlal ediyor. GTID modu, tek bir GTID'ye güvenli biçimde atanamayacak belirli ifade türlerine izin vermez.","cause":"1785 (ER_GTID_UNSAFE_NON_TRANSACTIONAL_TABLE) özellikle transactional olmayan (ör. MyISAM) tabloların, transactional (InnoDB) tablolarla aynı transaction'da veya autocommit dışı çok ifadeli bir transaction'da güncellenmesiyle oluşur. Eski sürümlerde ayrıca CREATE TABLE ... SELECT (8.0.21 öncesi; 8.0.21+'da atomik DDL destekleyen motorlarda serbest) ve transaction içinde CREATE/DROP TEMPORARY TABLE (8.0.13 öncesi; 8.0.13+'da binlog_format ROW/MIXED iken serbest) GTID tutarlılığını ihlal eder (bunlar ayrı hata kodlarıyla raporlanır). enforce_gtid_consistency=ON iken reddedilir.","fix":"Transactional olmayan motor tablolarını transactional tablolarla aynı transaction'da karıştırmayın; MyISAM tablolarını autocommit'li tekil ifadelerle güncelleyin ya da tüm tabloları InnoDB'ye taşıyın: ALTER TABLE tablo ENGINE=InnoDB; Eski sürümlerde (8.0.21 öncesi) CREATE TABLE ... SELECT'i iki adıma bölün (CREATE TABLE, ardından INSERT ... SELECT); 8.0.13 öncesinde geçici tabloları açık transaction dışında oluşturup bırakın.","tags":["gtid","replikasyon","tutarlilik","temporary table","myisam","innodb"]},{"code":"3024","title":"Query execution was interrupted, maximum statement execution time exceeded","severity":"caution","meaning":"Bir SELECT sorgusu, kendisi için tanımlanan azami çalışma süresini (max_execution_time / MAX_EXECUTION_TIME hint) aştığı için MySQL tarafından kesildi. Bu, uzun süren sorguların kaynakları tıkamasını önleyen bir zaman aşımı korumasıdır.","cause":"Sorgu, oturum/genel max_execution_time değerinden ya da SELECT üzerindeki MAX_EXECUTION_TIME(N) optimizer hint'inden daha uzun sürdü. Genellikle verimsiz plan, eksik index, büyük tarama ya da yoğun eşzamanlılık altında yavaşlama nedeniyle olur. (Yalnızca salt-okunur SELECT'lere uygulanır.)","fix":"Sorguyu EXPLAIN ile inceleyip optimize edin (uygun index'ler, daha seçici koşullar, tam tablo taramalarını azaltma). Sorgunun meşru olarak uzun sürmesi gerekiyorsa ilgili SELECT için MAX_EXECUTION_TIME hint değerini ya da oturum max_execution_time değerini artırın. Ağır analitik sorguları offline bir ortamda/replika üzerinde çalıştırın.","tags":["timeout","max_execution_time","sorgu","explain","indeks","select"]},{"code":"1298","title":"Unknown or incorrect time zone","severity":"caution","meaning":"Belirtilen saat dilimi adı MySQL tarafından tanınmadı. CONVERT_TZ() çağrısı, time_zone ayarı ya da adlandırılmış bir zaman dilimine (ör. 'Europe/Istanbul') başvuran bir işlem, sunucuda o zaman dilimi tanımlı olmadığı için başarısız oldu.","cause":"MySQL'in adlandırılmış zaman dilimlerini kullanabilmesi için mysql şemasındaki zaman dilimi tablolarının (time_zone, time_zone_name vb.) yüklenmiş olması gerekir. Bu tablolar boşsa yalnızca sayısal ofsetler ('+03:00') çalışır; adlandırılmış bölgeler bilinmez ve bu hata alınır.","fix":"Zaman dilimi tablolarını yükleyin. Linux'ta: mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql komutuyla sistem zoneinfo verisini içe aktarın; ardından sunucuyu yeniden başlatın ya da FLUSH TABLES yapın. Adlandırılmış bölge yüklemek mümkün değilse sayısal ofset ('+03:00') kullanın. Ad yazımını (büyük/küçük harf, 'Europe/Istanbul') doğrulayın.","tags":["time zone","saat dilimi","convert_tz","zoneinfo","mysql_tzinfo_to_sql","ofset"]},{"code":"1418","title":"Function has none of DETERMINISTIC, NO SQL, or READS SQL DATA (binary logging enabled)","severity":"caution","meaning":"Bir saklı fonksiyon (stored function) oluşturulmaya çalışıldı ancak binary logging etkin ve bu fonksiyon determinizm/veri erişim özelliklerinden hiçbiriyle işaretlenmemiş. MySQL, replikasyon güvenliği açısından belirsiz olan böyle bir fonksiyonu reddediyor.","cause":"log_bin açıkken ve log_bin_trust_function_creators=OFF iken, DETERMINISTIC, NO SQL veya READS SQL DATA nitelikleri belirtilmeden fonksiyon tanımlandı. Bu nitelikler olmadan MySQL, fonksiyonun replikada aynı sonucu üretip üretmeyeceğinden emin olamaz.","fix":"Fonksiyonun davranışını doğru niteliklerle bildirin: gerçekten deterministikse DETERMINISTIC, veri okumuyorsa NO SQL, yalnızca okuyorsa READS SQL DATA ekleyin. Fonksiyonların güvenli olduğuna eminseniz ve merkezi bir politika olarak log_bin_trust_function_creators=1 ayarlayabilirsiniz; ancak niteliği doğru bildirmek en güvenli yoldur. Niteliğin fonksiyonun gerçek davranışıyla uyumlu olmasına dikkat edin.","tags":["stored function","deterministic","binary log","replikasyon","log_bin_trust_function_creators","reads sql data"]},{"code":"1231","title":"Variable can't be set to the value of ...","severity":"caution","meaning":"Bir sistem/oturum değişkenine (SET komutuyla) verilmeye çalışılan değer geçersiz. Değişken için verilen değer izin verilen kümenin dışında, yanlış türde ya da uygunsuz bir formatta olduğu için reddedildi.","cause":"Sık örnekler: sql_mode'a geçersiz/yanlış yazılmış bir mod adı atanması, bir enum değişkenine tanımsız bir seçenek verilmesi, ya da NULL kabul etmeyen bir değişkene NULL atanması. Yanlış birim/aralıkta sayısal değerler de tetikleyebilir.","fix":"Değişkenin kabul ettiği geçerli değerleri ve türünü doğrulayın; enum/SET türü değişkenlerde (ör. SET türündeki sql_mode) değer/mod adlarını tam ve doğru yazın, birden çoğunu virgülle ayırın. Geçerli değer aralığını belgeye göre kontrol edin. sql_mode gibi listelerde mevcut değeri okuyup (SELECT @@sql_mode) üzerine güvenli biçimde ekleme/çıkarma yapın.","tags":["set","degisken","sql_mode","enum","deger","gecersiz"]}]},"errors/mssql-more4.json":{"engineId":"mssql","engine":"SQL Server","order":4,"errors":[{"code":"8645","title":"A time out occurred while waiting for memory resources to execute the query","severity":"danger","meaning":"Bir sorgu, çalışmak için gereken memory grant'i almak üzere kaynak semaforunda (resource semaphore) beklerken zaman aşımına uğradı. Bellek baskısı nedeniyle sorguya bellek ayrılamadığından işlem iptal edildi.","cause":"Eşzamanlı çalışan bellek yoğun sorgular (büyük sıralama, hash join, hash aggregate) tüm sorgu belleği havuzunu tüketti; yeni sorgular semaforda sıraya girdi ve süresi doldu. Aşırı büyük memory grant tahminleri (güncel olmayan istatistikler, kötü planlar) ya da yetersiz sunucu belleği kök nedendir.","fix":"sys.dm_exec_query_memory_grants ve resource semaphore DMV'leriyle bellek bekleyen/tutan sorguları belirleyin. İstatistikleri güncelleyin ve aşırı büyük memory grant'e yol açan planları düzeltin (uygun index'ler, daha iyi tahminler). Bellek yoğun sorguların eşzamanlılığını azaltın; gerekirse Resource Governor ile memory grant'i sınırlayın. Sunucu bellek yapılandırmasını (max server memory) gözden geçirin.","tags":["memory grant","resource semaphore","bellek","timeout","hash join","istatistik"]},{"code":"8651","title":"Could not perform the operation because the requested memory grant was not available","severity":"danger","meaning":"Sorgunun ihtiyaç duyduğu memory grant mevcut değildi ve işlem gerçekleştirilemedi. 8645'ten farkı, burada beklemeden ziyade doğrudan istenen büyük bellek bloğunun sağlanamamasıdır; genellikle ciddi bellek baskısını işaret eder.","cause":"Sunucudaki kullanılabilir sorgu belleği, tek bir operatörün (ör. çok büyük bir sıralama/hash) istediği memory grant'i karşılayamıyor. Aşırı yüksek bellek tahminleri, düşük max server memory, harici bellek baskısı ya da Resource Governor'da düşük REQUEST_MAX_MEMORY_GRANT_PERCENT (iş yükü grubu) veya MAX_MEMORY_PERCENT (resource pool) sınırı neden olabilir.","fix":"Memory grant'i şişiren sorguları optimize edin (istatistik güncelleme, uygun indeksleme, sorguyu bölme). Toplam ve kullanılabilir belleği izleyin; max server memory ayarını ve harici uygulamaların bellek baskısını kontrol edin. Resource Governor kullanılıyorsa iş yükü grubunun REQUEST_MAX_MEMORY_GRANT_PERCENT ve havuzun MAX_MEMORY_PERCENT ayarlarını gözden geçirin. Bellek yoğun toplu işleri yoğun olmayan saatlere alın.","tags":["memory grant","bellek","resource governor","istatistik","hash","baski"]},{"code":"5061","title":"ALTER DATABASE failed because a lock could not be placed on database","severity":"danger","meaning":"Bir ALTER DATABASE işlemi (ör. tek kullanıcı moduna alma, dosya değişikliği, seçenek ayarı), veritabanı üzerinde gereken lock'u alamadı çünkü başka etkin bağlantılar/oturumlar veritabanını kullanıyor.","cause":"İşlem, veritabanının o an kullanımda olduğu bir sırada denendi; SET SINGLE_USER, RESTRICTED_USER ya da benzeri seçenek değişiklikleri için gereken özel lock, aktif kullanıcı bağlantıları nedeniyle alınamadı. Sık deploy/bakım sırasında uygulama bağlantıları açıkken görülür.","fix":"Veritabanına bağlı diğer oturumları belirleyin (sys.dm_exec_sessions, sp_who2) ve güvenle kapatın. Bakım için ROLLBACK seçeneğiyle mevcut transaction'ları geri alarak modu değiştirin: ALTER DATABASE [db] SET SINGLE_USER WITH ROLLBACK IMMEDIATE; İşlemi uygulama trafiği düşükken/bakım penceresinde yapın. İşiniz bitince MULTI_USER moduna geri döndürmeyi unutmayın.","tags":["alter database","kilit","single_user","baglanti","bakim","rollback"]},{"code":"3702","title":"Cannot drop database because it is currently in use","severity":"caution","meaning":"Bir veritabanı silinmeye (DROP) ya da yeniden adlandırılmaya çalışıldı ancak hâlâ etkin bağlantılar tarafından kullanıldığı için işlem reddedildi. SQL Server, kullanımda olan bir veritabanını düşüremez.","cause":"Silinmek istenen veritabanına başka oturumlar (uygulama havuzu, açık bir SSMS sekmesi, arka plan işleri) bağlı. Kendi oturumunuzun bağlam olarak (USE) o veritabanında olması bile tetikleyebilir. İzleme/yedekleme araçlarının açık bağlantıları da sık nedendir.","fix":"Silmeden önce başka bir veritabanına geçin (USE master;). Bağlı oturumları bulup kapatın ya da veritabanını önce tek kullanıcı moduna alın: ALTER DATABASE [db] SET SINGLE_USER WITH ROLLBACK IMMEDIATE; ardından DROP DATABASE [db]; çalıştırın. Uygulama bağlantı havuzlarını durdurun ve izleme araçlarının bağlantı açmadığından emin olun.","tags":["drop database","baglanti","kullanimda","single_user","use","bakim"]},{"code":"15138","title":"The database principal owns a schema in the database, and cannot be dropped","severity":"caution","meaning":"Bir veritabanı kullanıcısı/rolü (database principal) silinmeye çalışıldı ancak bu principal, veritabanında bir veya daha fazla şemanın sahibi olduğu için silinemedi. Sahip olduğu şemalar başka bir principal'e devredilmeden silme mümkün değildir.","cause":"Kaldırılmak istenen kullanıcı, en az bir şemanın (ör. varsayılan olarak kendi adıyla oluşturulmuş bir şema ya da AUTHORIZATION ile atanmış bir şema) OWNER'ı. SQL Server, orphan şema bırakmamak için bu silmeyi engeller.","fix":"Kullanıcının sahip olduğu şemaları bulun: SELECT name FROM sys.schemas WHERE principal_id = USER_ID('kullanici'); Bu şemaların sahipliğini başka bir principal'e (ör. dbo) devredin: ALTER AUTHORIZATION ON SCHEMA::[sema] TO dbo; Şema artık gerekmiyorsa (ve boşsa) DROP SCHEMA yapın. Sahiplik devredildikten sonra DROP USER komutunu tekrar çalıştırın.","tags":["schema","principal","kullanici","owner","alter authorization","drop user"]},{"code":"1934","title":"INSERT/UPDATE failed because the following SET options have incorrect settings","severity":"danger","meaning":"Bir DML işlemi (INSERT/UPDATE/DELETE), gerekli SET seçeneklerinin yanlış ayarlanmış olması nedeniyle başarısız oldu. Genellikle indexed view'lar, hesaplanmış sütunlarda index'ler, filtrelenmiş index'ler ya da uzamsal/XML index'ler için zorunlu SET ayarları karşılanmadığında ortaya çıkar.","cause":"Etkilenen tabloda/view'da, belirli SET seçeneklerini (özellikle QUOTED_IDENTIFIER ve ANSI_NULLS'in ON olması, NUMERIC_ROUNDABORT'un OFF olması vb.) gerektiren bir nesne var; ancak oturumun geçerli SET seçenekleri bu gereksinimi karşılamıyor. Eski istemci sürücüleri ya da açıkça yanlış SET yapan betikler tetikler.","fix":"Bağlantı/oturumda gerekli seçenekleri ayarlayın: SET QUOTED_IDENTIFIER ON; SET ANSI_NULLS ON; SET ANSI_PADDING ON; SET ANSI_WARNINGS ON; SET CONCAT_NULL_YIELDS_NULL ON; SET ARITHABORT ON; SET NUMERIC_ROUNDABORT OFF; Uygulama sürücüsünün bağlantı kurarken bu seçenekleri doğru gönderdiğinden emin olun. Hata mesajı hangi seçeneklerin hatalı olduğunu belirtir; onları düzeltin.","tags":["set options","indexed view","computed column","quoted_identifier","ansi_nulls","dml"]},{"code":"468","title":"Cannot resolve the collation conflict","severity":"caution","meaning":"Bir işlemde (JOIN, UNION, WHERE karşılaştırması ya da eşitlik) farklı collation'lara sahip iki metin ifadesi bir araya geldi ve SQL Server hangi collation'ın uygulanacağını çözemedi. İşlem belirsizlik nedeniyle iptal edildi.","cause":"Karşılaştırılan sütunlar farklı collation'larla tanımlı; çoğunlukla veritabanı collation'ı ile sunucu/tempdb collation'ı farklı olduğunda ya da farklı collation'lara sahip veritabanlarındaki tablolar birleştirildiğinde görülür. Geçici tablolar (tempdb collation'ı) ile kalıcı tabloların birleştirilmesi klasik bir tetikleyicidir.","fix":"Karşılaştırmada açık collation belirtin: ... WHERE a.col = b.col COLLATE DATABASE_DEFAULT (ya da somut bir collation adı). Geçici tablo sütunlarını oluştururken COLLATE DATABASE_DEFAULT kullanın. Kalıcı çözüm için ilgili sütunları/veritabanlarını tek bir tutarlı collation'a hizalayın. tempdb ile uyumsuzluk sık ise DATABASE_DEFAULT en pratik çözümdür.","tags":["collation","harmanlama","join","tempdb","database_default","cakisma"]},{"code":"4864","title":"Bulk load data conversion error (type mismatch or invalid character)","severity":"caution","meaning":"Toplu yükleme (BULK INSERT, bcp ya da OPENROWSET(BULK...)) sırasında, kaynak dosyadaki bir alan hedef sütunun veri türüne dönüştürülemedi. Belirtilen satır/sütundaki veri, beklenen türle uyuşmuyor.","cause":"Kaynak veri dosyasındaki bir değer hedef sütun türüne uymuyor: sayısal sütuna metin, yanlış tarih formatı, beklenmeyen ondalık/binlik ayracı, hatalı karakter kodlaması (UTF-8/UTF-16) ya da yanlış alan/satır sonlandırıcıları nedeniyle sütunların kayması. Başlık satırının atlanmaması da sık nedendir.","fix":"Hatanın bildirdiği satır ve sütuna gidip kaynak veriyi inceleyin. Alan (FIELDTERMINATOR) ve satır (ROWTERMINATOR) sonlandırıcılarını dosyayla eşleştirin; başlık satırını atlamak için FIRSTROW=2 kullanın. Doğru kod sayfası/kodlama için CODEPAGE ya da DATAFILETYPE ayarlayın. Tarih/sayı biçimlerini hedef türle uyumlu hale getirin. Bir format dosyası (format file) kullanmak eşlemeyi güvenilir kılar.","tags":["bulk insert","bcp","donusum","fieldterminator","kodlama","format file"]},{"code":"916","title":"The server principal is not able to access the database under the current security context","severity":"caution","meaning":"Bir oturum (login) belirli bir veritabanına erişmeye çalıştı ancak geçerli güvenlik bağlamında o veritabanına erişim yetkisi yok. Login sunucuya bağlanabiliyor fakat hedef veritabanında karşılık gelen bir kullanıcısı/izni bulunmuyor.","cause":"Login'in ilgili veritabanında eşlenmiş bir kullanıcısı yok (orphan veya hiç oluşturulmamış), veritabanı erişimi kısıtlanmış, ya da guest hesabı devre dışı. Sık görülen bir durum, SSMS Object Explorer'ın erişim yetkisi olmayan bir veritabanının meta verisini okumaya çalışmasıdır.","fix":"Login için hedef veritabanında bir kullanıcı oluşturup gerekli izinleri verin: USE [db]; CREATE USER [login] FOR LOGIN [login]; ve uygun rol/izinleri atayın. Orphan user varsa ALTER USER ... WITH LOGIN = ... ile eşleyin. Erişim gerçekten gerekiyorsa uygun veritabanı rolüne ekleyin; gerekmiyorsa hata beklenen davranıştır (o veritabanına erişim yok).","tags":["login","kullanici","erisim","yetki","guvenlik baglami","yetim kullanici"]}]},"errors/mongodb-more4.json":{"engineId":"mongodb","engine":"MongoDB","order":5,"errors":[{"code":"216 ElectionInProgress","title":"ElectionInProgress","severity":"caution","meaning":"Replica set'te şu anda bir primary seçimi (election) sürüyor. Seçim tamamlanana kadar primary belirsiz olduğundan yazma (ve bazı okuma) işlemleri geçici olarak kabul edilemez.","cause":"Mevcut primary'nin düşmesi, ağ bölünmesi (partition), bakım için step-down ya da düğüm yeniden başlatılması sonucu küme yeni bir primary seçiyor. Seçim genellikle birkaç saniye sürer; bu pencere içinde gelen işlemler bu durumla karşılaşır.","fix":"Bu geçici bir durumdur; sürücünüzün yeniden deneme (retryable writes/reads) özelliğini etkinleştirin ki seçim bitince işlem otomatik yeniden denensin. Sık ve uzun seçimler görülüyorsa altta yatan nedeni araştırın: ağ kararlılığı, düğüm sağlığı, oy (vote) yapılandırması ve seçim zaman aşımı ayarları (settings.electionTimeoutMillis). rs.status() ile küme durumunu inceleyin.","tags":["replica set","election","primary","retry","step-down","yuksek erisilebilirlik"]},{"code":"225 TransactionTooOld","title":"TransactionTooOld","severity":"caution","meaning":"Bir multi-document transaction içinde bir komut çalıştırılmaya çalışıldı ancak transaction numarası, sunucunun o oturum için gördüğü en güncel transaction numarasından eski. Yani daha yeni bir transaction başlatıldığı için bu eski transaction artık geçersiz.","cause":"Aynı oturumda (session) eski bir transaction tamamlanmadan yeni bir transaction başlatıldı ya da eşzamanlılık nedeniyle transaction numaraları sıra dışı ilerledi. Genellikle oturum nesnesinin yanlış paylaşılması veya birden çok thread'in aynı oturumu kullanması nedeniyle olur.","fix":"Her mantıksal işlem için oturum yaşam döngüsünü doğru yönetin; bir oturumu eşzamanlı olarak birden çok thread'de paylaşmayın. Transaction'ları sürücünün önerdiği withTransaction/callback API'siyle çalıştırın (bu, yeniden deneme ve numara yönetimini üstlenir). Yeni bir transaction'a başlamadan önce öncekini commit/abort ile kapatın.","tags":["transaction","session","oturum","eszamanlilik","withtransaction","islem"]},{"code":"246 SnapshotUnavailable","title":"SnapshotUnavailable","severity":"caution","meaning":"İstenen snapshot okuma ilgisiyle (readConcern: snapshot) bir okuma yapılamadı çünkü sunucu o zaman noktasına ait tutarlı bir snapshot sağlayamıyor. Genellikle henüz yeterince ilerlememiş ya da geride kalmış bir okuma zaman damgasıyla ilgilidir.","cause":"readConcern 'snapshot' (çoğunlukla çok belgeli işlemlerde) kullanılıyor ancak istenen atLeast/at zaman damgası için tutarlı bir görüntü henüz mevcut değil; ör. yeni oluşturulan koleksiyon/index, katalog değişikliği ya da replikasyon gecikmesi. Sunucu bu durumda okumayı reddeder.","fix":"Bu genellikle geçici bir durumdur; transaction'ı kısa bir gecikmeyle yeniden deneyin (sürücünün transient transaction error yeniden deneme mekanizması bunu kapsar). Yakın zamanda DDL (koleksiyon/index oluşturma) yaptıysanız transaction'ı ondan sonra başlatın. Replikasyon gecikmesini ve düğüm sağlığını kontrol edin. Snapshot okuma gerçekten gerekli değilse daha uygun bir readConcern seçin.","tags":["snapshot","readconcern","transaction","zaman damgasi","retry","replikasyon"]},{"code":"257 TransactionTooLarge","title":"TransactionTooLarge","severity":"danger","meaning":"Çok belgeli bir transaction, izin verilen boyut/işlem sayısı sınırlarını aştı. Transaction içinde biriken değişiklikler (oplog girişi ya da bellek kullanımı) üst sınırı geçtiği için transaction reddedildi.","cause":"Tek bir işlemde çok sayıda belge değiştirmek/eklemek, işlemin ürettiği toplam veriyi (ör. WiredTiger önbelleğinde tutulması gereken değişiklik hacmi ya da transactionLimitBytes gibi sunucu sınırları) aşırıya çıkardı. 4.2'den beri bir transaction birden fazla oplog girişine bölünebildiğinden 16 MB'lik oplog girişi sınırı tek başına belirleyici değildir. İşlemleri toplu veri taşıma/ETL için kullanmak bu sınırı kolayca zorlar.","fix":"Transaction'ı daha küçük parçalara bölün; her partiyi ayrı bir transaction'da commit edin. Çok belgeli transaction'lar kısa ve küçük tutulmak üzere tasarlanmıştır; büyük toplu güncellemeleri transaction'sız (idempotent, parça parça) yapmayı ya da bulk write ile bölerek işlemeyi tercih edin. Tek transaction'da binlerce belge değiştirmekten kaçının.","tags":["transaction","boyut","oplog","batch","toplu","bulk write"]},{"code":"276 IndexBuildAborted","title":"IndexBuildAborted","severity":"danger","meaning":"Devam etmekte olan bir index oluşturma (index build) işlemi tamamlanamadan iptal edildi/durduruldu. Hedeflenen index başarıyla oluşturulmadı.","cause":"Index oluşturma; düğümde disk/bellek yetersizliği, dropIndexes ile açık iptal, primary step-down/replica durum değişimi, benzersizlik ihlali (unique index oluştururken çakışan belgeler) ya da düğümün yeniden başlatılması nedeniyle iptal edilmiş olabilir.","fix":"mongod loglarında iptal nedenini bulun (disk alanı, bellek, benzersizlik çakışması vb.) ve giderin. Unique index kuruyorsanız önce çakışan belgeleri temizleyin. Yeterli disk/bellek sağlayın ve replika durumunun kararlı olduğundan emin olun. Sorunu giderdikten sonra createIndex ile index'i yeniden oluşturun; büyük koleksiyonlarda düşük yük zamanını seçin.","tags":["index","index build","iptal","unique","disk","replica set"]},{"code":"86 IndexKeySpecsConflict","title":"IndexKeySpecsConflict","severity":"caution","meaning":"Oluşturulmak istenen index, mevcut bir index ile aynı anahtar tanımına (aynı alanlar/sıra) sahip ancak farklı seçeneklere ya da farklı bir ada sahip. MongoDB, aynı anahtarlı çakışan iki index tanımına izin vermez.","cause":"Aynı alan(lar) üzerinde, farklı bir ad veya farklı seçeneklerle (ör. farklı collation, partialFilterExpression, unique ayarı) ikinci bir index oluşturulmaya çalışıldı. Genellikle index tanımının migration/kod tarafında değiştirilip yeniden çalıştırılmasıyla olur.","fix":"Mevcut index'leri inceleyin: db.koleksiyon.getIndexes() Aynı anahtarlı çakışan index'i bulun. İstediğiniz seçeneklere geçmek için önce eski index'i kaldırın (dropIndex) sonra yeni tanımıyla yeniden oluşturun. Yalnızca ad farklıysa mevcut index'i kullanmaya devam edin; gereksiz ikinci bir tanım oluşturmayın.","tags":["index","getindexes","collation","unique","cakisma","createindex"]},{"code":"166 CommandNotSupportedOnView","title":"CommandNotSupportedOnView","severity":"caution","meaning":"Çalıştırılan komut bir view üzerinde desteklenmiyor. MongoDB view'ları salt-okunurdur ve yalnızca belirli okuma işlemlerini kabul eder; yazma ya da desteklenmeyen komutlar reddedilir.","cause":"Bir view üzerinde insert/update/delete gibi yazma işlemleri, ya da view'larda desteklenmeyen bazı komutlar (ör. belirli metin/geo işlemleri, doğrudan index oluşturma) denendi. Uygulama, bir koleksiyon zannederek view'a yazmaya çalıştığında görülür.","fix":"Yazma işlemlerini view'ın dayandığı temel (source) koleksiyona yapın; view'lar yalnızca okuma içindir. Komutun view'larda desteklenip desteklenmediğini doğrulayın ve desteklenen okuma/aggregation işlemlerini kullanın. Yazılabilir bir yapıya ihtiyaç varsa view yerine materyalize edilmiş bir koleksiyon ($merge/$out) tasarlayın.","tags":["view","gorunum","salt okunur","aggregation","yazma","koleksiyon"]},{"code":"168 InvalidPipelineOperator","title":"InvalidPipelineOperator","severity":"caution","meaning":"Bir aggregation (toplama) işlem hattında (pipeline) tanınmayan ya da geçersiz bir operatör/aşama kullanıldı. MongoDB, belirtilen operatör adını çözemedi ve pipeline'ı reddetti.","cause":"Yanlış yazılmış bir operatör adı (ör. '$groups' yerine '$group'), kullanılan MongoDB sürümünde bulunmayan yeni bir operatör, ya da yanlış bağlamda kullanılan bir ifade. $ önekinin unutulması veya operatörün geçersiz bir konumda kullanılması da tetikler.","fix":"Operatör/aşama adlarının yazımını ve $ önekini doğrulayın. Kullandığınız operatörün, sunucu MongoDB sürümünde desteklendiğinden emin olun (yeni operatörler eski sürümlerde yoktur). Pipeline'ı belgelenen sözdizimiyle karşılaştırın; ifadeyi doğru aşama içinde (ör. $expr, $project) kullanın. Aşamayı yalıtarak küçük bir örnekle test edin.","tags":["aggregation","pipeline","operator","sozdizimi","surum","expr"]},{"code":"118 NamespaceNotSharded","title":"NamespaceNotSharded","severity":"caution","meaning":"Yalnızca sharded koleksiyonlarda anlamlı olan bir işlem, henüz shard'lanmamış bir koleksiyon/namespace üzerinde çalıştırıldı. Hedef koleksiyon shard edilmediği için komut uygulanamadı.","cause":"moveChunk, split, ya da shard anahtarına dayalı belirli yönetim komutları, sharding etkinleştirilmemiş bir koleksiyon üzerinde çağrıldı. Genellikle koleksiyonun shardCollection ile shard'lanmamış olması ya da yanlış namespace hedeflenmesi nedeniyle olur.","fix":"Koleksiyonun sharding durumunu kontrol edin: sh.status() ya da config.collections. İşlem gerçekten sharding gerektiriyorsa önce veritabanında sharding'i etkinleştirip (sh.enableSharding) koleksiyonu shard'layın (sh.shardCollection ile uygun shard anahtarı). Aksi halde shard'lanmamış koleksiyonlarda bu yönetim komutlarına gerek yoktur; doğru namespace hedeflediğinizi doğrulayın.","tags":["sharding","shard","namespace","shardcollection","movechunk","cluster"]}]},"errors/redis-more4.json":{"engineId":"redis","engine":"Redis","order":6,"errors":[{"code":"ERR Protocol error: invalid multibulk length","title":"Protocol error: invalid multibulk length","severity":"danger","meaning":"Redis sunucusu, istemciden gelen bayt akışını RESP (Redis Serialization Protocol) protokolüne göre ayrıştıramadı. Çok-bölümlü (multibulk) bir komutun bildirdiği eleman sayısı geçersiz olduğundan bağlantı protokol hatasıyla kapatıldı.","cause":"Genellikle Redis olmayan bir istemcinin (ör. bir HTTP isteği, yanlış porta bağlanan bir uygulama) Redis portuna ham veri göndermesi, bozuk/eksik bir istemci kütüphanesi, pipeline'da hatalı çerçeveleme ya da protokol sınırlarını aşan (proto-max-bulk-len) devasa istekler tetikler.","fix":"Redis portuna yalnızca gerçek bir Redis istemcisinin bağlandığını doğrulayın (yanlışlıkla HTTP/başka protokol trafiği gelmemeli). İstemci kütüphanesini güncelleyin ve RESP çerçevelemesini bozan özel/manuel komut üretiminden kaçının. Çok büyük değerler gönderiyorsanız proto-max-bulk-len sınırını ve istek boyutunu gözden geçirin. Ağda araya giren bir proxy'nin veriyi bozmadığından emin olun.","tags":["protocol","resp","multibulk","istemci","pipeline","baglanti"]},{"code":"ERR Number of keys can't be greater than number of args","title":"EVAL/EVALSHA: numkeys exceeds argument count","severity":"caution","meaning":"Bir Lua betiği çalıştırılırken (EVAL/EVALSHA/FCALL), belirtilen anahtar sayısı (numkeys), komuta gerçekte verilen argüman sayısından fazla. Redis, KEYS ve ARGV dizilerini ayıramadığı için komutu reddediyor.","cause":"EVAL komutunun sözdizimi 'EVAL script numkeys key [key ...] arg [arg ...]' biçimindedir. numkeys değeri yanlış hesaplanmış (gereğinden büyük verilmiş) ya da beklenen anahtarlar komuta hiç eklenmemiş. Sık görülen bir programlama hatasıdır.","fix":"numkeys değerini, komuta gerçekten geçirilen anahtar sayısıyla birebir eşitleyin. İstemci kütüphanenizin EVAL sarmalayıcısını (genellikle KEYS ve ARGV'yi ayrı listeler olarak alır) kullanarak numkeys'i otomatik hesaplatın. Betiği çağırırken anahtarları KEYS, diğer parametreleri ARGV olarak doğru bölün.","tags":["lua","eval","evalsha","numkeys","keys","betik"]},{"code":"ERR WATCH inside MULTI is not allowed","title":"WATCH inside MULTI is not allowed","severity":"caution","meaning":"Açık bir MULTI bloğu içindeyken WATCH komutu gönderildi. WATCH, iyimser kilitleme (optimistic locking) için anahtarları transaction başlamadan ÖNCE izlemeye almalıdır; MULTI sonrasında çağrılırsa reddedilir. Hata transaction'ı iptal etmez, yalnızca WATCH çalışmaz ve izleme yapılmaz.","cause":"Kodda WATCH ile MULTI sırasının ters yazılması (önce MULTI, sonra WATCH); istemci kütüphanesinin pipeline/transaction sarmalayıcısı içinde WATCH çağırmak; ya da bağlantı havuzundan MULTI durumu açık kalmış bir bağlantının kullanılması. Bu durumda EXEC, izlenmesi beklenen anahtarlar değişmiş olsa bile çalışır; beklenen çakışma koruması devreye girmez.","fix":"Doğru sıra: WATCH anahtar → (değerleri okuyun) → MULTI → komutlar → EXEC. EXEC nil dönerse izlenen anahtar değişmiş demektir; transaction'ı baştan tekrarlayın. İstemci kütüphanesinin WATCH/transaction API'sini (ör. watch + pipeline yardımcıları) kullanın. Not: SUBSCRIBE gibi pub/sub komutları MULTI içinde reddedilmez, kuyruğa alınır ve EXEC sonrası bağlantı abone moduna geçer; bu da önerilmez, pub/sub için ayrı bağlantı kullanın.","tags":["multi","watch","transaction","optimistic locking","exec","baglanti"]},{"code":"ERR WAIT cannot be used with replica instances","title":"WAIT cannot be used with replica instances","severity":"caution","meaning":"WAIT komutu bir replika (replica/slave) örneğinde çalıştırıldı. WAIT, bir yazmanın belirli sayıda replikaya ulaşmasını beklemek için yalnızca primary (master) üzerinde anlamlıdır; replika üzerinde kullanılamaz.","cause":"Uygulama, WAIT komutunu yanlışlıkla bir replika bağlantısına gönderdi. Bu genellikle bağlantının bir okuma replikasına yönlendirilmesi ya da rol değişiminden (failover) sonra istemcinin hâlâ replikaya bağlı olması nedeniyle olur.","fix":"WAIT komutunu yalnızca primary'ye gönderin. İstemci/proxy yapılandırmasının yazma ve WAIT çağrılarını master'a yönlendirdiğinden emin olun. Failover sonrası rol değişikliklerini algılayıp bağlantıları yeni primary'ye yönlendirin (ROLE komutu ile rolü doğrulayabilirsiniz).","tags":["wait","replica","master","yazma","failover","replikasyon"]},{"code":"ERR Background append only file rewriting already in progress","title":"AOF rewrite already in progress","severity":"caution","meaning":"Bir AOF (Append Only File) yeniden yazma işlemi (BGREWRITEAOF) başlatılmaya çalışıldı ancak zaten devam eden bir AOF yeniden yazma süreci mevcut. Aynı anda iki AOF yeniden yazma çalışamaz.","cause":"Önceki bir BGREWRITEAOF (manuel ya da otomatik, auto-aof-rewrite-percentage tetiklemesiyle başlayan) hâlâ sürerken yeni bir yeniden yazma isteği geldi. Büyük veri kümelerinde AOF yeniden yazma uzun sürebilir ve bu çakışmaya yol açar.","fix":"Devam eden yeniden yazmanın bitmesini bekleyin; INFO persistence çıktısında aof_rewrite_in_progress alanını izleyin. İşlem meşru biçimde sürüyorsa ek bir istek göndermeyin. Sık çakışma varsa otomatik yeniden yazma eşiklerini (auto-aof-rewrite-percentage/min-size) ve disk I/O performansını gözden geçirin.","tags":["aof","bgrewriteaof","persistence","yeniden yazma","info","disk"]},{"code":"IOERR error or timeout reading from target instance","title":"MIGRATE: I/O error or timeout to target","severity":"danger","meaning":"Bir MIGRATE komutu (genellikle Redis Cluster'da slot/anahtar taşırken), hedef örneğe bağlanırken ya da ondan yanıt okurken bir I/O hatası veya zaman aşımı yaşadı. Anahtar taşıma işlemi güvenli biçimde tamamlanamadı.","cause":"Kaynak ile hedef düğüm arasındaki ağ gecikmesi/kesintisi, hedef düğümün aşırı yüklü ya da yanıt vermiyor olması, MIGRATE zaman aşımı süresinin çok kısa olması, ya da büyük bir anahtarın belirtilen sürede aktarılamaması. Cluster resharding sırasında sık görülür.","fix":"Kaynak ve hedef düğümler arası ağ bağlantısını ve gecikmeyi kontrol edin. MIGRATE için daha uzun bir timeout değeri belirtin (özellikle büyük anahtarlarda). Hedef düğümün sağlığını/yükünü ve bellek durumunu doğrulayın. Resharding sırasında büyük anahtarları taşırken yükü düşük saatleri seçin; gerekiyorsa taşımayı yeniden deneyin.","tags":["migrate","cluster","resharding","timeout","network","g-c"]},{"code":"ERR Error compiling script (new function)","title":"Error compiling Lua script","severity":"caution","meaning":"EVAL ile gönderilen Lua betiği, Redis'in gömülü Lua yorumlayıcısında derlenemedi. Betikte bir sözdizimi hatası bulunduğu için çalıştırma başlamadan reddedildi.","cause":"Lua betiğinde sözdizimi hataları: kapatılmamış parantez/tırnak, yanlış yazılmış anahtar sözcükler, eksik 'end', geçersiz operatörler ya da desteklenmeyen bir Lua yapısı. Betiğin istemci tarafında yanlış birleştirilmesi/kaçırılması da tetikleyebilir.","fix":"Hata mesajındaki satır/karakter bilgisini kullanarak Lua sözdizimini düzeltin (parantez, tırnak, 'end' eşleşmelerini kontrol edin). Betiği ayrı bir Lua ortamında derleyerek doğrulayın. İstemci tarafında betiği doğru biçimde (kaçış/birleştirme hatası olmadan) oluşturduğunuzdan emin olun. Doğrulanmış betikleri SCRIPT LOAD ile önden yükleyip EVALSHA ile çağırın.","tags":["lua","eval","derleme","sozdizimi","script load","betik"]},{"code":"ERR FAILOVER requires connected replicas.","title":"FAILOVER requires connected replicas","severity":"caution","meaning":"Kontrollü (graceful) bir failover başlatmak için FAILOVER komutu çalıştırıldı ancak primary'ye bağlı, rolü devralabilecek uygun bir replika bulunmadığı için işlem reddedildi. Rolü devredecek hedef olmadan failover yapılamaz.","cause":"Primary'nin şu anda bağlı hiçbir replikası yok (replikalar düşmüş, ağdan kopmuş ya da senkronizasyonda değil), ya da belirtilen hedef replika uygun/bağlı durumda değil. Manuel FAILOVER (Redis 6.2+) çağrılırken replikasyon topolojisi gerekli koşulu sağlamıyor. Not: FAILOVER yalnızca standalone (master/replica) replikasyonda çalışır; Redis Cluster'da replika üzerinde CLUSTER FAILOVER kullanılır.","fix":"En az bir sağlıklı, bağlı ve güncel replikanın bulunduğundan emin olun (INFO replication ile connected_slaves ve senkronizasyon durumunu kontrol edin). Replikaların ağ/erişim sorunlarını giderip primary'ye bağlanmalarını sağlayın. Belirli bir hedefe devretmek için FAILOVER TO host port kullanın ve o replikanın uygun olduğunu doğrulayın.","tags":["failover","replica","master","replikasyon","info replication","yuksek erisilebilirlik"]},{"code":"ERR invalid expire time in 'set' command","title":"invalid expire time in SET","severity":"caution","meaning":"SET komutuna (EX/PX/EXAT/PXAT seçenekleriyle) geçersiz bir son kullanma süresi verildi. Redis, sıfır ya da negatif gibi anlamsız bir yaşam süresini kabul etmediği için komutu reddetti.","cause":"EX/PX ile 0 veya negatif bir değer gönderilmesi, ya da uygulamanın son kullanma süresini yanlış hesaplayıp geçersiz bir sayı üretmesi. SETEX/GETEX gibi komutlarda da benzer biçimde pozitif olmayan süreler bu hatayı verir. Bazı istemci hataları saniye/milisaniye birim karışıklığından kaynaklanır.","fix":"Son kullanma süresini kesinlikle pozitif bir tamsayı olarak gönderin; EX saniye, PX milisaniye bekler. Uygulamada süre hesabını doğrulayın (negatif/sıfır sonuç üretmesin) ve birimleri (saniye vs. milisaniye) karıştırmayın. Bir anahtarı hemen silmek istiyorsanız süre atamak yerine DEL/UNLINK kullanın. Mutlak zaman için EXAT/PXAT'e geçerli bir gelecekteki Unix zaman damgası verin.","tags":["set","expire","ttl","ex","px","gecerlilik"]}]},"errors/elasticsearch-more4.json":{"engineId":"elasticsearch","engine":"Elasticsearch","order":7,"errors":[{"code":"bind_transport_exception","title":"bind_transport_exception (Address already in use)","severity":"danger","meaning":"Bir Elasticsearch düğümü başlarken transport (düğümler arası iletişim) ya da HTTP portunu dinlemek için sokete bağlanamadı. Genellikle 'Address already in use' alt hatasıyla gelir ve düğüm başlatılamaz.","cause":"İstenen port (varsayılan transport 9300, HTTP 9200) başka bir süreç tarafından zaten kullanılıyor; çoğunlukla aynı düğümün önceki bir örneğinin düzgün kapanmaması, aynı makinede çakışan bir başka ES/servis, ya da yanlış network.host/port yapılandırması. İzin/erişim kısıtı da bağlanmayı engelleyebilir.","fix":"Portu kimin tuttuğunu bulun (Linux: ss -ltnp | grep 9300 ya da lsof -i:9300) ve çakışan süreci sonlandırın veya düğüm için farklı bir port (transport.port / http.port) atayın. Önceki ES sürecinin gerçekten kapandığını doğrulayın. network.host ve port aralığı ayarlarının doğru ve bağlanılabilir olduğundan emin olun. Ardından düğümü yeniden başlatın.","tags":["transport","port","9300","bind","network.host","baslatma"]},{"code":"translog_corrupted_exception","title":"translog_corrupted_exception","severity":"danger","meaning":"Bir shard'ın translog'u, bozulmuş olduğu için okunamadı. Elasticsearch, kurtarma (recovery) sırasında translog'un bütünlük denetiminden geçemediğini tespit etti ve shard başlatılamadı.","cause":"Genellikle ani güç kesintisi, disk dolması, dosya sistemi hatası, donanım/disk arızası ya da veri dizinine dışarıdan (kopyalama, elle müdahale) yapılan işlemler sonucu translog dosyaları bozulur. Zorla kapatma (kill -9) sırasında yarım kalan yazmalar da neden olabilir.","fix":"Öncelikle veriyi bir replikadan ya da snapshot'tan kurtarmayı deneyin; sağlıklı bir kopya varsa bozuk shard'ı ondan yeniden oluşturmak en güvenli yoldur. Başka kopya yoksa ve veri kaybını göze alıyorsanız düğümü durdurup bin/elasticsearch-shard remove-corrupted-data --index <indeks> --shard-id <n> aracıyla bozuk translog'u/verileri temizleyin (bu işlem henüz commit edilmemiş veriyi kalıcı olarak kaybettirir; eski elasticsearch-translog aracı 7.0'da kaldırıldı). Araç, düğüm yeniden başladıktan sonra shard'ı atamak için gereken POST _cluster/reroute (allocate_stale_primary, accept_data_loss: true) komutunu çıktısında verir. İşlemden önce veri dizininin yedeğini alın. Disk sağlığını ve alanını kontrol edin.","tags":["translog","shard","recovery","bozulma","snapshot","disk"]},{"code":"recovery_engine_exception","title":"recovery_engine_exception","severity":"danger","meaning":"Bir shard'ın kurtarma (recovery) süreci sırasında motor (engine) düzeyinde bir hata oluştu ve shard başarıyla açılamadı. Kurtarma; düğüm yeniden başlatma, replika ataması ya da snapshot geri yükleme sırasında yürütülen adımdır.","cause":"Kurtarma sırasında altta yatan bir sorun: bozuk Lucene segmentleri ya da translog, disk alanı yetersizliği, dosya izinleri, kaynak/hedef düğüm arasındaki ağ kesintisi, ya da sürüm/uyumsuzluk problemleri. Genellikle daha spesifik bir alt hatayı (corruption, I/O) sarmalar.","fix":"Alt/neden (caused_by) hatasını inceleyip asıl sorunu belirleyin (bozulma, disk, ağ vb.). Disk alanı ve dosya izinlerini doğrulayın. Replika ataması başarısızsa _cluster/allocation/explain ile nedenini görün ve gerekirse yeniden atamayı tetikleyin. Bozulma varsa sağlıklı bir replikadan/snapshot'tan kurtarın. Ağ kaynaklı ise düğümler arası bağlantıyı ve recovery ayarlarını kontrol edin.","tags":["recovery","shard","engine","allocation","bozulma","disk"]},{"code":"snapshot_in_progress_exception","title":"snapshot_in_progress_exception","severity":"caution","meaning":"Yürütülmeye çalışılan işlem, o an devam eden bir snapshot işlemiyle çakıştığı için reddedildi. Örneğin snapshot alınırken bir index'i silme/kapatma ya da depoyu (repository) değiştirme girişimi engellenir.","cause":"Bir snapshot hâlâ sürerken, o snapshot'a dahil index'leri silmek/kapatmak, depoyu kaldırmak/değiştirmek ya da çakışan başka bir snapshot/restore işlemi başlatmak istendi. Elasticsearch, tutarlılığı korumak için bu çakışan işlemlere izin vermez.","fix":"Devam eden snapshot'ın bitmesini bekleyin: GET _snapshot/_status ile ilerlemeyi izleyin. İşlem gerçekten iptal edilmeliyse snapshot'ı silerek durdurun: DELETE _snapshot/repo/snapshot_adi (bu, devam eden snapshot'ı iptal eder). Snapshot tamamlandıktan/iptal edildikten sonra asıl işleminizi (index silme, depo değişikliği) yeniden çalıştırın.","tags":["snapshot","repository","restore","indeks silme","cakisma","yedek"]},{"code":"repository_verification_exception","title":"repository_verification_exception","severity":"danger","meaning":"Bir snapshot repository kaydedilirken ya da doğrulanırken, tüm düğümlerin depoya erişebildiğinin denetimi başarısız oldu. Depo doğrulaması geçemediği için snapshot/restore işlemleri güvenilir biçimde yapılamaz.","cause":"Paylaşımlı dosya sistemi (fs) deposunun tüm düğümlerde aynı yola bağlı/erişilebilir olmaması, path.repo yapılandırmasının eksikliği, yetersiz dosya izinleri, ya da bulut/nesne depolarında (S3, GCS, Azure) hatalı kimlik bilgileri/ağ erişimi. Bazı düğümlerin depoya yazamaması tipik nedendir.","fix":"Paylaşımlı fs deposu için path.repo'nun tüm düğümlerin elasticsearch.yml dosyasında tanımlı ve aynı yolun her düğümde okunur/yazılabilir bağlı olduğundan emin olun. Dosya izinlerini (elasticsearch kullanıcısı) düzeltin. Bulut depolarında kimlik bilgilerini (keystore), bucket adını ve ağ/erişim izinlerini doğrulayın. Depoyu POST _snapshot/repo/_verify ile yeniden doğrulayın.","tags":["repository","snapshot","path.repo","izin","s3","dogrulama"]},{"code":"reduce_search_phase_exception","title":"reduce_search_phase_exception","severity":"danger","meaning":"Bir aramanın azaltma (reduce) aşamasında hata oluştu. Koordinatör düğüm, farklı shard'lardan gelen kısmi sonuçları/agregasyonları birleştirirken (reduce) bir sorunla karşılaştı ve nihai sonucu üretemedi.","cause":"Genellikle sonuçların birleştirilmesi sırasında bellek/kaynak sınırının aşılması (ör. çok büyük agregasyonlar, circuit breaker tetiklemesi), uyumsuz/geçersiz agregasyon yapısı, ya da bir shard'ın döndürdüğü kısmi sonucun birleştirilememesi. Aşırı yüksek kardinaliteli agregasyonlarda sık görülür.","fix":"caused_by ayrıntısını okuyup asıl nedeni belirleyin. Ağır agregasyonları hafifletin: yüksek kardinaliteli terms agregasyonlarında size'ı düşürün, composite aggregation ile sayfalayın, gereksiz alt agregasyonları azaltın. Bellek baskısını izleyin ve gerekirse sorguyu daha küçük parçalara bölün. Circuit breaker tetikleniyorsa sorgu maliyetini düşürün.","tags":["search","reduce","aggregation","koordinator","bellek","kardinalite"]},{"code":"aggregation_execution_exception","title":"aggregation_execution_exception","severity":"caution","meaning":"Bir agregasyon çalıştırılırken yürütme (execution) sırasında hata oluştu. Agregasyonun tanımı ayrıştırılmış olsa da, çalışma zamanında hedef alanların/değerlerin işlenmesinde bir sorun ortaya çıktı.","cause":"Agregasyonun alan türüyle uyumsuz olması (ör. metin alanı üzerinde fielddata olmadan agregasyon), sıralama/hesaplama sırasında geçersiz değerler, pipeline agregasyonlarında var olmayan bir yola (bucket path) başvuru, ya da desteklenmeyen alan türü kombinasyonları. Script tabanlı agregasyonlardaki çalışma zamanı hataları da tetikler.","fix":"Hata ayrıntısındaki alan/agregasyon adını inceleyin. Agregasyon yapılacak alanların uygun türde olduğundan emin olun (metin yerine keyword/numeric; gerekiyorsa doc_values etkin alanlar kullanın). Pipeline agregasyonlarında buckets_path'in gerçek bucket adlarıyla eşleştiğini doğrulayın. Script agregasyonlarında null/tür kontrolleri ekleyin. Uygun alan türleriyle mapping'i düzeltin.","tags":["aggregation","execution","fielddata","keyword","pipeline","mapping"]},{"code":"failed_node_exception","title":"failed_node_exception","severity":"danger","meaning":"Bir kümesel işlem (ör. arama, istatistik, yönetim komutu) sırasında, kümedeki belirli bir düğüm isteği işleyemedi ya da yanıt veremedi. Koordinatör düğüm o düğümden gelen başarısızlığı bu istisnayla sarmalar.","cause":"İlgili düğümün çökmesi, ağdan kopması, aşırı yük/GC duraklamaları nedeniyle yanıt verememesi, disk/kaynak sorunları ya da o düğümdeki bir shard hatası. Küme yeniden yapılanması (düğüm ayrılması/katılması) sırasında da geçici olarak görülebilir.","fix":"caused_by ile hangi düğümde ve neden başarısız olunduğunu belirleyin. Düğüm sağlığını kontrol edin: GET _cat/nodes, GET _nodes/stats (CPU, bellek, GC, disk). Düğüm kaynak baskısı altındaysa yükü/heap ayarlarını gözden geçirin; ağ bağlantısını doğrulayın. Düğüm kümeden ayrıldıysa yeniden katılmasını ve shard atamalarının toparlanmasını (GET _cluster/health) bekleyin.","tags":["node","cluster","ag","gc","shard","kaynak"]},{"code":"elasticsearch_parse_exception","title":"elasticsearch_parse_exception","severity":"caution","meaning":"Elasticsearch, gönderilen isteğin gövdesini (JSON sorgu, ayar ya da yapılandırma) ayrıştırırken genel bir çözümleme hatasıyla karşılaştı. İstek yapısal olarak beklenen biçime uymuyor.","cause":"Bozuk/geçersiz JSON (eksik virgül, kapatılmamış parantez), yanlış yerleştirilmiş alanlar, beklenmeyen değer türleri (ör. sayı beklenen yere metin), ya da geçersiz bir zaman/aralık ifadesi. Bir DSL sorgusunun yanlış iç içe yapılandırılması da bu istisnayı üretir.","fix":"İstek gövdesini geçerli bir JSON doğrulayıcıdan geçirin; parantez, tırnak ve virgülleri denetleyin. Alanların doğru yerde ve doğru türde olduğunu Elasticsearch DSL belgelerine göre kontrol edin. Hata mesajındaki konum/alan ipucunu kullanarak sorunlu kısmı düzeltin. İstemci kütüphanesi kullanıyorsanız serileştirmenin geçerli JSON ürettiğinden emin olun.","tags":["parse","json","dsl","sorgu","ayrıştırma","istek"]}]},"health/oracle.json":{"engineId":"oracle","engine":"Oracle","order":1,"checks":[{"id":"version-uptime","group":"Genel","title":"Sürüm ve çalışma süresi (uptime)","command":"SELECT i.instance_name, i.version_full, i.status, i.startup_time, ROUND(SYSDATE - i.startup_time, 2) AS uptime_days FROM v$instance i;","expect":"Instance durumu OPEN olmalı. startup_time beklenmedik şekilde yakınsa (yeni açılış) plansız bir yeniden başlatma yaşanmış olabilir; araştırın. version_full kolonu 18c+ içindir; 12c ve öncesinde version kolonunu kullanın.","severity":"safe"},{"id":"alertlog-errors","group":"Genel","title":"Alert log içindeki son kritik hatalar (ORA-)","command":"SELECT originating_timestamp, message_text FROM v$diag_alert_ext WHERE message_text LIKE '%ORA-%' AND originating_timestamp > SYSTIMESTAMP - INTERVAL '1' DAY ORDER BY originating_timestamp DESC FETCH FIRST 50 ROWS ONLY;","expect":"Son 24 saatte ORA- hatası dönmemeli. ORA-00600, ORA-07445, ORA-01578 (block corruption) gibi kayıtlar acil müdahale gerektirir.","severity":"danger"},{"id":"invalid-objects","group":"Genel","title":"Geçersiz (INVALID) nesneler","command":"SELECT owner, object_type, COUNT(*) AS invalid_count FROM dba_objects WHERE status = 'INVALID' GROUP BY owner, object_type ORDER BY invalid_count DESC;","expect":"İdeal olarak hiç INVALID nesne olmamalı. Varsa EXEC DBMS_UTILITY.COMPILE_SCHEMA veya utlrp.sql ile derleyin; SYS/SYSTEM altındaki bozulmalar öncelikli.","severity":"caution"},{"id":"tablespace-usage","group":"Kapasite","title":"Tablespace doluluk oranı","command":"SELECT df.tablespace_name, ROUND(df.total_mb, 1) AS total_mb, ROUND(df.total_mb - NVL(fs.free_mb, 0), 1) AS used_mb, ROUND((df.total_mb - NVL(fs.free_mb, 0)) / df.total_mb * 100, 1) AS pct_used FROM (SELECT tablespace_name, SUM(bytes)/1024/1024 total_mb FROM dba_data_files GROUP BY tablespace_name) df LEFT JOIN (SELECT tablespace_name, SUM(bytes)/1024/1024 free_mb FROM dba_free_space GROUP BY tablespace_name) fs ON df.tablespace_name = fs.tablespace_name ORDER BY pct_used DESC;","expect":"pct_used %85 üzeri uyarı, %90 üzeri kritik eşiktir. autoextend kapalı tablespace'lerde dolma riski daha yüksektir; datafile ekleyin veya autoextend açın.","severity":"danger"},{"id":"largest-segments","group":"Kapasite","title":"En büyük segmentler (tablo/index)","command":"SELECT owner, segment_name, segment_type, ROUND(bytes/1024/1024/1024, 2) AS size_gb FROM dba_segments ORDER BY bytes DESC FETCH FIRST 20 ROWS ONLY;","expect":"En çok yer kaplayan segmentleri gösterir. Beklenmedik büyümeler arşivleme/temizleme veya bölümleme (partitioning) ihtiyacına işaret edebilir.","severity":"safe"},{"id":"undo-temp-usage","group":"Kapasite","title":"UNDO ve TEMP tablespace kullanımı","command":"SELECT ts.tablespace_name, ts.contents, ROUND(SUM(ss.used_blocks) * ts.block_size / 1024 / 1024, 1) AS used_mb FROM v$sort_segment ss JOIN (SELECT tablespace_name, contents, block_size FROM dba_tablespaces WHERE contents = 'TEMPORARY') ts ON ss.tablespace_name = ts.tablespace_name GROUP BY ts.tablespace_name, ts.contents, ts.block_size UNION ALL SELECT tablespace_name, 'UNDO', ROUND(SUM(bytes)/1024/1024, 1) FROM dba_undo_extents WHERE status = 'ACTIVE' GROUP BY tablespace_name;","expect":"TEMP kullanımı sürekli tavan yapıyorsa büyük sıralama/hash işlemleri vardır. UNDO active alanı retention'ı karşılamıyorsa ORA-01555 (snapshot too old) riski oluşur.","severity":"caution"},{"id":"sessions-vs-limit","group":"Kapasite","title":"Oturum sayısı ve limit karşılaştırması","command":"SELECT resource_name, current_utilization, max_utilization, limit_value FROM v$resource_limit WHERE resource_name IN ('sessions','processes','transactions');","expect":"current_utilization limit_value'ya yaklaşıyorsa (özellikle %85 üzeri) yeni bağlantılar reddedilebilir. max_utilization tarihsel tepe noktasını gösterir; processes parametresini gözden geçirin.","severity":"caution"},{"id":"fra-usage","group":"Kapasite","title":"Flash Recovery Area (FRA) doluluğu","command":"SELECT name, ROUND(space_limit/1024/1024/1024, 2) AS limit_gb, ROUND(space_used/1024/1024/1024, 2) AS used_gb, ROUND(space_used/space_limit*100, 1) AS pct_used FROM v$recovery_file_dest;","expect":"FRA %85'e ulaşınca alert log'a uyarı düşer; %100 dolduğunda arşiv log yazımı durur ve veritabanı asılır (archiver hung, ORA-00257). RMAN yedek/arşiv temizliği yapın veya db_recovery_file_dest_size artırın.","severity":"danger"},{"id":"buffer-cache-hit","group":"Performans","title":"Buffer cache hit oranı","command":"SELECT ROUND((1 - (phy.value - dir.value) / (con.value + cur.value)) * 100, 2) AS buffer_hit_ratio FROM v$sysstat con, v$sysstat cur, v$sysstat phy, v$sysstat dir WHERE con.name = 'consistent gets' AND cur.name = 'db block gets' AND phy.name = 'physical reads' AND dir.name = 'physical reads direct';","expect":"OLTP sistemlerde tipik olarak %90 üzeri beklenir. Sürekli düşük değerler yetersiz SGA/buffer cache veya kötü indeksleme işareti olabilir; tek başına değil wait event'lerle birlikte yorumlayın.","severity":"safe"},{"id":"top-sql","group":"Performans","title":"En maliyetli SQL sorguları (elapsed time)","command":"SELECT sql_id, ROUND(elapsed_time/1000000, 1) AS elapsed_sec, executions, ROUND(elapsed_time/1000000/GREATEST(executions,1), 3) AS sec_per_exec, SUBSTR(sql_text, 1, 100) AS sql_text FROM v$sqlarea ORDER BY elapsed_time DESC FETCH FIRST 15 ROWS ONLY;","expect":"Toplam elapsed time'ı en yüksek sorgular. sec_per_exec yüksek ya da executions çok yüksek olanlar tuning adayıdır; AWR/SQL Tuning Advisor ile inceleyin.","severity":"safe"},{"id":"long-active-sessions","group":"Performans","title":"Uzun süren aktif oturumlar","command":"SELECT s.sid, s.serial#, s.username, s.status, s.last_call_et AS active_seconds, s.event, SUBSTR(q.sql_text, 1, 80) AS sql_text FROM v$session s LEFT JOIN v$sqlarea q ON s.sql_id = q.sql_id WHERE s.status = 'ACTIVE' AND s.type = 'USER' AND s.last_call_et > 60 ORDER BY s.last_call_et DESC;","expect":"last_call_et (saniye) çok yüksek olan aktif oturumlar takılmış ya da ağır sorgu çalıştırıyor olabilir. event alanı beklenen kaynağı gösterir.","severity":"caution"},{"id":"blocking-sessions","group":"Performans","title":"Bloklayan ve beklenen oturumlar (lock'lar)","command":"SELECT bs.sid AS blocker_sid, bs.username AS blocker_user, ws.sid AS waiter_sid, ws.username AS waiter_user, ws.seconds_in_wait, ws.event FROM v$session ws JOIN v$session bs ON ws.blocking_session = bs.sid WHERE ws.blocking_session IS NOT NULL ORDER BY ws.seconds_in_wait DESC;","expect":"Hiç satır dönmemeli. Bloklayan oturumlar uygulamada gecikme/deadlock yaratır; blocker_sid uzun süre lock tutuyorsa (seconds_in_wait büyük) uygulama ekibiyle değerlendirip gerekirse ALTER SYSTEM KILL SESSION yapın.","severity":"danger"},{"id":"rman-last-backup","group":"Yedek & Kurtarma","title":"Son başarılı RMAN yedek durumu","command":"SELECT input_type, status, start_time, end_time, ROUND(output_bytes/1024/1024/1024, 2) AS output_gb FROM v$rman_backup_job_details ORDER BY start_time DESC FETCH FIRST 10 ROWS ONLY;","expect":"En son yedek status = COMPLETED olmalı ve start_time RPO politikanıza uygun tazelikte (ör. son 24 saat) olmalı. FAILED veya 'COMPLETED WITH WARNINGS' kayıtları incelenmeli.","severity":"danger"},{"id":"archivelog-mode","group":"Yedek & Kurtarma","title":"Arşiv log modu ve archiver durumu","command":"SELECT log_mode, force_logging, (SELECT COUNT(*) FROM v$archived_log WHERE first_time > SYSDATE - 1) AS logs_last_24h FROM v$database;","expect":"Üretim veritabanında log_mode = ARCHIVELOG olmalı (aksi halde point-in-time recovery mümkün değildir). Son 24 saatte arşiv üretilmiyorsa archiver takılmış olabilir.","severity":"danger"},{"id":"locked-expired-accounts","group":"Güvenlik","title":"Kilitli veya süresi dolmuş hesaplar","command":"SELECT username, account_status, lock_date, expiry_date, profile FROM dba_users WHERE account_status != 'OPEN' ORDER BY username;","expect":"LOCKED/EXPIRED kritik uygulama hesapları beklenmedik kesintiye yol açar. Varsayılan hesapların (SCOTT, HR vb.) kilitli/kapalı olması iyidir. EXPIRED(GRACE) yaklaşan parola bitişini gösterir.","severity":"caution"},{"id":"privileged-users","group":"Güvenlik","title":"Yüksek yetkili (DBA rolü) kullanıcılar","command":"SELECT grantee, granted_role, admin_option FROM dba_role_privs WHERE granted_role IN ('DBA','PDB_DBA') AND grantee NOT IN ('SYS','SYSTEM') ORDER BY grantee;","expect":"DBA rolü yalnızca gerekli ve bilinen hesaplarda olmalı. Beklenmedik grantee'ler ya da admin_option = YES olanlar yetki yükseltme riskidir; en az yetki ilkesine göre gözden geçirin. SYSDBA/SYSOPER yetkili hesaplar için ayrıca: SELECT username, sysdba, sysoper FROM v$pwfile_users;","severity":"caution"},{"id":"default-password-users","group":"Güvenlik","title":"Varsayılan parolası değiştirilmemiş açık hesaplar","command":"SELECT du.username, du.account_status, du.profile, CASE WHEN dp.username IS NOT NULL THEN 'YES' ELSE 'NO' END AS has_default_password FROM dba_users du LEFT JOIN (SELECT username FROM dba_users_with_defpwd) dp ON du.username = dp.username WHERE du.account_status = 'OPEN' ORDER BY du.username;","expect":"has_default_password = YES olan hesapların parolası hemen değiştirilmeli ya da hesap kilitlenmeli (ALTER USER ... ACCOUNT LOCK). Parola ömrü politikası için DBA_PROFILES'ta PASSWORD_LIFE_TIME değerini ayrıca kontrol edin.","severity":"caution"},{"id":"dataguard-lag","group":"Replikasyon","title":"Data Guard standby gecikmesi (lag)","command":"SELECT name, value, unit, time_computed FROM v$dataguard_stats WHERE name IN ('apply lag','transport lag');","expect":"apply lag ve transport lag mümkün olduğunca 0'a yakın olmalı. Dakikalar/saatler mertebesinde lag, network veya MRP (Managed Recovery Process) sorununa işarettir; failover hedefi risk altındadır.","severity":"danger"},{"id":"dataguard-mrp","group":"Replikasyon","title":"Standby uygulama süreci (MRP) durumu","command":"SELECT name, role, action, thread#, sequence#, block# FROM v$dataguard_process WHERE name LIKE 'MRP%' OR role LIKE 'RFS%' ORDER BY name;","expect":"Physical standby'da MRP0 süreci görünmeli ve action APPLYING_LOG veya WAIT_FOR_LOG olmalı. Hiç MRP yoksa apply durmuştur; RFS yoksa primary'den log gelmiyor demektir. v$dataguard_process 12.2+ içindir; 12.1 ve öncesinde kullanımdan kaldırılmış (deprecated) v$managed_standby (process, status kolonları) kullanılır.","severity":"danger"}]},"health/postgres.json":{"engineId":"postgres","engine":"PostgreSQL","order":2,"checks":[{"id":"version-uptime","group":"Genel","title":"Sürüm ve çalışma süresi (uptime)","command":"SELECT version() AS pg_version, pg_postmaster_start_time() AS started_at, date_trunc('second', now() - pg_postmaster_start_time()) AS uptime;","expect":"Sürüm ve başlatılma zamanını gösterir. uptime beklenmedik şekilde kısaysa (yeni başlatma) plansız bir yeniden başlatma veya çökme yaşanmış olabilir; log'ları kontrol edin.","severity":"safe"},{"id":"recent-errors","group":"Genel","title":"Checkpoint istatistikleri","command":"-- PG17+:\nSELECT num_timed, num_requested, buffers_written, stats_reset FROM pg_stat_checkpointer;\n-- PG16 ve öncesi:\nSELECT checkpoints_timed, checkpoints_req, buffers_checkpoint, buffers_backend, stats_reset FROM pg_stat_bgwriter;","expect":"İstek üzerine checkpoint sayısı (num_requested / checkpoints_req) zamanlanmış olanlara (num_timed / checkpoints_timed) göre yüksekse WAL çok hızlı doluyor demektir; max_wal_size artırın. Sayaçlar PG17'de pg_stat_bgwriter'dan pg_stat_checkpointer'a taşındı.","severity":"caution"},{"id":"table-bloat","group":"Genel","title":"Bloat'lı tablolar ve dead tuple oranı","command":"SELECT schemaname, relname, n_live_tup, n_dead_tup, CASE WHEN n_live_tup > 0 THEN round(n_dead_tup * 100.0 / n_live_tup, 1) ELSE 0 END AS dead_pct, last_autovacuum FROM pg_stat_user_tables WHERE n_dead_tup > 1000 ORDER BY n_dead_tup DESC LIMIT 20;","expect":"dead_pct yüksek (ör. %20 üzeri) tablolar şişmiştir; VACUUM performansı ve disk kullanımını etkiler. last_autovacuum çok eskiyse autovacuum ayarlarını gözden geçirin veya manuel VACUUM (ANALYZE) çalıştırın.","severity":"caution"},{"id":"database-size","group":"Kapasite","title":"Veritabanı boyutları","command":"SELECT datname, pg_size_pretty(pg_database_size(datname)) AS size, pg_database_size(datname) AS size_bytes FROM pg_database WHERE datistemplate = false ORDER BY pg_database_size(datname) DESC;","expect":"Veritabanı boyutlarını gösterir. Beklenmedik büyümeleri disk kapasitesiyle (df -h) birlikte değerlendirin; PostgreSQL disk dolunca yazma işlemlerini durdurur.","severity":"danger"},{"id":"largest-tables","group":"Kapasite","title":"En büyük tablolar (index dahil)","command":"SELECT schemaname, relname, pg_size_pretty(pg_total_relation_size(relid)) AS total_size, pg_size_pretty(pg_relation_size(relid)) AS table_size, pg_size_pretty(pg_total_relation_size(relid) - pg_relation_size(relid)) AS index_toast_size FROM pg_catalog.pg_statio_user_tables ORDER BY pg_total_relation_size(relid) DESC LIMIT 20;","expect":"En çok yer kaplayan tabloları gösterir. index_toast_size tablo boyutundan çok büyükse aşırı/kullanılmayan index olabilir; arşivleme veya bölümleme (partitioning) değerlendirin.","severity":"safe"},{"id":"temp-files","group":"Kapasite","title":"Geçici (temp) dosya kullanımı","command":"SELECT datname, temp_files, pg_size_pretty(temp_bytes) AS temp_size, stats_reset FROM pg_stat_database WHERE temp_files > 0 ORDER BY temp_bytes DESC;","expect":"Yüksek temp_files/temp_bytes, work_mem'in yetersiz olduğunu ve sıralama/hash işlemlerinin diske taştığını gösterir. work_mem artırmayı veya sorguları optimize etmeyi değerlendirin.","severity":"caution"},{"id":"connections-vs-limit","group":"Kapasite","title":"Bağlantı sayısı ve max_connections limiti","command":"SELECT (SELECT count(*) FROM pg_stat_activity WHERE backend_type = 'client backend') AS current_connections, (SELECT setting::int FROM pg_settings WHERE name = 'max_connections') AS max_connections, round((SELECT count(*) FROM pg_stat_activity WHERE backend_type = 'client backend') * 100.0 / (SELECT setting::int FROM pg_settings WHERE name = 'max_connections'), 1) AS pct_used;","expect":"Yalnızca istemci bağlantıları sayılır (pg_stat_activity arka plan süreçlerini de içerdiği için backend_type = 'client backend' filtresi gerekir). pct_used %80 üzerine çıkarsa yeni bağlantılar reddedilme riski taşır (özellikle superuser_reserved_connections sonrası). Bağlantı havuzu (PgBouncer) kullanımı önerilir.","severity":"caution"},{"id":"wal-directory-size","group":"Kapasite","title":"WAL dizini boyutu ve replication slot birikimi","command":"SELECT (SELECT count(*) FROM pg_ls_waldir()) AS wal_file_count, pg_size_pretty((SELECT sum(size) FROM pg_ls_waldir())) AS wal_total_size, slot_name, active, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS retained_wal FROM pg_replication_slots ORDER BY slot_name;","expect":"Aktif olmayan (active = false) replication slot'lar WAL birikmesine ve pg_wal dizininin dolmasına yol açar. retained_wal büyükse slot'un sahibini doğrulayın (slot_type, database, plugin): active = false geçici olarak kopmuş bir standby'ı ya da logical abone/CDC (ör. Debezium) slot'unu da gösterebilir. Gerçekten kullanılmıyorsa pg_drop_replication_slot ile silin; silinen slot'a bağlı standby yeniden kurulmalı, abone/CDC tarafı yeniden senkronize edilmelidir. Kalıcı koruma için max_slot_wal_keep_size (PG13+) ile üst sınır koyun.","severity":"danger"},{"id":"cache-hit-ratio","group":"Performans","title":"Buffer cache hit oranı","command":"SELECT sum(heap_blks_read) AS heap_read, sum(heap_blks_hit) AS heap_hit, round(sum(heap_blks_hit) * 100.0 / NULLIF(sum(heap_blks_hit) + sum(heap_blks_read), 0), 2) AS cache_hit_ratio FROM pg_statio_user_tables;","expect":"OLTP iş yüklerinde tipik olarak %99 üzeri hedeflenir. Sürekli düşük değer, shared_buffers'ın yetersiz olduğunu veya çalışma setinin belleğe sığmadığını gösterebilir.","severity":"safe"},{"id":"top-queries","group":"Performans","title":"En maliyetli sorgular (pg_stat_statements)","command":"SELECT round(total_exec_time::numeric, 1) AS total_ms, calls, round(mean_exec_time::numeric, 2) AS mean_ms, round((100 * total_exec_time / sum(total_exec_time) OVER ())::numeric, 1) AS pct, left(query, 100) AS query FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 15;","expect":"pg_stat_statements shared_preload_libraries içinde olmalı (restart gerekir) ve veritabanında kurulmalıdır (CREATE EXTENSION pg_stat_statements). total_exec_time/mean_exec_time adları PG13+ içindir; PG12'de total_time/mean_time kullanılır. Toplam süreyi en çok tüketen sorgular tuning adayıdır; mean_ms yüksek olanlar için EXPLAIN ANALYZE çalıştırın.","severity":"safe"},{"id":"long-running-queries","group":"Performans","title":"Uzun süren aktif sorgular","command":"SELECT pid, usename, state, now() - query_start AS duration, wait_event_type, wait_event, left(query, 80) AS query FROM pg_stat_activity WHERE state = 'active' AND now() - query_start > interval '1 minute' AND backend_type = 'client backend' ORDER BY duration DESC;","expect":"1 dakikadan uzun süren aktif sorgular takılmış veya ağır olabilir. wait_event ne beklendiğini gösterir. Bu sorgu yalnızca aktif sorguları listeler; 'idle in transaction' oturumlar (VACUUM'un dead tuple'ları temizlemesini engeller) için state = 'idle in transaction' ve xact_start ile ayrıca bakın.","severity":"caution"},{"id":"blocking-locks","group":"Performans","title":"Bloklayan oturumlar ve bekleyen lock'lar","command":"SELECT blocked.pid AS blocked_pid, blocked.usename AS blocked_user, blocking.pid AS blocking_pid, blocking.usename AS blocking_user, now() - blocked.query_start AS blocked_duration, left(blocked.query, 60) AS blocked_query FROM pg_stat_activity blocked JOIN pg_stat_activity blocking ON blocking.pid = ANY(pg_blocking_pids(blocked.pid)) WHERE cardinality(pg_blocking_pids(blocked.pid)) > 0;","expect":"Hiç satır dönmemeli. Bloklayan oturumlar (blocking_pid) uygulama gecikmelerine ve zaman aşımlarına yol açar; uzun süredir bloklayan transaction'ı araştırıp gerekirse pg_terminate_backend ile sonlandırın.","severity":"danger"},{"id":"archiver-status","group":"Yedek & Kurtarma","title":"WAL arşivleme sağlığı (pg_stat_archiver)","command":"SELECT archived_count, last_archived_wal, last_archived_time, failed_count, last_failed_wal, last_failed_time, now() - last_archived_time AS since_last_archive FROM pg_stat_archiver;","expect":"failed_count 0 olmalı ve last_failed_time last_archived_time'dan eski olmalı. since_last_archive çok büyükse arşivleme durmuştur (archive_command hatası); PITR yedek zinciri kırılır.","severity":"danger"},{"id":"last-basebackup","group":"Yedek & Kurtarma","title":"Son yedek ve WAL arşivi tazeliği","command":"-- Temel yedek zamanı veritabanında tutulmaz; yedek aracından okuyun: pgbackrest info / barman list-backup <sunucu>\nSELECT pg_is_in_recovery() AS in_recovery, last_archived_wal, last_archived_time, now() - last_archived_time AS since_last_archive, failed_count, last_failed_time FROM pg_stat_archiver;","expect":"Son temel yedeğin zamanını yedek aracından (pgBackRest / Barman / pg_basebackup iş logları) doğrulayın; RPO politikanıza uygun tazelikte olmalı. PITR için WAL arşivi de kesintisiz olmalıdır: since_last_archive büyükse veya failed_count artıyorsa arşiv zinciri kırılmış olabilir.","severity":"danger"},{"id":"locked-expired-roles","group":"Güvenlik","title":"Süresi dolmuş veya giriş yapamayan roller","command":"SELECT rolname, rolcanlogin, rolvaliduntil, rolconnlimit FROM pg_roles WHERE rolcanlogin = true AND (rolvaliduntil IS NOT NULL AND rolvaliduntil < now() + interval '7 days') ORDER BY rolvaliduntil;","expect":"rolvaliduntil geçmiş olan uygulama rollerinin girişi engellenir ve kesinti yaratır. Önümüzdeki 7 gün içinde dolacak parolalar için önceden yenileme planlayın.","severity":"caution"},{"id":"superuser-roles","group":"Güvenlik","title":"Yüksek yetkili (SUPERUSER / yaratma) roller","command":"SELECT rolname, rolsuper, rolcreaterole, rolcreatedb, rolbypassrls FROM pg_roles WHERE rolsuper = true OR rolcreaterole = true OR rolbypassrls = true ORDER BY rolsuper DESC, rolname;","expect":"SUPERUSER yalnızca gerekli ve bilinen hesaplarda olmalı. rolbypassrls = true olanlar satır seviyesi güvenliği (RLS) atlar; beklenmedik yüksek yetkiler en az yetki ilkesine göre kaldırılmalıdır.","severity":"caution"},{"id":"hba-trust-auth","group":"Güvenlik","title":"Zayıf kimlik doğrulama (trust) kuralları","command":"SELECT type, database, user_name, address, auth_method FROM pg_hba_file_rules WHERE auth_method IN ('trust','password') ORDER BY line_number;","expect":"auth_method = trust parolasız erişime izin verir ve üretimde tehlikelidir; 'password' ise parolayı düz metin gönderir. Bunları scram-sha-256 ile değiştirin. (PG 10+ gerektirir.)","severity":"danger"},{"id":"replication-lag","group":"Replikasyon","title":"Streaming replikasyon gecikmesi (primary tarafı)","command":"SELECT client_addr, state, sync_state, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), sent_lsn)) AS sent_lag, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn)) AS replay_lag, write_lag, flush_lag, replay_lag AS replay_time_lag FROM pg_stat_replication ORDER BY client_addr;","expect":"Primary'de çalıştırılır. state = streaming olmalı ve replay_lag (bayt/süre) küçük olmalı. Standby hiç görünmüyorsa bağlantı kopmuştur; sync_state = async ise senkron replikasyon beklendiği gibi çalışmıyordur.","severity":"danger"},{"id":"replica-lag-standby","group":"Replikasyon","title":"Standby tarafı replikasyon gecikmesi","command":"SELECT pg_is_in_recovery() AS in_recovery, CASE WHEN pg_is_in_recovery() THEN date_trunc('second', now() - pg_last_xact_replay_timestamp()) ELSE NULL END AS replication_delay, pg_last_wal_receive_lsn() AS receive_lsn, pg_last_wal_replay_lsn() AS replay_lsn;","expect":"Standby sunucuda çalıştırılır. in_recovery = true olmalı. replication_delay dakikalar/saatler mertebesindeyse apply gecikmesi olabilir; ancak primary'de yazma yokken de bu değer büyür (yanlış alarm), bu yüzden LSN farkıyla birlikte yorumlayın; receive_lsn ile replay_lsn arasındaki fark büyükse WAL uygulaması yetişemiyordur.","severity":"danger"}]},"health/mysql.json":{"engineId":"mysql","engine":"MySQL","order":3,"checks":[{"id":"version-uptime","group":"Genel","title":"Sürüm ve çalışma süresi (uptime)","command":"SELECT VERSION() AS mysql_version, VARIABLE_VALUE AS uptime_seconds, ROUND(VARIABLE_VALUE/86400, 2) AS uptime_days FROM performance_schema.global_status WHERE VARIABLE_NAME = 'Uptime';","expect":"Sürüm ve saniye cinsinden çalışma süresini gösterir. uptime_seconds beklenmedik şekilde küçükse plansız bir yeniden başlatma veya çökme yaşanmış olabilir; error log'u inceleyin.","severity":"safe"},{"id":"error-log-status","group":"Genel","title":"Son error log kayıtları (performance_schema)","command":"SELECT logged, prio, error_code, subsystem, LEFT(data, 120) AS message FROM performance_schema.error_log WHERE prio IN ('Error','Warning') ORDER BY logged DESC LIMIT 30;","expect":"Son hata ve uyarıları gösterir (MySQL 8.0+ gerektirir). prio = 'Error' kayıtları (özellikle InnoDB, lock, disk hataları) araştırılmalı. Eski sürümlerde sunucunun log_error dosyasına bakın.","severity":"danger"},{"id":"crashed-tables","group":"Genel","title":"Bozuk / kontrol edilmesi gereken tablolar","command":"SELECT table_schema, table_name, engine, table_rows, update_time FROM information_schema.tables WHERE table_schema NOT IN ('mysql','information_schema','performance_schema','sys') AND engine IS NOT NULL ORDER BY table_schema, table_name;","expect":"Tablo motoru ve son güncelleme zamanını listeler. MyISAM tablolar çökebilir; şüphede CHECK TABLE ... veya mysqlcheck ile bütünlük doğrulayın. Kritik veriler için InnoDB kullanımı önerilir.","severity":"caution"},{"id":"schema-sizes","group":"Kapasite","title":"Şema (veritabanı) boyutları","command":"SELECT table_schema, ROUND(SUM(data_length + index_length)/1024/1024, 1) AS size_mb, ROUND(SUM(data_free)/1024/1024, 1) AS free_mb FROM information_schema.tables GROUP BY table_schema ORDER BY SUM(data_length + index_length) DESC;","expect":"Şema boyutlarını ve geri kazanılabilir data_free alanını gösterir. Disk kapasitesiyle birlikte değerlendirin; free_mb yüksekse OPTIMIZE TABLE ile alan geri kazanılabilir.","severity":"danger"},{"id":"largest-tables","group":"Kapasite","title":"En büyük tablolar (data_free / fragmentasyon dahil)","command":"SELECT table_schema, table_name, engine, ROUND((data_length + index_length)/1024/1024, 1) AS total_mb, ROUND(data_free/1024/1024, 1) AS data_free_mb, table_rows FROM information_schema.tables WHERE table_schema NOT IN ('mysql','information_schema','performance_schema','sys') ORDER BY (data_length + index_length) DESC LIMIT 20;","expect":"En büyük tabloları gösterir. data_free_mb yüksek olan tablolar parçalanmıştır (fragmented); OPTIMIZE TABLE ile alan geri kazanılabilir. Aşırı büyük tablolarda bölümleme (partitioning) değerlendirin.","severity":"safe"},{"id":"innodb-tablespace","group":"Kapasite","title":"InnoDB tablespace ve geçici alan kullanımı","command":"SELECT FILE_NAME, TABLESPACE_NAME, ROUND(TOTAL_EXTENTS * EXTENT_SIZE / 1024 / 1024, 1) AS total_mb, ROUND((TOTAL_EXTENTS - FREE_EXTENTS) * EXTENT_SIZE / 1024 / 1024, 1) AS used_mb FROM information_schema.files WHERE FILE_TYPE = 'TABLESPACE' ORDER BY TOTAL_EXTENTS DESC LIMIT 20;","expect":"InnoDB data file'ların doluluğunu gösterir. innodb_file_per_table kapalıysa ibdata1 sürekli büyür ve küçülmez. Temp tablespace şişkinliği için ayrıca SHOW ENGINE INNODB STATUS çıktısına bakın.","severity":"caution"},{"id":"connections-vs-limit","group":"Kapasite","title":"Bağlantı sayısı ve max_connections limiti","command":"SELECT (SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME = 'Threads_connected') AS connected, (SELECT VARIABLE_VALUE FROM performance_schema.global_variables WHERE VARIABLE_NAME = 'max_connections') AS max_connections, (SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME = 'Max_used_connections') AS max_used, (SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME = 'Aborted_connects') AS aborted_connects;","expect":"max_used max_connections'a yaklaşıyorsa (%85 üzeri) 'Too many connections' hatası riski vardır. Yüksek aborted_connects kimlik doğrulama/ağ sorunlarına işaret eder; bağlantı havuzu kullanın.","severity":"caution"},{"id":"binlog-size","group":"Kapasite","title":"Binary log dosyaları ve toplam boyut","command":"SHOW BINARY LOGS;","expect":"Binlog dosyalarını ve boyutlarını listeler. Toplam boyut disk alanını zorluyorsa binlog_expire_logs_seconds ayarını (8.0 öncesinde expire_logs_days; bu değişken 8.0'da deprecated oldu, 8.4'te kaldırıldı) gözden geçirin; replikasyon kullanılıyorsa replica'lar okumadan silmeyin.","severity":"caution"},{"id":"buffer-pool-hit","group":"Performans","title":"InnoDB buffer pool hit oranı","command":"SELECT (SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME = 'Innodb_buffer_pool_read_requests') AS read_requests, (SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME = 'Innodb_buffer_pool_reads') AS disk_reads, ROUND((1 - (SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME = 'Innodb_buffer_pool_reads') / (SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME = 'Innodb_buffer_pool_read_requests')) * 100, 3) AS hit_ratio_pct;","expect":"hit_ratio_pct tipik olarak %99 üzeri hedeflenir. Sürekli düşükse innodb_buffer_pool_size yetersizdir; adanmış sunucuda RAM'in ~%70-80'ine kadar artırmayı değerlendirin (paylaşımlı sunucuda daha az).","severity":"safe"},{"id":"top-queries","group":"Performans","title":"En maliyetli sorgular (sys.statement_analysis)","command":"SELECT query, db, exec_count, total_latency, avg_latency, rows_sent_avg, rows_examined_avg FROM sys.statement_analysis ORDER BY total_latency DESC LIMIT 15;","expect":"sys şeması ve performance_schema açık olmalı. total_latency'yi en çok tüketen sorgular tuning adayıdır. rows_examined_avg, rows_sent_avg'den çok büyükse index eksikliği vardır; EXPLAIN ile inceleyin.","severity":"safe"},{"id":"long-running-queries","group":"Performans","title":"Uzun süren aktif sorgular","command":"SELECT id, user, host, db, command, time AS seconds, state, LEFT(info, 80) AS query FROM information_schema.processlist WHERE command != 'Sleep' AND time > 60 ORDER BY time DESC;","expect":"60 saniyeden uzun süren sorgular takılmış veya ağır olabilir. state alanı ne beklendiğini gösterir. 'Sleep' durumundaki uzun oturumlar da bağlantı havuzunu tüketir; gerekirse KILL <id> kullanın.","severity":"caution"},{"id":"blocking-locks","group":"Performans","title":"Bloklayan oturumlar ve bekleyen lock'lar","command":"SELECT r.trx_id AS waiting_trx, r.trx_mysql_thread_id AS waiting_thread, TIMESTAMPDIFF(SECOND, r.trx_wait_started, NOW()) AS wait_seconds, LEFT(r.trx_query, 60) AS waiting_query, b.trx_mysql_thread_id AS blocking_thread, LEFT(b.trx_query, 60) AS blocking_query FROM performance_schema.data_lock_waits w JOIN information_schema.innodb_trx r ON r.trx_id = w.requesting_engine_transaction_id JOIN information_schema.innodb_trx b ON b.trx_id = w.blocking_engine_transaction_id ORDER BY wait_seconds DESC;","expect":"Hiç satır dönmemeli. Bloklayan transaction (blocking_thread) uygulama gecikmesine ve lock wait timeout hatalarına yol açar. Uzun süredir bloklayan transaction'ı araştırıp gerekirse KILL ile sonlandırın. (MySQL 8.0 sözdizimi.)","severity":"danger"},{"id":"binlog-enabled","group":"Yedek & Kurtarma","title":"Binary log ve kurtarma ayarları","command":"SELECT (SELECT VARIABLE_VALUE FROM performance_schema.global_variables WHERE VARIABLE_NAME = 'log_bin') AS log_bin, (SELECT VARIABLE_VALUE FROM performance_schema.global_variables WHERE VARIABLE_NAME = 'binlog_format') AS binlog_format, (SELECT VARIABLE_VALUE FROM performance_schema.global_variables WHERE VARIABLE_NAME = 'sync_binlog') AS sync_binlog, (SELECT VARIABLE_VALUE FROM performance_schema.global_variables WHERE VARIABLE_NAME = 'innodb_flush_log_at_trx_commit') AS flush_log_commit;","expect":"Point-in-time recovery için log_bin = ON olmalı. Dayanıklılık için sync_binlog = 1 ve innodb_flush_log_at_trx_commit = 1 önerilir (aksi halde çökmede transaction kaybı olabilir). binlog_format = ROW replikasyon için en güvenlisidir.","severity":"danger"},{"id":"last-backup-note","group":"Yedek & Kurtarma","title":"Son yedek zamanı (binlog / araç göstergesi)","command":"SELECT (SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME = 'Uptime') AS uptime_seconds, (SELECT MAX(update_time) FROM information_schema.tables WHERE table_schema NOT IN ('mysql','information_schema','performance_schema','sys')) AS last_data_change;","expect":"MySQL yedek durumunu tek başına tutmaz; mysqldump / MySQL Shell dump / Percona XtraBackup araç loglarından (mysqlpump 8.0.34'te deprecated oldu, 8.4'te kaldırıldı) son başarılı yedek zamanını doğrulayın. Yedek, RPO politikanıza uygun tazelikte (ör. son 24 saat) olmalıdır.","severity":"danger"},{"id":"locked-expired-accounts","group":"Güvenlik","title":"Kilitli veya parolası süresi dolmuş hesaplar","command":"SELECT user, host, account_locked, password_expired, password_lifetime FROM mysql.user ORDER BY user, host;","expect":"account_locked = 'Y' veya password_expired = 'Y' olan kritik uygulama hesapları kesintiye yol açar. password_lifetime NULL ve global expire kapalıysa parola hiç dolmaz; politika boşluğu olabilir.","severity":"caution"},{"id":"anonymous-nopassword-users","group":"Güvenlik","title":"Anonim ve parolasız kullanıcılar","command":"SELECT user, host, plugin, IF(authentication_string = '', 'BOS_PAROLA', 'set') AS password_status FROM mysql.user WHERE user = '' OR authentication_string = '' ORDER BY host;","expect":"Hiç satır dönmemeli. Anonim kullanıcılar (user = '') ve parolasız hesaplar ciddi güvenlik açığıdır; mysql_secure_installation ile kaldırın veya güçlü parola atayın.","severity":"danger"},{"id":"super-privilege-users","group":"Güvenlik","title":"Yüksek yetkili (SUPER / GRANT) kullanıcılar","command":"SELECT grantee, privilege_type FROM information_schema.user_privileges WHERE privilege_type IN ('SUPER','GRANT OPTION','SHUTDOWN','FILE','CREATE USER') ORDER BY grantee, privilege_type;","expect":"SUPER, FILE ve GRANT OPTION gibi yetkiler yalnızca gerekli ve bilinen hesaplarda olmalı. Beklenmedik grantee'ler yetki yükseltme riskidir; % (herhangi bir host) ile tanımlı yüksek yetkili hesaplara özellikle dikkat edin.","severity":"caution"},{"id":"replica-status","group":"Replikasyon","title":"Replika (standby) durumu ve gecikmesi","command":"SHOW REPLICA STATUS;","expect":"Replika sunucuda çalıştırılır (MySQL 8.0.22+). Replica_IO_Running ve Replica_SQL_Running her ikisi de 'Yes' olmalı. Seconds_Behind_Source küçük olmalı; NULL ise replikasyon durmuştur. Last_Error alanını inceleyin. (Eski sürümlerde SHOW SLAVE STATUS.)","severity":"danger"},{"id":"replication-threads","group":"Replikasyon","title":"Replikasyon bağlantı ve uygulama durumu (performance_schema)","command":"SELECT c.channel_name, c.service_state AS io_state, a.service_state AS sql_state, c.last_error_message AS io_error, w.last_error_message AS sql_error FROM performance_schema.replication_connection_status c JOIN performance_schema.replication_applier_status a ON c.channel_name = a.channel_name LEFT JOIN performance_schema.replication_applier_status_by_coordinator w ON w.channel_name = a.channel_name;","expect":"io_state ve sql_state 'ON' olmalı. io_error/sql_error dolu ise replikasyon hata vermiştir ve durmuştur; çoklu kanal (multi-source) kurulumlarda her channel_name ayrı ayrı sağlıklı olmalıdır.","severity":"danger"}]},"health/mssql.json":{"engineId":"mssql","engine":"SQL Server","order":4,"checks":[{"id":"version-uptime","group":"Genel","title":"Sürüm ve çalışma süresi (uptime)","command":"SELECT @@VERSION AS surum, sqlserver_start_time AS baslangic_zamani, DATEDIFF(HOUR, sqlserver_start_time, GETDATE()) AS calisma_saati FROM sys.dm_os_sys_info;","expect":"Sürüm ve yama seviyesini doğrulayın. Çalışma süresi çok kısaysa (birkaç saatten az) beklenmedik bir yeniden başlatma yaşanmış olabilir; SQL Server error log'unu inceleyin.","severity":"safe"},{"id":"database-states","group":"Genel","title":"Sorunlu durumdaki veritabanları (SUSPECT / RECOVERY_PENDING)","command":"SELECT name AS veritabani, state_desc AS durum, recovery_model_desc AS kurtarma_modeli FROM sys.databases WHERE state_desc <> N'ONLINE' ORDER BY name;","expect":"Tüm üretim veritabanları ONLINE olmalıdır. SUSPECT, RECOVERY_PENDING veya EMERGENCY görülürse acil müdahale gerekir; kurtarma başlatın ve error log'u inceleyin.","severity":"danger"},{"id":"recent-errors","group":"Genel","title":"Son önemli hatalar (memory/error ring buffer)","command":"SELECT TOP 20 CAST(record AS XML).value('(//Record/@id)[1]', 'int') AS record_id, DATEADD(ms, timestamp - (SELECT ms_ticks FROM sys.dm_os_sys_info), GETDATE()) AS olay_zamani, CAST(record AS XML) AS kayit FROM sys.dm_os_ring_buffers WHERE ring_buffer_type = N'RING_BUFFER_EXCEPTION' ORDER BY timestamp DESC;","expect":"Son istisna/hata kayıtlarını inceleyin. Sık tekrarlayan 823/824/825 (I/O tutarlılık) hataları disk bozulmasına işaret eder. Ayrıntı için sunucuda xp_readerrorlog ile error log da okunmalıdır.","severity":"caution"},{"id":"data-log-file-usage","group":"Kapasite","title":"Veri ve log dosyası doluluğu","command":"SELECT DB_NAME() AS veritabani, name AS mantiksal_ad, type_desc AS dosya_tipi, size/128.0 AS ayrilan_mb, CAST(FILEPROPERTY(name, 'SpaceUsed') AS INT)/128.0 AS kullanilan_mb, (size - CAST(FILEPROPERTY(name, 'SpaceUsed') AS INT))/128.0 AS bos_mb, CASE WHEN max_size = -1 THEN N'Sinirsiz' WHEN max_size = 268435456 THEN N'2 TB (log)' ELSE CAST(max_size/128 AS VARCHAR(20)) + N' MB' END AS azami_boyut FROM sys.database_files;","expect":"Her veritabanında çalıştırın. Kullanılan alan ayrılan alana çok yaklaştıysa (%85+) ve autogrowth sınırlıysa büyüme veya disk ekleme planlayın. Log dosyası sürekli doluysa yedekleme/recovery model ayarını gözden geçirin.","severity":"caution"},{"id":"largest-tables","group":"Kapasite","title":"En büyük tablolar (boyut ve satır sayısı)","command":"SELECT TOP 20 s.name AS sema, t.name AS tablo, p.rows AS satir_sayisi, SUM(a.total_pages)*8/1024 AS toplam_mb, SUM(a.used_pages)*8/1024 AS kullanilan_mb FROM sys.tables t JOIN sys.schemas s ON t.schema_id = s.schema_id JOIN sys.indexes i ON t.object_id = i.object_id JOIN sys.partitions p ON i.object_id = p.object_id AND i.index_id = p.index_id JOIN sys.allocation_units a ON p.partition_id = a.container_id WHERE i.index_id <= 1 GROUP BY s.name, t.name, p.rows ORDER BY toplam_mb DESC;","expect":"En çok yer kaplayan tabloları tespit edin. Beklenmedik büyümeler arşivleme, index bakımı veya bölümleme (partitioning) ihtiyacına işaret edebilir.","severity":"safe"},{"id":"tempdb-usage","group":"Kapasite","title":"tempdb alan kullanımı","command":"SELECT SUM(user_object_reserved_page_count)*8/1024 AS kullanici_nesneleri_mb, SUM(internal_object_reserved_page_count)*8/1024 AS dahili_nesneler_mb, SUM(version_store_reserved_page_count)*8/1024 AS surum_deposu_mb, SUM(unallocated_extent_page_count)*8/1024 AS bos_mb FROM sys.dm_db_file_space_usage;","expect":"tempdb'de boş alan tükenmek üzereyse (unallocated düşük) sorgular hata verebilir. Sürüm deposu (version store) sürekli büyüyorsa uzun süren açık transaction'lar vardır; sys.dm_tran_active_snapshot_database_transactions ile araştırın.","severity":"caution"},{"id":"connection-count","group":"Kapasite","title":"Bağlantı sayısı ve dağılımı","command":"SELECT DB_NAME(dbid) AS veritabani, COUNT(*) AS baglanti_sayisi, SUM(CASE WHEN status = 'running' THEN 1 ELSE 0 END) AS aktif FROM sys.sysprocesses WHERE dbid > 0 GROUP BY dbid ORDER BY baglanti_sayisi DESC;","expect":"Bağlantı sayısını uygulama/veritabanı bazında izleyin. Tek bir uygulamanın olağandışı çok bağlantısı bağlantı havuzu (connection pool) sızıntısına işaret edebilir. max worker threads sınırına yaklaşmayın.","severity":"safe"},{"id":"vlf-count","group":"Kapasite","title":"Log dosyası VLF sayısı (fragmentasyon)","command":"SELECT DB_NAME(database_id) AS veritabani, COUNT(*) AS vlf_sayisi FROM sys.dm_db_log_info(DB_ID()) GROUP BY database_id;","expect":"VLF sayısı yüksekse (birkaç yüzü aşan, örneğin 500+) log dosyası çok küçük büyüme adımlarıyla büyümüştür; bu recovery ve backup performansını yavaşlatır. Log'u shrink edip büyük tek adımla yeniden büyütün.","severity":"caution"},{"id":"buffer-cache-ple","group":"Performans","title":"Buffer Cache Hit Ratio ve Page Life Expectancy","command":"SELECT (SELECT cntr_value FROM sys.dm_os_performance_counters WHERE counter_name = 'Buffer cache hit ratio') AS hit_ratio_ham, (SELECT cntr_value FROM sys.dm_os_performance_counters WHERE counter_name = 'Buffer cache hit ratio base') AS hit_ratio_taban, (SELECT cntr_value FROM sys.dm_os_performance_counters WHERE counter_name = 'Page life expectancy' AND object_name LIKE '%Buffer Manager%') AS page_life_expectancy_sn;","expect":"Buffer cache hit ratio ideal olarak %99+ olmalıdır (hit_ratio_ham / hit_ratio_taban). Page Life Expectancy sürekli düşükse (genel kural NUMA node başına her 4 GB için 300 sn'nin altı) bellek baskısı vardır; RAM veya sorgu optimizasyonu gerekir.","severity":"caution"},{"id":"expensive-queries","group":"Performans","title":"En pahalı sorgular (CPU ve okuma)","command":"SELECT TOP 15 qs.total_worker_time/1000 AS toplam_cpu_ms, qs.execution_count AS calisma_sayisi, qs.total_logical_reads AS toplam_mantiksal_okuma, qs.total_worker_time/qs.execution_count/1000 AS ort_cpu_ms, SUBSTRING(st.text, (qs.statement_start_offset/2)+1, ((CASE qs.statement_end_offset WHEN -1 THEN DATALENGTH(st.text) ELSE qs.statement_end_offset END - qs.statement_start_offset)/2)+1) AS sorgu_metni FROM sys.dm_exec_query_stats qs CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st ORDER BY qs.total_worker_time DESC;","expect":"CPU ve mantıksal okuma açısından en maliyetli sorguları belirleyin. Yüksek okuma yapan sorgular eksik index belirtisidir; execution plan'ları inceleyip indeksleme veya sorgu yeniden yazımı yapın.","severity":"safe"},{"id":"blocking-sessions","group":"Performans","title":"Bloklayan (blocking) oturumlar","command":"SELECT r.session_id AS engellenen_oturum, r.blocking_session_id AS engelleyen_oturum, r.wait_type AS bekleme_tipi, r.wait_time/1000 AS bekleme_sn, r.status AS durum, t.text AS sorgu FROM sys.dm_exec_requests r CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) t WHERE r.blocking_session_id <> 0 ORDER BY r.wait_time DESC;","expect":"Bloklayan oturum varsa (blocking_session_id <> 0) sorguların birbirini beklettiğini gösterir. Uzun süren bloklamalar uygulama zaman aşımına yol açar; kök oturumu bulup uzun transaction'ı sonlandırmayı değerlendirin.","severity":"danger"},{"id":"wait-stats","group":"Performans","title":"En yüksek bekleme istatistikleri (wait stats)","command":"SELECT TOP 15 wait_type AS bekleme_tipi, waiting_tasks_count AS bekleyen_gorev, wait_time_ms/1000 AS toplam_bekleme_sn, (wait_time_ms - signal_wait_time_ms)/1000 AS kaynak_bekleme_sn, signal_wait_time_ms/1000 AS cpu_bekleme_sn FROM sys.dm_os_wait_stats WHERE wait_type NOT IN (N'CLR_SEMAPHORE', N'CLR_AUTO_EVENT', N'CLR_MANUAL_EVENT', N'LAZYWRITER_SLEEP', N'SQLTRACE_BUFFER_FLUSH', N'SQLTRACE_INCREMENTAL_FLUSH_SLEEP', N'WAITFOR', N'BROKER_TASK_STOP', N'BROKER_EVENTHANDLER', N'BROKER_RECEIVE_WAITFOR', N'BROKER_TRANSMITTER', N'CHECKPOINT_QUEUE', N'CHKPT', N'REQUEST_FOR_DEADLOCK_SEARCH', N'XE_TIMER_EVENT', N'XE_DISPATCHER_WAIT', N'XE_LIVE_TARGET_TVF', N'BROKER_TO_FLUSH', N'DISPATCHER_QUEUE_SEMAPHORE', N'HADR_FILESTREAM_IOMGR_IOCOMPLETION', N'HADR_WORK_QUEUE', N'HADR_TIMER_TASK', N'HADR_CLUSAPI_CALL', N'HADR_LOGCAPTURE_WAIT', N'HADR_NOTIFICATION_DEQUEUE', N'DIRTY_PAGE_POLL', N'SP_SERVER_DIAGNOSTICS_SLEEP', N'SOS_WORK_DISPATCHER', N'LOGMGR_QUEUE', N'ONDEMAND_TASK_QUEUE', N'FT_IFTS_SCHEDULER_IDLE_WAIT', N'PWAIT_EXTENSIBILITY_CLEANUP_TASK', N'PWAIT_ALL_COMPONENTS_INITIALIZED', N'STARTUP_DEPENDENCY_MANAGER', N'PREEMPTIVE_XE_DISPATCHER', N'PVS_PREALLOCATE', N'WAIT_XTP_OFFLINE_CKPT_NEW_LOG', N'WAIT_XTP_CKPT_CLOSE', N'WAIT_XTP_HOST_WAIT', N'PARALLEL_REDO_DRAIN_WORKER', N'PARALLEL_REDO_LOG_CACHE', N'PARALLEL_REDO_TRAN_LIST', N'PARALLEL_REDO_WORKER_SYNC', N'PARALLEL_REDO_WORKER_WAIT_WORK') AND wait_type NOT LIKE N'SLEEP[_]%' AND wait_type NOT LIKE N'QDS[_]%' AND waiting_tasks_count > 0 ORDER BY wait_time_ms DESC;","expect":"Baskın bekleme tiplerini yorumlayın: PAGEIOLATCH = disk I/O darboğazı, CXPACKET/CXCONSUMER = paralellik, LCK_M = kilitleme, WRITELOG = log diski, RESOURCE_SEMAPHORE = bellek. Signal wait yüzdesi yüksekse CPU baskısı vardır.","severity":"safe"},{"id":"last-backup","group":"Yedek & Kurtarma","title":"Son yedek zamanları (tam / diferansiyel / log)","command":"SELECT d.name AS veritabani, d.recovery_model_desc AS kurtarma_modeli, MAX(CASE WHEN b.type = 'D' THEN b.backup_finish_date END) AS son_tam_yedek, MAX(CASE WHEN b.type = 'I' THEN b.backup_finish_date END) AS son_diferansiyel, MAX(CASE WHEN b.type = 'L' THEN b.backup_finish_date END) AS son_log_yedek FROM sys.databases d LEFT JOIN msdb.dbo.backupset b ON d.name = b.database_name WHERE d.database_id > 4 GROUP BY d.name, d.recovery_model_desc ORDER BY son_tam_yedek;","expect":"Her üretim veritabanının güncel bir tam yedeği olmalıdır. son_tam_yedek NULL veya çok eskiyse (RPO'yu aşan) yedekleme işi başarısızdır. FULL recovery modelinde log yedeği yoksa log dosyası büyümeye devam eder.","severity":"danger"},{"id":"recovery-model","group":"Yedek & Kurtarma","title":"Kurtarma modeli (recovery model) tutarlılığı","command":"SELECT name AS veritabani, recovery_model_desc AS kurtarma_modeli, log_reuse_wait_desc AS log_yeniden_kullanim_bekleme FROM sys.databases WHERE database_id > 4 ORDER BY name;","expect":"Kritik veritabanları point-in-time kurtarma için FULL olmalıdır. log_reuse_wait_desc = LOG_BACKUP ise log yedeği bekleniyor demektir; ACTIVE_TRANSACTION uzun süren transaction'a işaret eder.","severity":"caution"},{"id":"sysadmin-members","group":"Güvenlik","title":"sysadmin rolü üyeleri","command":"SELECT p.name AS login_adi, p.type_desc AS tip, p.is_disabled AS devre_disi FROM sys.server_role_members rm JOIN sys.server_principals r ON rm.role_principal_id = r.principal_id JOIN sys.server_principals p ON rm.member_principal_id = p.principal_id WHERE r.name = N'sysadmin' ORDER BY p.name;","expect":"sysadmin üyeliği en aza indirilmelidir. Beklenmeyen login'ler (özellikle uygulama hesapları veya bireysel kullanıcılar) yetki yükseltme riskidir; en az yetki (least privilege) ilkesini uygulayın.","severity":"danger"},{"id":"sa-and-password-policy","group":"Güvenlik","title":"sa hesabı ve şifre politikası kapalı login'ler","command":"SELECT name AS login_adi, is_disabled AS devre_disi, is_policy_checked AS sifre_politikasi_acik, is_expiration_checked AS suresi_dolma_kontrolu, LOGINPROPERTY(name, 'PasswordLastSetTime') AS son_sifre_degisimi FROM sys.sql_logins WHERE is_policy_checked = 0 OR name = N'sa' ORDER BY name;","expect":"sa hesabı devre dışı veya yeniden adlandırılmış olmalıdır. is_policy_checked = 0 olan SQL login'ler zayıf/eski şifre riski taşır; şifre politikasını (CHECK_POLICY) etkinleştirin.","severity":"caution"},{"id":"alwayson-sync","group":"Replikasyon","title":"Always On senkronizasyon durumu ve kuyruklar","command":"SELECT ag.name AS availability_group, ar.replica_server_name AS replika_sunucu, DB_NAME(drs.database_id) AS veritabani, drs.synchronization_state_desc AS senkron_durumu, drs.synchronization_health_desc AS saglik, drs.log_send_queue_size AS log_gonderme_kuyrugu_kb, drs.redo_queue_size AS redo_kuyrugu_kb FROM sys.dm_hadr_database_replica_states drs JOIN sys.availability_replicas ar ON drs.replica_id = ar.replica_id JOIN sys.availability_groups ag ON ar.group_id = ag.group_id ORDER BY ag.name, replika_sunucu;","expect":"synchronization_state_desc SYNCHRONIZED (senkron) veya SYNCHRONIZING (asenkron) olmalı, synchronization_health = HEALTHY olmalıdır. log_send_queue veya redo_queue büyüyorsa replika geride kalıyor; failover'da veri kaybı/RTO riski artar.","severity":"caution"}]},"health/mongodb.json":{"engineId":"mongodb","engine":"MongoDB","order":5,"checks":[{"id":"version-uptime","group":"Genel","title":"Sürüm ve çalışma süresi (uptime)","command":"db.serverStatus().version; db.serverStatus().uptime","expect":"Sürümün desteklenen ve yamalanmış olduğunu doğrulayın. uptime saniye cinsindendir; çok küçükse (birkaç bin saniye) beklenmedik yeniden başlatma olmuştur, mongod loglarını inceleyin.","severity":"safe"},{"id":"replset-status","group":"Genel","title":"Replica set üye durumları (health)","command":"rs.status().members.forEach(function(m) { print(m.name + \" | \" + m.stateStr + \" | health=\" + m.health); })","expect":"Her üye health=1 olmalı ve tam olarak bir PRIMARY bulunmalıdır. health=0 veya (not reachable/healthy), DOWN, RECOVERING durumları arıza belirtisidir. Birden fazla veya hiç PRIMARY yoksa seçim (election) sorunu vardır.","severity":"danger"},{"id":"dbstats-sizes","group":"Kapasite","title":"Veritabanı boyutları (veri / depolama / index)","command":"db.stats(1024*1024)","expect":"dataSize, storageSize ve indexSize değerlerini (MB) izleyin. storageSize dataSize'dan çok büyükse fragmentasyon olabilir. indexSize'ın RAM'e (WiredTiger cache) sığması performans için kritiktir.","severity":"safe"},{"id":"disk-space","group":"Kapasite","title":"Disk alanı kullanımı (fsUsedSize / fsTotalSize)","command":"var st = db.stats(); printjson({fsUsedSize_MB: (st.fsUsedSize/1048576).toFixed(0), fsTotalSize_MB: (st.fsTotalSize/1048576).toFixed(0), usedPct: (100*st.fsUsedSize/st.fsTotalSize).toFixed(1)})","expect":"fsUsedSize'ın fsTotalSize'a oranı %85'i aşarsa disk dolmak üzeredir; MongoDB disk dolduğunda yazma işlemlerini durdurur. Disk ekleme veya arşivleme planlayın.","severity":"caution"},{"id":"largest-collections","group":"Kapasite","title":"En büyük koleksiyonlar","command":"db.getCollectionNames().map(function(c) { var s = db.getCollection(c).stats(); return {koleksiyon: c, boyut_MB: (s.size/1048576).toFixed(1), depolama_MB: (s.storageSize/1048576).toFixed(1), indeks_MB: (s.totalIndexSize/1048576).toFixed(1), belge: s.count}; }).sort(function(a,b){return b.boyut_MB - a.boyut_MB;})","expect":"En çok yer kaplayan koleksiyonları belirleyin. Beklenmedik büyüme arşivleme, TTL index'i veya bölümleme (sharding) ihtiyacına işaret edebilir. Index boyutu veri boyutunu aşan koleksiyonları gözden geçirin.","severity":"safe"},{"id":"connections","group":"Kapasite","title":"Bağlantı sayısı (current / available)","command":"db.serverStatus().connections","expect":"current değeri available'a yaklaşıyorsa bağlantı limiti dolmak üzeredir ve yeni bağlantılar reddedilir. Uygulama bağlantı havuzu (connection pool) ayarlarını ve olası sızıntıları kontrol edin.","severity":"caution"},{"id":"wiredtiger-cache","group":"Performans","title":"WiredTiger cache kullanımı ve eviction","command":"var wt = db.serverStatus().wiredTiger.cache; printjson({kullanilan_MB: (wt['bytes currently in the cache']/1048576).toFixed(0), azami_MB: (wt['maximum bytes configured']/1048576).toFixed(0), kirli_MB: (wt['tracked dirty bytes in the cache']/1048576).toFixed(0), tahliye_edilen_sayfa: wt['unmodified pages evicted']})","expect":"Kullanılan bellek azami cache'in %80'ini aşınca eviction tetiklenir; %95'i aşarsa uygulama thread'leri eviction'a zorlanır ve performans düşer. Dirty page oranı yüksekse yazma baskısı vardır.","severity":"caution"},{"id":"slow-queries-profiler","group":"Performans","title":"Yavaş sorgular (profiler) ve COLLSCAN","command":"printjson(db.getProfilingStatus()); db.system.profile.find({millis: {$gt: 100}}).sort({ts: -1}).limit(10).forEach(function(d){ print(d.ts + \" | \" + d.millis + \"ms | \" + (d.planSummary || '') + \" | \" + JSON.stringify(d.command)); })","expect":"Bu kontrol salt okunurdur: önce profiler durumunu (was: 0 kapalı, 1 yalnız yavaşlar, 2 hepsi) gösterir, sonra kayıtlı yavaş işlemleri listeler. Profiler kapalıysa (was: 0) system.profile boş kalır; teşhis için ayrı bir adım olarak db.setProfilingLevel(1, {slowms: 100}) ile açın ve iş bitince db.setProfilingLevel(0) ile kapatın. planSummary'de COLLSCAN görülen sorgular tam koleksiyon taraması yapıyordur ve index eksiktir. Uzun millis değerli sorguları indeksleyerek optimize edin. Profiler yükü artırdığı için üretimde dikkatli kullanın.","severity":"caution"},{"id":"long-running-ops","group":"Performans","title":"Uzun süren işlemler (currentOp)","command":"db.getSiblingDB('admin').aggregate([{$currentOp: {}}, {$match: {active: true, secs_running: {$gt: 5}}}, {$project: {opid: 1, secs_running: 1, ns: 1, op: 1, planSummary: 1, waitingForLock: 1}}])","expect":"secs_running değeri yüksek olan aktif işlemler tıkanmaya yol açabilir. Gerektiğinde db.killOp(opid) ile sonlandırın. waitingForLock=true olan işlemler lock bekliyordur; kök işlemi araştırın.","severity":"danger"},{"id":"oplog-window","group":"Yedek & Kurtarma","title":"Oplog penceresi (replikasyon geçmişi)","command":"rs.printReplicationInfo()","expect":"Oplog penceresi (configured oplog size ve log length in hours) yeterince uzun olmalıdır. Pencere kısaysa (birkaç saat) yavaş bir secondary tam senkronizasyona (initial sync) düşebilir. Yedekleme ve nokta-zaman kurtarma stratejisi oplog'a bağlıdır.","severity":"caution"},{"id":"backup-note","group":"Yedek & Kurtarma","title":"Yedekleme durumu ve son yedek notu","command":"var r = db.getSiblingDB('local').getCollectionNames().includes('oplog.rs') ? db.getReplicationInfo() : null; printjson(r ? {oplogWindowHours: r.timeDiffHours, tFirst: r.tFirst, tLast: r.tLast} : 'standalone: oplog yok'); print('Yedek dogrulamasi: mongodump/mongorestore veya Ops Manager / Percona Backup (PBM) durumunu harici olarak kontrol edin.')","expect":"MongoDB'nin yerleşik zamanlanmış yedeği yoktur; mongodump, dosya sistemi snapshot'ı, Ops Manager veya PBM kullanılır. Son başarılı yedek zamanını ve geri yükleme testini harici araçtan doğrulayın. Replica set'te oplog penceresi (oplogWindowHours), oplog tabanlı PITR ile geri dönülebilecek en uzak noktayı belirler; yedek aralığından kısa olmamalı. RPO/RTO hedeflerini karşıladığını kontrol edin.","severity":"danger"},{"id":"users-roles","group":"Güvenlik","title":"Kullanıcı ve rol listesi","command":"db.getSiblingDB('admin').system.users.find({}, {user: 1, db: 1, roles: 1, _id: 0}).forEach(printjson)","expect":"Tanımlı kullanıcıları ve rollerini inceleyin. Beklenmeyen hesaplar veya aşırı geniş roller (root, __system, dbOwner) yetki yükseltme riskidir. En az yetki ilkesini uygulayın.","severity":"caution"},{"id":"auth-enabled","group":"Güvenlik","title":"Kimlik doğrulama (authorization) açık mı","command":"db.getSiblingDB('admin').runCommand({getCmdLineOpts: 1}).parsed.security","expect":"security.authorization = 'enabled' olmalıdır. Kapalıysa (veya security bloğu yoksa) veritabanı kimlik doğrulaması olmadan erişime açıktır; bu ciddi bir güvenlik açığıdır, hemen etkinleştirin.","severity":"danger"},{"id":"secondary-lag","group":"Replikasyon","title":"Secondary replikasyon gecikmesi (lag)","command":"rs.printSecondaryReplicationInfo()","expect":"Her secondary için 'replication lag' değeri düşük (birkaç saniye) olmalıdır. Lag büyükse (dakikalar) secondary yükü kaldıramıyor veya ağ/disk sorunu var demektir; failover'da veri kaybı ve okuma tutarsızlığı riski artar.","severity":"caution"},{"id":"member-health","group":"Replikasyon","title":"Üye sağlığı ve seçim (election) durumu","command":"rs.status().members.map(function(m){ return {uye: m.name, durum: m.stateStr, saglik: m.health, configVersion: m.configVersion, son_kalp_atisi: m.lastHeartbeatMessage || 'OK'}; })","expect":"Tüm üyeler sağlıklı (health=1) ve beklenen durumda (PRIMARY/SECONDARY) olmalıdır. lastHeartbeatMessage'da hata mesajı varsa ağ bölünmesi veya üye erişilemezliği söz konusudur. Çoğunluk (majority) kaybı yazmayı durdurur.","severity":"caution"}]},"health/redis.json":{"engineId":"redis","engine":"Redis","order":6,"checks":[{"id":"server-version-uptime","group":"Genel","title":"Sürüm ve çalışma süresi (uptime)","command":"redis-cli INFO server | grep -E \"redis_version|uptime_in_days|redis_mode|os\"","expect":"redis_version desteklenen ve yamalanmış olmalıdır. uptime_in_days çok küçükse beklenmedik yeniden başlatma olmuştur; redis_mode (standalone/sentinel/cluster) yapılandırmayı doğrular.","severity":"safe"},{"id":"persistence-status","group":"Genel","title":"Kalıcılık durumu (RDB / AOF)","command":"redis-cli INFO persistence | grep -E \"rdb_last_bgsave_status|aof_enabled|aof_last_bgrewrite_status|aof_last_write_status|rdb_bgsave_in_progress|loading\"","expect":"rdb_last_bgsave_status ve aof_last_write_status 'ok' olmalıdır. 'err' değeri disk/izin sorunu veya disk dolu olduğunu gösterir ve veri kaybı riski taşır. loading:1 sunucunun hâlâ veri yüklediğini belirtir.","severity":"danger"},{"id":"memory-usage","group":"Kapasite","title":"Bellek kullanımı (used_memory / maxmemory)","command":"redis-cli INFO memory | grep -E \"used_memory_human|used_memory:|maxmemory_human|maxmemory:|maxmemory_policy\"","expect":"used_memory maxmemory'ye yaklaşıyorsa (%85+) eviction veya OOM riski vardır. maxmemory=0 ise sınır yoktur ve Redis tüm RAM'i tüketip sistemi çökertebilir; mutlaka bir sınır ve uygun maxmemory_policy belirleyin.","severity":"caution"},{"id":"memory-fragmentation","group":"Kapasite","title":"Bellek fragmentasyon oranı","command":"redis-cli INFO memory | grep -E \"mem_fragmentation_ratio|mem_allocator\"","expect":"mem_fragmentation_ratio ideal olarak 1.0 - 1.5 arasındadır. 1.5'in üzeri yüksek fragmentasyon (bellek israfı) gösterir. 1.0'ın altı ise Redis'in diske swap edildiğine (ciddi performans sorunu) işaret eder; sistem RAM'ini kontrol edin.","severity":"caution"},{"id":"evicted-keys","group":"Kapasite","title":"Evict edilen anahtarlar (evicted_keys)","command":"redis-cli INFO stats | grep -E \"evicted_keys|expired_keys|keyspace_misses\"","expect":"evicted_keys sürekli artıyorsa Redis bellek sınırına ulaşıp veri atıyor demektir; bu istenmeyen veri kaybına yol açabilir. Bellek artırmayı, TTL kullanmayı veya maxmemory_policy'yi gözden geçirin.","severity":"caution"},{"id":"dbsize-keyspace","group":"Kapasite","title":"Anahtar sayısı ve keyspace dağılımı","command":"redis-cli DBSIZE; redis-cli INFO keyspace","expect":"Toplam anahtar sayısını (DBSIZE) ve veritabanı başına dağılımı (INFO keyspace: keys, expires, avg_ttl) izleyin. TTL'siz (expires düşük) büyüyen keyspace bellek şişmesine neden olur. Ani anahtar artışları anormal davranış işareti olabilir.","severity":"safe"},{"id":"hit-ratio","group":"Performans","title":"Cache isabet oranı (keyspace hits/misses)","command":"redis-cli INFO stats | grep -E \"keyspace_hits|keyspace_misses\"","expect":"İsabet oranı = hits / (hits + misses). Cache kullanımı için oran yüksek olmalıdır (%80+). Düşük oran verimsiz önbellekleme, yanlış TTL veya cache-miss deseni gösterir; sık istenen verinin önbelleklendiğinden emin olun.","severity":"safe"},{"id":"slowlog","group":"Performans","title":"Slow log (SLOWLOG)","command":"redis-cli SLOWLOG GET 10","expect":"Yavaş komutları (varsayılan eşik 10ms) inceleyin. O(N) komutlar (KEYS, SMEMBERS, büyük HGETALL, SORT) tek thread'li Redis'i bloke eder ve tüm istekleri geciktirir. Bu komutları SCAN gibi alternatiflerle değiştirin.","severity":"caution"},{"id":"clients","group":"Performans","title":"Bağlı ve bloke istemciler (clients)","command":"redis-cli INFO clients | grep -E \"connected_clients|blocked_clients|maxclients|client_recent_max_input_buffer\"","expect":"connected_clients maxclients'a yaklaşıyorsa yeni bağlantılar reddedilir. Yüksek blocked_clients (BLPOP/BRPOP bekleyen) tasarımsal olabilir ancak beklenmedik yükseklik tıkanma işaretidir. Bağlantı sızıntılarını kontrol edin.","severity":"safe"},{"id":"ops-per-sec","group":"Performans","title":"Anlık işlem hızı (ops/sec)","command":"redis-cli INFO stats | grep -E \"instantaneous_ops_per_sec|total_commands_processed|rejected_connections|total_net_input_bytes\"","expect":"instantaneous_ops_per_sec anlık iş yükünü gösterir. Ani düşüş/artışlar anormallik işaretidir. rejected_connections > 0 ise maxclients sınırına ulaşılmış demektir. Tek thread olduğundan çok yüksek ops CPU darboğazı yaratabilir.","severity":"safe"},{"id":"rdb-last-save","group":"Yedek & Kurtarma","title":"Son RDB kaydı ve bekleyen değişiklikler","command":"redis-cli INFO persistence | grep -E \"rdb_last_save_time|rdb_changes_since_last_save|rdb_last_bgsave_status\"; redis-cli LASTSAVE","expect":"rdb_changes_since_last_save çok yüksekse son snapshot'tan bu yana çok veri birikmiştir; çökme durumunda bu değişiklikler kaybolur. rdb_last_save_time (LASTSAVE, Unix zaman) çok eskiyse save aralığını veya yedekleme sıklığını gözden geçirin.","severity":"caution"},{"id":"aof-rewrite","group":"Yedek & Kurtarma","title":"AOF yeniden yazma durumu","command":"redis-cli INFO persistence | grep -E \"aof_enabled|aof_last_bgrewrite_status|aof_rewrite_in_progress|aof_current_size|aof_base_size\"","expect":"Dayanıklılık gerektiren senaryolarda aof_enabled=1 olmalıdır. aof_last_bgrewrite_status 'ok' olmalıdır; 'err' disk/kalıcılık sorunudur. aof_current_size, base_size'a göre çok büyükse yeniden yazma (rewrite) gereklidir.","severity":"caution"},{"id":"acl-auth","group":"Güvenlik","title":"ACL / kimlik doğrulama (requirepass) ayarı","command":"redis-cli ACL LIST; redis-cli ACL GETUSER default","expect":"En az bir parola korumalı kullanıcı olmalıdır. ACL GETUSER default çıktısında flags içinde 'on' ve 'nopass' görünüyorsa (requirepass da bu kullanıcının parolasıdır) Redis kimlik doğrulaması olmadan erişime açıktır; bu ciddi bir güvenlik açığıdır. Parolalar yalnızca hash olarak gösterilir; CONFIG GET requirepass parolayı düz metin döktüğü için kontrol amacıyla kullanmayın. ACL ile en az yetkili kullanıcılar tanımlayın.","severity":"danger"},{"id":"dangerous-commands","group":"Güvenlik","title":"Tehlikeli komutlar ve protected-mode","command":"redis-cli CONFIG GET protected-mode; redis-cli CONFIG GET bind; redis-cli COMMAND INFO flushall flushdb config keys","expect":"protected-mode 'yes' olmalı ve bind güvenli arayüzlerle sınırlanmalıdır. FLUSHALL, FLUSHDB, CONFIG, KEYS, DEBUG gibi tehlikeli komutlar üretimde rename-command ile devre dışı bırakılmalı veya ACL ile kısıtlanmalıdır.","severity":"caution"},{"id":"replication-status","group":"Replikasyon","title":"Replikasyon durumu (role, master link)","command":"redis-cli INFO replication","expect":"role (master/slave), connected_slaves ve her replika için durumu doğrulayın. Replikada master_link_status 'up' olmalıdır; 'down' ise bağlantı koptu demektir. master_last_io_seconds_ago yüksekse (gecikme) veri kaybı ve tutarsızlık riski artar.","severity":"danger"}]},"health/elasticsearch.json":{"engineId":"elasticsearch","engine":"Elasticsearch","order":7,"checks":[{"id":"cluster-health","group":"Genel","title":"Küme sağlığı (green / yellow / red)","command":"GET _cluster/health","expect":"status 'green' olmalıdır: tüm primary ve replica shard'lar atanmış demektir. 'yellow' primary'ler sağlam ama bazı replica'lar atanmamış (yedeklilik riski); 'red' en az bir primary shard kayıp/atanmamış (kısmi veri erişilemez, acil müdahale gerekir). unassigned_shards değeri 0 olmalıdır.","severity":"danger"},{"id":"cluster-version","group":"Genel","title":"Sürüm ve küme bilgisi","command":"GET /","expect":"version.number desteklenen ve güvenlik yamaları uygulanmış bir sürüm olmalıdır. Eski/EOL (kullanım ömrü bitmiş) sürümler güvenlik ve stabilite riski taşır. Tüm düğümlerin aynı sürümde olduğunu ayrıca GET _cat/nodes?v&h=name,version ile doğrulayın (rolling upgrade sırasında geçici karışıklık normaldir).","severity":"safe"},{"id":"pending-tasks","group":"Genel","title":"Bekleyen küme görevleri (pending tasks)","command":"GET _cluster/pending_tasks","expect":"Liste boş veya çok kısa olmalıdır. Sürekli birikmiş, uzun süredir (time_in_queue yüksek) bekleyen görevler master düğümün aşırı yüklendiğini veya küme durumu (cluster state) güncellemelerinin tıkandığını gösterir; bu, tüm kümenin yanıt süresini olumsuz etkiler.","severity":"caution"},{"id":"disk-allocation-watermark","group":"Kapasite","title":"Disk tahsisi ve watermark durumu","command":"GET _cat/allocation?v","expect":"Her düğüm için disk.percent değeri high watermark'ın (varsayılan %90) altında olmalıdır. %85 üstü uyarı, %90 (high) shard taşımayı tetikler, %95 (flood_stage) index'leri salt okunur yapar. shards sütununun düğümler arası dengeli dağıldığını doğrulayın; dengesiz dağılım tek düğümün erken dolmasına yol açar.","severity":"danger"},{"id":"largest-indices","group":"Kapasite","title":"En büyük index'ler (depolama boyutu)","command":"GET _cat/indices?v&s=store.size:desc","expect":"En çok yer kaplayan index'leri ve doc.count değerlerini izleyin. Kontrolsüz büyüyen log/metrik index'leri disk dolmasının ana nedenidir; bunlar için ILM (Index Lifecycle Management) ile rollover ve silme politikaları tanımlanmalıdır. status 'close' olan veya sağlığı yellow/red görünen index'lere ayrıca dikkat edin.","severity":"caution"},{"id":"jvm-heap-usage","group":"Kapasite","title":"JVM heap ve RAM kullanımı (düğüm başına)","command":"GET _cat/nodes?v&h=name,heap.percent,ram.percent,cpu,load_1m","expect":"heap.percent sürekli %75'in altında olmalıdır; kalıcı %85+ değerler bellek baskısı, sık GC duraklamaları ve circuit breaker riski demektir. JVM heap sunucu RAM'inin ~%50'si ve en fazla ~31GB (compressed oops sınırı) olmalıdır. Yüksek ve düşmeyen heap için sorguları optimize edin veya düğüm ekleyin.","severity":"caution"},{"id":"shard-count-limits","group":"Kapasite","title":"Shard sayısı ve düğüm başına shard limiti","command":"GET _cluster/health?level=shards","expect":"active_shards ve düğüm başına shard sayısı makul olmalıdır. Varsayılan üst sınır cluster.max_shards_per_node = 1000'dir (veri düğümü başına); bu sınıra yaklaşmak ve toplamda binlerce küçük shard (oversharding) master baskısı ve bellek israfı yaratır. Eski \"GB heap başına ~20 shard\" kuralı 8.3+ için geçerli değildir; güncel rehber shard başına 10-50GB boyut ve düğüm başına alan (mapping) sayısına dayalı heap planlamasıdır. initializing_shards / relocating_shards uzun süre yüksek kalmamalıdır. Aşırı shard varsa daha büyük/az sayıda shard veya rollover kullanın.","severity":"caution"},{"id":"http-connections","group":"Kapasite","title":"HTTP bağlantı sayısı","command":"GET _nodes/stats/http","expect":"http.current_open makul sınırlar içinde olmalıdır. http.total_opened çok hızlı artıyorsa istemciler bağlantı havuzu kullanmıyor, her istekte yeni bağlantı açıyor demektir (verimsiz). Anormal yüksek current_open bağlantı sızıntısına veya olası kaynak tükenmesine işaret eder.","severity":"safe"},{"id":"thread-pool-rejections","group":"Performans","title":"Thread pool reddi ve kuyruk doluluğu","command":"GET _cat/thread_pool?v&h=node_name,name,active,queue,rejected","expect":"rejected sütunu 0 olmalıdır. write/bulk ve search pool'larında artan rejected değeri kümenin aşırı yüklendiğini ve HTTP 429 döndürdüğünü gösterir (es_rejected_execution_exception). Sürekli dolu queue tıkanma işaretidir. İstemcide backoff uygulayın, batch boyutunu küçültün veya kapasite ekleyin.","severity":"danger"},{"id":"query-cache-hit","group":"Performans","title":"Query cache isabet oranı","command":"GET _nodes/stats/indices/query_cache","expect":"hit_count / (hit_count + miss_count) oranı, tekrar eden filtre sorgularında yüksek olmalıdır. Düşük isabet ve yüksek evictions, cache boyutunun yetersiz olduğunu veya sorguların önbelleklenemeyecek kadar değişken olduğunu gösterir. Sabit filtreleri (filter context) kullanmak isabet oranını artırır.","severity":"safe"},{"id":"slowlog-config","group":"Performans","title":"Slow log (slowlog) ayarı","command":"GET /_all/_settings?filter_path=**.search.slowlog,**.indexing.slowlog","expect":"Önemli index'lerde search ve indexing slowlog eşikleri tanımlı olmalıdır (ör. index.search.slowlog.threshold.query.warn: 10s). Slowlog kapalıysa yavaş sorguları teşhis etmek zorlaşır. Eşikleri açıp logları izleyerek pahalı sorguları (geniş agregasyon, wildcard, derin sayfalama) tespit edin.","severity":"safe"},{"id":"hot-threads","group":"Performans","title":"Hot threads","command":"GET _nodes/hot_threads","expect":"CPU'yu en çok tüketen thread'leri gösterir. Yüksek CPU/yavaşlık yaşandığında hangi işlemin (ağır agregasyon, merge, GC, script) darboğaz olduğunu belirlemek için kullanılır. Sürekli aynı pahalı sorgu/merge görülüyorsa ilgili sorguyu veya indeksleme stratejisini optimize edin.","severity":"safe"},{"id":"fielddata-memory","group":"Performans","title":"Fielddata bellek kullanımı","command":"GET _cat/fielddata?v","expect":"Fielddata bellek kullanımı düşük tutulmalıdır. Text alanlar üzerinde agregasyon/sıralama yapmak fielddata'yı belleğe yükler ve circuit breaker (Data too large) hatası ile OOM riskini artırır. Yüksek fielddata görülen alanlar için keyword alt-alanı (doc_values) kullanmaya geçin.","severity":"caution"},{"id":"snapshot-status","group":"Yedek & Kurtarma","title":"Snapshot repository ve son snapshot durumu","command":"GET _snapshot/_all","expect":"En az bir snapshot repository tanımlı olmalıdır. Repository'lerin varlığını doğruladıktan sonra son snapshot'ların durumunu kontrol edin (aşağıdaki verify kontrolü ile birlikte). Hiç repository yoksa küme yedeksizdir ve RED durumunda veri kalıcı olarak kaybolabilir. Düzenli otomatik snapshot için SLM (Snapshot Lifecycle Management) kurun.","severity":"danger"},{"id":"snapshot-latest-state","group":"Yedek & Kurtarma","title":"Son snapshot'ların başarı durumu","command":"GET _snapshot/<repo>/_all?verbose=false","expect":"En son snapshot'ların state değeri 'SUCCESS' olmalıdır. 'PARTIAL' bazı shard'ların yedeklenemediğini, 'FAILED' yedeğin başarısız olduğunu gösterir; bunlar geri yüklemede veri kaybı demektir. En güncel snapshot'ın tarihi (end_time) çok eski olmamalıdır (RPO hedefinize uygun sıklıkta yedek alın).","severity":"danger"},{"id":"snapshot-repo-verify","group":"Yedek & Kurtarma","title":"Snapshot repository doğrulaması","command":"POST _snapshot/<repo>/_verify","expect":"Doğrulama, tüm düğümlerin repository'ye (paylaşılan dosya sistemi, S3, HDFS vb.) erişebildiğini teyit eder ve yanıtta erişebilen düğümleri listeler. Hata dönerse bazı düğümler yedek deposuna yazamıyor demektir; bu durumda snapshot'lar eksik/başarısız olur. Depo erişimini ve kimlik bilgilerini düzeltin.","severity":"caution"},{"id":"security-enabled","group":"Güvenlik","title":"Güvenlik (X-Pack security) açık mı","command":"GET _xpack/usage","expect":"security.enabled ve security.available true olmalıdır. Güvenlik kapalıysa küme kimlik doğrulaması olmadan erişime açıktır; internete veya güvensiz ağa açık böyle bir küme ciddi bir açıktır (veri sızıntısı/silinmesi). Kimlik doğrulama, rol tabanlı erişim ve TLS mutlaka etkinleştirilmelidir.","severity":"danger"},{"id":"users-roles","group":"Güvenlik","title":"Kullanıcılar ve roller","command":"GET _security/user","expect":"Tanımlı kullanıcıları ve rol atamalarını gözden geçirin. Varsayılan hesapların (elastic, kibana_system vb.) güçlü parolalarla korunduğundan emin olun. En az yetki (least privilege) ilkesiyle her uygulama için sınırlı rollü ayrı kullanıcılar tanımlayın; superuser rolünü gereksiz yaygın kullanmaktan kaçının. Roller için GET _security/role kullanın.","severity":"caution"},{"id":"tls-transport-http","group":"Güvenlik","title":"TLS / HTTPS durumu (transport ve HTTP)","command":"GET _nodes/settings?filter_path=**.xpack.security.transport.ssl.enabled,**.xpack.security.http.ssl.enabled","expect":"xpack.security.transport.ssl.enabled true olmalıdır (düğümler arası şifreleme, zorunlu). İdealde http.ssl.enabled de true olmalıdır (istemci-küme HTTPS). TLS kapalıyken kimlik bilgileri ve veri ağ üzerinde açık taşınır. Sertifikaların süresini ve doğrulama modunu (verification_mode: certificate/full) ayrıca kontrol edin.","severity":"danger"},{"id":"unassigned-shards","group":"Replikasyon","title":"Atanmamış shard'lar ve nedenleri","command":"GET _cat/shards?v&h=index,shard,prirep,state,unassigned.reason","expect":"Tüm shard'ların state değeri 'STARTED' olmalıdır. UNASSIGNED durumdaki shard'lar ve unassigned.reason (NODE_LEFT, ALLOCATION_FAILED, DISK_THRESHOLD vb.) incelenmelidir. Atanmamış primary sağlık RED, atanmamış replica YELLOW demektir. Kök neden için GET _cluster/allocation/explain kullanın.","severity":"danger"},{"id":"recovery-active","group":"Replikasyon","title":"Devam eden shard recovery işlemleri","command":"GET _cat/recovery?v&active_only=true","expect":"Normalde aktif recovery olmamalıdır (liste boş). Düğüm ekleme/çıkarma veya failover sonrası geçici recovery normaldir ancak uzun süre takılı kalan, ilerlemeyen (%progress artmayan) recovery'ler ağ/disk darboğazına işaret eder. Rebalancing (relocation) iş yükünü etkiliyorsa recovery hız ayarlarını (indices.recovery.max_bytes_per_sec) gözden geçirin.","severity":"caution"},{"id":"replica-count","group":"Replikasyon","title":"Index başına replica sayısı","command":"GET _cat/indices?v&h=index,health,pri,rep,docs.count","expect":"Üretim index'lerinde rep (number_of_replicas) en az 1 olmalıdır; 0 replica olan index'te bir düğüm kaybında veri kalıcı olarak kaybolur. Ancak çok düğümlü kümede replica sayısı (veri düğümü sayısı - 1) değerini aşmamalıdır, aşarsa fazla replica atanamaz ve sağlık YELLOW kalır. health sütunu green olmayan index'leri inceleyin.","severity":"danger"}]},"recipes/oracle.json":{"engineId":"oracle","engine":"Oracle","order":1,"recipes":[{"id":"redo-switch","task":"Redo log switch (aktif log dosyasını değiştir)","category":"Redo & Arşiv","command":"ALTER SYSTEM SWITCH LOGFILE;","what":"Aktif redo log grubunu kapatıp bir sonrakine geçer; arşiv modda arşiv üretilmesini tetikler.","when":"Manuel arşiv üretmek, log değişimini zorlamak, test için.","caution":"Sık switch performansı düşürür; log dosyaları çok küçükse boyutlandırmayı gözden geçir.","tags":["redo","switch","logfile","archive","arsiv","alter system"]},{"id":"redo-add-group","task":"Yeni redo log grubu ekle","category":"Redo & Arşiv","command":"ALTER DATABASE ADD LOGFILE GROUP 4\n  ('/u01/oradata/ORCL/redo04a.log',\n   '/u02/oradata/ORCL/redo04b.log') SIZE 512M;","what":"Belirtilen boyut ve üyelerle yeni bir redo log grubu oluşturur (çoklu üye = mirror).","when":"Redo throughput yetersiz kaldığında ya da grup sayısını artırmak istediğinde.","caution":"Grup numarasının mevcut gruplarla çakışmadığından emin ol; V$LOG ile kontrol et.","tags":["redo","logfile","group","add","ekle","alter database"]},{"id":"redo-resize","task":"Redo log grubunun boyutunu değiştir (drop + add)","category":"Redo & Arşiv","command":"-- 1) Yeniden boyutlandirilacak grup INACTIVE olmali; degilse switch et:\nALTER SYSTEM SWITCH LOGFILE;\nALTER SYSTEM CHECKPOINT;\n-- 2) Eski grubu dusur:\nALTER DATABASE DROP LOGFILE GROUP 1;\n-- 3) Yeni boyutla tekrar ekle:\nALTER DATABASE ADD LOGFILE GROUP 1\n  ('/u01/oradata/ORCL/redo01a.log',\n   '/u02/oradata/ORCL/redo01b.log') SIZE 1G REUSE;","what":"Redo log boyutu doğrudan değiştirilemez; grup düşürülüp yeni boyutla yeniden eklenerek yapılır.","when":"Redo dosyaları çok küçük/büyük olduğunda, checkpoint sıklığını ayarlamak için.","caution":"Sadece INACTIVE veya UNUSED grup düşürülebilir; CURRENT/ACTIVE grubu düşürme. En az iki grup her zaman kalmalı. REUSE mevcut dosyayı yeniden kullanır.","tags":["redo","resize","boyut","drop","add","logfile","reuse"]},{"id":"enable-archivelog","task":"Veritabanını ARCHIVELOG moduna al","category":"Redo & Arşiv","command":"SHUTDOWN IMMEDIATE;\nSTARTUP MOUNT;\nALTER DATABASE ARCHIVELOG;\nALTER DATABASE OPEN;\n-- Dogrula:\nARCHIVE LOG LIST;","what":"Veritabanını arşiv log moduna alır; dolan redo loglar arşivlenir, hot backup ve point-in-time recovery mümkün olur.","when":"Prod veritabanında yedekleme ve kurtarma stratejisi için (RMAN, Data Guard öncesi zorunlu).","caution":"Instance yeniden başlatma gerekir; kesinti planla. Arşiv hedefinin (FRA veya LOG_ARCHIVE_DEST) yeterli alanı olduğundan emin ol, dolarsa DB durur. RAC'ta: srvctl stop database -d DB ile tüm instance'ları kapat, tek instance'ı STARTUP MOUNT ile aç, ARCHIVELOG'a al, kapat ve srvctl start database -d DB ile başlat (11gR2+ cluster_database=false gerekmez).","tags":["archivelog","arsiv","mode","mount","recovery","kurtarma"]},{"id":"fra-full-fix","task":"FRA / arşiv hedefi doldu sorununu çöz","category":"Redo & Arşiv","command":"-- Doluluk durumunu gor:\nSELECT name, space_limit/1024/1024/1024 AS limit_gb,\n       space_used/1024/1024/1024  AS used_gb,\n       ROUND(space_used/space_limit*100,1) AS pct_used\nFROM   v$recovery_file_dest;\n\n-- Cozum A) FRA boyutunu artir:\nALTER SYSTEM SET db_recovery_file_dest_size=100G SCOPE=BOTH;\n\n-- Cozum B) Yedegi alinmis arsivleri RMAN ile temizle:\n-- RMAN> DELETE ARCHIVELOG ALL BACKED UP 1 TIMES TO DISK COMPLETED BEFORE 'SYSDATE-3';\n-- Yedek yoksa (DIKKATLI): RMAN> DELETE ARCHIVELOG ALL COMPLETED BEFORE 'SYSDATE-1';","what":"Fast Recovery Area veya arşiv hedefi dolduğunda veritabanı asılır (ORA-00257). Alanı büyüterek veya arşivleri temizleyerek çözülür.","when":"ORA-00257 archiver error, DB yeni işlem kabul etmediğinde.","caution":"Yedeği alınmamış arşivleri silmek recovery yeteneğini yok eder. Önce RMAN yedeği al, sonra sil. OS'ten rm ile silme; RMAN CROSSCHECK gerekir. FRA doluyken arşiv yedeğini FRA dışındaki bir hedefe al (FORMAT '/backup/arc_%U'). Data Guard varsa standby'a gönderilmemiş/uygulanmamış arşivleri silme; aksi halde standby'da gap oluşur. CONFIGURE ARCHIVELOG DELETION POLICY TO APPLIED ON ALL STANDBY kullan.","tags":["fra","recovery area","ora-00257","archiver","arsiv","doldu","cleanup"]},{"id":"redo-status","task":"Redo log durumunu görüntüle","category":"Redo & Arşiv","command":"SELECT l.group#, l.thread#, l.sequence#,\n       ROUND(l.bytes/1024/1024) AS mb,\n       l.members, l.archived, l.status,\n       lf.member AS file_path\nFROM   v$log l\n  JOIN v$logfile lf ON lf.group# = l.group#\nORDER BY l.group#, lf.member;","what":"Redo log gruplarının durumunu (CURRENT/ACTIVE/INACTIVE), boyutlarını, üye dosyalarını ve arşiv durumunu gösterir.","when":"Redo yapılandırmasını incelerken, resize öncesi hangi grubun aktif olduğunu görmek için.","caution":"Sadece sorgulama; risksiz.","tags":["redo","status","durum","v$log","v$logfile","logfile"]},{"id":"asm-add-disk","task":"ASM diskgroup'a disk ekle","category":"ASM","command":"-- ASM instance'a baglan (sqlplus / as sysasm)\nALTER DISKGROUP DATA ADD DISK\n  '/dev/oracleasm/disks/DATA05' NAME DATA_0005,\n  '/dev/oracleasm/disks/DATA06' NAME DATA_0006\n  REBALANCE POWER 4;","what":"DATA diskgroup'una yeni diskler ekler ve otomatik rebalance başlatır; kapasite büyür.","when":"ASM diskgroup dolmaya başladığında, storage genişletirken.","caution":"SYSASM yetkisi gerekir. Disk boyutları benzer olmalı. Rebalance I/O yükü yaratır; yoğun saatlerde düşük POWER kullan.","tags":["asm","diskgroup","add disk","disk ekle","rebalance","alter diskgroup"]},{"id":"asm-drop-disk","task":"ASM diskgroup'tan disk çıkar","category":"ASM","command":"ALTER DISKGROUP DATA DROP DISK DATA_0005 REBALANCE POWER 4;\n\n-- Cikarma tamamlanana kadar BEKLE (V$ASM_OPERATION bosalinca disk fiziksel cikarilabilir):\nSELECT group_number, operation, state, power,\n       sofar, est_work, est_minutes\nFROM   v$asm_operation;","what":"Diski diskgroup'tan çıkarır; üzerindeki extent'ler kalan disklere taşınır (rebalance). Tamamlanınca disk HDR_STATUS=FORMER olur.","when":"Arızalı diski değiştirirken, kapasite küçültürken, storage taşırken.","caution":"Rebalance BİTMEDEN diski fiziksel olarak sökme, aksi halde veri kaybı olur. Kalan disklerde yeterli boş alan olduğundan emin ol.","tags":["asm","drop disk","disk cikar","rebalance","v$asm_operation","alter diskgroup"]},{"id":"asm-rebalance-power","task":"ASM rebalance gücünü (POWER) ayarla","category":"ASM","command":"-- Suren bir rebalance'in gucunu degistir (1-1024, 0 durdurur):\nALTER DISKGROUP DATA REBALANCE POWER 8;\n\n-- Rebalance'i tamamen durdur:\nALTER DISKGROUP DATA REBALANCE POWER 0;","what":"Devam eden rebalance işleminin paralelliğini/hızını ayarlar. Yüksek POWER daha hızlı ama daha çok I/O demektir.","when":"Rebalance çok yavaşsa hızlandırmak, ya da üretimi etkiliyorsa yavaşlatmak/durdurmak için.","caution":"POWER 0 rebalance'i askıya alır (disk çıkarma tamamlanmaz). Yüksek değer üretim I/O'sunu etkiler.","tags":["asm","rebalance","power","guc","diskgroup","tuning"]},{"id":"asm-diskgroup-space","task":"ASM diskgroup boş alanını gör","category":"ASM","command":"SELECT name,\n       state,\n       type,\n       total_mb/1024                 AS total_gb,\n       free_mb/1024                  AS free_gb,\n       ROUND((1-free_mb/total_mb)*100,1) AS pct_used,\n       usable_file_mb/1024           AS usable_gb\nFROM   v$asm_diskgroup\nORDER BY name;","what":"Her diskgroup'un toplam, boş ve (redundancy sonrası) kullanılabilir alanını gösterir.","when":"Kapasite planlaması, alan azaldığında, disk ekleme kararı öncesi.","caution":"usable_file_mb redundancy'yi hesaba katar; NORMAL/HIGH redundancy'de gerçek kullanılabilir alan bu sütundur. Sadece sorgu; risksiz.","tags":["asm","diskgroup","space","alan","free","v$asm_diskgroup","kapasite"]},{"id":"asm-monitor-rebalance","task":"ASM rebalance işlemini izle","category":"ASM","command":"SELECT group_number, operation, pass, state, power,\n       sofar, est_work,\n       ROUND(sofar/NULLIF(est_work,0)*100,1) AS pct_done,\n       est_minutes\nFROM   v$asm_operation\nORDER BY group_number;","what":"Devam eden rebalance/resync işlemlerinin ilerlemesini, gücünü ve tahmini kalan süreyi gösterir.","when":"Disk ekle/çıkar sonrası rebalance'in bitip bitmediğini takip ederken.","caution":"Boş sonuç = aktif işlem yok (tamamlanmış). Sadece sorgu; risksiz.","tags":["asm","rebalance","monitor","izle","v$asm_operation","ilerleme"]},{"id":"add-tablespace","task":"Yeni tablespace ekle","category":"Depolama","command":"-- Dosya sistemi:\nCREATE TABLESPACE musteri_data\n  DATAFILE '/u01/oradata/ORCL/musteri_data01.dbf'\n  SIZE 1G AUTOEXTEND ON NEXT 256M MAXSIZE 20G\n  EXTENT MANAGEMENT LOCAL\n  SEGMENT SPACE MANAGEMENT AUTO;\n\n-- ASM kullaniyorsan:\nCREATE TABLESPACE musteri_data\n  DATAFILE '+DATA' SIZE 1G AUTOEXTEND ON NEXT 256M MAXSIZE 20G;","what":"Yeni bir kalıcı tablespace oluşturur; içine tablo/index segmentleri yerleştirilebilir.","when":"Yeni uygulama/şema için ayrı depolama alanı ayırırken.","caution":"MAXSIZE belirt, aksi halde disk dolabilir. ASM'de dosya adı otomatik üretilir.","tags":["tablespace","create","olustur","datafile","storage","depolama","autoextend"]},{"id":"add-datafile","task":"Mevcut tablespace'e datafile ekle","category":"Depolama","command":"ALTER TABLESPACE musteri_data\n  ADD DATAFILE '/u01/oradata/ORCL/musteri_data02.dbf'\n  SIZE 2G AUTOEXTEND ON NEXT 256M MAXSIZE 30G;\n\n-- ASM:\nALTER TABLESPACE musteri_data\n  ADD DATAFILE '+DATA' SIZE 2G AUTOEXTEND ON NEXT 256M MAXSIZE 30G;","what":"Var olan tablespace'e yeni bir datafile ekleyerek kapasitesini büyütür.","when":"Tablespace dolduğunda ve tek dosya smallfile limitine (32G/64G) yaklaştığında.","caution":"Smallfile tablespace'te dosya başına blok limiti vardır; gerekirse yeni dosya ekle. MAXSIZE belirt.","tags":["datafile","add","ekle","tablespace","alter tablespace","storage"]},{"id":"resize-datafile","task":"Datafile boyutunu değiştir / autoextend ayarla","category":"Depolama","command":"-- Sabit boyuta buyut/kucult:\nALTER DATABASE DATAFILE '/u01/oradata/ORCL/musteri_data01.dbf' RESIZE 5G;\n\n-- Autoextend ac:\nALTER DATABASE DATAFILE '/u01/oradata/ORCL/musteri_data01.dbf'\n  AUTOEXTEND ON NEXT 256M MAXSIZE 30G;\n\n-- Autoextend kapat:\nALTER DATABASE DATAFILE '/u01/oradata/ORCL/musteri_data01.dbf' AUTOEXTEND OFF;","what":"Datafile'ı sabit boyuta getirir veya otomatik büyüme davranışını ayarlar.","when":"Alan kazanmak (shrink), önceden alan ayırmak, ya da kontrolsüz büyümeyi durdurmak için.","caution":"RESIZE ile küçültme, dosyanın sonundaki kullanılan blokların altına inemez (ORA-03297). Önce segmentleri taşı.","tags":["datafile","resize","boyut","autoextend","maxsize","alter database"]},{"id":"move-datafile-online","task":"Datafile'ı online taşı","category":"Depolama","command":"ALTER DATABASE MOVE DATAFILE\n  '/u01/oradata/ORCL/musteri_data01.dbf'\n  TO '/u03/oradata/ORCL/musteri_data01.dbf';\n\n-- ASM'ye tasima:\nALTER DATABASE MOVE DATAFILE\n  '/u01/oradata/ORCL/musteri_data01.dbf' TO '+DATA';\n\n-- Eski dosyayi silmeden korumak icin KEEP kullan:\n-- ALTER DATABASE MOVE DATAFILE '...' TO '...' KEEP;","what":"Veritabanı açıkken (12c+) datafile'ı yeni bir konuma taşır; kesinti olmadan storage değiştirir.","when":"Diski/mount noktasını değiştirirken, ASM'ye geçerken, hot storage'a taşırken.","caution":"12c ve üstü ile Enterprise Edition gerekir. Taşıma sırasında ek I/O oluşur. KEEP kullanmazsan eski dosya silinir.","since":"Oracle 12c","note":"Online datafile taşıma (ALTER DATABASE MOVE DATAFILE) Oracle 12c (12.1) ile geldi; öncesinde datafile taşımak için tablespace/datafile OFFLINE alınıp OS'te kopyalanır ve ALTER DATABASE RENAME FILE ile eşlenirdi.","tags":["datafile","move","tasi","online","alter database move datafile","asm"]},{"id":"temp-tablespace","task":"Temp tablespace ekle / varsayılanı değiştir","category":"Depolama","command":"-- Yeni temp tablespace olustur:\nCREATE TEMPORARY TABLESPACE temp2\n  TEMPFILE '/u01/oradata/ORCL/temp2_01.dbf'\n  SIZE 2G AUTOEXTEND ON NEXT 256M MAXSIZE 20G;\n\n-- Veritabani varsayilan temp'ini degistir:\nALTER DATABASE DEFAULT TEMPORARY TABLESPACE temp2;\n\n-- Eski temp'e tempfile ekle:\nALTER TABLESPACE temp ADD TEMPFILE '/u01/oradata/ORCL/temp_02.dbf' SIZE 2G;","what":"Sıralama/hash/global temp tablo işlemleri için geçici alan sağlar; varsayılanı yeni tablespace'e taşıyabilirsin.","when":"ORA-01652 (unable to extend temp segment), temp darboğazı, temp'i yeniden boyutlandırma için.","caution":"Varsayılanı değiştirdikten sonra eski temp kullanımdaysa hemen DROP etme; oturumlar boşalınca düşür.","tags":["temp","tablespace","tempfile","ora-01652","default temporary","depolama"]},{"id":"tablespace-space","task":"Tablespace boş alan sorgusu","category":"Depolama","command":"SELECT df.tablespace_name,\n       ROUND(df.total_mb/1024,2)                 AS total_gb,\n       ROUND(NVL(fs.free_mb,0)/1024,2)           AS free_gb,\n       ROUND((df.total_mb-NVL(fs.free_mb,0))/df.total_mb*100,1) AS pct_used\nFROM  (SELECT tablespace_name, SUM(bytes)/1024/1024 total_mb\n         FROM dba_data_files GROUP BY tablespace_name) df\n  LEFT JOIN\n       (SELECT tablespace_name, SUM(bytes)/1024/1024 free_mb\n          FROM dba_free_space GROUP BY tablespace_name) fs\n    ON df.tablespace_name = fs.tablespace_name\nORDER BY pct_used DESC;","what":"Her tablespace'in toplam, boş alanını ve doluluk yüzdesini gösterir (autoextend potansiyeli hariç, mevcut ayrılmış alana göre).","when":"Alan izleme, hangi tablespace'in büyütülmesi gerektiğini bulma.","caution":"Bu sorgu şu anki datafile boyutuna göredir; autoextend ile daha çok büyüyebilir. Temp için DBA_TEMP_FREE_SPACE kullan. Sadece sorgu; risksiz.","tags":["tablespace","space","alan","free","dba_free_space","doluluk","depolama"]},{"id":"alter-parameter","task":"Parametre değiştir (SCOPE ile)","category":"Bellek & Parametre","command":"-- Hem calisan instance hem spfile (varsayilan, dinamik parametreler):\nALTER SYSTEM SET open_cursors=500 SCOPE=BOTH;\n\n-- Sadece bir sonraki restart icin (statik parametreler):\nALTER SYSTEM SET processes=1000 SCOPE=SPFILE;\n\n-- Sadece anlik, spfile'a yazma:\nALTER SYSTEM SET optimizer_mode='ALL_ROWS' SCOPE=MEMORY;\n\n-- Mevcut degeri gor:\nSHOW PARAMETER open_cursors;","what":"Bir init parametresini çalışan instance'ta ve/veya spfile'da değiştirir. SCOPE davranışı belirler.","when":"Tuning, kapasite ayarı, parametre değişikliği gerektiren hata çözümlerinde.","caution":"Statik parametreler (processes, sga_max_size...) sadece SCOPE=SPFILE kabul eder ve restart gerektirir. Yanlış değer instance'ı açılmaz hale getirebilir; kritik parametrelerde önce pfile yedeği al.","tags":["parameter","parametre","alter system","scope","spfile","tuning"]},{"id":"flush-pool","task":"Shared pool / buffer cache flush","category":"Bellek & Parametre","command":"-- SQL plan/cursor cache temizle:\nALTER SYSTEM FLUSH SHARED_POOL;\n\n-- Buffer cache temizle (genelde sadece test/benchmark icin):\nALTER SYSTEM FLUSH BUFFER_CACHE;","what":"Shared pool tüm cache'lenmiş SQL/PL-SQL ve sözlük bilgisini, buffer cache tüm veri bloklarını bellekten atar.","when":"Plan sorunlarını test etmek, tek seferlik büyük işlem sonrası, tutarlı benchmark başlangıcı için.","caution":"ÜRETİMDE dikkatli! Flush sonrası tüm SQL yeniden parse edilir (hard parse fırtınası) ve bloklar diskten okunur; geçici ciddi performans düşüşü olur.","tags":["flush","shared pool","buffer cache","bellek","alter system","cache"]},{"id":"spfile-pfile","task":"spfile'dan pfile üret ve tersi","category":"Bellek & Parametre","command":"-- spfile -> pfile (yedek/duzenleme icin):\nCREATE PFILE='/tmp/init_orcl_yedek.ora' FROM SPFILE;\n\n-- pfile -> spfile (duzenlenmis pfile'i kalici yap; restart sonrasi gecerli):\nCREATE SPFILE FROM PFILE='/tmp/init_orcl_yedek.ora';\n\n-- Calisan instance degerlerinden pfile uret (11g+):\nCREATE PFILE='/tmp/init_current.ora' FROM MEMORY;","what":"Binary spfile ile metin pfile arasında dönüşüm yapar; pfile elle düzenlenebilir.","when":"Parametre değişikliği öncesi yedek, bozuk spfile onarımı, statik parametreyi elle düzeltme.","caution":"CREATE SPFILE FROM PFILE sonrası değişiklik ancak restart ile geçerli olur. Var olan spfile'ın üzerine yazmadan önce yolunu doğrula.","tags":["spfile","pfile","create pfile","create spfile","parametre","yedek"]},{"id":"sga-pga-target","task":"SGA / PGA hedeflerini değiştir","category":"Bellek & Parametre","command":"-- Otomatik bellek yonetimi (ASMM) hedefleri:\nALTER SYSTEM SET sga_target=8G   SCOPE=BOTH;\nALTER SYSTEM SET pga_aggregate_target=4G SCOPE=BOTH;\n\n-- Ust sinir (statik, restart gerektirir):\nALTER SYSTEM SET sga_max_size=12G SCOPE=SPFILE;\n\n-- Mevcut bellek dagilimini gor:\nSELECT component, current_size/1024/1024 AS mb\nFROM   v$sga_dynamic_components ORDER BY component;","what":"SGA ve PGA bellek hedeflerini ayarlar; Oracle bileşenleri otomatik yönetir (ASMM/AMM).","when":"Sunucuya RAM eklendiğinde, bellek darboğazında, bellek baskısında.","caution":"sga_target, sga_max_size'ı geçemez. sga_max_size statiktir, restart ister. İşletim sistemi ve diğer instance'lar için RAM bırak; aşırı ayar swap/OOM yapar.","tags":["sga","pga","memory","bellek","target","sga_target","pga_aggregate_target"]},{"id":"kill-session","task":"Oturum öldür (kill session)","category":"Oturum & Süreç","command":"-- Once oldurulecek oturumu bul:\nSELECT sid, serial#, username, status, machine, program\nFROM   v$session\nWHERE  username = 'MUSTERI_APP' AND status = 'ACTIVE';\n\n-- Oldur (aninda geri alma baslatir):\nALTER SYSTEM KILL SESSION '145,12345' IMMEDIATE;\n\n-- Takilirsa OS process'i sonlandirilabilir:\n-- ALTER SYSTEM DISCONNECT SESSION '145,12345' IMMEDIATE;","what":"Belirtilen SID,SERIAL# oturumunu sonlandırır; açık transaction rollback edilir.","when":"Lock tutan, kaçak sorgu çalıştıran, ya da bağlantı sızdıran oturumu durdurmak için.","caution":"Açık transaction varsa rollback uzun sürebilir (kısa iş yaptıysa çabuk biter). Yanlış SID öldürmemek için önce sorgu ile doğrula. Büyük DML'de rollback I/O yükü yaratır.","tags":["kill session","oturum oldur","v$session","alter system","sid","serial"]},{"id":"long-running-queries","task":"Uzun süren sorguları / oturumları gör","category":"Oturum & Süreç","command":"-- Aktif, uzun suren SQL'ler:\nSELECT s.sid, s.serial#, s.username, s.status,\n       s.last_call_et AS saniye_aktif,\n       s.sql_id, q.sql_text,\n       s.event, s.machine, s.program\nFROM   v$session s\n  LEFT JOIN v$sql q ON q.sql_id = s.sql_id\n                   AND q.child_number = s.sql_child_number\nWHERE  s.type = 'USER'\n  AND  s.status = 'ACTIVE'\n  AND  s.last_call_et > 60\nORDER BY s.last_call_et DESC;\n\n-- Yuzde ilerlemeli uzun islemler:\nSELECT sid, serial#, opname, sofar, totalwork,\n       ROUND(sofar/NULLIF(totalwork,0)*100,1) AS pct, time_remaining\nFROM   v$session_longops\nWHERE  sofar < totalwork ORDER BY start_time DESC;","what":"60 saniyeden uzun aktif oturumları ve uzun süren toplu işlemlerin ilerlemesini listeler.","when":"Yavaşlık şikayeti, hangi sorgunun sistemi meşgul ettiğini bulmak için.","caution":"last_call_et son çağrıdan bu yana geçen süredir; boşta bekleyen oturumda da büyük olabilir, status='ACTIVE' filtresi önemli. Sadece sorgu; risksiz.","tags":["long running","uzun sorgu","v$session","v$sql","v$session_longops","aktif"]},{"id":"find-blocking","task":"Blocking (lock bekleten) oturumu bul","category":"Oturum & Süreç","command":"SELECT bl.sid       AS blocker_sid,\n       bl.serial#   AS blocker_serial,\n       bl.username  AS blocker_user,\n       w.sid        AS waiter_sid,\n       w.serial#    AS waiter_serial,\n       w.username   AS waiter_user,\n       w.seconds_in_wait AS bekleme_sn,\n       w.event\nFROM   v$session w\n  JOIN v$session bl ON bl.sid = w.blocking_session\nWHERE  w.blocking_session IS NOT NULL\nORDER BY w.seconds_in_wait DESC;","what":"Lock bekleten (blocker) ve bekleyen (waiter) oturum çiftlerini, bekleme süresi ve olayıyla listeler.","when":"\"Uygulama takıldı / enq: TX bekleme\" gibi lock sorunlarında suçluyu bulmak için.","caution":"Blocker'ı öldürmeden önce iş sahibiyle teyit et; kritik bir işlem olabilir. Sadece sorgu; risksiz.","tags":["blocking","kilit","lock","blocker","waiter","v$session","blocking_session"]},{"id":"gather-stats","task":"İstatistik topla (DBMS_STATS)","category":"Bakım","command":"-- Tek tablo (kaskatli indeksler dahil):\nEXEC DBMS_STATS.GATHER_TABLE_STATS(ownname => 'MUSTERI_APP', tabname => 'MUSTERI', cascade => TRUE, estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE, degree => 4);\n\n-- Tum sema:\nEXEC DBMS_STATS.GATHER_SCHEMA_STATS(ownname => 'MUSTERI_APP', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE, cascade => TRUE, degree => 4);\n\n-- Tum veritabani (yalniz bakim penceresinde / yogun olmayan saatte calistir):\nEXEC DBMS_STATS.GATHER_DATABASE_STATS(estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE, degree => 4);","what":"Optimizer için tablo/index istatistiklerini toplar; doğru execution plan üretimini sağlar.","when":"Büyük DML/yükleme sonrası, plan kötüleşmesinde, yeni index/tablo sonrası.","caution":"İstatistik değişimi execution planları değiştirebilir; kritik sistemlerde önce test/AWR karşılaştırması yap. DEGREE paralellik CPU kullanır. Yoğun saatte GATHER_DATABASE_STATS ağır olur.","tags":["dbms_stats","statistics","istatistik","gather","optimizer","bakim"]},{"id":"rebuild-index-online","task":"Index'i online yeniden inşa et","category":"Bakım","command":"-- Normal indeks:\nALTER INDEX musteri_app.idx_musteri_email REBUILD ONLINE PARALLEL 4;\n\n-- Farkli tablespace'e tasiyarak:\nALTER INDEX musteri_app.idx_musteri_email\n  REBUILD ONLINE TABLESPACE musteri_idx PARALLEL 4;\n\n-- Rebuild sonrasi paralelligi geri al (plan etkilenmesin):\nALTER INDEX musteri_app.idx_musteri_email NOPARALLEL;","what":"Index'i DML'i engellemeden (ONLINE) yeniden oluşturur; fragmentasyonu giderir, tablespace değiştirebilir.","when":"Index bloat'ı/fragmentasyonu, index'i başka tablespace'e taşıma, UNUSABLE index onarımı.","caution":"ONLINE ek geçici alan ve I/O kullanır. PARALLEL kalıcı olur; rebuild sonrası NOPARALLEL ile geri al yoksa sorgular istemeden paralel çalışır. Bitmap index'te ONLINE her sürümde desteklenmez. ONLINE rebuild yalnızca Enterprise Edition'da vardır.","tags":["index","rebuild","online","yeniden insa","alter index","fragmentasyon","bakim"]},{"id":"rman-full-backup","task":"RMAN ile hızlı tam yedek","category":"Bakım","command":"# Kabuktan: rman target /\nRUN {\n  ALLOCATE CHANNEL c1 DEVICE TYPE DISK;\n  ALLOCATE CHANNEL c2 DEVICE TYPE DISK;\n  BACKUP AS COMPRESSED BACKUPSET\n    DATABASE\n    PLUS ARCHIVELOG\n    TAG 'FULL_DAILY';\n  BACKUP CURRENT CONTROLFILE;\n  DELETE NOPROMPT OBSOLETE;\n  RELEASE CHANNEL c1;\n  RELEASE CHANNEL c2;\n}","what":"Tüm veritabanının ve arşiv loglarının sıkıştırılmış tam yedeğini iki kanalla paralel alır, controlfile'ı yedekler ve eskimiş yedekleri temizler.","when":"Günlük/haftalık tam yedek, kurtarma noktası oluşturmak için.","caution":"COMPRESSED CPU kullanır. DELETE OBSOLETE retention policy'ye göre eski yedekleri siler; policy'yi (CONFIGURE RETENTION POLICY) doğru ayarla. ARCHIVELOG için DB ARCHIVELOG modda olmalı. Yedek hedefinde yeterli alan olsun.","tags":["rman","backup","yedek","full","compressed","archivelog","bakim"]},{"id":"controlfile-trace","task":"Controlfile trace yedeği al","category":"Bakım","command":"-- Trace (CREATE CONTROLFILE scripti) uret:\nALTER DATABASE BACKUP CONTROLFILE TO TRACE\n  AS '/tmp/create_controlfile.sql' REUSE;\n\n-- Binary controlfile kopyasi:\nALTER DATABASE BACKUP CONTROLFILE TO '/backup/controlfile_orcl.ctl' REUSE;","what":"Controlfile'ı yeniden yaratacak SQL scriptini (trace) ve/veya binary kopyasını üretir.","when":"Yapı değişikliği sonrası (datafile/redo ekleme), felaket kurtarma hazırlığı, tüm controlfile'lar kaybolursa yeniden yaratmak için.","caution":"Trace dosyasını yapı her değiştiğinde güncelle; eski script yanlış yapı yaratır. REUSE var olan dosyanın üzerine yazar. Sistem risksiz ama üretilen dosyayı güvenli sakla.","tags":["controlfile","trace","backup","yedek","alter database","recovery","bakim"]}]},"recipes/oracle-ha.json":{"engineId":"oracle","engine":"Oracle","order":1,"recipes":[{"id":"rac-srvctl-db-status","task":"RAC veritabanı, instance ve service durumunu srvctl ile gör","category":"RAC & Grid","command":"# Veritabani ve instance'lar hangi node'da, hangi durumda:\nsrvctl status database -db <db_unique_name> -verbose\n# Clusterware'e kayitli yapilandirma (Oracle home, spfile, disk group, policy, rol):\nsrvctl config database -db <db_unique_name>\n# Tek bir instance:\nsrvctl status instance -db <db_unique_name> -instance <instance>\n# Service'ler hangi instance'larda calisiyor:\nsrvctl status service -db <db_unique_name>","what":"Clusterware'in (CRS) gözünden veritabanının, her instance'ın ve service'lerin çalışma durumunu ve kayıtlı yapılandırmayı gösterir; -verbose instance open mode bilgisini de ekler.","when":"Her RAC müdahalesinden önce ve sonra ilk kontrol olarak; kesinti bildiriminde hangi node/instance'ın etkilendiğini anlamak için.","caution":"Salt okunurdur. Komutu veritabanının Oracle home'undan (oracle kullanıcısı) çalıştır; Grid home'daki srvctl farklı sürümdeyse yanıltıcı/hatalı sonuç verebilir.","since":"12c","note":"-db/-instance/-service uzun seçenekleri 12c+; 11g kısa seçenekleri (-d, -i, -s) 19c'de hâlâ çalışır ama deprecated.","tags":["rac","srvctl","durum","instance","service","cluster","config"],"untested":true},{"id":"rac-srvctl-start-stop","task":"RAC veritabanını veya tek instance'ı srvctl ile durdur / başlat (rolling)","category":"RAC & Grid","command":"# Tum veritabani (tum instance'lar):\nsrvctl stop database -db <db_unique_name> -stopoption immediate\nsrvctl start database -db <db_unique_name>\n# Rolling bakim: tek instance'i, service'lerini diger instance'lara tasiyarak durdur\nsrvctl stop instance -db <db_unique_name> -instance <instance> \\\n  -stopoption immediate -drain_timeout 300 -failover\nsrvctl start instance -db <db_unique_name> -instance <instance>\n# Node bazli:\nsrvctl stop instance -db <db_unique_name> -node <node> -stopoption immediate\n# Belirli bir open mode ile baslat (or. physical standby'i mount'ta):\nsrvctl start database -db <db_unique_name> -startoption mount","what":"Veritabanını veya seçilen instance'ı Clusterware üzerinden kontrollü durdurur/başlatır; -failover ile durdurulan instance'taki service'ler available instance'lara geçer, -drain_timeout oturumların boşalmasını bekler.","when":"Patch, OS bakımı veya parametre değişikliği için rolling (node node) yeniden başlatmada; planlı tam kapatmada.","caution":"RAC'ta SQL*Plus SHUTDOWN yerine srvctl kullan; aksi halde Clusterware kaynak hedefini (TARGET) bilmez ve instance'ı yeniden başlatabilir. stop database tüm instance'ları kapatır = tam kesinti. Service'lerin available instance tanımı yoksa -failover bağlantıları taşıyamaz.","since":"12c","note":"-drain_timeout ve -failover 12.2+. -stopoption abort yalnız acil durumda; bir sonraki açılışta instance recovery gerekir.","tags":["rac","srvctl","durdur","baslat","rolling","drain","shutdown"],"untested":true},{"id":"rac-service-add","task":"RAC service'i preferred/available instance'larla ekle (Application Continuity dahil)","category":"RAC & Grid","command":"srvctl add service -db <db_unique_name> -service <service> \\\n  -preferred <inst1>,<inst2> -available <inst3> \\\n  -pdb <pdb> -role PRIMARY -policy AUTOMATIC \\\n  -failovertype TRANSACTION -commit_outcome TRUE \\\n  -failoverretry 30 -failoverdelay 10 \\\n  -clbgoal SHORT -rlbgoal SERVICE_TIME -notification TRUE \\\n  -drain_timeout 300 -stopoption IMMEDIATE\nsrvctl start service -db <db_unique_name> -service <service>\n# Dogrula:\nsrvctl config service -db <db_unique_name> -service <service>\nsrvctl status service -db <db_unique_name> -service <service>","what":"Uygulamanın bağlanacağı, normalde preferred instance'larda çalışan ve onlar düşünce available instance'a geçen bir service tanımlar; -role PRIMARY ile Data Guard'da yalnız primary rolde başlar.","when":"Uygulamaları instance'a değil service'e bağlamak, iş yüklerini node'lara ayırmak ve planlı bakımda kesintisiz geçiş (drain/failover) sağlamak için.","caution":"Uygulamalar SID veya instance adıyla değil bu service adıyla (SCAN üzerinden) bağlanmalı. -failovertype TRANSACTION (Application Continuity) uygulama/driver desteği ister; emin değilsen -failovertype SELECT (TAF) veya NONE ile başla. SYS$ ve db_unique_name ile aynı adlı varsayılan service'i uygulama için kullanma.","since":"12c","note":"-pdb 12c+, -drain_timeout ve -stopoption 12.2+. Değişiklik için srvctl modify service; kalıcı preferred değişikliği -modifyconfig ister.","tags":["rac","service","srvctl","preferred","available","taf","application continuity"],"untested":true},{"id":"rac-service-relocate","task":"RAC service'ini başka instance'a taşı (relocate)","category":"RAC & Grid","command":"# Once mevcut yerlesimi gor:\nsrvctl status service -db <db_unique_name> -service <service>\n# Instance bazli tasima (oturumlar drain edilerek):\nsrvctl relocate service -db <db_unique_name> -service <service> \\\n  -oldinst <inst1> -newinst <inst3> -drain_timeout 120 -wait YES\n# Node bazli (policy-managed / tek node service):\nsrvctl relocate service -db <db_unique_name> -service <service> \\\n  -currentnode <node1> -targetnode <node2>\n# Ilgili oturumlarin dagilimi (SQL):\nSELECT inst_id, service_name, COUNT(*) AS sessions\nFROM   gv$session\nWHERE  type = 'USER'\nGROUP  BY inst_id, service_name\nORDER  BY service_name, inst_id;","what":"Çalışan bir service'i bir instance/node'dan diğerine taşır; yeni bağlantılar hedef instance'a gider, mevcut oturumlar drain_timeout süresince kendiliğinden kapanmaya bırakılır.","when":"Bir node'u bakım öncesi boşaltmak, failover sonrası service'i preferred instance'a geri almak veya yükü dengelemek için.","caution":"Relocate geçicidir: service yapılandırmasını (preferred/available) değiştirmez; instance yeniden başlayınca service yine preferred'a döner. -force mevcut oturumları keser; uygulama yeniden bağlanmayı desteklemiyorsa kesinti yaşanır.","since":"12c","note":"-drain_timeout ve -wait 12.2+. SQL sorgusu single instance'ta da çalışır; srvctl kısmı RAC gerektirir.","tags":["rac","service","relocate","tasi","srvctl","drain","gv$session"],"untested":true},{"id":"rac-crsctl-stat-res","task":"Cluster kaynaklarının durumunu gör (crsctl stat res -t)","category":"RAC & Grid","command":"# Grid home'dan, grid kullanicisiyla:\ncrsctl stat res -t\n# OHASD (init) katmani: ora.cssd, ora.crsd, ora.asm, ora.ctssd...\ncrsctl stat res -t -init\n# Sadece sorunlu kaynaklar (hedefi ONLINE ama durumu ONLINE degil):\ncrsctl stat res -t -w \"((TARGET = ONLINE) and (STATE != ONLINE))\"\n# Tek kaynagin profili ve calisma bilgisi:\ncrsctl stat res ora.<db_unique_name>.db -p\ncrsctl stat res ora.<db_unique_name>.db -v","what":"Clusterware'in yönettiği tüm kaynakları (veritabanı, instance, listener, SCAN, VIP, ASM, disk group, network) node bazında TARGET/STATE ile tablo olarak listeler.","when":"Node açılışından sonra, patch sonrası ve her kesinti incelemesinde; OFFLINE, INTERMEDIATE veya UNKNOWN kaynakları bulmak için.","caution":"Salt okunurdur. ora.* kaynaklarını crsctl start/stop/modify ile doğrudan yönetme; veritabanı kaynakları için srvctl kullan (Oracle desteklenen yöntem budur).","note":"Kaynak adı küçük harfli db_unique_name içerir (ora.orcl.db). -init çıktısı ancak root/grid ile tam görünür.","tags":["rac","grid","crsctl","kaynak","resource","clusterware","durum"],"untested":true},{"id":"rac-crsctl-check-cluster","task":"Cluster stack sağlığını, node listesini ve Clusterware sürümünü kontrol et","category":"RAC & Grid","command":"# Tum node'larda CRS, CSS, EVM saglik kontrolu:\ncrsctl check cluster -all\n# Bu node'da OHASD dahil tum stack:\ncrsctl check crs\n# Node listesi: numara, durum (Active/Inactive), pinned:\nolsnodes -n -s -t\n# Aktif surum, patch seviyesi ve upgrade durumu (rolling patch sonrasi):\ncrsctl query crs activeversion -f\ncrsctl query crs softwareversion -all","what":"Cluster Ready Services, Cluster Synchronization Services ve Event Manager daemon'larının her node'da çalıştığını, cluster üyelerini ve Clusterware'in aktif/yazılım sürümünü gösterir.","when":"Sabah sağlık kontrolünde, node eviction veya reboot sonrası ve rolling patch/upgrade bitince tüm node'ların aynı seviyede olduğunu doğrulamak için.","caution":"Salt okunurdur. activeversion -f \"ROLLING PATCH\" veya farklı patch level gösteriyorsa rolling işlem yarım kalmıştır; yeni değişiklik yapmadan önce tamamla (crsctl stop rollingpatch / rootcrs -postpatch).","since":"12c","note":"activeversion -f ve softwareversion -all 12c+.","tags":["rac","grid","crsctl","olsnodes","saglik","cluster","surum"],"untested":true},{"id":"rac-ocr-backup","task":"OCR bütünlüğünü kontrol et ve OCR yedeği al (ocrcheck / ocrconfig)","category":"RAC & Grid","command":"# OCR butunluk ve kapasite kontrolu (mantiksal kontrol icin root ile):\nocrcheck\nocrcheck -config\n# Otomatik yedekler (4 saatte bir, gunluk, haftalik):\nocrconfig -showbackup\n# Riskli degisiklikten once manuel yedek (root):\nocrconfig -manualbackup\nocrconfig -showbackup manual\n# Yedek konumunu disk group'a al (root):\nocrconfig -backuploc +<diskgroup>","what":"Oracle Cluster Registry'nin (cluster yapılandırma veritabanı) bütünlüğünü, konumlarını ve yedeklerini gösterir; -manualbackup anlık fiziksel OCR yedeği alır.","when":"Node ekleme/çıkarma, Grid patch/upgrade, voting disk veya ağ (oifcfg) değişikliği gibi cluster yapılandırma işlemlerinden hemen önce.","caution":"ocrconfig -restore tüm node'larda CRS durdurulmuş ve exclusive modda çalıştırılmalıdır; yanlış yedekten restore cluster'ı açılmaz hale getirebilir, Oracle Support eşliğinde yap. Otomatik yedekler varsayılan olarak tek node'un yerel diskinde kalabilir; konumu paylaşımlı disk group'a al.","note":"grid kullanıcısıyla ocrcheck mantiksal bozulma kontrolünü atlar (\"Logical corruption check bypassed\"). Disk group'a yedek 12c+.","tags":["rac","ocr","ocrcheck","ocrconfig","yedek","backup","grid"],"untested":true},{"id":"rac-votedisk-query","task":"Voting disk'leri ve CSS zaman aşımlarını kontrol et","category":"RAC & Grid","command":"# Voting disk'ler, durumlari ve bulunduklari disk group:\ncrsctl query css votedisk\n# Node eviction esikleri (saniye):\ncrsctl get css misscount\ncrsctl get css disktimeout\ncrsctl get css reboottime\n# Voting disk'leri baska bir ASM disk group'a tasi (root/grid):\ncrsctl replace votedisk +<diskgroup>","what":"Cluster üyeliği için kullanılan voting disk'lerin (voting file) durumunu ve network/disk heartbeat zaman aşımlarını gösterir; replace votedisk tüm voting file'ları hedef disk group'a taşır.","when":"Depolama değişikliği, disk group yeniden tasarımı veya node eviction incelemesinde; voting disk sayısının çoğunluğun (quorum) erişilebilir olduğunu doğrulamak için.","caution":"Node'lar voting disk'lerin yarısından fazlasına erişemezse kendini reboot eder. Hedef disk group'ta yeterli failure group olmalı (normal redundancy: 3, high: 5; gerekirse quorum failgroup). misscount/disktimeout değerlerini Oracle Support onayı olmadan değiştirme.","note":"Varsayılanlar: misscount 30 sn, disktimeout 200 sn (Linux).","tags":["rac","voting disk","votedisk","css","misscount","quorum","eviction"],"untested":true},{"id":"rac-cluvfy-checks","task":"Cluster Verification Utility (cluvfy) ile ön/son kontrolleri çalıştır","category":"RAC & Grid","command":"# Grid kurulumu/degisikligi sonrasi tam kontrol:\ncluvfy stage -post crsinst -n all -verbose\n# Node eklemeden once:\ncluvfy stage -pre nodeadd -n <new_node> -verbose\n# Bilesen bazli kontroller:\ncluvfy comp nodecon -n all -verbose\ncluvfy comp clocksync -n all -verbose\ncluvfy comp ocr -n all -verbose\ncluvfy comp asm -n all -verbose\n# Yalniz basarisiz kontrolleri raporla:\ncluvfy stage -post crsinst -n all -verbose | grep -iE \"failed|warning\"","what":"Ağ bağlantısı, saat senkronu, OCR, ASM, kullanıcı eşdeğerliği ve OS ön koşullarını tüm node'larda doğrular; sorunları düzeltme önerileriyle raporlar.","when":"Grid kurulumu, node ekleme, upgrade öncesi ve sonrası; açıklanamayan cluster sorunlarında temel doğrulama olarak.","caution":"Salt okunurdur ama tüm node'lara ssh ile bağlanır; grid kullanıcısının ssh eşdeğerliği gerekir. -fixup betiklerini (root) gözden geçirmeden çalıştırma; OS parametrelerini değiştirir.","note":"Daha kapsamlı best-practice taraması için AHF içindeki orachk/exachk önerilir. Güncel cluvfy sürümünü My Oracle Support'tan indirip kullanmak daha fazla kontrol içerir.","tags":["rac","cluvfy","kontrol","dogrulama","precheck","grid","orachk"],"untested":true},{"id":"rac-node-eviction-diag","task":"Node eviction / beklenmeyen node reboot nedenini teşhis et","category":"RAC & Grid","command":"# 1) Ne zaman, hangi node, kim tarafindan: CRS alert log (her node'da)\ngrep -E \"CRS-1601|CRS-1607|CRS-1608|CRS-1609|CRS-1610|CRS-1611|CRS-1612|CRS-8011\" \\\n  $ORACLE_BASE/diag/crs/$(hostname -s)/crs/trace/alert.log\n# 2) CSS ayrintisi: network heartbeat mi, disk heartbeat mi kayboldu\ngrep -iE \"evict|misscount|heartbeat|disk HB|network HB\" \\\n  $ORACLE_BASE/diag/crs/$(hostname -s)/crs/trace/ocssd.trc | tail -100\n# 3) Reboot'u kim tetikledi (cssdagent/cssdmonitor):\nls -lt $ORACLE_BASE/diag/crs/$(hostname -s)/crs/trace/ohasd_cssd*.trc\n# 4) Olay anindaki OS kaynaklari (Cluster Health Monitor):\noclumon dumpnodeview -allnodes -s \"2026-01-15 03:10:00\" -e \"2026-01-15 03:20:00\"\n# 5) Tum node'lardan diagnostic collection (AHF/TFA):\ntfactl diagcollect -crs -os -last 4h\n# 6) OS tarafi: /var/log/messages, journalctl -k (OOM, NIC, multipath, I/O hatalari)","what":"Node eviction zincirini sırayla izler: CRS alert log'daki CRS-16xx mesajları, ocssd.trc'deki heartbeat kayıpları, CHM'nin OS metrikleri ve TFA ile toplanan tüm node logları.","when":"Bir node beklenmedik şekilde reboot olduğunda veya cluster'dan çıkarıldığında, kök neden analizi (RCA) ve Oracle Support SR'ı için.","caution":"Logları her node'dan ve olay saatini kapsayacak şekilde topla; trace dosyaları döner (rotate) ve kanıt kaybolabilir. Saat dilimlerinin node'lar arasında aynı olduğunu doğrula (CTSS/NTP). Kanıt toplanmadan misscount artırma gibi \"çözümler\" uygulama.","note":"Tipik nedenler: private interconnect kopması/packet loss, voting disk I/O gecikmesi, CPU/bellek tükenmesi (OOM, swap), saat sıçraması. Yol 12c+ ADR yapısıdır; 11g'de $GRID_HOME/log/<host>/ altındadır.","tags":["rac","eviction","reboot","ocssd","tfactl","oclumon","rca"],"untested":true},{"id":"rac-gv-cluster-waits","task":"Cluster genelinde bekleme olaylarını (gc waits) GV$ ile instance bazında analiz et","category":"RAC & Grid","command":"-- Instance bazinda Cluster sinifi beklemeler (baslangictan beri):\nSELECT inst_id, event, total_waits,\n       ROUND(time_waited_micro/1e6) AS time_waited_s,\n       ROUND(time_waited_micro/NULLIF(total_waits,0)/1000, 2) AS avg_ms\nFROM   gv$system_event\nWHERE  wait_class = 'Cluster'\nORDER  BY time_waited_micro DESC\nFETCH FIRST 15 ROWS ONLY;\n\n-- Su an bekleyen oturumlar, instance ve olaya gore:\nSELECT inst_id, event, COUNT(*) AS sessions\nFROM   gv$session\nWHERE  wait_class <> 'Idle' AND state = 'WAITING'\nGROUP  BY inst_id, event\nORDER  BY sessions DESC;\n\n-- Son 15 dakikada ASH: hangi instance gc beklemesinde\nSELECT inst_id, event, COUNT(*) AS samples\nFROM   gv$active_session_history\nWHERE  sample_time > SYSTIMESTAMP - INTERVAL '15' MINUTE\n  AND  wait_class = 'Cluster'\nGROUP  BY inst_id, event\nORDER  BY samples DESC\nFETCH FIRST 10 ROWS ONLY;","what":"GV$ view'larıyla tüm instance'lardaki Cluster sınıfı beklemeleri (gc cr/current block 2-way/3-way, gc buffer busy, gc cr request) ve ortalama gecikmeyi tek sorguda gösterir.","when":"RAC'ta yavaşlık şikayetinde sorunun interconnect/global cache kaynaklı olup olmadığını ve hangi instance'ta yoğunlaştığını anlamak için.","caution":"gv$active_session_history Diagnostics Pack lisansı gerektirir. avg_ms birkaç ms'nin üzerindeyse önce interconnect'i (MTU, packet loss, netstat -s) ve LMS CPU'sunu kontrol et; gc buffer busy genelde uygulama hot block'u (sequence, right-hand index) işaretidir.","note":"Single instance'ta da çalışır (inst_id = 1 döner).","tags":["rac","gv$","gc","bekleme","wait event","interconnect","global cache"]},{"id":"asm-asmcmd-lsdg-du","task":"asmcmd ile disk group, disk ve klasör kullanımını gör (lsdg / lsdsk / du)","category":"ASM","command":"# grid kullanicisi, ORACLE_SID=+ASM1 (veya +ASM) ile:\nasmcmd lsdg\n# Disk group'taki diskler: -k boyut, -p durum (header/mount/mode):\nasmcmd lsdsk -k -G <diskgroup>\nasmcmd lsdsk -p -G <diskgroup>\n# I/O hata ve sure istatistikleri:\nasmcmd lsdsk --statistics -G <diskgroup>\n# Eklenebilir (CANDIDATE/PROVISIONED/FORMER) diskler:\nasmcmd lsdsk --candidate -p\n# Veritabani klasoru kullanimi (MB):\nasmcmd du +<diskgroup>/<db_unique_name>\nasmcmd ls -l -s +<diskgroup>/<db_unique_name>/DATAFILE","what":"Disk group'ların redundancy, toplam/boş alan ve Usable_file_MB değerlerini, disklerin durumunu ve bir veritabanının ASM'de kapladığı alanı komut satırından gösterir.","when":"Kapasite kontrolü, disk ekleme öncesi aday disk tespiti ve \"disk group doldu\" alarmlarında hangi veritabanının yer kapladığını bulmak için.","caution":"Salt okunurdur. lsdg'de Usable_file_MB negatifse disk group bir disk/failgroup kaybından sonra redundancy'yi geri kuramaz; derhal alan aç veya disk ekle. du sonucu Used_MB ve Mirror_used_MB (aynalı kullanım) olarak iki değer verir.","note":"SQL karşılığı için asm-diskgroup-space ve asm-disk-health reçetelerine bak.","tags":["asm","asmcmd","lsdg","lsdsk","du","alan","disk group"],"untested":true},{"id":"asm-disk-health","task":"ASM disklerinin durumunu, hata sayaçlarını ve aday diskleri SQL ile kontrol et","category":"ASM","command":"-- ASM instance'ta (veya DB instance'tan; DB'de yalniz kullanilan disk group'lar gorunur):\nSELECT dg.name AS diskgroup, d.disk_number, d.name AS disk_name, d.path,\n       d.header_status, d.mount_status, d.mode_status, d.state,\n       d.failgroup, d.total_mb, d.free_mb, d.read_errs, d.write_errs\nFROM   v$asm_disk d\nLEFT   JOIN v$asm_diskgroup dg ON dg.group_number = d.group_number\nORDER  BY dg.name, d.disk_number;\n\n-- Disk group ozeti: AU boyutu, offline disk, voting file:\nSELECT name, type, allocation_unit_size/1048576 AS au_mb,\n       compatibility, database_compatibility, offline_disks, voting_files\nFROM   v$asm_diskgroup;\n\n-- Bu ASM'yi kullanan veritabanlari:\nSELECT instance_name, db_name, status, software_version, compatible_version\nFROM   v$asm_client;","what":"Her diskin header_status (MEMBER, CANDIDATE, PROVISIONED, FORMER), mount/mode durumu, failgroup'u ve okuma/yazma hata sayaçlarını; disk group'ta offline disk sayısını ve ASM istemcilerini listeler.","when":"Disk ekleme öncesi yeni LUN'un CANDIDATE/PROVISIONED görünüp görünmediğini, disk arızasında hangi diskin OFFLINE olduğunu ve I/O hatalarını görmek için.","caution":"Salt okunurdur. v$asm_disk her çağrıda disk discovery yapar ve çok diskli sistemlerde yavaştır; sık izleme için v$asm_disk_stat kullan (discovery yapmaz, yeni diskleri göstermez). header_status MEMBER olan bir diski FORCE ile başka disk group'a ekleme; mevcut veriyi yok eder.","note":"ASM olmayan ortamda boş döner; anlamlı çıktı ASM instance'ı gerektirir.","tags":["asm","v$asm_disk","disk","header_status","hata","candidate","failgroup"]},{"id":"asm-diskgroup-attributes","task":"ASM disk group attribute'larını gör ve değiştir (compatible, disk_repair_time)","category":"ASM","command":"-- Mevcut attribute'lar:\nSELECT dg.name AS diskgroup, a.name, a.value\nFROM   v$asm_attribute a\nJOIN   v$asm_diskgroup dg ON dg.group_number = a.group_number\nWHERE  a.name IN ('compatible.asm','compatible.rdbms','au_size','disk_repair_time',\n                  'failgroup_repair_time','content.type','sector_size')\nORDER  BY dg.name, a.name;\n\n-- Degisiklik (ASM instance, SYSASM ile):\nALTER DISKGROUP <diskgroup> SET ATTRIBUTE 'disk_repair_time' = '8h';\nALTER DISKGROUP <diskgroup> SET ATTRIBUTE 'compatible.asm'   = '19.0.0.0.0';\nALTER DISKGROUP <diskgroup> SET ATTRIBUTE 'compatible.rdbms' = '19.0.0.0.0';\n\n-- asmcmd karsiligi:\n-- asmcmd lsattr -l -G <diskgroup>\n-- asmcmd setattr -G <diskgroup> disk_repair_time '8h'","what":"Disk group'un uyumluluk seviyelerini (compatible.asm/rdbms), AU boyutunu ve geçici disk arızasında diskin düşürülmeden önce bekleneceği süreyi (disk_repair_time) gösterir ve değiştirir.","when":"Grid upgrade sonrası yeni ASM özelliklerini (flex disk group, daha büyük dosya limitleri) açmak için veya planlı depolama bakımında disk_repair_time'ı uzatmak için.","caution":"compatible.asm ve compatible.rdbms YÜKSELTİLDİKTEN SONRA GERİ ALINAMAZ. compatible.rdbms bu disk group'u kullanan en eski veritabanının COMPATIBLE değerinden yüksek olursa o veritabanı disk group'u mount edemez. Önce compatible.asm, sonra compatible.rdbms yükseltilir. au_size yalnız disk group oluşturulurken belirlenir.","note":"ASM olmayan ortamda sorgu boş döner. Varsayılan disk_repair_time 12h.","tags":["asm","attribute","compatible","disk_repair_time","disk group","au_size","v$asm_attribute"],"untested":true},{"id":"dg-show-configuration","task":"Data Guard broker yapılandırmasını ve veritabanı durumunu gör (DGMGRL)","category":"Data Guard","command":"# Kabuktan (parola ile baglan; switchover/failover icin de gereklidir):\ndgmgrl sys@<primary_db_unique_name>\nSHOW CONFIGURATION VERBOSE;\nSHOW DATABASE VERBOSE '<standby_db_unique_name>';\n# Izlenebilir property'ler:\nSHOW DATABASE '<primary_db_unique_name>' 'LogXptStatus';\nSHOW DATABASE '<standby_db_unique_name>' 'RecvQEntries';\nSHOW DATABASE '<primary_db_unique_name>' 'InconsistentLogXptProps';\nSHOW DATABASE '<standby_db_unique_name>' 'StatusReport';","what":"Broker konfigürasyonunun genel durumunu (SUCCESS/WARNING/ERROR), koruma modunu, her veritabanının rolünü, transport/apply lag'ini ve broker ile spfile arasındaki tutarsızlıkları gösterir.","when":"Her Data Guard işleminden (switchover, failover, parametre değişikliği) önce ve sonra; günlük sağlık kontrolünde.","caution":"Salt okunurdur. Broker etkinken log_archive_dest_n, log_archive_config gibi Data Guard parametrelerini SQL ile değiştirme; broker bunları kendi değerleriyle ezer. Değişiklikleri EDIT DATABASE ... SET PROPERTY ile, 19c+'da initialization parameter'lar için EDIT DATABASE ... SET PARAMETER ile yap.","note":"StatusReport ORA- hatalarını veritabanı bazında listeler; WARNING durumunun nedenini bulmanın en hızlı yoludur. InconsistentProperties 19c'de deprecated'dır ve hep boş döner; redo transport tutarsızlıkları için InconsistentLogXptProps kullan.","tags":["data guard","dgmgrl","broker","configuration","standby","durum","lag"],"untested":true},{"id":"dg-readiness-sql","task":"Primary/standby rolünü ve switchover hazırlığını SQL ile kontrol et","category":"Data Guard","command":"SELECT name, db_unique_name, database_role, open_mode, protection_mode,\n       switchover_status, force_logging, flashback_on, dataguard_broker\nFROM   v$database;\n\n-- Redo hedeflerinin durumu ve gap (primary'de):\nSELECT dest_id, dest_name, status, type, database_mode,\n       recovery_mode, gap_status, error\nFROM   v$archive_dest_status\nWHERE  status <> 'INACTIVE';\n\n-- Standby'da eksik archivelog araligi:\nSELECT thread#, low_sequence#, high_sequence# FROM v$archive_gap;","what":"Veritabanının rolünü, open mode'unu, koruma modunu, switchover_status'u (TO STANDBY / TO PRIMARY / SESSIONS ACTIVE / NOT ALLOWED), FORCE LOGGING ve flashback durumunu; redo hedeflerinin hata ve gap bilgisini gösterir.","when":"Switchover/failover öncesi ön kontrolde, yeni standby kurulumundan sonra ve broker kullanılmayan ortamlarda temel izlemede.","caution":"Salt okunurdur. FORCE_LOGGING=NO ise NOLOGGING işlemler standby'da bozuk blok bırakır; Data Guard primary'sinde ALTER DATABASE FORCE LOGGING açık olmalı. FLASHBACK_ON=NO ise failover sonrası eski primary REINSTATE edilemez, yeniden kurulması gerekir.","note":"Primary'de de çalışır; v$archive_gap yalnız physical standby'da anlamlıdır.","tags":["data guard","v$database","switchover_status","force logging","gap","rol","standby"]},{"id":"dg-lag-apply-rate","task":"Standby'da transport/apply lag, apply hızı ve Data Guard süreçlerini ölç","category":"Data Guard","command":"-- Standby'da calistir:\nSELECT name, value, unit, time_computed, datum_time\nFROM   v$dataguard_stats\nWHERE  name IN ('transport lag','apply lag','apply finish time','estimated startup time');\n\n-- Redo apply hizi (KB/sn):\nSELECT item, units, sofar, total, TO_CHAR(timestamp,'YYYY-MM-DD HH24:MI:SS') AS ts\nFROM   v$recovery_progress\nWHERE  item IN ('Active Apply Rate','Average Apply Rate','Maximum Apply Rate','Last Applied Redo')\nORDER  BY start_time DESC, item;\n\n-- Transport ve apply surecleri (12.2+; v$managed_standby'in yerini alir):\nSELECT name, role, action, thread#, sequence#, block#, delay_mins\nFROM   v$dataguard_process\nORDER  BY role;","what":"Standby'ın primary'den ne kadar geride olduğunu (transport lag = alınmamış redo, apply lag = uygulanmamış redo), birikmiş redo'nun ne zaman biteceğini, apply hızını ve hangi sürecin hangi sequence'ı işlediğini gösterir.","when":"RPO/RTO izlemede, lag alarmında sorunun ağda (transport) mı yoksa standby I/O/CPU'sunda (apply) mı olduğunu ayırt etmek için.","caution":"Salt okunurdur. datum_time eskiyse (time_computed'dan çok gerideyse) standby primary'den veri almıyordur ve lag değeri güvenilmezdir. Apply lag ile birlikte DelayMins tanımlı olup olmadığını kontrol et; bilinçli gecikme lag gibi görünür.","since":"12c","note":"v$dataguard_process 12.2+. Standby yoksa v$dataguard_stats boş döner.","tags":["data guard","lag","gecikme","apply","transport","v$dataguard_stats","rpo"]},{"id":"dg-validate-database","task":"Switchover/failover öncesi standby'ı broker ile doğrula (VALIDATE DATABASE)","category":"Data Guard","command":"VALIDATE DATABASE '<standby_db_unique_name>';\nVALIDATE DATABASE VERBOSE '<standby_db_unique_name>';\n# Iki taraf arasindaki spfile parametre farklari:\nVALIDATE DATABASE '<standby_db_unique_name>' SPFILE;\n# Ag ve static listener kayitlari (18c+):\nVALIDATE NETWORK CONFIGURATION FOR ALL;\nVALIDATE STATIC CONNECT IDENTIFIER FOR ALL;","what":"Standby'ın rol değişimine hazır olup olmadığını (\"Ready for Switchover / Failover: Yes\"), standby redo log sayı/boyutlarını, flashback ve apply durumunu, spfile farklarını ve broker'ın instance'ları yeniden başlatmak için ihtiyaç duyduğu static servisleri kontrol eder.","when":"Her planlı switchover'dan önce zorunlu adım olarak; yeni standby kurulumu ve ağ/listener değişikliklerinden sonra.","caution":"Salt okunurdur. \"Ready for Switchover: No\" veya standby redo log uyarısı varsa switchover'a geçme. Static connect identifier hatası, switchover sırasında broker'ın instance'ı açamamasına ve elle müdahaleye yol açar.","since":"12c","note":"VALIDATE DATABASE 12.1+, SPFILE seçeneği 12.2+, NETWORK CONFIGURATION ve STATIC CONNECT IDENTIFIER 18c+.","tags":["data guard","dgmgrl","validate","dogrula","switchover","standby redo log","broker"],"untested":true},{"id":"dg-switchover","task":"Planlı switchover yap (DGMGRL, veri kaybı olmadan rol değişimi)","category":"Data Guard","command":"# Parola ile baglan (OS kimlik dogrulamasi \"/\" ile broker uzak instance'i yeniden baslatamaz):\ndgmgrl sys@<primary_db_unique_name>\n# 1) On kontrol:\nSHOW CONFIGURATION;\nVALIDATE DATABASE '<standby_db_unique_name>';\n# 2) Rol degisimi:\nSWITCHOVER TO '<standby_db_unique_name>';\n# 3) Dogrula: yeni primary ve yeni standby\nSHOW CONFIGURATION;\nSHOW DATABASE '<primary_db_unique_name>';","what":"Primary ile standby'ın rollerini kontrollü biçimde değiştirir: primary'deki tüm redo standby'a gönderilip uygulanır, eski primary standby olarak yeniden başlatılır ve redo apply otomatik açılır.","when":"Primary sitede planlı bakım (OS, donanım, rolling upgrade), DR tatbikatı veya veri merkezi taşıma için.","caution":"Primary'de kısa bir kesinti olur; uygulama bağlantıları -role PRIMARY tanımlı service'ler ve FAN/TAF/AC ile yeni primary'ye yönlenmelidir. Uzun süren transaction'lar ve yüksek apply lag switchover süresini uzatır; önce lag'i sıfıra yakın getir. RAC'ta broker instance'ları kendisi yönetir; srvctl ile müdahale etme.","since":"12c","note":"12.1+ broker tek komutla tüm adımları yapar; 11g'de broker yoksa SQL ile ALTER DATABASE COMMIT TO SWITCHOVER kullanılırdı (12c+: ALTER DATABASE SWITCHOVER TO <db> VERIFY).","tags":["data guard","switchover","dgmgrl","rol degisimi","planli","standby","primary"],"untested":true},{"id":"dg-failover","task":"Primary kaybında failover yap (DGMGRL)","category":"Data Guard","command":"# Standby'a baglan (primary erisilemez):\ndgmgrl sys@<standby_db_unique_name>\n# 1) Kaybedilecek veriyi degerlendir (Transport Lag / Apply Lag):\nSHOW DATABASE '<standby_db_unique_name>';\n# 2) Tam failover: alinmis tum redo uygulanir, sonra rol degisir (onerilen)\nFAILOVER TO '<standby_db_unique_name>';\n# 3) Acil durum: redo uygulanmadan aninda (veri kaybi artar)\n# FAILOVER TO '<standby_db_unique_name>' IMMEDIATE;\nSHOW CONFIGURATION;","what":"Primary kullanılamaz olduğunda standby'ı primary rolüne yükseltir; tam failover önce alınmış tüm redo'yu uygular, IMMEDIATE ise uygulamayı atlar.","when":"Primary site, depolama veya veritabanı geri getirilemeyecek şekilde kaybedildiğinde ve RTO switchover beklemeye izin vermediğinde.","caution":"Geri dönüşü olmayan bir rol değişikliğidir. Önce primary'nin GERÇEKTEN kapalı olduğundan emin ol; eski primary açık kalıp uygulama ona yazmaya devam ederse split-brain ve veri ayrışması olur (eski primary'yi kapat/izole et). MaxPerformance modunda transport lag kadar veri kaybedilir. Sonrasında tüm standby'lar ve yedek stratejisi yeni primary'ye göre gözden geçirilmeli.","note":"Eski primary'yi geri kazanmak için dg-reinstate-database reçetesine bak (flashback gerekir).","tags":["data guard","failover","dgmgrl","felaket","disaster recovery","veri kaybi","split-brain"],"untested":true},{"id":"dg-reinstate-database","task":"Failover sonrası eski primary'yi standby olarak geri kazan (REINSTATE)","category":"Data Guard","command":"# 1) Eski primary'yi MOUNT'a getir (sqlplus / as sysdba):\n#    SQL> STARTUP MOUNT;\n#    (RAC: srvctl start database -db <old_primary_db_unique_name> -startoption mount)\n# 2) Yeni primary'ye bagli DGMGRL'den:\ndgmgrl sys@<new_primary_db_unique_name>\nREINSTATE DATABASE '<old_primary_db_unique_name>';\n# 3) Dogrula:\nSHOW CONFIGURATION;\nSHOW DATABASE '<old_primary_db_unique_name>';","what":"Eski primary'yi flashback database ile failover SCN'inin öncesine geri sarar, physical standby'a dönüştürür ve yeni primary'den redo almaya başlatır; standby'ı sıfırdan kurmaya gerek kalmaz.","when":"Failover sonrasında eski primary sunucu/depolama tekrar erişilebilir olduğunda; FSFO otomatik failover'ından sonra (observer genellikle kendisi reinstate eder).","caution":"Eski primary'de failover'dan ÖNCE flashback açık olmalı ve flashback logları failover SCN'ini kapsamalı (db_flashback_retention_target, FRA boyutu); aksi halde reinstate başarısız olur ve standby RMAN duplicate ile yeniden kurulur. Eski primary'de failover sonrası yazılmış veriler kalıcı olarak kaybolur.","note":"Gerekli koşul kontrolü: dg-readiness-sql reçetesindeki flashback_on sütunu.","tags":["data guard","reinstate","flashback","failover","eski primary","standby","dgmgrl"],"untested":true},{"id":"dg-apply-transport-state","task":"Redo apply'ı veya redo transport'u broker ile durdur / başlat; gecikmeli apply ayarla","category":"Data Guard","command":"# Standby'da redo apply:\nEDIT DATABASE '<standby_db_unique_name>' SET STATE='APPLY-OFF';\nEDIT DATABASE '<standby_db_unique_name>' SET STATE='APPLY-ON';\n# Primary'de redo transport (tum standby'lara):\nEDIT DATABASE '<primary_db_unique_name>' SET STATE='TRANSPORT-OFF';\nEDIT DATABASE '<primary_db_unique_name>' SET STATE='TRANSPORT-ON';\n# Gecikmeli apply (dakika; mantiksal hatalara karsi koruma):\nEDIT DATABASE '<standby_db_unique_name>' SET PROPERTY DelayMins=240;\nSHOW DATABASE '<standby_db_unique_name>' DelayMins;","what":"Standby'da redo apply'ı (MRP) veya primary'de redo gönderimini broker üzerinden kalıcı olarak durdurur/başlatır; DelayMins redo'yu belirtilen süre bekletip uygular.","when":"Standby'da bakım veya yedekleme, ağ kesintisi planı, primary'de büyük toplu yükleme sırasında transport'u kontrol etmek ya da yanlışlıkla silmelere karşı gecikmeli standby kurmak için.","caution":"Broker etkinken SQL ile ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL kullanma; broker durumu yeniden açar. APPLY-OFF süresince apply lag ve failover süresi (RTO) büyür; TRANSPORT-OFF süresince primary'de oluşan veri korumasızdır (RPO). FSFO etkinse bu işlemler failover'ı engelleyebilir.","note":"DelayMins > 0 iken redo real-time apply ile değil, archived log'lardan gecikmeli uygulanır; standby gecikme süresince redo almaya devam eder.","tags":["data guard","apply","transport","mrp","delaymins","durdur","dgmgrl"],"untested":true},{"id":"dg-fsfo-observer","task":"Fast-Start Failover'ı (FSFO) etkinleştir ve observer'ı başlat","category":"Data Guard","command":"# 1) Hedefler ve esik (saniye):\nEDIT DATABASE '<primary_db_unique_name>' SET PROPERTY FastStartFailoverTarget='<standby_db_unique_name>';\nEDIT DATABASE '<standby_db_unique_name>' SET PROPERTY FastStartFailoverTarget='<primary_db_unique_name>';\nEDIT CONFIGURATION SET PROPERTY FastStartFailoverThreshold=30;\n# 2) Sifir veri kaybi icin MaxAvailability (SYNC/FASTSYNC transport):\nEDIT DATABASE '<primary_db_unique_name>' SET PROPERTY LogXptMode='FASTSYNC';\nEDIT DATABASE '<standby_db_unique_name>' SET PROPERTY LogXptMode='FASTSYNC';\nEDIT CONFIGURATION SET PROTECTION MODE AS MAXAVAILABILITY;\n# MaxPerformance'ta kabul edilen kayip: EDIT CONFIGURATION SET PROPERTY FastStartFailoverLagLimit=30;\nENABLE FAST_START FAILOVER;\n# 3) Observer: primary ve standby disinda ucuncu bir sunucuda (wallet ile parolasiz baglanti)\ndgmgrl /@<primary_tns> \"START OBSERVER obs1 IN BACKGROUND FILE IS '/u01/app/oracle/dg/fsfo_obs1.dat' LOGFILE IS '/u01/app/oracle/dg/obs1.log' CONNECT IDENTIFIER IS <primary_tns>\"\n# 4) Dogrula:\nSHOW FAST_START FAILOVER;\nSHOW OBSERVER;","what":"Primary erişilemez olduğunda observer'ın eşik süresi sonunda standby'a otomatik failover yapmasını ve eski primary geri gelince onu otomatik reinstate etmesini sağlar.","when":"İnsan müdahalesi beklemeden dakikalar içinde RTO hedeflenen kritik sistemlerde.","caution":"Observer primary veya standby ile aynı sunucuda/veri merkezinde çalışmamalı; aksi halde site kaybında FSFO çalışmaz veya ağ bölünmesinde yanlış karar verebilir. Her iki veritabanında flashback açık olmalı. Threshold çok düşükse kısa ağ dalgalanmaları gereksiz failover'a yol açar. Planlı bakımda primary'yi kapatmadan önce DISABLE FAST_START FAILOVER veya SHUTDOWN öncesi observer'ı hesaba kat.","since":"12c","note":"FASTSYNC 12.2+, IN BACKGROUND ve birden çok observer (SHOW OBSERVER) 12.2+. IN BACKGROUND Oracle wallet (mkstore) ile kimlik bilgisi gerektirir.","tags":["data guard","fsfo","fast-start failover","observer","otomatik failover","maxavailability","dgmgrl"],"untested":true},{"id":"dg-snapshot-standby","task":"Physical standby'ı snapshot standby'a çevir ve geri al (test ortamı)","category":"Data Guard","command":"# Standby'i okunur-yazilir yap (redo alinmaya devam eder, apply durur):\nCONVERT DATABASE '<standby_db_unique_name>' TO SNAPSHOT STANDBY;\nSHOW DATABASE '<standby_db_unique_name>';\n# ... test / uygulama dogrulamasi ...\n# Geri cevir: testteki tum degisiklikler silinir, birikmis redo uygulanir\nCONVERT DATABASE '<standby_db_unique_name>' TO PHYSICAL STANDBY;\nSHOW CONFIGURATION;","what":"Standby'da otomatik guaranteed restore point oluşturup veritabanını read-write açar; geri çevirirken o noktaya flashback yapar ve primary'den gelen birikmiş redo'yu uygular.","when":"Üretim verisi üzerinde upgrade provası, uygulama sürüm testi veya Real Application Testing (DB Replay) çalıştırmak için, ayrı bir kopya oluşturmadan.","caution":"Snapshot standby süresince redo uygulanmaz: RPO korunur ama failover süresi (RTO) birikmiş redo kadar uzar ve FSFO hedefi olamaz. Flashback logları FRA'yı doldurabilir; FRA alanını izle. Snapshot'ta yapılan değişiklikler geri dönüşte kalıcı olarak silinir.","note":"SQL karşılığı: ALTER DATABASE CONVERT TO SNAPSHOT STANDBY / CONVERT TO PHYSICAL STANDBY (broker yoksa).","tags":["data guard","snapshot standby","test","restore point","flashback","convert","dgmgrl"],"untested":true},{"id":"rman-catalog-create","task":"RMAN recovery catalog oluştur ve veritabanını kaydet","category":"RMAN","command":"-- 1) Katalog veritabaninda (ayri DB/PDB), sqlplus ile:\nCREATE TABLESPACE rcat_ts DATAFILE '/u02/oradata/RCAT/rcat01.dbf' SIZE 1G AUTOEXTEND ON NEXT 256M;\nCREATE USER rcat IDENTIFIED BY \"<password>\"\n  DEFAULT TABLESPACE rcat_ts QUOTA UNLIMITED ON rcat_ts;\nGRANT RECOVERY_CATALOG_OWNER TO rcat;\n# 2) Kabuktan: katalog semasini olustur\nrman catalog rcat@<rcat_tns>\nCREATE CATALOG;\n# 3) Hedef veritabanini kaydet ve dogrula:\nrman target / catalog rcat@<rcat_tns>\nREGISTER DATABASE;\nREPORT SCHEMA;\n# Controlfile'daki kayitlari kataloga esitle (yedekten sonra otomatik yapilir):\nRESYNC CATALOG;","what":"Yedek meta verisini controlfile'ın tutma süresinden (control_file_record_keep_time) bağımsız, merkezi bir şemada saklayan recovery catalog'u kurar ve hedef veritabanını kaydeder.","when":"Çok sayıda veritabanının yedek geçmişini tek yerde tutmak, Data Guard'da primary/standby yedeklerini birbirinin yerine kullanmak, uzun süreli (KEEP) yedekler ve stored script için.","caution":"Katalog veritabanı yedeklenen veritabanlarından ayrı bir sunucuda olmalı ve kendisi de yedeklenmelidir. Katalog şeması sürümü kullanılan en yeni RMAN istemcisinden düşük olamaz; yeni sürüm istemcide UPGRADE CATALOG gerekir. Data Guard'da yalnız primary REGISTER edilir; standby'lar DB_UNIQUE_NAME ile CONFIGURE DB_UNIQUE_NAME ... CONNECT IDENTIFIER tanımlanır.","note":"Catalog şeması ayrı bir veritabanında tutulmalı; hedef veritabanıyla aynı yerde olursa felakette catalog da kaybolur.","tags":["rman","catalog","katalog","recovery catalog","register","yedek","backup"],"untested":true},{"id":"rman-duplicate-standby","task":"RMAN DUPLICATE ile active database'den physical standby oluştur","category":"RMAN","command":"# On kosullar: standby'da yalniz db_name iceren pfile ile instance NOMOUNT,\n# primary'nin password file'i kopyalanmis, her iki tarafta static listener kaydi ve tnsnames.\nrman target sys@<primary_tns> auxiliary sys@<standby_tns>\nRUN {\n  ALLOCATE CHANNEL p1 DEVICE TYPE DISK;\n  ALLOCATE CHANNEL p2 DEVICE TYPE DISK;\n  ALLOCATE AUXILIARY CHANNEL s1 DEVICE TYPE DISK;\n  ALLOCATE AUXILIARY CHANNEL s2 DEVICE TYPE DISK;\n  DUPLICATE TARGET DATABASE FOR STANDBY FROM ACTIVE DATABASE\n    USING COMPRESSED BACKUPSET SECTION SIZE 32G\n    DORECOVER\n    SPFILE\n      SET db_unique_name='<standby_db_unique_name>'\n      SET control_files='+DATA','+FRA'\n      SET db_create_file_dest='+DATA'\n      SET db_recovery_file_dest='+FRA'\n      SET fal_server='<primary_tns>'\n      SET log_archive_dest_2=''\n      SET dg_broker_start='FALSE'\n    NOFILENAMECHECK;\n}","what":"Primary'nin datafile'larını ağ üzerinden (ara yedek dosyası olmadan) standby sunucuya kopyalar, spfile'ı standby'a uyarlayarak oluşturur ve DORECOVER ile mevcut archivelog'ları uygular.","when":"Yeni Data Guard standby kurulumunda veya reinstate edilemeyen standby'ı yeniden oluşturmada.","caution":"Primary'de ağ ve I/O yükü oluşturur; yoğun saatlerde çalıştırma veya kanal sayısını sınırla. NOFILENAMECHECK yalnız standby AYRI sunucudaysa güvenlidir; aynı sunucuda primary dosyalarının üzerine yazabilir. Standby redo log'ları (primary'deki online redo boyutunda, thread başına +1 grup) önceden veya sonradan eklenmeli; ardından broker yapılandırılır.","since":"12c","note":"USING [COMPRESSED] BACKUPSET ve SECTION SIZE ile active duplicate 12c+; 11g'de image copy ile çalışır. ASM yerine dosya sistemi kullanılıyorsa db_file_name_convert/log_file_name_convert ayarla.","tags":["rman","duplicate","standby","active database","data guard","kurulum","clone"],"untested":true},{"id":"rman-crosscheck-cleanup","task":"RMAN yedek kayıtlarını doğrula ve temizle (CROSSCHECK, EXPIRED, OBSOLETE)","category":"RMAN","command":"SHOW RETENTION POLICY;\n# 1) Kayitlari fiziksel dosyalarla karsilastir (bulunamayanlar EXPIRED olur):\nCROSSCHECK BACKUP;\nCROSSCHECK COPY;\nCROSSCHECK ARCHIVELOG ALL;\n# 2) Silmeden once gozden gecir:\nLIST EXPIRED BACKUP;\nLIST EXPIRED ARCHIVELOG ALL;\nREPORT OBSOLETE;\n# 3) Temizle:\nDELETE NOPROMPT EXPIRED BACKUP;\nDELETE NOPROMPT EXPIRED COPY;\nDELETE NOPROMPT EXPIRED ARCHIVELOG ALL;\nDELETE NOPROMPT OBSOLETE;","what":"CROSSCHECK, RMAN kayıtlarındaki yedeklerin diskte/teyp'te hâlâ bulunup bulunmadığını kontrol eder; DELETE EXPIRED kayıp dosyaların kayıtlarını, DELETE OBSOLETE retention policy'ye göre artık gerekmeyen yedekleri hem kayıttan hem diskten siler.","when":"Yedek dosyaları OS seviyesinde silindiğinde/taşındığında, FRA dolduğunda ve düzenli yedek bakım işinin parçası olarak.","caution":"DELETE OBSOLETE dosyaları fiziksel olarak siler; önce REPORT OBSOLETE ile listeyi doğrula ve retention policy'nin (RECOVERY WINDOW / REDUNDANCY) beklediğin gibi olduğundan emin ol. Teyp/medya yöneticisi geçici erişilemezken CROSSCHECK çalıştırırsan geçerli yedekler EXPIRED görünür; DELETE EXPIRED'ı o anda çalıştırma.","note":"Data Guard'da archivelog silme politikası için CONFIGURE ARCHIVELOG DELETION POLICY TO APPLIED ON ALL STANDBY kullan.","tags":["rman","crosscheck","expired","obsolete","temizlik","retention","yedek"],"untested":true},{"id":"rman-validate","task":"Veritabanını ve yedekleri bozulmaya karşı doğrula (VALIDATE)","category":"RMAN","command":"# Fiziksel + mantiksal blok kontrolu (yedek uretmeden):\nVALIDATE CHECK LOGICAL DATABASE;\n# Buyuk datafile'lari paralel tara (11g+, birden cok kanal gerekir):\nVALIDATE CHECK LOGICAL DATABASE SECTION SIZE 16G;\n# Tek datafile / tablespace:\nVALIDATE DATAFILE 7;\nVALIDATE TABLESPACE users;\n# Yedek alir gibi okuyup kontrol et (archivelog dahil):\nBACKUP VALIDATE CHECK LOGICAL DATABASE ARCHIVELOG ALL;\n# Belirli bir yedek setinin okunabilirligi:\nLIST BACKUP SUMMARY;\nVALIDATE BACKUPSET <bs_key>;\n-- Bulunan bozuk bloklar ve etkilenen segment (SQL):\nSELECT file#, block#, blocks, corruption_change#, corruption_type\nFROM   v$database_block_corruption ORDER BY file#, block#;\nSELECT DISTINCT e.owner, e.segment_name, e.segment_type\nFROM   dba_extents e\nJOIN   v$database_block_corruption c\n  ON   e.file_id = c.file#\n AND   c.block# BETWEEN e.block_id AND e.block_id + e.blocks - 1;","what":"Datafile'ları ve yedek setlerini okuyarak fiziksel ve (CHECK LOGICAL ile) mantıksal blok bozulmalarını tespit eder; bulunanları v$database_block_corruption'a yazar. SQL sorgusu bozuk bloğun hangi tablo/index'e ait olduğunu gösterir.","when":"ORA-01578/ORA-08103 gibi bozulma hatalarından sonra, depolama sorunlarının ardından ve düzenli (haftalık) bütünlük kontrolü olarak; yedeklerin gerçekten restore edilebilir olduğunu kanıtlamak için.","caution":"Tam okuma yapar; büyük veritabanlarında ciddi I/O yükü oluşturur, yoğun saatlerin dışında çalıştır. dba_extents sorgusu büyük veritabanlarında yavaş olabilir. Bozuk blok geçici (TEMP) veya boş alandaysa nesne eşleşmesi dönmez.","since":"11g","note":"Bozulma yoksa sorgular boş döner. SECTION SIZE ile VALIDATE 11g+.","tags":["rman","validate","bozulma","corruption","check logical","blok","ora-01578"],"untested":true},{"id":"rman-restore-preview","task":"Restore öncesi hangi yedeklerin kullanılacağını gör ve yedekleri doğrula (PREVIEW / VALIDATE)","category":"RMAN","command":"# Kullanilacak yedekler ve gereken archivelog'lar (dosya okumadan):\nRESTORE DATABASE PREVIEW SUMMARY;\n# Belirli bir zamana donus icin:\nRESTORE DATABASE UNTIL TIME \"TO_DATE('2026-01-15 03:00:00','YYYY-MM-DD HH24:MI:SS')\" PREVIEW;\n# Yedekleri gercekten okuyarak dogrula (restore etmeden):\nRESTORE DATABASE VALIDATE;\nRESTORE ARCHIVELOG FROM TIME 'SYSDATE-1' VALIDATE;\nRESTORE CONTROLFILE VALIDATE;\nRESTORE SPFILE VALIDATE;","what":"PREVIEW, bir restore'un hangi backup set/copy'leri ve hangi archivelog aralığını kullanacağını katalog/controlfile'dan raporlar; VALIDATE bu yedekleri gerçekten okuyup bozulma ve eksik dosya olmadığını doğrular.","when":"Gerçek bir restore'dan önce planlama için, yedek stratejisinin RPO hedefini karşıladığını kanıtlamak için ve periyodik restore testi olarak.","caution":"PREVIEW yalnız kayıtlara bakar; dosya silinmişse yanıltır, bu yüzden önce CROSSCHECK çalıştır veya RESTORE ... VALIDATE kullan. VALIDATE tüm yedeği okur; teyp/ağ üzerinde uzun sürebilir. Tarih formatı oturumun NLS ayarına değil TO_DATE maskesine bağlı olsun.","note":"PREVIEW RECALL ile teypten geri çağrılması gereken yedekler de istenebilir (media manager desteği gerekir).","tags":["rman","restore","preview","validate","restore testi","yedek","rpo"],"untested":true},{"id":"rman-block-media-recovery","task":"Bozuk blokları online onar (block media recovery, RECOVER CORRUPTION LIST)","category":"RMAN","command":"# 1) Bozuk bloklari tespit et (v$database_block_corruption dolar):\nVALIDATE CHECK LOGICAL DATABASE;\n# 2) Listedeki tum bloklari onar (datafile online kalir):\nRECOVER CORRUPTION LIST;\n# veya hata mesajindaki dosya/blok (ORA-01578: file# 7, block# 233):\nRECOVER DATAFILE 7 BLOCK 233;\nRECOVER DATAFILE 7 BLOCK 233 DATAFILE 9 BLOCK 1001;\n# 3) Dogrula:\nVALIDATE DATAFILE 7;\nSELECT * FROM v$database_block_corruption;","what":"Yalnız bozuk blokları yedekten (veya flashback log'larından / Active Data Guard standby'dan) geri yükleyip redo ile güncel hale getirir; datafile ve tablespace online kalır, uygulama yalnız o bloklara erişirken hata alır.","when":"ORA-01578 / ORA-01110 ile tek tük blok bozulması görüldüğünde; tüm datafile'ı restore etmenin gereksiz kesinti yaratacağı durumlarda.","caution":"Bloğu içeren temiz bir yedek ve o andan bugüne tüm archivelog'lar gerekir; NOLOGGING işlemden kaynaklı bozulma (ORA-26040) bu yolla onarılamaz, nesneyi yeniden oluşturman gerekir. Enterprise Edition özelliğidir. Bozulmanın kaynağını (depolama, HBA, firmware) bulmadan onarım tekrarlar.","note":"Active Data Guard varsa 11.2+ automatic block media recovery bozuk blokları standby'dan otomatik onarır.","tags":["rman","block recovery","bozuk blok","corruption","ora-01578","recover","onar"],"untested":true},{"id":"rman-tspitr","task":"Tablespace'i geçmiş bir zamana geri döndür (TSPITR)","category":"RMAN","command":"-- 1) Tablespace self-contained mi (SQL, hedef DB'de):\nEXEC DBMS_TTS.TRANSPORT_SET_CHECK(ts_list => 'USERS', incl_constraints => TRUE, full_check => TRUE);\nSELECT * FROM transport_set_violations;\n-- 2) Hedef zamandan SONRA olusturulmus ve TSPITR ile kaybolacak nesneler:\nSELECT owner, name, tablespace_name,\n       TO_CHAR(creation_time,'YYYY-MM-DD HH24:MI:SS') AS created\nFROM   ts_pitr_objects_to_be_dropped\nWHERE  tablespace_name = 'USERS'\n  AND  creation_time > TO_DATE('2026-01-15 03:00:00','YYYY-MM-DD HH24:MI:SS');\n# 3) RMAN: otomatik auxiliary instance ile\nRECOVER TABLESPACE users\n  UNTIL TIME \"TO_DATE('2026-01-15 03:00:00','YYYY-MM-DD HH24:MI:SS')\"\n  AUXILIARY DESTINATION '/u03/aux';\n# 4) Tablespace OFFLINE birakilir: once yedek al, sonra online yap\nBACKUP TABLESPACE users;\nALTER TABLESPACE users ONLINE;","what":"RMAN geçici bir auxiliary instance'ta SYSTEM/UNDO/SYSAUX ve hedef tablespace'i istenen zamana kadar kurtarır, ardından transportable tablespace ile hedef veritabanına geri takar; veritabanının geri kalanı bugünde kalır.","when":"Hatalı bir toplu işlem veya yanlış DROP/TRUNCATE yalnız bir tablespace'teki (veya kendi içinde tutarlı bir tablespace kümesindeki) veriyi bozduğunda ve flashback seçenekleri yetersizken.","caution":"Hedef zamandan sonra o tablespace'te yapılan TÜM değişiklikler ve oluşturulan nesneler kaybolur. Tablespace kümesi self-contained olmalı (index/tablo, partition, LOB, FK başka tablespace'te olmamalı). SYSTEM, UNDO ve SYS nesneleri içeren tablespace'ler için kullanılamaz. TSPITR sonrası o tablespace için önceki yedekler kullanılamaz; hemen yedek al. AUXILIARY DESTINATION'da SYSTEM+SYSAUX+UNDO+hedef tablespace kadar boş alan gerekir.","note":"Tek tablo için rman-recover-table daha az yıkıcıdır.","tags":["rman","tspitr","tablespace","pitr","point-in-time","auxiliary","geri donus"],"untested":true},{"id":"rman-recover-table","task":"Tek bir tabloyu RMAN yedeğinden geçmiş bir zamana geri getir (RECOVER TABLE)","category":"RMAN","command":"# Yeni adla geri yukle (orijinal tabloya dokunmaz):\nRECOVER TABLE hr.employees\n  UNTIL TIME \"TO_DATE('2026-01-15 03:00:00','YYYY-MM-DD HH24:MI:SS')\"\n  AUXILIARY DESTINATION '/u03/aux'\n  REMAP TABLE hr.employees:employees_rec;\n# Multitenant: PDB icindeki tablo\nRECOVER TABLE hr.employees OF PLUGGABLE DATABASE <pdb>\n  UNTIL SCN 12345678\n  AUXILIARY DESTINATION '/u03/aux'\n  REMAP TABLE hr.employees:employees_rec;\n# Sadece Data Pump dump uret, ice aktarma:\nRECOVER TABLE hr.employees\n  UNTIL SCN 12345678\n  AUXILIARY DESTINATION '/u03/aux'\n  DATAPUMP DESTINATION '/u03/dump'\n  DUMP FILE 'employees_rec.dmp'\n  NOTABLEIMPORT;","what":"RMAN otomatik bir auxiliary instance'ı istenen zamana kadar kurtarır, tabloyu (veya partition'ı) Data Pump ile dışa aktarır ve hedef veritabanına REMAP ile farklı adla içe aktarır; auxiliary instance sonra silinir.","when":"Flashback Table/Query undo süresini aşan, yanlışlıkla silinmiş/güncellenmiş veya DROP PURGE edilmiş tek tablonun verisini kurtarmak için.","caution":"AUXILIARY DESTINATION'da SYSTEM, SYSAUX, UNDO ve tablonun tablespace'i kadar boş alan gerekir; işlem saatler sürebilir. REMAP TABLE kullanmazsan aynı adlı tablo varsa işlem hata verir; orijinali ezmemek için daima REMAP veya NOTABLEIMPORT kullan. SYS/SYSTEM şemasındaki ve SYSTEM/SYSAUX tablespace'indeki tablolar bu yöntemle kurtarılamaz. Enterprise Edition gerekir.","since":"12c","note":"Gerekli: hedef zamanı kapsayan tam yedek + archivelog'lar. Partition için: RECOVER TABLE hr.sales:p2025 ... REMAP TABLE hr.sales:p2025:sales_p2025_rec.","tags":["rman","recover table","tablo kurtarma","pitr","auxiliary","remap","yanlis silme"],"untested":true},{"id":"pdb-create-from-seed","task":"PDB$SEED'den yeni PDB oluştur","category":"Multitenant","command":"-- CDB$ROOT'ta, SYSDBA ile:\nCREATE PLUGGABLE DATABASE <pdb>\n  ADMIN USER pdbadmin IDENTIFIED BY \"<password>\" ROLES = (DBA)\n  DEFAULT TABLESPACE users\n    DATAFILE '/u02/oradata/<cdb>/<pdb>/users01.dbf' SIZE 512M AUTOEXTEND ON NEXT 64M\n  FILE_NAME_CONVERT = ('/u02/oradata/<cdb>/pdbseed/', '/u02/oradata/<cdb>/<pdb>/')\n  STORAGE (MAXSIZE 50G);\n-- OMF/ASM kullaniliyorsa FILE_NAME_CONVERT yerine: CREATE_FILE_DEST = '+DATA'\nALTER PLUGGABLE DATABASE <pdb> OPEN;\nALTER PLUGGABLE DATABASE <pdb> SAVE STATE;\nSELECT con_id, name, open_mode, restricted FROM v$pdbs ORDER BY con_id;","what":"Seed şablonundan yeni, boş bir pluggable database oluşturur; yerel yönetici kullanıcısını, varsayılan tablespace'i ve toplam boyut sınırını aynı komutta tanımlar.","when":"Yeni uygulama/şema için izole veritabanı açarken; test ve geliştirme ortamı hazırlarken.","caution":"Oluşturulan PDB MOUNTED durumda gelir; OPEN ve (CDB restart sonrası açık kalması için) SAVE STATE gerekir. FILE_NAME_CONVERT yolları hatalıysa dosyalar yanlış dizine yazılır; OMF yoksa DATAFILE için tam dosya yolu zorunludur (ORA-02236). Lisans: 19c'de EE'de multitenant opsiyonu olmadan CDB başına 3 kullanıcı PDB'si kullanılabilir.","since":"12c","note":"RAC'ta PDB'ye uygulama service'i srvctl add service -pdb ile eklenir.","tags":["multitenant","pdb","olustur","create pluggable database","seed","cdb","pdb$seed"]},{"id":"pdb-clone-local","task":"PDB'yi aynı CDB içinde klonla (local / hot clone)","category":"Multitenant","command":"-- Hot clone on kosullari: local undo + ARCHIVELOG\nSELECT property_value AS local_undo\nFROM   database_properties WHERE property_name = 'LOCAL_UNDO_ENABLED';\nSELECT log_mode FROM v$database;\n\nCREATE PLUGGABLE DATABASE <new_pdb> FROM <pdb>\n  FILE_NAME_CONVERT = ('/<pdb>/', '/<new_pdb>/');\n-- OMF/ASM: CREATE PLUGGABLE DATABASE <new_pdb> FROM <pdb> CREATE_FILE_DEST = '+DATA';\nALTER PLUGGABLE DATABASE <new_pdb> OPEN;\nSELECT name, open_mode FROM v$pdbs WHERE name = UPPER('<new_pdb>');","what":"Kaynak PDB'nin datafile'larını kopyalayarak aynı CDB'de yeni bir PDB oluşturur; local undo ve ARCHIVELOG ile kaynak read-write açıkken (hot clone) yapılabilir.","when":"Üretim PDB'sinden test/geliştirme kopyası, upgrade veya patch provası, riskli değişiklik öncesi hızlı kopya almak için.","caution":"Kopyalama süresince kaynakta ek I/O oluşur ve hedefte kaynak kadar alan gerekir. Shared undo modunda veya NOARCHIVELOG'da kaynak READ ONLY olmalıdır (19c dokümantasyonu). Klon üretim verisi içerir: maskeleme, DB link'ler, job'lar (DBMS_SCHEDULER) ve dış sistem bağlantıları açılmadan önce kontrol edilmeli.","since":"12c","note":"Kaynak read-write iken hot clone için 19c'de local undo + ARCHIVELOG gerekir. Hızlı ince kopya için SNAPSHOT COPY (uygun depolama gerekir).","tags":["multitenant","pdb","clone","klon","hot clone","kopya","local undo"]},{"id":"pdb-clone-remote","task":"PDB'yi başka bir CDB'den DB link üzerinden klonla (remote clone)","category":"Multitenant","command":"-- 1) KAYNAK CDB'de ortak kullanici:\nCREATE USER c##clone_user IDENTIFIED BY \"<password>\" CONTAINER = ALL;\nGRANT CREATE SESSION, CREATE PLUGGABLE DATABASE TO c##clone_user CONTAINER = ALL;\n\n-- 2) HEDEF CDB root'unda DB link ve test:\nCREATE DATABASE LINK clone_link\n  CONNECT TO c##clone_user IDENTIFIED BY \"<password>\"\n  USING '//<source_host>:1521/<source_cdb_service>';\nSELECT * FROM dual@clone_link;\n\n-- 3) Klonla ve ac:\nCREATE PLUGGABLE DATABASE <new_pdb> FROM <pdb>@clone_link\n  FILE_NAME_CONVERT = ('/<pdb>/', '/<new_pdb>/');\nALTER PLUGGABLE DATABASE <new_pdb> OPEN;\n\n-- 4) Uyumsuzluklar (surum, opsiyon, parametre, patch):\nSELECT name, cause, type, message\nFROM   pdb_plug_in_violations\nWHERE  name = UPPER('<new_pdb>') AND status <> 'RESOLVED';","what":"Kaynak CDB'deki bir PDB'yi DB link üzerinden ağ ile hedef CDB'ye kopyalar; ara dosya veya unplug gerekmez.","when":"PDB'yi başka sunucuya/CDB'ye taşımak, üretimden ayrı sunucuda test kopyası oluşturmak veya daha yeni sürümlü CDB'ye geçmek için.","caution":"Kaynak ve hedef CDB'nin endian'ı, karakter seti (veya hedef AL32UTF8) ve opsiyonları uyumlu olmalı; daha yeni sürüme klonlanan PDB ilk açılışta RESTRICTED olur ve datapatch/upgrade gerekir. Klon bitince DB link'i ve ortak kullanıcıyı kaldır. Hot clone için kaynakta local undo + ARCHIVELOG gerekir.","since":"12c","note":"Taşıma (kaynak kalkar) için 12.2+ RELOCATE seçeneği: CREATE PLUGGABLE DATABASE <pdb> FROM <pdb>@clone_link RELOCATE.","tags":["multitenant","pdb","remote clone","db link","klon","tasima","relocate"]},{"id":"pdb-unplug-plug","task":"PDB'yi unplug et ve başka (veya aynı) CDB'ye plug et","category":"Multitenant","command":"-- KAYNAK CDB: kapat ve XML manifest'e unplug et\nALTER PLUGGABLE DATABASE <pdb> CLOSE IMMEDIATE;\nALTER PLUGGABLE DATABASE <pdb> UNPLUG INTO '/u01/stage/<pdb>.xml';\n-- (Tek dosya arsivi: UNPLUG INTO '/u01/stage/<pdb>.pdb' - datafile'lar dahil, 12.2+)\nDROP PLUGGABLE DATABASE <pdb> KEEP DATAFILES;\n\n-- HEDEF CDB: once uyumlulugu kontrol et\nSET SERVEROUTPUT ON\nDECLARE\n  l_ok BOOLEAN;\nBEGIN\n  l_ok := DBMS_PDB.CHECK_PLUG_COMPATIBILITY(\n            pdb_descr_file => '/u01/stage/<pdb>.xml',\n            pdb_name       => '<pdb>');\n  DBMS_OUTPUT.PUT_LINE(CASE WHEN l_ok THEN 'COMPATIBLE' ELSE 'NOT COMPATIBLE - see PDB_PLUG_IN_VIOLATIONS' END);\nEND;\n/\nSELECT name, cause, type, status, message\nFROM   pdb_plug_in_violations\nWHERE  name = UPPER('<pdb>') AND status <> 'RESOLVED';\n\n-- Dosyalar yerinde kaliyorsa NOCOPY, baska konuma kopyalanacaksa COPY FILE_NAME_CONVERT:\nCREATE PLUGGABLE DATABASE <pdb> USING '/u01/stage/<pdb>.xml' NOCOPY TEMPFILE REUSE;\n-- .pdb arsivinden: CREATE PLUGGABLE DATABASE <pdb> USING '/u01/stage/<pdb>.pdb'\n--                    FILE_NAME_CONVERT = ('/u01/stage/', '/u02/oradata/<cdb>/<pdb>/');\nALTER PLUGGABLE DATABASE <pdb> OPEN;","what":"PDB'yi CDB'den ayırıp meta verisini XML manifest'e (veya datafile'larla birlikte tek .pdb arşivine) yazar; hedef CDB'de uyumluluk kontrolünden sonra aynı dosyalarla yeniden takar.","when":"PDB'yi aynı sunucudaki daha yeni sürümlü CDB'ye taşımak (unplug/plug upgrade), CDB konsolidasyonu veya ağ üzerinden klonun mümkün olmadığı taşımalar için.","caution":"Unplug sonrası PDB kaynak CDB'de kullanılamaz (kesinti). NOCOPY ile plug edilen dosyalar artık hedef CDB'ye aittir; hata durumunda geri dönüş için önce dosya seviyesinde kopya veya RMAN yedeği al. ERROR tipindeki violation'lar çözülmeden PDB RESTRICTED açılır. Aynı CDB'ye geri takarken AS CLONE kullanmazsan aynı GUID ile çakışma olabilir.","since":"12c","note":".pdb arşivi (12.2+) datafile'ları da içerdiği için tek dosyayla taşınır; XML yönteminde datafile'lar ayrıca kopyalanır.","tags":["multitenant","pdb","unplug","plug","tasima","xml manifest","check_plug_compatibility"]},{"id":"pdb-open-save-state","task":"PDB'leri aç ve CDB yeniden başlatıldığında açık kalmasını sağla (SAVE STATE)","category":"Multitenant","command":"-- Tum PDB'leri ac (RAC: INSTANCES = ALL):\nALTER PLUGGABLE DATABASE ALL OPEN;\n-- ALTER PLUGGABLE DATABASE <pdb> OPEN INSTANCES = ALL;\n-- Mevcut acik durumu kaydet (CDB restart sonrasi otomatik acilir):\nALTER PLUGGABLE DATABASE <pdb> SAVE STATE;\n-- Kaydedilmis durumlar:\nSELECT con_name, instance_name, state, restricted FROM dba_pdb_saved_states;\n-- Kaydi kaldir:\nALTER PLUGGABLE DATABASE <pdb> DISCARD STATE;\n-- RESTRICTED aciliyorsa nedenini gor:\nSELECT name, cause, type, message\nFROM   pdb_plug_in_violations\nWHERE  status <> 'RESOLVED';","what":"PDB'leri READ WRITE açar ve o anki açık durumunu kaydederek CDB yeniden başladığında PDB'nin otomatik aynı moda açılmasını sağlar.","when":"Yeni PDB oluşturulduktan, plug/clone edildikten sonra; CDB yeniden başlatıldığında PDB'lerin MOUNTED kaldığı fark edildiğinde.","caution":"SAVE STATE komut anındaki durumu kaydeder: PDB kapalıyken çalıştırırsan \"kapalı\" durumu kaydedilir (veya kayıt silinir). RAC'ta durum instance bazındadır; servis tabanlı yönetimde (srvctl ile PDB service'leri) SAVE STATE yerine Clusterware açılışı tercih edilir. Data Guard standby'da open mode rolüne göre farklıdır.","since":"12c","note":"12.1.0.2+.","tags":["multitenant","pdb","open","save state","otomatik acilis","restricted","dba_pdb_saved_states"]},{"id":"pdb-resource-limits","task":"PDB başına CPU, bellek, I/O ve depolama sınırı koy","category":"Multitenant","command":"ALTER SESSION SET CONTAINER = <pdb>;\n-- CPU (Resource Manager ile instance caging; 19c'de PDB duzeyinde):\nALTER SYSTEM SET cpu_count = 2 SCOPE = BOTH;\n-- Bellek (sga_min_size garanti, sga_target ust sinir):\nALTER SYSTEM SET sga_target = 512M SCOPE = BOTH;\nALTER SYSTEM SET sga_min_size = 96M SCOPE = BOTH;\nALTER SYSTEM SET pga_aggregate_limit = 2G SCOPE = BOTH;\n-- I/O (Exadata disi):\nALTER SYSTEM SET max_iops = 5000 SCOPE = BOTH;\nALTER SYSTEM SET max_mbps = 200 SCOPE = BOTH;\n-- Oturum sayisi (PDB yeniden acilinca):\nALTER SYSTEM SET sessions = 200 SCOPE = SPFILE;\n-- Depolama:\nALTER PLUGGABLE DATABASE STORAGE (MAXSIZE 10G MAX_SHARED_TEMP_SIZE 2G);\n\n-- Root'tan tum PDB'lerdeki ayarlar:\nALTER SESSION SET CONTAINER = CDB$ROOT;\nSELECT p.name AS pdb, sp.name, sp.value\nFROM   v$system_parameter sp JOIN v$pdbs p ON p.con_id = sp.con_id\nWHERE  sp.name IN ('cpu_count','sga_target','sga_min_size','max_iops','max_mbps','pga_aggregate_limit')\nORDER  BY p.name, sp.name;","what":"Bir PDB'nin CDB kaynaklarından kullanabileceği CPU, SGA/PGA, IOPS/MBPS ve toplam depolama miktarını PDB düzeyindeki parametrelerle sınırlar; \"gürültülü komşu\" PDB'lerin diğerlerini etkilemesini önler.","when":"Konsolide CDB'lerde, farklı SLA'lı uygulamaları aynı CDB'de çalıştırırken veya bir PDB'nin tüm sunucu kaynağını tükettiği görüldüğünde.","caution":"PDB sga_target CDB sga_target'ından küçük olmalı; çok düşük değerler ORA-04031 ve performans sorunlarına yol açar. sga_min_size toplamı CDB SGA'nın tamamını rezerve etmemeli. PDB'de cpu_count etkili olması için CDB'de bir resource manager planı aktif olmalı. MAXSIZE dolunca PDB'de ORA-65114 alınır.","since":"12c","note":"23ai sga_min_size'ı sga_target'ın %20'sinden küçük olmaya zorladı (ORA-56746), 19c'de sınır %50'dir. MAX_IOPS/MAX_MBPS 12.2+, PDB bellek parametreleri 12.2+.","tags":["multitenant","pdb","kaynak","resource","cpu_count","sga_target","maxsize"]},{"id":"pdb-container-context","task":"Hangi container'da olduğunu doğrula ve tüm PDB'leri root'tan sorgula (CDB_ / CONTAINERS)","category":"Multitenant","command":"-- Su anki container:\nSHOW CON_NAME\nSHOW CON_ID\nSHOW PDBS\nSELECT SYS_CONTEXT('USERENV','CON_NAME') AS con_name,\n       SYS_CONTEXT('USERENV','CON_ID')   AS con_id\nFROM   dual;\n\n-- Root'tan tum container'lar:\nSELECT con_id, name, open_mode FROM v$containers ORDER BY con_id;\n\n-- CDB_ gorunumleri acik tum PDB'leri CON_ID ile birlestirir:\nSELECT c.name AS container, t.tablespace_name, t.status\nFROM   cdb_tablespaces t JOIN v$containers c ON c.con_id = t.con_id\nORDER  BY c.name, t.tablespace_name;\n\n-- CONTAINERS() ile herhangi bir tablo/view'u tum PDB'lerde sorgula:\nSELECT con_id, COUNT(*) AS users\nFROM   CONTAINERS(dba_users)\nGROUP  BY con_id ORDER BY con_id;","what":"Oturumun bağlı olduğu container'ı gösterir; root'tan CDB_ view'ları ve CONTAINERS() ifadesiyle tüm açık PDB'lerdeki sözlük bilgisini tek sorguda toplar.","when":"DDL/parametre değişikliğinden önce doğru container'da olduğundan emin olmak ve tüm PDB'ler için alan, kullanıcı, nesne envanteri çıkarmak için.","caution":"Salt okunurdur. Root'ta (CDB$ROOT) yanlışlıkla uygulama nesnesi veya yerel kullanıcı oluşturma; ALTER SYSTEM root'ta tüm CDB'yi etkiler. CDB_ ve CONTAINERS() yalnız açık PDB'leri döndürür; MOUNTED PDB'ler sonuçta görünmez.","since":"12c","note":"Container değiştirme: ALTER SESSION SET CONTAINER = <pdb>; (bkz. rosetta \"Aktif veritabanını değiştir\").","tags":["multitenant","container","con_name","cdb_","containers","pdb","root"]},{"id":"pdb-refreshable-clone","task":"Refreshable PDB oluştur, tazele ve bağımsız PDB'ye dönüştür","category":"Multitenant","command":"-- Hedef CDB root'unda (kaynaga DB link hazir: bkz. pdb-clone-remote):\nCREATE PLUGGABLE DATABASE <new_pdb> FROM <pdb>@clone_link\n  FILE_NAME_CONVERT = ('/<pdb>/', '/<new_pdb>/')\n  REFRESH MODE EVERY 60 MINUTES;\nSELECT pdb_name, status, refresh_mode, refresh_interval, last_refresh_scn\nFROM   dba_pdbs WHERE pdb_name = UPPER('<new_pdb>');\n\n-- Yalniz READ ONLY acilabilir; elle tazelemek icin once kapat:\nALTER PLUGGABLE DATABASE <new_pdb> OPEN READ ONLY;\nALTER PLUGGABLE DATABASE <new_pdb> CLOSE IMMEDIATE;\nALTER PLUGGABLE DATABASE <new_pdb> REFRESH;\n\n-- Mod degistir (MANUAL) veya bagimsiz, yazilabilir PDB'ye cevir (geri alinamaz):\nALTER PLUGGABLE DATABASE <new_pdb> REFRESH MODE MANUAL;\nALTER PLUGGABLE DATABASE <new_pdb> REFRESH MODE NONE;\nALTER PLUGGABLE DATABASE <new_pdb> OPEN;","what":"Kaynak PDB'nin redo'sunu periyodik veya elle uygulayarak güncel tutulan bir kopya oluşturur; raporlama için READ ONLY açılır, REFRESH MODE NONE ile bağımsız read-write PDB'ye dönüştürülür.","when":"Üretimden düzenli tazelenen raporlama/test kopyası, kesinti süresi az PDB taşıma (son refresh + REFRESH MODE NONE) veya \"PDB düzeyinde ucuz standby\" ihtiyacında.","caution":"Refresh sırasında PDB kapalı olmalı; READ ONLY açıkken otomatik refresh bekler. Refresh için kaynakta gerekli archivelog'lar erişilebilir olmalı. REFRESH MODE NONE geri alınamaz; kopya artık tazelenemez. Kaynakta local undo + ARCHIVELOG gerekir. Gerçek DR için Data Guard'ın yerini tutmaz.","since":"12c","note":"12.2+. REFRESH MODE NONE yapılınca clone normal PDB'ye döner ve READ WRITE açılabilir; bu geri alınamaz.","tags":["multitenant","pdb","refreshable","refresh","tazele","raporlama","clone"]}]},"recipes/oracle-ops.json":{"engineId":"oracle","engine":"Oracle","order":2,"recipes":[{"id":"awr-snapshot-report","task":"AWR snapshot al ve iki snapshot arası AWR raporu üret","category":"Performans","command":"-- 1) Olay oncesi ve sonrasi manuel snapshot (CDB root'ta calistir):\nEXEC DBMS_WORKLOAD_REPOSITORY.CREATE_SNAPSHOT;\n\n-- 2) Snapshot listesini gor:\nSELECT snap_id,\n       TO_CHAR(begin_interval_time,'YYYY-MM-DD HH24:MI') AS begin_time,\n       TO_CHAR(end_interval_time,'YYYY-MM-DD HH24:MI')   AS end_time\nFROM   dba_hist_snapshot\nWHERE  dbid = (SELECT dbid FROM v$database)\nORDER  BY snap_id DESC\nFETCH FIRST 24 ROWS ONLY;\n\n-- 3a) Etkilesimli rapor (HTML/TEXT ve snap araligini sorar):\n-- @?/rdbms/admin/awrrpt.sql      (RAC: awrgrpt.sql, tek instance: awrrpti.sql)\n\n-- 3b) Script'ten TEXT rapor:\nSET LINESIZE 8000 PAGESIZE 0 TRIMSPOOL ON HEADING OFF FEEDBACK OFF\nSPOOL /tmp/awr_<begin_snap>_<end_snap>.txt\nSELECT output\nFROM   TABLE(DBMS_WORKLOAD_REPOSITORY.AWR_REPORT_TEXT(\n         l_dbid     => (SELECT dbid FROM v$database),\n         l_inst_num => (SELECT instance_number FROM v$instance),\n         l_bid      => <begin_snap>,\n         l_eid      => <end_snap>));\nSPOOL OFF\n-- HTML icin: DBMS_WORKLOAD_REPOSITORY.AWR_REPORT_HTML (ayni parametreler)","what":"Olay penceresini kapsayan iki AWR snapshot'ı arasında load profile, top wait event, top SQL ve instance istatistiklerini içeren raporu üretir; tablo fonksiyonu sayesinde rapor script'ten veya scheduler job'ından alınabilir.","when":"Belirli bir zaman aralığındaki yavaşlığı analiz ederken, yük testi/batch öncesi-sonrası karşılaştırma için, kapasite raporlamasında.","caution":"Diagnostics Pack lisansı gerektirir (CONTROL_MANAGEMENT_PACK_ACCESS='DIAGNOSTIC' veya 'DIAGNOSTIC+TUNING'); lisans yoksa parametreyi 'NONE' yap ve Statspack kullan. Aralık içinde instance restart varsa rapor üretilemez. 1 saatten uzun aralıklar ortalama alır ve kısa süreli spike'ları gizler; olay penceresini dar tut.","note":"PDB seviyesinde AWR (12.2+) için AWR_PDB_AUTOFLUSH_ENABLED=TRUE ve PDB içinde AWR_SNAPSHOT_TIME_OFFSET/AWR_PDB_MAX_PARALLEL_SLAVES ayarlarına bak; PDB içinden alınan rapor yalnızca o PDB'nin verisini gösterir. Snapshot aralığı/saklama: DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS(interval => 30, retention => 43200).","tags":["awr","awr raporu","snapshot","awrrpt","dbms_workload_repository","performans raporu","diagnostics pack"]},{"id":"awr-diff-report","task":"İki dönemi karşılaştıran AWR diff (compare period) raporu","category":"Performans","command":"-- Etkilesimli: @?/rdbms/admin/awrddrpt.sql   (RAC: awrgdrpt.sql)\n\n-- Script'ten: 1. donem (iyi) = <bid1>-<eid1>, 2. donem (kotu) = <bid2>-<eid2>\nSET LINESIZE 8000 PAGESIZE 0 TRIMSPOOL ON HEADING OFF FEEDBACK OFF\nSPOOL /tmp/awr_diff.txt\nSELECT output\nFROM   TABLE(DBMS_WORKLOAD_REPOSITORY.AWR_DIFF_REPORT_TEXT(\n         dbid1 => (SELECT dbid FROM v$database), inst_num1 => 1,\n         bid1  => <bid1>, eid1 => <eid1>,\n         dbid2 => (SELECT dbid FROM v$database), inst_num2 => 1,\n         bid2  => <bid2>, eid2 => <eid2>));\nSPOOL OFF\n-- HTML: DBMS_WORKLOAD_REPOSITORY.AWR_DIFF_REPORT_HTML","what":"İki snapshot aralığını yan yana koyar; DB time, wait event, load profile ve SQL bazında yüzde farkları gösterir. \"Dün iyiydi, bugün yavaş\" sorusuna doğrudan cevap verir.","when":"Upgrade/patch, parametre değişikliği, deploy veya istatistik toplama sonrası regresyon analizi; aynı saat dilimindeki iki günü karşılaştırma.","caution":"Diagnostics Pack lisansı gerekir. Karşılaştırılan dönemler aynı uzunlukta ve benzer iş yükünde olmalı; aksi halde farklar yanıltıcıdır. Farklı DB'ler (ör. prod vs test) karşılaştırılacaksa AWR verisini awrextr.sql/awrload.sql ile taşı ve dbid2'yi buna göre ver.","tags":["awr diff","karsilastirma","compare period","awrddrpt","regresyon","performans","diagnostics pack"]},{"id":"ash-top-activity","task":"ASH ile anlık/son dakikaların top wait event ve top SQL analizi","category":"Performans","command":"-- Son 30 dk: wait event dagilimi (her ornek ~1 sn aktif session zamani)\nSELECT NVL(event, 'ON CPU') AS event, wait_class,\n       COUNT(*) AS samples,\n       ROUND(RATIO_TO_REPORT(COUNT(*)) OVER () * 100, 1) AS pct\nFROM   v$active_session_history\nWHERE  sample_time > SYSTIMESTAMP - INTERVAL '30' MINUTE\nGROUP  BY NVL(event, 'ON CPU'), wait_class\nORDER  BY samples DESC\nFETCH FIRST 10 ROWS ONLY;\n\n-- Son 30 dk: top SQL (CPU / User I/O kirilimi ile)\nSELECT sql_id, sql_opname,\n       COUNT(*) AS samples,\n       SUM(CASE WHEN session_state = 'ON CPU' THEN 1 ELSE 0 END) AS cpu,\n       SUM(CASE WHEN wait_class = 'User I/O' THEN 1 ELSE 0 END)  AS user_io,\n       ROUND(RATIO_TO_REPORT(COUNT(*)) OVER () * 100, 1) AS pct\nFROM   v$active_session_history\nWHERE  sample_time > SYSTIMESTAMP - INTERVAL '30' MINUTE\n  AND  sql_id IS NOT NULL\nGROUP  BY sql_id, sql_opname\nORDER  BY samples DESC\nFETCH FIRST 10 ROWS ONLY;\n\n-- Daha eski donem: DBA_HIST_ACTIVE_SESS_HISTORY (10 sn'de bir ornek; COUNT(*)*10 = sn)\n\n-- Hazir ASH raporu (son 30 dk):\nSET LINESIZE 8000 PAGESIZE 0 TRIMSPOOL ON HEADING OFF FEEDBACK OFF\nSELECT output\nFROM   TABLE(DBMS_WORKLOAD_REPOSITORY.ASH_REPORT_TEXT(\n         l_dbid     => (SELECT dbid FROM v$database),\n         l_inst_num => (SELECT instance_number FROM v$instance),\n         l_btime    => SYSDATE - 30/1440,\n         l_etime    => SYSDATE));\n-- Etkilesimli: @?/rdbms/admin/ashrpt.sql","what":"Active Session History örneklerinden son dakikalarda DB time'ın hangi wait event'lere ve hangi SQL'lere gittiğini yüzde olarak çıkarır; AWR snapshot'ını beklemeden olay anında teşhis sağlar.","when":"Canlı yavaşlık sırasında, kısa süreli spike'larda (AWR ortalamasında kaybolan), belirli bir session/SQL'in neyi beklediğini görmek için.","caution":"V$ACTIVE_SESSION_HISTORY ve DBA_HIST_ACTIVE_SESS_HISTORY sorgulamak Diagnostics Pack lisansı gerektirir. ASH örneklemdir: sample sayısı süre tahminidir, tam ölçüm değildir; çok kısa SQL'ler görünmeyebilir. Bellek içi ASH buffer'ı yoğun sistemlerde yalnızca birkaç saati tutar.","tags":["ash","active session history","top wait","top sql","bekleme","ashrpt","anlik analiz","diagnostics pack"]},{"id":"addm-task-report","task":"ADDM analizini çalıştır ve raporunu al","category":"Performans","command":"-- Iki snapshot arasini analiz et (CDB root'ta):\nVAR tname VARCHAR2(60)\nBEGIN\n  :tname := 'ADDM_<begin_snap>_<end_snap>';\n  DBMS_ADDM.ANALYZE_DB(\n    task_name      => :tname,\n    begin_snapshot => <begin_snap>,\n    end_snapshot   => <end_snap>);\nEND;\n/\n\nSET LONG 1000000 LONGCHUNKSIZE 1000000 LINESIZE 200 PAGESIZE 0\nSELECT DBMS_ADDM.GET_REPORT(task_name => :tname) FROM dual;\n\n-- Bulgular ozet (etkiye gore):\nSET PAGESIZE 100\nSELECT finding_name, type, ROUND(impact/1e6) AS impact_sec, message\nFROM   dba_advisor_findings\nWHERE  task_name = :tname\nORDER  BY impact DESC;\n\n-- Etkilesimli alternatif: @?/rdbms/admin/addmrpt.sql\n-- Is bitince gorevi temizle:\nEXEC DBMS_ADDM.DELETE(task_name => :tname);","what":"Automatic Database Diagnostic Monitor, iki AWR snapshot'ı arasındaki DB time'ı analiz eder; darboğazları etki süresiyle (finding) ve somut önerilerle (recommendation) raporlar.","when":"AWR raporunu yorumlamadan önce hızlı bir \"nereye bakmalıyım\" özeti almak için; otomatik ADDM (her snapshot sonrası) dışında özel bir aralık analiz edilecekse.","caution":"Diagnostics Pack lisansı gerekir. ADDM önerileri (parametre artırımı, SQL Tuning Advisor çalıştırma vb.) körü körüne uygulanmamalı; özellikle bellek önerilerini AWR advisory bölümleriyle doğrula. Aralıkta restart varsa analiz yapılamaz.","tags":["addm","dbms_addm","advisor","bulgu","finding","oneri","diagnostics pack","performans"]},{"id":"sql-monitor-report","task":"SQL Monitor raporu al (çalışan veya biten uzun SQL)","category":"Performans","command":"-- Izlenen SQL'leri listele (5 sn'den uzun, paralel veya /*+ MONITOR */):\nSELECT sql_id, status, username, sql_exec_id,\n       TO_CHAR(sql_exec_start,'YYYY-MM-DD HH24:MI:SS') AS exec_start,\n       ROUND(elapsed_time/1e6,1) AS elapsed_s,\n       ROUND(cpu_time/1e6,1)     AS cpu_s,\n       buffer_gets, px_servers_allocated\nFROM   v$sql_monitor\nORDER  BY sql_exec_start DESC\nFETCH FIRST 20 ROWS ONLY;\n\n-- TEXT rapor (plan satiri bazinda gercek satir, sure ve aktivite):\nSET LONG 10000000 LONGCHUNKSIZE 10000000 LINESIZE 300 PAGESIZE 0 TRIMSPOOL ON\nSELECT DBMS_SQLTUNE.REPORT_SQL_MONITOR(\n         sql_id       => '<sql_id>',\n         type         => 'TEXT',\n         report_level => 'ALL') AS report\nFROM   dual;\n\n-- Paylasilabilir HTML (tarayicida interaktif):\nSPOOL /tmp/sqlmon_<sql_id>.html\nSELECT DBMS_SQLTUNE.REPORT_SQL_MONITOR(\n         sql_id => '<sql_id>', type => 'ACTIVE', report_level => 'ALL')\nFROM   dual;\nSPOOL OFF","what":"Real-Time SQL Monitoring, uzun süren veya paralel bir SQL'in execution plan'ının her adımında gerçek satır sayısını, harcanan süreyi, bellek/temp kullanımını ve ASH aktivitesini gösterir; SQL hâlâ çalışırken bile ilerlemeyi görürsün.","when":"Batch/rapor sorgusu \"takıldı mı, ne kadar kaldı\" sorusunda, paralel sorgu dağılımı (PX skew) analizinde, tahmin (E-Rows) ile gerçek satır farkını bulmak için.","caution":"Tuning Pack lisansı gerekir (Diagnostics Pack ön koşuldur). Varsayılan olarak yalnızca 5 sn CPU/I-O süren veya paralel çalışan SQL izlenir; diğerleri için /*+ MONITOR */ hint'i kullan. Çok satırlı planlar (_sqlmon_max_planlines, varsayılan 300) izlenmez. Kayıtlar bellekte sınırlı süre tutulur; 12c+ sonrası raporlar DBA_HIST_REPORTS'tan da alınabilir.","tags":["sql monitor","report_sql_monitor","v$sql_monitor","gercek zamanli","uzun sorgu","paralel","tuning pack"]},{"id":"sql-trace-10046-tkprof","task":"Bir session için 10046 trace aç/kapat ve TKPROF ile özetle","category":"Performans","command":"-- 1) Hedef session'i ve trace dosyasini bul:\nSELECT s.sid, s.serial#, s.username, s.module, p.tracefile\nFROM   v$session s\n  JOIN v$process p ON p.addr = s.paddr\nWHERE  s.username = 'MUSTERI_APP';\n\n-- 2) Trace ac (waits + binds = level 12 karsiligi):\nBEGIN\n  DBMS_MONITOR.SESSION_TRACE_ENABLE(\n    session_id => <sid>,\n    serial_num => <serial#>,\n    waits      => TRUE,\n    binds      => TRUE,\n    plan_stat  => 'ALL_EXECUTIONS');\nEND;\n/\n-- Dogrula: SELECT sql_trace, sql_trace_waits, sql_trace_binds FROM v$session WHERE sid = <sid>;\n\n-- 3) Sorunlu islem bitince kapat:\nEXEC DBMS_MONITOR.SESSION_TRACE_DISABLE(session_id => <sid>, serial_num => <serial#>);\n\n-- Alternatifler:\n-- Kendi session'in: ALTER SESSION SET EVENTS '10046 trace name context forever, level 12';\n-- Tek SQL_ID, tum session'lar: ALTER SYSTEM SET EVENTS 'sql_trace[SQL: <sql_id>] wait=true, bind=true';\n--   kapat: ALTER SYSTEM SET EVENTS 'sql_trace[SQL: <sql_id>] off';\n-- Connection pool icin: DBMS_MONITOR.CLIENT_ID_TRACE_ENABLE / SERV_MOD_ACT_TRACE_ENABLE\n\n-- 4) OS'te TKPROF ile ozetle (en pahali SQL basta):\n-- $ tkprof /u01/app/oracle/diag/rdbms/orcl/ORCL/trace/ORCL_ora_12345.trc /tmp/ora_12345.prf \\\n--     sys=no sort=exeela,fchela,prsela waits=yes aggregate=yes","what":"Extended SQL trace (10046), session'ın çalıştırdığı her SQL için parse/execute/fetch sürelerini, wait event'leri ve bind değerlerini trace dosyasına yazar; TKPROF bunu SQL bazında toplanmış okunabilir rapora çevirir.","when":"AWR/ASH'ın yetmediği, tek bir kullanıcı işleminin uçtan uca nerede vakit harcadığını kanıtlamak gerektiğinde; uygulama ile DB arasındaki round-trip (SQL*Net) sorunlarında.","caution":"Lisans gerektirmez. Trace dosyası hızla büyür ve hedef session'a ek yük bindirir; kısa tut ve mutlaka kapat (DBA_ENABLED_TRACES ile açık kalanları kontrol et). binds=TRUE hassas veriyi (kimlik no, kart vb.) trace dosyasına yazar. ALTER SESSION SET EVENTS için ALTER SESSION yetkisi gerekir (yoksa ORA-01031). TKPROF varsayılan olarak bind değerlerini göstermez; ham .trc dosyasını sakla.","note":"Connection pool/servis bazlı trace'lerde birden çok dosya oluşur; trcsess (trcsess output=birlesik.trc clientid=<id> *.trc) ile birleştirip sonra TKPROF'a ver.","tags":["10046","trace","tkprof","dbms_monitor","sql trace","bekleme","bind","oturum izleme"]},{"id":"xplan-allstats-last","task":"Gerçek execution plan'ı satır istatistikleriyle göster (ALLSTATS LAST)","category":"Performans","command":"-- 1) Satir kaynagi istatistiklerini topla (yalniz bu sorgu icin):\nSET SERVEROUTPUT OFF\nSELECT /*+ gather_plan_statistics */ musteri_id, SUM(tutar)\nFROM   musteri_app.satislar\nWHERE  tarih >= DATE '2026-06-01'\nGROUP  BY musteri_id;\n-- veya oturum boyunca: ALTER SESSION SET statistics_level = ALL;\n\n-- 2) Ayni session'da son calisan cursor'in plani (E-Rows vs A-Rows):\nSELECT *\nFROM   TABLE(DBMS_XPLAN.DISPLAY_CURSOR(\n         sql_id          => NULL,\n         cursor_child_no => NULL,\n         format          => 'ALLSTATS LAST +PEEKED_BINDS +OUTLINE'));\n\n-- 3) Baska session'daki / gecmisteki bir cursor:\nSELECT *\nFROM   TABLE(DBMS_XPLAN.DISPLAY_CURSOR('<sql_id>', NULL, 'ALLSTATS LAST +PEEKED_BINDS'));","what":"EXPLAIN PLAN tahminidir; bu yöntem gerçekten çalışmış planı her adımda Starts, E-Rows (tahmin), A-Rows (gerçek), A-Time, Buffers ve bellek kullanımıyla gösterir. Cardinality hatasının hangi adımda başladığını bulmanın en doğrudan yoludur.","when":"Yavaş tek bir SQL'i tune ederken, istatistik/histogram ihtiyacını kanıtlamak için, hint veya index değişikliğinin etkisini ölçerken.","caution":"Lisans gerektirmez. SET SERVEROUTPUT ON iken sql_id=>NULL son cursor olarak DBMS_OUTPUT çağrısını gösterir; önce OFF yap. statistics_level=ALL'u sistem genelinde açma, belirgin CPU ek yükü getirir. Hint SQL metnini değiştirdiği için yeni bir sql_id oluşur. Kullanıcının V$SQL_PLAN_STATISTICS_ALL okuma yetkisi olmalı (SELECT_CATALOG_ROLE).","tags":["dbms_xplan","display_cursor","allstats last","gather_plan_statistics","gercek plan","execution plan","a-rows","cardinality"]},{"id":"sql-tuning-advisor-task","task":"SQL Tuning Advisor görevi oluştur, çalıştır ve önerileri oku","category":"Performans","command":"-- 1) Cursor cache'teki SQL icin gorev olustur ve calistir:\nVAR task VARCHAR2(64)\nBEGIN\n  :task := DBMS_SQLTUNE.CREATE_TUNING_TASK(\n             sql_id      => '<sql_id>',\n             scope       => DBMS_SQLTUNE.SCOPE_COMPREHENSIVE,\n             time_limit  => 300,\n             task_name   => 'STA_<sql_id>',\n             description => 'Yavas rapor sorgusu');\n  DBMS_SQLTUNE.EXECUTE_TUNING_TASK(task_name => :task);\nEND;\n/\n-- AWR'daki gecmis SQL icin: begin_snap => <b>, end_snap => <e>, sql_id => '<sql_id>'\n\n-- 2) Durum ve rapor:\nSELECT task_name, status FROM dba_advisor_log WHERE task_name = :task;\n\nSET LONG 1000000 LONGCHUNKSIZE 1000000 LINESIZE 200 PAGESIZE 0\nSELECT DBMS_SQLTUNE.REPORT_TUNING_TASK(:task) FROM dual;\n\n-- 3) Onerileri uygulanabilir script olarak al:\nSELECT DBMS_SQLTUNE.SCRIPT_TUNING_TASK(:task) FROM dual;\n\n-- 4) Is bitince:\nEXEC DBMS_SQLTUNE.DROP_TUNING_TASK(task_name => :task);","what":"Optimizer'ı daha uzun süreli \"tuning modu\"nda çalıştırarak SQL için istatistik eksikliği, yeni index, SQL profile, alternatif plan ve SQL yeniden yazım önerileri üretir; profile önerisini gerçek çalıştırmayla doğrular.","when":"Tek bir problemli SQL için hızlı ikinci görüş gerektiğinde, plan regresyonunda SQL profile ile kodu değiştirmeden düzeltme ararken.","caution":"Tuning Pack lisansı gerekir. COMPREHENSIVE kapsam SQL'i test amaçlı çalıştırabilir (DML için yalnız SELECT kısmı); prod'da time_limit ver. Index önerileri sistem genelini dikkate almaz; DML maliyetini ayrıca değerlendir. Kullanıcıya ADVISOR yetkisi gerekir.","tags":["sql tuning advisor","dbms_sqltune","tuning task","oneri","sql profile","index onerisi","tuning pack"]},{"id":"sql-profile-accept","task":"SQL profile kabul et, devre dışı bırak, kaldır","category":"Performans","command":"-- 1) Tuning task'in onerdigi profile'i kabul et:\nDECLARE\n  l_name VARCHAR2(128);\nBEGIN\n  l_name := DBMS_SQLTUNE.ACCEPT_SQL_PROFILE(\n              task_name   => '<task_name>',\n              name        => 'PROF_<sql_id>',\n              description => 'STA onerisi, CHG-1234',\n              force_match => TRUE,     -- literal farklari icin de eslesir\n              replace     => TRUE);\n  DBMS_OUTPUT.PUT_LINE('Profile: ' || l_name);\nEND;\n/\n\n-- 2) Profile'lar ve kullanan cursor'lar:\nSELECT name, category, status, force_matching,\n       TO_CHAR(created,'YYYY-MM-DD HH24:MI') AS created\nFROM   dba_sql_profiles\nORDER  BY created DESC;\n\nSELECT sql_id, child_number, plan_hash_value, sql_profile\nFROM   v$sql\nWHERE  sql_profile IS NOT NULL;\n\n-- 3) Gecici devre disi birak / kaldir:\nEXEC DBMS_SQLTUNE.ALTER_SQL_PROFILE(name => 'PROF_<sql_id>', attribute_name => 'STATUS', value => 'DISABLED');\nEXEC DBMS_SQLTUNE.DROP_SQL_PROFILE(name => 'PROF_<sql_id>', ignore => TRUE);","what":"SQL profile, optimizer'a ek cardinality/selectivity düzeltmeleri (OPT_ESTIMATE vb.) veren ve SQL metnine dokunmadan daha iyi plan üretmesini sağlayan nesnedir; FORCE_MATCH ile yalnızca literal'leri farklı SQL'lere de uygulanır.","when":"Hazır (packaged) uygulamada SQL değiştirilemiyorsa, STA doğrulanmış bir iyileşme önerdiğinde, plan regresyonuna hızlı müdahalede.","caution":"Tuning Pack lisansı gerekir. Profile planı \"kilitlemez\", tahminleri düzeltir; veri dağılımı değişince plan yine değişebilir. Plan sabitliği şartsa SQL Plan Baseline kullan. Profile ve baseline birlikte varsa baseline'daki kabul edilmiş planlar arasından seçim yapılır. Kabul öncesi validation sonuçlarını (raporun 'Validation results' bölümü) mutlaka oku.","tags":["sql profile","accept_sql_profile","dbms_sqltune","force_match","plan duzeltme","dba_sql_profiles","tuning pack"]},{"id":"spm-load-from-cursor-cache","task":"Cursor cache'teki iyi planı SQL Plan Baseline olarak yükle","category":"Performans","command":"-- 1) SQL'in planlarini ve performansini karsilastir:\nSELECT sql_id, child_number, plan_hash_value, executions,\n       ROUND(elapsed_time/1e3/NULLIF(executions,0),1) AS ms_per_exec,\n       sql_plan_baseline\nFROM   v$sql\nWHERE  sql_id = '<sql_id>';\n\n-- 2) Secilen planı baseline olarak yukle:\nSET SERVEROUTPUT ON\nDECLARE\n  n PLS_INTEGER;\nBEGIN\n  n := DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE(\n         sql_id          => '<sql_id>',\n         plan_hash_value => <plan_hash_value>,\n         fixed           => 'NO',\n         enabled         => 'YES');\n  DBMS_OUTPUT.PUT_LINE(n || ' plan yuklendi');\nEND;\n/\n\n-- 3) Baseline'i dogrula:\nSELECT sql_handle, plan_name, origin, enabled, accepted, fixed, reproduced,\n       TO_CHAR(last_executed,'YYYY-MM-DD HH24:MI') AS last_exec\nFROM   dba_sql_plan_baselines\nWHERE  signature = (SELECT exact_matching_signature FROM v$sql\n                    WHERE sql_id = '<sql_id>' AND ROWNUM = 1);\n-- Sonraki calistirmalarda v$sql.sql_plan_baseline dolu olmali.","what":"SQL Plan Management ile seçilen planı kabul edilmiş (ACCEPTED) baseline yapar; optimizer artık yalnızca baseline'daki kabul edilmiş planları kullanır, yeni bulduğu planları evolve edilene kadar beklemeye alır.","when":"Plan regresyonunda bilinen iyi plana dönmek için, upgrade/istatistik değişikliği öncesi kritik SQL'lerin planlarını korumak için.","caution":"Enterprise Edition'da ek lisans gerekmez (SE2'de SQL başına tek baseline planı ile sınırlıdır). ADMINISTER SQL MANAGEMENT OBJECT yetkisi gerekir. Baseline, SQL metninin birebir aynısına (signature) uygulanır; literal kullanan SQL'lerde işe yaramaz. Planda kullanılan index düşürülürse plan üretilemez (REPRODUCED=NO) ve optimizer serbest kalır. OPTIMIZER_USE_SQL_PLAN_BASELINES=TRUE olmalı (varsayılan).","note":"İyi plan artık cursor cache'te yoksa AWR'dan yükle: 12.2+ DBMS_SPM.LOAD_PLANS_FROM_AWR(begin_snap, end_snap, basic_filter => q'[sql_id='<sql_id>']'); öncesinde SQL Tuning Set üzerinden LOAD_PLANS_FROM_SQLSET.","tags":["spm","sql plan baseline","dbms_spm","load_plans_from_cursor_cache","plan sabitleme","plan regresyonu","plan_hash_value"]},{"id":"spm-evolve-baseline","task":"Bekleyen (kabul edilmemiş) baseline planlarını evolve et","category":"Performans","command":"-- 1) Kabul bekleyen planlar:\nSELECT sql_handle, plan_name, origin, enabled, accepted, fixed,\n       TO_CHAR(created,'YYYY-MM-DD HH24:MI') AS created\nFROM   dba_sql_plan_baselines\nWHERE  accepted = 'NO'\nORDER  BY created DESC;\n\n-- 2) Evolve gorevi: aday planı kabul edilmis planla karsilastirarak calistirir\nVAR tname VARCHAR2(128)\nVAR ename VARCHAR2(128)\nBEGIN\n  :tname := DBMS_SPM.CREATE_EVOLVE_TASK(\n              sql_handle => '<sql_handle>',\n              time_limit => 600,\n              task_name  => 'EVOLVE_<sql_handle>');\n  :ename := DBMS_SPM.EXECUTE_EVOLVE_TASK(task_name => :tname);\nEND;\n/\n\nSET LONG 1000000 LONGCHUNKSIZE 1000000 LINESIZE 200 PAGESIZE 0\nSELECT DBMS_SPM.REPORT_EVOLVE_TASK(\n         task_name => :tname, execution_name => :ename,\n         type => 'TEXT', level => 'TYPICAL', section => 'ALL')\nFROM   dual;\n\n-- 3) Raporda oneri varsa (daha iyi oldugu kanitlanan planlari) kabul et:\nSET SERVEROUTPUT ON\nDECLARE\n  n PLS_INTEGER;\nBEGIN\n  n := DBMS_SPM.IMPLEMENT_EVOLVE_TASK(task_name => :tname);\n  DBMS_OUTPUT.PUT_LINE(n || ' plan kabul edildi');\nEND;\n/\nEXEC DBMS_SPM.DROP_EVOLVE_TASK(task_name => :tname);","what":"Baseline varken optimizer'ın bulduğu yeni planlar ACCEPTED=NO olarak saklanır. Evolve görevi bu adayları gerçek çalıştırmayla kabul edilmiş planla karşılaştırır; yalnızca belirgin şekilde daha iyi olanları kabul eder.","when":"Baseline'lı SQL'lerde yeni index/istatistik sonrası daha iyi plan olasılığı doğduğunda; 12c+ otomatik SYS_AUTO_SPM_EVOLVE_TASK sonuçlarını beklemeden manuel karar vermek için.","caution":"Enterprise Edition gerekir. Evolve SQL'i gerçekten çalıştırır (DML'de yalnızca sorgu kısmı); ağır SQL'lerde time_limit ver ve yoğun saatlerde çalıştırma. ADMINISTER SQL MANAGEMENT OBJECT ve ADVISOR yetkileri gerekir. Planı SYS olarak parse edilmiş SQL'ler evolve edilemez (ORA-16963); uygulama kullanıcısıyla çalıştır.","since":"Oracle 12c","note":"12c öncesindeki DBMS_SPM.EVOLVE_SQL_PLAN_BASELINE fonksiyonu deprecated'dır; 12c+ görev tabanlı API (CREATE/EXECUTE/IMPLEMENT_EVOLVE_TASK) kullanılır. Otomatik görevin davranışı: DBMS_SPM.SET_EVOLVE_TASK_PARAMETER('SYS_AUTO_SPM_EVOLVE_TASK', 'ACCEPT_PLANS', 'FALSE').","tags":["spm","evolve","create_evolve_task","baseline","plan kabul","dbms_spm","accepted"]},{"id":"spm-alter-drop-baseline","task":"Baseline planını FIXED yap, devre dışı bırak veya sil","category":"Performans","command":"-- Planin icerigini gor:\nSELECT *\nFROM   TABLE(DBMS_XPLAN.DISPLAY_SQL_PLAN_BASELINE(\n         sql_handle => '<sql_handle>',\n         plan_name  => '<plan_name>',\n         format     => 'TYPICAL'));\n\nSET SERVEROUTPUT ON\nDECLARE\n  n PLS_INTEGER;\nBEGIN\n  -- FIXED: bu plan tercih edilir, yeni planlar otomatik evolve edilmez\n  n := DBMS_SPM.ALTER_SQL_PLAN_BASELINE(\n         sql_handle => '<sql_handle>', plan_name => '<plan_name>',\n         attribute_name => 'fixed', attribute_value => 'YES');\n\n  -- Kotu plani kullanima kapat (silmeden):\n  n := DBMS_SPM.ALTER_SQL_PLAN_BASELINE(\n         sql_handle => '<sql_handle>', plan_name => '<bad_plan_name>',\n         attribute_name => 'enabled', attribute_value => 'NO');\nEND;\n/\n\n-- Tek plani veya SQL'in tum baseline'ini sil:\nDECLARE\n  n PLS_INTEGER;\nBEGIN\n  n := DBMS_SPM.DROP_SQL_PLAN_BASELINE(sql_handle => '<sql_handle>', plan_name => '<plan_name>');\n  -- plan_name verilmezse SQL'in tum planlari silinir:\n  -- n := DBMS_SPM.DROP_SQL_PLAN_BASELINE(sql_handle => '<sql_handle>');\n  DBMS_OUTPUT.PUT_LINE(n || ' plan silindi');\nEND;\n/","what":"Baseline'daki planların özniteliklerini yönetir: FIXED plan diğer kabul edilmiş planlara tercih edilir ve yeni planların otomatik evolve'unu durdurur; ENABLED=NO planı silmeden devre dışı bırakır; DROP kalıcı olarak kaldırır.","when":"Kritik SQL'de planı kesin olarak sabitlemek, yanlışlıkla kabul edilmiş kötü planı kapatmak, artık gerekmeyen baseline'ları temizlemek için.","caution":"Enterprise Edition gerekir. FIXED planlar veri büyüdükçe kötüleşebilir ve optimizer'ın daha iyi planı kullanmasını engeller; periyodik gözden geçir. Tüm planları ENABLED=NO olan SQL serbestçe optimize edilir. DROP geri alınamaz; önce DBMS_SPM.PACK_STGTAB_BASELINE ile staging tablosuna yedekle.","tags":["spm","baseline","fixed","alter_sql_plan_baseline","drop_sql_plan_baseline","plan devre disi","display_sql_plan_baseline"]},{"id":"bind-sensitivity-acs-check","task":"Bind peeking ve adaptive cursor sharing durumunu kontrol et","category":"Performans","command":"-- 1) Child cursor'lar: bind-sensitive / bind-aware / paylasilabilir mi?\nSELECT sql_id, child_number, executions, plan_hash_value,\n       is_bind_sensitive, is_bind_aware, is_shareable,\n       ROUND(buffer_gets/NULLIF(executions,0)) AS gets_per_exec\nFROM   v$sql\nWHERE  sql_id = '<sql_id>'\nORDER  BY child_number;\n\n-- 2) ACS histogram ve selectivity araliklari:\nSELECT child_number, bucket_id, count\nFROM   v$sql_cs_histogram\nWHERE  sql_id = '<sql_id>'\nORDER  BY child_number, bucket_id;\n\nSELECT child_number, predicate, range_id, low, high\nFROM   v$sql_cs_selectivity\nWHERE  sql_id = '<sql_id>';\n\n-- 3) Peek edilen / yakalanan bind degerleri:\nSELECT child_number, name, position, datatype_string, value_string,\n       TO_CHAR(last_captured,'YYYY-MM-DD HH24:MI:SS') AS captured\nFROM   v$sql_bind_capture\nWHERE  sql_id = '<sql_id>'\nORDER  BY child_number, position;\n\nSELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('<sql_id>', NULL, 'TYPICAL +PEEKED_BINDS'));\n\n-- 4) Neden yeni child olustu?\nSELECT child_number, bind_mismatch, bind_equiv_failure,\n       optimizer_mismatch, load_optimizer_stats\nFROM   v$sql_shared_cursor\nWHERE  sql_id = '<sql_id>';","what":"Optimizer ilk hard parse'ta bind değerine bakarak (peeking) plan seçer. Adaptive cursor sharing, histogramlı kolonlarda bind değerine göre farklı child cursor/plan üretebilir; bu sorgular cursor'ın bind-sensitive/aware olup olmadığını, hangi değerin peek edildiğini ve child oluşma nedenlerini gösterir.","when":"\"Aynı SQL bazen hızlı bazen yavaş\" şikayetinde, çarpık (skewed) veri dağılımında, child cursor sayısı patladığında (high version count).","caution":"Lisans gerektirmez; salt okunur. V$SQL_BIND_CAPTURE örneklemedir (varsayılan ~15 dk'da bir) ve yalnız WHERE/HAVING bind'lerini tutar; her çalıştırmanın değeri değildir. ACS, cursor ancak birkaç kötü çalıştırmadan sonra bind-aware olur. Kritik SQL'de plan dalgalanmasını önlemek için SQL Plan Baseline'a birden çok plan yüklemek daha deterministiktir.","since":"Oracle 11g","note":"Adaptive cursor sharing 11g ile geldi. High version count analizinde V$SQL_SHARED_CURSOR'ın REASON kolonu (XML) asıl nedeni ayrıntılı verir.","tags":["bind peeking","adaptive cursor sharing","acs","bind degisken","v$sql_bind_capture","child cursor","version count"]},{"id":"top-sql-awr-history","task":"Geçmiş dönemde en çok elapsed/CPU harcayan SQL'leri bul (AWR + V$SQLAREA)","category":"Performans","command":"-- AWR: snapshot araliginda elapsed'a gore top 20 (plan bazinda)\nSELECT *\nFROM  (SELECT st.sql_id,\n              st.plan_hash_value,\n              SUM(st.executions_delta)                       AS execs,\n              ROUND(SUM(st.elapsed_time_delta)/1e6, 1)       AS elapsed_s,\n              ROUND(SUM(st.cpu_time_delta)/1e6, 1)           AS cpu_s,\n              ROUND(SUM(st.iowait_delta)/1e6, 1)             AS io_wait_s,\n              SUM(st.buffer_gets_delta)                      AS buffer_gets,\n              ROUND(SUM(st.elapsed_time_delta)/1e3\n                    / NULLIF(SUM(st.executions_delta),0), 2) AS ms_per_exec,\n              MAX(st.parsing_schema_name)                    AS parsing_schema\n       FROM   dba_hist_sqlstat st\n       WHERE  st.dbid = (SELECT dbid FROM v$database)\n         AND  st.snap_id BETWEEN <begin_snap> AND <end_snap>\n       GROUP  BY st.sql_id, st.plan_hash_value\n       ORDER  BY elapsed_s DESC)\nWHERE ROWNUM <= 20;\n-- CPU siralamasi icin: ORDER BY cpu_s DESC\n-- SQL metni: SELECT DBMS_LOB.SUBSTR(sql_text, 4000, 1) FROM dba_hist_sqltext WHERE sql_id = '<sql_id>';\n-- Tek SQL'in plan gecmisi: @?/rdbms/admin/awrsqrpt.sql\n\n-- Anlik (instance acildigindan beri, cache'te kalanlar) CPU'ya gore:\nSELECT sql_id,\n       ROUND(cpu_time/1e6,1)     AS cpu_s,\n       ROUND(elapsed_time/1e6,1) AS elapsed_s,\n       executions, buffer_gets, disk_reads,\n       ROUND(cpu_time/1e3/NULLIF(executions,0),2) AS cpu_ms_per_exec,\n       parsing_schema_name,\n       SUBSTR(sql_text,1,80) AS sql_text\nFROM   v$sqlarea\nWHERE  parsing_schema_name NOT IN ('SYS','SYSTEM')\nORDER  BY cpu_time DESC\nFETCH FIRST 20 ROWS ONLY;","what":"DBA_HIST_SQLSTAT'taki *_DELTA kolonlarını toplayarak bir snapshot aralığında en pahalı SQL'leri plan_hash_value kırılımıyla listeler; aynı SQL'in plan değiştirip değiştirmediği de görünür. V$SQLAREA sorgusu cache'teki kümülatif değerleri verir.","when":"\"Dün gece 02:00-04:00 arası ne yordu sistemi?\" sorusunda, plan değişikliği (aynı sql_id, farklı plan_hash_value) tespitinde, tuning adayı listesi çıkarırken.","caution":"DBA_HIST_* sorgulamak Diagnostics Pack lisansı gerektirir; V$SQLAREA gerektirmez. AWR yalnızca top SQL'leri saklar (varsayılan top-N), küçük ama çok sık çalışan SQL'ler eksik olabilir. V$SQLAREA değerleri cursor cache'ten düştüğünde kaybolur. Snapshot aralığına restart girmişse delta'lar yine doğrudur ama cache bazlı sorgu sıfırlanmıştır.","tags":["top sql","dba_hist_sqlstat","v$sqlarea","elapsed","cpu","en pahali sorgu","plan degisikligi","diagnostics pack"]},{"id":"stats-stale-prefs","task":"Stale istatistikleri bul ve tablo bazlı istatistik tercihlerini (prefs) ayarla","category":"İstatistik","command":"-- 1) DML sayaclarini sozluge yaz ve stale olanlari listele:\nEXEC DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO;\n\nSELECT owner, table_name, partition_name, num_rows,\n       TO_CHAR(last_analyzed,'YYYY-MM-DD HH24:MI') AS last_analyzed,\n       stale_stats, stattype_locked\nFROM   dba_tab_statistics\nWHERE  owner = 'MUSTERI_APP'\n  AND  (stale_stats = 'YES' OR last_analyzed IS NULL)\nORDER  BY table_name, partition_name;\n\nSELECT table_name, partition_name, inserts, updates, deletes, truncated\nFROM   dba_tab_modifications\nWHERE  table_owner = 'MUSTERI_APP';\n\n-- 2) Tablo bazli tercihler (auto stats job ve manuel GATHER bunlari kullanir):\nEXEC DBMS_STATS.SET_TABLE_PREFS('MUSTERI_APP', 'SATISLAR', 'STALE_PERCENT', '5');\nEXEC DBMS_STATS.SET_TABLE_PREFS('MUSTERI_APP', 'SATISLAR', 'METHOD_OPT', 'FOR ALL COLUMNS SIZE AUTO FOR COLUMNS SIZE 254 MUSTERI_ID');\nEXEC DBMS_STATS.SET_TABLE_PREFS('MUSTERI_APP', 'SATISLAR', 'DEGREE', '4');\n\nSELECT DBMS_STATS.GET_PREFS('STALE_PERCENT', 'MUSTERI_APP', 'SATISLAR') AS stale_pct FROM dual;\nSELECT table_name, preference_name, preference_value\nFROM   dba_tab_stat_prefs WHERE owner = 'MUSTERI_APP';\n\n-- 3) Yalniz stale olanlari topla:\nEXEC DBMS_STATS.GATHER_SCHEMA_STATS(ownname => 'MUSTERI_APP', options => 'GATHER STALE');\n-- Tercihi geri al: EXEC DBMS_STATS.DELETE_TABLE_PREFS('MUSTERI_APP', 'SATISLAR', 'STALE_PERCENT');","what":"Tablo değişiklik oranı STALE_PERCENT'i (varsayılan %10) aşınca istatistik stale sayılır. Tercihler (prefs) tablo bazında örnekleme, histogram, paralellik ve stale eşiğini kalıcı kılar; böylece gece otomatik istatistik görevi de aynı kuralları uygular.","when":"Büyük tablolarda %10 eşiği geç kaldığında, belirli kolonlara histogram zorunlu kılınacaksa, toplama stratejisini script yerine sözlükte tanımlamak için.","caution":"Lisans gerektirmez. Manuel GATHER çağrısında açıkça verilen parametre tercihin önüne geçer. METHOD_OPT değişikliği histogramları ekler/kaldırır ve planları değiştirebilir. DBA_TAB_MODIFICATIONS ancak flush sonrası güncel olur (otomatik flush ~15 dk'da bir).","tags":["stale stats","stale_percent","set_table_prefs","dba_tab_statistics","dba_tab_modifications","istatistik tercihi","gather stale"]},{"id":"stats-lock-unlock","task":"Tablo/şema istatistiklerini kilitle ve kilidi aç","category":"İstatistik","command":"-- Kilitle (auto stats job ve normal GATHER artik dokunmaz):\nEXEC DBMS_STATS.LOCK_TABLE_STATS(ownname => 'MUSTERI_APP', tabname => 'SIPARIS');\nEXEC DBMS_STATS.LOCK_SCHEMA_STATS(ownname => 'MUSTERI_APP');\n-- Yalnizca bir partition: DBMS_STATS.LOCK_PARTITION_STATS('MUSTERI_APP', 'SATIS_PART', 'P2026_H1');\n\n-- Kilitli olanlar:\nSELECT owner, table_name, partition_name, stattype_locked\nFROM   dba_tab_statistics\nWHERE  owner = 'MUSTERI_APP' AND stattype_locked IS NOT NULL;\n\n-- Kilitliyken bilincli toplama (ORA-20005 yerine):\nEXEC DBMS_STATS.GATHER_TABLE_STATS('MUSTERI_APP', 'SIPARIS', force => TRUE);\n\n-- Kilidi ac:\nEXEC DBMS_STATS.UNLOCK_SCHEMA_STATS(ownname => 'MUSTERI_APP');\nEXEC DBMS_STATS.UNLOCK_TABLE_STATS(ownname => 'MUSTERI_APP', tabname => 'SIPARIS');","what":"İstatistikleri değişmeye karşı kilitler; otomatik görev kilitli nesneleri atlar, tablo bazlı GATHER çağrısı ORA-20005 verir. force=>TRUE kilidi delmeden toplama yapar.","when":"Gün içinde boşalıp dolan staging/geçici tablolar için temsilî istatistik sabitlemek, kritik tabloda planı istatistik değişimine karşı korumak, set edilmiş (DBMS_STATS.SET_TABLE_STATS) değerleri korumak için.","caution":"Lisans gerektirmez. Kilitli istatistikler zamanla gerçeklikten uzaklaşır ve cardinality hatalarına yol açar; kilitli nesneleri düzenli raporla. Şema kilidi şemaya sonradan eklenen tabloları kapsamaz. Kilitli tabloda index oluşturma/rebuild ile otomatik index istatistiği de toplanmaz.","tags":["lock stats","istatistik kilitle","unlock_table_stats","lock_schema_stats","ora-20005","stattype_locked","dbms_stats"]},{"id":"stats-restore-history","task":"İstatistikleri geçmişteki bir zamana geri yükle (restore)","category":"İstatistik","command":"-- 1) Saklama suresi ve geri donulebilecek en eski an:\nSELECT DBMS_STATS.GET_STATS_HISTORY_RETENTION    AS retention_days,\n       DBMS_STATS.GET_STATS_HISTORY_AVAILABILITY AS oldest_available\nFROM   dual;\n\n-- 2) Tablonun istatistik gecmisi:\nSELECT table_name, partition_name,\n       TO_CHAR(stats_update_time,'YYYY-MM-DD HH24:MI:SS TZH:TZM') AS stats_update_time\nFROM   dba_tab_stats_history\nWHERE  owner = 'MUSTERI_APP' AND table_name = 'SATISLAR'\nORDER  BY stats_update_time DESC;\n\n-- 3) Plan bozulmadan onceki ana geri don:\nBEGIN\n  DBMS_STATS.RESTORE_TABLE_STATS(\n    ownname         => 'MUSTERI_APP',\n    tabname         => 'SATISLAR',\n    as_of_timestamp => TIMESTAMP '2026-10-07 22:00:00 +03:00',\n    no_invalidate   => FALSE);\nEND;\n/\n-- Sema geneli: DBMS_STATS.RESTORE_SCHEMA_STATS('MUSTERI_APP', <timestamp>)\n\n-- Saklama suresini degistir (gun):\n-- EXEC DBMS_STATS.ALTER_STATS_HISTORY_RETENTION(31);","what":"DBMS_STATS her toplamadan önce eski istatistikleri SYSAUX'ta saklar (varsayılan 31 gün). RESTORE_* prosedürleri tablo/şema istatistiklerini verilen andaki haline döndürür; no_invalidate=>FALSE ile cursor'lar hemen yeniden parse edilir.","when":"Gece istatistik toplaması sonrası plan regresyonu oluştuğunda en hızlı geri dönüş yolu olarak; değişikliğin istatistik kaynaklı olup olmadığını test etmek için.","caution":"Lisans gerektirmez. Kilitli istatistikler restore edilemez (önce unlock). Restore sonrası bir sonraki otomatik toplama yeni istatistikleri tekrar getirir; kalıcı çözüm için tablo için tercih ayarla, kilitle veya SQL Plan Baseline kullan. Uzun retention SYSAUX'u büyütür (WRI$_OPTSTAT_* tabloları).","tags":["restore stats","istatistik geri yukle","restore_table_stats","dba_tab_stats_history","stats history","plan regresyonu","dbms_stats"]},{"id":"stats-pending-publish","task":"İstatistikleri pending olarak topla, test et ve yayınla","category":"İstatistik","command":"-- 1) Tablo icin yayinlamayi kapat (yeni istatistik pending'e gider):\nEXEC DBMS_STATS.SET_TABLE_PREFS('MUSTERI_APP', 'SIPARIS', 'PUBLISH', 'FALSE');\nEXEC DBMS_STATS.GATHER_TABLE_STATS('MUSTERI_APP', 'SIPARIS');\n\n-- 2) Pending ve yayindaki degerleri karsilastir:\nSELECT owner, table_name, partition_name, num_rows,\n       TO_CHAR(last_analyzed,'YYYY-MM-DD HH24:MI') AS last_analyzed\nFROM   dba_tab_pending_stats\nWHERE  owner = 'MUSTERI_APP';\nSELECT num_rows, last_analyzed FROM dba_tables\nWHERE  owner = 'MUSTERI_APP' AND table_name = 'SIPARIS';\n\n-- 3) Yalnizca bu session'da pending istatistiklerle planlari dene:\nALTER SESSION SET optimizer_use_pending_statistics = TRUE;\nEXPLAIN PLAN FOR SELECT COUNT(*) FROM musteri_app.siparis WHERE durum = 7;\nSELECT * FROM TABLE(DBMS_XPLAN.DISPLAY(format => 'BASIC +ROWS'));\nALTER SESSION SET optimizer_use_pending_statistics = FALSE;\n\n-- 4a) Iyiyse yayinla:\nEXEC DBMS_STATS.PUBLISH_PENDING_STATS('MUSTERI_APP', 'SIPARIS', no_invalidate => FALSE);\n-- 4b) Kotuyse at:\n-- EXEC DBMS_STATS.DELETE_PENDING_STATS('MUSTERI_APP', 'SIPARIS');\n\n-- 5) Normal davranisa don:\nEXEC DBMS_STATS.SET_TABLE_PREFS('MUSTERI_APP', 'SIPARIS', 'PUBLISH', 'TRUE');","what":"PUBLISH=FALSE tercihiyle toplanan istatistikler sözlüğe değil pending alanına yazılır; diğer session'lar etkilenmez. Test session'ında optimizer_use_pending_statistics ile planlar doğrulanır, sonra tek komutla yayınlanır veya atılır.","when":"Kritik OLTP tablolarında istatistik yenilemesinin planlara etkisini canlıda risksiz denemek için; büyük veri yüklemesi sonrası kontrollü geçişte.","caution":"Lisans gerektirmez. PUBLISH=FALSE kaldığı sürece otomatik görevin topladıkları da pending'de birikir ve hiç yayınlanmaz; işin sonunda tercihi TRUE'ya döndürmeyi unutma. EXPLAIN PLAN tahmindir; mümkünse sorguyu gerçekten çalıştırıp DISPLAY_CURSOR ile bak.","since":"Oracle 11g","tags":["pending stats","publish","publish_pending_stats","optimizer_use_pending_statistics","istatistik test","dbms_stats","dba_tab_pending_stats"]},{"id":"stats-incremental-partitioned","task":"Partition'lı tablo için incremental istatistik ayarla","category":"İstatistik","command":"-- 1) Incremental modu ac (global istatistik partition synopsis'lerinden turetilir):\nEXEC DBMS_STATS.SET_TABLE_PREFS('MUSTERI_APP', 'SATIS_PART', 'INCREMENTAL', 'TRUE');\nEXEC DBMS_STATS.SET_TABLE_PREFS('MUSTERI_APP', 'SATIS_PART', 'INCREMENTAL_STALENESS', 'USE_STALE_PERCENT');\nEXEC DBMS_STATS.SET_TABLE_PREFS('MUSTERI_APP', 'SATIS_PART', 'GRANULARITY', 'AUTO');\n\n-- 2) Ilk toplama tam tarar ve synopsis olusturur; sonrakiler yalniz degisen partition'lari okur:\nEXEC DBMS_STATS.GATHER_TABLE_STATS(ownname => 'MUSTERI_APP', tabname => 'SATIS_PART');\n\n-- 3) Dogrula:\nSELECT DBMS_STATS.GET_PREFS('INCREMENTAL', 'MUSTERI_APP', 'SATIS_PART') AS incremental FROM dual;\nSELECT partition_name, num_rows,\n       TO_CHAR(last_analyzed,'YYYY-MM-DD HH24:MI:SS') AS last_analyzed, stale_stats\nFROM   dba_tab_statistics\nWHERE  owner = 'MUSTERI_APP' AND table_name = 'SATIS_PART'\nORDER  BY partition_position NULLS FIRST;\n\n-- 4) Exchange ile yuklenecek staging tablo icin onceden synopsis uret (12c+):\n-- EXEC DBMS_STATS.SET_TABLE_PREFS('MUSTERI_APP', 'SATIS_STAGE', 'INCREMENTAL', 'TRUE');\n-- EXEC DBMS_STATS.SET_TABLE_PREFS('MUSTERI_APP', 'SATIS_STAGE', 'INCREMENTAL_LEVEL', 'TABLE');\n-- EXEC DBMS_STATS.GATHER_TABLE_STATS('MUSTERI_APP', 'SATIS_STAGE');","what":"Incremental modda her partition için synopsis saklanır; global (tablo düzeyi) istatistikler, özellikle NDV, tüm tabloyu yeniden taramadan synopsis'lerin birleştirilmesiyle hesaplanır. Yalnızca değişen partition'lar yeniden okunur.","when":"Yeni veri yalnız son partition'lara giren büyük (TB seviyesi) range/interval partition'lı tablolarda, global istatistik toplama süresi bakım penceresini aştığında.","caution":"Lisans gerektirmez ancak Partitioning opsiyonu (EE ek lisans) zaten gereklidir. Synopsis'ler SYSAUX'ta yer kaplar (12.2+ HyperLogLog formatı çok daha küçüktür). İlk toplama tam tarama yapar; bakım penceresinde başlat. ESTIMATE_PERCENT AUTO_SAMPLE_SIZE dışında verilirse incremental devre dışı kalır.","since":"Oracle 11g","note":"INCREMENTAL_STALENESS ve INCREMENTAL_LEVEL tercihleri 12c ile geldi; 12.2+ synopsis formatı APPROXIMATE_NDV_ALGORITHM ile (HYPERLOGLOG) belirlenir.","tags":["incremental stats","synopsis","partition istatistik","global stats","incremental_staleness","dbms_stats","buyuk tablo"]},{"id":"partition-split-merge-online","task":"Partition'ı online böl (SPLIT) ve birleştir (MERGE)","category":"Partition","command":"-- SPLIT: bir range partition'i ikiye bol, indeksler kullanilabilir kalsin\nALTER TABLE musteri_app.satis_part\n  SPLIT PARTITION p2026_h2 AT (DATE '2026-10-01')\n  INTO (PARTITION p2026_q3, PARTITION p2026_q4)\n  UPDATE INDEXES ONLINE;\n\n-- MERGE: iki komsu partition'i birlestir\nALTER TABLE musteri_app.satis_part\n  MERGE PARTITIONS p2026_q3, p2026_q4 INTO PARTITION p2026_h2\n  UPDATE INDEXES ONLINE;\n\n-- ADD: en sona yeni partition (MAXVALUE yoksa)\nALTER TABLE musteri_app.satis_part\n  ADD PARTITION p2027 VALUES LESS THAN (DATE '2028-01-01');\n\n-- Kontrol: partition sinirlari ve UNUSABLE index partition'lari\nSELECT partition_name, partition_position, high_value, num_rows\nFROM   dba_tab_partitions\nWHERE  table_owner = 'MUSTERI_APP' AND table_name = 'SATIS_PART'\nORDER  BY partition_position;\n\nSELECT index_name, partition_name, status\nFROM   dba_ind_partitions\nWHERE  index_owner = 'MUSTERI_APP' AND status <> 'USABLE';","what":"SPLIT bir partition'ı sınır değerinden ikiye (12c+ birden çoğa) ayırır; MERGE komşu partition'ları birleştirir. ONLINE ile işlem sırasında DML devam eder, UPDATE INDEXES ile local ve global index'ler UNUSABLE olmaz.","when":"MAXVALUE/\"diğer\" partition'ı büyüdüğünde bölmek, eski küçük partition'ları arşiv öncesi birleştirmek, partition stratejisini (aylık → çeyreklik) değiştirmek için.","caution":"Partitioning opsiyonu (EE ek lisans) gerekir; ONLINE için Enterprise Edition gerekir. SPLIT/MERGE veriyi fiziksel olarak yeniden yazar: büyük partition'da uzun sürer, redo/undo ve geçici alan üretir. ONLINE olmadan işlem süresince tablo DML'e kilitlenir; UPDATE INDEXES olmadan global index'ler UNUSABLE olur. Boş partition'ı bölmek hızlıdır (fast split).","since":"Oracle 12.2","note":"ONLINE SPLIT 12.2, ONLINE MERGE 18c ile geldi; 19c'de ikisi de kullanılabilir. Daha eski sürümlerde ONLINE anahtar kelimesini çıkar ve işlemi bakım penceresinde yap.","tags":["split partition","merge partition","add partition","partition bol","partition birlestir","update indexes","online","partitioning"]},{"id":"partition-exchange","task":"Exchange partition ile toplu veri yükle/arşivle","category":"Partition","command":"-- 1) Hedef tabloyla birebir uyumlu staging tablo (12.2+):\nCREATE TABLE musteri_app.satis_stage\n  FOR EXCHANGE WITH TABLE musteri_app.satis_part;\n\n-- 2) Staging'i doldur, local index'lerle ayni yapida index olustur:\nINSERT /*+ APPEND */ INTO musteri_app.satis_stage\nSELECT * FROM musteri_app.satis_yukleme WHERE tarih >= DATE '2027-01-01';\nCOMMIT;\nCREATE INDEX musteri_app.satis_stage_musteri_ix ON musteri_app.satis_stage (musteri_id);\n\n-- 3) Yer degistir (sadece sozluk islemi, veri tasinmaz):\nALTER TABLE musteri_app.satis_part\n  EXCHANGE PARTITION p2027 WITH TABLE musteri_app.satis_stage\n  INCLUDING INDEXES WITHOUT VALIDATION\n  UPDATE GLOBAL INDEXES;\n\n-- 4) Dogrula:\nSELECT COUNT(*) FROM musteri_app.satis_part PARTITION (p2027);\nSELECT index_name, partition_name, status\nFROM   dba_ind_partitions\nWHERE  index_owner = 'MUSTERI_APP' AND status <> 'USABLE';","what":"Bir partition'ın segmenti ile normal bir tablonun segmentini sözlükte yer değiştirir; milyonlarca satır saniyeler içinde tabloya \"girer\" veya arşiv için tablodan \"çıkar\". FOR EXCHANGE WITH TABLE, kolon/gizli kolon uyumunu garanti eden staging tablo üretir.","when":"DWH/ETL toplu yüklemelerinde, eski partition'ı arşiv tablosuna almakta, yükleme sırasında canlı tabloyu etkilemeden index ve istatistik hazırlamak için.","caution":"Partitioning opsiyonu (EE ek lisans) gerekir. WITHOUT VALIDATION, staging'deki satırların partition sınırına uyduğunu kontrol etmez; yanlış veri yanlış partition'da kalır ve sorgular hatalı sonuç verebilir; emin değilsen WITH VALIDATION kullan (tam tarama yapar). UPDATE GLOBAL INDEXES olmadan global index'ler UNUSABLE olur. Unique/PK constraint'lerin durumu iki tarafta da aynı olmalı.","note":"CREATE TABLE ... FOR EXCHANGE WITH TABLE 12.2 ile geldi; öncesinde staging tablo CREATE TABLE ... AS SELECT * FROM <tablo> WHERE 1=0 ile oluşturulur ve gizli/sanal kolon farkları elle kontrol edilir.","tags":["exchange partition","staging","for exchange with table","toplu yukleme","arsiv","update global indexes","partitioning"]},{"id":"partition-drop-truncate-gidx","task":"Partition'ı TRUNCATE/DROP et ve global index'leri kullanılabilir tut","category":"Partition","command":"-- Partition icerigini bosalt / partition'i kaldir (global index'ler bakimda kalir):\nALTER TABLE musteri_app.satis_part TRUNCATE PARTITION p2025 UPDATE INDEXES;\nALTER TABLE musteri_app.satis_part DROP PARTITION p2025 UPDATE INDEXES;\n\n-- 12c+ asenkron global index bakimi: index VALID ama yetim kayit tasir\nSELECT index_name, status, orphaned_entries\nFROM   dba_indexes\nWHERE  owner = 'MUSTERI_APP' AND table_name = 'SATIS_PART';\n\n-- Yetim kayitlari hemen temizle (normalde SYS.PMO_DEFERRED_GIDX_MAINT_JOB gece yapar):\nEXEC DBMS_PART.CLEANUP_GIDX(schema_name_in => 'MUSTERI_APP', table_name_in => 'SATIS_PART');\n-- veya tek index: ALTER INDEX musteri_app.satis_part_id_gidx COALESCE CLEANUP;\n\n-- Partition'i adiyla degil degeriyle hedefle:\n-- ALTER TABLE musteri_app.satis_part DROP PARTITION FOR (DATE '2025-06-15') UPDATE INDEXES;","what":"Eski verinin satır satır DELETE yerine partition düzeyinde anında silinmesini sağlar. 12c+ ile UPDATE INDEXES, global index'leri tek tek güncellemek yerine yalnız sözlükte işaretler (asenkron bakım); index anında kullanılabilir kalır, yetim kayıtlar sonra temizlenir.","when":"Veri saklama politikası (retention) gereği eski dönemleri atarken, ILM/purge işlerinde, büyük tabloda DELETE'in yarattığı undo/redo yükünden kaçınmak için.","caution":"Partitioning opsiyonu (EE ek lisans) gerekir. DROP/TRUNCATE geri alınamaz (flashback table partition'ı geri getirmez); önce yedek veya exchange ile arşiv al. UPDATE INDEXES unutulursa global index'ler UNUSABLE olur ve sorgular ORA-01502 alabilir. Referans veren child tablolar varsa (FK) işlem hata verir. Interval tablolarda son range (transition) partition'ı düşürülemez.","since":"Oracle 12c","tags":["drop partition","truncate partition","update indexes","orphaned_entries","cleanup_gidx","global index","veri silme","partitioning"]},{"id":"interval-partitioning","task":"Interval partitioning oluştur ve mevcut range tabloyu interval'e çevir","category":"Partition","command":"-- Yeni tablo: her ay icin partition otomatik olusur\nCREATE TABLE musteri_app.olcum (\n  ts        DATE   NOT NULL,\n  sensor_id NUMBER,\n  deger     NUMBER)\nPARTITION BY RANGE (ts) INTERVAL (NUMTOYMINTERVAL(1, 'MONTH'))\n( PARTITION p_ilk VALUES LESS THAN (DATE '2026-01-01') );\n\n-- Mevcut range tabloyu interval'e cevir (MAXVALUE partition olmamali):\nALTER TABLE musteri_app.satis_part SET INTERVAL (NUMTOYMINTERVAL(1, 'MONTH'));\n-- Geri range'e: ALTER TABLE musteri_app.satis_part SET INTERVAL ();\n\n-- Sistem adli partition'i anlamli adla yeniden adlandir:\nALTER TABLE musteri_app.olcum RENAME PARTITION FOR (DATE '2026-03-15') TO p2026_03;\n\n-- Kontrol:\nSELECT partition_name, partition_position, interval, high_value\nFROM   dba_tab_partitions\nWHERE  table_owner = 'MUSTERI_APP' AND table_name = 'OLCUM'\nORDER  BY partition_position;\n\nSELECT table_name, partitioning_type, interval\nFROM   dba_part_tables\nWHERE  owner = 'MUSTERI_APP';","what":"Interval partitioning, sınırın ötesine ilk satır geldiğinde yeni partition'ı otomatik yaratır; \"gelecek ayın partition'ını eklemeyi unuttuk\" kaynaklı ORA-14400 hatasını ortadan kaldırır. SET INTERVAL mevcut range tabloyu veri taşımadan dönüştürür.","when":"Zaman serisi, log, sipariş gibi tarihe göre büyüyen tablolarda; partition bakım script'lerini azaltmak için.","caution":"Partitioning opsiyonu (EE ek lisans) gerekir. Partition anahtarı tek kolon ve NUMBER/DATE/TIMESTAMP olmalı; MAXVALUE partition'ı varsa önce kaldırılmalı. Hatalı/uç bir tarih (ör. 9999 yılı) çok uzak bir partition açar ve partition numaralandırmasını bozar; dar interval'lerde 1.048.575 partition sınırına (ORA-14300) yaklaşılabilir, uygulamada tarih kontrolü yap. Otomatik partition'lar tablonun varsayılan tablespace'ine gider (STORE IN ile yönlendir).","since":"Oracle 11g","tags":["interval partitioning","interval","otomatik partition","numtoyminterval","ora-14400","set interval","range partition","partitioning"]},{"id":"partition-wise-join-check","task":"Partition anahtarlarını ve partition-wise join kullanımını doğrula","category":"Partition","command":"-- 1) Iki tablonun partition tipi, anahtari ve sayisi ayni mi?\nSELECT p.owner, p.table_name, p.partitioning_type, k.column_name,\n       p.partition_count, p.subpartitioning_type\nFROM   dba_part_tables p\n  JOIN dba_part_key_columns k\n    ON k.owner = p.owner AND k.name = p.table_name AND k.object_type = 'TABLE'\nWHERE  p.owner = 'MUSTERI_APP'\n  AND  p.table_name IN ('MUSTERI_H', 'SIPARIS_H');\n\n-- 2) Join'i acikla ve plan sekline bak:\nEXPLAIN PLAN FOR\nSELECT /*+ PARALLEL(4) */ m.il, SUM(s.tutar)\nFROM   musteri_app.musteri_h m\n  JOIN musteri_app.siparis_h s ON s.musteri_id = m.id\nGROUP  BY m.il;\n\nSELECT * FROM TABLE(DBMS_XPLAN.DISPLAY(format => 'BASIC +PARALLEL +PARTITION'));\n-- Full PWJ: HASH JOIN, PARTITION HASH ALL (paralelde PX PARTITION HASH ALL) satirinin ALTINDA\n-- Partial PWJ: tek tarafta PX SEND PARTITION (KEY)\n-- PWJ yok: her iki tarafta PX SEND HASH / BROADCAST","what":"Join anahtarına göre aynı şekilde (equi-partitioned) bölümlenmiş iki tablo, partition çiftleri halinde birleştirilebilir (full partition-wise join); bu, paralel sorgularda dağıtım (redistribution) trafiğini ve bellek kullanımını belirgin şekilde azaltır. Plan şekli PWJ'nin kullanılıp kullanılmadığını gösterir.","when":"DWH'ta büyük fact-fact veya fact-dimension join'lerini tasarlarken, paralel sorguda yoğun PX dağıtımı (PX Deq Credit: send blkd) görüldüğünde, partition stratejisini doğrularken.","caution":"Lisans: Partitioning opsiyonu (EE ek lisans); paralel sorgu Enterprise Edition gerektirir. EXPLAIN PLAN tahmindir, gerçek plan için DISPLAY_CURSOR/SQL Monitor kullan. Full PWJ için partition sayıları (hash'te 2'nin kuvveti önerilir) ve anahtar veri tipleri aynı olmalı. Seri planda da PWJ görülebilir ama asıl kazanç paralelde ortaya çıkar.","tags":["partition-wise join","pwj","equi-partitioning","hash partition","paralel sorgu","dba_part_key_columns","partitioning"]},{"id":"online-redefinition-flow","task":"DBMS_REDEFINITION ile tabloyu online yeniden tanımla (tam akış)","category":"Online İşlemler","command":"-- 1) Uygun mu? (PK yoksa CONS_USE_ROWID kullan)\nEXEC DBMS_REDEFINITION.CAN_REDEF_TABLE('MUSTERI_APP', 'MUSTERI', DBMS_REDEFINITION.CONS_USE_PK);\n\n-- 2) Hedef yapida ara (interim) tablo: ornekte hash partition'li\nCREATE TABLE musteri_app.musteri_int (\n  id NUMBER, ad VARCHAR2(100), il VARCHAR2(30))\nPARTITION BY HASH (id) PARTITIONS 8;\n\n-- 3) Baslat: ilk kopya + MV log ile degisiklik takibi\nBEGIN\n  DBMS_REDEFINITION.START_REDEF_TABLE(\n    uname        => 'MUSTERI_APP',\n    orig_table   => 'MUSTERI',\n    int_table    => 'MUSTERI_INT',\n    col_mapping  => NULL,\n    options_flag => DBMS_REDEFINITION.CONS_USE_PK);\nEND;\n/\n\n-- 4) Index, constraint, trigger, grant ve istatistikleri kopyala:\nSET SERVEROUTPUT ON\nDECLARE\n  l_errors PLS_INTEGER;\nBEGIN\n  DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS(\n    uname            => 'MUSTERI_APP',\n    orig_table       => 'MUSTERI',\n    int_table        => 'MUSTERI_INT',\n    copy_indexes     => DBMS_REDEFINITION.CONS_ORIG_PARAMS,\n    copy_triggers    => TRUE,\n    copy_constraints => TRUE,\n    copy_privileges  => TRUE,\n    ignore_errors    => FALSE,\n    num_errors       => l_errors,\n    copy_statistics  => TRUE);\n  DBMS_OUTPUT.PUT_LINE('Hata sayisi: ' || l_errors);\nEND;\n/\nSELECT object_name, base_table_name, ddl_txt FROM dba_redefinition_errors;\n\n-- 5) Bitis oncesi farki kapat (finish suresini kisaltir; birkac kez calistirilabilir):\nEXEC DBMS_REDEFINITION.SYNC_INTERIM_TABLE('MUSTERI_APP', 'MUSTERI', 'MUSTERI_INT');\n\n-- 6) Kisa kilitle yer degistir:\nEXEC DBMS_REDEFINITION.FINISH_REDEF_TABLE('MUSTERI_APP', 'MUSTERI', 'MUSTERI_INT', dml_lock_timeout => 60);\n\n-- 7) Artik eski yapiyi tasiyan ara tabloyu kaldir:\nDROP TABLE musteri_app.musteri_int PURGE;\n\n-- Sorun olursa: EXEC DBMS_REDEFINITION.ABORT_REDEF_TABLE('MUSTERI_APP', 'MUSTERI', 'MUSTERI_INT');\n-- Durum: SELECT * FROM dba_redefinition_status WHERE base_table_owner = 'MUSTERI_APP';","what":"Tablonun yapısını (partitioning, kolon tipi/sırası, tablespace, sıkıştırma, LOB ayarları) uygulama çalışırken değiştirir: veri ara tabloya kopyalanır, değişiklikler MV log ile senkronlanır, sonunda çok kısa bir lock ile isimler yer değiştirir.","when":"Partition'sız büyük bir tabloyu kesintisiz partition'lı hale getirmek, kolon tipini değiştirmek, BasicFile LOB'u SecureFile'a çevirmek gibi ALTER TABLE ile online yapılamayan değişikliklerde.","caution":"Enterprise Edition gerekir (hedef partition'lı ise Partitioning opsiyonu da). İşlem boyunca tablonun iki katı alan, ek redo ve MV log yükü oluşur. FINISH aşaması kısa bir exclusive lock alır; uzun süren transaction'lar bekletir (dml_lock_timeout). COPY_TABLE_DEPENDENTS hatalarını DBA_REDEFINITION_ERRORS'tan mutlaka kontrol et; FK'ler NOVALIDATE kopyalanabilir. Önce test ortamında prova et.","note":"dml_lock_timeout parametresi 12c ile geldi. 12.2+ ilerlemeyi V$ONLINE_REDEF view'ından izle. Basit taşıma/sıkıştırma için DBMS_REDEFINITION yerine ALTER TABLE ... MOVE ONLINE yeterlidir.","tags":["dbms_redefinition","online redefinition","yeniden tanimlama","kesintisiz","partition'a cevir","can_redef_table","finish_redef_table","enterprise edition"]},{"id":"table-move-online","task":"Tabloyu veya partition'ı online taşı (ALTER TABLE MOVE ONLINE)","category":"Online İşlemler","command":"-- Tabloyu baska tablespace'e tasi / yeniden duzenle (DML devam eder):\nALTER TABLE musteri_app.siparis MOVE ONLINE TABLESPACE musteri_data;\n\n-- Tasirken sikistir (BASIC; OLTP sikistirmasi icin ROW STORE COMPRESS ADVANCED):\nALTER TABLE musteri_app.siparis MOVE ONLINE COMPRESS;\n\n-- Tek partition:\nALTER TABLE musteri_app.satis_part\n  MOVE PARTITION p2026_h1 ONLINE TABLESPACE musteri_arsiv UPDATE INDEXES;\n\n-- Dogrula: index'ler VALID kalmali\nSELECT index_name, status FROM dba_indexes\nWHERE  owner = 'MUSTERI_APP' AND table_name = 'SIPARIS';\nSELECT table_name, tablespace_name, compression, compress_for\nFROM   dba_tables\nWHERE  owner = 'MUSTERI_APP' AND table_name = 'SIPARIS';","what":"Tablo segmentini yeniden yazar: fragmentasyonu ve high water mark'ı düşürür, tablespace değiştirir, sıkıştırma uygular. ONLINE ile işlem sırasında DML engellenmez ve index'ler otomatik olarak güncel/VALID kalır.","when":"Toplu DELETE sonrası alan geri kazanmak, tabloyu yeni tablespace/storage'a taşımak, eski partition'ları sıkıştırıp arşiv tablespace'ine almak için.","caution":"Enterprise Edition gerekir; ROW STORE COMPRESS ADVANCED için Advanced Compression opsiyonu (ek lisans) gerekir. İşlem süresince ek olarak tablo boyutu kadar alan ve yoğun redo üretir. İşlem başında ve sonunda kısa lock'lar alınır; uzun açık transaction'lar bekletir. ONLINE ve UPDATE INDEXES olmadan yapılan MOVE tüm index'leri UNUSABLE bırakır.","since":"Oracle 12.2","note":"Tablo düzeyinde MOVE ONLINE 12.2 ile geldi; partition düzeyinde MOVE PARTITION ONLINE 12.1'den beri vardır. 12.1 ve öncesinde tablo için DBMS_REDEFINITION kullan.","tags":["move online","alter table move","tablo tasi","reorganizasyon","high water mark","sikistirma","enterprise edition"]},{"id":"tde-keystore-setup","task":"TDE keystore oluştur, aç, master key üret ve yedekle (19c+)","category":"Güvenlik","command":"-- 1) Keystore konumu (statik parametre, restart gerekir), sonra keystore tipi:\nALTER SYSTEM SET WALLET_ROOT = '/u01/app/oracle/admin/ORCL/wallet' SCOPE = SPFILE;\n-- SHUTDOWN IMMEDIATE;  STARTUP;\nALTER SYSTEM SET TDE_CONFIGURATION = 'KEYSTORE_CONFIGURATION=FILE' SCOPE = BOTH;\n\n-- 2) CDB root'ta: software keystore olustur (WALLET_ROOT/tde altina), ac, master key uret\nADMINISTER KEY MANAGEMENT CREATE KEYSTORE IDENTIFIED BY \"<keystore_pwd>\";\nADMINISTER KEY MANAGEMENT SET KEYSTORE OPEN\n  IDENTIFIED BY \"<keystore_pwd>\" CONTAINER = ALL;\nADMINISTER KEY MANAGEMENT SET KEY USING TAG 'mk_2026_10'\n  IDENTIFIED BY \"<keystore_pwd>\" WITH BACKUP USING 'mk_oncesi' CONTAINER = ALL;\n\n-- 3) Restart sonrasi otomatik acilma (auto-login, cwallet.sso):\nADMINISTER KEY MANAGEMENT CREATE AUTO_LOGIN KEYSTORE\n  FROM KEYSTORE IDENTIFIED BY \"<keystore_pwd>\";\n\n-- 4) Yedek (her SET KEY / rekey sonrasi tekrarla, DB yedeginden AYRI sakla):\nADMINISTER KEY MANAGEMENT BACKUP KEYSTORE USING 'gunluk'\n  FORCE KEYSTORE IDENTIFIED BY \"<keystore_pwd>\" TO '/backup/tde/';\n\n-- 5) Durum:\nSELECT con_id, wrl_type, wrl_parameter, status, wallet_type, keystore_mode\nFROM   v$encryption_wallet;\nSELECT con_id, key_id, tag, creation_time, activation_time\nFROM   v$encryption_keys ORDER BY creation_time;","what":"Transparent Data Encryption için United mode'da (tüm PDB'ler CDB keystore'unu paylaşır) software keystore kurar, master encryption key üretir ve auto-login ile restart sonrası otomatik açılmasını sağlar. 19c+ önerilen yöntem sqlnet.ora ENCRYPTION_WALLET_LOCATION yerine WALLET_ROOT/TDE_CONFIGURATION'dır.","when":"Veri-at-rest şifreleme gerektiren uyumluluk (KVKK, PCI-DSS, ISO 27001) projelerinde, tablespace/kolon şifrelemeye başlamadan önce ilk adım olarak.","caution":"On-prem'de Advanced Security opsiyonu (ek lisans) gerekir; Oracle Cloud (OCI/Autonomous) lisansına dahildir. WALLET_ROOT statiktir, instance restart (kesinti) ister. Keystore ve parolası kaybolursa şifreli veri KALICI olarak okunamaz; keystore yedeğini DB yedeklerinden ayrı, güvenli bir yerde sakla. Auto-login (cwallet.sso) dosyasını ele geçiren DB'yi açabilir; dosya izinlerini kısıtla, gerekiyorsa LOCAL AUTO_LOGIN kullan. Data Guard'da keystore'u standby'a da kopyala.","since":"Oracle 18c","note":"WALLET_ROOT ve TDE_CONFIGURATION 18c ile geldi, 19c'de standarttır; 12c-18c'deki sqlnet.ora ENCRYPTION_WALLET_LOCATION yöntemi 19c'de deprecated, 23ai'de desupport edildi. 23ai'de varsayılan algoritma AES256'dır; GOST ve SEED ile şifreleme desupport, bunlarla şifre çözme deprecated'dır. WALLET_ROOT statik parametredir, instance restart gerektirir.","tags":["tde","keystore","wallet","master key","sifreleme","advanced security","wallet_root","administer key management"],"untested":true},{"id":"tde-tablespace-encryption","task":"Tablespace'i TDE ile şifrele (yeni ve mevcut tablespace, online/offline)","category":"Güvenlik","command":"-- On kosul: keystore OPEN ve master key set edilmis olmali (v$encryption_wallet.status = 'OPEN')\n\n-- 1) Yeni sifreli tablespace:\nCREATE TABLESPACE musteri_enc\n  DATAFILE '+DATA' SIZE 1G AUTOEXTEND ON NEXT 256M MAXSIZE 20G\n  ENCRYPTION USING 'AES256' ENCRYPT;\n\n-- 2a) Mevcut tablespace'i ONLINE sifrele (12.2+, gecici olarak ek alan ister):\nALTER TABLESPACE musteri_data ENCRYPTION ONLINE USING 'AES256' ENCRYPT;\n-- OMF degilse: ... ENCRYPT FILE_NAME_CONVERT = ('musteri_data01.dbf', 'musteri_data01_enc.dbf');\n\n-- 2b) OFFLINE donusum (ek alan istemez, tablespace bu surede erisilemez):\nALTER TABLESPACE musteri_data OFFLINE NORMAL;\nALTER TABLESPACE musteri_data ENCRYPTION OFFLINE ENCRYPT;\nALTER TABLESPACE musteri_data ONLINE;\n\n-- 3) Ilerleme ve durum:\nSELECT t.name AS tablespace_name, e.encryptionalg, e.status, e.con_id\nFROM   v$encrypted_tablespaces e\n  JOIN v$tablespace t ON t.ts# = e.ts# AND t.con_id = e.con_id;\nSELECT tablespace_name, encrypted FROM dba_tablespaces ORDER BY tablespace_name;","what":"Tablespace şifrelemesi, datafile'lara yazılan tüm blokları şifreler; buffer cache'te veri açık olduğu için uygulama ve SQL'de değişiklik gerekmez. Online dönüşüm datafile'ın şifreli kopyasını oluşturup DML sürerken yerine geçirir; offline dönüşüm blokları yerinde şifreler.","when":"Hassas veri içeren uygulama tablespace'lerini at-rest şifrelemek, yeni şifreli tablespace'e veri taşımak, denetim bulgusunu kapatmak için.","caution":"On-prem'de Advanced Security opsiyonu (ek lisans) gerekir. Online dönüşüm, şifrelenen datafile boyutu kadar ek alan ve yoğun I/O-redo üretir; Data Guard'da standby da aynı işlemi yapar. Offline dönüşüm Data Guard standby'da ayrıca çalıştırılmalıdır. SYSTEM/SYSAUX/UNDO şifrelemesi 12.2+ online yapılabilir ama ek dikkat ister. Şifreli tablespace'in yedekleri keystore olmadan geri yüklenemez.","since":"Oracle 12.2","note":"Online/offline tablespace dönüşümü 12.2 ile geldi. Yeni tablespace'leri otomatik şifrelemek için 19c'de TABLESPACE_ENCRYPTION=AUTO_ENABLE (19.16+ RU) veya ENCRYPT_NEW_TABLESPACES=ALWAYS kullanılır. Önce keystore açık ve master key set edilmiş olmalı (bkz. tde-keystore-setup).","tags":["tde","tablespace sifreleme","encryption online","aes256","v$encrypted_tablespaces","advanced security","at-rest"],"untested":true},{"id":"unified-audit-policy-lifecycle","task":"Unified Auditing politikası oluştur, koşullu etkinleştir, kayıtları izle, kaldır","category":"Güvenlik","command":"-- 1) Nesne + kosul bazli politika (batch modulu haric):\nCREATE AUDIT POLICY pol_musteri_dml\n  ACTIONS SELECT ON musteri_app.musteri,\n          UPDATE ON musteri_app.musteri,\n          DELETE ON musteri_app.musteri\n  WHEN 'SYS_CONTEXT(''USERENV'',''MODULE'') NOT LIKE ''batch%'''\n  EVALUATE PER SESSION;\n\n-- 2) Ayricalikli islemler politikasi:\nCREATE AUDIT POLICY pol_ddl_priv\n  PRIVILEGES DROP ANY TABLE, ALTER SYSTEM\n  ACTIONS DROP USER, ALTER USER, CREATE USER;\n\n-- 3) Etkinlestir:\nAUDIT POLICY pol_musteri_dml EXCEPT musteri_app;   -- sema sahibi haric herkes\nAUDIT POLICY pol_ddl_priv WHENEVER SUCCESSFUL;\nAUDIT POLICY ORA_LOGON_FAILURES WHENEVER NOT SUCCESSFUL;\n\n-- 4) Hangi politika kime acik?\nSELECT policy_name, enabled_option, entity_name, success, failure\nFROM   audit_unified_enabled_policies ORDER BY policy_name;\nSELECT policy_name, audit_option, object_schema, object_name, audit_condition\nFROM   audit_unified_policies WHERE policy_name LIKE 'POL_%';\n\n-- 5) Kayitlar:\nSELECT event_timestamp, dbusername, action_name, object_schema, object_name,\n       return_code, unified_audit_policies, os_username, userhost\nFROM   unified_audit_trail\nWHERE  event_timestamp > SYSTIMESTAMP - INTERVAL '1' DAY\n  AND  unified_audit_policies LIKE '%POL_%'\nORDER  BY event_timestamp DESC;\n-- 19c (queued-write): EXEC DBMS_AUDIT_MGMT.FLUSH_UNIFIED_AUDIT_TRAIL;  (23ai'de yok)\n\n-- 6) Kapat ve kaldir:\nNOAUDIT POLICY pol_musteri_dml;\nNOAUDIT POLICY pol_ddl_priv;\nDROP AUDIT POLICY pol_musteri_dml;\nDROP AUDIT POLICY pol_ddl_priv;","what":"Unified Auditing, tüm denetim kayıtlarını tek bir trail'de (AUDSYS şeması, UNIFIED_AUDIT_TRAIL) toplar. Politikalar nesne eylemi, sistem yetkisi veya eylem bazında tanımlanır; WHEN koşulu ve BY/EXCEPT kullanıcı listesiyle gürültü azaltılır.","when":"Hassas tablolara erişimi kayıt altına almak, ayrıcalıklı DDL/yetki değişikliklerini izlemek, başarısız login denemelerini görmek, denetim gereksinimlerini karşılamak için.","caution":"Ek lisans gerektirmez. SELECT denetimi yoğun tablolarda çok kayıt ve SYSAUX büyümesi üretir; koşul ve EXCEPT ile daralt, DBMS_AUDIT_MGMT ile arşivleme/temizlik (CLEAN_AUDIT_TRAIL, SET_LAST_ARCHIVE_TIMESTAMP) job'ı kur. Etkin politika DROP edilemez (ORA-46361), önce NOAUDIT. Politika değişikliği yeni session'larda geçerli olur. 19c'de varsayılan mixed mode'dur; geleneksel AUDIT_TRAIL kayıtları da üretilebilir.","since":"Oracle 12c","note":"23ai'de geleneksel (traditional) denetim desupport edildi; yalnız unified auditing vardır ve kayıtlar doğrudan tabloya yazıldığı için FLUSH_UNIFIED_AUDIT_TRAIL kaldırıldı. 19c'de saf unified moda geçiş için oracle binary'si uniaud_on ile relink edilir.","tags":["unified auditing","audit policy","denetim","unified_audit_trail","create audit policy","noaudit","ora_logon_failures","guvenlik"]},{"id":"vpd-row-level-policy","task":"VPD (DBMS_RLS) ile satır düzeyinde erişim politikası ekle","category":"Güvenlik","command":"-- 1) Predicate donduren policy fonksiyonu:\nCREATE OR REPLACE FUNCTION musteri_app.musteri_vpd_fn (\n  p_schema IN VARCHAR2,\n  p_object IN VARCHAR2\n) RETURN VARCHAR2\nAS\nBEGIN\n  -- Sema sahibi tum satirlari gorur (NULL = kisit yok)\n  IF SYS_CONTEXT('USERENV', 'SESSION_USER') = 'MUSTERI_APP' THEN\n    RETURN NULL;\n  END IF;\n  -- Diger kullanicilar yalniz kendi illerini gorur\n  RETURN 'il = SYS_CONTEXT(''USERENV'', ''CLIENT_IDENTIFIER'')';\nEND;\n/\n\n-- 2) Politikayi tabloya bagla:\nBEGIN\n  DBMS_RLS.ADD_POLICY(\n    object_schema   => 'MUSTERI_APP',\n    object_name     => 'MUSTERI',\n    policy_name     => 'MUSTERI_IL_VPD',\n    function_schema => 'MUSTERI_APP',\n    policy_function => 'MUSTERI_VPD_FN',\n    statement_types => 'SELECT, UPDATE, DELETE',\n    update_check    => TRUE,\n    policy_type     => DBMS_RLS.CONTEXT_SENSITIVE);\nEND;\n/\n\n-- 3) Kontrol:\nSELECT object_owner, object_name, policy_name, function,\n       sel, upd, del, chk_option, enable, policy_type\nFROM   dba_policies WHERE object_owner = 'MUSTERI_APP';\n-- Test (uygulama kullanicisi ile): EXEC DBMS_SESSION.SET_IDENTIFIER('Ankara');\n\n-- 4) Gecici kapat / kaldir:\nEXEC DBMS_RLS.ENABLE_POLICY('MUSTERI_APP', 'MUSTERI', 'MUSTERI_IL_VPD', FALSE);\nEXEC DBMS_RLS.DROP_POLICY('MUSTERI_APP', 'MUSTERI', 'MUSTERI_IL_VPD');","what":"Virtual Private Database, tabloya yapılan her SQL'e policy fonksiyonunun döndürdüğü WHERE koşulunu otomatik ekler; aynı tabloya erişen kullanıcılar yalnızca yetkili oldukları satırları görür/değiştirir. update_check=>TRUE, kullanıcının satırı göremeyeceği bir değere güncellemesini engeller.","when":"Çok kiracılı (multi-tenant) uygulamalarda, bölge/şube bazlı veri izolasyonunda, uygulama koduna dokunmadan satır güvenliği eklemek için.","caution":"Enterprise Edition'a dahildir, ek lisans gerekmez. CLIENT_IDENTIFIER istemci tarafından serbestçe set edilebilir; üretimde değeri güvenilir bir package ile set edilen application context (CREATE CONTEXT ... USING) kullan. SYS ve EXEMPT ACCESS POLICY yetkisine sahip kullanıcılar politikayı aşar; Data Pump export'ları da bu yetki yoksa eksik veri çıkarır. Fonksiyondaki hata ORA-28112 ile tüm erişimi keser. policy_type yanlış seçilirse (ör. STATIC) predicate önbelleğe alınır ve yanlış sonuç döner.","tags":["vpd","virtual private database","dbms_rls","satir guvenligi","row level security","add_policy","policy function","guvenlik"]},{"id":"password-profile-hardening","task":"Parola politikası için profile oluştur ve kullanıcıya ata","category":"Güvenlik","command":"-- Uygulama/insan kullanicilari icin sikilastirilmis profile:\nCREATE PROFILE app_kullanici_prf LIMIT\n  FAILED_LOGIN_ATTEMPTS    5\n  PASSWORD_LOCK_TIME       1/24          -- 1 saat kilit\n  PASSWORD_LIFE_TIME       90\n  PASSWORD_GRACE_TIME      7\n  PASSWORD_REUSE_TIME      365\n  PASSWORD_REUSE_MAX       10\n  INACTIVE_ACCOUNT_TIME    60            -- 60 gun kullanilmayan hesap kilitlenir\n  PASSWORD_VERIFY_FUNCTION ora12c_strong_verify_function;\n\n-- Servis hesaplari: parola suresi dolmasin, kademeli parola degisimi (rollover) acik:\nCREATE PROFILE servis_hesabi_prf LIMIT\n  FAILED_LOGIN_ATTEMPTS    UNLIMITED\n  PASSWORD_LIFE_TIME       UNLIMITED\n  PASSWORD_ROLLOVER_TIME   1;            -- 1 gun eski+yeni parola birlikte gecerli\n\nALTER USER musteri_app PROFILE app_kullanici_prf;\n\n-- Kontrol:\nSELECT username, profile, account_status,\n       TO_CHAR(expiry_date,'YYYY-MM-DD') AS expiry_date, lock_date\nFROM   dba_users\nWHERE  profile IN ('APP_KULLANICI_PRF', 'SERVIS_HESABI_PRF');\n\nSELECT profile, resource_name, limit\nFROM   dba_profiles\nWHERE  profile = 'APP_KULLANICI_PRF' AND resource_type = 'PASSWORD'\nORDER  BY resource_name;","what":"Profile ile hatalı giriş kilidi, parola ömrü, tekrar kullanım, karmaşıklık (verify function) ve uzun süre kullanılmayan hesabın kilitlenmesi kuralları kullanıcı grubuna uygulanır. PASSWORD_ROLLOVER_TIME, servis hesabının parolası değiştirilirken uygulamaların kesintisiz geçişini sağlar.","when":"Güvenlik denetimi/CIS benchmark gereksinimlerinde, yeni uygulama kullanıcıları açılırken, DEFAULT profile'ın gevşek değerlerini kullanıcı gruplarına göre ayırmak için.","caution":"Ek lisans gerektirmez. Servis hesabına FAILED_LOGIN_ATTEMPTS sınırı koymak, yanlış parolalı bir uygulama sunucusunun hesabı kilitleyip prod kesintisi yaratmasına yol açabilir. PASSWORD_LIFE_TIME uygulama hesaplarında beklenmedik EXPIRED durumuna neden olur. Verify function SYS altında olmalı (yoksa @?/rdbms/admin/utlpwdmg.sql; bu script DEFAULT profile'ı da değiştirir). Profile değişikliği mevcut parolayı geriye dönük denetlemez.","note":"INACTIVE_ACCOUNT_TIME 12.2 ile, PASSWORD_ROLLOVER_TIME 21c ile geldi ve 19c'ye 19.12 RU ile backport edildi. Rollover süresi içinde eski parolayla giriş yapan session'lar audit kayıtlarıyla izlenebilir.","tags":["profile","parola politikasi","password_verify_function","failed_login_attempts","inactive_account_time","password_rollover_time","hesap kilidi","guvenlik"]},{"id":"privilege-analysis-capture","task":"Privilege analysis ile kullanılmayan yetkileri tespit et","category":"Güvenlik","command":"-- 1) Belirli kullanici icin yetki kullanimini yakala:\nBEGIN\n  DBMS_PRIVILEGE_CAPTURE.CREATE_CAPTURE(\n    name        => 'CAP_APP_KULLANICI',\n    description => 'Uygulama kullanicisinin gercek yetki kullanimi',\n    type        => DBMS_PRIVILEGE_CAPTURE.G_CONTEXT,\n    condition   => 'SYS_CONTEXT(''USERENV'',''SESSION_USER'') = ''MUSTERI_APP''');\n  DBMS_PRIVILEGE_CAPTURE.ENABLE_CAPTURE(name => 'CAP_APP_KULLANICI', run_name => 'RUN_2026_10');\nEND;\n/\n-- Diger tipler: G_DATABASE (tum DB), G_ROLE (roles => role_name_list('DBA')), G_ROLE_AND_CONTEXT\n\n-- 2) Temsili is yuku (ay sonu dahil) bittikten sonra durdur ve sonuc uret:\nBEGIN\n  DBMS_PRIVILEGE_CAPTURE.DISABLE_CAPTURE(name => 'CAP_APP_KULLANICI');\n  DBMS_PRIVILEGE_CAPTURE.GENERATE_RESULT(name => 'CAP_APP_KULLANICI', run_name => 'RUN_2026_10');\nEND;\n/\n\n-- 3) Kullanilan ve hic kullanilmayan yetkiler:\nSELECT username, sys_priv, obj_priv, object_owner, object_name, used_role\nFROM   dba_used_privs   WHERE capture = 'CAP_APP_KULLANICI';\nSELECT username, sys_priv, obj_priv, object_owner, object_name\nFROM   dba_unused_privs WHERE capture = 'CAP_APP_KULLANICI';\n\n-- 4) Yetki hangi rol zinciri uzerinden kullanildi?\nSELECT username, sys_priv, used_role, path\nFROM   dba_used_sysprivs_path WHERE capture = 'CAP_APP_KULLANICI';\n\n-- 5) Temizlik:\nEXEC DBMS_PRIVILEGE_CAPTURE.DROP_CAPTURE(name => 'CAP_APP_KULLANICI');","what":"Privilege analysis, belirlenen kapsamda (tüm DB, rol, koşul) çalışma zamanında hangi sistem/nesne yetkilerinin gerçekten kullanıldığını kaydeder; sonuçta kullanılmayan yetkiler listelenir ve en az yetki (least privilege) prensibine göre REVOKE planlanır.","when":"DBA/ANY yetkili uygulama hesaplarını temizlerken, denetim öncesi yetki gözden geçirmede, hazır (packaged) uygulamanın gerçekten neye ihtiyaç duyduğunu çıkarmak için.","caution":"2018'den itibaren Enterprise Edition'a dahildir (önceden Database Vault lisansı gerektiriyordu); ek lisans gerekmez. Yakalama sırasında az da olsa ek yük vardır. Sonuç yalnızca yakalama penceresindeki iş yükünü yansıtır: ay sonu, yıl sonu veya acil durum işleri çalışmadıysa \"kullanılmıyor\" görünen yetki aslında gerekebilir; REVOKE'u kademeli yap. Aynı anda yalnızca bir capture etkin olabilir; tek istisna, bir G_DATABASE capture'ının rol veya context tipindeki bir capture ile birlikte etkin olabilmesidir.","since":"Oracle 12c","tags":["privilege analysis","dbms_privilege_capture","kullanilmayan yetki","least privilege","dba_unused_privs","yetki temizligi","guvenlik"]},{"id":"opatch-inventory-prereq","task":"OPatch ile envanteri gör ve yama öncesi ön kontrolleri çalıştır","category":"Patch & Yaşam Döngüsü","command":"# OPatch surumu (yama README'sindeki minimum surumu karsilamali; gerekirse yama 6880880 ile guncelle)\n$ORACLE_HOME/OPatch/opatch version\n\n# Kurulu yamalar: kisa liste / ayrintili envanter\n$ORACLE_HOME/OPatch/opatch lspatches\n$ORACLE_HOME/OPatch/opatch lsinventory -detail -oh $ORACLE_HOME\n\n# Uygulama oncesi kontroller (acilmis yama dizininde):\ncd /u01/stage/<patch_id>\n$ORACLE_HOME/OPatch/opatch prereq CheckConflictAgainstOHWithDetail -ph ./\n$ORACLE_HOME/OPatch/opatch prereq CheckSystemSpace -ph ./\n\n# Grid Infrastructure / RAC home'lari icin (root olarak) analiz modu:\n# opatchauto apply /u01/stage/<patch_id> -analyze","what":"Oracle Home'a uygulanmış binary yamaları (RU, one-off) listeler ve yeni yamanın mevcut yamalarla çakışıp çakışmadığını, yeterli disk alanı olup olmadığını uygulama öncesinde kontrol eder.","when":"Çeyreklik RU/güvenlik yaması öncesi, destek (SR) açarken envanter çıktısı istendiğinde, iki ortamın patch seviyesini karşılaştırırken.","caution":"Komutlar Oracle Home sahibi OS kullanıcısıyla (oracle) çalıştırılmalı; opatchauto root ister. Prereq kontrolleri salt okunurdur ve DB'yi etkilemez, ancak çakışma çıkarsa merge/overlay yama için Oracle Support'a başvurmadan apply yapma. Uygulamadan önce Oracle Home'un (tar) ve inventory'nin yedeğini al.","note":"SQL'den envanter görmek için DBMS_QOPATCH.GET_OPATCH_LSINVENTORY kullanılabilir (OPatch inventory'si olan kurulumlarda).","tags":["opatch","lsinventory","lspatches","prereq","yama","patch conflict","opatchauto","release update"],"untested":true},{"id":"datapatch-apply-verify","task":"Binary yama sonrası datapatch -verbose ile SQL katmanını güncelle","category":"Patch & Yaşam Döngüsü","command":"# 1) Binary yama (opatch apply) sonrasi DB'yi ac, tum PDB'ler acik olmali:\nsqlplus / as sysdba <<EOF\nSTARTUP;\nALTER PLUGGABLE DATABASE ALL OPEN;\nEXIT;\nEOF\n\n# 2) Once yalniz kontrol, sonra uygula:\ncd $ORACLE_HOME/OPatch\n./datapatch -prereq\n./datapatch -verbose\n# Belirli PDB'ler icin: ./datapatch -verbose -pdbs PDB1,PDB2\n\n# 3) Gecersiz nesneleri derle:\nsqlplus / as sysdba @?/rdbms/admin/utlrp.sql\n\n# Loglar: $ORACLE_BASE/cfgtoollogs/sqlpatch/","what":"datapatch, Oracle Home'daki binary yamaların SQL/PL-SQL bileşenlerini (sözlük, package'lar) CDB root, PDB$SEED ve tüm açık PDB'lere uygular ve sonucu DBA_REGISTRY_SQLPATCH'e yazar. Rollback edilen yamaların SQL kısmını da geri alır.","when":"Her RU/RUR/one-off binary yama veya rollback sonrasında; yeni patch'li home'a taşınan/unplug-plug edilen PDB'lerde; DBA_REGISTRY_SQLPATCH'te WITH ERRORS görüldüğünde yeniden çalıştırmak için.","caution":"Kapalı veya MOUNT durumdaki PDB'ler yamalanmaz ve açıldıklarında RESTRICTED modda kalabilir; önce hepsini aç. Yoğun yükte çalıştırma (sözlük lock'ları, package invalidation'ı). RAC'ta yalnızca bir node'dan bir kez çalıştırılır. Data Guard'da datapatch yalnızca primary'de çalıştırılır; değişiklik redo ile standby'a gider (önce standby binary'leri yamalanmalı).","note":"Güncel 19c RU'larla gelen datapatch'te -sanity_checks seçeneği yama öncesi sözlük ve ortam sağlığını (invalid nesneler, PDB violation'ları, tablespace/TEMP durumu) kontrol eder.","tags":["datapatch","sql patch","release update","dba_registry_sqlpatch","yama sonrasi","utlrp","pdb","patching"],"untested":true},{"id":"sqlpatch-registry-check","task":"SQL patch geçmişini, bileşen durumunu ve geçersiz nesneleri doğrula","category":"Patch & Yaşam Döngüsü","command":"-- 1) datapatch gecmisi (en son uygulanan en altta):\nSELECT patch_id, patch_type, action, status, source_version, target_version,\n       TO_CHAR(action_time,'YYYY-MM-DD HH24:MI') AS action_time, description\nFROM   dba_registry_sqlpatch\nORDER  BY action_time;\n\n-- Basarisiz olanlar ve log dosyalari:\nSELECT install_id, patch_id, action, status, logfile\nFROM   dba_registry_sqlpatch\nWHERE  status <> 'SUCCESS';\n\n-- CDB'de tum PDB'ler icin (root'tan):\nSELECT con_id, patch_id, action, status\nFROM   cdb_registry_sqlpatch ORDER BY con_id, action_time;\n\n-- 2) Bilesenler VALID olmali:\nSELECT comp_id, comp_name, version_full, status\nFROM   dba_registry ORDER BY comp_id;\n\n-- 3) Gecersiz nesne ozeti (utlrp oncesi/sonrasi karsilastir):\nSELECT owner, object_type, COUNT(*) AS invalid_cnt\nFROM   dba_objects\nWHERE  status = 'INVALID'\nGROUP  BY owner, object_type\nORDER  BY invalid_cnt DESC;","what":"Yama sonrası SQL katmanının gerçekten güncellendiğini (binary ile sözlük uyumlu mu), hangi PDB'de hangi yamanın başarısız olduğunu, sözlük bileşenlerinin VALID durumunu ve geçersiz nesne sayısını tek bakışta gösterir.","when":"Her datapatch sonrası doğrulama adımı olarak, yama/upgrade öncesi baz durum almak için, PDB taşıma (plug-in) sonrasında uyumsuzluk şüphesinde.","caution":"Salt okunur; lisans gerektirmez. SOURCE_VERSION/TARGET_VERSION kolonları 18c+ RU modelinde doludur. STATUS='WITH ERRORS' ise LOGFILE'daki hatayı çöz ve datapatch'i tekrar çalıştır. Bazı bileşenler (ör. kullanılmayan XDB/JAVA) INVALID/REMOVED görünebilir; yamadan önceki durumla karşılaştır.","note":"Binary envanteri SQL'den görmek için SELECT XMLTRANSFORM(DBMS_QOPATCH.GET_OPATCH_LIST, DBMS_QOPATCH.GET_OPATCH_XSLT) FROM dual; kullanılabilir; OPatch inventory'si olmayan kurulumda ORA-20013 verir.","tags":["dba_registry_sqlpatch","patch gecmisi","datapatch","dba_registry","invalid objects","gecersiz nesne","yama dogrulama"]},{"id":"scheduler-job-lifecycle","task":"Scheduler job oluştur, elle çalıştır, devre dışı bırak ve kaldır","category":"Scheduler","command":"-- 1) Kapali olarak olustur, ozelliklerini ayarla, sonra etkinlestir:\nBEGIN\n  DBMS_SCHEDULER.CREATE_JOB(\n    job_name        => 'MUSTERI_APP.GECE_ISTATISTIK',\n    job_type        => 'PLSQL_BLOCK',\n    job_action      => q'[BEGIN DBMS_STATS.GATHER_SCHEMA_STATS(ownname => 'MUSTERI_APP', options => 'GATHER STALE'); END;]',\n    start_date      => SYSTIMESTAMP,\n    repeat_interval => 'FREQ=DAILY; BYHOUR=2; BYMINUTE=30; BYSECOND=0',\n    enabled         => FALSE,\n    auto_drop       => FALSE,\n    comments        => 'Gece stale istatistik toplama');\n  DBMS_SCHEDULER.SET_ATTRIBUTE('MUSTERI_APP.GECE_ISTATISTIK', 'max_run_duration', INTERVAL '2' HOUR);\n  DBMS_SCHEDULER.SET_ATTRIBUTE('MUSTERI_APP.GECE_ISTATISTIK', 'logging_level', DBMS_SCHEDULER.LOGGING_FULL);\n  DBMS_SCHEDULER.ENABLE('MUSTERI_APP.GECE_ISTATISTIK');\nEND;\n/\n\n-- 2) Takvim ifadesini dogrula (sonraki calisma ani):\nSET SERVEROUTPUT ON\nDECLARE\n  l_next TIMESTAMP WITH TIME ZONE;\nBEGIN\n  DBMS_SCHEDULER.EVALUATE_CALENDAR_STRING(\n    calendar_string   => 'FREQ=DAILY; BYHOUR=2; BYMINUTE=30; BYSECOND=0',\n    start_date        => SYSTIMESTAMP,\n    return_date_after => SYSTIMESTAMP,\n    next_run_date     => l_next);\n  DBMS_OUTPUT.PUT_LINE('Sonraki calisma: ' || l_next);\nEND;\n/\n\n-- 3) Simdi arka planda calistir (takvimi bozmaz):\nEXEC DBMS_SCHEDULER.RUN_JOB('MUSTERI_APP.GECE_ISTATISTIK', use_current_session => FALSE);\n\n-- 4) Durum:\nSELECT owner, job_name, enabled, state, run_count, failure_count,\n       last_start_date, next_run_date\nFROM   dba_scheduler_jobs WHERE owner = 'MUSTERI_APP';\n\n-- 5) Durdur (calisiyorsa) / devre disi birak / kaldir:\n-- EXEC DBMS_SCHEDULER.STOP_JOB('MUSTERI_APP.GECE_ISTATISTIK', force => FALSE);\nEXEC DBMS_SCHEDULER.DISABLE('MUSTERI_APP.GECE_ISTATISTIK', force => TRUE);\nEXEC DBMS_SCHEDULER.DROP_JOB('MUSTERI_APP.GECE_ISTATISTIK', force => TRUE);","what":"DBMS_SCHEDULER ile takvimli bir PL/SQL işi tanımlar; maksimum süre aşımında olay üreten max_run_duration ve ayrıntılı log seviyesi ayarlanır, takvim ifadesi önceden doğrulanır, iş takvimi bozulmadan elle tetiklenebilir.","when":"Bakım, ETL, temizlik gibi tekrarlayan DB işlerini cron yerine veritabanı içinde, RAC/Data Guard farkındalığıyla çalıştırmak için.","caution":"Ek lisans gerektirmez. start_date'in saat dilimi önemlidir: SYSTIMESTAMP DB sunucusunun TZ'sini alır; yaz saati geçişlerinde kaymaması için açık bölge (ör. 'Europe/Istanbul') kullan. JOB_QUEUE_PROCESSES=0 ise hiçbir job çalışmaz. DISABLE force=>TRUE çalışan örneği durdurmaz, yalnız sonrakileri engeller; çalışanı kesmek için STOP_JOB kullan. Başka şemada job oluşturmak CREATE ANY JOB ister.","tags":["dbms_scheduler","job","zamanlanmis is","create_job","run_job","repeat_interval","disable job","scheduler"]},{"id":"scheduler-job-history","task":"Scheduler job'larının çalışma geçmişini ve hatalarını izle","category":"Scheduler","command":"-- 1) Son calismalar: sure, CPU, hata kodu ve mesaji\nSELECT owner, job_name, status, error#,\n       TO_CHAR(actual_start_date,'YYYY-MM-DD HH24:MI:SS') AS started,\n       run_duration, cpu_used,\n       SUBSTR(additional_info, 1, 200) AS info\nFROM   dba_scheduler_job_run_details\nWHERE  owner = 'MUSTERI_APP'\nORDER  BY actual_start_date DESC\nFETCH FIRST 20 ROWS ONLY;\n\n-- 2) Son 24 saatte basarisiz olanlar (tum DB):\nSELECT owner, job_name, error#, actual_start_date, SUBSTR(errors, 1, 300) AS errors\nFROM   dba_scheduler_job_run_details\nWHERE  status <> 'SUCCEEDED'\n  AND  log_date > SYSTIMESTAMP - INTERVAL '1' DAY\nORDER  BY log_date DESC;\n\n-- 3) Su an calisanlar:\nSELECT owner, job_name, session_id, running_instance, elapsed_time, cpu_used\nFROM   dba_scheduler_running_jobs;\n\n-- 4) Yasam dongusu olaylari (ENABLE/DISABLE/RUN/STOP...):\nSELECT log_date, owner, job_name, operation, status\nFROM   dba_scheduler_job_log\nWHERE  owner = 'MUSTERI_APP'\nORDER  BY log_date DESC\nFETCH FIRST 20 ROWS ONLY;\n\n-- Log saklama suresi (gun): EXEC DBMS_SCHEDULER.SET_SCHEDULER_ATTRIBUTE('log_history', '30');","what":"Scheduler log view'larından her çalışmanın başlangıç zamanını, süresini, CPU kullanımını, durumunu ve hata mesajını; çalışan job'ları ve job yaşam döngüsü olaylarını listeler.","when":"Gece işi çalışmadı/uzun sürdü şikayetinde, job'ların SLA takibinde, izleme sistemine (OEM/Zabbix/Prometheus) hata kuralı tanımlarken.","caution":"Salt okunur; lisans gerektirmez. Varsayılan log saklama 30 gündür ve logging_level OFF olan job'lar kayıt üretmez. ERRORS kolonu 12c+ ile gelir; eski sürümlerde ADDITIONAL_INFO'ya bak. RAC'ta RUNNING_INSTANCE işin hangi node'da koştuğunu gösterir.","tags":["scheduler","job gecmisi","dba_scheduler_job_run_details","basarisiz job","dba_scheduler_running_jobs","job log","izleme"]},{"id":"resource-plan-basic","task":"Basit bir Resource Manager planı oluştur ve etkinleştir","category":"Scheduler","command":"-- 1) Pending area icinde grup, plan, direktif ve eslesme tanimla (PDB veya non-CDB):\nBEGIN\n  DBMS_RESOURCE_MANAGER.CLEAR_PENDING_AREA;\n  DBMS_RESOURCE_MANAGER.CREATE_PENDING_AREA;\n\n  DBMS_RESOURCE_MANAGER.CREATE_CONSUMER_GROUP('OLTP_GRP',  'Online islemler');\n  DBMS_RESOURCE_MANAGER.CREATE_CONSUMER_GROUP('RAPOR_GRP', 'Raporlama / batch');\n  DBMS_RESOURCE_MANAGER.CREATE_PLAN('GUNDUZ_PLAN', 'Mesai saati plani');\n\n  DBMS_RESOURCE_MANAGER.CREATE_PLAN_DIRECTIVE(\n    plan => 'GUNDUZ_PLAN', group_or_subplan => 'OLTP_GRP',\n    comment => 'OLTP oncelikli', mgmt_p1 => 70);\n  DBMS_RESOURCE_MANAGER.CREATE_PLAN_DIRECTIVE(\n    plan => 'GUNDUZ_PLAN', group_or_subplan => 'RAPOR_GRP',\n    comment => 'Rapor sinirli', mgmt_p1 => 20,\n    parallel_degree_limit_p1 => 4,\n    switch_group => 'CANCEL_SQL', switch_time => 1800, switch_for_call => TRUE);\n  DBMS_RESOURCE_MANAGER.CREATE_PLAN_DIRECTIVE(\n    plan => 'GUNDUZ_PLAN', group_or_subplan => 'OTHER_GROUPS',\n    comment => 'Diger herkes (zorunlu)', mgmt_p1 => 10);\n\n  DBMS_RESOURCE_MANAGER.SET_CONSUMER_GROUP_MAPPING(\n    attribute      => DBMS_RESOURCE_MANAGER.ORACLE_USER,\n    value          => 'RAPOR_KULLANICI',\n    consumer_group => 'RAPOR_GRP');\n\n  DBMS_RESOURCE_MANAGER.VALIDATE_PENDING_AREA;\n  DBMS_RESOURCE_MANAGER.SUBMIT_PENDING_AREA;\nEND;\n/\n-- Eslesmenin gecerli olmasi icin switch yetkisi:\nEXEC DBMS_RESOURCE_MANAGER_PRIVS.GRANT_SWITCH_CONSUMER_GROUP('RAPOR_KULLANICI', 'RAPOR_GRP', FALSE);\n\n-- 2) Etkinlestir (FORCE: bakim penceresinin plani degistirmesini engeller):\nALTER SYSTEM SET resource_manager_plan = 'FORCE:GUNDUZ_PLAN' SCOPE = BOTH;\n\n-- 3) Izle:\nSELECT sid, username, resource_consumer_group FROM v$session WHERE username IS NOT NULL;\nSELECT name, active_sessions, execution_waiters, consumed_cpu_time, cpu_wait_time\nFROM   v$rsrc_consumer_group;\n\n-- 4) Geri al: plani kapat, sonra sil\n-- ALTER SYSTEM SET resource_manager_plan = '' SCOPE = BOTH;\n-- BEGIN DBMS_RESOURCE_MANAGER.CREATE_PENDING_AREA;\n--       DBMS_RESOURCE_MANAGER.DELETE_PLAN_CASCADE('GUNDUZ_PLAN');\n--       DBMS_RESOURCE_MANAGER.SUBMIT_PENDING_AREA; END;\n-- /","what":"CPU darboğazında hangi iş yükünün öncelikli olacağını belirler: OLTP grubuna %70, rapor grubuna %20 CPU payı verir; rapor grubunda paralelliği 4 ile sınırlar ve 30 dakikayı aşan çağrıyı iptal eder (CANCEL_SQL). Kullanıcılar consumer group'lara otomatik eşlenir.","when":"Gün içi raporların OLTP'yi yavaşlattığı karma iş yüklerinde, kontrolsüz paralel sorguları sınırlamak, kaçak (runaway) sorguları otomatik kesmek için.","caution":"Resource Manager Enterprise Edition gerektirir (SE2'de çok sınırlıdır); ek lisans gerekmez. mgmt_p1 yüzdeleri yalnız CPU yarıştığında devreye girer ve bir seviyede toplam %100'ü geçemez. CANCEL_SQL çalışan sorguyu ORA-00040 ile keser; yanlış eşleme kritik işleri kesebileceği için eşikleri önce test ortamında dene. Plan etkinken CPU throttling 'resmgr:cpu quantum' wait event'i olarak görünür. CDB seviyesinde PDB'ler arası paylaşım için CREATE_CDB_PLAN kullanılır.","tags":["resource manager","dbms_resource_manager","resource plan","consumer group","cpu onceligi","cancel_sql","resmgr:cpu quantum","kaynak yonetimi"]}]},"recipes/postgres.json":{"engineId":"postgres","engine":"PostgreSQL","order":2,"recipes":[{"id":"wal-switch","task":"WAL segmentini değiştir (switch)","category":"WAL & Checkpoint","command":"SELECT pg_switch_wal();","what":"Mevcut WAL segmentini kapatıp yenisine geçer; arşivlemeyi tetikler.","when":"Arşiv üretmek, yedek sonrası WAL'ı zorlamak için.","caution":"PostgreSQL 10 öncesi pg_switch_xlog() idi.","since":"PostgreSQL 10","note":"Bu fonksiyon PostgreSQL 10'da pg_switch_wal() olarak adlandırıldı; öncesinde pg_switch_xlog() idi (WAL eskiden 'xlog' olarak anılırdı).","tags":["wal","switch","checkpoint","archive"]},{"id":"manual-checkpoint","task":"Manuel CHECKPOINT çalıştır","category":"WAL & Checkpoint","command":"CHECKPOINT;","what":"Dirty buffer'ları diske yazar ve bir checkpoint kaydı oluşturur; kurtarma başlangıç noktasını ilerletir.","when":"Yedek öncesi, bakım penceresinde veya sunucuyu durdurmadan önce diski senkronlamak için.","caution":"Yoğun I/O üretebilir; production'da tepe saatlerde çalıştırma. Yalnızca superuser veya (PG15+) pg_checkpoint rolü çalıştırabilir.","tags":["checkpoint","wal","io","flush"]},{"id":"wal-status-size","task":"WAL boyutu ve mevcut LSN durumunu gör","category":"WAL & Checkpoint","command":"SELECT pg_current_wal_lsn() AS current_lsn, pg_walfile_name(pg_current_wal_lsn()) AS current_wal_file, pg_size_pretty(sum(size)) AS wal_dir_size FROM pg_ls_waldir();","what":"Aktif WAL LSN'ini, o an yazılan WAL dosya adını ve pg_wal dizininin toplam boyutunu döndürür.","when":"WAL birikimini, disk kullanımını ve checkpoint aralığını izlemek için.","caution":"pg_ls_waldir ve pg_walfile_name PostgreSQL 10+ ile gelir; erişim için pg_monitor rolü gerekebilir.","tags":["wal","lsn","size","monitor"]},{"id":"archive-lag","task":"Arşiv gecikmesini (henüz arşivlenmemiş WAL) gör","category":"WAL & Checkpoint","command":"SELECT last_archived_wal, last_failed_wal, archived_count, failed_count, pg_walfile_name(pg_current_wal_lsn()) AS current_wal FROM pg_stat_archiver;","what":"En son arşivlenen WAL dosyasını, o an yazılan WAL'ı ve arşivleme hata sayaçlarını karşılaştırarak arşiv gecikmesini gösterir.","when":"archive_command'ın geride kalıp kalmadığını, arşiv hatalarını izlemek için.","caution":"failed_count sürekli artıyorsa archive_command başarısızdır ve pg_wal dolabilir; disk taşmasına karşı acil müdahale gerekir.","tags":["archive","wal","lag","monitor"]},{"id":"create-tablespace","task":"Yeni tablespace ekle","category":"Depolama","command":"CREATE TABLESPACE ssd_ts OWNER postgres LOCATION '/mnt/ssd/pgdata';","what":"Belirtilen dizinde yeni bir tablespace tanımlar; tablo ve index'ler bu diske yerleştirilebilir.","when":"Verileri farklı bir diske (ör. hızlı SSD) yaymak, I/O'yu ayırmak için.","caution":"Dizin önceden var, boş ve postgres kullanıcısına ait olmalı. Sembolik link ile başka disklere dağıtma; PostgreSQL'in kendi tablespace mekanizmasını kullan.","tags":["tablespace","storage","disk","create"]},{"id":"move-table-tablespace","task":"Tabloyu başka tablespace'e taşı","category":"Depolama","command":"ALTER TABLE musteri SET TABLESPACE ssd_ts;","what":"Tablonun tüm verisini yeni tablespace'e (diske) fiziksel olarak taşır.","when":"Bir tabloyu daha hızlı/ayrı bir diske almak için.","caution":"Taşıma sırasında tabloya ACCESS EXCLUSIVE lock alınır; tablo taşınana kadar erişilemez. Büyük tablolar için bakım penceresinde yap.","tags":["tablespace","table","move","storage"]},{"id":"move-index-tablespace","task":"Index'i başka tablespace'e taşı","category":"Depolama","command":"ALTER INDEX musteri_email_idx SET TABLESPACE ssd_ts;","what":"Index'i belirtilen tablespace'e taşır.","when":"Index'leri veriden ayrı bir diske koyup I/O'yu dağıtmak için.","caution":"Taşıma sırasında ACCESS EXCLUSIVE lock alınır; index kullanılamaz. Tablodaki tüm index'leri tek seferde taşımak için ALTER TABLE ... SET TABLESPACE index'leri kapsamaz; her index'i ayrı taşı.","tags":["tablespace","index","move","storage"]},{"id":"db-table-size","task":"Veritabanı ve tablo boyutunu sorgula","category":"Depolama","command":"SELECT relname AS tablo, pg_size_pretty(pg_total_relation_size(relid)) AS toplam_boyut, pg_size_pretty(pg_relation_size(relid)) AS sadece_veri FROM pg_catalog.pg_statio_user_tables ORDER BY pg_total_relation_size(relid) DESC LIMIT 20;","what":"En büyük 20 tabloyu, index'ler ve TOAST dahil toplam boyutlarıyla listeler.","when":"Disk kullanımını analiz etmek, hangi tabloların yer kapladığını bulmak için.","caution":"Tüm veritabanı boyutu için: SELECT pg_size_pretty(pg_database_size(current_database()));","tags":["size","table","database","storage"]},{"id":"table-bloat","task":"Tablo bloat'ını tahmin et","category":"Depolama","command":"SELECT schemaname, relname AS tablo, n_dead_tup AS olu_satir, n_live_tup AS canli_satir, round(n_dead_tup::numeric / NULLIF(n_live_tup + n_dead_tup, 0) * 100, 1) AS olu_yuzde, last_autovacuum FROM pg_stat_user_tables WHERE n_dead_tup > 0 ORDER BY n_dead_tup DESC LIMIT 20;","what":"Dead tuple sayısına göre bloat oranını ve son autovacuum zamanını gösterir.","when":"VACUUM ihtiyacını, autovacuum'un yetişip yetişmediğini belirlemek için.","caution":"n_dead_tup, DML sayaçlarından sürekli güncellenen bir tahmindir (VACUUM sonrası düşer, ANALYZE yalnızca tahmini düzeltir); kesin fiziksel bloat için pgstattuple eklentisi (pgstattuple('musteri')) daha doğrudur.","tags":["bloat","dead-tuple","vacuum","storage"]},{"id":"vacuum-analyze-table","task":"Belirli tabloyu VACUUM ANALYZE et","category":"Bakım","command":"VACUUM (ANALYZE, VERBOSE) musteri;","what":"Tablodaki dead tuple'ları temizler, alanı yeniden kullanılabilir yapar ve planlayıcı istatistiklerini günceller.","when":"Toplu DELETE/UPDATE sonrası, sorgu planları bozulduğunda.","caution":"VACUUM diski OS'e geri vermez; alan geri kazanımı için VACUUM FULL gerekir ancak o ACCESS EXCLUSIVE lock alır. Normal VACUUM tabloyu bloklamaz.","tags":["vacuum","analyze","maintenance","cleanup"]},{"id":"vacuum-freeze","task":"Agresif VACUUM FREEZE çalıştır","category":"Bakım","command":"VACUUM (FREEZE, VERBOSE, ANALYZE) musteri;","what":"Tablodaki tüm uygun satırları hemen 'frozen' işaretler; transaction ID wraparound riskini azaltır.","when":"Wraparound uyarısı geldiğinde, arşivlenecek/salt-okunur olacak büyük tablolarda önleyici olarak.","caution":"Tüm tabloyu taradığı için yoğun I/O üretir. Acil wraparound durumunda veritabanı salt-okunur moda geçebilir; öncesinde datfrozenxid'i izle.","tags":["vacuum","freeze","wraparound","maintenance"]},{"id":"reindex-concurrently","task":"Index'i kilitlemeden yeniden oluştur (REINDEX CONCURRENTLY)","category":"Bakım","command":"REINDEX INDEX CONCURRENTLY musteri_email_idx;","what":"Index'i yazma işlemlerini bloklamadan yeniden inşa eder; index bloat'ını giderir.","when":"Index büyümüş/bozulmuş olduğunda, canlı sistemde bakım penceresi olmadan.","caution":"PostgreSQL 12+ gerektirir. Başarısız olursa _ccnew soneki ile geçersiz (INVALID) index bırakabilir; kontrol için pg_index.indisvalid bak ve gerekirse DROP INDEX ile temizle. Tüm tabloyu yenilemek için: REINDEX TABLE CONCURRENTLY musteri;","since":"PostgreSQL 12","note":"REINDEX ... CONCURRENTLY PostgreSQL 12 ile geldi; öncesinde REINDEX index'i ACCESS EXCLUSIVE lock ile kilitlerdi (kilitsiz yenileme için CREATE INDEX CONCURRENTLY + DROP gerekirdi).","tags":["reindex","concurrently","index","maintenance"]},{"id":"autovacuum-per-table","task":"Autovacuum'u belirli tablo için ayarla","category":"Bakım","command":"ALTER TABLE musteri SET (autovacuum_vacuum_scale_factor = 0.02, autovacuum_vacuum_threshold = 5000, autovacuum_analyze_scale_factor = 0.01);","what":"Sadece bu tablo için autovacuum tetikleme eşiklerini düşürür; büyük/hareketli tabloların daha sık vacuum edilmesini sağlar.","when":"Yoğun UPDATE/DELETE alan büyük tablolarda autovacuum geç kaldığında.","caution":"Çok agresif ayar sürekli autovacuum'a ve I/O yüküne yol açabilir. Ayarı geri almak için: ALTER TABLE musteri RESET (autovacuum_vacuum_scale_factor);","tags":["autovacuum","tuning","table","maintenance"]},{"id":"statistics-target","task":"Sütun istatistik hedefini artır","category":"Bakım","command":"ALTER TABLE musteri ALTER COLUMN sehir SET STATISTICS 500; ANALYZE musteri;","what":"Belirli bir sütun için toplanan histogram/örneklem detayını artırır; planlayıcının tahminlerini iyileştirir.","when":"Eğri dağılımlı (skewed) sütunlarda kötü sorgu planları alındığında.","caution":"Yüksek değer (default 100, maks 10000) ANALYZE süresini ve planlama süresini artırır. Değişiklik ancak ANALYZE sonrası etkin olur.","tags":["statistics","planner","analyze","tuning"]},{"id":"alter-system-reload","task":"Parametre değiştir ve reload et (ALTER SYSTEM)","category":"Parametre","command":"ALTER SYSTEM SET work_mem = '64MB'; SELECT pg_reload_conf();","what":"postgresql.auto.conf dosyasına parametreyi yazar ve yapılandırmayı yeniden yükler (restart gerektirmeyen parametreler için anında etkin).","when":"work_mem, log ayarları gibi reload ile uygulanabilen parametreleri kalıcı değiştirmek için.","caution":"shared_buffers, max_connections gibi bazı parametreler reload ile değil yalnızca restart ile etkin olur; pg_settings.context = 'postmaster' olanlar restart ister.","tags":["alter-system","reload","parameter","config"]},{"id":"session-set","task":"Parametreyi oturum bazında değiştir (SET)","category":"Parametre","command":"SET work_mem = '256MB';","what":"Parametreyi yalnızca mevcut bağlantı/oturum için değiştirir; oturum kapanınca sıfırlanır.","when":"Tek bir ağır sorgu veya toplu işlem için geçici olarak ayar yükseltmek gerektiğinde.","caution":"Tek transaction için sınırlamak istersen SET LOCAL kullan. Global etki için ALTER SYSTEM gerekir.","tags":["set","session","parameter","work-mem"]},{"id":"show-setting","task":"Mevcut parametre değerini gör","category":"Parametre","command":"SELECT name, setting, unit, context, source FROM pg_settings WHERE name = 'shared_buffers';","what":"Parametrenin etkin değerini, birimini ve nasıl uygulanabileceğini (context) ve kaynağını gösterir.","when":"Bir parametrenin çalışan değerini, restart mi reload mu gerektirdiğini öğrenmek için.","caution":"Kısa yol: SHOW shared_buffers; veya SELECT current_setting('shared_buffers'); context sütunu 'postmaster' ise restart gerekir.","tags":["show","pg_settings","parameter","current-setting"]},{"id":"physical-replica-basebackup","task":"Fiziksel replika kur (pg_basebackup)","category":"Replikasyon","command":"pg_basebackup -h primary_host -U replikator -D /var/lib/postgresql/16/main -Fp -Xs -P -R --slot=replica_slot_1 -C","what":"Primary'den tam fiziksel yedek alır, streaming ile WAL'ı çeker (-Xs), standby.signal ve primary_conninfo'yu yazar (-R) ve replikasyon slot'unu oluşturur (-C).","when":"Yeni bir streaming standby (okuma replikası veya failover hedefi) kurmak için.","caution":"Hedef dizin (-D) boş olmalı. Primary'de pg_hba.conf'ta replikator kullanıcısına 'replication' izni ve yeterli wal_keep_size / slot bulunmalı. -R PostgreSQL 12+ ile recovery.conf yerine standby.signal üretir.","tags":["replication","basebackup","standby","physical"]},{"id":"promote-replica","task":"Replikayı primary'ye yükselt (promote)","category":"Replikasyon","command":"SELECT pg_promote(wait := true, wait_seconds := 60);","what":"Standby sunucuyu kurtarma modundan çıkarıp yazılabilir primary'ye dönüştürür.","when":"Planlı veya acil failover'da standby'ı yeni primary yapmak için.","caution":"Promote geri alınamaz; sunucu artık eski primary'yi takip edemez. Split-brain'i önlemek için eski primary'nin gerçekten kapalı olduğundan emin ol. Alternatif: pg_ctl promote.","since":"PostgreSQL 12","note":"pg_promote() SQL fonksiyonu PostgreSQL 12 ile geldi; öncesinde standby'ı yükseltmek için trigger file (promote_trigger_file) ya da pg_ctl promote kullanılırdı.","tags":["replication","promote","failover","standby"]},{"id":"replication-lag","task":"Replikasyon gecikmesini gör","category":"Replikasyon","command":"SELECT client_addr, state, sent_lsn, replay_lsn, pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS replay_lag_bytes, write_lag, flush_lag, replay_lag FROM pg_stat_replication;","what":"Primary üzerinde her standby'ın primary'nin güncel WAL konumuna göre uygulama (replay) farkını bayt olarak ve write/flush/replay gecikmelerini gösterir.","when":"Streaming replikasyonun ne kadar geride olduğunu izlemek için (primary'de çalıştır).","caution":"Standby tarafında gecikme saniyesi için: SELECT now() - pg_last_xact_replay_timestamp(); bu değer primary'de yazma yokken de büyür, LSN farkıyla birlikte yorumlayın. Boş sonuç dönerse standby bağlı değildir.","tags":["replication","lag","lsn","monitor"]},{"id":"replication-slot","task":"Replication slot oluştur ve sil","category":"Replikasyon","command":"SELECT pg_create_physical_replication_slot('replica_slot_1'); -- Silmek için: SELECT pg_drop_replication_slot('replica_slot_1');","what":"Primary'nin, standby onaylayana kadar gerekli WAL'ı silmemesini garantileyen bir fiziksel slot oluşturur; ikinci komut slot'u kaldırır.","when":"Standby'ın kısa kesintilerde WAL kaybetmemesini sağlamak için.","caution":"Kullanılmayan/terk edilmiş slot WAL birikimine ve disk dolmasına yol açar. Slot durumunu izle: SELECT slot_name, active, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS retained FROM pg_replication_slots; Aktif slot silinemez.","tags":["replication","slot","wal","cleanup"]},{"id":"logical-replication","task":"Logical replication publication ve subscription kur","category":"Replikasyon","command":"-- Kaynak (publisher): CREATE PUBLICATION pub_musteri FOR TABLE musteri; -- Hedef (subscriber): CREATE SUBSCRIPTION sub_musteri CONNECTION 'host=primary_host dbname=uygulama user=replikator password=gizli' PUBLICATION pub_musteri;","what":"Kaynakta belirli tablolar için bir publication, hedefte ona bağlanan bir subscription oluşturarak tablo bazlı mantıksal replikasyon başlatır.","when":"Sürüm yükseltme, seçili tabloları farklı bir sunucuya çoğaltma, tek yönlü veri dağıtımı için.","caution":"PostgreSQL 10+ gerektirir. Hedef tabloların şeması önceden var olmalı; subscription otomatik olarak initial COPY yapar. wal_level = logical olmalı (restart gerektirir). DDL değişiklikleri ve sequence değerleri replike edilmez; şema değişikliklerini iki tarafta ayrıca uygulayın, geçişte sequence'ları setval ile eşitleyin.","since":"PostgreSQL 10","note":"Yerleşik logical replication (CREATE PUBLICATION / CREATE SUBSCRIPTION) PostgreSQL 10 ile geldi; öncesinde aynı iş için pglogical gibi harici eklentiler gerekiyordu.","tags":["logical","replication","publication","subscription"]},{"id":"terminate-backend","task":"Backend'i sonlandır (pg_terminate_backend)","category":"Oturum","command":"SELECT pg_terminate_backend(12345);","what":"Belirtilen PID'e sahip backend sürecini zorla sonlandırır; bağlantıyı ve çalışan transaction'ı keser.","when":"Takılı/askıda kalmış bağlantıyı, lock tutan oturumu kapatmak için.","caution":"Çalışan transaction rollback edilir; veri kaybı olabilir. Önce daha nazik olan pg_cancel_backend'i dene. PID'yi pg_stat_activity'den doğrula.","tags":["terminate","backend","session","kill"]},{"id":"cancel-backend","task":"Çalışan sorguyu iptal et (pg_cancel_backend)","category":"Oturum","command":"SELECT pg_cancel_backend(12345);","what":"Belirtilen PID üzerinde o an çalışan sorguyu iptal eder; bağlantı açık kalır.","when":"Uzun süren bir sorguyu bağlantıyı düşürmeden durdurmak için.","caution":"Yalnızca aktif sorguyu iptal eder; idle in transaction durumundaki oturumu kapatmaz, onun için pg_terminate_backend gerekir.","tags":["cancel","backend","query","session"]},{"id":"active-blocking-queries","task":"Aktif ve bloklayan sorguları gör","category":"Oturum","command":"SELECT pid, usename, state, wait_event_type, wait_event, pg_blocking_pids(pid) AS blocklayan_pidler, now() - query_start AS sure, left(query, 100) AS sorgu FROM pg_stat_activity WHERE state <> 'idle' AND pid <> pg_backend_pid() ORDER BY sure DESC;","what":"Boşta olmayan tüm backend'leri, hangi PID'ler tarafından bloklandıklarını ve ne kadar süredir çalıştıklarını listeler.","when":"Kilitlenme/blocking sorunlarını ve uzun süren sorguları teşhis etmek için.","caution":"pg_blocking_pids PostgreSQL 9.6+ ile gelir. blocklayan_pidler dizisi doluysa oradaki PID'ler lock'u tutuyordur; gerekirse o PID'yi iptal/sonlandır.","since":"PostgreSQL 9.6","note":"pg_blocking_pids() fonksiyonu PostgreSQL 9.6 ile geldi; öncesinde bloklayan süreçleri bulmak için pg_locks tablosunu elle join etmek gerekiyordu.","tags":["activity","blocking","lock","session"]},{"id":"create-extension","task":"Extension (eklenti) ekle","category":"Eklenti","command":"CREATE EXTENSION IF NOT EXISTS pg_stat_statements;","what":"Belirtilen eklentiyi mevcut veritabanına kurar (fonksiyon, view, tip vb. ekler).","when":"pg_stat_statements, pgcrypto, postgis gibi ek yetenekler gerektiğinde.","caution":"pg_stat_statements gibi shared_preload_libraries gerektiren eklentiler için önce postgresql.conf'a ekleyip sunucuyu restart etmelisin. Eklenti dosyaları (contrib paketi) sunucuda kurulu olmalı.","tags":["extension","create","pg_stat_statements","plugin"]},{"id":"list-extensions","task":"Mevcut eklentileri listele","category":"Eklenti","command":"SELECT extname AS eklenti, extversion AS surum FROM pg_extension ORDER BY extname;","what":"Mevcut veritabanında kurulu tüm eklentileri ve sürümlerini listeler.","when":"Hangi eklentilerin kurulu olduğunu, güncelleme gerekip gerekmediğini görmek için.","caution":"Kurulabilir (ama henüz kurulmamış) eklentileri görmek için: SELECT * FROM pg_available_extensions; Sürüm yükseltme: ALTER EXTENSION pg_stat_statements UPDATE;","tags":["extension","list","pg_extension","plugin"]}]},"recipes/postgres-ha.json":{"engineId":"postgres","engine":"PostgreSQL","order":1,"recipes":[{"id":"patroni-cluster-status","task":"Patroni kümesinin durumunu, topolojisini ve geçmişini gör","category":"Patroni","command":"# Üyeler, roller, durum, timeline ve lag (MB):\npatronictl -c /etc/patroni/patroni.yml list <cluster>\n# Genişletilmiş bilgi (pending restart, tags) + zaman damgası, 5 sn'de bir yenile:\npatronictl -c /etc/patroni/patroni.yml list <cluster> -e -t -w 5\n# Leader -> replica ağacı (cascading replikalar dahil):\npatronictl -c /etc/patroni/patroni.yml topology <cluster>\n# Geçmiş failover/switchover'lar (timeline, LSN, neden, zaman):\npatronictl -c /etc/patroni/patroni.yml history <cluster>","what":"Patroni'nin DCS'teki küme görünümünü gösterir: leader/replica rolleri, üye durumu (running/streaming), timeline, replikasyon lag'i ve bekleyen restart'lar; history ise timeline değişikliklerini hangi LSN'de olduğuyla listeler.","when":"Her switchover/failover/bakım öncesi ve sonrası, alarm geldiğinde ilk teşhis adımı olarak.","caution":"Bu çıktı DCS'teki kaydı yansıtır; DCS erişilemiyorsa komut hata verir veya bayat bilgi gösterebilir. Tüm üyelerin aynı timeline'da ve Lag in MB değerinin maximum_lag_on_failover altında olduğunu doğrulamadan switchover başlatma.","untested":true,"tags":["patroni","küme durumu","topoloji","geçmiş","lag"]},{"id":"patroni-switchover","task":"Patroni ile planlı switchover yap","category":"Patroni","command":"# Hemen, onay sormadan switchover:\npatronictl -c /etc/patroni/patroni.yml switchover <cluster> --leader <leader_member> --candidate <member> --force\n# Planlı switchover (ISO 8601 zaman damgası, saat dilimiyle):\npatronictl -c /etc/patroni/patroni.yml switchover <cluster> --leader <leader_member> --candidate <member> --scheduled '2026-10-10T02:00:00+03:00' --force\n# Bekleyen planlı switchover'ı iptal et:\npatronictl -c /etc/patroni/patroni.yml flush <cluster> switchover","what":"Sağlıklı leader'ı kontrollü biçimde demote edip seçilen replica'yı (--candidate) promote eder; eski leader otomatik olarak yeni leader'ın replica'sı olur. --scheduled ile işlem belirtilen zamana ertelenir.","when":"Bakım (OS yaması, donanım değişimi, minor sürüm yükseltme) öncesi primary'yi başka node'a taşımak veya failover sonrası rolleri eski düzene almak için.","caution":"Leader değişiminde tüm bağlantılar kopar; uygulama yeniden bağlanabilmeli. Candidate'ın lag'i maximum_lag_on_failover'ı aşıyorsa Patroni switchover'ı reddeder. synchronous_mode açıksa candidate senkron standby olmalıdır.","note":"Eski Patroni sürümlerinde --leader seçeneğinin adı --master'dı; Patroni 4'te --master kaldırıldı. --primary, --leader ile eşdeğerdir.","untested":true,"tags":["patroni","switchover","planlı geçiş","bakım","leader"]},{"id":"patroni-failover","task":"Patroni ile manuel failover yap","category":"Patroni","command":"# Leader sağlıksızken manuel failover (candidate zorunlu):\npatronictl -c /etc/patroni/patroni.yml failover <cluster> --candidate <member> --force\n# Sonucu ve yeni timeline'ı doğrula:\npatronictl -c /etc/patroni/patroni.yml list <cluster>\npatronictl -c /etc/patroni/patroni.yml history <cluster>","what":"Leader'ın durumuna bakmadan belirtilen replica'yı promote eder; otomatik failover'ın gerçekleşmediği veya yanlış node'u seçtiği durumlar içindir.","when":"Leader erişilemez/sağlıksız olduğunda ve otomatik failover devreye girmediğinde (ör. pause modunda) ya da belirli bir node'a zorla geçmek gerektiğinde.","caution":"Asenkron replikasyonda candidate'a ulaşmamış transaction'lar kaybolur (RPO > 0). Leader sağlıklıysa failover yerine switchover kullan. Eski leader geri geldiğinde Patroni use_pg_rewind açıksa pg_rewind, değilse reinit gerektirebilir.","note":"Patroni 3.2+ sürümlerinde failover için --candidate zorunludur; failover'daki --leader/--primary seçeneği 3.2'de deprecated oldu, Patroni 4.0'da kaldırıldı. Leader belirtmek gerekiyorsa switchover kullanılır.","untested":true,"tags":["patroni","failover","manuel failover","promote","rpo"]},{"id":"patroni-reinit-replica","task":"Bozulan replica'yı Patroni ile yeniden oluştur (reinit)","category":"Patroni","command":"# Replica'nın PGDATA'sını silip yeniden oluştur (create_replica_methods: pgbackrest/basebackup):\npatronictl -c /etc/patroni/patroni.yml reinit <cluster> <member> --wait --force\n# Yedek deposu yerine doğrudan leader'dan basebackup al:\npatronictl -c /etc/patroni/patroni.yml reinit <cluster> <member> --from-leader --wait --force","what":"Belirtilen replica'nın veri dizinini siler ve Patroni'nin create_replica_methods ayarına göre (pgBackRest restore veya pg_basebackup) sıfırdan yeniden kurar.","when":"Replica timeline uyuşmazlığı, pg_rewind başarısızlığı, eksik WAL veya veri bozulması nedeniyle replikasyona katılamadığında.","caution":"Üyenin tüm yerel verisi silinir; komutun doğru üyeyi hedeflediğini iki kez kontrol et (Patroni leader üzerinde reinit'i reddeder). Büyük veritabanlarında saatler sürebilir ve leader'a I/O/ağ yükü bindirir; bu sürede küme bir replica eksik çalışır. --from-leader yalnız güncel Patroni 4.x sürümlerinde vardır (patronictl reinit --help ile kontrol et); create_replica_methods'u atlayıp leader'dan pg_basebackup alır.","untested":true,"tags":["patroni","reinit","replica yeniden kur","rebuild","basebackup"]},{"id":"patroni-edit-config","task":"Patroni'de küme geneli parametre değiştir (edit-config) ve pending restart uygula","category":"Patroni","command":"# DCS'teki mevcut dinamik yapılandırmayı gör:\npatronictl -c /etc/patroni/patroni.yml show-config <cluster>\n# Küme geneli PostgreSQL parametresi (tüm üyelere dağıtılır):\npatronictl -c /etc/patroni/patroni.yml edit-config <cluster> -p 'work_mem=64MB' -p 'max_connections=500' --force\n# Patroni davranış parametresi:\npatronictl -c /etc/patroni/patroni.yml edit-config <cluster> -s 'maximum_lag_on_failover=1048576' --force\n# Restart isteyen parametreler 'Pending restart' olarak işaretlenir:\npatronictl -c /etc/patroni/patroni.yml list <cluster> -e\n# Önce replikaları, sonra leader'ı restart et:\npatronictl -c /etc/patroni/patroni.yml restart <cluster> --role replica --pending --force\npatronictl -c /etc/patroni/patroni.yml restart <cluster> --role leader --pending --force","what":"PostgreSQL ve Patroni parametrelerini DCS'teki dinamik yapılandırmaya yazar; Patroni değişikliği tüm üyelere uygular, reload yeterli olanları anında etkinleştirir, restart gerektirenleri 'Pending restart' olarak işaretler.","when":"Patroni yönetimindeki bir kümede max_connections, shared_buffers, work_mem gibi parametreleri tüm node'larda tutarlı biçimde değiştirmek için.","caution":"Patroni altında postgresql.conf'u elle düzenleme ve ALTER SYSTEM kullanma: Patroni postgresql.conf'u yeniden yazar, postgresql.auto.conf ise Patroni ayarlarını ezerek node'lar arasında tutarsızlık yaratır. max_connections, max_worker_processes, max_wal_senders, max_prepared_transactions, max_locks_per_transaction değerleri standby'da primary'den küçük olamaz; restart sırasını buna göre planla.","untested":true,"tags":["patroni","edit-config","parametre","pending restart","dcs"]},{"id":"patroni-pause-resume","task":"Patroni bakım moduna al ve çıkar (pause/resume)","category":"Patroni","command":"# Bakım modu: otomatik failover ve Patroni'nin PostgreSQL'e müdahalesi durur\npatronictl -c /etc/patroni/patroni.yml pause <cluster> --wait\npatronictl -c /etc/patroni/patroni.yml list <cluster>          # 'Maintenance mode: on' görünmeli\n# ... bakım işlemleri (ör. PostgreSQL'i elle restart, DCS bakımı) ...\npatronictl -c /etc/patroni/patroni.yml resume <cluster> --wait","what":"Kümeyi bakım moduna alır: Patroni otomatik failover yapmaz, durdurulan PostgreSQL'i yeniden başlatmaz; resume ile normal yönetime döner.","when":"DCS (etcd/Consul) bakımı, Patroni sürüm yükseltmesi veya PostgreSQL'i Patroni'nin müdahalesi olmadan elle yönetmek gerektiğinde.","caution":"Pause süresince primary çökerse otomatik failover olmaz, kesinti sürer. Bakım bitince resume'u unutma; alarm sistemine 'Maintenance mode' kontrolü ekle. Pause modunda bir PostgreSQL'i elle primary olarak başlatmak split-brain'e yol açabilir.","untested":true,"tags":["patroni","pause","resume","bakım modu","maintenance"]},{"id":"patroni-dcs-health","task":"Patroni DCS (etcd/Consul) ve REST API sağlığını kontrol et","category":"Patroni","command":"# etcd v3 (etcd 3.4+ varsayılan API): üye sağlığı, leader, raft term ve DB boyutu\netcdctl --endpoints=https://<etcd1>:2379,https://<etcd2>:2379,https://<etcd3>:2379 --cacert=/etc/etcd/ca.crt endpoint health --cluster -w table\netcdctl --endpoints=https://<etcd1>:2379 --cacert=/etc/etcd/ca.crt endpoint status --cluster -w table\netcdctl --endpoints=https://<etcd1>:2379 --cacert=/etc/etcd/ca.crt alarm list\n# Consul:\nconsul members\nconsul operator raft list-peers\n# Patroni REST API (her üyede):\ncurl -s http://<member>:8008/cluster | python3 -m json.tool\ncurl -s -o /dev/null -w '%{http_code}\\n' http://<member>:8008/primary   # 200 = leader, 503 = değil","what":"Patroni'nin leader lock'unu tuttuğu DCS'in quorum, leader ve kapasite durumunu; Patroni REST API üzerinden de üyelerin kendi rol görüşünü kontrol eder. /primary uç noktası load balancer (HAProxy) health check'lerinin temelidir.","when":"Patroni 'DCS is not accessible' logladığında, beklenmeyen demote/failover sonrasında ve düzenli sağlık kontrolünde.","caution":"DCS quorum'u kaybedilirse Patroni leader lock'unu yenileyemez ve primary'yi read-only'e demote eder (Patroni 3.0+ failsafe_mode açık değilse); yani etcd kesintisi doğrudan veritabanı yazma kesintisidir. etcd DB boyutu kotaya (varsayılan 2 GB) ulaşırsa NOSPACE alarmı ile yazmalar durur. DCS'i en az 3 node ve ayrı disklerde çalıştır.","untested":true,"tags":["patroni","etcd","consul","dcs sağlığı","rest api"]},{"id":"pgbackrest-archive-config","task":"pgBackRest için WAL arşivlemeyi yapılandır (archive-push/archive-get)","category":"Yedekleme & PITR","command":"# postgresql.conf (archive_mode değişikliği restart ister):\nwal_level = replica\narchive_mode = on\narchive_command = 'pgbackrest --stanza=<stanza> archive-push %p'\n# Restore/standby tarafında (PG12+ postgresql.conf içinde):\nrestore_command = 'pgbackrest --stanza=<stanza> archive-get %f \"%p\"'\n\n# /etc/pgbackrest/pgbackrest.conf (DB sunucusu, yerel repo örneği):\n[global]\nrepo1-path=/var/lib/pgbackrest\nrepo1-retention-full=2\narchive-async=y\nspool-path=/var/spool/pgbackrest\nprocess-max=4\ncompress-type=zst\nstart-fast=y\n\n[<stanza>]\npg1-path=/var/lib/pgsql/16/data","what":"PostgreSQL'in her tamamlanan WAL segmentini pgBackRest deposuna göndermesini (archive-push) ve recovery sırasında oradan çekmesini (archive-get) sağlar; archive-async ile gönderim paralel ve spool üzerinden asenkron yapılır.","when":"pgBackRest ile fiziksel yedek ve PITR kurulumunun ilk adımı olarak, stanza-create'ten önce.","caution":"archive_command başarısız olduğu sürece WAL pg_wal'da birikir ve disk dolarsa primary durur; pg_stat_archiver.failed_count'u izle. Patroni kullanıyorsan bu parametreleri postgresql.conf yerine patroni.yml / edit-config ile ver. Aynı stanza'ya iki farklı kümeden arşiv göndermek depoyu bozar.","untested":true,"tags":["pgbackrest","arşivleme","archive_command","wal arşivi","yapılandırma"]},{"id":"pgbackrest-stanza-create-check","task":"pgBackRest stanza oluştur ve arşivlemeyi doğrula (stanza-create/check)","category":"Yedekleme & PITR","command":"# Depoda stanza'yı oluştur (bir kez):\nsudo -u postgres pgbackrest --stanza=<stanza> --log-level-console=info stanza-create\n# Yapılandırmayı ve arşivlemeyi uçtan uca doğrula (WAL switch yapıp segmentin depoya ulaşmasını bekler):\nsudo -u postgres pgbackrest --stanza=<stanza> --log-level-console=info check","what":"stanza-create depoda kümeye ait meta veriyi (sistem kimliği, sürüm) oluşturur; check ise PostgreSQL bağlantısını, archive_command'ı ve depoya WAL ulaşıp ulaşmadığını gerçek bir WAL switch ile test eder.","when":"İlk kurulumda, archive_command veya depo değişikliğinden sonra ve izleme/cron sağlık kontrolü olarak.","caution":"Komutları postgres (veya repo sahibi) kullanıcısıyla çalıştır; root ile çalıştırmak dosya sahipliklerini bozar. Major sürüm yükseltmesinden sonra stanza-create değil stanza-upgrade gerekir. check başarısızsa yedek alınsa bile PITR mümkün olmayabilir.","untested":true,"tags":["pgbackrest","stanza","stanza-create","check","arşiv doğrulama"]},{"id":"pgbackrest-backup-full-diff-incr","task":"pgBackRest ile full, differential ve incremental yedek al","category":"Yedekleme & PITR","command":"sudo -u postgres pgbackrest --stanza=<stanza> --type=full backup\nsudo -u postgres pgbackrest --stanza=<stanza> --type=diff backup   # son full'dan beri değişenler\nsudo -u postgres pgbackrest --stanza=<stanza> --type=incr backup   # son herhangi bir yedekten beri değişenler\n# cron örneği (postgres kullanıcısı): Pazar full, diğer günler diff\n# 30 1 * * 0   pgbackrest --stanza=<stanza> --type=full backup\n# 30 1 * * 1-6 pgbackrest --stanza=<stanza> --type=diff backup","what":"Full yedek tüm kümeyi, diff son full'dan, incr son herhangi bir yedekten bu yana değişen dosyaları kopyalar; yedek sonunda gerekli WAL'ın arşivlendiği doğrulanır ve retention'a göre expire otomatik çalışır.","when":"Düzenli yedekleme planında: genellikle haftalık full + günlük diff/incr, büyük kümelerde daha sık incr.","caution":"Önce full yoksa diff/incr istekleri otomatik olarak full'a dönüşür. Incr zinciri uzadıkça restore süresi ve bağımlılık artar; zincirdeki tek bir yedeğin kaybı sonrakileri kullanılamaz kılar. Yükü primary'den almak için backup-standby=y ile yedeği standby'dan al (primary yine bağlantı için gereklidir).","untested":true,"tags":["pgbackrest","yedek","full","differential","incremental"]},{"id":"pgbackrest-info","task":"pgBackRest yedek kataloğunu ve WAL arşiv aralığını gör (info)","category":"Yedekleme & PITR","command":"sudo -u postgres pgbackrest --stanza=<stanza> info\n# İzleme/otomasyon için JSON:\nsudo -u postgres pgbackrest --stanza=<stanza> --output=json info\n# Tek bir yedeğin ayrıntısı (veritabanları, LSN aralığı):\nsudo -u postgres pgbackrest --stanza=<stanza> --set=<backup_label> info","what":"Stanza durumunu, her yedeğin etiketini, tipini, başlangıç/bitiş zamanını, boyutunu, bağımlı olduğu yedeği ve depodaki WAL arşivinin min/max aralığını listeler.","when":"Restore/PITR öncesi hedef zamanın kapsandığını doğrulamak, yedeklerin düzenli alındığını izlemek ve retention'ı kontrol etmek için.","caution":"info yedeğin varlığını gösterir, geri yüklenebilirliğini kanıtlamaz; düzenli test restore'u ve pgbackrest verify ile doğrula. WAL min/max aralığında boşluk varsa PITR o aralığı geçemez.","untested":true,"tags":["pgbackrest","info","yedek listesi","katalog","izleme"]},{"id":"pgbackrest-restore-latest","task":"pgBackRest ile son yedekten tam restore yap","category":"Yedekleme & PITR","command":"# PostgreSQL kapalı ve PGDATA boş olmalı (aksi halde --delta kullan)\nsudo systemctl stop postgresql-16\nsudo -u postgres pgbackrest --stanza=<stanza> --log-level-console=info restore\n# Belirli bir yedekten: --set=<backup_label>\n# Test amaçlı başka bir sunucuya restore'da arşivi kapat:\n# sudo -u postgres pgbackrest --stanza=<stanza> --archive-mode=off restore\nsudo systemctl start postgresql-16","what":"En son yedeği geri yükler, recovery.signal ve restore_command'ı yazar; PostgreSQL açılırken arşivdeki tüm WAL'ı uygulayıp en güncel tutarlı noktaya getirir ve yeni bir timeline ile promote olur.","when":"Primary'nin veri dizini kaybolduğunda/bozulduğunda veya yedeklerin geri yüklenebilirliğini düzenli test ederken.","caution":"Restore edilen küme ile eski küme aynı anda aynı stanza'ya arşiv gönderirse depo bozulur; test restore'larında --archive-mode=off kullan. Patroni altındaysa önce kümeyi pause'a al veya Patroni'yi durdur, aksi halde Patroni araya girer. Tablespace'ler ve postgresql.conf dışı yollar varsa --tablespace-map ve link seçeneklerini gözden geçir.","untested":true,"tags":["pgbackrest","restore","geri yükleme","kurtarma","felaket kurtarma"]},{"id":"pgbackrest-pitr-restore","task":"pgBackRest ile belirli bir zamana geri dön (PITR, --type=time)","category":"Yedekleme & PITR","command":"sudo systemctl stop postgresql-16\nsudo -u postgres pgbackrest --stanza=<stanza> --delta --type=time \"--target=2026-10-08 14:30:00+03\" --target-action=pause restore\nsudo systemctl start postgresql-16\n# Recovery hedefte durur (salt okunur); veriyi doğrula:\npsql -X -c \"SELECT pg_is_in_recovery(), pg_last_xact_replay_timestamp();\"\n# Doğruysa recovery'yi bitir ve yeni timeline ile yazılabilir aç:\npsql -X -c \"SELECT pg_wal_replay_resume();\"","what":"Hedef zamandan önce biten bir yedeği geri yükler ve WAL'ı yalnızca hedef zamana kadar uygular; target-action=pause ile hedefte durup veriyi doğrulamana izin verir, pg_wal_replay_resume() ile promote olur.","when":"Yanlışlıkla yapılan DELETE/DROP/UPDATE gibi mantıksal hatalardan hemen önceki ana dönmek için.","caution":"Hedeften sonraki tüm değişiklikler bu kümede kaybolur; mümkünse PITR'ı ayrı bir sunucuya yapıp yalnızca etkilenen veriyi pg_dump ile geri taşı. Saat dilimini hedefte açıkça belirt. pgBackRest 2.24+ hedef zamandan önceki uygun yedeği kendisi seçer; daha eski sürümlerde --set ile hedeften önce biten yedeği belirt. Hedef yedeğin bitiş zamanından önceyse restore tutarlılığa ulaşamaz.","untested":true,"tags":["pgbackrest","pitr","zamana dönüş","point in time","kurtarma"]},{"id":"pgbackrest-delta-restore-standby","task":"pgBackRest delta restore ile standby'ı hızlıca yeniden kur","category":"Yedekleme & PITR","command":"sudo systemctl stop postgresql-16\n# Mevcut PGDATA'yı koruyup yalnızca farklı dosyaları getirir; standby.signal yazar:\nsudo -u postgres pgbackrest --stanza=<stanza> --delta --type=standby \"--recovery-option=primary_conninfo=host=<primary_host> port=5432 user=replicator application_name=<standby_name>\" restore\nsudo systemctl start postgresql-16\npsql -X -c \"SELECT status, sender_host FROM pg_stat_wal_receiver;\"","what":"--delta mevcut PGDATA'daki dosyaları yedekle karşılaştırıp (boyut/zaman damgası ve checksum) yalnızca farklı olanları kopyalar; --type=standby standby.signal yazar, recovery-option ile primary_conninfo eklenir. Standby önce arşivden yetişir, sonra streaming'e geçer.","when":"Geride kalmış, timeline'ı ayrışmış veya pg_rewind'in başarısız olduğu bir standby'ı/eski primary'yi tam kopya almadan yeniden replica yapmak için.","caution":"Delta, hedef dizindeki farklı veya fazla dosyaları yedektekiyle değiştirir/siler; yanlış sunucuda çalıştırmak o sunucunun verisini yok eder. pgBackRest çalışan bir PostgreSQL'e restore etmez, ancak servisin gerçekten durduğunu kendin de doğrula. Parola primary_conninfo yerine .pgpass'te tutulmalı.","untested":true,"tags":["pgbackrest","delta restore","standby yeniden kur","rebuild","replica"]},{"id":"pgbackrest-retention-expire","task":"pgBackRest retention politikasını ayarla ve expire çalıştır","category":"Yedekleme & PITR","command":"# /etc/pgbackrest/pgbackrest.conf [global] — sayı bazlı:\nrepo1-retention-full-type=count\nrepo1-retention-full=2\nrepo1-retention-diff=6\n# Zaman bazlı alternatif (en az 14 günlük PITR penceresi):\n# repo1-retention-full-type=time\n# repo1-retention-full=14\n\n# Expire her backup sonrası otomatik çalışır; elle tetiklemek için:\nsudo -u postgres pgbackrest --stanza=<stanza> --log-level-console=info expire","what":"Kaç full/diff yedeğin (count) veya kaç günlük full yedeğin (time) saklanacağını belirler; expire bu politikanın dışında kalan yedekleri, onlara bağlı diff/incr'leri ve artık gerekmeyen WAL arşivini siler.","when":"Depo boyutunu kontrol altında tutmak ve RPO/PITR penceresi gereksinimini (ör. 14 gün geri dönebilme) garanti etmek için.","caution":"PITR penceresi en eski saklanan full yedekle sınırlıdır; retention-full=2 ile haftalık full alıyorsan geri dönüş en fazla ~2 hafta olur. repo1-retention-archive varsayılan olarak full retention'ı izler; düşük ayarlamak eski yedekleri yalnızca tutarlılık noktasına kadar kullanılabilir bırakır. Expire geri alınamaz.","untested":true,"tags":["pgbackrest","retention","saklama süresi","expire","yedek temizliği"]},{"id":"standby-manual-config","task":"Standby'ı elle yapılandır (standby.signal + primary_conninfo)","category":"Replikasyon","command":"# Standby'da, PostgreSQL kapalıyken (PGDATA bir yedekten/kopyadan geldi):\ntouch $PGDATA/standby.signal\ncat >> $PGDATA/postgresql.auto.conf <<'EOF'\nprimary_conninfo = 'host=<primary_host> port=5432 user=replicator application_name=<standby_name>'\nprimary_slot_name = '<slot>'\nEOF\npg_ctl -D $PGDATA start\n# PG13+: çalışan standby'da bağlantıyı restart'sız değiştir (ör. yeni primary'ye yönlendir):\npsql -X -c \"ALTER SYSTEM SET primary_conninfo = 'host=<new_primary_host> port=5432 user=replicator application_name=<standby_name>'\" -c \"SELECT pg_reload_conf();\"","what":"standby.signal dosyası sunucunun standby olarak açılmasını sağlar; primary_conninfo streaming bağlantısını, primary_slot_name kullanılacak replication slot'u tanımlar. PG13+ ile primary_conninfo ve primary_slot_name reload ile değiştirilebilir.","when":"pg_basebackup -R kullanılmadan (pgBackRest, snapshot, rsync ile) hazırlanan bir veri dizinini standby yapmak veya mevcut standby'ı yeni primary'ye yönlendirmek için.","caution":"Slot primary'de önceden oluşturulmalı (pg_create_physical_replication_slot), yoksa walreceiver sürekli hata verir. Parolayı conninfo yerine ~/.pgpass'e koy. application_name, synchronous_standby_names'teki adla birebir eşleşmeli. standby.signal unutulursa sunucu primary olarak açılır ve ayrı bir timeline'a geçer.","since":"PostgreSQL 12","note":"PostgreSQL 12 öncesinde bu ayarlar recovery.conf içinde (standby_mode = on) tutulurdu; PG12'de standby.signal ve postgresql.conf'a taşındı. PG13'ten önce primary_conninfo değişikliği restart gerektirirdi.","tags":["standby","standby.signal","primary_conninfo","replika kurulumu","streaming"]},{"id":"standby-wal-receiver-lag","task":"Standby tarafında WAL alım ve replay gecikmesini izle (pg_stat_wal_receiver)","category":"Replikasyon","command":"-- Standby'da çalıştır:\nSELECT pg_is_in_recovery() AS in_recovery,\n       pg_last_wal_receive_lsn() AS receive_lsn,\n       pg_last_wal_replay_lsn() AS replay_lsn,\n       pg_size_pretty(pg_wal_lsn_diff(pg_last_wal_receive_lsn(), pg_last_wal_replay_lsn())) AS replay_backlog,\n       now() - pg_last_xact_replay_timestamp() AS last_replay_age,\n       pg_get_wal_replay_pause_state() AS pause_state;\nSELECT pid, status, sender_host, sender_port, slot_name, received_tli, flushed_lsn, latest_end_lsn, now() - last_msg_receipt_time AS since_last_msg FROM pg_stat_wal_receiver;","what":"Standby'ın ne kadar WAL aldığını ve ne kadarını uyguladığını (replay backlog), son uygulanan transaction'ın yaşını, replay'in duraklatılıp duraklatılmadığını ve walreceiver bağlantısının durumunu (hangi primary, slot, timeline, son mesaj zamanı) gösterir.","when":"Primary'ye erişim yokken veya cascading standby'larda gecikmeyi teşhis etmek; 'standby geride' alarmında sorunun ağda (alım) mı yoksa replay'de (I/O, conflict) mi olduğunu ayırmak için.","caution":"pg_stat_wal_receiver boş dönüyorsa standby streaming yapmıyordur (arşivden besleniyor veya bağlantı kopuk). last_replay_age primary'de yazma yokken de büyür; receive_lsn/replay_lsn farkıyla birlikte yorumla. Replay büyürken receive ilerliyorsa standby'da uzun sorgular (max_standby_streaming_delay) veya I/O darboğazı vardır.","since":"PostgreSQL 14","note":"pg_get_wal_replay_pause_state() PostgreSQL 14 ile geldi; öncesinde yalnızca pg_is_wal_replay_paused() vardı. Sorgunun geri kalanı PG10+ ile çalışır.","tags":["standby","replikasyon gecikmesi","wal receiver","replay","lag"]},{"id":"pg-rewind-old-primary","task":"Failover sonrası eski primary'yi pg_rewind ile replica olarak geri kat","category":"Replikasyon","command":"# Önkoşul (olaydan ÖNCE ayarlı olmalı): wal_log_hints = on VEYA data checksums; full_page_writes = on\npg_controldata $PGDATA | grep -E 'wal_log_hints|checksum'\n# 1) Eski primary kapalı olmalı:\npg_ctl -D $PGDATA stop -m fast\n# 2) Önce dry-run:\npg_rewind --target-pgdata=$PGDATA --source-server='host=<new_primary_host> port=5432 user=postgres dbname=postgres' --progress --dry-run\n# 3) Gerçek rewind + standby yapılandırması (standby.signal + primary_conninfo):\npg_rewind --target-pgdata=$PGDATA --source-server='host=<new_primary_host> port=5432 user=postgres dbname=postgres' --progress --write-recovery-conf\n# 4) Kaynaktan kopyalanan postgresql.auto.conf'u (port, primary_slot_name) gözden geçir, sonra başlat:\npg_ctl -D $PGDATA start","what":"Eski primary'nin, timeline ayrıştığı noktadan sonra değişen bloklarını yeni primary'den kopyalayarak veri dizinini yeni primary ile uyumlu hale getirir; tam basebackup almadan dakikalar içinde replica'ya dönüştürür.","when":"Failover/promote sonrası eski primary geri geldiğinde ve yeni timeline'ın gerisinde kalan, ayrışmış değişiklikler içerdiğinde.","caution":"Eski primary'de failover sonrası kalan, yeni primary'ye ulaşmamış transaction'lar kalıcı olarak silinir. pg_rewind config dosyalarını (postgresql.conf, postgresql.auto.conf, pg_hba.conf) da kaynaktan kopyalar; başlatmadan önce port ve slot ayarlarını düzelt. Ayrışma noktasından itibaren gereken WAL kaynakta yoksa -c (--restore-target-wal) ile arşivden çekilmeli. Kaynak bağlantı için superuser veya dokümandaki fonksiyon yetkilerine sahip bir rol gerekir. Patroni'de bu iş use_pg_rewind: true ile otomatik yapılır.","since":"PostgreSQL 13","note":"-R/--write-recovery-conf ve -c/--restore-target-wal PostgreSQL 13 ile geldi; PG13+ pg_rewind, temiz kapanmamış hedefte önce kendisi crash recovery çalıştırır (--no-ensure-shutdown ile kapatılır). pg_rewind 9.5'ten beri mevcuttur.","tags":["pg_rewind","failover sonrası","eski primary","timeline","rejoin"]},{"id":"sync-standby-quorum","task":"Senkron replikasyonu quorum (ANY) veya öncelik (FIRST) ile ayarla","category":"Replikasyon","command":"-- Quorum: listedeki herhangi 1 standby onaylayınca commit tamamlanır\nALTER SYSTEM SET synchronous_standby_names = 'ANY 1 (stby_a, stby_b)';\n-- Öncelik bazlı: listede ilk sıradaki bağlı standby senkron, diğerleri 'potential'\n-- ALTER SYSTEM SET synchronous_standby_names = 'FIRST 1 (stby_a, stby_b)';\nSELECT pg_reload_conf();\nSELECT application_name, state, sync_state, sync_priority FROM pg_stat_replication ORDER BY application_name;","what":"Commit'in hangi standby'lardan onay beklendikten sonra tamamlanacağını belirler: ANY N quorum tabanlıdır (sync_state = quorum), FIRST N listedeki önceliğe göre ilk N bağlı standby'ı senkron (sync), kalanları yedek (potential) yapar. Onay seviyesi synchronous_commit ile belirlenir (remote_write, on, remote_apply).","when":"Failover'da veri kaybı olmaması (RPO = 0) gereken sistemlerde; birden çok standby varken tek bir standby arızasının yazmaları durdurmaması için ANY tercih edilir.","caution":"Gerekli sayıda senkron standby bağlı değilse commit'ler hata vermeden askıda kalır, uygulama donar. Listedeki adlar standby'ların application_name değeriyle eşleşmelidir. Acil durumda tek bir oturum için SET synchronous_commit = local ile atlanabilir. Patroni altında bu parametreyi elle değil synchronous_mode ile yönet.","since":"PostgreSQL 10","note":"FIRST sözdizimi PostgreSQL 9.6, ANY (quorum commit) PostgreSQL 10 ile geldi; anahtar kelimesiz 'N (a, b)' biçimi FIRST anlamına gelir.","tags":["senkron replikasyon","synchronous_standby_names","quorum","rpo","sync"]},{"id":"slot-retained-wal-monitor","task":"Replication slot'ların tuttuğu WAL'ı izle ve terk edilmiş slot'u güvenle sil","category":"Replikasyon","command":"SELECT slot_name, slot_type, database, active, active_pid, wal_status,\n       pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS retained_wal,\n       pg_size_pretty(safe_wal_size) AS safe_wal_size,\n       xmin, catalog_xmin\nFROM pg_replication_slots\nORDER BY pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn) DESC NULLS LAST;\n-- Güvenli silme: yalnızca aktif değilse siler (aktifse 0 satır döner)\nSELECT pg_drop_replication_slot(slot_name) FROM pg_replication_slots WHERE slot_name = '<slot>' AND NOT active;","what":"Her slot'un primary'de ne kadar WAL tutturduğunu, wal_status (reserved/extended/unreserved/lost) ve max_slot_wal_keep_size'a göre kalan güvenli payı (safe_wal_size), ayrıca VACUUM'u engelleyen xmin/catalog_xmin değerlerini gösterir; ikinci sorgu slot'u yalnızca kullanılmıyorsa siler.","when":"pg_wal dizini büyüdüğünde, disk alarmında ve düzenli izlemede; standby veya subscriber kalıcı olarak kaldırıldıktan sonra slot temizliğinde.","caution":"Aktif olmayan bir slot WAL'ı sınırsız biriktirir ve diski doldurarak primary'yi durdurabilir; xmin/catalog_xmin tutan slot ayrıca dead tuple temizliğini engeller ve bloat/wraparound riski yaratır. Slot'u silmek, ona bağlı standby/subscriber'ın kaldığı yerden devam etmesini imkansız kılar (yeniden kurulum gerekir); silmeden önce sahibini doğrula. Primary'de çalıştır (standby'da pg_current_wal_lsn() hata verir).","since":"PostgreSQL 13","note":"wal_status ve safe_wal_size PostgreSQL 13 ile geldi. PG16'da logical slot'lar için conflicting, PG17'de inactive_since sütunu eklendi; terk edilmiş slot'u bulmada inactive_since en doğrudan göstergedir.","tags":["replication slot","wal birikimi","disk doluluğu","slot silme","retained wal"]},{"id":"slot-max-wal-keep-size","task":"Slot'ların tutabileceği WAL miktarını sınırla (max_slot_wal_keep_size)","category":"Replikasyon","command":"ALTER SYSTEM SET max_slot_wal_keep_size = '100GB';\nSELECT pg_reload_conf();\nSELECT slot_name, active, wal_status, pg_size_pretty(safe_wal_size) AS safe_wal_size FROM pg_replication_slots;","what":"Replication slot'ların pg_wal'da tutabileceği WAL için üst sınır koyar (varsayılan -1 = sınırsız); sınır aşılınca checkpoint eski WAL'ı siler ve slot wal_status = 'lost' olur. Parametre reload ile etkinleşir.","when":"Kopan bir standby veya subscriber'ın primary diskini doldurup tüm sistemi durdurma riskine karşı, her slot kullanan kümede koruma olarak.","caution":"Sınır, primary'nin ayakta kalmasını slot sahibinin aleyhine seçer: 'lost' olan slot'un standby'ı yeniden kurulmalı, logical subscription baştan oluşturulmalıdır. Değeri pg_wal diskinin boş alanının altında ama beklenen en uzun kesintide üretilen WAL'dan büyük seç. wal_status 'unreserved' ise slot kaybolmak üzeredir, alarm üret.","since":"PostgreSQL 13","note":"max_slot_wal_keep_size PostgreSQL 13 ile geldi; öncesinde slot'ların tuttuğu WAL'ı sınırlamanın yolu yoktu ve tek koruma izleme + elle slot silmeydi.","tags":["max_slot_wal_keep_size","slot sınırı","wal birikimi","disk koruması","replication slot"]},{"id":"logical-add-table-refresh","task":"Publication'a tablo ekle ve subscription'ı yenile (REFRESH PUBLICATION)","category":"Logical Replication","command":"-- Publisher:\nALTER PUBLICATION pub_app ADD TABLE siparis;\n-- PG15+: şemadaki tüm tablolar: ALTER PUBLICATION pub_app ADD TABLES IN SCHEMA sema;\nSELECT pubname, schemaname, tablename FROM pg_publication_tables WHERE pubname = 'pub_app';\n-- Subscriber (tablo yapısı önceden oluşturulmuş olmalı):\nALTER SUBSCRIPTION sub_app REFRESH PUBLICATION WITH (copy_data = true);\nSELECT srrelid::regclass AS table_name, srsubstate FROM pg_subscription_rel ORDER BY 1;","what":"Publisher'da yayına yeni tablo ekler; subscriber'da REFRESH PUBLICATION yeni tabloları subscription'a dahil eder ve copy_data = true ile ilk kopyayı (tablesync) başlatır. srsubstate: i = init, d = veri kopyalanıyor, f = kopya bitti, s = senkronize, r = ready.","when":"Çalışan bir logical replication'a yeni tablo eklendiğinde veya publication'dan tablo çıkarıldığında.","caution":"FOR ALL TABLES veya TABLES IN SCHEMA yayınlarında bile subscriber yeni tabloyu REFRESH yapılmadan almaz. Subscriber'da tablo yoksa REFRESH hata verir; DDL replike edilmez. UPDATE/DELETE yayınlanan tabloda PRIMARY KEY veya REPLICA IDENTITY yoksa publisher'da bu işlemler hata verir. Büyük tablonun ilk kopyası publisher'da uzun süre slot ve snapshot tutar.","since":"PostgreSQL 10","note":"ADD TABLES IN SCHEMA PostgreSQL 15 ile geldi (PG15 ayrıca satır filtresi WHERE ve sütun listesi ekledi).","tags":["logical replication","publication","tablo ekle","refresh publication","subscription"]},{"id":"logical-subscription-monitor","task":"Logical replication'ı izle (pg_stat_subscription, apply hataları, slot lag'i)","category":"Logical Replication","command":"-- Subscriber:\nSELECT subname, pid, leader_pid, relid::regclass AS syncing_table, received_lsn, latest_end_lsn, now() - last_msg_receipt_time AS since_last_msg, latest_end_time FROM pg_stat_subscription;\nSELECT subname, apply_error_count, sync_error_count, stats_reset FROM pg_stat_subscription_stats;\n-- Publisher:\nSELECT slot_name, plugin, database, active, wal_status,\n       pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), confirmed_flush_lsn)) AS confirmed_lag,\n       pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS retained_wal\nFROM pg_replication_slots WHERE slot_type = 'logical';","what":"Subscriber'da apply/tablesync worker'larını, alınan ve onaylanan LSN'i, son mesaj zamanını ve kümülatif apply/sync hata sayılarını; publisher'da logical slot'un onaylanmamış (confirmed_flush) WAL miktarını ve tuttuğu toplam WAL'ı gösterir.","when":"Logical replication kurulumunda, sürüm yükseltme/migrasyon geçişinde lag'in sıfıra yaklaştığını doğrulamak ve hata alarmı için.","caution":"pid NULL ise apply worker çalışmıyordur (subscription disable edilmiş veya sürekli hata alıp yeniden başlıyor); sunucu logunu kontrol et. apply_error_count artıyorsa çakışma vardır. Duran bir subscription publisher'da WAL ve catalog_xmin biriktirir; publisher diskini ve catalog bloat'ını izle.","since":"PostgreSQL 15","note":"pg_stat_subscription_stats PostgreSQL 15, pg_stat_subscription.leader_pid PG16 (paralel apply) ile geldi; PG17 worker_type sütununu ekledi. pg_stat_subscription'ın temel sütunları PG10'dan beri mevcuttur.","tags":["logical replication","subscription izleme","pg_stat_subscription","apply hatası","lag"]},{"id":"logical-conflict-skip","task":"Logical replication çakışmasını çöz (disable_on_error, SKIP)","category":"Logical Replication","command":"-- 1) Hata alan apply worker'ın sonsuz döngüye girmesini engelle:\nALTER SUBSCRIPTION sub_app SET (disable_on_error = true);\n-- 2) Subscriber logundan çakışan transaction'ın bitiş LSN'ini bul:\n--    CONTEXT: ... in transaction 749, finished at 0/5035378\n-- 3a) Tercih edilen: subscriber'daki çakışan satırı düzelt/sil, sonra yeniden etkinleştir:\nALTER SUBSCRIPTION sub_app ENABLE;\n-- 3b) Ya da tüm uzak transaction'ı atla (içindeki TÜM değişiklikler subscriber'a uygulanmaz):\nALTER SUBSCRIPTION sub_app SKIP (lsn = '0/5035378');\nALTER SUBSCRIPTION sub_app ENABLE;\nSELECT subname, subenabled, subskiplsn FROM pg_subscription;","what":"Subscriber'da duplicate key, eksik satır, yetki gibi bir hata apply'ı durdurduğunda: disable_on_error subscription'ı otomatik devre dışı bırakır; çakışan veri düzeltilip ENABLE edilir ya da SKIP ile logdaki 'finished at' LSN'ine ait uzak transaction tamamen atlanır.","when":"Subscriber'a doğrudan yazılması, eksik ilk kopya veya iki yönlü yazma nedeniyle apply worker hata verip sürekli yeniden başladığında.","caution":"SKIP o transaction'daki çakışmayan değişiklikleri de atlar ve iki taraf kalıcı olarak ayrışır; mümkünse önce veriyi düzeltme yolunu seç, SKIP sonrası tabloyu karşılaştır. Çakışma çözülmeden publisher'daki slot WAL biriktirmeye devam eder. Subscriber tablolarına uygulamanın yazmasını yetkilerle engelle.","since":"PostgreSQL 15","note":"SKIP ve disable_on_error PostgreSQL 15 ile geldi; öncesinde aynı iş subscriber'da pg_replication_origin_advance() ile origin'i ilerleterek yapılırdı (daha riskli).","tags":["logical replication","çakışma","conflict","skip","duplicate key"]},{"id":"logical-sync-sequences","task":"Logical replication'da sequence değerlerini subscriber'a eşitle","category":"Logical Replication","command":"# Publisher'da setval betiğini üret, subscriber'da uygula (cutover'da yazmalar durdurulduktan sonra):\npsql -h <publisher_host> -d <db> -XAtc \"SELECT format('SELECT setval(%L, %s, %s);', quote_ident(schemaname) || '.' || quote_ident(sequencename), COALESCE(last_value, start_value), (last_value IS NOT NULL)::text) FROM pg_sequences;\" | psql -h <subscriber_host> -d <db> -X","what":"Logical replication sequence (identity dahil) değerlerini taşımadığı için publisher'daki her sequence'ın son değerini okuyup subscriber'da aynı değeri setval ile ayarlayan komutları üretir ve doğrudan uygular.","when":"Logical replication ile sürüm yükseltme/migrasyon cutover'ında, uygulamayı subscriber'a yönlendirmeden hemen önce.","caution":"Publisher'a yazma sürerken çalıştırılırsa değerler hemen eskir ve cutover sonrası duplicate key hatası alınır; yazmaları durdurduktan sonra çalıştır veya güvenlik payı ekle. DDL de replike edilmez: şema değişikliklerini (ALTER TABLE, yeni index) iki tarafa ayrıca uygula, önce subscriber'a. pg_sequences, okuma yetkin olmayan sequence'lar için last_value'yu NULL döndürür; komutu sahip veya superuser ile çalıştır.","since":"PostgreSQL 10","tags":["logical replication","sequence","setval","ddl replike edilmez","cutover"]},{"id":"logical-orphan-slot-cleanup","task":"Subscription'ı kaldır ve publisher'da sahipsiz logical slot'u temizle","category":"Logical Replication","command":"-- Subscriber: publisher erişilemezken DROP SUBSCRIPTION uzak slot'u silemeyip hata verir; önce slot bağını kopar:\nALTER SUBSCRIPTION sub_app DISABLE;\nALTER SUBSCRIPTION sub_app SET (slot_name = NONE);\nDROP SUBSCRIPTION sub_app;\n-- Publisher: sahipsiz kalan logical slot'ları (tablesync slot'ları pg_<suboid>_sync_<relid>_<sysid> dahil) bul ve sil:\nSELECT slot_name, active, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS retained_wal FROM pg_replication_slots WHERE slot_type = 'logical' AND NOT active;\nSELECT pg_drop_replication_slot('sub_app');","what":"Subscription'ı uzak slot'a dokunmadan siler (slot_name = NONE); ardından publisher'da artık tüketicisi olmayan logical slot'ları ve kalan tablesync slot'larını bulup kaldırır.","when":"Publisher erişilemezken subscription kaldırılması gerektiğinde, migrasyon bittikten sonra veya publisher'da active = false bir logical slot WAL biriktirirken.","caution":"Sahipsiz logical slot hem WAL'ı hem catalog_xmin'i tutar: disk dolar ve sistem kataloglarında bloat oluşur. Ancak slot'u silmek o subscription'ın kaldığı yerden devamını imkansız kılar; silmeden önce hiçbir subscriber'ın (başka bir sunucudaki dahil) bu slot'u kullanmadığını doğrula. Aktif slot silinemez; önce bağlı walsender'ı sonlandırmak gerekir.","since":"PostgreSQL 10","tags":["logical replication","slot temizliği","drop subscription","sahipsiz slot","catalog_xmin"]},{"id":"pg-upgrade-link-runbook","task":"pg_upgrade --link ile major sürüm yükseltmesi (uçtan uca runbook)","category":"Upgrade","command":"# postgres kullanıcısıyla, yazılabilir bir dizinde; örnek 16 -> 17\nexport OLD_BIN=/usr/pgsql-16/bin NEW_BIN=/usr/pgsql-17/bin\nexport OLD_DATA=/var/lib/pgsql/16/data NEW_DATA=/var/lib/pgsql/17/data\n# 0) Yeni kümeyi eski ile aynı encoding/locale ve checksum ayarıyla initdb et (eski kümede checksum açıksa -k)\n# 1) Uyumluluk kontrolü (eski küme çalışırken yapılabilir, veri değiştirmez):\n$NEW_BIN/pg_upgrade --old-bindir=$OLD_BIN --new-bindir=$NEW_BIN --old-datadir=$OLD_DATA --new-datadir=$NEW_DATA --check\n# 2) Eski kümeyi durdur ve hard link ile yükselt:\n$OLD_BIN/pg_ctl -D $OLD_DATA stop -m fast\n$NEW_BIN/pg_upgrade --old-bindir=$OLD_BIN --new-bindir=$NEW_BIN --old-datadir=$OLD_DATA --new-datadir=$NEW_DATA --link --jobs=4\n# 3) postgresql.conf/pg_hba.conf özelleştirmelerini yeni kümeye taşı, başlat:\n$NEW_BIN/pg_ctl -D $NEW_DATA -l /tmp/pg17_start.log start\n# 4) İstatistikleri topla, gerekiyorsa üretilen betikleri çalıştır:\n$NEW_BIN/vacuumdb --all --analyze-in-stages\n# psql -X -f update_extensions.sql   (pg_upgrade ürettiyse)\n# 5) Doğrulama ve yeni yedek sonrası eski kümeyi sil:\n./delete_old_cluster.sh","what":"Önce --check ile uyumluluğu doğrular, ardından eski kümenin veri dosyalarını kopyalamadan hard link ile yeni sürüme bağlayarak major yükseltmeyi veri boyutundan bağımsız olarak dakikalar içinde yapar; sonrasında istatistikleri aşamalı toplar ve eski kümeyi temizler.","when":"Kabul edilebilir kısa bir kesintiyle (dakikalar) büyük bir kümeyi yerinde yeni major sürüme taşımak için.","caution":"--link ile yeni küme bir kez başlatıldıktan sonra eski küme artık güvenle kullanılamaz; geri dönüş yolu yalnızca yükseltme öncesi alınan yedektir. Eski ve yeni veri dizini aynı dosya sisteminde olmalı. Yeni kümede istatistik yokken (analyze bitene kadar) planlar kötü olabilir. pgBackRest kullanıyorsan stanza-upgrade çalıştırıp hemen yeni bir full yedek al; eski sürümün yedekleri yeni kümeye restore edilemez.","note":"Fiziksel standby'lar pg_upgrade ile yükseltilmez: primary yükseltildikten sonra dokümandaki rsync --hard-links --size-only yöntemiyle güncellenir veya yeniden kurulur. PG17 öncesinde logical slot'lar taşınmaz (eski küme PG17+ ise taşınır); PG18 öncesinde planlayıcı istatistikleri taşınmaz.","tags":["pg_upgrade","major yükseltme","sürüm yükseltme","link","check"]},{"id":"logical-upgrade-near-zero-downtime","task":"Logical replication ile neredeyse kesintisiz major sürüm yükseltmesi","category":"Upgrade","command":"# 0) Eski sürümde wal_level = logical (restart); tüm tablolarda PRIMARY KEY veya REPLICA IDENTITY olmalı\n# 1) Rolleri ve şemayı yeni sürüme taşı ('role postgres already exists' hatası beklenir):\npg_dumpall -h <old_host> --globals-only | psql -h <new_host> -X -d postgres\npg_dump -h <old_host> --schema-only --create -d <db> | psql -h <new_host> -X -d postgres\n# 2) Eski sürümde publication, yeni sürümde subscription (ilk kopya + sürekli akış):\npsql -h <old_host> -d <db> -X -c \"CREATE PUBLICATION upg_pub FOR ALL TABLES;\"\npsql -h <new_host> -d <db> -X -c \"CREATE SUBSCRIPTION upg_sub CONNECTION 'host=<old_host> dbname=<db> user=<repl_user>' PUBLICATION upg_pub;\"\n# 3) Tüm tablolar 'r' (ready) olana ve lag ~0 olana kadar bekle:\npsql -h <new_host> -d <db> -X -c \"SELECT srsubstate, count(*) FROM pg_subscription_rel GROUP BY 1;\"\npsql -h <old_host> -d <db> -X -c \"SELECT slot_name, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), confirmed_flush_lsn)) AS lag FROM pg_replication_slots WHERE slot_name = 'upg_sub';\"\n# 4) Cutover: uygulama yazmalarını durdur, lag = 0 doğrula, sequence'ları eşitle (logical-sync-sequences)\n# 5) Subscription'ı kaldır (uzak slot da silinir), uygulamayı yeni sunucuya yönlendir:\npsql -h <new_host> -d <db> -X -c \"DROP SUBSCRIPTION upg_sub;\"","what":"Yeni sürümde boş bir küme kurup şemayı taşır, eski sürümden logical replication ile veriyi sürekli akıtır; yalnızca son cutover adımında (yazmaları durdurma, sequence eşitleme, yönlendirme) kısa bir kesinti olur. Ters yönde ikinci bir replikasyonla geri dönüş yolu da açık tutulabilir.","when":"pg_upgrade'in gerektirdiği kesintinin kabul edilemediği, farklı donanıma/OS'e geçişin de aynı anda yapıldığı veya birden çok major sürüm atlanan yükseltmelerde.","caution":"DDL, sequence, large object ve materialized view içeriği replike edilmez; geçiş süresince şema dondurulmalı. Primary key/replica identity'si olmayan tablolarda UPDATE/DELETE publisher'da hata verir. Büyük veritabanlarında ilk kopya uzun sürer ve eski sunucuda WAL ile catalog_xmin tutar. Database başına ayrı publication/subscription gerekir. Cutover öncesi satır sayısı/checksum karşılaştırması yap.","since":"PostgreSQL 10","note":"PostgreSQL 17 ile gelen pg_createsubscriber, fiziksel bir standby'ı ilk kopya yapmadan logical subscriber'a dönüştürerek büyük veritabanlarında ilk kopya süresini ortadan kaldırır.","tags":["upgrade","logical replication","kesintisiz geçiş","major yükseltme","cutover"]},{"id":"pgbouncer-show-pools-stats","task":"PgBouncer pool, istatistik ve bağlantı durumunu gör (SHOW POOLS/STATS/CLIENTS/SERVERS)","category":"PgBouncer","command":"# PgBouncer yönetim konsoluna bağlan (kullanıcı admin_users/stats_users içinde olmalı):\npsql -h 127.0.0.1 -p 6432 -U pgbouncer -d pgbouncer -X\nSHOW POOLS;    -- cl_waiting > 0 ve maxwait artıyorsa pool doymuştur\nSHOW STATS;    -- veritabanı bazında toplam/ortalama sorgu, transaction ve bekleme süreleri\nSHOW CLIENTS;  -- istemci bağlantıları (durum, kaynak adres, bağlı olduğu sunucu bağlantısı)\nSHOW SERVERS;  -- PostgreSQL'e açılan sunucu bağlantıları\nSHOW CONFIG;","what":"Her database/user pool'u için aktif ve bekleyen istemcileri (cl_active, cl_waiting), aktif/boşta sunucu bağlantılarını (sv_active, sv_idle), en uzun bekleme süresini (maxwait) ve sorgu/transaction sayaçlarını gösterir.","when":"Uygulama 'bağlantı alınamıyor'/zaman aşımı yaşadığında, pool boyutlandırmasında ve bakım öncesi aktif bağlantıları görmek için.","caution":"Yönetim konsolu SQL kabul etmez, yalnızca PgBouncer komutlarını çalıştırır. cl_waiting sürekli doluysa önce sunucu tarafında uzun transaction veya lock olup olmadığına bak; default_pool_size'ı körlemesine artırmak PostgreSQL'i max_connections sınırına ve bellek baskısına iter. SHOW STATS değerleri kümülatiftir; ortalamalar stats_period aralığına göredir.","untested":true,"tags":["pgbouncer","show pools","bağlantı havuzu","istatistik","connection pool"]},{"id":"pgbouncer-pause-resume-reload","task":"PgBouncer ile bakımda bağlantıları beklet (PAUSE/RESUME) ve yapılandırmayı yeniden yükle (RELOAD)","category":"PgBouncer","command":"psql -h 127.0.0.1 -p 6432 -U pgbouncer -d pgbouncer -X\nRELOAD;            -- pgbouncer.ini ve auth_file değişikliklerini bağlantıları koparmadan uygula\nPAUSE <db>;        -- devam eden sorgu/transaction'lar bitince sunucu bağlantılarını kapatır; yeni istekler bekletilir\n-- ... bakım: switchover, PostgreSQL restart vb. ...\nRESUME <db>;\n-- [databases] içinde host değiştirildiyse (RELOAD sonrası) sunucu bağlantılarını kademeli yenile:\nRECONNECT <db>;","what":"PAUSE, istemci bağlantılarını koparmadan PostgreSQL tarafındaki bağlantıları boşaltır ve yeni sorguları kuyrukta tutar; RESUME ile kuyruk akmaya devam eder. Böylece kısa bir primary restart veya switchover uygulamaya hata yerine kısa bir gecikme olarak yansır.","when":"Kısa bakım pencerelerinde (switchover, minor sürüm restart'ı, parametre restart'ı) ve pgbouncer.ini/userlist değişikliklerini uygularken.","caution":"PAUSE, tüm aktif transaction'lar bitene kadar döner; uzun süren bir sorgu PAUSE'u bekletir (gerekirse o oturumu PostgreSQL'de sonlandır). Bekleyen istemciler query_wait_timeout (varsayılan 120 sn) dolunca hata alır; bakımı bu sürenin içinde bitir. PAUSE'dan sonra RESUME'u unutmak tam kesintidir. Bazı ayarlar (listen_addr, listen_port vb.) RELOAD ile değişmez, restart gerekir.","untested":true,"tags":["pgbouncer","pause","resume","reload","bakım"]},{"id":"pgbouncer-pool-mode","task":"PgBouncer pool_mode seçimi ve temel boyutlandırma","category":"PgBouncer","command":"; /etc/pgbouncer/pgbouncer.ini\n[databases]\nappdb = host=<primary_host> port=5432 dbname=appdb pool_mode=transaction\nreportdb = host=<primary_host> port=5432 dbname=appdb pool_mode=session\n\n[pgbouncer]\nlisten_addr = 0.0.0.0\nlisten_port = 6432\nauth_type = scram-sha-256\nauth_file = /etc/pgbouncer/userlist.txt\npool_mode = transaction\nmax_client_conn = 5000\ndefault_pool_size = 20\nreserve_pool_size = 5\nmax_prepared_statements = 200\nquery_wait_timeout = 120","what":"session modu istemciyi bağlantı boyunca tek sunucu bağlantısına bağlar; transaction modu sunucu bağlantısını yalnızca transaction süresince verir ve binlerce istemciyi onlarca PostgreSQL bağlantısıyla taşır; statement modu her sorgudan sonra bağlantıyı geri alır ve çok-sorgulu transaction'a izin vermez. pool_mode database bazında da ezilebilir.","when":"Çok sayıda kısa ömürlü bağlantı açan OLTP/mikroservis uygulamalarında transaction modu; oturum durumuna bağımlı işler (raporlama, migration, LISTEN kullanan servisler) için session modu.","caution":"Transaction modunda oturum durumu transaction'lar arasında korunmaz: SET (SET LOCAL hariç), oturum seviyesi advisory lock, LISTEN, WITH HOLD cursor, transaction'lar arası temp table ve SQL düzeyinde PREPARE güvenilmezdir. Protokol düzeyindeki prepared statement'lar yalnızca PgBouncer 1.21+ ve max_prepared_statements > 0 ile desteklenir (1.24+'ta varsayılan 200, öncesinde 0). default_pool_size × (database, user) çifti sayısı PostgreSQL max_connections'ı (superuser_reserved_connections payı düşülerek) aşmamalı.","untested":true,"tags":["pgbouncer","pool_mode","transaction modu","bağlantı havuzu","boyutlandırma"]}]},"recipes/postgres-ops.json":{"engineId":"postgres","engine":"PostgreSQL","order":2,"recipes":[{"id":"pgss-top-queries","task":"En pahalı sorguları bul (pg_stat_statements: toplam ve ortalama süre)","category":"Performans","command":"-- Toplam süreye göre: sunucunun zamanını en çok harcayanlar\nSELECT queryid,\n       calls,\n       round(total_exec_time::numeric, 1) AS total_ms,\n       round(mean_exec_time::numeric, 2) AS mean_ms,\n       round(stddev_exec_time::numeric, 2) AS stddev_ms,\n       round((100 * total_exec_time / sum(total_exec_time) OVER ())::numeric, 1) AS pct_total,\n       rows / NULLIF(calls, 0) AS rows_per_call,\n       left(regexp_replace(query, '\\s+', ' ', 'g'), 120) AS query\nFROM pg_stat_statements\nWHERE dbid = (SELECT oid FROM pg_database WHERE datname = current_database())\nORDER BY total_exec_time DESC\nLIMIT 20;\n\n-- Çağrı başına ortalama süreye göre: tek tek yavaş olanlar\nSELECT queryid,\n       calls,\n       round(mean_exec_time::numeric, 2) AS mean_ms,\n       round(max_exec_time::numeric, 2) AS max_ms,\n       round(mean_plan_time::numeric, 2) AS mean_plan_ms,\n       left(regexp_replace(query, '\\s+', ' ', 'g'), 120) AS query\nFROM pg_stat_statements\nWHERE calls >= 50\nORDER BY mean_exec_time DESC\nLIMIT 20;","what":"Bağlı olunan veritabanında toplam çalışma süresine göre sunucunun zamanını en çok harcayan normalize edilmiş sorguları ve toplam içindeki paylarını; ikinci sorguyla çağrı başına en yavaş olanları listeler.","when":"CPU/IO yükü arttığında veya 'veritabanı yavaş' şikâyetinde ilk bakılacak yer; tuning'e nereden başlanacağını belirlemek için.","caution":"pg_stat_statements, shared_preload_libraries'e eklenip sunucu restart edilmeden ve ilgili veritabanında CREATE EXTENSION çalıştırılmadan veri toplamaz. Değerler son reset'ten bu yana kümülatiftir. stddev_ms'in mean_ms'e göre yüksek olması planın veya veri dağılımının çağrıdan çağrıya değiştiğine işaret eder. mean_plan_time yalnızca pg_stat_statements.track_planning = on iken dolar (varsayılan off; açmak ek yük getirir). Diğer kullanıcıların sorgu metinlerini görmek için superuser veya pg_read_all_stats rolü gerekir.","since":"PostgreSQL 13","note":"PostgreSQL 13'te total_time/mean_time sütunları total_exec_time/mean_exec_time olarak yeniden adlandırıldı ve planlama süreleri (total_plan_time) ayrı sütunlara alındı; PG12 ve öncesinde eski adları kullan.","tags":["pg_stat_statements","yavaş sorgu","en pahalı sorgu","top sql","performans","query tuning"]},{"id":"pgss-io-temp-heavy","task":"Disk I/O, temp dosya ve WAL üreten sorguları bul (pg_stat_statements)","category":"Performans","command":"SELECT queryid,\n       calls,\n       shared_blks_hit,\n       shared_blks_read,\n       round(100.0 * shared_blks_hit / NULLIF(shared_blks_hit + shared_blks_read, 0), 1) AS hit_pct,\n       pg_size_pretty(temp_blks_written * current_setting('block_size')::bigint) AS temp_written,\n       pg_size_pretty(wal_bytes) AS wal,\n       left(regexp_replace(query, '\\s+', ' ', 'g'), 120) AS query\nFROM pg_stat_statements\nORDER BY shared_blks_read + temp_blks_read + temp_blks_written DESC\nLIMIT 20;","what":"Shared buffer'a sığmayıp en çok blok okuyan, temp dosyaya en çok yazan (work_mem'e sığmayan sort/hash) ve en çok WAL üreten sorguları cache hit oranıyla birlikte gösterir.","when":"Disk okuma gecikmesi, temp dosya alarmı (log_temp_files) veya WAL hacminde ani artış olduğunda sorumlu sorguyu bulmak için.","caution":"shared_blks_read, OS page cache'ten karşılanan okumaları da içerir; gerçek disk süresi için track_io_timing = on gerekir (yükünü önce pg_test_timing ile ölç). temp_written yüksekse çözüm genellikle rol/oturum bazında work_mem artırmak ya da sorguyu/index'i düzeltmektir; global work_mem artışı bellek riskini büyütür.","since":"PostgreSQL 13","note":"wal_bytes/wal_records sütunları PG13 ile geldi. PG17'de blk_read_time/blk_write_time sütunları shared_blk_read_time/shared_blk_write_time olarak yeniden adlandırıldı ve local_blk_*_time eklendi.","tags":["pg_stat_statements","io","temp dosya","temp_blks_written","work_mem","wal"]},{"id":"pgss-reset","task":"pg_stat_statements istatistiklerini sıfırla (tümü veya tek sorgu)","category":"Performans","command":"-- Son reset zamanı ve tablo dolduğu için atılan (dealloc) girdi sayısı\nSELECT dealloc, stats_reset FROM pg_stat_statements_info;\n\n-- Yalnızca tek sorgunun istatistiğini sıfırla (userid, dbid, queryid; 0 = hepsi)\nSELECT pg_stat_statements_reset(0, 0, 5927525816675996975);\n\n-- Tüm istatistikleri sıfırla\nSELECT pg_stat_statements_reset();","what":"pg_stat_statements sayaçlarını tamamen ya da kullanıcı/veritabanı/queryid bazında sıfırlar; pg_stat_statements_info ile son reset zamanını ve kaç girdinin yer kalmadığı için atıldığını gösterir.","when":"Tuning değişikliği (index, parametre, deploy) öncesi temiz ölçüm başlatmak veya tek bir sorgunun yeni planını izole ölçmek için.","caution":"Reset geri alınamaz; izleme/APM araçları kümülatif sayaçlara dayanıyorsa veride boşluk oluşur, önce snapshot al (bkz. plan regresyonu reçetesi). dealloc sürekli artıyorsa pg_stat_statements.max yetersizdir (değişikliği restart ister). Varsayılan olarak yalnızca superuser çalıştırabilir; GRANT EXECUTE ON FUNCTION ile yetki verilebilir.","since":"PostgreSQL 14","note":"Parametreli reset (userid, dbid, queryid) PG12, pg_stat_statements_info view'ı PG14 ile geldi. PG17'de dördüncü parametre minmax_only eklendi: pg_stat_statements_reset(0, 0, 0, true) yalnızca min/max sürelerini sıfırlar; stats_since ve minmax_stats_since sütunları da PG17'dedir.","tags":["pg_stat_statements","reset","sıfırla","queryid","istatistik","baseline"]},{"id":"auto-explain-setup","task":"auto_explain ile yavaş sorguların execution plan'ını logla","category":"Performans","command":"-- 1) Oturum bazında: anında etkin, restart gerekmez (superuser)\nLOAD 'auto_explain';\nSET auto_explain.log_min_duration = '500ms';\nSET auto_explain.log_analyze = on;\nSET auto_explain.log_buffers = on;\nSET auto_explain.log_timing = off;\nSET auto_explain.log_nested_statements = on;\n\n-- 2) Kalıcı: yeni oturumlarda yüklenir, reload yeterli.\n--    auto_explain.* parametrelerini ALTER SYSTEM ile yazabilmek için modül önce bu oturumda LOAD edilmeli.\nLOAD 'auto_explain';\nALTER SYSTEM SET session_preload_libraries = 'auto_explain';\nALTER SYSTEM SET auto_explain.log_min_duration = '2s';\nALTER SYSTEM SET auto_explain.log_analyze = on;\nALTER SYSTEM SET auto_explain.log_buffers = on;\nALTER SYSTEM SET auto_explain.log_timing = off;\nALTER SYSTEM SET auto_explain.sample_rate = 0.1;\nSELECT pg_reload_conf();","what":"Eşiği aşan sorguların execution plan'ını (log_analyze ile gerçek satır sayıları ve buffer bilgisiyle) sunucu loguna yazar; uygulamanın gerçek parametreleriyle oluşan planı yakalar.","when":"Sorgu yalnızca uygulamada veya belirli parametrelerle yavaşlıyor ve elle EXPLAIN ile yeniden üretilemiyorsa; ara sıra görülen plan değişikliklerini yakalamak için.","caution":"log_analyze = on, eşiğin altında kalanlar dahil örneklenen her sorguya instrumentation yükü bindirir; log_timing = off ve sample_rate < 1 bu yükü azaltır. log_min_duration = 0 üretimde log hacmini patlatır. ALTER SYSTEM SET session_preload_libraries mevcut değerin üzerine yazar; önce SHOW session_preload_libraries ile kontrol et. session_preload_libraries mevcut oturumları etkilemez; tüm süreçlerde yüklemek için shared_preload_libraries + restart gerekir.","note":"auto_explain contrib modülüdür; CREATE EXTENSION gerektirmez. log_wal (PG13+) ve log_settings (PG12+) seçenekleri de vardır.","tags":["auto_explain","execution plan","yavaş sorgu","log","plan yakalama","explain"]},{"id":"explain-analyze-buffers-wal","task":"EXPLAIN (ANALYZE, BUFFERS, SETTINGS, WAL) ile planı derinlemesine oku","category":"Performans","command":"-- ANALYZE sorguyu gerçekten çalıştırır: DML'i transaction içinde çalıştırıp geri al\nBEGIN;\nEXPLAIN (ANALYZE, BUFFERS, SETTINGS, WAL, VERBOSE)\nUPDATE musteri SET bakiye = bakiye + 1 WHERE il = 'Ankara';\nROLLBACK;\n\n-- SELECT için\nEXPLAIN (ANALYZE, BUFFERS, SETTINGS)\nSELECT ad FROM musteri ORDER BY ad DESC LIMIT 10 OFFSET 1000;","what":"Planı gerçek çalıştırma istatistikleriyle verir: BUFFERS her düğümdeki shared hit/read/dirtied ve temp bloklarını, SETTINGS planı etkileyen varsayılan dışı parametreleri, WAL üretilen WAL kayıt/bayt miktarını gösterir.","when":"Tahmini ve gerçek satır sayısı farkını, diske taşan sort/hash'i (Sort Method: external merge, temp read/written) ve DML'in WAL maliyetini analiz etmek için.","caution":"ANALYZE sorguyu gerçekten çalıştırır; DML'i mutlaka BEGIN/ROLLBACK içinde çalıştır (trigger'lar ve sequence artışları yine de gerçekleşir). Okuma ipuçları: 'rows' tahmini ile 'actual rows' arasında 10 kat ve üzeri fark istatistik sorununa işaret eder; döngüdeki düğümlerde süre ve satırlar loops başınadır, toplam için loops ile çarp; Index Only Scan'de yüksek 'Heap Fetches' visibility map'in güncel olmadığını, 'Workers Planned' > 'Workers Launched' worker havuzunun tükendiğini gösterir. Timing yükü yüksek sistemlerde TIMING OFF kullan; COSTS OFF, JIT bölümünü de gizler.","since":"PostgreSQL 13","note":"SETTINGS seçeneği PG12, WAL seçeneği PG13 ile geldi. PG16'da GENERIC_PLAN, PG17'de SERIALIZE ve MEMORY seçenekleri eklendi; PG18'de ANALYZE ile BUFFERS varsayılan olarak açıktır.","tags":["explain analyze","buffers","execution plan","plan okuma","wal","performans"]},{"id":"plan-regression-queryid","task":"Plan regresyonunu queryid ile yakala (pg_stat_statements snapshot karşılaştırması)","category":"Performans","command":"-- 1) Referans snapshot al (deploy/upgrade/ANALYZE öncesi)\nCREATE TABLE IF NOT EXISTS pgss_snapshot AS\n  SELECT now() AS snap_time, userid, dbid, queryid, calls, total_exec_time,\n         shared_blks_hit, shared_blks_read, left(query, 200) AS query\n  FROM pg_stat_statements WITH NO DATA;\nINSERT INTO pgss_snapshot\n  SELECT now(), userid, dbid, queryid, calls, total_exec_time,\n         shared_blks_hit, shared_blks_read, left(query, 200)\n  FROM pg_stat_statements;\n\n-- 2) Sonra: snapshot'tan bu yana çağrı başına süresi en çok artan sorgular\nWITH base AS (\n  SELECT DISTINCT ON (userid, dbid, queryid) *\n  FROM pgss_snapshot\n  ORDER BY userid, dbid, queryid, snap_time DESC\n)\nSELECT s.queryid,\n       s.calls - b.calls AS new_calls,\n       round((b.total_exec_time / b.calls)::numeric, 2) AS old_mean_ms,\n       round(((s.total_exec_time - b.total_exec_time) / (s.calls - b.calls))::numeric, 2) AS new_mean_ms,\n       round((b.shared_blks_hit + b.shared_blks_read)::numeric / b.calls, 0) AS old_blks_per_call,\n       round((s.shared_blks_hit + s.shared_blks_read - b.shared_blks_hit - b.shared_blks_read)::numeric\n             / (s.calls - b.calls), 0) AS new_blks_per_call,\n       left(regexp_replace(s.query, '\\s+', ' ', 'g'), 100) AS query\nFROM pg_stat_statements s\nJOIN base b USING (userid, dbid, queryid)\nWHERE s.calls - b.calls >= 10\n  AND b.calls > 0\nORDER BY ((s.total_exec_time - b.total_exec_time) / (s.calls - b.calls))\n         / NULLIF(b.total_exec_time / b.calls, 0) DESC NULLS LAST\nLIMIT 20;\n\n-- 3) Şüpheli queryid şu anda çalışıyor mu?\nSELECT pid, state, now() - query_start AS runtime, left(query, 100) AS query\nFROM pg_stat_activity\nWHERE query_id = -4094682686355101727;","what":"pg_stat_statements'ın kümülatif sayaçlarını tabloya kaydeder ve sonraki durumla queryid bazında karşılaştırır; snapshot sonrasındaki çağrıların ortalama süresini ve çağrı başına buffer sayısını eski değerlerle yan yana gösterir.","when":"Deploy, major upgrade, istatistik yenilemesi veya parametre değişikliği sonrası 'dün hızlıydı, bugün yavaş' şikâyetinde planı değişen sorguyu bulmak için.","caution":"Snapshot ile karşılaştırma arasında pg_stat_statements_reset() çalışırsa veya girdi yer kalmadığı için atılırsa (dealloc) farklar anlamsızlaşır; pg_stat_statements_info.stats_reset'i kontrol et. Çağrı başına buffer sayısındaki artış, cache etkisinden bağımsız olduğu için süre artışından daha güvenilir bir plan değişikliği işaretidir. Planı doğrulamak için sorguyu gerçek parametrelerle EXPLAIN et veya auto_explain kullan; PostgreSQL'de yerleşik plan sabitleme yoktur (pg_hint_plan eklentisi gerekir). Snapshot tablosunu iş bitince sil.","since":"PostgreSQL 14","note":"pg_stat_activity.query_id ve compute_query_id parametresi PG14 ile geldi (varsayılan auto: pg_stat_statements yüklüyse hesaplanır). EXPLAIN VERBOSE çıktısındaki 'Query Identifier' aynı değeri verir. 1. ve 2. adımlar PG13'te de çalışır.","tags":["plan regresyonu","queryid","pg_stat_statements","snapshot","plan değişikliği","performans"]},{"id":"parallel-query-usage","task":"Paralel sorgu kapasitesini ve anlık worker kullanımını denetle","category":"Performans","command":"-- Paralel worker havuzu ayarları\nSELECT name, current_setting(name) AS value\nFROM pg_settings\nWHERE name IN ('max_worker_processes', 'max_parallel_workers', 'max_parallel_workers_per_gather',\n               'max_parallel_maintenance_workers', 'parallel_setup_cost', 'parallel_tuple_cost',\n               'min_parallel_table_scan_size', 'min_parallel_index_scan_size')\nORDER BY name;\n\n-- Şu anda paralel çalışan sorgular ve worker sayıları\nSELECT a.pid AS leader_pid,\n       count(w.pid) AS workers_running,\n       current_setting('max_parallel_workers')::int AS max_parallel_workers,\n       now() - a.query_start AS runtime,\n       left(a.query, 80) AS query\nFROM pg_stat_activity a\nJOIN pg_stat_activity w ON w.leader_pid = a.pid AND w.pid <> a.pid\nGROUP BY a.pid, a.query_start, a.query\nORDER BY workers_running DESC;\n\n-- Tek tablo için planlanan worker sayısını sabitle / geri al\nALTER TABLE siparis SET (parallel_workers = 4);\nALTER TABLE siparis RESET (parallel_workers);","what":"Paralel sorgu limitlerini ve hangi lider sürecin şu anda kaç parallel worker kullandığını gösterir; tablo bazında worker sayısı ayarını örnekler.","when":"Analitik sorgular beklenenden yavaşsa, planda 'Workers Planned' > 'Workers Launched' görülüyorsa veya CPU çekirdekleri boşta kalıyorsa.","caution":"max_parallel_workers, max_worker_processes (restart ister) ile sınırlıdır ve bu havuzu logical replication worker'ları ve diğer background worker'lar da kullanır. OLTP'de yüksek max_parallel_workers_per_gather eşzamanlı sorgularda CPU'yu doyurur; her worker ayrıca kendi work_mem'ini kullanır. Veri değiştiren veya satır kilitleyen sorgular (CREATE TABLE AS / SELECT INTO hariç), cursor'lar ve PARALLEL UNSAFE fonksiyon çağıranlar paralel plan almaz. ALTER TABLE ... SET (parallel_workers) kısa bir ShareUpdateExclusiveLock alır.","since":"PostgreSQL 13","note":"pg_stat_activity.leader_pid PG13 ile geldi; öncesinde parallel worker'lar yalnızca backend_type = 'parallel worker' olarak görünür ve lidere bağlanamazdı.","tags":["paralel sorgu","parallel worker","leader_pid","max_parallel_workers","gather","cpu"]},{"id":"jit-impact-check","task":"JIT derlemenin sorgu süresine etkisini ölç","category":"Performans","command":"-- JIT süresinin toplam çalışma süresi içindeki payı (PG15+)\nSELECT queryid,\n       calls,\n       jit_functions,\n       round((jit_generation_time + jit_inlining_time + jit_optimization_time + jit_emission_time)::numeric, 1) AS jit_ms,\n       round(total_exec_time::numeric, 1) AS total_ms,\n       round((100 * (jit_generation_time + jit_inlining_time + jit_optimization_time + jit_emission_time)\n             / NULLIF(total_exec_time, 0))::numeric, 1) AS jit_pct,\n       left(regexp_replace(query, '\\s+', ' ', 'g'), 100) AS query\nFROM pg_stat_statements\nWHERE jit_functions > 0\nORDER BY jit_pct DESC NULLS LAST\nLIMIT 20;\n\n-- Tek sorguda karşılaştır: çıktının sonundaki \"JIT:\" bölümüne ve Execution Time'a bak\nSET jit = on;\nEXPLAIN (ANALYZE) SELECT il, sum(bakiye) FROM musteri GROUP BY il;\nSET jit = off;\nEXPLAIN (ANALYZE) SELECT il, sum(bakiye) FROM musteri GROUP BY il;\nRESET jit;","what":"JIT derleme süresinin (generation, inlining, optimization, emission) sorgu süresi içindeki payını sorgu bazında gösterir; aynı sorguyu JIT açık ve kapalı çalıştırarak net etkiyi ölçer.","when":"Kısa süren OLTP veya raporlama sorgularında açıklanamayan onlarca/yüzlerce ms gecikme varsa; özellikle çok partition'lı tablolarda maliyet tahmini şişip JIT'i tetiklediğinde.","caution":"JIT yalnızca plan maliyeti jit_above_cost'u (varsayılan 100000) aşınca devreye girer; maliyet tahmini abartılıysa kısa sorgularda derleme süresi çalışma süresini geçebilir. Global kapatmak yerine önce sorunlu rol/veritabanı için ALTER ROLE ... SET jit = off ya da jit_above_cost'u yükseltmeyi değerlendir. EXPLAIN (ANALYZE, COSTS OFF) JIT bölümünü göstermez. PostgreSQL LLVM desteğiyle derlenmemişse JIT hiç kullanılmaz; kontrol: SELECT pg_jit_available();","since":"PostgreSQL 15","note":"jit_* sütunları pg_stat_statements'a PG15'te eklendi; PG17'de jit_deform_count/jit_deform_time da geldi. JIT PG11'de eklendi ve PG12'den itibaren varsayılan olarak açıktır.","tags":["jit","llvm","jit_above_cost","pg_stat_statements","derleme süresi","performans"]},{"id":"blocking-tree","task":"Blocking ağacını çıkar (kök bloklayan oturumu bul)","category":"Oturum","command":"WITH RECURSIVE tree AS (\n  SELECT a.pid, a.pid AS root_pid, 0 AS level, ARRAY[a.pid] AS path\n  FROM pg_stat_activity a\n  WHERE cardinality(pg_blocking_pids(a.pid)) = 0\n    AND EXISTS (SELECT 1 FROM pg_stat_activity w WHERE a.pid = ANY (pg_blocking_pids(w.pid)))\n  UNION ALL\n  SELECT w.pid, t.root_pid, t.level + 1, t.path || w.pid\n  FROM tree t\n  JOIN pg_stat_activity w ON t.pid = ANY (pg_blocking_pids(w.pid))\n  WHERE w.pid <> ALL (t.path)\n), node AS (\n  SELECT DISTINCT ON (pid) pid, root_pid, level\n  FROM tree\n  ORDER BY pid, level DESC\n)\nSELECT repeat('  ', n.level) || n.pid AS pid_tree,\n       n.root_pid,\n       pg_blocking_pids(n.pid) AS blocked_by,\n       a.usename,\n       a.state,\n       a.wait_event_type || ':' || a.wait_event AS wait,\n       now() - a.xact_start AS xact_age,\n       left(regexp_replace(a.query, '\\s+', ' ', 'g'), 80) AS query\nFROM node n\nJOIN pg_stat_activity a USING (pid)\nORDER BY n.root_pid, n.level, n.pid;","what":"pg_blocking_pids() ile bekleme zincirini özyinelemeli izler; kimseyi beklemeyen kök bloklayıcıdan başlayarak her bekleyen oturumu girintili ağaç halinde, onu doğrudan bloklayan PID'ler ve transaction yaşıyla gösterir.","when":"Uygulamada toplu zaman aşımı veya kuyruk birikmesi olduğunda; onlarca bekleyen oturum içinden müdahale edilmesi gereken tek kök oturumu bulmak için.","caution":"Kök çoğu zaman lock'u tutup unutulmuş 'idle in transaction' bir oturumdur; query sütunu o oturumun lock'u alan komutunu değil SON çalıştırdığı komutu gösterir. ACCESS EXCLUSIVE bekleyen bir DDL, lock kuyruğu nedeniyle arkasındaki basit SELECT'leri de bloklar ve ağaçta ara düğüm olarak görünür. pg_blocking_pids() lock manager üzerinde kısa süreli lock alır; bu sorguyu sık aralıklı döngüyle çalıştırma. Bir oturum birden çok kola bağlıysa en derin seviyesinde bir kez gösterilir.","since":"PostgreSQL 9.6","tags":["blocking","lock ağacı","kilit zinciri","pg_blocking_pids","bloklayan oturum","lock"]},{"id":"lock-wait-detail","task":"Bekleyen lock'ları nesne ve lock modu düzeyinde ayrıntılı gör (pg_locks)","category":"Oturum","command":"SELECT DISTINCT\n       w.pid AS waiting_pid,\n       w.locktype,\n       coalesce(w.relation::regclass::text, 'xid ' || w.transactionid, w.virtualxid, w.objid::text) AS target,\n       w.mode AS wanted_mode,\n       b.pid AS blocker_pid,\n       b.mode AS blocker_mode,\n       b.granted AS blocker_holds,\n       now() - wa.state_change AS waiting_for,\n       left(wa.query, 60) AS waiting_query,\n       left(ba.query, 60) AS blocker_query\nFROM pg_locks w\nJOIN pg_locks b\n  ON b.pid = ANY (pg_blocking_pids(w.pid))\n AND b.locktype = w.locktype\n AND b.database IS NOT DISTINCT FROM w.database\n AND b.relation IS NOT DISTINCT FROM w.relation\n AND b.page IS NOT DISTINCT FROM w.page\n AND b.tuple IS NOT DISTINCT FROM w.tuple\n AND b.virtualxid IS NOT DISTINCT FROM w.virtualxid\n AND b.transactionid IS NOT DISTINCT FROM w.transactionid\n AND b.classid IS NOT DISTINCT FROM w.classid\n AND b.objid IS NOT DISTINCT FROM w.objid\n AND b.objsubid IS NOT DISTINCT FROM w.objsubid\nJOIN pg_stat_activity wa ON wa.pid = w.pid\nJOIN pg_stat_activity ba ON ba.pid = b.pid\nWHERE NOT w.granted\nORDER BY waiting_for DESC, waiting_pid;","what":"Verilmemiş (granted = false) her lock isteği için hedef nesneyi (tablo, transaction id vb.), istenen modu, engelleyen PID'i ve onun modunu, engelleyenin lock'u gerçekten tutup tutmadığını ve yaklaşık bekleme süresini gösterir.","when":"Blocking'in hangi tablo ve lock modu çakışmasından kaynaklandığını anlamak için; örn. DDL'in AccessExclusiveLock beklemesi veya row lock'ta transactionid beklemesi.","caution":"Eşleşme pg_blocking_pids() ile yapıldığı için yalnızca gerçekten çakışan istekler listelenir. blocker_holds = false, engelleyenin lock'u henüz almadığını, çakışan modla kuyrukta önde beklediğini gösterir (lock kuyruğu). locktype = 'transactionid' satır düzeyi çakışmadır: satırı değiştiren transaction bitene kadar beklenir; satırın kendisi pg_locks'ta görünmez. pg_locks büyük sistemlerde binlerce satır içerebilir; sorguyu sık çalıştırma. waiting_for, state_change üzerinden hesaplanan yaklaşık değerdir.","since":"PostgreSQL 9.6","tags":["pg_locks","lock wait","kilit bekleme","accessexclusivelock","transactionid","lock"]},{"id":"long-idle-transactions","task":"Uzun süren ve 'idle in transaction' kalan transaction'ları bul","category":"Oturum","command":"SELECT pid,\n       usename,\n       datname,\n       application_name,\n       client_addr,\n       state,\n       now() - xact_start AS xact_age,\n       now() - state_change AS in_state_for,\n       backend_xid,\n       age(backend_xmin) AS xmin_age,\n       left(regexp_replace(query, '\\s+', ' ', 'g'), 100) AS last_query\nFROM pg_stat_activity\nWHERE xact_start IS NOT NULL\n  AND backend_type = 'client backend'\n  AND pid <> pg_backend_pid()\n  AND (now() - xact_start > interval '5 minutes' OR state LIKE 'idle in transaction%')\nORDER BY xact_start;","what":"Açık transaction'ı 5 dakikadan eski olan veya transaction açıkken boşta bekleyen oturumları; transaction yaşını, mevcut durumda geçen süreyi, atanmış XID'i ve tuttuğu xmin'in yaşını gösterir.","when":"Bloat arttığında, VACUUM 'dead row versions cannot be removed yet' raporladığında, lock beklemelerinde veya bağlantı havuzu sızıntısı şüphesinde.","caution":"Uzun transaction'lar (özellikle REPEATABLE READ/SERIALIZABLE veya açık cursor tutanlar) backend_xmin ile VACUUM'un temizleme sınırını (xmin horizon) geride tutar; bu tüm veritabanında bloat ve XID yaşlanmasına yol açar. 'idle in transaction (aborted)' hata almış ve ROLLBACK bekleyen oturumdur. Kalıcı çözüm: rol bazında idle_in_transaction_session_timeout ve uygulamada transaction sınırlarının düzeltilmesi.","tags":["uzun transaction","idle in transaction","xmin","bloat","oturum","long running"]},{"id":"terminate-idle-in-transaction","task":"Uzun süre 'idle in transaction' bekleyen oturumları toplu ve kontrollü sonlandır","category":"Oturum","command":"-- 1) Önce kuru çalıştırma: kimler etkilenecek?\nSELECT pid, usename, application_name, client_addr,\n       now() - state_change AS idle_for, left(query, 80) AS last_query\nFROM pg_stat_activity\nWHERE state IN ('idle in transaction', 'idle in transaction (aborted)')\n  AND now() - state_change > interval '15 minutes'\n  AND backend_type = 'client backend'\n  AND pid <> pg_backend_pid();\n\n-- 2) Sonlandır; her süreç için çıkışını en fazla 5 sn bekle\nSELECT pid, usename, now() - state_change AS idle_for,\n       pg_terminate_backend(pid, 5000) AS terminated\nFROM pg_stat_activity\nWHERE state IN ('idle in transaction', 'idle in transaction (aborted)')\n  AND now() - state_change > interval '15 minutes'\n  AND backend_type = 'client backend'\n  AND pid <> pg_backend_pid();","what":"Belirli süredir transaction'ı açık bırakıp boşta bekleyen oturumları önce listeler, ardından sonlandırır; timeout parametresi süreç gerçekten çıkana kadar (veya süre dolana kadar) bekler.","when":"Lock tutan unutulmuş oturumlar blocking yarattığında veya xmin horizon'u tutarak VACUUM'u engellediğinde acil müdahale için.","caution":"'idle in transaction' oturumda pg_cancel_backend işe yaramaz (iptal edilecek çalışan sorgu yoktur); pg_terminate_backend gerekir ve commit edilmemiş tüm değişiklikler rollback olur. Filtreyi usename/application_name ile daralt; replikasyon, yedekleme ve izleme oturumlarını hariç tut. Bağlantı havuzları sonlandırılan bağlantıyı yeniden açar. Süre dolarsa fonksiyon uyarı verip false döner. Kalıcı çözüm için rol bazında idle_in_transaction_session_timeout tanımla.","since":"PostgreSQL 14","note":"İki parametreli pg_terminate_backend(pid, timeout) PG14 ile geldi; öncesinde yalnızca pg_terminate_backend(pid) vardır ve sinyali gönderip hemen döner.","tags":["pg_terminate_backend","idle in transaction","oturum sonlandır","kill session","toplu","lock"]},{"id":"role-timeouts","task":"Rol ve veritabanı bazında statement_timeout / lock_timeout tanımla","category":"Oturum","command":"-- Uygulama rolü: kısa sorgular, kısa lock beklemesi, unutulan transaction'a sınır\nALTER ROLE web_app SET statement_timeout = '30s';\nALTER ROLE web_app SET lock_timeout = '5s';\nALTER ROLE web_app SET idle_in_transaction_session_timeout = '10min';\n\n-- Raporlama rolü yalnızca bu veritabanında daha uzun çalışabilsin\nALTER ROLE report_app IN DATABASE veritabani SET statement_timeout = '15min';\n\n-- Tanımlı rol/veritabanı ayarlarını gör\nSELECT coalesce(r.rolname, '(all)') AS role,\n       coalesce(d.datname, '(all)') AS database,\n       s.setconfig\nFROM pg_db_role_setting s\nLEFT JOIN pg_roles r ON r.oid = s.setrole\nLEFT JOIN pg_database d ON d.oid = s.setdatabase\nORDER BY 1, 2;\n\n-- Geri al\nALTER ROLE web_app RESET lock_timeout;","what":"Zaman aşımı parametrelerini rol (ve isteğe bağlı olarak veritabanı) düzeyinde kalıcı hale getirir; global ayarı değiştirmeden her iş yükünü kendi sınırıyla çalıştırır.","when":"Kaçak sorguların kaynakları tüketmesini, DDL/lock kuyruklarının uygulamayı kilitlemesini ve unutulan transaction'ların bloat üretmesini önlemek için.","caution":"Ayarlar yalnızca YENİ oturumlarda etkin olur; havuzdaki mevcut bağlantıları yenile. Kullanıcı oturumda SET ile değeri değiştirebilir; bu bir güvenlik sınırı değildir. statement_timeout'u postgresql.conf'ta global ayarlama: pg_dump, VACUUM, CREATE INDEX gibi bakım işleri de kesilir. Öncelik sırası: rol+veritabanı > rol > veritabanı > postgresql.conf.","note":"idle_in_transaction_session_timeout PG9.6, idle_session_timeout PG14, transaction_timeout PG17 ile geldi.","tags":["statement_timeout","lock_timeout","idle_in_transaction_session_timeout","alter role","zaman aşımı","timeout"]},{"id":"ddl-lock-timeout-retry","task":"DDL'i lock_timeout ve yeniden deneme ile güvenli uygula (lock kuyruğunu önle)","category":"Oturum","command":"-- Tek deneme: kilit 3 sn içinde alınamazsa vazgeç, kuyrukta bekleyip trafiği bloklama\nSET lock_timeout = '3s';\nALTER TABLE musteri ADD COLUMN IF NOT EXISTS segment text;\nRESET lock_timeout;\n\n-- Otomatik yeniden deneme: en fazla 5 deneme, aralarda 3 sn\nDO $$\nDECLARE\n  attempt int := 0;\nBEGIN\n  LOOP\n    attempt := attempt + 1;\n    BEGIN\n      SET LOCAL lock_timeout = '2s';\n      ALTER TABLE musteri ADD COLUMN IF NOT EXISTS segment text;\n      RAISE NOTICE 'OK, attempt %', attempt;\n      EXIT;\n    EXCEPTION WHEN lock_not_available THEN\n      RAISE NOTICE 'lock not acquired, attempt %', attempt;\n      IF attempt >= 5 THEN RAISE; END IF;\n      PERFORM pg_sleep(3);\n    END;\n  END LOOP;\nEND $$;","what":"ACCESS EXCLUSIVE gerektiren DDL'in lock'u alamadığında süresiz beklemesini ve beklerken arkasında biriken tüm sorguları (lock kuyruğu) bloklamasını önler; kısa aralıklarla yeniden dener.","when":"Yoğun tablolarda ALTER TABLE, CREATE/DROP TRIGGER, ATTACH PARTITION, RENAME gibi kısa süren ama ağır lock isteyen değişiklikleri canlıda uygularken.","caution":"lock_timeout olmadan, uzun süren tek bir SELECT'in arkasında bekleyen ALTER TABLE, sonradan gelen tüm okuma/yazmaları da bekletir ve dakikalar içinde bağlantı havuzunu tüketebilir. lock_timeout yalnızca lock bekleme süresini sınırlar; tabloyu yeniden yazan DDL'lerin (örn. kolon tipi değişikliği) çalışma süresini sınırlamaz. DO bloğu tek transaction'dır ve denemeler boyunca snapshot tutar; uzun yeniden deneme senaryolarında dışarıdan bir shell döngüsü tercih et.","tags":["lock_timeout","ddl","alter table","lock kuyruğu","yeniden deneme","lock"]},{"id":"connection-usage","task":"Bağlantı kullanımını max_connections'a göre ölç","category":"Oturum","command":"-- Kapasite: kullanılan ve normal kullanıcılara kalan slot\nSELECT max_conn,\n       reserved,\n       used,\n       max_conn - reserved - used AS free_for_normal_users,\n       round(100.0 * used / max_conn, 1) AS used_pct\nFROM (SELECT current_setting('max_connections')::int AS max_conn,\n             current_setting('superuser_reserved_connections')::int\n             + coalesce(current_setting('reserved_connections', true)::int, 0) AS reserved,\n             (SELECT count(*) FROM pg_stat_activity WHERE backend_type = 'client backend') AS used) x;\n\n-- Dağılım: veritabanı, kullanıcı, uygulama ve duruma göre\nSELECT datname, usename, application_name, state,\n       count(*) AS sessions,\n       max(now() - state_change) AS longest_in_state\nFROM pg_stat_activity\nWHERE backend_type = 'client backend'\nGROUP BY datname, usename, application_name, state\nORDER BY sessions DESC;\n\n-- Rol ve veritabanı bağlantı limitleri\nSELECT rolname, rolconnlimit FROM pg_roles WHERE rolconnlimit <> -1;\nSELECT datname, datconnlimit FROM pg_database WHERE datconnlimit <> -1;","what":"max_connections'a göre kullanılan ve normal kullanıcılara kalan bağlantı slotlarını, bağlantıların veritabanı/kullanıcı/uygulama/durum dağılımını ve tanımlı CONNECTION LIMIT'leri gösterir.","when":"'too many clients already' / 'remaining connection slots are reserved' hatalarında, kapasite planlamasında veya pooler ihtiyacını değerlendirirken.","caution":"max_connections yalnızca client backend'leri sınırlar; autovacuum worker'ları, background worker'lar ve walsender'lar ayrı slot kullanır. Son superuser_reserved_connections (PG16+ ek olarak reserved_connections) slot normal kullanıcılara kapalıdır. max_connections'u yüzlerce/binlerce yapmak yerine PgBouncer gibi bir pooler kullan: her bağlantı ayrı bir süreçtir ve bellek, snapshot maliyeti bağlantı sayısıyla büyür. Çok sayıda 'idle' oturum uygulama havuzunun gereğinden büyük olduğunu gösterir. Kaçak bir uygulamanın tüm slotları tüketmesini ALTER ROLE ... CONNECTION LIMIT ile engelle; max_connections değişikliği restart ister.","note":"reserved_connections parametresi ve pg_use_reserved_connections rolü PG16 ile geldi; sorgu eski sürümlerde de çalışır (parametre yoksa 0 sayılır).","tags":["max_connections","bağlantı sayısı","connection","pooler","superuser_reserved_connections","oturum"]},{"id":"autovacuum-progress","task":"Çalışan autovacuum/VACUUM işlemlerinin ilerlemesini izle","category":"Bakım","command":"SELECT p.pid,\n       a.backend_type,\n       p.datname,\n       p.relid::regclass AS table_name,\n       p.phase,\n       pg_size_pretty(p.heap_blks_total * current_setting('block_size')::bigint) AS table_size,\n       round(100.0 * p.heap_blks_scanned / NULLIF(p.heap_blks_total, 0), 1) AS scanned_pct,\n       round(100.0 * p.heap_blks_vacuumed / NULLIF(p.heap_blks_total, 0), 1) AS vacuumed_pct,\n       p.index_vacuum_count,\n       now() - a.xact_start AS running_for,\n       a.wait_event_type || ':' || a.wait_event AS wait,\n       left(a.query, 80) AS query\nFROM pg_stat_progress_vacuum p\nJOIN pg_stat_activity a USING (pid)\nORDER BY running_for DESC;\n\n-- Meşgul autovacuum worker sayısı / üst sınır\nSELECT count(*) FILTER (WHERE backend_type = 'autovacuum worker') AS av_workers_busy,\n       current_setting('autovacuum_max_workers') AS av_max_workers\nFROM pg_stat_activity;","what":"Çalışan her VACUUM'un (autovacuum worker veya manuel) tablosunu, fazını, taranan/temizlenen heap yüzdesini, index vacuum tur sayısını ve bekleme olayını; ayrıca meşgul autovacuum worker sayısını gösterir.","when":"Büyük tablodaki VACUUM'un ne zaman biteceğini kestirmek, tüm autovacuum worker'larının dolu olup olmadığını (kuyrukta bekleyen tablolar) ve vacuum'un throttling nedeniyle beklediğini görmek için.","caution":"index_vacuum_count > 1 ise dead tuple listesi belleğe sığmamış ve index'ler birden çok kez taranmıştır; maintenance_work_mem/autovacuum_work_mem'i artır (PG17 öncesi bu amaçla en fazla 1GB kullanılır). wait = Timeout:VacuumDelay, cost-based throttling'dir (autovacuum_vacuum_cost_delay/cost_limit). Sorgu metninde 'to prevent wraparound' görünen autovacuum'u sonlandırma; hemen yeniden başlar. VACUUM FULL ve CLUSTER bu view'da değil pg_stat_progress_cluster'da görünür.","since":"PostgreSQL 9.6","note":"PG17'de max_dead_tuples/num_dead_tuples sütunları max_dead_tuple_bytes/num_dead_item_ids olarak değişti ve indexes_total/indexes_processed eklendi; sorgu bu yüzden sürümden bağımsız sütunları kullanır.","tags":["autovacuum","vacuum ilerleme","pg_stat_progress_vacuum","vacuum","bakım","progress"]},{"id":"xid-wraparound-risk","task":"Transaction ID wraparound riskini ölç (veritabanı ve tablo bazında XID yaşı)","category":"Bakım","command":"-- Veritabanı bazında: autovacuum_freeze_max_age'e ve ~2^31 sınırına uzaklık\nSELECT datname,\n       age(datfrozenxid) AS xid_age,\n       mxid_age(datminmxid) AS mxid_age,\n       round(100.0 * age(datfrozenxid) / current_setting('autovacuum_freeze_max_age')::int, 1) AS pct_of_freeze_max_age,\n       round(100.0 * age(datfrozenxid) / 2147483647, 1) AS pct_of_wraparound\nFROM pg_database\nORDER BY age(datfrozenxid) DESC;\n\n-- Bağlı olunan veritabanında en yaşlı tablolar (TOAST dahil)\nSELECT c.oid::regclass AS table_name,\n       greatest(age(c.relfrozenxid), age(t.relfrozenxid)) AS xid_age,\n       mxid_age(c.relminmxid) AS mxid_age,\n       pg_size_pretty(pg_total_relation_size(c.oid)) AS total_size,\n       s.last_autovacuum,\n       s.last_vacuum\nFROM pg_class c\nLEFT JOIN pg_class t ON t.oid = c.reltoastrelid\nLEFT JOIN pg_stat_all_tables s ON s.relid = c.oid\nWHERE c.relkind IN ('r', 'm')\nORDER BY 2 DESC\nLIMIT 20;","what":"Her veritabanının en eski unfrozen XID ve multixact yaşını, autovacuum_freeze_max_age eşiğine ve wraparound sınırına oranla; bağlı olunan veritabanında ise TOAST dahil en yaşlı tabloları boyut ve son vacuum zamanıyla gösterir.","when":"Rutin izlemede (tipik alarm eşiği pct_of_wraparound %50 uyarı / %75 kritik), loglarda 'must be vacuumed within N transactions' uyarısı görüldüğünde ve freeze çalışmasını önceliklendirmek için.","caution":"pct_of_freeze_max_age 100'ü geçen tablolar için autovacuum zorunlu (anti-wraparound) vacuum başlatır; bu vacuum yoğun I/O üretir ve sonlandırılsa da yeniden başlar. Yaş düşmüyorsa sebep neredeyse her zaman xmin horizon'u tutan bir şeydir (uzun transaction, prepared transaction, replication slot, hot_standby_feedback); önce onu çöz, aksi halde VACUUM FREEZE de yaşı düşüremez. Sınıra yaklaşıldığında sunucu önce uyarı verir, son birkaç milyon XID kala yeni XID atamayı (yazmayı) reddeder. Hedefli freeze için: VACUUM (FREEZE, VERBOSE) <tablo>;","note":"PG14'te vacuum_failsafe_age / vacuum_multixact_failsafe_age (varsayılan 1.6 milyar) eklendi: bu yaşa ulaşan tabloda VACUUM, cost-delay'i ve index temizliğini atlayarak acil moda geçer.","tags":["wraparound","xid yaşı","datfrozenxid","relfrozenxid","freeze","multixact"]},{"id":"xmin-horizon-holders","task":"VACUUM'un dead tuple temizlemesini engelleyen xmin horizon tutucularını bul","category":"Bakım","command":"SELECT 'session' AS source, pid::text AS id, usename::text AS owner, state AS detail,\n       age(backend_xmin) AS xmin_age\nFROM pg_stat_activity\nWHERE backend_xmin IS NOT NULL AND pid <> pg_backend_pid()\nUNION ALL\nSELECT 'prepared_xact', gid, owner::text, prepared::text, age(transaction)\nFROM pg_prepared_xacts\nUNION ALL\nSELECT 'replication_slot', slot_name::text, slot_type, active::text,\n       greatest(age(xmin), age(catalog_xmin))\nFROM pg_replication_slots\nWHERE xmin IS NOT NULL OR catalog_xmin IS NOT NULL\nUNION ALL\nSELECT 'standby_feedback', application_name, usename::text, state, age(backend_xmin)\nFROM pg_stat_replication\nWHERE backend_xmin IS NOT NULL\nORDER BY xmin_age DESC NULLS LAST;","what":"Dead tuple temizliğini engelleyebilecek dört kaynağı (snapshot tutan oturumlar, prepared transaction'lar, replication slot'lar, hot_standby_feedback gönderen standby'lar) tek listede xmin yaşına göre sıralar.","when":"VACUUM VERBOSE 'dead row versions cannot be removed yet' raporladığında, bloat sürekli artıyor ve XID yaşı düşmüyorsa.","caution":"En yaşlı xmin temizleme sınırını belirler; replication slot'lar ve standby feedback tüm veritabanlarını etkiler. Prepared transaction'lar restart sonrasında da kalır; sahibini doğrulayıp COMMIT PREPARED / ROLLBACK PREPARED '<gid>' ile kapat. Kullanılmayan bir slot'u silmek downstream'i (standby, CDC) bozar; önce sahibini doğrula. Standby'da çalıştırılırsa yalnızca o standby'daki oturumları gösterir.","tags":["xmin horizon","vacuum engeli","dead tuple","prepared transaction","replication slot","bloat"]},{"id":"pgstattuple-bloat","task":"Tablo ve index bloat'ını pgstattuple ile ölç","category":"Bakım","command":"CREATE EXTENSION IF NOT EXISTS pgstattuple;\n\n-- Hızlı tahmin: visibility map'te all-visible sayfaları okumaz\nSELECT pg_size_pretty(table_len) AS table_size,\n       round(approx_tuple_percent::numeric, 1) AS live_pct,\n       round(dead_tuple_percent::numeric, 1) AS dead_pct,\n       round(approx_free_percent::numeric, 1) AS free_pct\nFROM pgstattuple_approx('siparis');\n\n-- Kesin ölçüm: tüm tabloyu okur\nSELECT pg_size_pretty(table_len) AS table_size,\n       round(dead_tuple_percent::numeric, 1) AS dead_pct,\n       round(free_percent::numeric, 1) AS free_pct,\n       pg_size_pretty(dead_tuple_len + free_space) AS reclaimable\nFROM pgstattuple('siparis');\n\n-- B-tree index'ler: yaprak doluluğu (yeni oluşturulmuş ~90; 50'nin altı bloat'lı)\nWITH idx AS MATERIALIZED (\n  SELECT i.indexrelid\n  FROM pg_index i\n  JOIN pg_class c ON c.oid = i.indexrelid\n  JOIN pg_am am ON am.oid = c.relam\n  WHERE am.amname = 'btree' AND i.indrelid = 'siparis'::regclass\n)\nSELECT idx.indexrelid::regclass AS index_name,\n       pg_size_pretty(s.index_size) AS index_size,\n       s.avg_leaf_density,\n       s.leaf_fragmentation\nFROM idx\nCROSS JOIN LATERAL pgstatindex(idx.indexrelid) s;","what":"Tablodaki canlı/ölü satır ve boş alan yüzdesini (hızlı tahmini ve kesin olarak) ve geri kazanılabilir alanı; B-tree index'lerin yaprak doluluk ve fragmentasyon oranını gösterir.","when":"pg_stat_user_tables'taki n_dead_tup tahmini yeterli olmadığında; pg_repack, VACUUM FULL veya REINDEX kararını veriyle desteklemek için.","caution":"pgstattuple ve pgstatindex tüm ilişkiyi okur; büyük tablolarda yoğun I/O üretir (yalnızca AccessShareLock alır). Önce pgstattuple_approx kullan. Varsayılan olarak superuser veya pg_stat_scan_tables rolü gerekir. Bir miktar boş alan normaldir (fillfactor, HOT update payı); VACUUM bu alanı yeniden kullanılabilir yapar ama dosyayı küçültmez, geri kazanmak için pg_repack ya da VACUUM FULL (ACCESS EXCLUSIVE lock!) gerekir. avg_leaf_density düşük index'i REINDEX CONCURRENTLY ile yenile.","since":"PostgreSQL 12","note":"pgstattuple contrib eklentisidir; pgstattuple_approx PG9.5 ile geldi. CTE'deki MATERIALIZED (PG12+), pgstatindex'in B-tree olmayan index'lerde çağrılıp hata vermesini önler.","tags":["bloat","pgstattuple","pgstatindex","index bloat","dead tuple","boş alan"]},{"id":"pg-repack-online","task":"Bloat'lı tabloyu uzun süre kilitlemeden yeniden düzenle (pg_repack)","category":"Bakım","command":"-- Hedef veritabanında bir kez (sunucuda pg_repack package'ı kurulu olmalı)\nCREATE EXTENSION pg_repack;\n\n# Kuru çalıştırma: ne yapılacağını göster\npg_repack -h localhost -U postgres -d veritabani --table=public.siparis --dry-run\n\n# Tabloyu ve index'lerini yeniden yaz: 2 paralel index build, lock için en fazla 60 sn bekle\npg_repack -h localhost -U postgres -d veritabani --table=public.siparis --jobs=2 --wait-timeout=60 --no-kill-backend\n\n# Yalnızca index'leri yeniden oluştur\npg_repack -h localhost -U postgres -d veritabani --table=public.siparis --only-indexes","what":"Tablonun sıkıştırılmış kopyasını arka planda oluşturur, bu sırada gelen değişiklikleri trigger ile log tablosuna yakalar ve sonunda kısa bir ACCESS EXCLUSIVE lock ile tabloları yer değiştirir; VACUUM FULL'ün aksine işlem boyunca okuma/yazmayı bloklamaz.","when":"VACUUM'un geri veremediği ciddi bloat'ı (pgstattuple ile doğrulanmış) canlı sistemde diske geri kazandırmak gerektiğinde.","caution":"Tabloda PRIMARY KEY veya NOT NULL kolonlu bir UNIQUE index olmalıdır. Geçici olarak tablo + index'leri kadar ek disk alanı gerekir ve yoğun WAL üretir (replica gecikmesi, arşiv hacmi). Başlangıçta ve sonda ACCESS EXCLUSIVE lock gerekir; --wait-timeout dolunca varsayılan davranış çakışan sorguları iptal edip gerekirse oturumları sonlandırmaktır, --no-kill-backend bunun yerine tabloyu atlar. İşlem sürerken hedef tabloda DDL çalıştırma. İstemci ve eklenti sürümleri aynı olmalıdır. Yarıda kesilirse kalıntıları DROP EXTENSION pg_repack CASCADE; CREATE EXTENSION pg_repack; ile temizle.","note":"pg_repack core PostgreSQL'in parçası değildir (ayrı package, örn. postgresql-17-repack).","tags":["pg_repack","bloat","online","vacuum full alternatifi","tablo yeniden düzenleme","repack"]},{"id":"invalid-indexes","task":"Geçersiz (INVALID) index'leri bul ve temizle","category":"Bakım","command":"SELECT n.nspname AS schema_name,\n       c.relname AS index_name,\n       t.relname AS table_name,\n       pg_size_pretty(pg_relation_size(c.oid)) AS index_size,\n       i.indisvalid,\n       i.indisready,\n       format('DROP INDEX CONCURRENTLY %I.%I;', n.nspname, c.relname) AS fix\nFROM pg_index i\nJOIN pg_class c ON c.oid = i.indexrelid\nJOIN pg_class t ON t.oid = i.indrelid\nJOIN pg_namespace n ON n.oid = c.relnamespace\nWHERE NOT i.indisvalid OR NOT i.indisready;\n\n-- Silmeden önce: devam eden bir index build var mı?\nSELECT pid, relid::regclass AS table_name, index_relid::regclass AS index_name, command, phase\nFROM pg_stat_progress_create_index;","what":"CREATE INDEX CONCURRENTLY veya REINDEX CONCURRENTLY yarıda kalınca geride kalan geçersiz index'leri boyutlarıyla listeler ve silme komutunu üretir.","when":"Başarısız veya iptal edilmiş online index işlemlerinden sonra, düzenli sağlık kontrolünde ve major upgrade öncesinde.","caution":"Hâlâ devam eden bir CREATE INDEX CONCURRENTLY / REINDEX CONCURRENTLY de o anda INVALID görünür; silmeden önce pg_stat_progress_create_index'i kontrol et. INVALID index sorgularda kullanılmaz ama indisready = true ise her INSERT/UPDATE'te güncellenmeye devam eder, yani yalnızca yük getirir. Yeniden oluşturmak için REINDEX INDEX CONCURRENTLY kullanılabilir; ancak hata sebebi (örn. unique ihlali) giderilmediyse tekrar başarısız olur. REINDEX CONCURRENTLY kalıntıları _ccnew/_ccold sonekini taşır. DROP INDEX CONCURRENTLY transaction bloğu içinde çalışmaz.","tags":["invalid index","indisvalid","create index concurrently","geçersiz index","_ccnew","index"]},{"id":"extended-statistics","task":"Birbirine bağımlı kolonlar için extended statistics oluştur (CREATE STATISTICS)","category":"Bakım","command":"-- il ve ilce bağımlı: planner bağımsız varsayıp satır sayısını çok düşük tahmin eder\nCREATE STATISTICS musteri_il_ilce_stx (dependencies, ndistinct, mcv) ON il, ilce FROM musteri;\nANALYZE musteri;\n\n-- Toplanan istatistik\nSELECT statistics_name, attnames, kinds, n_distinct, dependencies\nFROM pg_stats_ext\nWHERE tablename = 'musteri';\n\n-- Doğrula: tahmini rows artık actual rows'a yakın olmalı\nEXPLAIN (ANALYZE, TIMING OFF)\nSELECT * FROM musteri WHERE il = 'Ankara' AND ilce = 'Cankaya';","what":"Planner'a kolonlar arası bağımlılığı (fonksiyonel bağımlılık, kombinasyon distinct sayısı, ortak en sık değerler) öğretir; çok kolonlu WHERE ve GROUP BY koşullarında satır tahminini düzeltir.","when":"EXPLAIN ANALYZE'da çok kolonlu filtrelerde tahmini satır sayısı gerçeğin çok altındaysa (ör. 12'ye karşı 570) ve bu yüzden yanlış join yöntemi/index seçiliyorsa.","caution":"Etkisi ancak ANALYZE sonrası başlar. Kolon kombinasyonu sayısı istatistik hedefinden (varsayılan 100) çok fazlaysa mcv listesi kombinasyonların çoğunu kapsayamaz; bu durumda mcv, dependencies'in düzelteceği tahmini düzeltmeyebilir. EXPLAIN ile doğrula; gerekirse mcv'yi tanımdan çıkar veya ALTER STATISTICS musteri_il_ilce_stx SET STATISTICS 1000; ile hedefi yükselt. dependencies yalnızca eşitlik/IN koşullarında, ndistinct GROUP BY tahmininde kullanılır. Her tanım ANALYZE süresini uzatır; yalnızca yanlış tahmini kanıtlanmış kolon gruplarına ekle.","since":"PostgreSQL 12","note":"CREATE STATISTICS PG10 (ndistinct, dependencies), mcv türü PG12, ALTER STATISTICS ... SET STATISTICS PG13, ifade (expression) istatistikleri PG14 ile geldi.","tags":["extended statistics","create statistics","korelasyon","satır tahmini","cardinality","analyze"]},{"id":"analyze-staleness","task":"İstatistikleri bayatlamış tabloları bul (ANALYZE stratejisi)","category":"Bakım","command":"SELECT schemaname,\n       relname AS table_name,\n       n_live_tup,\n       n_mod_since_analyze,\n       round(100.0 * n_mod_since_analyze / NULLIF(n_live_tup, 0), 1) AS mod_pct,\n       greatest(last_analyze, last_autoanalyze) AS last_analyzed,\n       round(current_setting('autovacuum_analyze_threshold')::int\n             + current_setting('autovacuum_analyze_scale_factor')::numeric * n_live_tup) AS autoanalyze_at\nFROM pg_stat_user_tables\nWHERE n_mod_since_analyze > 0\nORDER BY mod_pct DESC NULLS LAST\nLIMIT 20;\n\n-- Toplu yükleme sonrası autovacuum'u beklemeden\nANALYZE (VERBOSE) siparis;","what":"Son ANALYZE'dan bu yana değişen satır sayısını, canlı satıra oranını ve autovacuum'un ANALYZE'ı tetikleyeceği yaklaşık değişiklik eşiğini gösterir.","when":"Toplu yükleme/silme sonrası, yanlış satır tahminli planlar görüldüğünde veya autoanalyze'ın büyük tablolarda geç kaldığından şüphelenildiğinde.","caution":"Hesaplanan eşik global ayarlara göredir; tabloya özel autovacuum_analyze_* reloptions tanımlıysa (pg_class.reloptions) gerçek eşik farklıdır. Büyük tablolarda varsayılan scale_factor (0.1) çok geç tetikler; tablo bazında düşür. Partitioned tabloların parent'ı autovacuum tarafından ANALYZE edilmez; parent düzeyi istatistik için elle ANALYZE gerekir. Temp tablolar autovacuum görmez. ANALYZE örneklem okur ve ShareUpdateExclusiveLock alır (DML'i bloklamaz).","tags":["analyze","bayat istatistik","n_mod_since_analyze","autoanalyze","istatistik","planner"]},{"id":"visibility-map-index-only","task":"Visibility map durumunu ve Index Only Scan verimini kontrol et","category":"Bakım","command":"-- all-visible sayfa oranı düşük tablolar: Index Only Scan heap'e gitmek zorunda kalır\nSELECT c.oid::regclass AS table_name,\n       c.relpages,\n       c.relallvisible,\n       round(100.0 * c.relallvisible / NULLIF(c.relpages, 0), 1) AS all_visible_pct,\n       pg_size_pretty(pg_relation_size(c.oid)) AS heap_size,\n       s.n_ins_since_vacuum,\n       s.last_autovacuum\nFROM pg_class c\nJOIN pg_stat_user_tables s ON s.relid = c.oid\nWHERE c.relpages > 1000\nORDER BY all_visible_pct NULLS FIRST\nLIMIT 20;\n\n-- Planda \"Heap Fetches\" döndürülen satıra yakınsa visibility map güncel değildir\nEXPLAIN (ANALYZE, BUFFERS) SELECT id FROM musteri WHERE id BETWEEN 1 AND 50000;\n\n-- Kesin sayım (pg_visibility eklentisi)\nCREATE EXTENSION IF NOT EXISTS pg_visibility;\nSELECT * FROM pg_visibility_map_summary('musteri');","what":"Tabloların all-visible sayfa oranını, son vacuum'dan bu yana eklenen satırları ve Index Only Scan'in heap'e kaç kez gitmek zorunda kaldığını (Heap Fetches) gösterir.","when":"Index Only Scan beklenen performansı vermiyorsa; insert ağırlıklı/append-only tablolarda ve covering (INCLUDE) index tasarımını doğrularken.","caution":"relpages/relallvisible son VACUUM/ANALYZE'ın kaydettiği tahminlerdir. Visibility map bitlerini yalnızca VACUUM set eder; her UPDATE/DELETE ilgili sayfanın bitini temizler. Sık güncellenen tablolarda düşük oran için autovacuum_vacuum_scale_factor'ü tablo bazında düşür. pg_visibility_map_summary küçük olan VM dosyasını okur, heap'i taramaz.","since":"PostgreSQL 13","note":"n_ins_since_vacuum ve insert tetiklemeli autovacuum (autovacuum_vacuum_insert_threshold/scale_factor) PG13 ile geldi; öncesinde append-only tablolar wraparound vacuum'una kadar hiç vacuum görmeyebilir ve visibility map set edilmez.","tags":["visibility map","index only scan","heap fetches","relallvisible","pg_visibility","vacuum"]},{"id":"range-partition-monthly","task":"Aylık range partition'lı tablo oluştur (partition'ları döngüyle üret)","category":"Partition","command":"CREATE TABLE satislar (\n  id         bigint GENERATED ALWAYS AS IDENTITY,\n  tarih      date   NOT NULL,\n  musteri_id bigint NOT NULL,\n  tutar      numeric(12,2),\n  PRIMARY KEY (id, tarih)\n) PARTITION BY RANGE (tarih);\n\n-- Parent'ta tanımlanan index tüm partition'lara otomatik yayılır\nCREATE INDEX satislar_musteri_id_idx ON satislar (musteri_id);\n\n-- 2026 yılı için 12 aylık partition\nDO $$\nDECLARE\n  m date;\nBEGIN\n  FOR m IN SELECT generate_series(date '2026-01-01', date '2026-12-01', interval '1 month')::date LOOP\n    EXECUTE format(\n      'CREATE TABLE IF NOT EXISTS %I PARTITION OF satislar FOR VALUES FROM (%L) TO (%L)',\n      'satislar_' || to_char(m, 'YYYY_MM'), m, (m + interval '1 month')::date);\n  END LOOP;\nEND $$;\n\n-- Hiyerarşi, sınırlar ve boyutlar\nSELECT t.relid::regclass AS partition_name,\n       t.parentrelid::regclass AS parent,\n       t.isleaf,\n       t.level,\n       pg_get_expr(c.relpartbound, c.oid) AS bounds,\n       pg_size_pretty(pg_total_relation_size(t.relid)) AS total_size\nFROM pg_partition_tree('satislar') t\nJOIN pg_class c ON c.oid = t.relid\nORDER BY t.level, bounds;","what":"Tarih kolonuna göre RANGE partition'lı ana tabloyu, tüm partition'lara otomatik yayılan index'i ve döngüyle 12 aylık partition'ı oluşturur; ardından hiyerarşiyi sınırları ve boyutlarıyla listeler.","when":"Sürekli büyüyen, eski veriyi dönemsel olarak silen (DETACH/DROP) veya sorguları çoğunlukla tarih aralığıyla filtrelenen büyük tablolarda (sipariş, log, zaman serisi).","caution":"Partition'lı tabloda PRIMARY KEY/UNIQUE constraint'i partition anahtarını içermek zorundadır (global unique index yoktur). Alt sınır dahil, üst sınır hariçtir (FROM dahil, TO hariç). Gelecek dönemlerin partition'larını önceden oluşturan bir iş (pg_cron, pg_partman) kurulmazsa aralık dışı INSERT hata verir. Binlerce partition planlama süresini ve lock yükünü artırır. Parent'ta CREATE INDEX CONCURRENTLY desteklenmez: parent'ta CREATE INDEX ... ON ONLY, her partition'da CREATE INDEX CONCURRENTLY, ardından ALTER INDEX ... ATTACH PARTITION kullan.","since":"PostgreSQL 12","note":"Declarative partitioning PG10, parent'ta index/PRIMARY KEY ve default partition PG11, pg_partition_tree() PG12 ile geldi.","tags":["partition","range partition","declarative partitioning","aylık partition","pg_partition_tree","partitioning"]},{"id":"attach-partition-safely","task":"Hazırlanmış tabloyu partition olarak kısa lock ile ekle (ATTACH PARTITION)","category":"Partition","command":"-- 1) Veriyi canlı tabloyu etkilemeden ayrı tabloya hazırla\nCREATE TABLE satislar_2027_01 (LIKE satislar INCLUDING DEFAULTS INCLUDING CONSTRAINTS);\n-- ... toplu yükleme (COPY / INSERT) ...\nALTER TABLE satislar_2027_01 ADD PRIMARY KEY (id, tarih);\nCREATE INDEX CONCURRENTLY satislar_2027_01_musteri_id_idx ON satislar_2027_01 (musteri_id);\n\n-- 2) Sınırla birebir eşleşen CHECK: ATTACH sırasında tam tablo taramasını önler\nALTER TABLE satislar_2027_01 ADD CONSTRAINT satislar_2027_01_bound_chk\n  CHECK (tarih IS NOT NULL AND tarih >= DATE '2027-01-01' AND tarih < DATE '2027-02-01') NOT VALID;\nALTER TABLE satislar_2027_01 VALIDATE CONSTRAINT satislar_2027_01_bound_chk;\n\n-- 3) Ekle (parent'ta SHARE UPDATE EXCLUSIVE; okuma/yazma devam eder)\nSET lock_timeout = '5s';\nALTER TABLE satislar ATTACH PARTITION satislar_2027_01\n  FOR VALUES FROM ('2027-01-01') TO ('2027-02-01');\nRESET lock_timeout;\n\n-- 4) Artık gereksiz olan CHECK'i kaldır\nALTER TABLE satislar_2027_01 DROP CONSTRAINT satislar_2027_01_bound_chk;","what":"Ayrı tabloya yüklenmiş veriyi, sınırla eşleşen önceden doğrulanmış CHECK constraint'i ve hazır index'lerle tam tablo taraması ve uzun lock olmadan partition'a dönüştürür.","when":"Toplu veri yüklemede (ETL) veya arşivden geri getirmede, veriyi canlı tabloyu etkilemeden hazırlayıp tek adımda devreye almak için.","caution":"ATTACH parent üzerinde SHARE UPDATE EXCLUSIVE, eklenen tabloda ACCESS EXCLUSIVE lock alır. Eşleşen geçerli bir CHECK yoksa sınır doğrulaması için tablo bu lock altında baştan sona taranır; parent'taki index'lerin karşılığı yoksa ATTACH onları lock altında oluşturur, ikisini de önceden hazırla. Default partition varsa yeni aralıkta satır içermediği de taranarak doğrulanır (bkz. default partition reçetesi). Kolon adları ve tipleri parent ile birebir aynı olmalıdır; LIKE ... INCLUDING ile oluşturmak en güvenlisidir.","since":"PostgreSQL 12","note":"ATTACH PARTITION'ın parent'ta SHARE UPDATE EXCLUSIVE ile yetinmesi PG12'de geldi; PG11 ve öncesinde parent ACCESS EXCLUSIVE ile kilitlenir.","tags":["attach partition","partition ekle","check constraint","not valid","etl","partitioning"]},{"id":"detach-partition-concurrently","task":"Eski partition'ı canlı trafiği bloklamadan ayır (DETACH CONCURRENTLY)","category":"Partition","command":"-- Transaction bloğu dışında çalıştırılmalıdır\nALTER TABLE satislar DETACH PARTITION satislar_2026_01 CONCURRENTLY;\n\n-- Kesintiye uğradıysa (iptal, bağlantı kopması) partition 'detach pending' kalır; tamamla:\nALTER TABLE satislar DETACH PARTITION satislar_2026_01 FINALIZE;\n\n-- Bekleyen detach var mı?\nSELECT inhrelid::regclass AS partition_name, inhparent::regclass AS parent\nFROM pg_inherits\nWHERE inhdetachpending;\n\n-- Ayrılan tablo artık bağımsızdır: arşivle veya sil\nDROP TABLE satislar_2026_01;","what":"Partition'ı iki transaction'da ayırır; parent üzerinde yalnızca SHARE UPDATE EXCLUSIVE alarak çalışan sorguları bloklamaz ve ayrılan tabloya partition sınırına eşdeğer bir CHECK constraint'i ekler.","when":"Retention/arşivleme için eski dönemleri canlı sistemde ayırırken (ardından DROP, başka tablespace'e taşıma veya pg_dump ile arşiv).","caution":"BEGIN ... COMMIT bloğu içinde çalıştırılamaz ve parent'ta default partition varsa kullanılamaz. Parent'ı kullanan ve işlemden önce başlamış tüm transaction'ların bitmesini bekler; uzun transaction'lar işlemi uzatır. Kesintiye uğrarsa partition sorgulardan gizlenmiş ama ayrılmamış ('detach pending') kalır ve FINALIZE ile tamamlanmalıdır. CONCURRENTLY'siz klasik DETACH daha hızlıdır ama parent'ta ACCESS EXCLUSIVE ister; onu lock_timeout ile dene.","since":"PostgreSQL 14","tags":["detach partition","concurrently","finalize","retention","arşivleme","partitioning"]},{"id":"default-partition-pitfall","task":"Default partition tuzağı: yeni partition 'would be violated by some row' hatası verirse","category":"Partition","command":"-- Default partition'a hangi dönemlerden satır düşmüş?\nSELECT date_trunc('month', tarih)::date AS month, count(*) AS row_count\nFROM satislar_default\nGROUP BY 1\nORDER BY 1;\n\n-- Satırları yeni partition'a taşı ve tek transaction'da ekle\nBEGIN;\nSET LOCAL lock_timeout = '5s';\nLOCK TABLE satislar_default IN ACCESS EXCLUSIVE MODE;\nCREATE TABLE satislar_2027_02 (LIKE satislar INCLUDING DEFAULTS INCLUDING CONSTRAINTS);\nWITH moved AS (\n  DELETE FROM satislar_default\n  WHERE tarih >= DATE '2027-02-01' AND tarih < DATE '2027-03-01'\n  RETURNING *\n)\nINSERT INTO satislar_2027_02 SELECT * FROM moved;\nALTER TABLE satislar ATTACH PARTITION satislar_2027_02\n  FOR VALUES FROM ('2027-02-01') TO ('2027-03-01');\nCOMMIT;","what":"Default partition'a düşmüş satırları dönem bazında sayar; yeni partition'ın aralığına giren satırları aynı transaction içinde yeni tabloya taşıyıp tabloyu partition olarak ekler.","when":"CREATE TABLE ... PARTITION OF veya ATTACH 'updated partition constraint for default partition would be violated by some row' hatası verdiğinde ya da default partition'ın şiştiği fark edildiğinde.","caution":"Default partition varken her yeni partition eklemesi default'u tamamen tarar ve bu sürede default üzerinde ACCESS EXCLUSIVE tutar; büyük bir default partition her bakımda kesinti demektir. Taşıma sırasında default yazmaya kapalıdır; işlemi düşük trafikte yap. Kalıcı çözüm: partition'ları önceden oluştur, default'u boş kalacak şekilde izle (satır sayısı > 0 alarmı) ya da hiç kullanma; o zaman aralık dışı INSERT hata verir ve sorun erken görünür. Default partition ayrıca DETACH ... CONCURRENTLY kullanımını engeller.","since":"PostgreSQL 11","tags":["default partition","partition hatası","violated by some row","partition constraint","tuzak","partitioning"]},{"id":"partition-pruning-check","task":"Partition pruning'in (planlama ve çalışma zamanı) gerçekten çalıştığını doğrula","category":"Partition","command":"SHOW enable_partition_pruning;\n\n-- Planlama zamanı pruning: planda yalnızca ilgili partition görünmeli\nEXPLAIN (COSTS OFF)\nSELECT count(*) FROM satislar WHERE tarih >= DATE '2026-03-01' AND tarih < DATE '2026-04-01';\n\n-- Çalışma zamanı pruning: generic plan / parametreli sorgu, \"Subplans Removed: N\"\nPREPARE q_satis(date) AS SELECT count(*) FROM satislar WHERE tarih = $1;\nSET plan_cache_mode = force_generic_plan;\nEXPLAIN (ANALYZE, COSTS OFF, TIMING OFF) EXECUTE q_satis('2026-03-15');\nRESET plan_cache_mode;\nDEALLOCATE q_satis;\n\n-- Pruning'i bozan yazım: anahtar kolona fonksiyon uygulamak tüm partition'ları taratır\nEXPLAIN (COSTS OFF)\nSELECT count(*) FROM satislar WHERE date_trunc('month', tarih) = DATE '2026-03-01';","what":"Planlama zamanı pruning'i, generic plan ile çalışma zamanı pruning'ini ('Subplans Removed: N') ve partition anahtarına fonksiyon uygulandığında pruning'in nasıl kaybolduğunu karşılaştırmalı gösterir.","when":"Partition'lı tabloda sorgular beklenenden yavaşsa, planda tüm partition'lar taranıyorsa veya ORM/prepared statement kullanan uygulamalarda.","caution":"Partition anahtarına fonksiyon veya tip dönüşümü uygulamak (date_trunc(tarih), tarih::text) pruning'i devre dışı bırakır; koşulu anahtar üzerinde aralık olarak yaz. Generic planda pruning yürütme başında yapılır ve yalnızca 'Subplans Removed' satırıyla görünür; now() gibi STABLE ifadelerde ANALYZE'sız EXPLAIN'de de görünür. enable_partition_pruning = off ise hiç pruning yapılmaz. Çok sayıda partition'da Planning Time'ı da ölç.","since":"PostgreSQL 12","note":"Çalışma zamanı pruning'i PG11 ile geldi; plan_cache_mode PG12 ile geldi ve PG12 çok sayıda partition'da planlama performansını büyük ölçüde iyileştirdi.","tags":["partition pruning","subplans removed","generic plan","plan_cache_mode","explain","partitioning"]},{"id":"pg-partman-setup","task":"pg_partman ile partition oluşturma ve retention'ı otomatikleştir","category":"Partition","command":"CREATE SCHEMA partman;\nCREATE EXTENSION pg_partman SCHEMA partman;\n\nCREATE TABLE public.olcum (\n  id    bigint GENERATED ALWAYS AS IDENTITY,\n  ts    timestamptz NOT NULL,\n  deger numeric,\n  PRIMARY KEY (id, ts)\n) PARTITION BY RANGE (ts);\n\n-- Günlük partition, 7 gün ilerisini önceden oluştur (pg_partman 5.x söz dizimi)\nSELECT partman.create_parent(\n  p_parent_table := 'public.olcum',\n  p_control      := 'ts',\n  p_interval     := '1 day',\n  p_premake      := 7\n);\n\n-- 30 günden eski partition'ları sil\nUPDATE partman.part_config\n   SET retention = '30 days',\n       retention_keep_table = false\n WHERE parent_table = 'public.olcum';\n\n-- Bakım: periyodik çalıştır (pg_cron veya pg_partman_bgw ile zamanla)\nCALL partman.run_maintenance_proc();\n\n-- Default partition'a düşen satır var mı?\nSELECT * FROM partman.check_default(p_exact_count := true);","what":"pg_partman'a bir parent tabloyu kaydeder; gelecek partition'ları önceden oluşturur, retention süresini aşanları siler ve default partition'a düşen satırları raporlar.","when":"Günlük/aylık partition'ları elle veya özel script'le yönetmek yerine standart, izlenebilir bir otomasyon gerektiğinde (log, metrik, olay tabloları).","caution":"pg_partman 4.x ile 5.x arasında API değişti: 5.x'te p_type yalnızca 'range'/'list' alır (varsayılan 'range'), 4.x'teki p_type := 'native' geçersizdir; kurulu sürümü SELECT extversion FROM pg_extension WHERE extname = 'pg_partman'; ile kontrol et. create_parent varsayılan olarak bir default partition da oluşturur. retention_keep_table = false partition'ı kalıcı olarak DROP eder; arşiv gerekiyorsa true bırakıp retention_schema kullan. run_maintenance_proc() zamanlanmazsa yeni partition'lar oluşmaz ve veriler default'a düşer. pg_partman_bgw için shared_preload_libraries + restart gerekir.","note":"pg_partman core PostgreSQL'in parçası değildir (ayrı package, örn. postgresql-17-partman). Komutlar pg_partman 5.x söz dizimidir.","tags":["pg_partman","partition bakımı","retention","create_parent","otomatik partition","partitioning"]},{"id":"least-privilege-roles","task":"En az yetki ilkesiyle rol hiyerarşisi kur (GRANT + ALTER DEFAULT PRIVILEGES)","category":"Güvenlik","command":"-- Grup rolleri (NOLOGIN): nesne sahibi, salt okur, okur-yazar\nCREATE ROLE app_owner NOLOGIN;\nCREATE ROLE app_readonly NOLOGIN;\nCREATE ROLE app_readwrite NOLOGIN;\nGRANT app_readonly TO app_readwrite;\nCREATE SCHEMA app AUTHORIZATION app_owner;\n\n-- PUBLIC'in varsayılan haklarını kıs\nREVOKE ALL ON DATABASE veritabani FROM PUBLIC;\nREVOKE CREATE ON SCHEMA public FROM PUBLIC;\n\n-- Mevcut nesneler\nGRANT CONNECT ON DATABASE veritabani TO app_readonly;\nGRANT USAGE ON SCHEMA app TO app_readonly;\nGRANT SELECT ON ALL TABLES IN SCHEMA app TO app_readonly;\nGRANT INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA app TO app_readwrite;\nGRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA app TO app_readwrite;\n\n-- app_owner'ın İLERİDE oluşturacağı nesneler\nALTER DEFAULT PRIVILEGES FOR ROLE app_owner IN SCHEMA app GRANT SELECT ON TABLES TO app_readonly;\nALTER DEFAULT PRIVILEGES FOR ROLE app_owner IN SCHEMA app GRANT INSERT, UPDATE, DELETE ON TABLES TO app_readwrite;\nALTER DEFAULT PRIVILEGES FOR ROLE app_owner IN SCHEMA app GRANT USAGE, SELECT ON SEQUENCES TO app_readwrite;\n\n-- Giriş yapan kullanıcılar yetkiyi yalnızca grup üyeliğiyle alır\nCREATE ROLE web_app LOGIN PASSWORD 'Degistir#2026' IN ROLE app_readwrite;\nCREATE ROLE report_app LOGIN PASSWORD 'Degistir#2026' IN ROLE app_readonly;\n\n-- Tanımlı default privileges (psql: \\ddp)\nSELECT pg_get_userbyid(d.defaclrole) AS owner_role,\n       n.nspname AS schema_name,\n       d.defaclobjtype AS object_type,\n       d.defaclacl\nFROM pg_default_acl d\nLEFT JOIN pg_namespace n ON n.oid = d.defaclnamespace\nORDER BY 1, 2, 3;","what":"Nesne sahibi, salt okur ve okur-yazar grup rollerinden oluşan bir hiyerarşi kurar; mevcut ve gelecekte oluşturulacak tablo/sequence'lere doğru hakları verir, uygulama kullanıcılarını yalnızca grup üyeliğiyle yetkilendirir.","when":"Yeni uygulama şeması kurarken, superuser veya tablo sahibi olarak bağlanan uygulamaları düzeltirken ve denetim (audit) öncesi yetki sadeleştirmesinde.","caution":"ALTER DEFAULT PRIVILEGES yalnızca FOR ROLE ile belirtilen rolün SONRADAN oluşturduğu nesnelere uygulanır; migration aracı tabloları başka bir kullanıcıyla oluşturursa haklar gelmez, DDL'i SET ROLE app_owner ile çalıştır. GRANT ... ON ALL TABLES yalnızca o an var olan nesneleri kapsar. PG15+ ile oluşturulan veritabanlarında public şemasında CREATE hakkı PUBLIC'e zaten verilmez; eski sürümden yükseltilenlerde REVOKE gerekir. REVOKE ALL ON DATABASE ... FROM PUBLIC, CONNECT ve TEMP haklarını da alır; gereken diğer rollere ayrıca ver. Parolayı komut satırında vermek yerine psql \\password kullan (log ve history'e düşmez).","note":"pg_read_all_data / pg_write_all_data rolleri PG14, rol üyeliğinde INHERIT/SET seçenekleri (GRANT ... WITH INHERIT FALSE) PG16 ile geldi.","tags":["least privilege","rol hiyerarşisi","alter default privileges","grant","yetki","security"]},{"id":"row-level-security","task":"Row-level security ile kiracı (tenant) izolasyonu kur","category":"Güvenlik","command":"ALTER TABLE app.siparis ENABLE ROW LEVEL SECURITY;\n-- Tablo sahibi de politikaya tabi olsun\nALTER TABLE app.siparis FORCE ROW LEVEL SECURITY;\n\nCREATE POLICY siparis_tenant_isolation ON app.siparis\n  FOR ALL\n  TO app_readwrite\n  USING (tenant_id = NULLIF(current_setting('app.tenant_id', true), '')::int)\n  WITH CHECK (tenant_id = NULLIF(current_setting('app.tenant_id', true), '')::int);\n\n-- Uygulama her transaction başında kiracıyı belirler (pooler ile uyumlu)\nBEGIN;\nSET LOCAL app.tenant_id = '42';\nSELECT * FROM app.siparis;\nCOMMIT;\n\n-- Tanımlı politikalar\nSELECT schemaname, tablename, policyname, roles, cmd, qual, with_check\nFROM pg_policies\nWHERE tablename = 'siparis';","what":"Tabloda RLS'i etkinleştirir ve oturum değişkenindeki kiracı kimliğine göre satırları filtreleyen (USING) ve başka kiracıya yazmayı engelleyen (WITH CHECK) bir politika tanımlar.","when":"Çok kiracılı (multi-tenant) uygulamalarda veri izolasyonunu uygulama koduna bırakmadan veritabanında zorlamak için.","caution":"Superuser'lar ve BYPASSRLS özniteliğine sahip roller politikaları her zaman atlar; tablo sahibi yalnızca FORCE ROW LEVEL SECURITY ile tabi olur. RLS açık olup eşleşen politika yoksa sonuç boş döner (hata vermez). current_setting(..., true) değişken tanımsızsa NULL döner; NULLIF, RESET sonrası boş string'in ''::int hatası vermesini önler. Kullanıcı app.tenant_id'yi SET ile değiştirebilir; değeri yalnızca güvenilir uygulama katmanı ayarlamalı, son kullanıcıya SQL erişimi verilmemeli. Pooler (transaction modu) kullanılıyorsa SET yerine SET LOCAL kullan. Politika ifadesindeki tenant_id kolonuna index ekle. RLS'ye tabi bir kullanıcıyla pg_dump hata verir; yedeği BYPASSRLS'li rolle al.","since":"PostgreSQL 9.5","tags":["row level security","rls","create policy","çok kiracılı","tenant izolasyonu","security"]},{"id":"pg-hba-validate-reload","task":"pg_hba.conf kural sırasını doğrula ve güvenle reload et","category":"Güvenlik","command":"-- Dosyanın yeri\nSHOW hba_file;\n\n# Kurallar yukarıdan aşağı okunur ve İLK eşleşen kural uygulanır;\n# özel kurallar genel kurallardan ÖNCE gelmelidir:\n#   hostssl  appdb  web_app  10.10.0.0/16  scram-sha-256\n#   host     all    all      10.10.0.0/16  reject\n#   host     all    all      0.0.0.0/0     scram-sha-256\n\n-- Reload ÖNCESİ doğrula: pg_hba_file_rules diskteki dosyayı okur\nSELECT line_number, type, database, user_name, address, netmask, auth_method, error\nFROM pg_hba_file_rules\nORDER BY line_number;\n\n-- error sütunu boşsa uygula\nSELECT pg_reload_conf();","what":"pg_hba.conf'un yerini, PostgreSQL'in dosyayı nasıl yorumladığını (satır, tip, veritabanı, kullanıcı, adres, yöntem) ve sözdizimi hatalarını reload öncesinde gösterir; ardından yapılandırmayı yeniden yükler.","when":"Yeni istemci ağı/uygulama eklerken, md5'ten scram-sha-256'ya geçişte veya 'no pg_hba.conf entry for host' hatası araştırılırken.","caution":"pg_hba_file_rules dosyanın şu anki halini gösterir, etkin kuralları değil. Herhangi bir satırda error doluysa reload yapılsa bile pg_hba.conf HİÇ yüklenmez ve eski kurallar geçerli kalır (logda 'pg_hba.conf was not reloaded'). Değişiklikler yalnızca yeni bağlantıları etkiler. Sırada önde kalan geniş bir kural (ör. host all all 0.0.0.0/0 trust) arkasındaki tüm kısıtlamaları etkisiz kılar. SSL kapalıyken hostssl satırları eşleşemez ve error sütununda uyarı görünür. View'ı varsayılan olarak yalnızca superuser okuyabilir. Dosyayı root olarak düzenleyen araçların sahipliği değiştirmediğinden emin ol; postgres kullanıcısı okuyamazsa reload başarısız olur.","since":"PostgreSQL 10","note":"pg_hba_file_rules PG10 ile geldi; yeni sürümlerde rule_number ve file_name sütunları da vardır. PG16'da pg_hba.conf'ta include direktifleri ve kullanıcı/veritabanı alanlarında regex eşleşmesi desteklenir.","tags":["pg_hba.conf","kimlik doğrulama","kural sırası","reload","pg_hba_file_rules","security"]},{"id":"ssl-enable-verify","task":"SSL/TLS'i etkinleştir ve şifreli bağlantıları doğrula (pg_stat_ssl)","category":"Güvenlik","command":"# Sunucu sertifikası (test için self-signed; üretimde kurumsal CA kullan)\nopenssl req -new -x509 -days 365 -nodes -subj \"/CN=db.example.com\" -keyout server.key -out server.crt\nchmod 600 server.key    # data dizininde, sahibi postgres\n\n-- SSL'i aç (reload yeterli)\nALTER SYSTEM SET ssl = on;\nALTER SYSTEM SET ssl_cert_file = 'server.crt';\nALTER SYSTEM SET ssl_key_file = 'server.key';\nALTER SYSTEM SET ssl_min_protocol_version = 'TLSv1.2';\nSELECT pg_reload_conf();\n\n-- Hangi bağlantılar şifreli?\nSELECT a.pid, a.usename, a.client_addr, a.application_name,\n       s.ssl, s.version, s.cipher, s.bits\nFROM pg_stat_ssl s\nJOIN pg_stat_activity a USING (pid)\nWHERE a.backend_type = 'client backend'\nORDER BY s.ssl, a.usename;\n\n# İstemcide sunucu kimliğini de doğrula\npsql \"host=db.example.com dbname=postgres user=postgres sslmode=verify-full sslrootcert=root.crt\"","what":"Sunucu sertifikasıyla TLS'i restart gerektirmeden açar, minimum protokol sürümünü belirler ve mevcut bağlantıların şifreli olup olmadığını, TLS sürümü ve cipher bilgisiyle listeler.","when":"Güvenlik denetimi/uyumluluk (PCI, KVKK/GDPR) gereksinimlerinde, ağ üzerinden parola ve veri trafiğini korumak için.","caution":"ssl = on tek başına şifrelemeyi zorunlu kılmaz; istemci sslmode=prefer/disable ile şifresiz bağlanabilir. Zorunlu kılmak için pg_hba.conf'ta host yerine hostssl kullan (ve hostnossl ... reject ekle). sslmode=require sunucu kimliğini doğrulamaz (MITM'e açık); sertifika doğrulaması için verify-full kullan. Anahtar dosyası postgres kullanıcısına ait ve 0600 (veya root sahipli 0640) olmalıdır; aksi halde SSL yüklenmez, reload sonrası logu ve SHOW ssl çıktısını kontrol et. Sertifika yenilemesi de reload ile alınır.","since":"PostgreSQL 10","note":"SSL ayarlarının restart olmadan reload ile değiştirilebilmesi PG10, ssl_min_protocol_version PG12 ile geldi; varsayılanı PG13'ten itibaren TLSv1.2'dir.","tags":["ssl","tls","pg_stat_ssl","hostssl","sertifika","şifreleme"]},{"id":"scram-migration","task":"md5 parolalardan scram-sha-256'ya geçiş yap","category":"Güvenlik","command":"-- 1) Yeni parolalar SCRAM ile saklansın\nALTER SYSTEM SET password_encryption = 'scram-sha-256';\nSELECT pg_reload_conf();\n\n-- 2) Hâlâ md5 hash'li parola taşıyan rolleri bul (superuser gerekir)\nSELECT rolname,\n       CASE\n         WHEN rolpassword LIKE 'SCRAM-SHA-256$%' THEN 'scram-sha-256'\n         WHEN rolpassword LIKE 'md5%' THEN 'md5'\n         WHEN rolpassword IS NULL THEN 'no password'\n         ELSE 'other'\n       END AS password_type,\n       rolvaliduntil\nFROM pg_authid\nWHERE rolcanlogin\nORDER BY password_type, rolname;\n\n-- 3) Her md5 rolün parolasını yeniden belirle (psql'de tercihen: \\password legacy_app)\nALTER ROLE legacy_app PASSWORD 'Yeni#Parola2';\n\n# 4) Tüm roller SCRAM olduktan sonra pg_hba.conf'ta md5 -> scram-sha-256 yap ve reload et","what":"Yeni parolaların SCRAM-SHA-256 ile saklanmasını sağlar, hâlâ md5 hash taşıyan login rollerini tespit eder ve parolalar yenilendikten sonra pg_hba.conf'u scram-sha-256'ya geçirme adımlarını verir.","when":"Güvenlik denetiminde md5 bulgusu geldiğinde, PG14+ yükseltmesi sonrası veya md5'in kullanımdan kaldırıldığı sürümlere hazırlanırken.","caution":"Mevcut md5 hash'lerden SCRAM üretilemez; her parola açık haliyle yeniden set edilmelidir (uygulama ekipleriyle koordinasyon gerekir). pg_hba.conf'ta 'md5' yöntemi, parolası SCRAM olan roller için otomatik olarak SCRAM doğrulaması yapar; bu yüzden geçiş boyunca md5 bırakmak güvenli bir ara adımdır, ancak yöntem 'scram-sha-256' yapılınca md5 parolalı roller bağlanamaz. Eski istemci sürücüleri (libpq < 10, eski JDBC/.NET sürücüleri) SCRAM desteklemeyebilir; önce sürücüleri güncelle. ALTER ROLE ... PASSWORD parolayı log_statement ile loga yazabilir; psql \\password parolayı istemci tarafında hash'leyip gönderir.","since":"PostgreSQL 10","note":"SCRAM-SHA-256 PG10 ile geldi, password_encryption varsayılanı PG14'te scram-sha-256 oldu. PG18'de md5 parolalar kullanımdan kaldırıldı (deprecated) ve uyarı üretir.","tags":["scram-sha-256","md5","password_encryption","parola","kimlik doğrulama","security"]},{"id":"pgaudit-object-audit","task":"pgaudit ile rol ve nesne bazlı denetim kaydı (audit) tut","category":"Güvenlik","command":"-- Ön koşul: shared_preload_libraries = 'pgaudit' + restart, ardından:\nCREATE EXTENSION pgaudit;\n\n-- Oturum denetimi: sunucu genelinde yalnızca DDL ve rol/yetki değişiklikleri\nALTER SYSTEM SET pgaudit.log = 'ddl, role';\nALTER SYSTEM SET pgaudit.log_relation = on;\nALTER SYSTEM SET pgaudit.log_parameter = off;\nSELECT pg_reload_conf();\n\n-- Belirli bir uygulama rolünün tüm okuma/yazmaları\nALTER ROLE web_app SET pgaudit.log = 'read, write';\n\n-- Nesne denetimi: denetçi role verilen haklar = loglanacak işlemler\nCREATE ROLE auditor NOLOGIN;\nALTER SYSTEM SET pgaudit.role = 'auditor';\nSELECT pg_reload_conf();\nGRANT SELECT, DELETE ON musteri TO auditor;\nGRANT UPDATE (bakiye) ON musteri TO auditor;","what":"Sunucu genelinde DDL ve yetki değişikliklerini, belirli bir rolün tüm okuma/yazmalarını ve yalnızca denetçi rolüne hak verilmiş hassas tablo/kolonlara erişimi 'AUDIT:' önekli yapılandırılmış log satırları olarak kaydeder.","when":"KVKK/GDPR, PCI-DSS, SOX gibi uyumluluk denetimlerinde hassas veriye kimin eriştiğini kanıtlamak için.","caution":"pgaudit.log = 'all' veya 'read' sunucu genelinde açılırsa log hacmi ve I/O ciddi artar; kapsamı rol veya nesne denetimiyle daralt. Superuser denetimi kapatabilir (ALTER SYSTEM/ALTER ROLE); kayıtları merkezi log sistemine (syslog/SIEM) gönder ve veritabanı sunucusundan bağımsız sakla. log_parameter = on bind parametrelerini (kişisel veri) de loglar. Rol ayarları yeni oturumlarda etkin olur. pgaudit ana sürümü PostgreSQL ana sürümüyle eşleşmelidir (pgaudit 17.x = PG17).","note":"pgaudit core PostgreSQL'in parçası değildir (ayrı package, örn. postgresql-17-pgaudit).","tags":["pgaudit","audit","denetim","object audit","log","security"]},{"id":"memory-settings-check","task":"Bellek parametrelerini değerlendir (shared_buffers, work_mem, maintenance_work_mem)","category":"Parametre","command":"SELECT name,\n       current_setting(name) AS value,\n       source,\n       context\nFROM pg_settings\nWHERE name IN ('shared_buffers', 'effective_cache_size', 'work_mem', 'hash_mem_multiplier',\n               'maintenance_work_mem', 'autovacuum_work_mem', 'max_connections',\n               'max_parallel_workers_per_gather', 'huge_pages', 'temp_buffers', 'wal_buffers')\nORDER BY name;\n\n-- Kaba tavanlar: work_mem x max_connections ve autovacuum bellek tavanı\nSELECT pg_size_pretty(pg_size_bytes(current_setting('work_mem'))\n                      * current_setting('max_connections')::int) AS work_mem_x_max_connections,\n       pg_size_pretty(pg_size_bytes(current_setting('maintenance_work_mem'))\n                      * current_setting('autovacuum_max_workers')::int) AS autovacuum_mem_ceiling;\n\n-- work_mem'e sığmayan işlemlerin izi: veritabanı bazında temp dosyalar\nSELECT datname, temp_files, pg_size_pretty(temp_bytes) AS temp_size, stats_reset\nFROM pg_stat_database\nWHERE datname IS NOT NULL\nORDER BY temp_bytes DESC;","what":"Bellekle ilgili parametrelerin değerini, kaynağını (default/configuration file) ve değişiklik bağlamını (postmaster = restart); work_mem ve autovacuum için kaba bellek tavanlarını ve veritabanı bazında temp dosya hacmini gösterir.","when":"Yeni sunucu kurulumunda, RAM artırımı sonrası, OOM killer olayında veya yoğun temp dosya kullanımı görüldüğünde.","caution":"work_mem bağlantı başına değil, her sort/hash DÜĞÜMÜ başına (hash için ayrıca × hash_mem_multiplier) ve her paralel worker için ayrı ayrılır; karmaşık bir sorgu work_mem'in birkaç katını kullanabilir, bu yüzden hesaplanan çarpım bir üst sınır değil kaba bir uyarıdır. Tipik başlangıç: shared_buffers RAM'in ~%25'i (restart ister), effective_cache_size ~%50-75 (yalnızca planner ipucudur, bellek ayırmaz), maintenance_work_mem 512MB-2GB. autovacuum_work_mem = -1 ise her autovacuum worker maintenance_work_mem kadar kullanabilir. temp_bytes yüksekse work_mem'i global değil rol veya sorgu bazında artır. Büyük shared_buffers ile Linux'ta huge_pages kullanmayı değerlendir.","note":"hash_mem_multiplier PG13 ile geldi (varsayılanı PG15'ten itibaren 2.0).","tags":["shared_buffers","work_mem","maintenance_work_mem","bellek","memory tuning","temp_bytes"]},{"id":"pending-restart-config-errors","task":"Restart bekleyen parametreleri ve yapılandırma dosyası hatalarını gör","category":"Parametre","command":"-- Değiştirilmiş ama restart olmadan etkinleşmeyen parametreler\nSELECT name, setting, unit, context, source, sourcefile, pending_restart\nFROM pg_settings\nWHERE pending_restart;\n\n-- Konfigürasyon dosyalarında uygulanamayan veya hatalı satırlar\nSELECT sourcefile, sourceline, seqno, name, setting, applied, error\nFROM pg_file_settings\nWHERE NOT applied OR error IS NOT NULL\nORDER BY sourcefile, sourceline;\n\n-- Bir parametrenin etkin değeri nereden geliyor?\nSELECT name, setting, source, sourcefile, sourceline\nFROM pg_settings\nWHERE name = 'work_mem';","what":"Dosyada değiştirilmiş ancak restart bekleyen parametreleri, konfigürasyon dosyalarındaki uygulanamamış veya hatalı satırları ve bir parametrenin etkin değerinin hangi dosya/satırdan geldiğini gösterir.","when":"ALTER SYSTEM veya postgresql.conf değişikliği sonrası reload'un beklenen etkiyi gösterip göstermediğini doğrulamak ve planlı restart öncesi bekleyen değişiklikleri listelemek için.","caution":"pg_file_settings dosyaların şu anki halini okur; aynı parametre birden çok yerde tanımlıysa yalnızca sonuncusu applied = true olur (postgresql.auto.conf en son okunduğu için ALTER SYSTEM her zaman kazanır). applied = false ve error boş olan satır, başka bir tanım tarafından gölgelenmiştir; hata değildir. Restart gerektiren bir parametre için error 'setting could not be applied' görünür. Hatalı bir dosya reload'da kısmen uygulanabilir; değişiklikten sonra pg_reload_conf() ardından bu sorguları ve sunucu logunu kontrol et. postgresql.auto.conf'u elle düzenleme; ALTER SYSTEM RESET kullan.","since":"PostgreSQL 9.5","tags":["pending_restart","pg_file_settings","restart","konfigürasyon hatası","alter system","config"]},{"id":"checkpoint-stats","task":"Checkpoint davranışını değerlendir (PG17+ pg_stat_checkpointer, PG16 ve öncesi pg_stat_bgwriter)","category":"Parametre","command":"-- PG17+\nSELECT num_timed,\n       num_requested,\n       round(100.0 * num_requested / NULLIF(num_timed + num_requested, 0), 1) AS req_pct,\n       restartpoints_timed,\n       restartpoints_req,\n       round((write_time / 1000)::numeric / NULLIF(num_timed + num_requested, 0), 1) AS avg_write_s,\n       round((sync_time / 1000)::numeric / NULLIF(num_timed + num_requested, 0), 1) AS avg_sync_s,\n       pg_size_pretty(buffers_written * current_setting('block_size')::bigint) AS written_by_checkpoint,\n       stats_reset\nFROM pg_stat_checkpointer;\n\n-- PG16 ve öncesi\nSELECT checkpoints_timed,\n       checkpoints_req,\n       round(100.0 * checkpoints_req / NULLIF(checkpoints_timed + checkpoints_req, 0), 1) AS req_pct,\n       round((checkpoint_write_time / 1000)::numeric / NULLIF(checkpoints_timed + checkpoints_req, 0), 1) AS avg_write_s,\n       round((checkpoint_sync_time / 1000)::numeric / NULLIF(checkpoints_timed + checkpoints_req, 0), 1) AS avg_sync_s,\n       pg_size_pretty(buffers_checkpoint * current_setting('block_size')::bigint) AS written_by_checkpoint,\n       pg_size_pretty(buffers_clean * current_setting('block_size')::bigint) AS written_by_bgwriter,\n       pg_size_pretty(buffers_backend * current_setting('block_size')::bigint) AS written_by_backends,\n       maxwritten_clean,\n       stats_reset\nFROM pg_stat_bgwriter;\n\n-- İlgili ayarlar\nSELECT name, current_setting(name) AS value\nFROM pg_settings\nWHERE name IN ('checkpoint_timeout', 'max_wal_size', 'min_wal_size',\n               'checkpoint_completion_target', 'log_checkpoints')\nORDER BY name;","what":"Zamanlanmış ve WAL hacmi nedeniyle zorla tetiklenen checkpoint oranını, checkpoint başına ortalama yazma/sync süresini ve yazılan buffer hacmini (PG16 ve öncesinde bgwriter ve backend yazılarıyla birlikte) gösterir.","when":"Yazma yoğun dönemlerde I/O dalgalanması, yüksek WAL üretimi veya loglarda 'checkpoints are occurring too frequently' uyarısı görüldüğünde.","caution":"req_pct yüksekse (genellikle %10-20 üzeri) checkpoint'ler max_wal_size dolduğu için zorla tetikleniyordur; max_wal_size'ı artır ve log_checkpoints = on ile 'checkpoint starting: wal' satırlarını izle. checkpoint_timeout'u uzatmak I/O'yu yayar ama crash recovery süresini uzatır. PG16 ve öncesinde written_by_backends yüksekse backend'ler kirli sayfaları kendileri yazmak zorunda kalıyordur (shared_buffers/bgwriter yetersiz); PG17'de bu bilgi pg_stat_io'dadır. Ortalamalar, yapılacak iş olmadığı için atlanan zamanlanmış checkpoint'leri de paydaya kattığından kabaca yorumlanmalıdır. Sayaçlar stats_reset'ten bu yana kümülatiftir.","since":"PostgreSQL 17","note":"PG17'de checkpointer istatistikleri pg_stat_bgwriter'dan yeni pg_stat_checkpointer view'ına taşındı (checkpoints_timed → num_timed, checkpoints_req → num_requested, buffers_checkpoint → buffers_written); buffers_backend ve buffers_backend_fsync kaldırıldı. PG18'de num_done ve slru_written sütunları eklendi.","tags":["checkpoint","pg_stat_checkpointer","pg_stat_bgwriter","max_wal_size","checkpoint_timeout","wal"]},{"id":"relation-size-breakdown","task":"Tablo boyutunu heap / index / TOAST kırılımıyla ve en büyük index'leri listele","category":"Depolama","command":"SELECT n.nspname AS schema_name,\n       c.relname AS table_name,\n       pg_size_pretty(pg_total_relation_size(c.oid)) AS total,\n       pg_size_pretty(pg_relation_size(c.oid)) AS heap,\n       pg_size_pretty(pg_indexes_size(c.oid)) AS indexes,\n       pg_size_pretty(pg_total_relation_size(c.oid) - pg_relation_size(c.oid) - pg_indexes_size(c.oid)) AS toast_fsm_vm,\n       round(100.0 * pg_total_relation_size(c.oid) / NULLIF(pg_database_size(current_database()), 0), 1) AS pct_of_db\nFROM pg_class c\nJOIN pg_namespace n ON n.oid = c.relnamespace\nWHERE c.relkind IN ('r', 'm')\n  AND n.nspname NOT IN ('pg_catalog', 'information_schema')\nORDER BY pg_total_relation_size(c.oid) DESC\nLIMIT 20;\n\n-- En büyük index'ler ve kullanım sayıları\nSELECT s.schemaname,\n       s.relname AS table_name,\n       s.indexrelname AS index_name,\n       pg_size_pretty(pg_relation_size(s.indexrelid)) AS index_size,\n       s.idx_scan,\n       i.indisunique,\n       i.indisprimary\nFROM pg_stat_user_indexes s\nJOIN pg_index i ON i.indexrelid = s.indexrelid\nORDER BY pg_relation_size(s.indexrelid) DESC\nLIMIT 20;","what":"En büyük tabloları toplam, heap, index ve TOAST (+FSM/VM) olarak ayrıştırıp veritabanı içindeki yüzdesiyle; en büyük index'leri ise tarama sayısı ve unique/primary bilgisiyle gösterir.","when":"Disk doluluğu artarken büyümenin kaynağını (veri mi, index mi, TOAST mu) bulmak ve kullanılmayan büyük index'leri tespit etmek için.","caution":"Boyut fonksiyonları her ilişki için dosya sistemine erişir; on binlerce tablolu veritabanlarında yavaş olabilir. Partitioned parent (relkind 'p') kendisi 0 bayttır ve bu listeye alınmaz; hiyerarşinin toplamı için: SELECT pg_size_pretty(sum(pg_total_relation_size(relid))) FROM pg_partition_tree('satislar'); idx_scan = 0 olan büyük index'ler silme adayıdır, ancak sayaçlar son istatistik reset'inden beri ve yalnızca bu sunucu için tutulur (replica'lardaki kullanım görünmez); unique/primary index'ler constraint sağladığı için silinmez.","tags":["tablo boyutu","index boyutu","toast","disk kullanımı","pg_total_relation_size","storage"]},{"id":"extension-update-check","task":"Güncellemesi bekleyen eklentileri bul ve güncelle","category":"Eklenti","command":"SELECT e.extname,\n       e.extversion AS installed,\n       a.default_version AS available,\n       n.nspname AS schema_name,\n       format('ALTER EXTENSION %I UPDATE;', e.extname) AS fix\nFROM pg_extension e\nJOIN pg_available_extensions a ON a.name = e.extname\nJOIN pg_namespace n ON n.oid = e.extnamespace\nWHERE e.extversion IS DISTINCT FROM a.default_version\nORDER BY e.extname;\n\n-- Güncelleme yolu var mı?\nSELECT * FROM pg_extension_update_paths('pgstattuple') WHERE path IS NOT NULL;\n\nALTER EXTENSION pgstattuple UPDATE;","what":"Her eklentinin veritabanındaki kurulu sürümünü, sunucuda yüklü package'ın varsayılan sürümüyle karşılaştırır ve güncelleme bekleyenler için ALTER EXTENSION komutunu üretir.","when":"PostgreSQL minor/major yükseltmesinden ve extension package güncellemesinden sonra, periyodik bakımda.","caution":"OS package'ını yükseltmek SQL tarafını otomatik güncellemez; ALTER EXTENSION ... UPDATE her veritabanında ayrı çalıştırılmalıdır (pg_upgrade sonrası özellikle önemli). Güncelleme script'i lock alabilir ve nesneleri değiştirebilir (ör. PostGIS); önce test ortamında dene ve sürüm notlarını oku. Belirli sürüme geçmek için: ALTER EXTENSION pgstattuple UPDATE TO '1.5'; Bazı eklentiler (ör. pg_stat_statements) ayrıca shared library'nin restart ile yeniden yüklenmesini gerektirir.","tags":["alter extension update","eklenti sürümü","extension","pg_available_extensions","upgrade","güncelleme"]},{"id":"pg-stat-io-analysis","task":"pg_stat_io ile I/O'nun kaynağını analiz et (backend tipi, nesne, bağlam)","category":"Eklenti","command":"SELECT backend_type,\n       object,\n       context,\n       reads,\n       pg_size_pretty(reads * op_bytes) AS read_size,\n       writes,\n       pg_size_pretty(writes * op_bytes) AS write_size,\n       extends,\n       hits,\n       round(100.0 * hits / NULLIF(hits + reads, 0), 1) AS hit_pct,\n       evictions,\n       reuses,\n       fsyncs,\n       round(read_time::numeric, 1) AS read_ms,\n       round(write_time::numeric, 1) AS write_ms\nFROM pg_stat_io\nWHERE coalesce(reads, 0) + coalesce(writes, 0) + coalesce(extends, 0) + coalesce(evictions, 0) > 0\nORDER BY coalesce(reads, 0) + coalesce(writes, 0) DESC;\n\n-- Kim yazıyor? İdeal durumda yazıların çoğu checkpointer ve background writer'dandır\nSELECT backend_type,\n       pg_size_pretty(sum(writes * op_bytes)) AS written,\n       round(100.0 * sum(writes) / NULLIF(sum(sum(writes)) OVER (), 0), 1) AS pct_of_writes,\n       sum(fsyncs) AS fsyncs\nFROM pg_stat_io\nWHERE object = 'relation' AND writes > 0\nGROUP BY backend_type\nORDER BY sum(writes) DESC;","what":"Okuma, yazma, extend, eviction ve fsync sayılarını backend tipi (client backend, autovacuum, checkpointer...), nesne (relation/temp relation) ve bağlam (normal, vacuum, bulkread, bulkwrite) bazında; ayrıca yazıların hangi süreç tipinden geldiğini gösterir.","when":"I/O darboğazında yükün sorgulardan mı, autovacuum'dan mı yoksa checkpoint'ten mi geldiğini ayırt etmek ve shared_buffers/bgwriter ayarlarını doğrulamak için.","caution":"pg_stat_io küme geneldir ve son reset'ten beri kümülatiftir; değişimi görmek için iki ölçüm arasındaki farkı al (sıfırlamak için: SELECT pg_stat_reset_shared('io');). read_time/write_time yalnızca track_io_timing = on iken dolar. reads, OS page cache'ten karşılanan okumaları da içerir. client backend writes veya evictions yüksekse backend'ler buffer boşaltmak için kendileri yazıyordur; shared_buffers, bgwriter_lru_maxpages ve checkpoint ayarlarını incele. context = 'vacuum'/'bulkread' satırları ring buffer kullanımıdır; buradaki reuses normaldir.","since":"PostgreSQL 16","note":"pg_stat_io PG16 ile geldi. PG18'de op_bytes sütunu kaldırıldı, read_bytes/write_bytes/extend_bytes eklendi ve WAL I/O'su da bu view'da raporlanır; PG18'de reads * op_bytes yerine read_bytes kullan.","tags":["pg_stat_io","io istatistikleri","evictions","fsync","shared_buffers","io"]}]},"recipes/mysql.json":{"engineId":"mysql","engine":"MySQL / MariaDB","order":3,"recipes":[{"id":"rotate-binlog","task":"Binary log'u döndür (rotate)","category":"Binlog & Log","command":"FLUSH BINARY LOGS;","what":"Mevcut binary log dosyasını kapatıp yeni bir dosyaya geçer.","when":"Yedek öncesi temiz bir binlog başlangıç noktası oluşturmak, dosya boyutunu sınırlamak için.","caution":"Sık rotate çok sayıda küçük binlog dosyası üretir. MariaDB'de de aynı komut geçerlidir; kısaca FLUSH LOGS tüm logları döndürür.","tags":["binlog","rotate","flush","log"]},{"id":"purge-binlog","task":"Eski binary log'ları temizle (PURGE)","category":"Binlog & Log","command":"PURGE BINARY LOGS BEFORE NOW() - INTERVAL 7 DAY;","what":"Belirtilen tarihten eski binary log dosyalarını diskten siler.","when":"Binlog'lar disk doldururken, artık gerekmeyen eski logları temizlemek için.","caution":"Bir replika hâlâ silinecek binlog'a ihtiyaç duyuyorsa replikasyon bozulur; önce SHOW REPLICA STATUS ile tüm replikaların ilerlediğini doğrula. Belirli dosyaya kadar silmek için: PURGE BINARY LOGS TO 'mysql-bin.000123'; Otomatik temizlik için binlog_expire_logs_seconds ayarını kullan.","tags":["binlog","purge","cleanup","log"]},{"id":"show-binlogs","task":"Binary log durumunu gör","category":"Binlog & Log","command":"SHOW BINARY LOGS;","what":"Sunucudaki tüm binary log dosyalarını ve boyutlarını listeler.","when":"Binlog disk kullanımını, hangi dosyaların mevcut olduğunu görmek için.","caution":"O an yazılan binlog dosyası ve pozisyon için: SHOW BINARY LOG STATUS; (MySQL 8.2+). Eski sürümlerde SHOW MASTER STATUS kullanılır (8.2–8.3'te deprecated, 8.4'te kaldırıldı).","tags":["binlog","status","show","log"]},{"id":"enable-general-slow-log","task":"Genel ve slow query log'u aç","category":"Binlog & Log","command":"SET GLOBAL slow_query_log = 'ON'; SET GLOBAL long_query_time = 1; SET GLOBAL general_log = 'ON';","what":"Slow query log'u (1 saniyeden uzun sorgular) ve tüm sorguları kaydeden general log'u çalışırken açar.","when":"Yavaş sorguları veya tüm sorgu trafiğini geçici olarak analiz etmek için.","caution":"general_log ciddi performans ve disk yükü getirir; teşhis bitince mutlaka kapat (SET GLOBAL general_log='OFF'). Bu ayarlar restart'ta sıfırlanır; kalıcı için SET PERSIST kullan.","tags":["slow-log","general-log","log","diagnostics"]},{"id":"innodb-redo-capacity","task":"InnoDB redo log boyutunu değiştir","category":"Depolama","command":"SET GLOBAL innodb_redo_log_capacity = 2147483648;","what":"InnoDB redo log toplam kapasitesini (bayt cinsinden, burada 2 GB) çalışırken dinamik olarak ayarlar.","when":"Yazma yoğun iş yükünde checkpoint sıklığını azaltıp performansı artırmak için.","caution":"innodb_redo_log_capacity MySQL 8.0.30+ ile gelir ve eski innodb_log_file_size + innodb_log_files_in_group ayarlarının yerini alır. Eski sürümde/MariaDB'de innodb_log_file_size my.cnf'te değiştirilip restart gerektirir. Kalıcı için: SET PERSIST innodb_redo_log_capacity = 2147483648;","since":"MySQL 8.0.30","note":"innodb_redo_log_capacity MySQL 8.0.30 ile geldi ve redo log'un dinamik (restart'sız) yeniden boyutlandırılmasını sağladı; öncesinde innodb_log_file_size + innodb_log_files_in_group ayarlanıp sunucu restart edilirdi.","tags":["innodb","redo-log","capacity","storage"]},{"id":"innodb-undo-tablespace","task":"InnoDB undo tablespace ekle / yönet","category":"Depolama","command":"CREATE UNDO TABLESPACE undo_003 ADD DATAFILE 'undo_003.ibu';","what":"Yeni bir InnoDB undo tablespace oluşturur; undo log'ları veri dosyalarından ayrı yönetilir ve truncate edilebilir hale gelir.","when":"Uzun süren transaction'lar undo log'u şişirdiğinde alanı yönetmek, undo'yu ayrı diske almak için.","caution":"Dosya adı .ibu ile bitmeli. Bir undo tablespace'i silmeden önce pasife almak gerekir: ALTER UNDO TABLESPACE undo_003 SET INACTIVE; sonra DROP UNDO TABLESPACE undo_003; MySQL 8.0+ özelliğidir.","since":"MySQL 8.0","note":"SQL ile undo tablespace oluşturma/silme (CREATE/DROP UNDO TABLESPACE) MySQL 8.0 ile geldi; öncesinde undo tablespace sayısı innodb_undo_tablespaces ile sabitti ve çalışırken yönetilemezdi.","tags":["innodb","undo-log","tablespace","storage"]},{"id":"create-tablespace","task":"Genel tablespace (general tablespace) ekle","category":"Depolama","command":"CREATE TABLESPACE ssd_ts ADD DATAFILE 'ssd_ts.ibd' ENGINE=InnoDB;","what":"Birden çok tablonun paylaşabileceği bir InnoDB genel tablespace oluşturur.","when":"Tabloları belirli bir dosyada/diskte gruplamak, dosya sayısını azaltmak için.","caution":"DATAFILE yolu göreliyse datadir altına yazılır; farklı diske almak için mutlak yol ve gerekli izinler gerekir. Tabloyu buraya almak için: ALTER TABLE musteri TABLESPACE ssd_ts; Tablespace ancak içi boşken DROP edilebilir.","tags":["tablespace","innodb","storage","create"]},{"id":"optimize-table","task":"Tabloyu OPTIMIZE et","category":"Depolama","command":"OPTIMIZE TABLE musteri;","what":"Tabloyu yeniden oluşturarak fragmentasyonu giderir, kullanılmayan alanı geri kazanır ve index istatistiklerini günceller.","when":"Çok sayıda DELETE/UPDATE sonrası şişen InnoDB tablosunda alan geri kazanmak için.","caution":"InnoDB'de OPTIMIZE aslında tabloyu yeniden inşa eden online ALTER olarak çalışır ancak yine de I/O ve geçici disk alanı gerektirir; büyük tablolarda tablo boyutu kadar boş disk gerekir. Kilitlenmeyi azaltmak için düşük trafikte çalıştır.","tags":["optimize","table","defragment","storage"]},{"id":"table-schema-size","task":"Tablo ve şema boyutunu sorgula","category":"Depolama","command":"SELECT table_schema AS sema, table_name AS tablo, ROUND((data_length + index_length) / 1024 / 1024, 1) AS boyut_mb FROM information_schema.tables WHERE table_schema NOT IN ('mysql','information_schema','performance_schema','sys') ORDER BY (data_length + index_length) DESC LIMIT 20;","what":"En büyük 20 tabloyu, veri ve index boyutları toplamıyla (MB) listeler.","when":"Disk kullanımını analiz etmek, hangi tabloların yer kapladığını bulmak için.","caution":"information_schema boyutları InnoDB'de yaklaşık değerlerdir. Şema bazında toplam için table_name yerine sadece table_schema ile GROUP BY yap.","tags":["size","table","schema","information-schema"]},{"id":"analyze-table","task":"Tablo istatistiklerini güncelle (ANALYZE TABLE)","category":"Bakım","command":"ANALYZE TABLE musteri;","what":"Tablonun index/anahtar dağılım istatistiklerini yeniden hesaplar; optimizer'ın daha iyi plan seçmesini sağlar.","when":"Toplu veri değişimi sonrası kötü sorgu planları alındığında.","caution":"Çalışırken tabloya kısa süreli metadata lock alınır. InnoDB'de örneklem tabanlıdır; hassasiyet için innodb_stats_persistent_sample_pages artırılabilir.","tags":["analyze","statistics","optimizer","maintenance"]},{"id":"rebuild-table","task":"Tabloyu/index'leri yeniden oluştur (rebuild)","category":"Bakım","command":"ALTER TABLE musteri ENGINE=InnoDB;","what":"Tabloyu aynı motorla yeniden inşa eder; index'leri ve veri sayfalarını yeniden oluşturarak fragmentasyonu ve index bloat'ını giderir.","when":"Null ALTER ile tabloyu tazelemek, bozuk sayfa düzenini onarmak için.","caution":"Büyük tablolarda tablo boyutu kadar geçici disk gerekir. Lock'u azaltmak için: ALTER TABLE musteri ENGINE=InnoDB, ALGORITHM=INPLACE, LOCK=NONE;","tags":["rebuild","alter","innodb","maintenance"]},{"id":"check-table","task":"Tablo bütünlüğünü kontrol et (CHECK TABLE)","category":"Bakım","command":"CHECK TABLE musteri;","what":"Tablo ve index'lerinde bozulma (corruption) olup olmadığını denetler ve durum döndürür.","when":"Beklenmedik hatalar, olası bozulma şüphesi olduğunda.","caution":"Kontrol sırasında tabloya read lock alınır. Bozulma tespit edilirse InnoDB için onarım genelde dump/restore ile yapılır; REPAIR TABLE yalnızca MyISAM/Archive gibi motorlarda çalışır.","tags":["check","integrity","corruption","maintenance"]},{"id":"set-global-persist","task":"Global değişkeni değiştir ve kalıcı yap","category":"Parametre","command":"SET PERSIST innodb_buffer_pool_size = 4294967296;","what":"Değişkeni hem çalışan sunucuda hem de restart sonrası kalıcı olacak şekilde (mysqld-auto.cnf) ayarlar.","when":"Bir sunucu değişkenini restart gerektirmeden kalıcı değiştirmek için.","caution":"SET PERSIST MySQL 8.0+ özelliğidir; MariaDB desteklemez (orada my.cnf düzenlenip restart gerekir). Sadece bu oturum/anlık için SET GLOBAL kullan. Salt-restart değişkenleri için SET PERSIST_ONLY gerekir.","since":"MySQL 8.0","note":"SET PERSIST MySQL 8.0 ile geldi ve değişkeni mysqld-auto.cnf'e yazarak kalıcı yapar; öncesinde (ve MariaDB'de) kalıcılık için my.cnf elle düzenlenip restart gerekiyordu.","tags":["set-persist","global","variable","parameter"]},{"id":"show-variables","task":"Mevcut değişken değerini gör","category":"Parametre","command":"SHOW VARIABLES LIKE 'innodb_buffer_pool_size';","what":"Belirtilen sunucu değişkeninin (veya desene uyanların) etkin değerini gösterir.","when":"Bir parametrenin çalışan değerini kontrol etmek için.","caution":"Oturum yerine global değeri için SHOW GLOBAL VARIABLES kullan. Değerin kaynağını (dosya, komut satırı, persist) görmek için: SELECT * FROM performance_schema.variables_info WHERE variable_name = 'innodb_buffer_pool_size';","tags":["show-variables","parameter","current-value","config"]},{"id":"flush-privileges","task":"Yetki tablolarını yeniden yükle (FLUSH PRIVILEGES)","category":"Parametre","command":"FLUSH PRIVILEGES;","what":"mysql.user gibi grant tablolarını doğrudan değiştirdikten sonra bunları belleğe yeniden yükler.","when":"Grant tablolarına elle INSERT/UPDATE yapıldıysa değişikliği etkinleştirmek için.","caution":"GRANT/REVOKE/CREATE USER komutları yetkileri zaten anında uygular; onlardan sonra FLUSH PRIVILEGES gereksizdir. Yalnızca grant tablolarına doğrudan müdahale ettiğinde gerekir.","tags":["flush-privileges","grants","privileges","reload"]},{"id":"setup-replica","task":"Replika kur (CHANGE REPLICATION SOURCE)","category":"Replikasyon","command":"CHANGE REPLICATION SOURCE TO SOURCE_HOST='source_host', SOURCE_PORT=3306, SOURCE_USER='replikator', SOURCE_PASSWORD='gizli', SOURCE_AUTO_POSITION=1;","what":"Bu sunucuyu, GTID tabanlı otomatik pozisyonla belirtilen kaynağı (source) takip edecek replika olarak yapılandırır.","when":"Yeni bir replika kurmak veya replikasyon kaynağını değiştirmek için.","caution":"MySQL 8.0.23+ terimidir; eski sürümde CHANGE MASTER TO ... MASTER_HOST kullanılır (8.0.23–8.3'te takma ad, 8.4'te kaldırıldı). SOURCE_AUTO_POSITION=1 için GTID açık olmalı (gtid_mode=ON). Aksi halde SOURCE_LOG_FILE ve SOURCE_LOG_POS belirtilmelidir. Komut öncesi replikasyon durmuş olmalı. Replikasyon kullanıcısı 8.0+ varsayılanı caching_sha2_password ile oluşturulduysa bağlantı TLS ister: SOURCE_SSL=1 ekleyin ya da TLS yoksa GET_SOURCE_PUBLIC_KEY=1 verin; aksi halde I/O thread 2061 hatasıyla bağlanamaz.","since":"MySQL 8.0.23","note":"CHANGE REPLICATION SOURCE TO (SOURCE_HOST vb.) MySQL 8.0.23 ile geldi; öncesinde CHANGE MASTER TO ... MASTER_HOST / MASTER_AUTO_POSITION kullanılırdı.","tags":["replication","change-source","replica","setup"]},{"id":"start-stop-replica","task":"Replikayı başlat / durdur","category":"Replikasyon","command":"STOP REPLICA; START REPLICA;","what":"Replikasyon I/O ve SQL thread'lerini durdurur ve yeniden başlatır.","when":"Bakım, yapılandırma değişikliği veya replikasyon hatasını gidermek için.","caution":"MySQL 8.0.22+ terimidir; eski sürümde STOP SLAVE / START SLAVE. Yalnızca SQL thread'i için: STOP REPLICA SQL_THREAD; STOP REPLICA sonrası CHANGE REPLICATION SOURCE yapılabilir.","since":"MySQL 8.0.22","note":"START REPLICA / STOP REPLICA MySQL 8.0.22 ile geldi; öncesinde START SLAVE / STOP SLAVE kullanılırdı (eski sözdizimi 8.0.22–8.3'te takma ad olarak çalışır, 8.4'te kaldırıldı).","tags":["replication","start","stop","replica"]},{"id":"replica-status","task":"Replika durumunu gör (SHOW REPLICA STATUS)","category":"Replikasyon","command":"SHOW REPLICA STATUS\\G","what":"Replikanın kaynağa bağlantısını, thread durumlarını, gecikmeyi ve varsa hataları ayrıntılı gösterir.","when":"Replikasyonun sağlıklı çalışıp çalışmadığını, ne kadar geride olduğunu kontrol etmek için.","caution":"MySQL 8.0.22+ terimidir; eski sürümde SHOW SLAVE STATUS (8.0.22–8.3'te takma ad, 8.4'te kaldırıldı). Kritik alanlar: Replica_IO_Running ve Replica_SQL_Running 'Yes' olmalı, Seconds_Behind_Source gecikmeyi, Last_Error hatayı gösterir.","since":"MySQL 8.0.22","note":"SHOW REPLICA STATUS MySQL 8.0.22 ile geldi; öncesinde SHOW SLAVE STATUS kullanılır ve alanlar Slave_IO_Running / Seconds_Behind_Master gibi adlanırdı.","tags":["replication","status","replica","lag"]},{"id":"skip-gtid-transaction","task":"Bozuk transaction'ı atla (GTID)","category":"Replikasyon","command":"STOP REPLICA; SET GTID_NEXT='aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee:15'; BEGIN; COMMIT; SET GTID_NEXT='AUTOMATIC'; START REPLICA;","what":"Belirtilen GTID için boş bir transaction işleyerek o transaction'ı 'uygulanmış' sayar ve replikasyonu ilerletir.","when":"Replikada tekrar eden/uygulanamayan bir olay replikasyonu durdurduğunda, o olayı atlamak için.","caution":"Transaction'ı atlamak replika ile kaynak arasında veri tutarsızlığı yaratır; yalnızca atlanan olayın etkisini bildiğinde kullan. GTID değerini SHOW REPLICA STATUS'taki Last_Error / Retrieved_Gtid_Set'ten al. GTID kapalıysa SET GLOBAL sql_replica_skip_counter = 1; kullanılır (8.0.26+; öncesinde sql_slave_skip_counter, 8.0.26+'da deprecated takma ad).","tags":["replication","gtid","skip","recovery"]},{"id":"kill-query-connection","task":"Sorguyu veya bağlantıyı öldür (KILL)","category":"Oturum","command":"KILL QUERY 4567;","what":"Belirtilen bağlantı ID'sinde o an çalışan sorguyu, bağlantıyı kapatmadan sonlandırır.","when":"Uzun süren/takılı bir sorguyu durdurmak için.","caution":"Bağlantının tamamını (oturumu) kapatmak için: KILL CONNECTION 4567; (veya kısaca KILL 4567). Çalışan yazma transaction'ı öldürülürse rollback yapılır ve bu büyük tablolarda uzun sürebilir.","tags":["kill","query","connection","session"]},{"id":"process-list","task":"İşlem (process) listesini gör","category":"Oturum","command":"SELECT id, user, host, db, command, time, state, LEFT(info, 100) AS sorgu FROM performance_schema.processlist WHERE command <> 'Sleep' ORDER BY time DESC;","what":"Boşta olmayan tüm bağlantıları, çalıştıkları sorguyu ve süreyi listeler.","when":"Aktif oturumları ve uzun süren sorguları teşhis etmek için.","caution":"Kısa yol: SHOW FULL PROCESSLIST; performance_schema.processlist tüm sütunları verir ve WHERE ile filtrelenebilir. Süre (time) saniye cinsindendir.","tags":["processlist","session","activity","performance-schema"]},{"id":"blocking-locks","task":"Bloklayan lock'ları gör (data_lock_waits)","category":"Oturum","command":"SELECT r.trx_id AS bekleyen_trx, r.trx_mysql_thread_id AS bekleyen_thread, LEFT(r.trx_query,80) AS bekleyen_sorgu, b.trx_id AS bloklayan_trx, b.trx_mysql_thread_id AS bloklayan_thread, LEFT(b.trx_query,80) AS bloklayan_sorgu FROM performance_schema.data_lock_waits w JOIN information_schema.innodb_trx r ON r.trx_id = w.requesting_engine_transaction_id JOIN information_schema.innodb_trx b ON b.trx_id = w.blocking_engine_transaction_id;","what":"Hangi transaction'ın hangi transaction tarafından bloklandığını, ilgili sorgu ve thread ID'leriyle gösterir.","when":"Lock beklemeleri ve deadlock kaynaklı yavaşlıkları teşhis etmek için.","caution":"performance_schema.data_lock_waits MySQL 8.0+ ile gelir; eski sürümde information_schema.innodb_lock_waits kullanılır. Bloklayan thread'i durdurmak için KILL bloklayan_thread; kullanılabilir.","since":"MySQL 8.0","note":"performance_schema.data_lock_waits MySQL 8.0 ile geldi; MySQL 5.7 ve öncesinde aynı bilgi için information_schema.innodb_lock_waits kullanılırdı.","tags":["blocking","lock","data-lock-waits","deadlock"]}]},"recipes/mysql-ext.json":{"engineId":"mysql","engine":"MySQL","order":2,"recipes":[{"id":"replica-applier-health","task":"Replika gecikmesini ve applier worker hatalarını izle (performance_schema)","category":"Replikasyon","command":"-- Receiver (I/O) thread: baglanti durumu ve son hata\nSELECT CHANNEL_NAME, SERVICE_STATE, LAST_ERROR_NUMBER,\n       LEFT(LAST_ERROR_MESSAGE, 100) AS last_error,\n       LAST_QUEUED_TRANSACTION, LAST_HEARTBEAT_TIMESTAMP\nFROM performance_schema.replication_connection_status;\n\n-- Applier worker'lar: hata, uygulanan GTID ve gercek gecikme\nSELECT CHANNEL_NAME, WORKER_ID, SERVICE_STATE, LAST_ERROR_NUMBER,\n       LEFT(LAST_ERROR_MESSAGE, 120) AS last_error,\n       LAST_APPLIED_TRANSACTION,\n       APPLYING_TRANSACTION,\n       IF(APPLYING_TRANSACTION = '', 0,\n          TIMESTAMPDIFF(SECOND, APPLYING_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP, NOW(6))) AS current_lag_sec,\n       TIMESTAMPDIFF(MICROSECOND, LAST_APPLIED_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP,\n                     LAST_APPLIED_TRANSACTION_END_APPLY_TIMESTAMP) / 1000000 AS last_trx_lag_sec\nFROM performance_schema.replication_applier_status_by_worker\nORDER BY CHANNEL_NAME, WORKER_ID;","what":"SHOW REPLICA STATUS'un tek satırda özetlediği bilgiyi channel ve worker bazında verir: receiver thread durumu, her worker'ın son hatası, uygulanan / uygulanmakta olan GTID ve original commit timestamp'e göre hesaplanan gerçek gecikme.","when":"Seconds_Behind_Source güvenilmez göründüğünde (0 ile büyük değer arasında zıplama, NULL), multi-threaded replica'da hangi worker'ın takıldığını bulmak ve monitoring'e doğru bir lag metriği eklemek için.","caution":"current_lag_sec yalnız bir transaction uygulanırken anlamlıdır; replica boşta ise 0 döner. Receiver'ın da geride olup olmadığını görmek için LAST_QUEUED_TRANSACTION'ı kaynağın gtid_executed değeriyle karşılaştır. Original commit timestamp kaynağın saatine dayanır; sunucular arası saat farkı (NTP) sonucu saptırır. Seconds_Behind_Source büyük bir transaction'ın başında sıfıra yakın, sonunda birden yüksek görünür; uzun transaction'lar bu metriği yanıltır.","note":"ORIGINAL_COMMIT_TIMESTAMP / END_APPLY_TIMESTAMP sütunları 8.0.2 ile geldi ve zincirin tamamını (source → intermediate → replica) kapsar; 5.7'de yalnız Seconds_Behind_Master vardır.","since":"MySQL 8.0","tags":["replication","lag","applier","worker","performance_schema","gecikme"]},{"id":"replica-parallel-applier","task":"Multi-threaded replica'yı ayarla (replica_parallel_workers)","category":"Replikasyon","command":"-- Replica: applier'i durdur, worker sayisini ve commit sirasini ayarla\nSTOP REPLICA SQL_THREAD;\nSET PERSIST replica_parallel_workers = 8;\nSET PERSIST replica_preserve_commit_order = ON;\nSTART REPLICA SQL_THREAD;\nSELECT COUNT(*) AS workers FROM performance_schema.replication_applier_status_by_worker;\n\n-- Source (yalniz 8.0): bagimlilik takibini WRITESET yap (8.4'te varsayilan, degisken kaldirildi)\nSET PERSIST binlog_transaction_dependency_tracking = WRITESET;","what":"Replikada transaction'ları paralel uygulayan worker sayısını ayarlar; replica_preserve_commit_order commit sırasını kaynaktakiyle aynı tutar. Kaynakta WRITESET bağımlılık takibi, aynı satırlara dokunmayan transaction'ların kaynakta seri commit edilmiş olsalar bile paralel uygulanmasını sağlar.","when":"Replica, kaynağın yazma hızına yetişemeyip lag biriktiriyorsa ve applier fiilen tek thread'de çalışıyorsa.","caution":"Worker sayısı değişikliği applier yeniden başlatılınca etkili olur. Worker'ları CPU çekirdeğinden fazla açmak koordinasyon yükü getirir; 8–16 aralığından başla, lag ve worker hatalarını izle. Tek bir büyük transaction veya PK'sız tabloda yoğun DML paralelleştirilemez; kalıcı lag'in asıl nedeni çoğu zaman budur. replica_preserve_commit_order=OFF daha fazla paralellik verir ama replikada kısa süreli sıra dışı commit görülür; okuma trafiği alan replikada ON bırak.","note":"8.0.27'den itibaren varsayılanlar replica_parallel_workers=4, replica_parallel_type=LOGICAL_CLOCK, replica_preserve_commit_order=ON'dur. 8.0.26 öncesinde değişken adları slave_parallel_workers / slave_preserve_commit_order idi. binlog_transaction_dependency_tracking 8.0.35'te deprecated oldu, 8.4'te kaldırıldı ve WRITESET davranışı varsayılan oldu.","since":"MySQL 8.0.26","tags":["replication","parallel","replica_parallel_workers","writeset","lag","mta"]},{"id":"replica-fix-row-conflict","task":"Kopan replikayı onar: 1062 / 1032 satır çakışması","category":"Replikasyon","command":"-- 1) Hatali worker, hata ve GTID\nSELECT WORKER_ID, LAST_ERROR_NUMBER, LEFT(LAST_ERROR_MESSAGE, 250) AS last_error, APPLYING_TRANSACTION\nFROM performance_schema.replication_applier_status_by_worker\nWHERE LAST_ERROR_NUMBER <> 0;\n\n-- 2) Shell: relay log'da o transaction'in row image'larini coz\nmysqlbinlog --base64-output=DECODE-ROWS -vv --include-gtids='af6bc361-c353-11f1-8f12-f69e63ad6c0e:11' /var/lib/mysql/db2-relay-bin.0* | grep '^###'\n\n-- 3a) 1062 Duplicate entry: replikadaki fazla satiri binlog'a yazmadan sil\nSET SESSION sql_log_bin = 0;\nDELETE FROM shop.orders WHERE id = 20001;\n-- 3b) 1032 Can't find record: eksik satiri WHERE (before image) degerleriyle ekle\nINSERT INTO shop.orders (id, cust, amount, note, created) VALUES (6, 6, 9.00, 'n6', '2026-10-08 20:09:44');\nSET SESSION sql_log_bin = 1;\n\n-- 4) Applier'i baslat ve dogrula\nSTART REPLICA SQL_THREAD;\nSELECT SERVICE_STATE, LAST_ERROR_NUMBER FROM performance_schema.replication_applier_status_by_coordinator;","what":"Row-based replikasyonun en sık iki kırılmasını (1062 duplicate key, 1032 row not found) transaction'ı atlamadan, replikadaki satırı kaynağın beklediği hale getirerek düzeltir; veri tutarlılığı korunur.","when":"Replica_SQL_Running = No ve hata 1062 / 1032 olduğunda; GTID'yi boş transaction ile atlamak yerine kalıcı onarım için.","caution":"Replikadaki düzeltme mutlaka sql_log_bin=0 ile yapılmalı; aksi halde errant GTID oluşur ve failover'da sorun çıkarır. super_read_only=ON ise önce geçici kapat, iş bitince geri aç. Before image değerleri binlog_row_image=FULL varsayar; MINIMAL'de yalnız PK gelir, satırın kalanı kaynaktan okunmalıdır. Aynı tabloda tek çakışma genellikle daha fazlasının işaretidir; onarımdan sonra pt-table-checksum ile tabloyu kaynakla karşılaştır. Relay log yolu için: SELECT @@relay_log_basename;","note":"replica_exec_mode=IDEMPOTENT bu hataları sessizce yutar; NDB ve özel senaryolar için tasarlanmıştır, kalıcı ayar olarak kullanılmamalı. Transaction'ı tamamen atlamak gerekiyorsa skip-gtid-transaction reçetesine bak.","since":"MySQL 8.0.22","tags":["replication","1062","1032","mysqlbinlog","relay log","kopan replika"]},{"id":"gtid-errant-transactions","task":"Errant GTID transaction'larını bul ve etkisizleştir","category":"Replikasyon","command":"-- 1) Kaynakta: gtid_executed degerini al\nSELECT @@GLOBAL.gtid_executed;\n\n-- 2) Replikada: kaynakta olmayan GTID'ler (bos sonuc = temiz)\nSELECT GTID_SUBTRACT(@@GLOBAL.gtid_executed,\n       'af6bc361-c353-11f1-8f12-f69e63ad6c0e:1-13') AS errant_gtids;\n\n-- 3) Icerik zararsizsa: kaynakta her errant GTID icin bos transaction isle\nSET GTID_NEXT = 'b030e5a6-c353-11f1-a887-523817ec642a:1'; BEGIN; COMMIT;\nSET GTID_NEXT = 'b030e5a6-c353-11f1-a887-523817ec642a:2'; BEGIN; COMMIT;\nSET GTID_NEXT = 'AUTOMATIC';","what":"Replikada doğrudan çalıştırılmış ve kaynakta karşılığı olmayan (errant) transaction'ları GTID set farkıyla tespit eder; kaynakta boş transaction ile işaretleyerek topolojideki GTID setlerini eşitler.","when":"Failover / switchover öncesi rutin kontrol olarak; Orchestrator veya MySQL Shell bir replikayı errant GTID gerekçesiyle promote etmediğinde ya da replika yeni kaynağa bağlanırken 1236 hatası verdiğinde.","caution":"Önce errant transaction'ın ne yaptığını replikanın binlog'undan bul (mysqlbinlog --include-gtids=...). Veri değiştiren bir transaction'sa boş transaction yalnız GTID'yi örter, veri farkı kalır; bu durumda replikayı yeniden kur (CLONE) veya veriyi elle hizala. Kaynakta işlenen boş transaction'lar tüm replikalara yayılır; istenen davranış budur. Tekrarını önlemek için replikalarda super_read_only=ON tut.","note":"Replika promote edildiğinde diğer replikalar bu GTID'leri ondan ister; ilgili binlog purge edilmişse replikasyon 1236 hatasıyla kopar. Errant GTID bu yüzden failover'a kadar fark edilmeyen bir risktir.","since":"MySQL 5.6","tags":["gtid","errant","gtid_subtract","failover","replication","empty transaction"]},{"id":"replica-rebuild-clone","task":"Replikayı CLONE plugin ile sıfırdan yeniden kur","category":"Replikasyon","command":"-- Donor (saglikli replika veya kaynak)\nINSTALL PLUGIN clone SONAME 'mysql_clone.so';\nCREATE USER 'clone_donor'@'%' IDENTIFIED BY 'Cl0ne#Donor';\nGRANT BACKUP_ADMIN ON *.* TO 'clone_donor'@'%';\n\n-- Recipient (yeniden kurulacak replika; mevcut verisi silinir)\nINSTALL PLUGIN clone SONAME 'mysql_clone.so';\nSET GLOBAL clone_valid_donor_list = 'db1:3306';\nCLONE INSTANCE FROM 'clone_donor'@'db1':3306 IDENTIFIED BY 'Cl0ne#Donor';\n\n-- Restart sonrasi: sonucu dogrula ve replikasyonu baslat\nSELECT STATE, ERROR_NO, BINLOG_FILE, BINLOG_POSITION, GTID_EXECUTED FROM performance_schema.clone_status;\nSELECT STAGE, STATE, ROUND(DATA / 1024 / 1024) AS data_mb FROM performance_schema.clone_progress;\nCHANGE REPLICATION SOURCE TO SOURCE_HOST = 'db1', SOURCE_PORT = 3306, SOURCE_USER = 'repl', SOURCE_PASSWORD = 'Repl#2024', SOURCE_AUTO_POSITION = 1, SOURCE_SSL = 1;\nSTART REPLICA;","what":"Donor sunucunun InnoDB verisini fiziksel olarak ağ üzerinden kopyalar, recipient'ı restart eder ve GTID durumunu da taşır; ayrı yedek alma / taşıma / geri yükleme adımları olmadan tutarlı bir replika üretir.","when":"Bozulan, errant GTID'li veya çok geride kalıp binlog'u purge edilmiş bir replikayı yeniden kurmak ya da yeni replika eklemek için.","caution":"Recipient'taki tüm veri (kullanıcılar dahil) donor'un kopyasıyla değişir; root parolası da donor'unki olur. Donor ve recipient aynı sürüm serisi, platform ve plugin setine sahip olmalı (8.0.37 öncesinde aynı point release şarttı). Komutu çalıştıran recipient kullanıcısında CLONE_ADMIN gerekir. Klon bitince mysqld kendini restart eder; systemd / mysqld_safe gibi bir supervisor yoksa 3707 'Restart server failed (mysqld is not managed by supervisor process)' döner. Bu bir hata değildir, klon tamamlanmıştır; sunucuyu elle başlat. Donor'da ciddi IO / network yükü oluşur; clone_max_concurrency ve clone_max_data_bandwidth ile sınırla. GTID kapalıysa clone_status'taki BINLOG_FILE / BINLOG_POSITION ile SOURCE_LOG_FILE / SOURCE_LOG_POS ver.","note":"Yalnız InnoDB verisi klonlanır; MyISAM ve CSV tablolar boş gelir. InnoDB Cluster'da addInstance(..., {recoveryMethod: 'clone'}) aynı mekanizmayı kullanır.","since":"MySQL 8.0.17","tags":["clone","rebuild","replica","provisioning","gtid","yeniden kurulum"]},{"id":"delayed-replica-recover","task":"Gecikmeli replika ile hatalı DROP / DELETE'ten kurtar (SOURCE_DELAY + UNTIL)","category":"Replikasyon","command":"-- Kurulum: replika olaylari 1 saat geriden uygular\nSTOP REPLICA;\nCHANGE REPLICATION SOURCE TO SOURCE_DELAY = 3600;\nSTART REPLICA;\n\n-- Olay aninda: applier'i durdur (receiver binlog almaya devam eder)\nSTOP REPLICA SQL_THREAD;\n\n-- Hatali transaction'in GTID'sini kaynagin binlog'unda bul, hemen oncesine kadar uygula\nCHANGE REPLICATION SOURCE TO SOURCE_DELAY = 0;\nSTART REPLICA SQL_THREAD UNTIL SQL_BEFORE_GTIDS = 'af6bc361-c353-11f1-8f12-f69e63ad6c0e:17';\nSELECT SERVICE_STATE FROM performance_schema.replication_applier_status_by_coordinator;","what":"Replikanın olayları belirli bir süre geriden uygulamasını sağlar; hatalı bir DROP / DELETE kaynağa düştüğünde replikayı tam o transaction'dan önceye kadar ilerletip silinen veriyi buradan geri almayı mümkün kılar.","when":"Yedekten geri dönüşün saatler süreceği büyük veritabanlarında insan hatasına karşı hızlı kurtarma katmanı olarak.","caution":"Coordinator OFF olduğunda veri hatalı işlemden hemen önceki haldedir; ilgili tabloyu mysqldump ile al ve kaynağa yükle. İş bitince replikayı yeniden gecikmeli moda al; hatalı transaction'ı da uygularsa veri bu replikada da kaybolur. Gecikmeli replika failover adayı olmamalı (Orchestrator / Router / ProxySQL'de hariç tut). Gecikme süresince relay log birikir; disk alanını buna göre ayır.","note":"8.0.23 öncesinde CHANGE MASTER TO MASTER_DELAY. Gecikme, transaction'ın bir üstteki kaynaktaki (immediate source) commit anına göre ölçülür; zincirde gecikmeli ara replika varsa gecikmeler toplanır. SQL_BEFORE_GTIDS verilen GTID'den önce durur, SQL_AFTER_GTIDS o GTID'yi de uygular; 8.2 öncesinde (8.0 dahil) SQL_AFTER_GTIDS multi-threaded applier ile kullanılırsa uyarı verilir ve replica single-threaded moda geçer.","since":"MySQL 8.0.23","tags":["delayed replica","source_delay","until","sql_before_gtids","recovery","drop table"]},{"id":"mysqldump-consistent","task":"mysqldump ile tutarlı, GTID bilgili mantıksal yedek al","category":"Yedekleme & PITR","command":"mysqldump -h db1 -u backup -p \\\n  --single-transaction --source-data=2 --set-gtid-purged=ON \\\n  --routines --events --triggers --hex-blob \\\n  --all-databases | gzip > /backup/full_$(date +%F_%H%M).sql.gz\n\n# Geri yukleme: hedefte GTID setleri cakismamali\nzcat /backup/full_2026-10-08_0200.sql.gz | mysql -h db2 -u root -p","what":"InnoDB tablolarını tek bir consistent snapshot içinde döker; dosyanın başına binlog dosya / pozisyonunu (yorum olarak) ve SET @@GLOBAL.GTID_PURGED satırını yazar. Böylece yedek hem replika kurmak hem de binlog ile PITR yapmak için başlangıç noktası olur.","when":"Birkaç on GB'a kadar veritabanlarında, şema / tablo taşımada ve sürümler arası mantıksal geçişte.","caution":"--single-transaction yalnız InnoDB için tutarlıdır; MyISAM tablolar tutarsız gelir. Dump sırasında aynı tabloda DDL (ALTER / RENAME / TRUNCATE) çalışırsa dump hata verir veya tablo eksik gelir. --source-data / --set-gtid-purged başlangıçta kısa bir global read lock alır (RELOAD yetkisi gerekir); o anda uzun süren bir sorgu varsa lock beklerken tüm yazmalar durur. Kısmi dump (--databases) yine tüm GTID'leri yazar; başka bir sunucuya parça taşırken --set-gtid-purged=OFF kullan. Dump tek thread'lidir; büyük veride MySQL Shell dump veya XtraBackup tercih et.","note":"--source-data 8.0.26'da --master-data'nın yerine geldi. mysqlpump 8.0.34'te deprecated oldu, 8.4'te kaldırıldı; paralel mantıksal yedek için MySQL Shell util.dumpInstance kullan.","since":"MySQL 8.0.26","tags":["mysqldump","backup","single-transaction","gtid","logical backup","yedek"]},{"id":"mysqlsh-dump-load","task":"MySQL Shell ile paralel dump / load (util.dumpInstance, loadDump)","category":"Yedekleme & PITR","command":"# Paralel, zstd sikistirmali, tutarli instance dump\nmysqlsh backup@db1:3306 -- util dump-instance /backup/dump_20261008 --threads=8 --compression=zstd --consistent=true\n# Tek sema\nmysqlsh backup@db1:3306 -- util dump-schemas shop --outputUrl=/backup/shop_20261008 --threads=8\n\n# Yukleme: hedefte local_infile gecici olarak acik olmali\nmysql -h db2 -u root -p -e \"SET GLOBAL local_infile = ON\"\nmysqlsh root@db2:3306 -- util load-dump /backup/dump_20261008 --threads=8 --skipBinlog=false\nmysql -h db2 -u root -p -e \"SET GLOBAL local_infile = OFF\"","what":"Tabloları chunk'lara bölerek çok thread'le döker ve yükler; mysqldump'a göre hem dump hem restore kat kat hızlıdır. Dump dizini GTID ve binlog koordinatlarını @.json dosyasında tutar.","when":"Yüzlerce GB'lık mantıksal yedekte, sürüm yükseltmede mantıksal taşımada, on-prem → cloud (RDS, HeatWave) geçişinde.","caution":"--consistent=true kısa bir global read lock / backup lock alır; uzun süren sorgu varsa yazmalar bekler. loadDump LOAD DATA LOCAL kullanır; hedefte local_infile=ON gerekir ve iş bitince kapatılmalıdır. Yükleme yarıda kalırsa aynı komut kaldığı yerden devam eder (progress dosyası); baştan başlamak için --resetProgress. Kullanıcı hesapları varsayılan olarak yüklenmez (--loadUsers=true). --skipBinlog=true yükleme sırasında binlog yazmayı keser; hedefin replikaları varsa false bırak.","note":"Fiziksel yedek değildir; PITR için dump'ın @.json içindeki gtidExecuted değerinden itibaren binlog uygulanır. ocimds / compatibility seçenekleri HeatWave / RDS kısıtlarına uygun dump üretir.","since":"MySQL Shell 8.0.21","tags":["mysqlsh","dumpinstance","loaddump","parallel","logical backup","migration"]},{"id":"xtrabackup-full-incremental","task":"XtraBackup ile full + incremental fiziksel yedek ve restore","category":"Yedekleme & PITR","command":"# Full backup\nxtrabackup --backup --host=127.0.0.1 --user=bkp --password='Bkp#2024' --target-dir=/backup/full --parallel=4\n# Incremental (bir oncekini taban alir)\nxtrabackup --backup --host=127.0.0.1 --user=bkp --password='Bkp#2024' --target-dir=/backup/inc1 --incremental-basedir=/backup/full\n\n# Prepare: full ve ara incremental'lar --apply-log-only ile, son adim onsuz\nxtrabackup --prepare --apply-log-only --target-dir=/backup/full\nxtrabackup --prepare --apply-log-only --target-dir=/backup/full --incremental-dir=/backup/inc1\nxtrabackup --prepare --target-dir=/backup/full\n\n# Restore: mysqld durmus ve datadir bos olmali\nsystemctl stop mysqld\nxtrabackup --copy-back --target-dir=/backup/full --datadir=/var/lib/mysql\nchown -R mysql:mysql /var/lib/mysql\nsystemctl start mysqld\ncat /backup/full/xtrabackup_binlog_info","what":"Sunucu çalışırken InnoDB dosyalarını ve redo log'u kopyalayarak hot fiziksel yedek alır; incremental yedek yalnız son yedekten sonra değişen sayfaları içerir. Prepare adımı redo'yu uygulayıp yedeği tutarlı hale getirir.","when":"Büyük veritabanlarında hızlı restore gerektiğinde (mantıksal yedekten kat kat hızlı), replika kurmak için ve günlük full + saatlik incremental stratejisinde.","caution":"XtraBackup sürümü sunucu sürüm serisiyle eşleşmeli (8.0 sunucu → XtraBackup 8.0, 8.4 → 8.4); sunucu, kullanılan XtraBackup'tan yeni bir redo / data dictionary formatına geçmişse yedek reddedilir. Prepare edilmemiş yedek tutarsızdır. Ara adımlarda --apply-log-only unutulursa sonraki incremental uygulanamaz. Restore'da datadir boş olmalı; --move-back disk kazandırır ama yedeği tüketir. Yedek kullanıcısı: BACKUP_ADMIN, PROCESS, RELOAD, LOCK TABLES, REPLICATION CLIENT ve performance_schema.log_status, keyring_component_status, replication_group_members üzerinde SELECT.","note":"xtrabackup_binlog_info yedeğin binlog dosya / pozisyon ve GTID setini içerir; PITR için binlog bu noktadan itibaren uygulanır. Başka sunucuya akış halinde göndermek için --stream=xbstream | ssh host 'xbstream -x -C /backup' kullanılır.","since":"XtraBackup 8.0","tags":["xtrabackup","physical backup","incremental","prepare","restore","percona"]},{"id":"pitr-binlog-replay","task":"Binlog ile point-in-time recovery: hatalı transaction'ı bul ve atla","category":"Yedekleme & PITR","command":"# 1) Hatali olayin GTID ve pozisyonunu bul (zaman araligiyla daralt)\nmysqlbinlog --base64-output=DECODE-ROWS -vv --start-datetime='2026-10-08 20:00:00' --stop-datetime='2026-10-08 20:30:00' /var/lib/mysql/binlog.000003 | grep -B12 -iE '^(DROP|TRUNCATE)' | grep -E 'GTID_NEXT|^# at|^#[0-9]{6}|^DROP|^TRUNCATE'\n\n# 2) Yedegi ayri bir sunucuya yukle (dump GTID_PURGED'i ayarlar)\nzcat /backup/full_2026-10-08_0200.sql.gz | mysql -h restore-db -u root -p\n\n# 3a) Yalniz hatali transaction'i atlayarak tum binlog'lari uygula\nmysqlbinlog --exclude-gtids='af6bc361-c353-11f1-8f12-f69e63ad6c0e:23' /binlogs/binlog.000003 /binlogs/binlog.000004 | mysql -h restore-db -u root -p\n# 3b) Ya da hatali olayin GTID event'inden hemen once dur\nmysqlbinlog --stop-position=537205 /binlogs/binlog.000003 | mysql -h restore-db -u root -p","what":"Yedeği geri yükledikten sonra binlog'ları sırayla uygulayarak veritabanını istenen ana getirir. GTID açıkken yedekte zaten bulunan transaction'lar otomatik atlanır; --exclude-gtids ile yalnız hatalı transaction çıkarılıp sonrasındaki tüm değişiklikler korunabilir.","when":"Hatalı DROP / DELETE / UPDATE sonrası, yedek ile olay anı arasındaki değişiklikleri kaybetmeden geri dönmek için.","caution":"Geri yüklemeyi production'a değil ayrı bir sunucuya yap, doğrula, sonra yalnız etkilenen tabloyu taşı. --start/--stop-datetime mysqlbinlog'u çalıştıran makinenin saat dilimine göre yorumlanır. --stop-position yalnız son verilen dosyaya uygulanır; birden çok dosyada önceki dosyaları ayrı komutla tam uygula. --exclude-gtids yalnız bağımsız bir transaction için güvenlidir; sonraki transaction'lar silinen tabloya yazıyorsa onlar da hata verir. Gereken binlog'lar kaynakta purge edilmemiş olmalı; binlog retention en az bir yedek aralığından uzun tutulmalı.","note":"mysqlbinlog ve mysql tek pipe'ta, tüm dosyalar tek komutla çalıştırılmalı; dosyaları ayrı ayrı uygulamak geçici tabloları ve dosyalar arasında bölünen transaction'ları bozar. Çok büyük binlog setinde alternatif: binlog'ları restore sunucusuna relay log olarak koyup SQL thread ile (paralel) uygulamak.","since":"MySQL 8.0","tags":["pitr","mysqlbinlog","binlog","point in time","exclude-gtids","geri dönüş"]},{"id":"innodb-cluster-status","task":"InnoDB Cluster / Group Replication sağlık durumunu gör","category":"InnoDB Cluster","command":"# Shell: topoloji, primary, hata toleransi, lag\nmysqlsh icadmin@db1:3306 -- cluster status --extended=1\nmysqlsh icadmin@db1:3306 -- cluster list-routers\n\n-- SQL: herhangi bir uyeden grup uyeleri ve kuyruklar\nSELECT m.MEMBER_HOST, m.MEMBER_PORT, m.MEMBER_STATE, m.MEMBER_ROLE, m.MEMBER_VERSION,\n       s.COUNT_TRANSACTIONS_IN_QUEUE AS certify_queue,\n       s.COUNT_TRANSACTIONS_REMOTE_IN_APPLIER_QUEUE AS apply_queue,\n       s.COUNT_CONFLICTS_DETECTED AS conflicts\nFROM performance_schema.replication_group_members m\nJOIN performance_schema.replication_group_member_stats s ON s.MEMBER_ID = m.MEMBER_ID\nORDER BY m.MEMBER_ROLE, m.MEMBER_HOST;","what":"Cluster'ın genel durumunu (OK / OK_NO_TOLERANCE / NO_QUORUM), primary'yi, her üyenin state'ini ve certification / applier kuyruklarını gösterir; kuyruklar hangi üyenin geride kaldığını ve flow control riskini ortaya koyar.","when":"Her müdahaleden önce ve sonra; alarm, yazma yavaşlaması veya bir üyenin RECOVERING / ERROR / UNREACHABLE görünmesi durumunda.","caution":"statusText 'can tolerate up to ONE failure' (3 üye) olmalı. NO_QUORUM'da yazma durur; forceQuorumUsingPartitionOf yalnız diğer partition'ın kesin kapalı olduğundan eminken kullanılır, aksi halde split-brain olur. apply_queue sürekli büyüyen üye flow control'ü tetikleyip primary'deki yazmaları yavaşlatır. RECOVERING uzun sürüyorsa üye clone / incremental recovery yapıyordur; ERROR ise error log'a bak ve cluster.rejoinInstance() dene. Parolada özel karakter varsa (#, @) URI'de URL-encode et (# → %23).","note":"MEMBER_COMMUNICATION_STACK 8.0.27 ile geldi; MYSQL stack GR trafiğini 3306 üzerinden normal TLS ve kullanıcı doğrulamasıyla taşır (XCOM ayrı port kullanır, genellikle 33061). 8.4'te group_replication_consistency varsayılanı BEFORE_ON_PRIMARY_FAILOVER, exit_state_action varsayılanı OFFLINE_MODE'dur.","since":"MySQL 8.0","tags":["innodb cluster","group replication","mysqlsh","status","flow control","quorum"]},{"id":"innodb-cluster-switch-primary","task":"InnoDB Cluster'da planlı primary değişimi (switchover)","category":"InnoDB Cluster","command":"# Shell: planli switchover\nmysqlsh icadmin@db1:3306 -- cluster set-primary-instance db2:3306\n\n-- SQL alternatifi: hedef uyenin server_uuid'i, acik transaction'lar icin 30 sn timeout\nSELECT MEMBER_HOST, MEMBER_ID, MEMBER_ROLE FROM performance_schema.replication_group_members;\nSELECT group_replication_set_as_primary('3f06e651-c356-11f1-8aac-927a9034ef99', 30);","what":"Single-primary modda primary rolünü kontrollü biçimde başka üyeye taşır; eski primary super_read_only olur, yeni primary backlog'unu uygulayıp yazmaya açılır. MySQL Router yeni primary'yi otomatik öğrenir.","when":"Primary'nin bakımı, OS patch'i veya upgrade'i öncesinde ve donanım taşımada.","caution":"Eski primary'deki açık transaction'lar timeout sonunda kesilir; timeout verilmezse bitmeleri beklenir ve switchover uzar. Uygulama Router üzerinden bağlanmıyorsa yönlendirmeyi kendin yapmalısın. BEFORE_ON_PRIMARY_FAILOVER ile yeni primary backlog'u bitirene kadar yazmalar bekler; önce cluster status'ta apply_queue'nun boş olduğunu doğrula. InnoDB Cluster'da Shell komutu tercih edilir; metadata ile tutarlı kalır.","note":"group_replication_set_as_primary 8.0.13 ile geldi; timeout parametresi 8.0.29'da eklendi. Plansız failover'da GR yeni primary'yi kendisi seçer (group_replication_member_weight ile öncelik verilebilir).","since":"MySQL 8.0.13","tags":["innodb cluster","switchover","primary","group replication","set_as_primary","bakım"]},{"id":"innodb-cluster-reboot-outage","task":"Tüm üyeler kapandıktan sonra cluster'ı ayağa kaldır (rebootClusterFromCompleteOutage)","category":"InnoDB Cluster","command":"# Tum uyeler OFFLINE mi? (her node'da)\nmysql -h db1 -u icadmin -p -e \"SELECT MEMBER_HOST, MEMBER_STATE FROM performance_schema.replication_group_members\"\n# Once kuru calistirma: en guncel uyeyi ve yapilacaklari gosterir\nmysqlsh icadmin@db1:3306 --js -e \"dba.rebootClusterFromCompleteOutage('prodCluster', {dryRun: true})\"\nmysqlsh icadmin@db1:3306 --js -e \"dba.rebootClusterFromCompleteOutage('prodCluster')\"\nmysqlsh icadmin@db1:3306 -- cluster status","what":"Elektrik kesintisi veya tüm node'ların aynı anda restart'ı sonrası quorum kalmadığında grubu yeniden bootstrap eder; en yüksek GTID setine sahip üyeyi seçer, diğerlerini rejoin eder.","when":"cluster status 'Cluster is not reachable' dediğinde ve tüm üyeler OFFLINE göründüğünde.","caution":"Yalnız tüm üyeler OFFLINE iken kullanılır; bir üye hâlâ ONLINE ise grup ayaktadır, diğerleri rejoinInstance ile eklenir. Komuttan önce tüm node'ları ayağa kaldır: erişilemeyen bir üye daha güncelse onun transaction'ları kaybolur. force: true eksik üyeleri yok sayar; son çaredir. primary: 'host:port' seçeneği belirli bir üyeyi primary yapar.","note":"dryRun, primary ve force seçenekleri Shell 8.0.31 ile geldi; öncesinde fonksiyon etkileşimli sorularla çalışırdı. group_replication_start_on_boot=ON olsa bile tam kesintiden sonra grup kendiliğinden kurulmaz; bootstrap bilinçli olarak tek noktadan yapılmalıdır.","since":"MySQL Shell 8.0.31","tags":["innodb cluster","outage","reboot","bootstrap","mysqlsh","kesinti"]},{"id":"mysql-router-bootstrap","task":"MySQL Router'ı InnoDB Cluster'a bootstrap et","category":"Router & Proxy","command":"# Metadata'dan konfig uretir, router hesabini acar; root ile calisiyorsan --user zorunlu\nmysqlrouter --bootstrap icadmin@db1:3306 --directory /etc/mysqlrouter/prod --account routeruser --account-create if-not-exists --name router01 --conf-bind-address 0.0.0.0 --user mysqlrouter\n/etc/mysqlrouter/prod/start.sh\n# Portlar: 6446 RW, 6447 RO, 6450 RW split (classic); 6448 / 6449 X protocol\nmysql -h app-host -P 6446 -u app -p -e \"SELECT @@hostname\"\nmysql -h app-host -P 6447 -u app -p -e \"SELECT @@hostname\"\nmysqlsh icadmin@db1:3306 -- cluster list-routers","what":"Router'ı cluster metadata'sına kaydeder, gerekli hesap ve konfigürasyonu üretir; uygulama RW portundan her zaman güncel primary'ye, RO portundan secondary'lere round-robin ile ulaşır.","when":"InnoDB Cluster / ClusterSet / ReplicaSet önüne transparent failover katmanı koyarken; genellikle her uygulama sunucusuna bir Router.","caution":"Router durumsuzdur; uygulama sunucusunun yanında çalıştırmak tek hata noktası yaratmaz, merkezi tek Router ise yaratır. Bootstrap hesabı yalnız bootstrap'ta kullanılır; Router metadata'yı kendi hesabıyla (routeruser) okur. Topoloji değişikliklerini metadata cache ile otomatik öğrenir, yeniden bootstrap gerekmez. RW split portu (6450) transaction içindeki okumaları primary'ye, dışındakileri secondary'lere gönderir; read-your-writes bekleyen uygulamada dikkat. Router sürümü cluster'daki MySQL sürümünden eski olmamalı.","note":"Read/write splitting portu (6450) 8.2 ile geldi. Failover sonrası mevcut bağlantılar kopar; uygulamanın yeniden bağlanma (retry) mantığı olmalıdır.","since":"MySQL Router 8.0","tags":["mysql router","bootstrap","innodb cluster","failover","read write split","6446"]},{"id":"proxysql-rw-split","task":"ProxySQL ile read/write split ve replika sağlık kontrolü","category":"Router & Proxy","command":"-- MySQL'de (kaynakta): monitor kullanicisi\nCREATE USER 'proxysql_mon'@'%' IDENTIFIED BY 'M0n#itor2024';\nGRANT USAGE, REPLICATION CLIENT ON *.* TO 'proxysql_mon'@'%';\n\n-- ProxySQL admin: mysql -u admin -p -h 127.0.0.1 -P 6032\nUPDATE global_variables SET variable_value = 'proxysql_mon' WHERE variable_name = 'mysql-monitor_username';\nUPDATE global_variables SET variable_value = 'M0n#itor2024' WHERE variable_name = 'mysql-monitor_password';\nLOAD MYSQL VARIABLES TO RUNTIME; SAVE MYSQL VARIABLES TO DISK;\nINSERT INTO mysql_replication_hostgroups (writer_hostgroup, reader_hostgroup, check_type, comment) VALUES (10, 20, 'read_only', 'shop');\nINSERT INTO mysql_servers (hostgroup_id, hostname, port, max_replication_lag) VALUES (10, 'db1', 3306, 0), (20, 'db2', 3306, 30), (20, 'db3', 3306, 30);\nLOAD MYSQL SERVERS TO RUNTIME; SAVE MYSQL SERVERS TO DISK;\nINSERT INTO mysql_users (username, password, default_hostgroup, transaction_persistent) VALUES ('app', 'App#Pass2024', 10, 1);\nLOAD MYSQL USERS TO RUNTIME; SAVE MYSQL USERS TO DISK;\nINSERT INTO mysql_query_rules (rule_id, active, match_digest, destination_hostgroup, apply) VALUES (100, 1, '^SELECT .* FOR (UPDATE|SHARE)', 10, 1), (200, 1, '^SELECT ', 20, 1);\nLOAD MYSQL QUERY RULES TO RUNTIME; SAVE MYSQL QUERY RULES TO DISK;\n\n-- Dogrulama\nSELECT hostgroup_id, hostname, status FROM runtime_mysql_servers;\nSELECT hostgroup, srv_host, status, ConnUsed, Queries, Latency_us FROM stats_mysql_connection_pool;\nSELECT hostgroup, substr(digest_text, 1, 60) AS digest, count_star, sum_time / 1000 AS sum_ms FROM stats_mysql_query_digest ORDER BY sum_time DESC LIMIT 10;","what":"Writer (10) ve reader (20) hostgroup'larını read_only bayrağına göre otomatik yönetir; SELECT'leri replikalara, kilitli okumaları ve yazmaları kaynağa yönlendirir; max_replication_lag'i aşan replikayı geçici olarak devreden çıkarır (SHUNNED).","when":"Async replikasyon topolojisinde uygulamaya dokunmadan okuma yükünü dağıtmak; connection pooling ve sorgu bazlı routing / cache / firewall için.","caution":"Konfigürasyon 3 katmanlıdır (MEMORY → RUNTIME → DISK): LOAD ... TO RUNTIME olmadan etkisiz, SAVE ... TO DISK olmadan restart'ta kaybolur. read_only check'i için replikalarda super_read_only=ON şart; aksi halde replikalar writer hostgroup'a taşınır. Tüm SELECT'leri replikaya göndermek lag nedeniyle read-after-write hatası üretir; kuralları stats_mysql_query_digest'e bakarak ağır / raporlama sorgularına özel yazmak daha güvenlidir. Admin arayüzü SQLite'tır: LEFT() gibi MySQL fonksiyonları yoktur, substr() kullan. Varsayılan admin:admin hesabını değiştir (admin-admin_credentials).","note":"max_replication_lag kontrolü için monitor kullanıcısının REPLICATION CLIENT yetkisi olmalı. Group Replication / InnoDB Cluster için mysql_group_replication_hostgroups tablosu kullanılır.","since":"ProxySQL 2.0","tags":["proxysql","read write split","hostgroup","query rules","connection pool","replication lag"]},{"id":"online-ddl-instant-inplace","task":"Online DDL: ALGORITHM=INSTANT / INPLACE, LOCK=NONE ve ilerleme takibi","category":"Online İşlemler","command":"-- ALGORITHM/LOCK'u acikca yaz: desteklenmiyorsa ALTER hemen hata verir, sessizce COPY'ye dusmez\nALTER TABLE shop.orders ADD COLUMN status TINYINT NOT NULL DEFAULT 0, ALGORITHM=INSTANT;\nALTER TABLE shop.orders RENAME COLUMN note TO remark, ALGORITHM=INSTANT;\nALTER TABLE shop.orders ADD INDEX ix_status (status), ALGORITHM=INPLACE, LOCK=NONE;\nALTER TABLE shop.orders MODIFY remark VARCHAR(200), ALGORITHM=INPLACE, LOCK=NONE;\n\n-- INSTANT row version sayaci (64'e ulasinca INSTANT reddedilir, rebuild sifirlar)\nSELECT NAME, TOTAL_ROW_VERSIONS FROM information_schema.INNODB_TABLES WHERE NAME = 'shop/orders';\n\n-- Uzun ALTER'in ilerlemesi (instrument'lari bir kez ac)\nUPDATE performance_schema.setup_instruments SET ENABLED = 'YES', TIMED = 'YES' WHERE NAME LIKE 'stage/innodb/alter%';\nUPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME LIKE 'events_stages_%';\nSELECT t.PROCESSLIST_ID, s.EVENT_NAME, s.WORK_COMPLETED, s.WORK_ESTIMATED,\n       ROUND(100 * s.WORK_COMPLETED / NULLIF(s.WORK_ESTIMATED, 0), 1) AS pct_done\nFROM performance_schema.events_stages_current s\nJOIN performance_schema.threads t ON t.THREAD_ID = s.THREAD_ID\nWHERE s.EVENT_NAME LIKE 'stage/innodb/alter%';","what":"INSTANT yalnız data dictionary'yi değiştirir, tablo boyutundan bağımsız anında biter. INPLACE + LOCK=NONE tabloyu yerinde işlerken eşzamanlı okuma / yazmaya izin verir. Son sorgu çalışan ALTER'in hangi aşamada ve yüzde kaçta olduğunu gösterir.","when":"Production tablosunda şema değişikliği öncesi; hangi işlemin kesintisiz yapılabileceğini netleştirmek ve uzun ALTER'in ne zaman biteceğini tahmin etmek için.","caution":"INSTANT ve INPLACE de başta ve sonda kısa bir exclusive metadata lock alır; tabloda uzun açık transaction varsa ALTER bekler ve arkasındaki tüm sorgular kuyruğa girer (bkz. metadata lock teşhisi). Oturumda lock_wait_timeout'u düşür (SET SESSION lock_wait_timeout = 5). INPLACE sırasında gelen DML innodb_online_alter_log_max_size kadar log'lanır; aşılırsa ALTER sonunda geri alınır. Kolon tipi değişikliği, charset dönüşümü ve PK değişikliği COPY gerektirir ve yazmaları bloklar; büyük tabloda gh-ost / pt-online-schema-change kullan. Replikada ALTER aynı süre boyunca tek thread'de çalışır; büyük INPLACE ALTER replica lag üretir, INSTANT üretmez.","note":"INSTANT ADD COLUMN 8.0.12'de yalnız son kolon için geldi; 8.0.29'dan itibaren herhangi bir konuma ekleme ve INSTANT DROP COLUMN desteklenir. VARCHAR genişletme, uzunluk byte sayısı değişmiyorsa (255 byte sınırı geçilmiyorsa) yalnız metadata değişikliğidir; INSTANT değil INPLACE ile anında biter. Index'li bir kolon INSTANT ile silinemez; önce index düşürülmelidir.","since":"MySQL 8.0.29","tags":["online ddl","instant","inplace","alter table","lock=none","progress"]},{"id":"pt-online-schema-change","task":"pt-online-schema-change ile büyük tabloda kesintisiz ALTER","category":"Online İşlemler","command":"# Once --dry-run, sonra ayni komut --execute ile; replika lag'ine gore yavaslar\npt-online-schema-change --alter \"ADD COLUMN region CHAR(2) NULL, ADD INDEX ix_region (region)\" \\\n  D=shop,t=orders,h=db1,u=osc,p='Osc#2024',s=1 \\\n  --max-lag=5 --check-replica-lag h=db2,u=osc,p='Osc#2024',s=1 \\\n  --max-load Threads_running=50 --critical-load Threads_running=200 \\\n  --set-vars lock_wait_timeout=5 --noversion-check --dry-run","what":"Yeni yapıda boş bir kopya tablo oluşturur, satırları chunk'lar halinde kopyalar, kopyalama sırasında gelen değişiklikleri trigger'larla yansıtır ve sonunda atomik RENAME ile tabloları değiştirir. Yük ve replika lag'i eşiği aşınca kendiliğinden yavaşlar / durur.","when":"COPY gerektiren (kolon tipi, charset, PK değişikliği) veya replikada uzun lag yaratacak ALTER'ler için.","caution":"Tabloda PK veya unique key olmalı. Trigger'lar migration boyunca her yazmaya ek maliyet bindirir; çok yoğun yazmalı tabloda gh-ost daha az etkilidir. Child tablolar bu tabloya foreign key ile bağlıysa --alter-foreign-keys-method=auto gerekir. caching_sha2_password hesaplarında DSN'e s=1 (TLS) ekle; aksi halde replika bağlantısı 'Authentication requires secure connection' ile düşer. --check-replica-lag DSN'i kullanıcı / parolayı ana DSN'den devralmaz, açıkça yaz. Swap anında kısa metadata lock alır; lock_wait_timeout düşük tutulur, lock alınamazsa tekrar dener.","note":"Replikalar varsayılan olarak processlist üzerinden IP ile keşfedilir; IP'ler erişilemiyorsa --recursion-method=dsn=D=percona,t=dsns ile DSN tablosu kullan. 3.7 ile --check-slave-lag adı --check-replica-lag oldu (eski ad deprecated).","since":"Percona Toolkit 3.7","tags":["pt-online-schema-change","pt-osc","percona toolkit","alter","trigger","online schema change"]},{"id":"gh-ost-migration","task":"gh-ost ile trigger'sız online şema değişikliği","category":"Online İşlemler","command":"# Replikaya baglanir, binlog'u oradan okur; cut-over bayrak dosyasi silinene kadar bekler\ngh-ost --host=db2 --port=3306 --user=ghost --password='Gh0st#2024' \\\n  --database=shop --table=orders \\\n  --alter=\"ADD COLUMN channel VARCHAR(20) NULL, ADD INDEX ix_channel (channel)\" \\\n  --max-load=Threads_running=50 --critical-load=Threads_running=200 --max-lag-millis=1500 \\\n  --exact-rowcount --concurrent-rowcount --default-retries=120 \\\n  --postpone-cut-over-flag-file=/tmp/ghost.postpone --panic-flag-file=/tmp/ghost.panic \\\n  --serve-socket-file=/tmp/gh-ost.shop.orders.sock --ssl --ssl-allow-insecure --execute\n# Calisirken: durum / throttle / cut-over\necho status | nc -U /tmp/gh-ost.shop.orders.sock\necho throttle | nc -U /tmp/gh-ost.shop.orders.sock\nrm /tmp/ghost.postpone","what":"Kopya tabloyu oluşturup satırları kopyalar; eşzamanlı değişiklikleri trigger yerine binlog'u okuyarak uygular. Throttle, durdurma ve cut-over zamanı çalışırken socket veya bayrak dosyalarıyla kontrol edilir.","when":"Yoğun yazma alan büyük tablolarda trigger yükü kabul edilemediğinde ve cut-over anını (ör. düşük trafik saati) elle seçmek istediğinde.","caution":"binlog_format=ROW ve binlog_row_image=FULL gerekir; bağlanılan replikada log_replica_updates=ON olmalı. Kullanıcıya SUPER veya REPLICATION CLIENT / REPLICATION SLAVE ve tabloda ALL gerekir. Foreign key içeren (parent veya child) tabloları desteklemez. Cut-over sonrası eski tablo _<tablo>_del adıyla kalır; doğruladıktan sonra elle DROP et (--ok-to-drop-table otomatik siler). 1.1.8 öncesi gh-ost sürümleri SHOW SLAVE STATUS kullandığından MySQL 8.4'te 1064 hatasıyla durur; 8.4 desteği 1.1.8 ile geldi. --postpone-cut-over-flag-file ile verilen dosyayı gh-ost kendisi oluşturur; dosya silinmeden cut-over yapılmaz.","note":"--test-on-replica ve --migrate-on-replica seçenekleri değişikliği önce yalnız bir replikada deneyip doğrulamaya izin verir. Throttle sebebi ve kalan süre 'status' komutunun çıktısında görünür.","tags":["gh-ost","online schema change","binlog","cut-over","alter","triggerless"]},{"id":"ps-top-digests","task":"En pahalı sorguları bul (performance_schema digest)","category":"Performans","command":"SELECT SCHEMA_NAME AS db,\n       LEFT(DIGEST_TEXT, 80) AS query,\n       COUNT_STAR AS calls,\n       ROUND(SUM_TIMER_WAIT / 1e12, 2) AS total_sec,\n       ROUND(AVG_TIMER_WAIT / 1e9, 2) AS avg_ms,\n       ROUND(QUANTILE_95 / 1e9, 2) AS p95_ms,\n       ROUND(100 * SUM_TIMER_WAIT / SUM(SUM_TIMER_WAIT) OVER (), 1) AS pct_total,\n       ROUND(SUM_ROWS_EXAMINED / NULLIF(COUNT_STAR, 0)) AS rows_exam_per_call,\n       ROUND(SUM_ROWS_SENT / NULLIF(COUNT_STAR, 0)) AS rows_sent_per_call,\n       SUM_NO_INDEX_USED AS no_index,\n       SUM_CREATED_TMP_DISK_TABLES AS tmp_disk,\n       LAST_SEEN\nFROM performance_schema.events_statements_summary_by_digest\nWHERE SCHEMA_NAME IS NOT NULL\nORDER BY SUM_TIMER_WAIT DESC\nLIMIT 20;\n\n-- Sunucu genelinde en cok beklenen wait event'ler\nSELECT events, total, total_latency, avg_latency FROM sys.waits_global_by_latency LIMIT 10;","what":"Normalize edilmiş sorguları toplam süreye göre sıralar; çağrı sayısı, ortalama ve p95 süre, toplam içindeki pay, çağrı başına okunan / dönen satır, index kullanmayan çalıştırma ve diske düşen temp tablo sayısını verir. İkinci sorgu zamanın hangi wait'lerde (IO, lock, redo) harcandığını gösterir.","when":"CPU / IO yükü arttığında veya 'veritabanı yavaş' şikâyetinde ilk bakılacak yer; slow log kapalıyken de çalışır.","caution":"Değerler son restart'tan veya TRUNCATE TABLE performance_schema.events_statements_summary_by_digest'ten bu yana kümülatiftir; anlık durumu görmek için iki görüntü alıp farkına bak. Tablo performance_schema_digests_size satırla sınırlıdır; dolarsa yeni sorgular DIGEST'i NULL olan tek satırda toplanır. DIGEST_TEXT performance_schema_max_digest_length (1024) byte'ta kesilir. Zamanlar picosaniyedir. rows_exam_per_call / rows_sent_per_call oranının yüksek olması eksik index'in en net işaretidir.","note":"QUANTILE_95 / QUANTILE_99 ve QUERY_SAMPLE_TEXT sütunları 8.0 ile geldi. Aynı veri okunur birimlerle sys.statement_analysis ve sys.statements_with_full_table_scans view'larında da var.","since":"MySQL 8.0","tags":["performance_schema","digest","top sql","slow query","sys","wait"]},{"id":"sys-session-activity","task":"Şu anda ne çalışıyor: aktif oturumlar, süre, lock ve transaction (sys.session)","category":"Performans","command":"SELECT conn_id, user, db, command, state, time,\n       LEFT(current_statement, 100) AS current_statement,\n       statement_latency, progress, lock_latency,\n       rows_examined, full_scan, tmp_disk_tables,\n       trx_state, trx_latency, last_wait\nFROM sys.session\nWHERE command <> 'Sleep' OR trx_state = 'ACTIVE'\nORDER BY time DESC\nLIMIT 25;","what":"SHOW PROCESSLIST'i performance_schema verisiyle zenginleştirir: çalışan sorgunun gecikmesi, ilerleme yüzdesi, lock bekleme süresi, taranan satır, full scan / disk temp tablo bilgisi ve açık transaction durumu tek satırda görünür. Sleep durumunda olup transaction'ı açık kalan oturumları da listeler.","when":"Olay anında ilk 30 saniyede: hangi sorgu ne kadar süredir çalışıyor, kim lock bekliyor, hangi idle oturum transaction'ı açık tutuyor.","caution":"sys.session performance_schema'ya birden çok join yapar; binlerce bağlantıda sorgunun kendisi saniyeler sürebilir, sık aralıklı monitoring'de x$ view'larını ve LIMIT kullan. progress yalnız stage instrument'ları açıkken ve ALTER gibi ilerleme raporlayan işlemlerde dolar. Sleep + trx_state=ACTIVE olan oturum, autocommit=0 kullanan uygulamanın / connection pool'un unuttuğu transaction'dır ve metadata lock ile purge sorunlarının en yaygın nedenidir.","note":"sys.processlist aynı veriyi arka plan thread'leri dahil verir. Sonlandırmak için KILL QUERY conn_id (yalnız sorgu) veya KILL conn_id (bağlantı, transaction rollback edilir).","since":"MySQL 8.0","tags":["sys.session","processlist","active sessions","incident","trx","oturum"]},{"id":"metadata-lock-diagnose","task":"'Waiting for table metadata lock' teşhisi ve asıl bloklayanı bulma","category":"Performans","command":"-- Bekleyen -> bloklayan eslesmesi; ALTER'in kendi SHARED_UPGRADABLE kaydini ele\nSELECT object_schema, object_name, waiting_pid, LEFT(waiting_query, 60) AS waiting_query,\n       waiting_lock_type, blocking_pid, blocking_lock_type, sql_kill_blocking_connection\nFROM sys.schema_table_lock_waits\nWHERE blocking_lock_type <> 'SHARED_UPGRADABLE';\n\n-- Tablo uzerindeki tum MDL'ler, sahibinin yasi ve acik transaction'i\nSELECT ml.OBJECT_SCHEMA, ml.OBJECT_NAME, ml.LOCK_TYPE, ml.LOCK_DURATION, ml.LOCK_STATUS,\n       t.PROCESSLIST_ID AS conn_id, t.PROCESSLIST_COMMAND AS command, t.PROCESSLIST_TIME AS sec,\n       LEFT(t.PROCESSLIST_INFO, 60) AS query, trx.trx_started\nFROM performance_schema.metadata_locks ml\nJOIN performance_schema.threads t ON t.THREAD_ID = ml.OWNER_THREAD_ID\nLEFT JOIN information_schema.INNODB_TRX trx ON trx.trx_mysql_thread_id = t.PROCESSLIST_ID\nWHERE ml.OBJECT_TYPE = 'TABLE' AND ml.OBJECT_SCHEMA NOT IN ('performance_schema', 'mysql')\nORDER BY ml.OBJECT_NAME, ml.LOCK_STATUS DESC;","what":"ALTER / TRUNCATE / RENAME gibi bir DDL'in hangi oturumun tuttuğu metadata lock yüzünden beklediğini ve DDL'in arkasında kuyruğa giren sorguları gösterir. Bloklayan çoğu zaman tabloyu okuyup transaction'ı kapatmamış, Sleep durumundaki bir oturumdur.","when":"Bir ALTER başladıktan sonra o tabloya gelen tüm sorgular 'Waiting for table metadata lock' durumunda yığıldığında.","caution":"Bekleyen DDL, kendisinden sonra gelen SELECT'leri de bloklar; olay anında hızlı karar ver: ya bloklayan oturumu KILL et ya da ALTER'i iptal et (KILL QUERY). Bloklayanın PROCESSLIST_INFO'su NULL olabilir (idle); son sorgusunu görmek için performance_schema.events_statements_history veya sys.session.last_statement kullan. Önleme: DDL öncesi SET SESSION lock_wait_timeout = 5 ile ALTER'in kısa sürede vazgeçmesini sağla ve uygulamada uzun açık transaction bırakma.","note":"wait/lock/metadata/sql/mdl instrument'ı 8.0'da varsayılan açıktır; 5.7'de setup_instruments'tan açılması gerekir. sys.schema_table_lock_waits bir ALTER için kendi SHARED_UPGRADABLE lock'unu da bloklayan olarak listeler; asıl suçlu GRANTED SHARED_READ / SHARED_WRITE tutan oturumdur.","since":"MySQL 8.0","tags":["metadata lock","mdl","alter","waiting for table metadata lock","lock","blocking"]},{"id":"innodb-deadlock-analysis","task":"InnoDB deadlock analizi ve tüm deadlock'ları loglama","category":"Performans","command":"-- Son deadlock: LATEST DETECTED DEADLOCK bolumu (yalniz en sonuncusu tutulur)\nSHOW ENGINE INNODB STATUS\\G\n-- Toplam deadlock sayaci\nSELECT NAME, COUNT FROM information_schema.INNODB_METRICS WHERE NAME = 'lock_deadlocks';\n-- Tum deadlock'lari error log'a yaz (Note seviyesinde yazilir, verbosity 3 gerekir)\nSET PERSIST innodb_print_all_deadlocks = ON;\nSET PERSIST log_error_verbosity = 3;","what":"Deadlock'a giren iki transaction'ı, her birinin tuttuğu ve beklediği lock'u (index, lock_mode, kayıt) ve InnoDB'nin hangisini rollback ettiğini gösterir; sayaçla sıklık izlenir, error log ile geçmiş deadlock'lar kaybolmaz.","when":"Uygulama 1213 'Deadlock found when trying to get lock' hatası aldığında veya deadlock alarmı arttığında.","caution":"LATEST DETECTED DEADLOCK yalnız son olayı tutar ve restart'ta kaybolur. 'HOLDS THE LOCK(S)' / 'WAITING FOR THIS LOCK TO BE GRANTED' satırlarındaki index adı ve lock_mode (X, S, gap, insert intention) nedeni verir; 'WE ROLL BACK TRANSACTION (n)' kurbanı gösterir. Uygulama 1213'te transaction'ı baştan yeniden denemeli. Kalıcı çözüm: satırlara hep aynı sırayla erişmek, transaction'ları kısa tutmak, gap lock'u azaltmak için doğru index ve gerekiyorsa READ COMMITTED. log_error_verbosity=3 tüm Note mesajlarını da açar; error log büyümesini izle. Innodb_deadlocks status değişkeni MySQL Community'de yoktur; sayaç için INNODB_METRICS kullan.","note":"Çok yüksek eşzamanlılıkta deadlock detection'ın kendisi CPU darboğazı olabilir; innodb_deadlock_detect=OFF yalnız innodb_lock_wait_timeout düşük ayarlıyken düşünülür. Lock wait timeout (1205) deadlock değildir; o durumda blocking-locks reçetesiyle bloklayanı bul.","since":"MySQL 8.0","tags":["deadlock","innodb","1213","innodb status","lock","error log"]},{"id":"long-trx-history-list","task":"Uzun açık transaction'lar ve history list length (purge gecikmesi)","category":"Performans","command":"-- Purge edilmeyi bekleyen undo kayitlari (milyonlar = sorun)\nSELECT NAME, COUNT AS history_list_length\nFROM information_schema.INNODB_METRICS WHERE NAME = 'trx_rseg_history_len';\n\n-- En eski transaction'lar, sahibi ve son SQL'i\nSELECT trx.trx_id, trx.trx_mysql_thread_id AS conn_id, trx.trx_state,\n       TIMESTAMPDIFF(SECOND, trx.trx_started, NOW()) AS age_sec,\n       trx.trx_rows_modified, trx.trx_rows_locked, trx.trx_isolation_level,\n       p.USER, p.HOST, p.COMMAND, p.TIME AS state_sec,\n       LEFT(COALESCE(trx.trx_query, esc.SQL_TEXT), 80) AS current_or_last_sql\nFROM information_schema.INNODB_TRX trx\nJOIN performance_schema.processlist p ON p.ID = trx.trx_mysql_thread_id\nLEFT JOIN performance_schema.threads th ON th.PROCESSLIST_ID = trx.trx_mysql_thread_id\nLEFT JOIN performance_schema.events_statements_current esc ON esc.THREAD_ID = th.THREAD_ID\nORDER BY trx.trx_started\nLIMIT 10;","what":"Purge'ün ne kadar geride olduğunu (history list length) ve purge'ü tutan en eski transaction'ları; sahibini, yaşını, değiştirdiği satır sayısını ve çalıştırdığı son SQL'i gösterir.","when":"Undo tablespace büyüdüğünde, aynı sorgular zamanla yavaşladığında (eski satır versiyonlarını taradıkları için) veya disk alanı alarmında.","caution":"En yaygın neden Sleep durumunda ama transaction'ı açık bir oturum veya REPEATABLE READ'de unutulmuş consistent snapshot'tır (ör. yarıda bırakılmış bir mysqldump / rapor). KILL sonrası rollback, transaction'ın değiştirdiği satır kadar sürer; trx_rows_modified yüksek bir transaction'ı öldürmek uzun ve IO yoğun bir rollback demektir, restart da bu süreyi kısaltmaz. Undo, purge ilerledikçe kendiliğinden truncate edilir (innodb_undo_log_truncate=ON).","note":"performance_schema.processlist 8.0.22 ile geldi ve deprecated olan information_schema.PROCESSLIST'in yerine geçer. SHOW ENGINE INNODB STATUS'taki 'History list length' aynı değeri verir.","since":"MySQL 8.0.22","tags":["history list length","purge","undo","long transaction","innodb_trx","uzun transaction"]},{"id":"slow-log-pt-query-digest","task":"Slow log'u kısa süreli tam yakala ve pt-query-digest ile analiz et","category":"Performans","command":"-- Gecici tam yakalama (ornegin 10 dakika); yalniz yeni baglantilar etkilenir\nSET GLOBAL slow_query_log_file = '/var/lib/mysql/slow.log';\nSET GLOBAL log_slow_extra = ON;\nSET GLOBAL long_query_time = 0;\nSET GLOBAL slow_query_log = ON;\n-- ... sonra normal esige don\nSET GLOBAL long_query_time = 1;\n\n# Shell: toplam sureye gore ilk 10 sorgu\npt-query-digest --limit=10 --order-by=Query_time:sum --noversion-check /var/lib/mysql/slow.log > /tmp/digest.txt\npt-query-digest --since='2026-10-08 09:00:00' --until='2026-10-08 10:00:00' --filter '$event->{db} && $event->{db} eq \"shop\"' --report-format=profile --noversion-check /var/lib/mysql/slow.log","what":"long_query_time=0 ile kısa bir pencerede tüm sorguları yakalar; pt-query-digest bunları fingerprint'e göre gruplayıp toplam / ortalama / p95 süre, taranan satır ve örnek sorguyla sıralı rapor üretir.","when":"performance_schema digest'in yetmediği durumlarda: tam sorgu metni ve gerçek parametrelerle analiz, deploy öncesi / sonrası karşılaştırma, başka sunucuda offline inceleme.","caution":"long_query_time oturum başında global'den kopyalanır; connection pool'daki mevcut bağlantılar yeni eşiği yeniden bağlanana kadar görmez. long_query_time=0 yoğun sunucuda saniyede binlerce satır yazar; disk alanını ve IO'yu izle, pencereyi kısa tut ve sonra mutlaka geri al. Analiz için dosyayı production dışına kopyala. pt-query-digest'i çalıştıran kullanıcının dosyayı okuma izni olmalı (dosya 640, mysql:mysql).","note":"log_slow_extra (8.0.14) Bytes_sent, Read_first / Read_next, Created_tmp_disk_tables gibi ek alanları yazar; pt-query-digest bunları raporda gösterir. Kalıcı açma / kapama için enable-general-slow-log reçetesine bak.","since":"MySQL 8.0.14","tags":["slow log","pt-query-digest","long_query_time","percona toolkit","query analysis","yavaş sorgu"]},{"id":"explain-analyze-optimizer-trace","task":"EXPLAIN ANALYZE ve optimizer trace ile kötü planı çöz","category":"Performans","command":"-- Plan + gercek sure ve satir (sorgu gercekten calisir)\nEXPLAIN ANALYZE\nSELECT region, COUNT(*) FROM shop.big WHERE id < 20000 GROUP BY region;\n\n-- Optimizer neden bu plani secti: optimizer trace\nSET SESSION optimizer_trace = 'enabled=on', SESSION optimizer_trace_max_mem_size = 1048576;\nSELECT * FROM shop.big WHERE region = 'TR' AND id > 100 LIMIT 5;\nSELECT JSON_PRETTY(JSON_EXTRACT(TRACE, '$**.considered_execution_plans')) AS plans,\n       MISSING_BYTES_BEYOND_MAX_MEM_SIZE\nFROM information_schema.OPTIMIZER_TRACE;\nSET SESSION optimizer_trace = 'enabled=off';","what":"EXPLAIN ANALYZE her plan adımı için tahmini (cost, rows) ve gerçekleşen (actual time, rows, loops) değerleri yan yana verir; optimizer trace değerlendirilen erişim yollarını, maliyetlerini ve neden seçilip elendiklerini gösterir.","when":"Sorgu aniden yavaşladığında (plan değişimi), optimizer yanlış index seçtiğinde veya tahmini / gerçek satır farkının kaynağını bulmak için.","caution":"EXPLAIN ANALYZE sorguyu gerçekten çalıştırır; ağır sorguda production'da dikkat. SELECT, TABLE ve çok tablolu UPDATE / DELETE ile çalışır. Tahmini ve gerçek rows arasında 10 kattan büyük fark istatistik / histogram sorununa işaret eder (ANALYZE TABLE, histogram). Nested loop'un iç tarafında actual rows tek bir loop içindir; toplam = rows × loops. MISSING_BYTES_BEYOND_MAX_MEM_SIZE > 0 ise trace kesilmiştir; optimizer_trace_max_mem_size'ı artır. Trace yalnız aynı oturumda son çalışan sorguyu tutar.","note":"EXPLAIN FORMAT=TREE 8.0.16, EXPLAIN ANALYZE 8.0.18 ile geldi. Planı sabitlemek için optimizer hint'leri (/*+ INDEX(t ix) */, JOIN_ORDER) FORCE INDEX'e göre daha ince kontrol sağlar.","since":"MySQL 8.0.18","tags":["explain analyze","optimizer trace","execution plan","query tuning","index","plan"]},{"id":"histogram-statistics","task":"Index'siz kolonlar için histogram oluştur ve yönet","category":"Index & İstatistik","command":"ANALYZE TABLE shop.big UPDATE HISTOGRAM ON status WITH 64 BUCKETS;\n-- 8.4+: veri degistikce otomatik guncellenen histogram\nANALYZE TABLE shop.big UPDATE HISTOGRAM ON status WITH 64 BUCKETS AUTO UPDATE;\n\nSELECT SCHEMA_NAME, TABLE_NAME, COLUMN_NAME,\n       HISTOGRAM->>'$.\"histogram-type\"' AS type,\n       JSON_LENGTH(HISTOGRAM->'$.buckets') AS buckets,\n       HISTOGRAM->>'$.\"last-updated\"' AS last_updated,\n       HISTOGRAM->>'$.\"sampling-rate\"' AS sampling_rate\nFROM information_schema.COLUMN_STATISTICS;\n\nANALYZE TABLE shop.big DROP HISTOGRAM ON status;","what":"Kolondaki değer dağılımını (singleton veya equi-height) data dictionary'de saklar; optimizer index'i olmayan kolonlardaki filtrelerin seçiciliğini doğru tahmin eder, join sırası ve plan kalitesi düzelir.","when":"Çarpık dağılımlı (ör. status, type) ve index eklenmesi istenmeyen kolonlarda EXPLAIN ANALYZE tahmini ile gerçek satır sayısı çok farklıysa.","caution":"Index'li kolonda optimizer index dive kullandığından histogram genellikle etkisizdir (eq_range_index_dive_limit aşılmadıkça). Varsayılan MANUAL modda histogram veri değiştikçe güncellenmez; periyodik ANALYZE ... UPDATE HISTOGRAM gerekir. Büyük tabloda histogram_generation_max_mem_size'a göre örnekleme yapılır (sampling-rate < 1). ANALYZE TABLE kısa bir metadata lock alır; histogram güncellemesi tablo istatistiğini (index cardinality) değiştirmez.","note":"Histogramlar 8.0 ile geldi; AUTO UPDATE seçeneği 8.4'te eklendi ve otomatik istatistik yeniden hesaplamasıyla birlikte tazelenir. Bucket sayısı en fazla 1024'tür; farklı değer sayısı bucket sayısından azsa singleton histogram oluşur.","since":"MySQL 8.0","tags":["histogram","statistics","optimizer","analyze table","selectivity","istatistik"]},{"id":"invisible-redundant-index","task":"Kullanılmayan / gereksiz index'i bul, invisible yap, güvenle sil","category":"Index & İstatistik","command":"-- Aday 1: restart'tan beri hic kullanilmamis index'ler\nSELECT * FROM sys.schema_unused_indexes WHERE object_schema = 'shop';\n-- Aday 2: baska bir index'in sol on eki olan (redundant) index'ler\nSELECT table_name, redundant_index_name, redundant_index_columns, dominant_index_name, sql_drop_index\nFROM sys.schema_redundant_indexes WHERE table_schema = 'shop';\n\n-- Silmeden once gorunmez yap; sorun cikarsa aninda geri al\nALTER TABLE shop.big ALTER INDEX ix_region INVISIBLE;\nSELECT INDEX_NAME, IS_VISIBLE FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = 'shop' AND TABLE_NAME = 'big' AND SEQ_IN_INDEX = 1;\n-- Tek sorguda gorunmez index'i dene\nEXPLAIN SELECT /*+ SET_VAR(optimizer_switch = 'use_invisible_indexes=on') */ COUNT(*) FROM shop.big WHERE region = 'TR';\nALTER TABLE shop.big ALTER INDEX ix_region VISIBLE;\n-- Birkac is dongusu (ay sonu dahil) sorunsuz gecerse\nALTER TABLE shop.big DROP INDEX ix_region, ALGORITHM=INPLACE, LOCK=NONE;","what":"Kullanılmayan ve başka bir index tarafından kapsanan index'leri listeler; silmeden önce index'i invisible yaparak optimizer'ın onu kullanmadığı durumu canlıda test etmeye ve gerekirse anında (yeniden build etmeden) geri almaya izin verir.","when":"Yazma maliyetini, buffer pool baskısını ve disk kullanımını azaltmak için index temizliği yaparken.","caution":"schema_unused_indexes yalnız son restart'tan bu yana toplanan istatistiğe dayanır; aylık rapor gibi seyrek sorgular görünmeyebilir. Replikalarda farklı sorgu yükü varsa her sunucuda ayrı kontrol et. Invisible index DML'de güncellenmeye devam eder (yazma maliyeti sürer) ama optimizer kullanmaz; unique index invisible olsa da unique constraint'i uygulanır. PRIMARY KEY invisible yapılamaz. Index'i FORCE INDEX / USE INDEX ile adıyla kullanan sorgular, index invisible olunca hata verir.","note":"Index görünürlüğünü değiştirmek yalnız metadata değişikliğidir, anında biter. Redundant listesi kolon sırasına bakar; (a) index'i (a,b) tarafından kapsanır ama (b) kapsanmaz.","since":"MySQL 8.0","tags":["invisible index","unused index","redundant index","sys","drop index","index temizliği"]},{"id":"buffer-pool-sizing","task":"Buffer pool yeterli mi: hit oranı, wait_free ve online resize","category":"Bellek","command":"SELECT ROUND(@@innodb_buffer_pool_size / 1024 / 1024) AS bp_mb,\n       @@innodb_buffer_pool_chunk_size / 1024 / 1024 AS chunk_mb,\n       @@innodb_buffer_pool_instances AS instances;\nSELECT\n  ROUND(100 * (1 - (SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME = 'Innodb_buffer_pool_reads')\n                 / NULLIF((SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME = 'Innodb_buffer_pool_read_requests'), 0)), 3) AS hit_pct,\n  (SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME = 'Innodb_buffer_pool_pages_free') AS pages_free,\n  (SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME = 'Innodb_buffer_pool_pages_dirty') AS pages_dirty,\n  (SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME = 'Innodb_buffer_pool_wait_free') AS wait_free;\n\n-- Online resize ve durum takibi\nSET PERSIST innodb_buffer_pool_size = 8589934592;\nSELECT VARIABLE_NAME, VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME LIKE 'Innodb_buffer_pool_resize_status%';","what":"Buffer pool boyutunu, cache hit oranını, boş / dirty sayfa sayısını ve boş sayfa bekleme (wait_free) sayacını gösterir; boyutu restart'sız değiştirip ilerlemesini izler.","when":"Disk okuma IO'su yüksekken, sunucuya RAM eklendiğinde / çıkarıldığında veya kapasite planlamada.","caution":"Hit oranı tek başına yanıltıcıdır; %99 bile saniyede binlerce disk okuması olabilir. Innodb_buffer_pool_reads'in saniyelik artışına bak; wait_free > 0 buffer pool'un dar olduğunu veya page cleaner'ın yetişemediğini gösterir. Yeni boyut innodb_buffer_pool_chunk_size × instances katına yuvarlanır. Resize sırasında kısa süreli bekleme olabilir, küçültmede daha belirgindir; yoğun saatte yapma. Dedicated sunucuda başlangıç RAM'in %60–75'idir; bağlantı başına bellek, OS cache ve diğer süreçler için pay bırak, swap'e düşmek her zaman küçük buffer pool'dan kötüdür.","note":"Innodb_buffer_pool_resize_status_code / _progress 8.0.31 ile geldi. innodb_dedicated_server=ON buffer pool ve redo kapasitesini RAM'e göre otomatik ayarlar. Tablo bazında buffer pool kullanımı için sys.innodb_buffer_stats_by_table vardır; INNODB_BUFFER_PAGE'i taradığı için büyük buffer pool'da ağırdır.","since":"MySQL 8.0","tags":["buffer pool","innodb","memory","hit ratio","resize","bellek"]},{"id":"partition-maintenance","task":"RANGE partition bakımı: ileri partition aç, eskiyi arşivle / düşür","category":"Partition","command":"-- Mevcut partition'lar\nSELECT PARTITION_NAME, PARTITION_DESCRIPTION, TABLE_ROWS\nFROM information_schema.PARTITIONS\nWHERE TABLE_SCHEMA = 'shop' AND TABLE_NAME = 'events_log' ORDER BY PARTITION_ORDINAL_POSITION;\n\n-- Bos pmax'i bolerek yeni ay ekle\nALTER TABLE shop.events_log REORGANIZE PARTITION pmax INTO (\n  PARTITION p2026_11 VALUES LESS THAN ('2026-12-01'),\n  PARTITION pmax VALUES LESS THAN (MAXVALUE));\n\n-- Eski ayi arsiv tablosuna tasi (aninda), sonra bos partition'i dusur\nCREATE TABLE shop.events_log_2026_08 LIKE shop.events_log;\nALTER TABLE shop.events_log_2026_08 REMOVE PARTITIONING;\nALTER TABLE shop.events_log EXCHANGE PARTITION p2026_08 WITH TABLE shop.events_log_2026_08;\nALTER TABLE shop.events_log DROP PARTITION p2026_08;\n\n-- Pruning kontrolu: partitions sutununda tek partition gorunmeli\nEXPLAIN SELECT * FROM shop.events_log WHERE created >= '2026-10-01' AND created < '2026-11-01';","what":"Tarih bazlı RANGE partition'lı tabloda yeni dönem partition'ı ekler, eski dönemi EXCHANGE ile milisaniyeler içinde ayrı tabloya taşır ve partition'ı DELETE'e göre çok daha ucuz biçimde düşürür.","when":"Log / event / audit gibi zamanla büyüyen tablolarda aylık retention ve arşiv işlerinde.","caution":"Partition kolonu tüm unique key'lerde (PK dahil) bulunmalı. REORGANIZE PARTITION pmax, pmax'taki veriyi yeniden yazar; pmax'ı boş tut ve partition'ları önceden (ör. 3 ay ileri) aç. DROP PARTITION geri alınamaz ve satır satır binlog'a yazılmaz; replikada da DDL olarak çalışır. EXCHANGE hedefi aynı yapıda ve partition'sız olmalı; satırlar aralığa uymuyorsa hata verir (WITHOUT VALIDATION hızlıdır ama yanlış veriyi içeri alabilir). Partition DDL'leri tablo düzeyinde metadata lock alır. Pruning için WHERE'de partition kolonu fonksiyona sarılmadan kullanılmalı.","note":"8.0'da partitioning yalnız InnoDB (ve NDB) ile desteklenir. İleri partition ekleme / eski partition düşürme genellikle Event Scheduler veya cron ile otomatikleştirilir; ALTER TABLE ... TRUNCATE PARTITION veriyi silip partition'ı korur.","since":"MySQL 8.0","tags":["partition","range","reorganize","exchange partition","retention","archive"]},{"id":"roles-least-privilege","task":"Rol tabanlı en az yetki modeli kur (CREATE ROLE, DEFAULT ROLE)","category":"Güvenlik","command":"CREATE ROLE IF NOT EXISTS 'app_read', 'app_write';\nGRANT SELECT ON shop.* TO 'app_read';\nGRANT INSERT, UPDATE, DELETE ON shop.* TO 'app_write';\n\n-- Uygulama hesabi: ag araligi, TLS zorunlu, roller varsayilan aktif\nCREATE USER 'svc_app'@'10.0.%' IDENTIFIED BY 'S3cure#App2024' DEFAULT ROLE 'app_read', 'app_write' REQUIRE SSL;\nCREATE USER 'ana'@'%' IDENTIFIED BY 'An4#Report2024';\nGRANT 'app_read' TO 'ana'@'%';\nSET DEFAULT ROLE ALL TO 'ana'@'%';\n\n-- Rollerin acilmis yetkileriyle birlikte goster\nSHOW GRANTS FOR 'svc_app'@'10.0.%' USING 'app_read', 'app_write';\nSELECT FROM_USER, FROM_HOST, TO_USER, TO_HOST FROM mysql.role_edges;","what":"Yetkileri kullanıcılara tek tek değil rollere verir; hesaplar rol üyeliğiyle yetki alır. Yetki değişikliği tek noktadan yapılır, denetim ve offboarding kolaylaşır.","when":"Yeni uygulama / ekip hesabı açarken ve yetki karmaşası olan eski sunucuları toparlarken.","caution":"Rol varsayılan rol yapılmazsa oturumda aktif olmaz (CURRENT_ROLE() NONE) ve kullanıcı yetkisiz görünür; SET DEFAULT ROLE ALL veya activate_all_roles_on_login=ON. Rol de bir hesaptır (kilitli, parolasız) ve mysql.user'da görünür. Host'u '%' olan uygulama hesapları yerine ağ aralığı kullan. Uygulama hesabına ALL, SUPER, FILE, PROCESS, CONNECTION_ADMIN verme. Rolden yetki geri alındığında aktif oturumlar da etkilenir.","note":"mandatory_roles ile tüm hesaplara otomatik rol atanabilir. CREATE USER ... DEFAULT ROLE rolleri hem atar hem varsayılan yapar.","since":"MySQL 8.0","tags":["role","grant","least privilege","default role","security","yetki"]},{"id":"password-policy-lockout","task":"Parola politikası, hatalı giriş kilidi ve kesintisiz parola rotasyonu","category":"Güvenlik","command":"-- Parola gucu politikasi (component)\nINSTALL COMPONENT 'file://component_validate_password';\nSET PERSIST validate_password.policy = 'MEDIUM';\nSET PERSIST validate_password.length = 12;\nSELECT VALIDATE_PASSWORD_STRENGTH('Summer2024') AS score;\n\n-- Hatali giris kilidi, parola omru, gecmis\nALTER USER 'ana'@'%' FAILED_LOGIN_ATTEMPTS 5 PASSWORD_LOCK_TIME 1\n  PASSWORD EXPIRE INTERVAL 90 DAY PASSWORD HISTORY 5 PASSWORD REUSE INTERVAL 365 DAY;\n\n-- Kesintisiz rotasyon: dual password\nALTER USER 'svc_app'@'10.0.%' IDENTIFIED BY 'N3w#AppSecret2025' RETAIN CURRENT PASSWORD;\n-- Tum uygulamalar yeni parolaya gecince\nALTER USER 'svc_app'@'10.0.%' DISCARD OLD PASSWORD;","what":"Zayıf parolaları reddeden politikayı açar, art arda hatalı girişte hesabı geçici kilitler, parola ömrü ve tekrar kullanım kuralı koyar; dual password ile servis hesabının parolası uygulamalar sırayla güncellenirken kesintisiz değiştirilir.","when":"Güvenlik denetimi / uyum (PCI, ISO 27001) gereklerinde ve servis hesabı parola rotasyonunda.","caution":"Politika yalnız yeni / değişen parolalara uygulanır; mevcut zayıf parolaları tespit etmez. Servis hesaplarında FAILED_LOGIN_ATTEMPTS, yanlış yapılandırılmış tek bir istemcinin hesabı kilitleyip kesinti yaratmasına yol açabilir; insan hesaplarında kullan. PASSWORD_LOCK_TIME gün cinsindendir (UNBOUNDED: elle açılana kadar); kilidi açmak için ALTER USER ... ACCOUNT UNLOCK. PASSWORD EXPIRE servis hesaplarında beklenmedik kesintiye yol açar; orada PASSWORD EXPIRE NEVER ve dual password rotasyonu tercih et.","note":"Dual password 8.0.14, FAILED_LOGIN_ATTEMPTS / PASSWORD_LOCK_TIME 8.0.19 ile geldi. 5.7'deki validate_password plugin'i 8.0'da component ile değişti; değişken adları noktalıdır (validate_password.policy).","since":"MySQL 8.0.19","tags":["password policy","validate_password","failed_login_attempts","dual password","security","parola"]},{"id":"require-tls-transport","task":"TLS'i zorunlu kıl, TLS'siz bağlantıları bul, sertifikayı restart'sız yenile","category":"Güvenlik","command":"SELECT @@require_secure_transport, @@tls_version, @@ssl_ca, @@ssl_cert;\nSELECT * FROM performance_schema.tls_channel_status\nWHERE PROPERTY IN ('Enabled', 'Current_tls_version', 'Current_tls_cert', 'Ssl_server_not_after');\n\n-- Aktif baglantilar ve TLS surumleri (bos = TLS yok)\nSELECT t.PROCESSLIST_USER AS user, t.PROCESSLIST_HOST AS host, t.CONNECTION_TYPE, sv.VARIABLE_VALUE AS tls_version\nFROM performance_schema.threads t\nLEFT JOIN performance_schema.status_by_thread sv ON sv.THREAD_ID = t.THREAD_ID AND sv.VARIABLE_NAME = 'Ssl_version'\nWHERE t.TYPE = 'FOREGROUND' AND t.PROCESSLIST_USER IS NOT NULL;\n\nSET PERSIST require_secure_transport = ON;\n-- Yeni sertifika dosyalarini kopyaladiktan sonra\nALTER INSTANCE RELOAD TLS;","what":"Sunucunun TLS yapılandırmasını, sertifika bitiş tarihini ve her bağlantının TLS kullanıp kullanmadığını gösterir; TCP üzerinden şifresiz bağlantıyı tamamen yasaklar ve sertifikayı sunucuyu durdurmadan yeniler.","when":"Güvenlik denetimi / uyum gereğinde, sertifika süresi dolmadan önce ve şifresiz bağlanan eski istemcileri tespit ederken.","caution":"require_secure_transport=ON Unix socket ve shared memory bağlantılarını etkilemez; bunlar güvenli sayılır. Açmadan önce TLS'siz bağlanan istemcileri bul; aksi halde 3159 hatasıyla bağlanamazlar. ALTER INSTANCE RELOAD TLS mevcut bağlantıları etkilemez, yalnız yenilere uygulanır; sertifika dosyası hatalıysa hata verir ve eski sertifikayla devam eder. Otomatik üretilen self-signed sertifika istemcide VERIFY_CA / VERIFY_IDENTITY ile doğrulanamaz; production'da kurum CA'sıyla imzalı sertifika kullan.","note":"ALTER INSTANCE RELOAD TLS 8.0.16, performance_schema.tls_channel_status 8.0.21 ile geldi. Hesap bazında zorunluluk için ALTER USER ... REQUIRE SSL (veya REQUIRE X509).","since":"MySQL 8.0.21","tags":["tls","ssl","require_secure_transport","certificate","encryption","sertifika"]},{"id":"risky-accounts-audit","task":"Riskli hesapları denetle: boş parola, '%' host, SUPER, mysql_native_password","category":"Güvenlik","command":"SELECT user, host, plugin,\n       CONCAT_WS(', ',\n         IF(authentication_string = '' AND account_locked = 'N', 'EMPTY PASSWORD', NULL),\n         IF(host = '%', 'ANY HOST', NULL),\n         IF(plugin = 'mysql_native_password', 'NATIVE AUTH', NULL),\n         IF(Super_priv = 'Y', 'SUPER', NULL),\n         IF(Grant_priv = 'Y', 'GRANT OPTION', NULL),\n         IF(File_priv = 'Y', 'FILE', NULL),\n         IF(ssl_type = '', 'NO TLS REQUIRED', NULL),\n         IF(password_expired = 'Y', 'EXPIRED', NULL),\n         IF(account_locked = 'Y', 'LOCKED', NULL)) AS findings,\n       password_last_changed\nFROM mysql.user\nWHERE user NOT IN ('mysql.sys', 'mysql.session', 'mysql.infoschema')\nORDER BY (Super_priv = 'Y') DESC, user;\n\n-- Guclu dinamik yetkilere sahip hesaplar\nSELECT GRANTEE, PRIVILEGE_TYPE FROM information_schema.USER_PRIVILEGES\nWHERE PRIVILEGE_TYPE IN ('SUPER', 'SYSTEM_VARIABLES_ADMIN', 'CONNECTION_ADMIN', 'BINLOG_ADMIN', 'REPLICATION_SLAVE_ADMIN')\nORDER BY GRANTEE;","what":"Her hesap için güvenlik bulgularını tek satırda listeler: parolasız, her yerden bağlanabilen, eski kimlik doğrulama plugin'i kullanan, SUPER / GRANT / FILE yetkili ve TLS zorunluluğu olmayan hesaplar; ikinci sorgu tehlikeli dinamik yetkileri gösterir.","when":"Periyodik güvenlik denetiminde, yeni devralınan sunucuda ve 8.4 upgrade'i öncesinde.","caution":"Sorgu mysql.user'ı doğrudan okur; bu tabloda SELECT yetkisi gerekir. Rol hesapları kilitli ve parolasız olduğu için EMPTY PASSWORD yalnız kilitsiz hesaplarda raporlanır. Super_priv statik SUPER yetkisidir; 8.0'da yetkiler dinamik yetkilere bölündüğü için ikinci sorgu da kontrol edilmeli. NATIVE AUTH bulgusu olan hesaplar 8.4'e geçmeden caching_sha2_password'a taşınmalı: ALTER USER 'u'@'h' IDENTIFIED WITH caching_sha2_password BY '...'; eski istemci / connector sürümleri caching_sha2_password desteklemeyebilir, önce test et.","note":"mysql_native_password 8.0.34'te deprecated oldu, 8.4'te varsayılan olarak devre dışıdır (mysql_native_password=ON ile açılabilir) ve 9.0'da kaldırıldı.","since":"MySQL 8.0","tags":["security audit","mysql.user","mysql_native_password","super","privileges","denetim"]},{"id":"upgrade-checker-84","task":"8.0 → 8.4 LTS upgrade ön kontrolü (util.checkForServerUpgrade)","category":"Upgrade","command":"# Hedef surumu acikca ver; Shell surumu hedefle ayni veya daha yeni olmali\nmysqlsh root@db1:3306 -- util check-for-server-upgrade --target-version=8.4.10 --output-format=TEXT\n# Otomasyon icin JSON cikti, my.cnf kontrolu dahil\nmysqlsh root@db1:3306 -- util check-for-server-upgrade --target-version=8.4.10 --output-format=JSON --config-path=/etc/my.cnf > /tmp/upgrade_check.json","what":"Mevcut sunucuyu hedef sürüme karşı denetler: kaldırılan değişkenler ve yetkiler, varsayılanı değişen parametreler, eski kimlik doğrulama yöntemleri, geçersiz kolon tanımları, foreign key ve partition sorunları. Error seviyesindeki bulgular upgrade'i engeller.","when":"Her major / LTS geçişinden önce; bulgular kapatıldıktan sonra tekrar çalıştırılarak.","caution":"Warning'leri de gözden geçir: 8.4'te innodb_io_capacity (10000), innodb_log_buffer_size (64 MB), innodb_adaptive_hash_index (OFF), innodb_change_buffering (none), innodb_buffer_pool_instances, group_replication_consistency gibi varsayılanlar değişir ve performansı etkileyebilir; mevcut davranışı korumak istediğin değerleri my.cnf'e açıkça yaz. SET_USER_ID gibi kaldırılan yetkiler upgrade'de silinir. Önce bir replikayı yükselt, yük altında izle, sonra switchover yap; 8.4'ten 8.0'a binary downgrade desteklenmez, geri dönüş planı mantıksal yedek veya eski sürümde bekleyen bir replikadır.","note":"8.4'te kaldırılanlar: START / STOP SLAVE, SHOW SLAVE STATUS, CHANGE MASTER TO gibi eski replikasyon sözdizimi, default_authentication_plugin (yerine authentication_policy), binlog_transaction_dependency_tracking ve mysqlpump. mysql_native_password varsayılan olarak devre dışıdır.","since":"MySQL Shell 8.0","tags":["upgrade","8.4","checkforserverupgrade","mysqlsh","lts","sürüm yükseltme"]},{"id":"charset-utf8mb4-convert","task":"latin1 / utf8mb3 tablolarını utf8mb4'e dönüştür","category":"Bakım","command":"-- utf8mb4 olmayan kolonlar\nSELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, CHARACTER_SET_NAME, COLLATION_NAME, COLUMN_TYPE\nFROM information_schema.COLUMNS\nWHERE CHARACTER_SET_NAME IS NOT NULL AND CHARACTER_SET_NAME <> 'utf8mb4'\n  AND TABLE_SCHEMA NOT IN ('mysql', 'sys', 'information_schema', 'performance_schema')\nORDER BY TABLE_SCHEMA, TABLE_NAME;\n\n-- Varsayilan charset'i utf8mb4 olmayan tablolar icin donusum DDL'i uret\nSELECT CONCAT('ALTER TABLE `', t.TABLE_SCHEMA, '`.`', t.TABLE_NAME,\n              '` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci, ALGORITHM=COPY, LOCK=SHARED;') AS ddl\nFROM information_schema.TABLES t\nJOIN information_schema.COLLATIONS c ON c.COLLATION_NAME = t.TABLE_COLLATION\nWHERE c.CHARACTER_SET_NAME <> 'utf8mb4' AND t.TABLE_TYPE = 'BASE TABLE'\n  AND t.TABLE_SCHEMA NOT IN ('mysql', 'sys', 'information_schema', 'performance_schema');\n\n-- Sema varsayilani ve tek tablo\nALTER DATABASE legacy CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;\nALTER TABLE legacy.cust CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci, ALGORITHM=COPY, LOCK=SHARED;","what":"utf8mb4 olmayan kolon ve tabloları bulur, dönüşüm DDL'lerini üretir; CONVERT TO hem tablo varsayılanını hem tüm karakter kolonlarını dönüştürür ve emoji / 4 byte karakter desteği sağlar.","when":"5.x'ten taşınan şemalarda, 'Incorrect string value' (1366) hatası alındığında ve farklı collation'lı kolonlar arasındaki join'ler index kullanamadığında.","caution":"CONVERT TO tabloyu COPY ile yeniden yazar ve süre boyunca yazmaları bloklar (INPLACE desteklenmez); büyük tabloda aynı --alter'ı pt-online-schema-change / gh-ost ile çalıştır. utf8mb4 karakter başına 4 byte'tır: index'li VARCHAR(255) 1020 byte eder; DYNAMIC / COMPRESSED row format'ta sınır 3072 byte, COMPACT / REDUNDANT'ta 767'dir, aşılırsa 1071 hatası alınır. VARCHAR / TEXT kolonlar aynı karakter kapasitesini korumak için gerekirse bir üst tipe (TEXT → MEDIUMTEXT) yükseltilir. Collation değişimi sıralama ve karşılaştırmayı etkiler: utf8mb4_0900_ai_ci aksan ve büyük/küçük harf duyarsızdır, unique index'te önceden farklı sayılan değerler çakışabilir (1062). JOIN'lenen tabloları birlikte dönüştür. İstemci bağlantısı da utf8mb4 olmalı.","note":"utf8 (utf8mb3) 8.0'da deprecated'dır; 8.0.30'dan itibaren SHOW CREATE TABLE'da utf8mb3 olarak görünür. Türkçe sıralama (İ/ı, Ş, Ğ) için utf8mb4_tr_0900_ai_ci kullanılabilir. 8.0 varsayılanı utf8mb4 / utf8mb4_0900_ai_ci'dir.","since":"MySQL 8.0","tags":["utf8mb4","character set","collation","convert","emoji","karakter seti"]}]},"recipes/mssql.json":{"engineId":"mssql","engine":"SQL Server","order":4,"recipes":[{"id":"backup-log","task":"Transaction log yedeği al","category":"Yedek & Log","command":"BACKUP LOG [Musteri]\nTO DISK = N'D:\\Backup\\Musteri_log_20260706_1200.trn'\nWITH COMPRESSION, CHECKSUM, STATS = 10;","what":"Transaction log yedeği alır ve (FULL/BULK_LOGGED recovery modda) logun kullanılan kısmını kesip yeniden kullanılabilir hale getirir.","when":"FULL recovery modda düzenli olarak (ör. her 15 dk), point-in-time kurtarma zinciri için, log dosyası büyüdüğünde.","caution":"Yalnızca FULL/BULK_LOGGED recovery modda anlamlıdır (SIMPLE modda log otomatik kesilir). Log zincirini bozmamak için önce en az bir FULL yedek alınmış olmalı. Yedek dosyalarını sil-üzerine yazma stratejisini doğru kur.","tags":["backup log","log yedek","transaction log","trn","recovery","yedek"]},{"id":"backup-full-diff","task":"Tam (FULL) ve fark (DIFF) yedeği al","category":"Yedek & Log","command":"-- Tam yedek:\nBACKUP DATABASE [Musteri]\nTO DISK = N'D:\\Backup\\Musteri_full_20260706.bak'\nWITH COMPRESSION, CHECKSUM, INIT, STATS = 10;\n\n-- Fark (differential) yedek:\nBACKUP DATABASE [Musteri]\nTO DISK = N'D:\\Backup\\Musteri_diff_20260706.bak'\nWITH DIFFERENTIAL, COMPRESSION, CHECKSUM, INIT, STATS = 10;","what":"FULL tüm veritabanını, DIFFERENTIAL son FULL'den bu yana değişen extent'leri yedekler.","when":"FULL: günlük/haftalık taban yedek. DIFF: FULL arası hızlı ara yedekler için.","caution":"DIFF geri yükleme için ilgili FULL yedeğe ihtiyaç duyar. INIT mevcut dosyanın üzerine yazar; yanlış dosya adı verirsen yedeği kaybedersin. CHECKSUM ile bozulma erken yakalanır.","tags":["backup","full","differential","fark yedek","bak","yedek"]},{"id":"log-reuse-wait","task":"Log dosyası neden büyüdü / neden kesilmiyor","category":"Yedek & Log","command":"SELECT name,\n       recovery_model_desc,\n       log_reuse_wait_desc\nFROM   sys.databases\nWHERE  name = N'Musteri';\n\n-- Tum veritabanlari icin log alan kullanimi:\nSELECT DB_NAME(database_id) AS db, name, type_desc,\n       size*8/1024        AS size_mb,\n       CAST(FILEPROPERTY(name,'SpaceUsed') AS BIGINT)*8/1024 AS used_mb\nFROM   sys.master_files\nWHERE  type_desc = 'LOG';","what":"log_reuse_wait_desc sütunu, transaction logun neden kesilemediğini (ör. LOG_BACKUP, ACTIVE_TRANSACTION, REPLICATION, AVAILABILITY_REPLICA) söyler.","when":"Log dosyası sürekli büyüdüğünde, log dolduğunda (9002 hatası) kök nedeni bulmak için.","caution":"LOG_BACKUP görünüyorsa çözüm log yedeği almaktır, dosyayı shrink etmek değil. Sadece sorgu; risksiz.","tags":["log_reuse_wait_desc","log buyudu","sys.databases","log backup","recovery","tani"]},{"id":"shrink-log","task":"Log dosyasını küçült (shrink)","category":"Yedek & Log","command":"-- Once log yedegi alarak logu kesilebilir yap (FULL modda):\nBACKUP LOG [Musteri] TO DISK = N'D:\\Backup\\Musteri_log_pre_shrink.trn' WITH COMPRESSION;\n\n-- Log dosyasinin mantiksal adini ogren:\nSELECT name, type_desc FROM sys.database_files WHERE type_desc = 'LOG';\n\n-- Kucult (hedef 2048 MB):\nUSE [Musteri];\nDBCC SHRINKFILE (N'Musteri_log', 2048);","what":"Transaction log dosyasının fiziksel boyutunu küçültür ve işletim sistemine alan iade eder.","when":"Tek seferlik olağandışı büyüme (büyük işlem/index rebuild) sonrası log kalıcı olarak şiştiğinde.","caution":"TEHLIKELI/DIKKAT: Rutin shrink KÖTÜ pratiktir; log tekrar büyürken performans düşer ve VLF parçalanması artar. Önce log yedeği alınmalı, aksi halde boyut düşmez. Data file'ı değil sadece gereksiz büyümüş log dosyasını shrink et. Ardından uygun boyutta tek seferde geri büyüt.","tags":["shrink","dbcc shrinkfile","log kucult","log","vlf","dikkat"]},{"id":"vlf-count","task":"VLF (Virtual Log File) sayısını gör","category":"Yedek & Log","command":"-- SQL Server 2016 SP2 / 2017 ve sonrasi:\nSELECT DB_NAME(database_id) AS db,\n       COUNT(*)             AS vlf_count,\n       SUM(CASE WHEN vlf_active = 1 THEN 1 ELSE 0 END) AS aktif_vlf\nFROM   sys.dm_db_log_info(DB_ID(N'Musteri'))\nGROUP BY database_id;\n\n-- Eski surumler icin: DBCC LOGINFO('Musteri'); (satir sayisi = VLF sayisi)","what":"Transaction logun içindeki sanal log dosyası (VLF) sayısını verir. Çok fazla VLF açılış/recovery/log backup performansını düşürür.","when":"Log'un yavaş, DB açılışının uzun sürdüğü durumlarda; log büyüme ayarını gözden geçirirken.","caution":"Yüzlerce/binlerce VLF sorun işaretidir; çözüm log'u shrink edip uygun büyük artışlarla (ör. 8GB adımlarla) yeniden büyütmektir. Sadece sorgu; risksiz.","since":"SQL Server 2016 SP2","note":"sys.dm_db_log_info DMV'si SQL Server 2016 SP2 ve 2017 ile geldi; öncesinde VLF bilgisi için belgelenmemiş DBCC LOGINFO çıktısının satır sayısı sayılırdı.","tags":["vlf","dm_db_log_info","dbcc loginfo","log","virtual log file","performans"]},{"id":"open-transaction","task":"En eski açık transaction'ı bul (ACTIVE_TRANSACTION)","category":"Yedek & Log","command":"USE [Musteri];\nDBCC OPENTRAN;\n\n-- Detayli: uzun suren acik islemleri ve sahibini gor:\nSELECT s.session_id, s.login_name, s.host_name, s.program_name,\n       t.transaction_id,\n       DATEDIFF(SECOND, t.transaction_begin_time, GETDATE()) AS sure_sn,\n       t.transaction_begin_time\nFROM   sys.dm_tran_active_transactions t\n  JOIN sys.dm_tran_session_transactions st ON st.transaction_id = t.transaction_id\n  JOIN sys.dm_exec_sessions s ON s.session_id = st.session_id\nORDER BY t.transaction_begin_time;","what":"En eski açık (commit/rollback edilmemiş) transaction'ı ve onu tutan oturumu gösterir. Açık transaction, logun kesilmesini (LOG_REUSE_WAIT = ACTIVE_TRANSACTION) engeller.","when":"Log yedeği alındığı halde log küçülmüyorsa, log_reuse_wait_desc = ACTIVE_TRANSACTION olduğunda kök nedeni bulmak için.","caution":"Uzun açık transaction'ı tutan oturumu KILL etmeden önce iş sahibiyle teyit et; rollback uzun sürebilir. Sadece sorgu; risksiz.","tags":["dbcc opentran","acik transaction","active_transaction","dm_tran_active_transactions","log","tani"]},{"id":"add-data-file","task":"Veritabanına data file ekle","category":"Depolama","command":"ALTER DATABASE [Musteri]\nADD FILE (\n  NAME = N'Musteri_data2',\n  FILENAME = N'E:\\Data\\Musteri_data2.ndf',\n  SIZE = 4GB,\n  FILEGROWTH = 512MB,\n  MAXSIZE = 100GB\n) TO FILEGROUP [PRIMARY];","what":"Var olan bir filegroup'a yeni bir data file (.ndf) ekleyerek kapasiteyi büyütür ve I/O'yu dağıtır.","when":"Disk dolduğunda, I/O'yu birden çok diske yaymak istediğinde.","caution":"Yeni dosyaya yazım proportional fill ile dengelenir; en boş dosya önce dolar. FILEGROWTH'u yüzde değil sabit MB olarak ver. MAXSIZE belirtmek kontrolsüz büyümeyi engeller.","tags":["add file","veri dosyasi ekle","ndf","alter database","filegroup","depolama"]},{"id":"add-filegroup","task":"Filegroup ekle","category":"Depolama","command":"-- 1) Filegroup olustur:\nALTER DATABASE [Musteri] ADD FILEGROUP [FG_Arsiv];\n\n-- 2) Icine dosya ekle:\nALTER DATABASE [Musteri]\nADD FILE (\n  NAME = N'Musteri_arsiv1',\n  FILENAME = N'F:\\Data\\Musteri_arsiv1.ndf',\n  SIZE = 8GB, FILEGROWTH = 1GB\n) TO FILEGROUP [FG_Arsiv];\n\n-- (Istege bagli) varsayilan filegroup yap:\n-- ALTER DATABASE [Musteri] MODIFY FILEGROUP [FG_Arsiv] DEFAULT;","what":"Yeni bir filegroup ve ona ait dosya oluşturur; tabloları/index'leri ayrı diske/dosya grubuna yerleştirmeyi sağlar.","when":"Arşiv/soğuk veriyi ayırmak, filegroup bazlı yedek/restore, I/O ayrıştırması için.","caution":"Boş filegroup yedeklenemez/kullanılamaz; içine en az bir dosya ekle. Varsayılanı değiştirmek yeni nesnelerin yerini etkiler.","tags":["filegroup","dosya grubu","add filegroup","alter database","ndf","depolama"]},{"id":"modify-file-growth","task":"Dosya boyutu / autogrowth değiştir","category":"Depolama","command":"-- Buyut (SIZE sadece buyutmek icin, kucultmek RESIZE degil shrink ister):\nALTER DATABASE [Musteri]\nMODIFY FILE (NAME = N'Musteri_data', SIZE = 20GB);\n\n-- Autogrowth ayarla (sabit MB onerilir):\nALTER DATABASE [Musteri]\nMODIFY FILE (NAME = N'Musteri_data', FILEGROWTH = 1GB, MAXSIZE = 200GB);\n\n-- Autogrowth kapat:\nALTER DATABASE [Musteri]\nMODIFY FILE (NAME = N'Musteri_log', FILEGROWTH = 0);","what":"Bir veri/log dosyasını önceden büyütür veya otomatik büyüme adımını/üst sınırını ayarlar.","when":"Kontrolsüz küçük büyüme adımlarını düzeltmek, önceden alan ayırmak, MAXSIZE koymak için.","caution":"Yüzde bazlı autogrowth büyük dosyalarda çok büyük adımlar üretir; sabit MB kullan. Instant File Initialization açık değilse data file büyümesi bloklar. SIZE ile küçültme yapılmaz (shrink gerekir).","tags":["modify file","autogrowth","filegrowth","boyut","alter database","depolama"]},{"id":"move-file","task":"Veri/log dosyasını başka konuma taşı","category":"Depolama","command":"-- 1) SQL Server'a yeni yolu bildir (henuz tasima olmaz):\nALTER DATABASE [Musteri]\nMODIFY FILE (NAME = N'Musteri_data',\n             FILENAME = N'G:\\Data\\Musteri_data.mdf');\n\n-- 2) Veritabanini cevrimdisi al:\nALTER DATABASE [Musteri] SET OFFLINE WITH ROLLBACK IMMEDIATE;\n\n-- 3) Dosyayi ISLETIM SISTEMINDEN yeni yola fiziksel kopyala/tasi (G:\\Data\\...).\n\n-- 4) Cevrimici al:\nALTER DATABASE [Musteri] SET ONLINE;","what":"Bir veritabanı dosyasının fiziksel konumunu değiştirir: metadata'da yeni yol tanımlanır, DB offline'ken dosya fiziksel taşınır, sonra online alınır.","when":"Diski değiştirirken, alan kazanmak için başka sürücüye taşırken.","caution":"OFFLINE + ROLLBACK IMMEDIATE tüm aktif bağlantıları keser; kesinti planla. Dosyayı OS'te yeni yola gerçekten kopyalamadan ONLINE alma, DB SUSPECT olur. tempdb için farklı yöntem (MODIFY FILE + SQL servis restart) gerekir.","tags":["move file","dosya tasi","modify file","offline","online","mdf","ldf","depolama"]},{"id":"add-tempdb-file","task":"tempdb'ye data file ekle","category":"Depolama","command":"-- Mevcut tempdb dosyalarini gor:\nSELECT name, physical_name, size*8/1024 AS size_mb, growth\nFROM   sys.master_files WHERE database_id = DB_ID(N'tempdb');\n\n-- Yeni dosya ekle (CPU cekirdek sayisina kadar, esit boyutlu):\nALTER DATABASE [tempdb]\nADD FILE (\n  NAME = N'tempdev2',\n  FILENAME = N'T:\\tempdb\\tempdb_mssql_2.ndf',\n  SIZE = 8GB, FILEGROWTH = 1GB\n);","what":"tempdb'ye ek data file ekleyerek allocation (PFS/GAM/SGAM) çekişmesini azaltır ve I/O'yu dağıtır.","when":"tempdb çekişmesi (PAGELATCH_UP beklemeleri), yüksek tempdb kullanımı olan sistemlerde.","caution":"Tüm tempdb data file'lar AYNI boyut ve büyüme adımında olmalı (proportional fill için). Eklenen dosya restart gerektirmeden hemen kullanılmaya başlar; mevcut dosyalar farklı boyuttaysa önce hepsini eşit boyuta getirin, yoksa yeni (boş) dosya orantısız yük alır. Dosya sayısı genelde çekirdek sayısı (8'e kadar) ile eşleştirilir; SQL Server 2016+ kurulumu bunu varsayılan olarak yapar.","tags":["tempdb","add file","tempdb dosya","ndf","cekisme","pagelatch","depolama"]},{"id":"index-rebuild-reorg","task":"Index rebuild / reorganize","category":"Bakım","command":"-- Yeniden insa (yuksek fragmentasyon > %30). ONLINE Enterprise'da:\nALTER INDEX IX_Musteri_Email ON dbo.Musteri\n  REBUILD WITH (ONLINE = ON, MAXDOP = 4, SORT_IN_TEMPDB = ON);\n\n-- Bir tablonun tum indeksleri:\nALTER INDEX ALL ON dbo.Musteri REBUILD WITH (FILLFACTOR = 90);\n\n-- Reorganize (orta fragmentasyon %5-30, her zaman online, iptal edilebilir):\nALTER INDEX IX_Musteri_Email ON dbo.Musteri REORGANIZE;","what":"REBUILD index'i baştan oluşturur (fragmentasyonu tamamen giderir, istatistikleri tazeler); REORGANIZE yaprak seviyesini yerinde sıkıştırır (hafif, kesintisiz).","when":"Fragmentasyon %5-30 ise REORGANIZE, >%30 ise REBUILD. Büyük tablo bakım pencerelerinde.","caution":"ONLINE = ON yalnızca Enterprise/Developer'da; Standard'da OFF kullan (tablo kilitlenir). REBUILD çok log üretir ve alan gerektirir. MAXDOP ve SORT_IN_TEMPDB kaynak kullanımını etkiler.","tags":["index","rebuild","reorganize","alter index","fragmentasyon","bakim","online"]},{"id":"update-statistics","task":"İstatistikleri güncelle","category":"Bakım","command":"-- Tek tablo, tam tarama:\nUPDATE STATISTICS dbo.Musteri WITH FULLSCAN;\n\n-- Belirli istatistik, ornekleme ile:\nUPDATE STATISTICS dbo.Musteri IX_Musteri_Email WITH SAMPLE 30 PERCENT;\n\n-- Tum veritabani (kullanici tablolari) icin toplu (ornekleme):\nEXEC sys.sp_updatestats;","what":"Optimizer'ın kullandığı sütun/index istatistiklerini günceller; doğru execution plan ve kardinalite tahmini sağlar.","when":"Büyük veri değişimi/yükleme sonrası, plan bozulmasında; index rebuild zaten istatistikleri tam tazeler (ayrıca gerekmez).","caution":"FULLSCAN doğru ama pahalıdır; büyük tablolarda I/O yükü yaratır. sp_updatestats yalnızca değişmiş istatistikleri günceller ve varsayılan örnekleme kullanır. Index REBUILD sonrası aynı index'e tekrar UPDATE STATISTICS gereksizdir.","tags":["update statistics","istatistik","sp_updatestats","fullscan","optimizer","bakim"]},{"id":"dbcc-checkdb","task":"Bütünlük kontrolü (DBCC CHECKDB)","category":"Bakım","command":"-- Tam butunluk kontrolu:\nDBCC CHECKDB (N'Musteri') WITH NO_INFOMSGS, ALL_ERRORMSGS;\n\n-- Buyuk DB'de daha hafif (fiziksel tutarlilik):\nDBCC CHECKDB (N'Musteri') WITH PHYSICAL_ONLY, NO_INFOMSGS;","what":"Veritabanının fiziksel ve mantıksal bütünlüğünü (sayfa yapıları, allocation, index tutarlılığı) kontrol eder, bozulmaları raporlar.","when":"Düzenli bakımda (haftalık), donanım/IO şüphesinde, 823/824 hataları sonrası.","caution":"Yoğun I/O ve tempdb kullanır; bakım penceresinde çalıştır. Hata bulunursa REPAIR_ALLOW_DATA_LOSS SON çare olmalı ve VERİ KAYBINA yol açar; önce sağlam yedekten restore düşün. PHYSICAL_ONLY daha hızlıdır ama mantıksal kontrolleri atlar.","tags":["dbcc checkdb","butunluk","corruption","bozulma","integrity","bakim"]},{"id":"index-fragmentation","task":"Index fragmentasyonunu gör","category":"Bakım","command":"SELECT OBJECT_SCHEMA_NAME(ips.object_id) AS sema,\n       OBJECT_NAME(ips.object_id)        AS tablo,\n       i.name                            AS indeks,\n       ips.index_type_desc,\n       ROUND(ips.avg_fragmentation_in_percent,1) AS frag_pct,\n       ips.page_count\nFROM   sys.dm_db_index_physical_stats(DB_ID(N'Musteri'), NULL, NULL, NULL, 'LIMITED') ips\n  JOIN sys.indexes i\n    ON i.object_id = ips.object_id AND i.index_id = ips.index_id\nWHERE  ips.avg_fragmentation_in_percent > 10\n  AND  ips.page_count > 1000\nORDER BY ips.avg_fragmentation_in_percent DESC;","what":"Index'lerin fragmentasyon yüzdesini ve sayfa sayısını listeler; rebuild/reorganize kararına temel oluşturur.","when":"Bakım öncesi hangi index'lerin ele alınacağını belirlemek için.","caution":"Küçük index'lerde (< 1000 sayfa) fragmentasyon önemsizdir, filtrelendi. 'DETAILED' modu daha doğru ama çok pahalıdır; 'LIMITED' genelde yeterli. Sadece sorgu; risksiz.","tags":["fragmentasyon","dm_db_index_physical_stats","index","frag","bakim","tani"]},{"id":"kill-spid","task":"Oturumu (SPID) öldür","category":"Oturum","command":"-- Once suclu SPID'i bul:\nSELECT s.session_id, s.login_name, s.host_name, s.program_name,\n       r.status, r.command, r.wait_type, r.blocking_session_id,\n       DB_NAME(r.database_id) AS db\nFROM   sys.dm_exec_sessions s\n  LEFT JOIN sys.dm_exec_requests r ON r.session_id = s.session_id\nWHERE  s.is_user_process = 1;\n\n-- Oldur (ornek SPID 63):\nKILL 63;\n\n-- Rollback ilerlemesini gor:\nKILL 63 WITH STATUSONLY;","what":"Belirtilen session_id (SPID) oturumunu sonlandırır; açık transaction geri alınır.","when":"Lock tutan, kaçak/uzun sorgu çalıştıran veya bağlantıyı bırakmayan oturumu durdurmak için.","caution":"Açık büyük transaction'da rollback uzun sürebilir ve iptal edilemez; KILL WITH STATUSONLY ile ilerlemeyi izle. Sistem SPID'lerini (is_user_process=0) öldürme. Doğru SPID'i teyit et.","tags":["kill","spid","oturum oldur","dm_exec_sessions","dm_exec_requests","oturum"]},{"id":"blocking-chain","task":"Blocking (lock) zincirini bul","category":"Oturum","command":"SELECT r.session_id            AS bekleyen_spid,\n       r.blocking_session_id  AS engelleyen_spid,\n       r.wait_type,\n       r.wait_time / 1000.0   AS bekleme_sn,\n       r.status, r.command,\n       DB_NAME(r.database_id) AS db,\n       t.text                 AS bekleyen_sorgu\nFROM   sys.dm_exec_requests r\n  CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) t\nWHERE  r.blocking_session_id <> 0\nORDER BY r.wait_time DESC;\n\n-- Zincirin en tepesindeki (kok) engelleyeni bulmak icin blocking_session_id'si\n-- kendisi engellenmemis SPID'i ara.","what":"Bekleyen ve onları engelleyen oturumları, bekleme süresi ve çalıştırdıkları sorguyla listeler; lock zincirini görünür kılar.","when":"\"Uygulama takıldı / zaman aşımı\" şikayetlerinde lock çakışmasının kaynağını bulmak için.","caution":"Kök engelleyeni (kimse tarafından engellenmeyen ama başkalarını engelleyen SPID) öldürmeden önce iş sahibiyle teyit et. Sadece sorgu; risksiz.","tags":["blocking","kilit","lock","dm_exec_requests","blocking_session_id","oturum","zincir"]},{"id":"active-queries","task":"Aktif sorguları ve maliyetlerini gör","category":"Oturum","command":"SELECT r.session_id,\n       r.status,\n       r.command,\n       DB_NAME(r.database_id) AS db,\n       r.cpu_time,\n       r.total_elapsed_time / 1000 AS gecen_sn,\n       r.reads, r.writes, r.logical_reads,\n       r.wait_type,\n       SUBSTRING(t.text,\n         (r.statement_start_offset/2)+1,\n         ((CASE r.statement_end_offset WHEN -1 THEN DATALENGTH(t.text)\n            ELSE r.statement_end_offset END - r.statement_start_offset)/2)+1) AS calisan_ifade\nFROM   sys.dm_exec_requests r\n  JOIN sys.dm_exec_sessions s ON s.session_id = r.session_id\n  CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) t\nWHERE  s.is_user_process = 1 AND r.session_id <> @@SPID\nORDER BY r.total_elapsed_time DESC;","what":"O anda çalışan kullanıcı sorgularını CPU, geçen süre, okuma/yazma ve tam ifade metniyle gösterir.","when":"Anlık yavaşlıkta hangi sorgunun kaynak tükettiğini bulmak için.","caution":"statement_start/end_offset ile tam çalışan ifade çıkarılır (batch'in tümü değil). Sadece sorgu; risksiz.","tags":["active queries","aktif sorgu","dm_exec_requests","dm_exec_sql_text","cpu","oturum"]},{"id":"sp-configure-memory","task":"sp_configure ile ayar (max server memory)","category":"Yapılandırma","command":"-- Gelismis ayarlari gorunur yap:\nEXEC sys.sp_configure 'show advanced options', 1;\nRECONFIGURE;\n\n-- Max sunucu bellegini ayarla (MB). Ornek: 24 GB birak:\nEXEC sys.sp_configure 'max server memory (MB)', 24576;\nRECONFIGURE;\n\n-- Dogrula:\nEXEC sys.sp_configure 'max server memory (MB)';","what":"SQL Server'ın buffer pool için kullanabileceği azami belleği sınırlar; işletim sistemine ve diğer bileşenlere RAM bırakır.","when":"Sunucuda OS/diğer servislerin bellek açlığı çektiği, yeni RAM eklendiği durumlarda.","caution":"İşletim sistemi, SSAS/SSIS, CLR ve thread stack için yeterli RAM bırak (genelde OS'e en az 4-6 GB). Çok düşük ayarlamak SQL Server performansını çökertir. RECONFIGURE olmadan değişiklik uygulanmaz; bu ayar dinamiktir (restart gerekmez).","tags":["sp_configure","max server memory","reconfigure","bellek","yapilandirma","memory"]},{"id":"reconfigure-general","task":"Genel sp_configure ayarı ve RECONFIGURE","category":"Yapılandırma","command":"EXEC sys.sp_configure 'show advanced options', 1;\nRECONFIGURE;\n\n-- Ornek: paralellik maliyet esigi ve MAXDOP:\nEXEC sys.sp_configure 'cost threshold for parallelism', 50;\nEXEC sys.sp_configure 'max degree of parallelism', 4;\nRECONFIGURE;\n\n-- Tum mevcut/calisan degerleri gor:\nSELECT name, value AS ayarlanan, value_in_use AS calisan, is_dynamic, is_advanced\nFROM   sys.configurations\nORDER BY name;","what":"Sunucu düzeyi yapılandırma değerlerini ayarlar; RECONFIGURE ile çalışan değere uygular.","when":"MAXDOP, paralellik eşiği, optimize for ad hoc gibi sunucu ayarlarını değiştirirken.","caution":"is_dynamic = 0 olan ayarlar SQL Server restart gerektirir. RECONFIGURE WITH OVERRIDE bazı ayarlarda doğrulamayı atlar; dikkatli kullan. Değişiklik öncesi value_in_use'u not al.","tags":["sp_configure","reconfigure","maxdop","cost threshold","sys.configurations","yapilandirma"]},{"id":"ag-failover","task":"Availability Group failover","category":"Yapılandırma","command":"-- HEDEF (secondary) REPLIKADA calistir - planli, veri kaybi yok (senkron):\nALTER AVAILABILITY GROUP [AG_Musteri] FAILOVER;\n\n-- Zorlamali (asenkron replika / primary erisilemezken, VERI KAYBI riski):\n-- ALTER AVAILABILITY GROUP [AG_Musteri] FORCE_FAILOVER_ALLOW_DATA_LOSS;\n\n-- Durumu kontrol et:\nSELECT ag.name, ar.replica_server_name,\n       rs.role_desc, rs.synchronization_health_desc, ar.availability_mode_desc\nFROM   sys.availability_groups ag\n  JOIN sys.availability_replicas ar ON ar.group_id = ag.group_id\n  JOIN sys.dm_hadr_availability_replica_states rs ON rs.replica_id = ar.replica_id;","what":"Availability Group primary rolünü başka bir replikaya taşır; planlı failover senkron replikada veri kaybı olmadan yapılır.","when":"Bakım/yama için rol devri, primary node arızasında failover.","caution":"Normal FAILOVER komutu FAILOVER'ın devralınacağı SECONDARY replikada çalıştırılır. FORCE_FAILOVER_ALLOW_DATA_LOSS yalnızca primary erişilemez ve asenkron replikadayken kullanılır ve VERİ KAYBINA yol açabilir; senkronizasyon sağlıklı değilse çok dikkatli ol.","tags":["availability group","ag","failover","hadr","yuk devri","alwayson","yapilandirma"]},{"id":"change-recovery-model","task":"Veritabanı recovery model değiştir","category":"Yapılandırma","command":"-- Mevcut modeli gor:\nSELECT name, recovery_model_desc FROM sys.databases WHERE name = N'Musteri';\n\n-- FULL recovery (point-in-time kurtarma icin):\nALTER DATABASE [Musteri] SET RECOVERY FULL;\n\n-- SIMPLE recovery (log otomatik kesilir, log yedek gerekmez):\n-- ALTER DATABASE [Musteri] SET RECOVERY SIMPLE;\n\n-- BULK_LOGGED (buyuk toplu islemler icin gecici):\n-- ALTER DATABASE [Musteri] SET RECOVERY BULK_LOGGED;","what":"Veritabanının recovery modelini değiştirir; logun nasıl yönetildiğini ve kurtarma seçeneklerini belirler.","when":"FULL: point-in-time kurtarma/log yedek/AG gerektiğinde. SIMPLE: kurtarma noktası gerekmeyen (dev/test, DW) sistemlerde.","caution":"FULL'e geçtikten sonra log zincirini başlatmak için bir FULL yedek al ve düzenli log yedeği kur, yoksa log sürekli büyür. FULL'den SIMPLE'a geçmek log zincirini kırar; point-in-time kurtarmayı kaybedersin. AG üyeleri FULL modda olmalıdır.","tags":["recovery model","recovery full","simple","bulk_logged","alter database","yapilandirma"]}]},"recipes/mssql-ext.json":{"engineId":"mssql","engine":"SQL Server","order":2,"recipes":[{"id":"ag-health-lag","task":"Availability group sağlık ve gecikme izleme (log send / redo queue, RPO)","category":"Always On & HA","command":"-- Replika sagligi (primary'de calistir, tum replikalari gorur):\nSELECT ag.name AS ag_name, ar.replica_server_name, ars.role_desc,\n       ar.availability_mode_desc, ar.failover_mode_desc,\n       ars.connected_state_desc, ars.synchronization_health_desc,\n       ars.operational_state_desc, ars.last_connect_error_description\nFROM   sys.availability_groups ag\n  JOIN sys.availability_replicas ar                ON ar.group_id = ag.group_id\n  JOIN sys.dm_hadr_availability_replica_states ars ON ars.replica_id = ar.replica_id\nORDER BY ag.name, ars.role_desc;\n\n-- Veritabani bazinda gecikme: log send queue (RPO), redo queue (RTO):\nSELECT ag.name AS ag_name, ar.replica_server_name, DB_NAME(drs.database_id) AS db,\n       drs.is_primary_replica, drs.synchronization_state_desc, drs.synchronization_health_desc,\n       drs.is_suspended, drs.suspend_reason_desc,\n       drs.log_send_queue_size  AS log_send_queue_kb,\n       drs.log_send_rate        AS log_send_kb_s,\n       drs.redo_queue_size      AS redo_queue_kb,\n       drs.redo_rate            AS redo_kb_s,\n       CAST(drs.redo_queue_size * 1.0 / NULLIF(drs.redo_rate, 0) AS DECIMAL(18,1)) AS est_redo_catchup_s,\n       drs.last_commit_time,\n       DATEDIFF(SECOND, drs.last_commit_time, pri.last_commit_time) AS data_loss_window_s,\n       drs.secondary_lag_seconds\nFROM   sys.dm_hadr_database_replica_states drs\n  JOIN sys.availability_replicas ar ON ar.replica_id = drs.replica_id\n  JOIN sys.availability_groups ag   ON ag.group_id = drs.group_id\n  LEFT JOIN sys.dm_hadr_database_replica_states pri\n         ON pri.group_database_id = drs.group_database_id AND pri.is_primary_replica = 1\nORDER BY ag.name, db, drs.is_primary_replica DESC;\n\n-- WSFC quorum durumu:\nSELECT cluster_name, quorum_type_desc, quorum_state_desc FROM sys.dm_hadr_cluster;\nSELECT member_name, member_type_desc, member_state_desc, number_of_quorum_votes\nFROM   sys.dm_hadr_cluster_members;","what":"Replikaların bağlantı ve senkronizasyon sağlığını; veritabanı bazında log send queue, redo queue, gönderim/redo hızını, tahmini redo yetişme süresini ve primary ile son commit farkını (olası veri kaybı penceresi) gösterir; ayrıca WSFC quorum durumunu verir.","when":"AG dashboard'da NOT_HEALTHY / NOT SYNCHRONIZING uyarısında, planlı failover öncesi RPO/RTO kontrolünde, readable secondary'de eski veri şikâyetinde.","caution":"log_send_queue büyüyorsa primary kaybında o kadar log kaybolur (RPO); redo_queue büyüyorsa failover sonrası veritabanının açılması o kadar uzar (RTO). Secondary'de çalıştırıldığında yalnız yerel replika görünür; tam resim için primary'de çalıştır. data_loss_window_s yalnız yazma trafiği varken anlamlıdır. Sadece sorgu; risksiz.","since":"2016","note":"secondary_lag_seconds 2016+ sütunudur. Redo kuyruğu kalıcı büyüyorsa secondary'de redo thread'inin blocking'e takılıp takılmadığını (uzun okuma sorguları, DDL) ve wait_type = REDO_THREAD_PENDING_WORK / PARALLEL_REDO_* beklemelerini kontrol et.","tags":["availability group","ag","log send queue","redo queue","senkronizasyon","rpo"],"untested":true},{"id":"ag-forced-failover-dr","task":"Zorunlu failover (FORCE_FAILOVER_ALLOW_DATA_LOSS) ve sonrası toparlanma","category":"Always On & HA","command":"-- 1) Her aday secondary'de: en guncel replikayi sec (en yuksek end_of_log_lsn)\nSELECT ag.name AS ag_name, DB_NAME(drs.database_id) AS db,\n       drs.synchronization_state_desc, drs.end_of_log_lsn, drs.last_commit_time\nFROM   sys.dm_hadr_database_replica_states drs\n  JOIN sys.availability_groups ag ON ag.group_id = drs.group_id\nWHERE  drs.is_local = 1;\n\n-- 2) Secilen replikada (primary erisilemezken):\nALTER AVAILABILITY GROUP [AG_Musteri] FORCE_FAILOVER_ALLOW_DATA_LOSS;\n\n-- 3) Diger secondary'lerde askiya alinan veri hareketini baslat:\nALTER DATABASE [Musteri] SET HADR RESUME;\n\n-- 4) Eski primary geri geldiginde (artik SUSPENDED secondary):\n--    kaybolan islemleri incelemek icin once snapshot al, sonra resume et\nCREATE DATABASE [Musteri_lost_snap]\n  ON (NAME = N'Musteri', FILENAME = N'D:\\Data\\Musteri_lost_snap.ss')\n  AS SNAPSHOT OF [Musteri];\nALTER DATABASE [Musteri] SET HADR RESUME;","what":"Primary tamamen kaybedildiğinde DR replikasını veri kaybını kabul ederek primary yapar; ardından diğer replikalarda SUSPENDED kalan data movement'ı başlatır ve eski primary döndüğünde ona ait, yeni primary'ye hiç ulaşmamış işlemleri incelemek için snapshot alır.","when":"Primary veri merkezi çöktüğünde, yalnız asynchronous replika kaldığında ya da senkron replika SYNCHRONIZED değilken failover zorunlu olduğunda.","caution":"VERİ KAYBI: Son hardened LSN'den sonraki transaction'lar kaybolur. Önce iş birimiyle RPO onayı al. Forced failover sonrası tüm secondary veritabanları SUSPENDED olur; HADR RESUME edilene kadar log truncate edilmez ve log büyür. WSFC quorum kaybedildiyse önce cluster'ı force quorum ile başlat (PowerShell: Start-ClusterNode -FixQuorum), aksi halde komut çalışmaz. Eski primary'de HADR RESUME, kaybolan transaction'ları kalıcı olarak geri alır; snapshot almadan resume etme.","note":"Planlı failover (veri kaybı yok) için ag-failover reçetesindeki FAILOVER komutunu kullan. CLUSTER_TYPE = NONE / EXTERNAL AG'lerde de FORCE_FAILOVER_ALLOW_DATA_LOSS kullanılır; EXTERNAL (Pacemaker) ortamında failover cluster yöneticisinden yapılır. Snapshot kaynak veritabanının dosya mantıksal adlarını tek tek ister; çok dosyalı DB'de her data file için bir ON satırı ekle.","tags":["force failover","allow data loss","dr","availability group","hadr resume","veri kaybi"],"untested":true},{"id":"ag-add-db-autoseed","task":"AG'ye veritabanı ekle (automatic seeding) ve seeding ilerlemesini izle","category":"Always On & HA","command":"-- Onkosul (primary): FULL recovery ve en az bir FULL yedek\nSELECT name, recovery_model_desc FROM sys.databases WHERE name = N'Musteri';\nBACKUP DATABASE [Musteri] TO DISK = N'D:\\Backup\\Musteri_pre_ag.bak' WITH COMPRESSION, CHECKSUM, INIT;\n\n-- 1) Primary: replikayi automatic seeding moduna al\nALTER AVAILABILITY GROUP [AG_Musteri]\n  MODIFY REPLICA ON N'SQL02' WITH (SEEDING_MODE = AUTOMATIC);\n\n-- 2) Her secondary'de: AG'ye veritabani olusturma izni ver\nALTER AVAILABILITY GROUP [AG_Musteri] GRANT CREATE ANY DATABASE;\n\n-- 3) Primary: veritabanini ekle\nALTER AVAILABILITY GROUP [AG_Musteri] ADD DATABASE [Musteri];\n\n-- 4) Ilerleme (primary veya secondary):\nSELECT local_database_name, role_desc, internal_state_desc,\n       transferred_size_bytes / 1048576         AS transferred_mb,\n       database_size_bytes / 1048576            AS db_mb,\n       transfer_rate_bytes_per_second / 1048576 AS mb_s,\n       estimate_time_complete_utc, failure_message\nFROM   sys.dm_hadr_physical_seeding_stats;\n\n-- 5) Seeding gecmisi ve hata nedeni:\nSELECT s.start_time, s.completion_time, adc.database_name, ar.replica_server_name,\n       s.current_state, s.failure_state_desc, s.error_code, s.number_of_attempts\nFROM   sys.dm_hadr_automatic_seeding s\n  JOIN sys.availability_databases_cluster adc ON adc.group_database_id = s.ag_db_id\n  JOIN sys.availability_replicas ar           ON ar.replica_id = s.ag_remote_replica_id\nORDER BY s.start_time DESC;","what":"Veritabanını backup/restore yapmadan, endpoint üzerinden VDI stream ile secondary'lere kopyalayarak AG'ye ekler; seeding'in aktarım hızını, tahmini bitişini ve başarısızlık nedenini gösterir.","when":"Yeni veritabanını AG'ye alırken, yeni bir replika eklerken veya bozulan secondary veritabanını yeniden oluştururken.","caution":"Seeding endpoint ağ bağlantısını doldurur ve varsayılan olarak sıkıştırmasızdır; çok büyük DB'de veya zayıf WAN'da manuel backup/restore + JOIN daha öngörülebilirdir. Seeding süresince primary'de log truncate olmaz (log_reuse_wait_desc = AVAILABILITY_REPLICA). 2016'da secondary'de primary ile aynı data/log klasör yolu şarttır; 2017+'da primary dosyaları instance varsayılan yolundaysa secondary kendi varsayılan yolunu kullanır. TDE'li DB'de sertifika önce tüm secondary'lere restore edilmeli. Secondary'de GRANT CREATE ANY DATABASE verilmezse seeding beklemede kalır.","since":"2016","note":"Seeding sıkıştırması trace flag 9567 ile açılır (CPU maliyeti vardır). Seeding başlangıç, bitiş ve hata kayıtları SQL Server error log'una düşer; ayrıntılı izleme için hadr_automatic_seeding_* ve hadr_physical_seeding_* event'leriyle ayrı bir Extended Events oturumu kur. Manuel moda dönmek için SEEDING_MODE = MANUAL.","tags":["automatic seeding","availability group","add database","seeding_mode","dm_hadr_physical_seeding_stats","ag"],"untested":true},{"id":"ag-listener-routing","task":"Listener, IP ve read-only routing yapılandırmasını kontrol et","category":"Always On & HA","command":"-- Listener, port ve IP durumlari:\nSELECT ag.name AS ag_name, l.dns_name, l.port, l.is_conformant,\n       ip.ip_address, ip.ip_subnet_mask, ip.state_desc\nFROM   sys.availability_group_listeners l\n  JOIN sys.availability_groups ag ON ag.group_id = l.group_id\n  LEFT JOIN sys.availability_group_listener_ip_addresses ip ON ip.listener_id = l.listener_id;\n\n-- Read-only routing listesi: primary X iken okuma baglantisi nereye gider:\nSELECT ag.name AS ag_name, pr.replica_server_name AS when_primary_is,\n       rl.routing_priority, sr.replica_server_name AS route_to,\n       sr.read_only_routing_url, sr.secondary_role_allow_connections_desc\nFROM   sys.availability_read_only_routing_lists rl\n  JOIN sys.availability_replicas pr ON pr.replica_id = rl.replica_id\n  JOIN sys.availability_replicas sr ON sr.replica_id = rl.read_only_replica_id\n  JOIN sys.availability_groups ag   ON ag.group_id = pr.group_id\nORDER BY ag.name, when_primary_is, rl.routing_priority;\n\n-- Replika endpoint ve baglanti ayarlari:\nSELECT replica_server_name, endpoint_url, read_only_routing_url,\n       secondary_role_allow_connections_desc, seeding_mode_desc, session_timeout\nFROM   sys.availability_replicas;\n\n-- Komut satirindan routing testi (-K ReadOnly icin -d zorunlu):\n-- sqlcmd -S tcp:AGL-Musteri,1433 -d Musteri -E -M -K ReadOnly -Q \"SELECT @@SERVERNAME\"","what":"Listener DNS adını, portunu ve her subnet IP'sinin cluster'daki durumunu; read-only routing listesinde her primary senaryosu için okuma bağlantısının hangi replikaya ve hangi URL'ye yönleneceğini gösterir.","when":"Failover sonrası uygulamalar bağlanamıyorsa, ApplicationIntent=ReadOnly bağlantıları primary'ye düşüyorsa, yeni subnet/replika eklendiğinde.","caution":"Read-only routing yalnız listener üzerinden, ApplicationIntent=ReadOnly ve hedef veritabanı belirtilerek yapılan bağlantılarda çalışır; instance adına doğrudan bağlantı yönlendirilmez. read_only_routing_url boşsa o replika routing hedefi olamaz. Multi-subnet listener'da istemci MultiSubnetFailover=True kullanmazsa failover sonrası 20-30 sn bağlantı zaman aşımı görülür. Sadece sorgu; risksiz.","note":"2016+ load balancing için routing listesinde iç içe parantez kullanılır: READ_ONLY_ROUTING_LIST = (('SQL02','SQL03'),'SQL01'). Listener IP'leri OFFLINE görünüyorsa cluster tarafında (Failover Cluster Manager / Get-ClusterResource) kaynak bağımlılıklarını kontrol et.","tags":["listener","read-only routing","applicationintent","multisubnetfailover","availability group","baglanti"],"untested":true},{"id":"logshipping-monitor","task":"Log shipping durumunu ve gecikmesini izle","category":"Always On & HA","command":"-- Ozet (primary, secondary veya monitor sunucuda):\nEXEC master.sys.sp_help_log_shipping_monitor;\n\n-- PRIMARY: son log yedegi ne zaman alindi:\nSELECT p.primary_server, p.primary_database,\n       p.last_backup_date, p.last_backup_file,\n       DATEDIFF(MINUTE, p.last_backup_date, GETDATE()) AS backup_age_min,\n       p.backup_threshold                              AS threshold_min\nFROM   msdb.dbo.log_shipping_monitor_primary p;\n\n-- SECONDARY: kopyalama ve restore gecikmesi:\nSELECT s.secondary_server, s.secondary_database, s.primary_server,\n       s.last_copied_date, s.last_copied_file,\n       s.last_restored_date, s.last_restored_file,\n       s.last_restored_latency                           AS restore_latency_min,\n       DATEDIFF(MINUTE, s.last_restored_date, GETDATE()) AS since_last_restore_min,\n       s.restore_threshold                               AS threshold_min\nFROM   msdb.dbo.log_shipping_monitor_secondary s;\n\n-- Son 24 saatin hatalari:\nSELECT e.database_name, e.agent_type, e.log_time, e.message\nFROM   msdb.dbo.log_shipping_monitor_error_detail e\nWHERE  e.log_time >= DATEADD(HOUR, -24, GETDATE())\nORDER BY e.log_time DESC;\n\n-- Secondary DB modu (RESTORING = NORECOVERY, is_in_standby = STANDBY):\nSELECT name, state_desc, is_in_standby FROM sys.databases WHERE name = N'Musteri';","what":"Primary'de son log yedeğinin yaşını, secondary'de son kopyalanan/restore edilen dosyayı ve restore gecikmesini eşik değerleriyle birlikte; son 24 saatin backup/copy/restore job hatalarını gösterir.","when":"Log shipping alert job'ı (14420/14421 hatası) tetiklendiğinde, DR testinden önce, secondary'nin ne kadar geride olduğunu raporlarken.","caution":"Monitor tabloları yalnız ilgili sunucunun gördüğü tarafı içerir: primary tablosu primary/monitor'de, secondary tablosu secondary/monitor'de dolar. Araya manuel (log shipping dışı) bir log yedeği girerse zincir kırılır ve restore job sürekli hata verir; ad-hoc log yedeği gerekiyorsa COPY_ONLY kullan. STANDBY modda her restore öncesi kullanıcı bağlantıları kesilir. Sadece sorgu; risksiz.","note":"Tarih sütunları sunucu yerel saatindedir; farklı saat dilimindeki sunucuları karşılaştırırken *_utc sütunlarını kullan. Restore job'ı \"skipping log backup file\" mesajı veriyorsa dosya zaten uygulanmıştır; gerçek boşluk için secondary'de RESTORE HEADERONLY ile FirstLSN/LastLSN sırasını kontrol et.","tags":["log shipping","sp_help_log_shipping_monitor","restore latency","dr","secondary","gecikme"],"untested":true},{"id":"backup-copy-only","task":"Zinciri bozmadan ad-hoc yedek al (COPY_ONLY, stripe, throughput)","category":"Yedek & Log","command":"-- DIFF tabanini degistirmeyen ad-hoc FULL:\nBACKUP DATABASE [Musteri]\nTO DISK = N'D:\\Backup\\Musteri_copyonly_20261008.bak'\nWITH COPY_ONLY, COMPRESSION, CHECKSUM, INIT, STATS = 10;\n\n-- Logu kesmeyen ad-hoc log yedegi:\nBACKUP LOG [Musteri]\nTO DISK = N'D:\\Backup\\Musteri_copyonly_20261008.trn'\nWITH COPY_ONLY, COMPRESSION, CHECKSUM, INIT;\n\n-- Buyuk DB: birden cok dosyaya bol (stripe), buffer ayarla:\nBACKUP DATABASE [Musteri]\nTO DISK = N'D:\\Backup\\Musteri_s1.bak', DISK = N'E:\\Backup\\Musteri_s2.bak'\nWITH COPY_ONLY, COMPRESSION, CHECKSUM, INIT,\n     MAXTRANSFERSIZE = 4194304, BUFFERCOUNT = 64, STATS = 5;","what":"Düzenli yedek zincirini (differential base ve log zinciri) etkilemeyen bağımsız FULL veya log yedeği alır; büyük veritabanlarında yedeği birden çok dosyaya bölerek ve transfer boyutunu büyüterek süreyi kısaltır.","when":"Test/dev ortamına kopya verirken, riskli bir değişiklik öncesi, denetim için yedek isterken; zamanlanmış yedek stratejisine dokunmadan yedek gerektiğinde.","caution":"COPY_ONLY olmayan ad-hoc FULL, sonraki DIFF yedeklerinin tabanını değiştirir; o dosya silinirse DIFF'ler işe yaramaz. COPY_ONLY, DIFFERENTIAL ile birlikte etkisizdir. Stripe edilmiş yedeğin restore'u için tüm dosyalar gerekir; tek dosya kaybı tüm yedeği kullanılamaz yapar. BUFFERCOUNT x MAXTRANSFERSIZE kadar bellek buffer pool dışından ayrılır (örnekte 256 MB); bellek baskısı olan sunucuda düşür.","note":"TDE'li veritabanında backup compression için MAXTRANSFERSIZE 65536'dan büyük olmalıdır (2016+). Sunucu varsayılanı: sp_configure 'backup compression default' ve 'backup checksum default'. 2022'de Intel QAT donanımı varsa WITH COMPRESSION (ALGORITHM = QAT_DEFLATE) kullanılabilir.","tags":["copy_only","ad-hoc yedek","stripe","maxtransfersize","buffercount","yedek"]},{"id":"backup-to-url","task":"URL'ye yedek al (Azure Blob SAS / S3 uyumlu depolama)","category":"Yedek & Log","command":"-- A) Azure Blob: SAS credential (adi container URL'si, SECRET basinda '?' olmadan)\nCREATE CREDENTIAL [https://dbabackup.blob.core.windows.net/sql]\nWITH IDENTITY = N'SHARED ACCESS SIGNATURE',\n     SECRET   = N'sv=2022-11-02&ss=b&srt=co&sp=rwdlac&se=2027-01-01T00:00:00Z&sig=XXXX';\n\nBACKUP DATABASE [Musteri]\nTO URL = N'https://dbabackup.blob.core.windows.net/sql/Musteri_full_1.bak',\n   URL = N'https://dbabackup.blob.core.windows.net/sql/Musteri_full_2.bak'\nWITH COMPRESSION, CHECKSUM, MAXTRANSFERSIZE = 4194304, BLOCKSIZE = 65536, STATS = 10;\n\n-- B) S3 uyumlu depolama (2022+):\nCREATE CREDENTIAL [s3://s3.eu-central-1.amazonaws.com/dba-backup/sql]\nWITH IDENTITY = N'S3 Access Key',\n     SECRET   = N'<AccessKeyID>:<SecretKeyID>';\n\nBACKUP DATABASE [Musteri]\nTO URL = N's3://s3.eu-central-1.amazonaws.com/dba-backup/sql/Musteri_full.bak'\nWITH COMPRESSION, CHECKSUM, FORMAT, STATS = 10;\n\n-- Dogrula (ayni credential kullanilir):\nRESTORE VERIFYONLY\nFROM URL = N's3://s3.eu-central-1.amazonaws.com/dba-backup/sql/Musteri_full.bak'\nWITH CHECKSUM;","what":"Yedeği doğrudan nesne depolamaya yazar: Azure Blob'a SAS credential ile block blob olarak, 2022'de S3 API uyumlu depolamaya (AWS S3, MinIO vb.) access key credential ile. Credential URL ön ekiyle eşleştirilerek otomatik seçilir.","when":"Off-site yedek gereksiniminde, buluta taşıma/hibrit DR senaryolarında, yerel yedek diski yetmediğinde.","caution":"Azure'da tek block blob en fazla 50.000 blok alır; 4 MB MAXTRANSFERSIZE ile dosya başına yaklaşık 195 GB sınırı vardır, büyük DB'yi birden çok URL'ye böl. S3'te dosya başına en fazla 10.000 part vardır; büyük DB için MAXTRANSFERSIZE'ı (en fazla 20 MB, COMPRESSION ile) artır ve birden çok URL (en fazla 64) kullan. S3'te INIT/append desteklenmez; FORMAT aynı adlı mevcut yedeğin üzerine yazar. SAS süresi dolarsa yedek job'ları sessizce değil hata ile düşer; son kullanma tarihini takvime koy. Credential secret'ı master'da saklanır; CONTROL SERVER yetkilileri credential'ı kullanabilir.","since":"2022","note":"SAS ile block blob yedeği 2016+, S3 desteği 2022+. Eski storage account key yöntemi (IDENTITY = hesap adı) page blob üretir ve önerilmez. S3 için endpoint'in TLS sertifikası sunucuda güvenilir olmalı; MinIO gibi yerel çözümlerde port URL'ye yazılır (s3://minio.local:9000/bucket/...).","tags":["backup to url","azure blob","s3","credential","sas","bulut yedek"],"untested":true},{"id":"backup-history-msdb","task":"msdb'den yedek geçmişi ve eksik yedek kontrolü","category":"Yedek & Log","command":"-- Her veritabani icin son FULL / DIFF / LOG (hic yedegi olmayanlar ustte):\nSELECT d.name AS db,\n       d.recovery_model_desc,\n       MAX(CASE WHEN b.type = 'D' THEN b.backup_finish_date END) AS last_full,\n       MAX(CASE WHEN b.type = 'I' THEN b.backup_finish_date END) AS last_diff,\n       MAX(CASE WHEN b.type = 'L' THEN b.backup_finish_date END) AS last_log,\n       DATEDIFF(MINUTE, MAX(CASE WHEN b.type = 'L' THEN b.backup_finish_date END), GETDATE()) AS log_age_min\nFROM   sys.databases d\n  LEFT JOIN msdb.dbo.backupset b\n         ON b.database_name = d.name AND b.is_copy_only = 0\nWHERE  d.name <> N'tempdb'\nGROUP BY d.name, d.recovery_model_desc\nORDER BY last_full;\n\n-- Tek DB icin son 7 gunun zinciri (LSN, boyut, dosya):\nSELECT b.backup_start_date, b.backup_finish_date, b.type, b.is_copy_only,\n       b.first_lsn, b.last_lsn, b.database_backup_lsn,\n       CAST(b.backup_size / 1048576.0 AS DECIMAL(12,1))            AS size_mb,\n       CAST(b.compressed_backup_size / 1048576.0 AS DECIMAL(12,1)) AS compressed_mb,\n       b.has_backup_checksums, mf.physical_device_name\nFROM   msdb.dbo.backupset b\n  JOIN msdb.dbo.backupmediafamily mf ON mf.media_set_id = b.media_set_id\nWHERE  b.database_name = N'Musteri'\n  AND  b.backup_start_date >= DATEADD(DAY, -7, GETDATE())\nORDER BY b.backup_start_date;","what":"Her veritabanının son FULL/DIFF/LOG yedek zamanını ve log yedeğinin yaşını; tek veritabanı için LSN sırası, sıkıştırılmış boyut, checksum ve dosya yoluyla yedek zincirini listeler.","when":"Sabah kontrolünde, restore öncesi hangi dosyaların gerektiğini bulmak için, denetimde \"son yedek ne zaman\" sorusuna, log dolması alarmında log yedeği çalışıyor mu bakmak için.","caution":"msdb yalnız bu instance'ın aldığı yedekleri bilir; başka sunucuda alınan veya AG'de diğer replikada alınan yedekler görünmez (AG'de her replikada kontrol et). Bir log yedeğinin first_lsn'i bir öncekinin last_lsn'ine eşit olmalı; boşluk zincirin kırık olduğunu gösterir. FULL modda last_log NULL ise log hiç yedeklenmiyor ve büyüyecektir. Sadece sorgu; risksiz.","note":"msdb geçmişi sınırsız büyür ve yedek job'larını yavaşlatır; EXEC msdb.dbo.sp_delete_backuphistory @oldest_date = '2026-01-01'; ile düzenli temizle. type değerleri: D = FULL, I = DIFF, L = LOG, F = file/filegroup.","tags":["backupset","msdb","yedek gecmisi","son yedek","lsn","backup history"]},{"id":"backup-restore-progress","task":"Yedek / restore / CHECKDB ilerlemesini ve bitiş tahminini gör","category":"Yedek & Log","command":"SELECT r.session_id, r.command, DB_NAME(r.database_id) AS db,\n       CAST(r.percent_complete AS DECIMAL(5,1))                     AS pct,\n       DATEADD(SECOND, r.estimated_completion_time / 1000, GETDATE()) AS eta,\n       r.total_elapsed_time / 60000                                 AS elapsed_min,\n       r.wait_type, r.wait_time, r.blocking_session_id\nFROM   sys.dm_exec_requests r\nWHERE  r.percent_complete > 0;\n\n-- Restore asamalari ve hiz bilgisi error log'da:\nEXEC sys.xp_readerrorlog 0, 1, N'Restore';","what":"percent_complete raporlayan uzun işlemlerin (BACKUP, RESTORE, DBCC CHECKDB/SHRINK, ALTER INDEX REORGANIZE, KILL sonrası rollback) yüzde ilerlemesini, tahmini bitiş saatini ve o an ne beklediğini gösterir.","when":"Gece yedeği sabaha sarktığında, büyük restore sırasında \"ne zaman biter\" sorusuna, KILL edilen oturumun rollback'ini izlerken.","caution":"Tahmin doğrusal ilerlemeye dayanır; restore'un redo/undo aşamasında ve log zero-initialization sırasında yüzde uzun süre yerinde sayabilir. Log dosyası instant file initialization'dan yararlanmaz (2022'de 64 MB'a kadar growth hariç); büyük log'lu restore'larda ilk aşama uzun sürer. Sadece sorgu; risksiz.","note":"wait_type = BACKUPIO / ASYNC_IO_COMPLETION ağırlıklıysa darboğaz hedef/kaynak diskidir; BACKUPTHREAD veya CPU yüksekse compression maliyetidir. Restore'daki uzun zeroing aşamasını error log'da ayrıntılı görmek için trace flag 3004 + 3605 kullanılır.","tags":["percent_complete","backup progress","restore progress","eta","dm_exec_requests","ilerleme"]},{"id":"tail-log-backup","task":"Restore öncesi tail-log yedeği al (NORECOVERY / NO_TRUNCATE)","category":"Restore & Kurtarma","command":"-- A) Saglam DB: son log'u al ve DB'yi RESTORING durumuna gecir (yeni yazma olmaz):\nBACKUP LOG [Musteri]\nTO DISK = N'D:\\Backup\\Musteri_tail.trn'\nWITH NORECOVERY, CHECKSUM, INIT;\n\n-- B) Hasarli DB / data file kayip, log dosyasi saglam:\n-- BACKUP LOG [Musteri]\n-- TO DISK = N'D:\\Backup\\Musteri_tail_damaged.trn'\n-- WITH NO_TRUNCATE, CONTINUE_AFTER_ERROR, INIT;\n\nSELECT name, state_desc FROM sys.databases WHERE name = N'Musteri';","what":"Son log yedeğinden bu yana oluşan ve henüz yedeklenmemiş log kısmını (tail) yedekler; böylece restore zinciri arıza anına kadar uzatılır ve son dakikaların işlemleri kaybolmaz.","when":"Aynı veritabanının üzerine restore yapmadan önce, data file diski arızalandığında, migration'da son kesme anında (cutover).","caution":"NORECOVERY veritabanını RESTORING durumuna alır ve kullanıcı erişimi biter; yanlış veritabanında çalıştırma. Restore'u WITH REPLACE ile tail-log almadan yapmak son log yedeğinden sonraki işlemleri kalıcı olarak siler. NO_TRUNCATE ile alınan yedek hasarlı metadata içerebilir; restore sonrası DBCC CHECKDB çalıştır. SIMPLE recovery'de tail-log alınamaz.","note":"Veritabanını RESTORING'den geri açmak (restore yapmadan) için: RESTORE DATABASE [Musteri] WITH RECOVERY;. NO_TRUNCATE, COPY_ONLY + CONTINUE_AFTER_ERROR ile eşdeğerdir ve veritabanı açılamıyorsa bile log'u okumaya çalışır.","tags":["tail-log","backup log","norecovery","no_truncate","restore","kurtarma"]},{"id":"restore-pitr-stopat","task":"Belirli bir zamana geri dön (point-in-time restore, STOPAT)","category":"Restore & Kurtarma","command":"-- Yan isimle restore et, orijinali bozma:\nRESTORE DATABASE [Musteri_PITR]\nFROM DISK = N'D:\\Backup\\Musteri_full_20261008.bak'\nWITH MOVE N'Musteri'     TO N'D:\\Data\\Musteri_PITR.mdf',\n     MOVE N'Musteri_log' TO N'D:\\Log\\Musteri_PITR_log.ldf',\n     NORECOVERY, STATS = 10;\n\nRESTORE DATABASE [Musteri_PITR]\nFROM DISK = N'D:\\Backup\\Musteri_diff_20261008.bak' WITH NORECOVERY;\n\n-- Tum log yedeklerini sirayla, hepsinde ayni STOPAT ile:\nRESTORE LOG [Musteri_PITR] FROM DISK = N'D:\\Backup\\Musteri_log_1200.trn'\nWITH NORECOVERY, STOPAT = '2026-10-08T14:29:00';\nRESTORE LOG [Musteri_PITR] FROM DISK = N'D:\\Backup\\Musteri_log_1500.trn'\nWITH NORECOVERY, STOPAT = '2026-10-08T14:29:00';\n\nRESTORE DATABASE [Musteri_PITR] WITH RECOVERY;\n\n-- Alternatif: STANDBY ile ara noktalarda veriyi okuyarak ilerle:\n-- RESTORE LOG [Musteri_PITR] FROM DISK = N'...' WITH STANDBY = N'D:\\Backup\\Musteri_PITR_undo.dat', STOPAT = '...';","what":"FULL + (varsa) DIFF + log yedeklerini NORECOVERY ile uygulayıp log'u verilen zamanda durdurur; veritabanını hatalı işlemin (yanlış DELETE/UPDATE, DROP) hemen öncesine döndürür.","when":"Yanlışlıkla silinen/güncellenen veriyi kurtarmak, belirli bir andaki veri durumunu incelemek veya denetim için.","caution":"Orijinal veritabanının üzerine değil yan isimle restore et, sonra gereken satırları geri taşı; üzerine restore gerekiyorsa önce tail-log yedeği al. STOPAT zamanı sunucu yerel saatidir. Recovery model FULL olmalı; STOPAT zamanını içeren log yedeği BULK_LOGGED'da minimal loglu işlem içeriyorsa o yedek içinde durulamaz. RESTORE ... WITH RECOVERY sonrası ek log uygulanamaz.","note":"STOPAT'ın tüm log restore'larında belirtilmesi önerilen kalıptır; erken dosyalarda \"contains records logged before the designated point in time\" bilgi mesajı normaldir. Transaction adıyla (BEGIN TRAN ... WITH MARK) işaretlenmiş noktaya dönmek için STOPATMARK / STOPBEFOREMARK kullanılır. Doğru zamanı bulmak için fn_dump_dblog veya uygulama loglarına bak.","tags":["stopat","point-in-time","restore log","norecovery","standby","geri donus"]},{"id":"restore-verify-header","task":"Yedek dosyasını incele ve doğrula (VERIFYONLY, HEADERONLY, FILELISTONLY)","category":"Restore & Kurtarma","command":"-- Okunabilirlik ve sayfa checksum dogrulamasi:\nRESTORE VERIFYONLY FROM DISK = N'D:\\Backup\\Musteri_full_20261008.bak' WITH CHECKSUM;\n\n-- Dosyadaki yedek setleri (tip, LSN, tarih, surum, sikistirma):\nRESTORE HEADERONLY FROM DISK = N'D:\\Backup\\Musteri_full_20261008.bak';\n\n-- Mantiksal dosya adlari ve boyutlari (MOVE icin gerekli):\nRESTORE FILELISTONLY FROM DISK = N'D:\\Backup\\Musteri_full_20261008.bak';\n\n-- Media bilgisi (stripe sayisi: FamilyCount):\nRESTORE LABELONLY FROM DISK = N'D:\\Backup\\Musteri_full_20261008.bak';","what":"Yedeği geri yüklemeden okunabilirliğini ve sayfa checksum'larını doğrular; içindeki yedek setlerini (Position, BackupType, FirstLSN/LastLSN, DatabaseVersion), mantıksal dosya adlarını ve stripe bilgisini gösterir.","when":"Başka ekipten gelen yedeği restore etmeden önce, MOVE için dosya adlarını öğrenirken, yedek job'ı sonrası hızlı doğrulamada, dosyada birden çok set varsa doğru FILE = n'yi seçerken.","caution":"VERIFYONLY veritabanının restore edilebilir ve tutarlı olduğunu garanti etmez; yalnız yedek yapısını ve (CHECKSUM ile alınmışsa) sayfa checksum'larını kontrol eder. Kesin güvence için düzenli test restore + DBCC CHECKDB yap. Daha yeni sürümde alınan yedek eski sürüme restore edilemez (DatabaseVersion'a bak). Okuma işlemleridir; risksiz.","note":"HEADERONLY'de HasBackupChecksums = 0 ise yedek CHECKSUM'sız alınmıştır ve VERIFYONLY WITH CHECKSUM sayfa doğrulaması yapamaz. INIT kullanılmayan yedek dosyalarında birden çok set birikir; restore'da WITH FILE = <Position> ver.","tags":["restore verifyonly","headeronly","filelistonly","labelonly","yedek dogrulama","checksum"]},{"id":"page-restore-suspect","task":"Bozuk sayfaları bul (suspect_pages) ve sayfa bazında restore et","category":"Restore & Kurtarma","command":"-- 823/824 ve checksum hatasi alan sayfalar:\nSELECT DB_NAME(sp.database_id) AS db, sp.file_id, sp.page_id,\n       CASE sp.event_type WHEN 1 THEN '823/824 error' WHEN 2 THEN 'bad checksum'\n            WHEN 3 THEN 'torn page'     WHEN 4 THEN 'restored'\n            WHEN 5 THEN 'repaired'      WHEN 7 THEN 'deallocated by DBCC' END AS event_desc,\n       sp.error_count, sp.last_update_date\nFROM   msdb.dbo.suspect_pages sp\nORDER BY sp.last_update_date DESC;\n\n-- Sayfa restore (ornek 1:336): FULL + sonraki log'lar + yeni log yedegi\nRESTORE DATABASE [Musteri] PAGE = '1:336'\nFROM DISK = N'D:\\Backup\\Musteri_full_20261008.bak' WITH NORECOVERY;\nRESTORE LOG [Musteri] FROM DISK = N'D:\\Backup\\Musteri_log_1200.trn' WITH NORECOVERY;\nBACKUP LOG [Musteri] TO DISK = N'D:\\Backup\\Musteri_log_pagetail.trn' WITH INIT;\nRESTORE LOG [Musteri] FROM DISK = N'D:\\Backup\\Musteri_log_pagetail.trn' WITH RECOVERY;\n\n-- Dogrula:\nDBCC CHECKDB (N'Musteri') WITH NO_INFOMSGS, ALL_ERRORMSGS;","what":"msdb.dbo.suspect_pages'tan I/O (823/824), checksum ve torn page hatası alan sayfaları listeler; tek tek bozuk sayfaları FULL yedekten alıp log'larla güncel hale getirerek tüm veritabanını restore etmeden onarır.","when":"Error log'da 823/824 hatası, CHECKDB'de az sayıda sayfada consistency error veya kullanıcı sorgusu \"incorrect checksum\" ile düştüğünde.","caution":"FULL veya BULK_LOGGED recovery ve kesintisiz log zinciri gerekir. Online page restore yalnız Enterprise/Developer'da; diğer edition'larda veritabanı restore süresince offline olur. Allocation sayfaları (GAM/SGAM/PFS), file header ve boot page (1:9) bu yöntemle restore edilemez. 823/824 çoğunlukla depolama sorunudur; disk/controller/SAN tarafını incelemeden kapatma, hata tekrar eder. Sayfa sayısı fazlaysa tüm DB restore daha hızlıdır.","note":"suspect_pages en fazla 1.000 satır tutar; dolarsa yeni hatalar kaydedilmez, eski (event_type 4/5/7) satırları temizle. Birden çok sayfa virgülle verilir: PAGE = '1:336, 1:337'. AG'de primary'deki bozuk sayfa automatic page repair ile secondary'den otomatik onarılır (sys.dm_hadr_auto_page_repair).","tags":["suspect_pages","page restore","823","824","corruption","bozuk sayfa"]},{"id":"top-queries-cpu","task":"Plan cache'ten en pahalı sorguları bul (CPU, okuma, süre)","category":"Performans","command":"SELECT TOP (20)\n       qs.query_hash,\n       SUM(qs.execution_count)                                       AS execs,\n       SUM(qs.total_worker_time) / 1000                              AS total_cpu_ms,\n       SUM(qs.total_worker_time) / SUM(qs.execution_count) / 1000    AS avg_cpu_ms,\n       SUM(qs.total_elapsed_time) / SUM(qs.execution_count) / 1000   AS avg_ms,\n       SUM(qs.total_logical_reads) / SUM(qs.execution_count)         AS avg_reads,\n       SUM(qs.total_grant_kb) / SUM(qs.execution_count)              AS avg_grant_kb,\n       COUNT(DISTINCT qs.query_plan_hash)                            AS plan_count,\n       MAX(qs.last_execution_time)                                   AS last_exec,\n       MIN(SUBSTRING(st.text, qs.statement_start_offset / 2 + 1,\n           ((CASE qs.statement_end_offset WHEN -1 THEN DATALENGTH(st.text)\n             ELSE qs.statement_end_offset END - qs.statement_start_offset) / 2) + 1)) AS statement_text,\n       MIN(DB_NAME(pa.dbid))                                         AS db\nFROM   sys.dm_exec_query_stats qs\n  CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st\n  OUTER APPLY (SELECT CONVERT(int, value) AS dbid FROM sys.dm_exec_plan_attributes(qs.plan_handle)\n               WHERE attribute = N'dbid') pa\nGROUP BY qs.query_hash\nORDER BY total_cpu_ms DESC;\n\n-- Okumaya gore siralamak icin: ORDER BY SUM(qs.total_logical_reads) DESC\n-- Plan: SELECT query_plan FROM sys.dm_exec_query_plan(<plan_handle>);","what":"Plan cache'teki ifadeleri query_hash ile gruplayarak (yalnız literal değeri farklı ad-hoc sorgular tek satırda) toplam ve ortalama CPU, süre, logical read, memory grant ve plan sayısını verir.","when":"CPU %100'e dayandığında, \"sunucu yavaş\" şikâyetinde, Query Store kapalı veritabanlarında veya sunucu genelinde (tüm DB'ler) bakış gerektiğinde.","caution":"Yalnız cache'te kalan planları görür: restart, DBCC FREEPROCCACHE, memory pressure veya RECOMPILE ile planı atılan sorgular eksik kalır. Kalıcı ve zaman aralıklı analiz için Query Store kullan. plan_count > 1 parametre hassasiyeti veya farklı SET seçenekleri işaretidir. Çok büyük plan cache'te sorgu birkaç saniye sürebilir; risksiz.","since":"2016","note":"total_grant_kb 2016+ sütunudur. Stored procedure bazında toplam için sys.dm_exec_procedure_stats kullan.","tags":["dm_exec_query_stats","top sorgu","cpu","query_hash","plan cache","pahali sorgu"]},{"id":"wait-stats-top","task":"Wait istatistikleri: sunucu neyi bekliyor","category":"Performans","command":"WITH w AS (\n    SELECT wait_type, waiting_tasks_count,\n           wait_time_ms / 1000.0                         AS wait_s,\n           (wait_time_ms - signal_wait_time_ms) / 1000.0 AS resource_s,\n           signal_wait_time_ms / 1000.0                  AS signal_s\n    FROM   sys.dm_os_wait_stats\n    WHERE  waiting_tasks_count > 0\n      AND  wait_type NOT LIKE N'SLEEP[_]%'\n      AND  wait_type NOT IN (\n           N'BROKER_EVENTHANDLER', N'BROKER_RECEIVE_WAITFOR', N'BROKER_TASK_STOP', N'BROKER_TO_FLUSH',\n           N'BROKER_TRANSMITTER', N'CHECKPOINT_QUEUE', N'CLR_AUTO_EVENT', N'CLR_MANUAL_EVENT',\n           N'DIRTY_PAGE_POLL', N'DISPATCHER_QUEUE_SEMAPHORE', N'FT_IFTS_SCHEDULER_IDLE_WAIT',\n           N'HADR_FILESTREAM_IOMGR_IOCOMPLETION', N'HADR_WORK_QUEUE', N'LAZYWRITER_SLEEP',\n           N'LOGMGR_QUEUE', N'ONDEMAND_TASK_QUEUE', N'PVS_PREALLOCATE', N'REQUEST_FOR_DEADLOCK_SEARCH',\n           N'SNI_HTTP_ACCEPT', N'SOS_WORK_DISPATCHER', N'SP_SERVER_DIAGNOSTICS_SLEEP',\n           N'SQLTRACE_BUFFER_FLUSH', N'SQLTRACE_INCREMENTAL_FLUSH_SLEEP', N'WAITFOR',\n           N'XE_DISPATCHER_WAIT', N'XE_TIMER_EVENT', N'XE_LIVE_TARGET_TVF', N'PREEMPTIVE_XE_DISPATCHER',\n           N'QDS_PERSIST_TASK_MAIN_LOOP_SLEEP', N'QDS_ASYNC_QUEUE', N'QDS_SHUTDOWN_QUEUE',\n           N'QDS_CLEANUP_STALE_QUERIES_TASK_MAIN_LOOP_SLEEP', N'PWAIT_ALL_COMPONENTS_INITIALIZED',\n           N'PWAIT_EXTENSIBILITY_CLEANUP_TASK', N'STARTUP_DEPENDENCY_MANAGER', N'WAIT_XTP_CKPT_CLOSE')\n)\nSELECT TOP (20) wait_type, waiting_tasks_count,\n       CAST(wait_s AS DECIMAL(18,1))                                AS wait_s,\n       CAST(100.0 * wait_s / SUM(wait_s) OVER () AS DECIMAL(5,1))   AS pct,\n       CAST(resource_s AS DECIMAL(18,1))                            AS resource_s,\n       CAST(signal_s AS DECIMAL(18,1))                              AS signal_s,\n       CAST(1000.0 * wait_s / waiting_tasks_count AS DECIMAL(18,2)) AS avg_wait_ms\nFROM   w\nORDER BY wait_s DESC;\n\n-- Degerler bu zamandan beri birikiyor:\nSELECT sqlserver_start_time FROM sys.dm_os_sys_info;\n\n-- Su anda bekleyen kullanici istekleri:\nSELECT wt.session_id, wt.wait_type, wt.wait_duration_ms, wt.resource_description, wt.blocking_session_id\nFROM   sys.dm_os_waiting_tasks wt\n  JOIN sys.dm_exec_sessions s ON s.session_id = wt.session_id\nWHERE  s.is_user_process = 1;","what":"Zararsız arka plan wait'lerini eleyerek sunucunun toplam bekleme süresini wait türüne göre yüzde, resource ve signal (runnable queue, CPU) payıyla verir; ayrıca şu an bekleyen kullanıcı isteklerini gösterir.","when":"Performans incelemesinin ilk adımında darboğaz türünü (I/O, CPU, lock, log, memory, paralellik) belirlemek için; değişiklik öncesi/sonrası baseline karşılaştırmasında.","caution":"Değerler restart'tan beri kümülatiftir; anlık sorun için iki snapshot alıp farkını (delta) karşılaştır. DBCC SQLPERF('sys.dm_os_wait_stats', CLEAR) tüm sunucunun sayaçlarını sıfırlar ve izleme araçlarını bozar; tercih etme. Yorum: PAGEIOLATCH_* = disk okuma, WRITELOG = log diski, LCK_M_* = blocking, CXPACKET/CXCONSUMER = paralellik, RESOURCE_SEMAPHORE = memory grant, SOS_SCHEDULER_YIELD + yüksek signal = CPU baskısı. Sadece sorgu; risksiz.","note":"Oturum bazında wait dağılımı için 2016+ sys.dm_exec_session_wait_stats; Query Store'da sorgu bazında wait kategorileri için sys.query_store_wait_stats (2017+) kullan.","tags":["wait stats","dm_os_wait_stats","bekleme","pageiolatch","writelog","performans"]},{"id":"deadlock-system-health","task":"Geçmiş deadlock'ları system_health oturumundan oku (deadlock graph)","category":"Performans","command":"SET QUOTED_IDENTIFIER ON;  -- XML metodlari icin gerekli (sqlcmd/Agent varsayilani OFF)\nWITH dl AS (\n    SELECT CAST(event_data AS XML) AS x\n    FROM   sys.fn_xe_file_target_read_file(N'system_health*.xel', NULL, NULL, NULL)\n    WHERE  object_name = N'xml_deadlock_report'\n)\nSELECT TOP (20)\n       x.value('(event/@timestamp)[1]', 'datetime2')                                          AS utc_time,\n       x.value('(event/data/value/deadlock/victim-list/victimProcess/@id)[1]', 'varchar(50)')  AS victim,\n       x.value('count(event/data/value/deadlock/process-list/process)', 'int')                 AS process_count,\n       x.value('(event/data/value/deadlock/process-list/process/@currentdbname)[1]', 'sysname') AS db,\n       x.query('event/data/value/deadlock')                                                    AS deadlock_graph\nFROM   dl\nORDER BY utc_time DESC;","what":"Varsayılan açık gelen system_health Extended Events oturumunun event_file hedefinden xml_deadlock_report event'lerini okur; her deadlock için zaman (UTC), victim process, katılımcı sayısı, veritabanı ve tam deadlock graph XML'ini verir.","when":"Uygulama 1205 hatası raporladığında, deadlock sıklığını ve hangi nesnelerde yaşandığını analiz ederken; trace flag 1222 açık olmayan sunucularda.","caution":"system_health dosyaları rollover ile döner; yoğun sunucuda eski deadlock'lar silinmiş olabilir, kalıcı arşiv için ayrı XE oturumu kur. Dosya sayısı büyükse okuma CPU tüketir; mesai içinde TOP ile sınırla. Event dosyaya gecikmeli yazılır, yeni deadlock birkaç saniye sonra görünür. Sadece okuma; risksiz.","note":"deadlock_graph sütununa tıklayıp .xdl olarak kaydedersen SSMS grafik olarak açar. system_health event_file varsayılanı 2016 SP2 CU12 / 2017 CU20 / 2019 CU3 ve sonrasında (Standard/Enterprise) 10 x 100 MB'dir; daha eski build'lerde ve diğer edition'larda 4 x 5 MB. Graph'ta inputbuf, waitresource (KEY/PAGE/OBJECT) ve lockMode alanları çözümün anahtarıdır; çoğu deadlock eksik index veya tutarsız erişim sırasıyla çözülür.","tags":["deadlock","system_health","xml_deadlock_report","extended events","1205","deadlock graph"]},{"id":"xe-long-query-session","task":"Extended Events oturumu kur: yavaş sorguları dosyaya yakala ve oku","category":"Performans","command":"SET QUOTED_IDENTIFIER ON;\nCREATE EVENT SESSION [dba_long_queries] ON SERVER\nADD EVENT sqlserver.sql_statement_completed (\n    ACTION (sqlserver.client_app_name, sqlserver.client_hostname, sqlserver.database_name,\n            sqlserver.session_id, sqlserver.sql_text, sqlserver.username, sqlserver.query_hash)\n    WHERE (duration >= 1000000 AND sqlserver.is_system = 0)),   -- 1 sn (mikrosaniye)\nADD EVENT sqlserver.rpc_completed (\n    ACTION (sqlserver.client_app_name, sqlserver.client_hostname, sqlserver.database_name,\n            sqlserver.session_id, sqlserver.sql_text, sqlserver.username, sqlserver.query_hash)\n    WHERE (duration >= 1000000 AND sqlserver.is_system = 0))\nADD TARGET package0.event_file (SET filename = N'D:\\XE\\dba_long_queries.xel',\n                                    max_file_size = 256, max_rollover_files = 4)\nWITH (MAX_MEMORY = 8 MB, EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS,\n      MAX_DISPATCH_LATENCY = 15 SECONDS, STARTUP_STATE = OFF);\n\nALTER EVENT SESSION [dba_long_queries] ON SERVER STATE = START;\n\n-- Oku:\nSELECT x.value('(event/@name)[1]', 'sysname')                                AS event_name,\n       x.value('(event/@timestamp)[1]', 'datetime2')                         AS utc_time,\n       x.value('(event/data[@name=\"duration\"]/value)[1]', 'bigint') / 1000   AS duration_ms,\n       x.value('(event/data[@name=\"cpu_time\"]/value)[1]', 'bigint') / 1000   AS cpu_ms,\n       x.value('(event/data[@name=\"logical_reads\"]/value)[1]', 'bigint')     AS logical_reads,\n       x.value('(event/action[@name=\"database_name\"]/value)[1]', 'sysname')  AS db,\n       x.value('(event/action[@name=\"client_app_name\"]/value)[1]', 'nvarchar(256)') AS app,\n       x.value('(event/action[@name=\"sql_text\"]/value)[1]', 'nvarchar(max)') AS sql_text\nFROM  (SELECT CAST(event_data AS XML) AS x\n       FROM sys.fn_xe_file_target_read_file(N'D:\\XE\\dba_long_queries*.xel', NULL, NULL, NULL)) t\nORDER BY duration_ms DESC;\n\n-- Is bitince:\n-- ALTER EVENT SESSION [dba_long_queries] ON SERVER STATE = STOP;\n-- DROP EVENT SESSION [dba_long_queries] ON SERVER;","what":"1 saniyeden uzun süren ifade ve RPC çağrılarını uygulama, host, kullanıcı, veritabanı ve SQL metniyle diske yazan hafif bir Extended Events oturumu kurar; .xel dosyalarını T-SQL ile tabloya çevirir.","when":"Aralıklı yavaşlık şikâyetinde, Query Store'un göstermediği istemci bilgisi (app/host) gerektiğinde, SQL Trace/Profiler yerine.","caution":"Eşik çok düşük (ör. 0) seçilirse yoğun sunucuda dosyalar hızla dolar ve ek yük oluşur; filtreyi WHERE'de ver, sonradan değil. sql_text action'ı yüksek hacimde maliyetlidir. Klasör SQL Server servis hesabının yazabileceği bir yer olmalı. duration mikrosaniye, cpu_time mikrosaniyedir. İş bitince oturumu durdur/sil; STARTUP_STATE = OFF restart sonrası otomatik başlamaz.","note":"Belirli bir veritabanına daraltmak için WHERE'e sqlserver.database_name = N'Musteri' ekle. Hızlı bakış için SSMS > Management > Extended Events > Watch Live Data.","tags":["extended events","xe","event session","yavas sorgu","sql_statement_completed","event_file"]},{"id":"tempdb-contention","task":"tempdb contention ve alan kullanımını teşhis et","category":"Performans","command":"-- 1) Anlik tempdb sayfa latch beklemeleri (2:1:1 PFS, 2:1:2 GAM, 2:1:3 SGAM):\nSELECT wt.session_id, wt.wait_type, wt.wait_duration_ms, wt.resource_description\nFROM   sys.dm_os_waiting_tasks wt\nWHERE  wt.wait_type LIKE N'PAGELATCH[_]%'\n  AND  wt.resource_description LIKE N'2:%';\n\n-- 2) tempdb'yi en cok kullanan oturumlar (MB):\nSELECT TOP (20) su.session_id, s.login_name, s.program_name,\n       (su.user_objects_alloc_page_count - su.user_objects_dealloc_page_count) * 8 / 1024         AS user_obj_mb,\n       (su.internal_objects_alloc_page_count - su.internal_objects_dealloc_page_count) * 8 / 1024 AS internal_obj_mb\nFROM   sys.dm_db_session_space_usage su\n  JOIN sys.dm_exec_sessions s ON s.session_id = su.session_id\nWHERE  s.is_user_process = 1\nORDER BY su.user_objects_alloc_page_count + su.internal_objects_alloc_page_count\n       - su.user_objects_dealloc_page_count - su.internal_objects_dealloc_page_count DESC;\n\n-- 3) Genel dagilim ve version store:\nSELECT SUM(unallocated_extent_page_count) * 8 / 1024       AS free_mb,\n       SUM(user_object_reserved_page_count) * 8 / 1024     AS user_obj_mb,\n       SUM(internal_object_reserved_page_count) * 8 / 1024 AS internal_obj_mb,\n       SUM(version_store_reserved_page_count) * 8 / 1024   AS version_store_mb\nFROM   tempdb.sys.dm_db_file_space_usage;\n\nSELECT DB_NAME(database_id) AS db, reserved_page_count * 8 / 1024 AS version_store_mb\nFROM   sys.dm_tran_version_store_space_usage\nORDER BY reserved_page_count DESC;\n\n-- 4) Dosya sayisi / esit boyut ve memory-optimized metadata:\nSELECT name, type_desc, size * 8 / 1024 AS size_mb, growth * 8 / 1024 AS growth_mb, is_percent_growth\nFROM   tempdb.sys.database_files;\nSELECT SERVERPROPERTY('IsTempdbMetadataMemoryOptimized') AS tempdb_metadata_memopt;","what":"tempdb allocation sayfalarındaki (PFS/GAM/SGAM) ve sistem tablolarındaki PAGELATCH beklemelerini, tempdb'yi en çok kullanan oturumları (temp tablo vs. sort/hash spill), version store'u hangi veritabanının şişirdiğini ve dosya yapılandırmasını gösterir.","when":"Yoğun temp tablo kullanan iş yükünde PAGELATCH_UP/EX beklemeleri artınca, tempdb dolduğunda (1105/9002), version store büyümesinde.","caution":"2:1:1, 2:1:2, 2:1:3 ve 8088'in katı PFS sayfaları allocation contention'dır: çözüm eşit boyutlu, eşit growth'lu birden çok data file'dır (8 çekirdeğe kadar çekirdek başına bir, sonra 4'er artır). Sistem tablosu sayfalarında (2:1:1xx) contention için 2019+ memory-optimized tempdb metadata açılır (restart gerektirir). Version store büyüyorsa en eski açık snapshot transaction'ı bul; tempdb shrink çözüm değildir. Sadece sorgu; risksiz.","note":"Memory-optimized metadata: ALTER SERVER CONFIGURATION SET MEMORY_OPTIMIZED TEMPDB_METADATA = ON; + restart (2019+). 2022'de GAM/SGAM için de latch-free güncellemeler geldi ve contention ciddi biçimde azaldı. Version store'u tutan transaction: sys.dm_tran_active_snapshot_database_transactions ORDER BY elapsed_time_seconds DESC.","tags":["tempdb","pagelatch","pfs","gam","version store","contention"]},{"id":"qs-enable-config","task":"Query Store'u aç, önerilen ayarları ver ve durumunu kontrol et","category":"Query Store","command":"ALTER DATABASE [Musteri] SET QUERY_STORE = ON;\nALTER DATABASE [Musteri] SET QUERY_STORE (\n    OPERATION_MODE = READ_WRITE,\n    QUERY_CAPTURE_MODE = AUTO,\n    MAX_STORAGE_SIZE_MB = 2048,\n    INTERVAL_LENGTH_MINUTES = 15,\n    DATA_FLUSH_INTERVAL_SECONDS = 900,\n    CLEANUP_POLICY = (STALE_QUERY_THRESHOLD_DAYS = 30),\n    SIZE_BASED_CLEANUP_MODE = AUTO,\n    MAX_PLANS_PER_QUERY = 200,\n    WAIT_STATS_CAPTURE_MODE = ON);\n\n-- Durum: actual_state READ_ONLY'ye dustuyse readonly_reason'a bak\nUSE [Musteri];\nSELECT actual_state_desc, desired_state_desc, readonly_reason,\n       current_storage_size_mb, max_storage_size_mb,\n       query_capture_mode_desc, size_based_cleanup_mode_desc, wait_stats_capture_mode_desc\nFROM   sys.database_query_store_options;","what":"Veritabanında Query Store'u açar; sorgu metinlerini, planları, runtime ve wait istatistiklerini zaman aralıklarıyla kalıcı olarak saklamaya başlar. Seçenekler depolama sınırı, temizleme ve yakalama modunu belirler.","when":"Yeni veritabanı canlıya alınırken, sürüm/compat level yükseltmesi öncesi (baseline için), plan regresyonu şüphesinde.","caution":"MAX_STORAGE_SIZE_MB dolarsa Query Store sessizce READ_ONLY'ye geçer (readonly_reason = 65536) ve yeni veri toplanmaz; current_storage_size_mb'yi izle. QUERY_CAPTURE_MODE = ALL yoğun ad-hoc iş yükünde depolamayı hızla doldurur ve ek yük getirir. Çok yoğun OLTP'de QDS_* wait'leri görülebilir. Kapatmak (OFF) toplanan veriyi silmez; CLEAR siler.","since":"2016","note":"2022'de yeni oluşturulan veritabanlarında Query Store varsayılan olarak READ_WRITE açıktır. 2019+ QUERY_CAPTURE_MODE = CUSTOM ile eşik (EXECUTION_COUNT, TOTAL_COMPILE_CPU_TIME_MS, TOTAL_EXECUTION_CPU_TIME_MS) verilebilir. Readable secondary'ler için Query Store (ALTER DATABASE ... FOR SECONDARY SET QUERY_STORE = ON) 2022'de yalnız trace flag 12606 ile açılan ve production'da desteklenmeyen limited preview'dur; 2025'te trace flag gerekmez (hâlâ preview).","tags":["query store","enable","max_storage_size_mb","query_capture_mode","read_only","qds"]},{"id":"qs-regressed-queries","task":"Query Store ile plan regresyonu bul (aynı sorgu, farklı planlar)","category":"Query Store","command":"USE [Musteri];\n-- Son 24 saatte birden fazla plani olan sorgular, plan bazinda performans:\nWITH plan_stats AS (\n    SELECT p.query_id, p.plan_id, p.is_forced_plan,\n           SUM(rs.count_executions) AS execs,\n           SUM(rs.avg_duration * rs.count_executions) / SUM(rs.count_executions) / 1000.0     AS avg_ms,\n           SUM(rs.avg_cpu_time * rs.count_executions) / SUM(rs.count_executions) / 1000.0     AS avg_cpu_ms,\n           SUM(rs.avg_logical_io_reads * rs.count_executions) / SUM(rs.count_executions)      AS avg_reads,\n           MAX(rs.last_execution_time) AS last_exec\n    FROM   sys.query_store_plan p\n      JOIN sys.query_store_runtime_stats rs ON rs.plan_id = p.plan_id\n      JOIN sys.query_store_runtime_stats_interval i\n        ON i.runtime_stats_interval_id = rs.runtime_stats_interval_id\n    WHERE  i.start_time >= DATEADD(HOUR, -24, SYSUTCDATETIME())\n    GROUP BY p.query_id, p.plan_id, p.is_forced_plan\n)\nSELECT ps.query_id, ps.plan_id, ps.is_forced_plan, ps.execs,\n       CAST(ps.avg_ms AS DECIMAL(18,2))     AS avg_ms,\n       CAST(ps.avg_cpu_ms AS DECIMAL(18,2)) AS avg_cpu_ms,\n       CAST(ps.avg_reads AS BIGINT)         AS avg_reads,\n       CAST(ps.avg_ms / NULLIF(MIN(ps.avg_ms) OVER (PARTITION BY ps.query_id), 0) AS DECIMAL(18,1)) AS x_slower_than_best,\n       ps.last_exec,\n       OBJECT_NAME(q.object_id)     AS module,\n       LEFT(qt.query_sql_text, 120) AS query_text\nFROM   plan_stats ps\n  JOIN sys.query_store_query q       ON q.query_id = ps.query_id\n  JOIN sys.query_store_query_text qt ON qt.query_text_id = q.query_text_id\nWHERE  ps.query_id IN (SELECT query_id FROM plan_stats GROUP BY query_id HAVING COUNT(*) > 1)\nORDER BY ps.query_id, ps.avg_ms;","what":"Son 24 saatte birden fazla planla çalışan sorguları bulur; her planın çalışma sayısını, ağırlıklı ortalama süre/CPU/okuma değerlerini ve en iyi plana göre kaç kat yavaş olduğunu yan yana koyar.","when":"Bir sorgu \"dün hızlıydı bugün yavaş\" olduğunda, istatistik güncellemesi, index değişikliği, compat level yükseltmesi veya patch sonrası.","caution":"Ortalama süre veri dağılımına da bağlıdır; farklı parametre değerleriyle çalışan planları karşılaştırırken avg_reads'e de bak (parameter sniffing). Zaman aralığı UTC'dir. Az çalışmış (execs düşük) planlar için sonuç istatistiksel olarak zayıftır. Sadece sorgu; risksiz.","since":"2016","note":"SSMS > Query Store > Regressed Queries raporu aynı işi grafik olarak yapar. 2022'de compat level 160 ile Parameter Sensitive Plan (PSP) optimization aynı ifade için birden çok variant query_id üretir; bunları sys.query_store_query_variant (parent_query_id) ile ana sorguya bağla. 2017+ automatic tuning (FORCE_LAST_GOOD_PLAN) bu regresyonu otomatik düzeltebilir.","tags":["query store","plan regresyonu","regressed queries","parameter sniffing","query_store_runtime_stats","plan"]},{"id":"qs-force-plan-hints","task":"Query Store ile iyi planı zorla (force plan) veya hint ekle","category":"Query Store","command":"USE [Musteri];\n-- Iyi plani zorla (query_id / plan_id regresyon sorgusundan):\nEXEC sys.sp_query_store_force_plan @query_id = 42, @plan_id = 7;\n\n-- Zorlanmis planlar ve basarisizlik nedeni:\nSELECT p.query_id, p.plan_id, p.is_forced_plan, p.plan_forcing_type_desc,\n       p.force_failure_count, p.last_force_failure_reason_desc\nFROM   sys.query_store_plan p\nWHERE  p.is_forced_plan = 1;\n\n-- Geri al:\nEXEC sys.sp_query_store_unforce_plan @query_id = 42, @plan_id = 7;\n\n-- 2022+: kodu degistirmeden sorguya hint ekle / kaldir:\nEXEC sys.sp_query_store_set_hints @query_id = 42, @query_hints = N'OPTION (RECOMPILE)';\nSELECT query_id, query_hint_text, last_query_hint_failure_reason_desc\nFROM   sys.query_store_query_hints;\nEXEC sys.sp_query_store_clear_hints @query_id = 42;","what":"Seçilen sorgu için Query Store'daki belirli bir planı zorlar; optimizer her derlemede o planı kullanır. 2022'de alternatif olarak uygulama kodunu değiştirmeden sorguya RECOMPILE, MAXDOP, OPTIMIZE FOR gibi hint'ler bağlanır.","when":"Plan regresyonu nedeniyle canlıda acil müdahale gerektiğinde, kalıcı düzeltme (index, sorgu yeniden yazımı, istatistik) hazırlanana kadar.","caution":"Zorlanan plan veri büyüdükçe kötüleşebilir ve kalıcı çözüm değildir; düzenli gözden geçir. Plan kullandığı index silinir/yeniden adlandırılırsa forcing başarısız olur (last_force_failure_reason_desc = NO_INDEX vb.) ve sorgu normal derlenir. Forcing sonrası \"morally equivalent\" plan yeni bir plan_id ile görünebilir; bu normaldir. Query Store READ_ONLY iken de forcing çalışır; restore veya AG failover sonrası yine de kontrol et.","since":"2016","note":"Query Store hints 2022+ (Azure SQL'de daha önce). Hint'ler plan guide'ların yerini alır; hint uygulanamazsa sorgu hint'siz çalışır ve nedeni last_query_hint_failure_reason_desc'te görünür. Readable secondary'de plan forcing (@replica_group_id) Query Store for secondary replicas açık olmasını gerektirir; bu özellik 2022'de trace flag 12606 ile açılan limited preview'dur.","tags":["force plan","sp_query_store_force_plan","query store hints","plan zorla","regresyon","recompile"]},{"id":"missing-index-dmv","task":"Eksik index önerilerini DMV'lerden oku (uyarılarıyla)","category":"Bakım","command":"USE [Musteri];\nSELECT TOP (25)\n       mid.statement                                   AS table_name,\n       mid.equality_columns, mid.inequality_columns, mid.included_columns,\n       migs.user_seeks, migs.user_scans,\n       CAST(migs.avg_total_user_cost AS DECIMAL(18,2)) AS avg_query_cost,\n       migs.avg_user_impact                            AS est_impact_pct,\n       CAST(migs.user_seeks * migs.avg_total_user_cost * migs.avg_user_impact / 100.0 AS DECIMAL(18,0)) AS score,\n       migs.last_user_seek,\n       N'CREATE INDEX [IX_' + OBJECT_NAME(mid.object_id, mid.database_id) + N'_missing_'\n         + CAST(mid.index_handle AS NVARCHAR(10)) + N'] ON ' + mid.statement + N' ('\n         + ISNULL(mid.equality_columns, N'')\n         + CASE WHEN mid.equality_columns IS NOT NULL AND mid.inequality_columns IS NOT NULL THEN N', ' ELSE N'' END\n         + ISNULL(mid.inequality_columns, N'') + N')'\n         + ISNULL(N' INCLUDE (' + mid.included_columns + N')', N'') AS create_stmt_draft\nFROM   sys.dm_db_missing_index_details mid\n  JOIN sys.dm_db_missing_index_groups mig       ON mig.index_handle = mid.index_handle\n  JOIN sys.dm_db_missing_index_group_stats migs ON migs.group_handle = mig.index_group_handle\nWHERE  mid.database_id = DB_ID()\nORDER BY score DESC;\n\n-- 2019+: oneriyi doguran sorgu metni:\nSELECT TOP (25) mid.statement AS table_name, misq.group_handle, misq.user_seeks,\n       SUBSTRING(st.text, misq.last_statement_start_offset / 2 + 1, 300) AS statement_text\nFROM   sys.dm_db_missing_index_group_stats_query misq\n  JOIN sys.dm_db_missing_index_groups mig  ON mig.index_group_handle = misq.group_handle\n  JOIN sys.dm_db_missing_index_details mid ON mid.index_handle = mig.index_handle\n  CROSS APPLY sys.dm_exec_sql_text(misq.last_sql_handle) st\nWHERE  mid.database_id = DB_ID()\nORDER BY misq.user_seeks DESC;","what":"Optimizer'ın derleme sırasında kaydettiği eksik index önerilerini kullanım sayısı, tahmini maliyet ve etkiye göre puanlar, taslak CREATE INDEX ifadesi üretir; 2019+ ile öneriyi doğuran sorguyu da gösterir.","when":"Yeni uygulama sürümü sonrası, yüksek okuma yapan sorguların index ihtiyacını hızlı tarama için, index tasarımı gözden geçirmesinde başlangıç listesi olarak.","caution":"Öneriler körü körüne uygulanmamalı: optimizer mevcut index'lere bakmadan önerir, sık sık neredeyse aynı (overlapping) öneriler ve gereksiz geniş INCLUDE listeleri üretir, sütun sırasını seçicilik değil eşitlik/eşitsizlik ayrımına göre verir. Her yeni index yazma maliyeti ve depolama getirir; önce mevcut index'i genişletmeyi düşün. DMV restart, DB offline ve tablo üzerindeki index değişikliğinde sıfırlanır. Sadece sorgu; risksiz.","note":"Önerilen index'i oluşturmadan önce aynı tablodaki index'leri sp_helpindex veya sys.index_columns ile karşılaştır ve kullanılmayan index reçetesiyle birlikte değerlendir. Plan XML'inde MissingIndex elemanı aynı bilgiyi sorgu bazında verir.","tags":["missing index","eksik index","dm_db_missing_index_details","index onerisi","create index","tuning"]},{"id":"unused-indexes","task":"Kullanılmayan / yalnız yazılan index'leri bul","category":"Bakım","command":"USE [Musteri];\nSELECT OBJECT_SCHEMA_NAME(i.object_id) AS schema_name,\n       OBJECT_NAME(i.object_id)        AS table_name,\n       i.name                          AS index_name,\n       ISNULL(us.user_seeks, 0) + ISNULL(us.user_scans, 0) + ISNULL(us.user_lookups, 0) AS reads,\n       ISNULL(us.user_updates, 0)      AS writes,\n       ps.used_mb,\n       us.last_user_seek, us.last_user_scan,\n       N'DROP INDEX ' + QUOTENAME(i.name) + N' ON ' + QUOTENAME(OBJECT_SCHEMA_NAME(i.object_id))\n         + N'.' + QUOTENAME(OBJECT_NAME(i.object_id)) + N';' AS drop_stmt_draft\nFROM   sys.indexes i\n  LEFT JOIN sys.dm_db_index_usage_stats us\n         ON us.database_id = DB_ID() AND us.object_id = i.object_id AND us.index_id = i.index_id\n  CROSS APPLY (SELECT CAST(SUM(p.used_page_count) * 8 / 1024.0 AS DECIMAL(18,1)) AS used_mb\n               FROM sys.dm_db_partition_stats p\n               WHERE p.object_id = i.object_id AND p.index_id = i.index_id) ps\nWHERE  OBJECTPROPERTY(i.object_id, 'IsUserTable') = 1\n  AND  i.type_desc = N'NONCLUSTERED'\n  AND  i.is_primary_key = 0 AND i.is_unique_constraint = 0 AND i.is_unique = 0\n  AND  ISNULL(us.user_seeks, 0) + ISNULL(us.user_scans, 0) + ISNULL(us.user_lookups, 0) = 0\nORDER BY writes DESC, ps.used_mb DESC;\n\n-- Kullanim sayaclari bu zamandan beri:\nSELECT sqlserver_start_time FROM sys.dm_os_sys_info;","what":"Restart'tan bu yana hiç okunmamış (seek/scan/lookup = 0) ama yazma maliyeti üreten nonclustered index'leri boyutlarıyla listeler ve taslak DROP INDEX ifadesi üretir.","when":"Yazma yoğun tablolarda INSERT/UPDATE yavaşlığında, depolama ve bakım (rebuild, CHECKDB) süresini azaltmak için, index konsolidasyonu öncesi.","caution":"Sayaçlar restart'ta, DB offline/detach'ta ve bazı eski build'lerde (2012/2014) index rebuild'de sıfırlanır; ay sonu/yıl sonu raporlarının kullandığı index'ler kısa gözlemde \"kullanılmıyor\" görünür. Silmeden önce en az bir tam iş döngüsü boyunca gözle ve AG'de readable secondary'lerdeki kullanımı ayrıca kontrol et (sayaçlar replika bazındadır). Unique index'ler okunmasa da constraint sağlar; listeden çıkarıldı. Sadece sorgu; risksiz.","note":"Silmek yerine önce ALTER INDEX ... DISABLE ile devre dışı bırakmak geri dönüşü kolaylaştırır (tanım kalır, REBUILD ile geri gelir). Query Store veya plan cache'te index adını aramak, index'in hint ile kullanılıp kullanılmadığını gösterir.","tags":["unused index","kullanilmayan index","dm_db_index_usage_stats","drop index","write overhead","index"]},{"id":"stats-health","task":"İstatistik sağlığı: ne zaman güncellendi, kaç satır değişti","category":"Bakım","command":"USE [Musteri];\nSELECT OBJECT_SCHEMA_NAME(s.object_id) AS schema_name,\n       OBJECT_NAME(s.object_id)        AS table_name,\n       s.name                          AS stats_name,\n       s.auto_created, s.has_filter, s.no_recompute,\n       sp.last_updated,\n       sp.rows, sp.rows_sampled,\n       CAST(100.0 * sp.rows_sampled / NULLIF(sp.rows, 0) AS DECIMAL(5,1))         AS sample_pct,\n       sp.modification_counter,\n       CAST(100.0 * sp.modification_counter / NULLIF(sp.rows, 0) AS DECIMAL(9,1)) AS modified_pct,\n       CAST(CASE WHEN 500 + 0.20 * sp.rows < SQRT(1000.0 * sp.rows) THEN 500 + 0.20 * sp.rows\n                 ELSE SQRT(1000.0 * sp.rows) END AS BIGINT)                       AS auto_update_threshold,\n       sp.persisted_sample_percent\nFROM   sys.stats s\n  CROSS APPLY sys.dm_db_stats_properties(s.object_id, s.stats_id) sp\nWHERE  OBJECTPROPERTY(s.object_id, 'IsUserTable') = 1\nORDER BY sp.modification_counter DESC;\n\nSELECT name, is_auto_create_stats_on, is_auto_update_stats_on, is_auto_update_stats_async_on\nFROM   sys.databases\nWHERE  name = DB_NAME();","what":"Her istatistiğin son güncellenme zamanını, örnekleme oranını, son güncellemeden bu yana değişen satır sayısını ve otomatik güncellemenin tetikleneceği eşiği (compat 130+ dinamik eşik) gösterir.","when":"Tahmini ve gerçek satır sayısı arasında büyük fark olan planlarda, büyük veri yüklemesi sonrası, istatistik bakım job'ının etkinliğini kontrol ederken.","caution":"Eşik formülü compat level 130+ içindir (MIN(500 + %20, SQRT(1000 x satır))); daha düşük compat'ta %20 + 500 kuralı geçerlidir. Hiç güncellenmemiş istatistiklerde (boş tablo) değerler NULL döner. Düşük sample_pct'li ve çarpık dağılımlı sütunlarda FULLSCAN veya PERSIST_SAMPLE_PERCENT gerekebilir. Sadece sorgu; risksiz.","since":"2016","note":"persisted_sample_percent 2016 SP1 CU4 / 2017 CU1+ ile gelen UPDATE STATISTICS ... WITH PERSIST_SAMPLE_PERCENT = ON ayarını gösterir. Güncelleme komutları için update-statistics reçetesine bak.","tags":["statistics","istatistik","dm_db_stats_properties","modification_counter","auto update","cardinality"]},{"id":"checkdb-strategy","task":"DBCC CHECKDB stratejisi: son başarılı kontrol, bölerek çalıştırma, sonucu yorumlama","category":"Bakım","command":"-- Son basarili CHECKDB (1900-01-01 = hic yapilmamis):\nSELECT name, DATABASEPROPERTYEX(name, 'LastGoodCheckDbTime') AS last_good_checkdb\nFROM   sys.databases\nWHERE  state_desc = N'ONLINE' AND name <> N'tempdb'\nORDER BY last_good_checkdb;\n\n-- tempdb ihtiyaci tahmini:\nDBCC CHECKDB (N'Musteri') WITH ESTIMATEONLY;\n\n-- Buyuk DB'yi gunlere bol: allocation + catalog + tablo tablo CHECKTABLE\nUSE [Musteri];\nDBCC CHECKALLOC (N'Musteri') WITH NO_INFOMSGS;\nDBCC CHECKCATALOG (N'Musteri') WITH NO_INFOMSGS;\nDBCC CHECKTABLE (N'dbo.Siparis') WITH NO_INFOMSGS, ALL_ERRORMSGS;\n\n-- Sonucu tablo olarak al (hata satirlari, nesne ve sayfa bilgisi):\nDBCC CHECKDB (N'Musteri') WITH TABLERESULTS, NO_INFOMSGS, ALL_ERRORMSGS, MAXDOP = 4;","what":"Her veritabanında son başarılı CHECKDB zamanını gösterir, gereken tempdb alanını tahmin eder, büyük veritabanlarında kontrolü CHECKALLOC + CHECKCATALOG + CHECKTABLE parçalarına bölmeyi ve sonuçları satır olarak (nesne, index, sayfa) almayı sağlar.","when":"Bakım planını denetlerken, bakım penceresine sığmayan çok büyük veritabanlarında, 823/824 sonrası bozulmanın kapsamını belirlerken.","caution":"Sonuç satırındaki \"repair_allow_data_loss is the minimum repair level\" ifadesi onarımın veri sileceği anlamına gelir; önce sağlam yedekten restore (veya page restore) değerlendir. Yalnız nonclustered index (index_id > 1) hatalarıysa index'i drop/create etmek veri kaybı olmadan çözer. Hatayı bulduktan sonra disk alt sistemini incele. PHYSICAL_ONLY mantıksal kontrolleri atlar; arada bir tam CHECKDB şart. CHECKTABLE ile bölmede CHECKALLOC/CHECKCATALOG da çalıştırılmazsa kapsam eksik kalır.","note":"DATABASEPROPERTYEX(..., 'LastGoodCheckDbTime') 2016 SP2, 2017 CU9 ve 2019+ ile gelir; daha eski sürümlerde DBCC DBINFO WITH TABLERESULTS çıktısındaki dbi_dbccLastKnownGood alanına bakılır. Üretim yükünü azaltmak için CHECKDB'yi yedekten restore edilen bir kopyada (ör. test sunucusunda) çalıştırmak üretim veritabanını da doğrular. MAXDOP seçeneği 2014 SP2 / 2016+.","tags":["dbcc checkdb","lastgoodcheckdbtime","checktable","corruption","repair_allow_data_loss","butunluk"]},{"id":"resource-governor","task":"Resource Governor ile rapor yükünü sınırla (pool, workload group, classifier)","category":"Yapılandırma","command":"USE master;\n-- 1) Havuz ve workload group:\nCREATE RESOURCE POOL [pool_report]\nWITH (MIN_CPU_PERCENT = 0, MAX_CPU_PERCENT = 30, CAP_CPU_PERCENT = 40,\n      MIN_MEMORY_PERCENT = 0, MAX_MEMORY_PERCENT = 25);\nCREATE WORKLOAD GROUP [wg_report]\nWITH (IMPORTANCE = LOW, REQUEST_MAX_MEMORY_GRANT_PERCENT = 15,\n      MAX_DOP = 2, REQUEST_MAX_CPU_TIME_SEC = 600)\nUSING [pool_report];\nGO\n-- 2) Classifier function (master'da, SCHEMABINDING zorunlu):\nCREATE FUNCTION dbo.fn_rg_classifier()\nRETURNS sysname\nWITH SCHEMABINDING\nAS\nBEGIN\n    DECLARE @grp sysname = N'default';\n    IF SUSER_SNAME() = N'rapor_user' OR APP_NAME() LIKE N'Power BI%'\n        SET @grp = N'wg_report';\n    RETURN @grp;\nEND;\nGO\n-- 3) Etkinlestir:\nALTER RESOURCE GOVERNOR WITH (CLASSIFIER_FUNCTION = dbo.fn_rg_classifier);\nALTER RESOURCE GOVERNOR RECONFIGURE;\n\n-- 4) Hangi oturum hangi gruba dustu:\nSELECT s.session_id, s.login_name, s.program_name, wg.name AS workload_group, rp.name AS pool\nFROM   sys.dm_exec_sessions s\n  JOIN sys.dm_resource_governor_workload_groups wg ON wg.group_id = s.group_id\n  JOIN sys.dm_resource_governor_resource_pools rp  ON rp.pool_id = wg.pool_id\nWHERE  s.is_user_process = 1;\n\n-- Geri alma:\n-- ALTER RESOURCE GOVERNOR WITH (CLASSIFIER_FUNCTION = NULL); ALTER RESOURCE GOVERNOR DISABLE;","what":"Belirli login veya uygulamalardan gelen oturumları bağlantı anında ayrı bir workload group'a yönlendirir; o grubun CPU, memory grant, DOP ve istek başına CPU süresini sınırlayarak OLTP yükünü korur.","when":"Rapor/BI sorguları OLTP'yi boğduğunda, ETL ile mesai yükü çakıştığında, çok kiracılı (multi-tenant) sunucuda kaynak paylaşımında.","caution":"Classifier function her yeni bağlantıda çalışır; yavaş veya hata veren fonksiyon tüm login'leri yavaşlatır/bozar (sorgu, tablo erişimi koyma). Sorun olursa DAC ile bağlanıp CLASSIFIER_FUNCTION = NULL yap. Sınıflandırma yalnız bağlantı anında yapılır; mevcut oturumlar etkilenmez. CAP_CPU_PERCENT sert sınırdır ve boşta CPU olsa bile uygulanır. MAX_CPU_PERCENT yalnız CPU rekabeti varken devreye girer. Resource Governor Enterprise/Developer özelliğidir.","note":"REQUEST_MAX_CPU_TIME_SEC aşımı varsayılan olarak yalnız event üretir (cpu_threshold_exceeded); 2016 SP2 / 2017 CU3+ sürümlerinde trace flag 2422 ile istek iptal edilir. I/O sınırı için pool'da MAX_IOPS_PER_VOLUME (2014+). İstatistikler: sys.dm_resource_governor_resource_pools / _workload_groups.","tags":["resource governor","resource pool","workload group","classifier","cpu limit","kaynak yonetimi"]},{"id":"tde-enable","task":"TDE kur: master key, sertifika, sertifika yedeği ve şifreleme ilerlemesi","category":"Güvenlik","command":"USE master;\nIF NOT EXISTS (SELECT 1 FROM sys.symmetric_keys WHERE name = N'##MS_DatabaseMasterKey##')\n    CREATE MASTER KEY ENCRYPTION BY PASSWORD = N'<GucluParola_1>';\nCREATE CERTIFICATE [TDE_Cert_2026]\n    WITH SUBJECT = N'TDE certificate', EXPIRY_DATE = '20361231';\n\n-- HEMEN yedekle: sertifika + private key olmadan yedekler hicbir yerde acilmaz\nBACKUP CERTIFICATE [TDE_Cert_2026]\n    TO FILE = N'D:\\Keys\\TDE_Cert_2026.cer'\n    WITH PRIVATE KEY (FILE = N'D:\\Keys\\TDE_Cert_2026.pvk',\n                      ENCRYPTION BY PASSWORD = N'<GucluParola_2>');\n\nUSE [Musteri];\nCREATE DATABASE ENCRYPTION KEY\n    WITH ALGORITHM = AES_256\n    ENCRYPTION BY SERVER CERTIFICATE [TDE_Cert_2026];\nALTER DATABASE [Musteri] SET ENCRYPTION ON;\n\n-- Ilerleme ve sertifika yedek tarihi:\nSELECT DB_NAME(dek.database_id) AS db, dek.encryption_state_desc, dek.percent_complete,\n       dek.encryption_scan_state_desc, c.name AS cert_name, c.expiry_date, c.pvt_key_last_backup_date\nFROM   sys.dm_database_encryption_keys dek\n  LEFT JOIN master.sys.certificates c ON c.thumbprint = dek.encryptor_thumbprint;\n\n-- Hedef sunucuda (restore / AG secondary oncesi):\n-- CREATE CERTIFICATE [TDE_Cert_2026] FROM FILE = N'D:\\Keys\\TDE_Cert_2026.cer'\n--   WITH PRIVATE KEY (FILE = N'D:\\Keys\\TDE_Cert_2026.pvk', DECRYPTION BY PASSWORD = N'<GucluParola_2>');","what":"master'da database master key ve sertifika oluşturur, sertifikayı private key ile dosyaya yedekler, veritabanında AES-256 database encryption key oluşturup data ve log dosyalarını diskte şifreler; arka plan şifreleme taramasının ilerlemesini gösterir.","when":"KVKK/GDPR/PCI gibi \"data at rest\" şifreleme gereksiniminde, yedek dosyalarının ve MDF/LDF'lerin çalınma riskine karşı.","caution":"Sertifika + private key yedeği ve parolası kaybolursa TDE'li veritabanı ve tüm yedekleri KALICI olarak açılamaz; yedeği sunucudan ayrı, güvenli bir kasada sakla. Bir veritabanında TDE açılınca tempdb de şifrelenir (sunucu genelinde küçük CPU maliyeti). Şifreleme taraması I/O yoğundur; yoğun saatlerde ALTER DATABASE ... SET ENCRYPTION SUSPEND/RESUME (2019+) ile durdurulabilir. AG/log shipping'de sertifika önce tüm hedef sunuculara kurulmalı. TDE bellek/ağ trafiğini şifrelemez.","note":"Sertifikanın süresinin dolması mevcut TDE'yi durdurmaz, ama rotasyon için yeni sertifika oluşturup ALTER DATABASE ENCRYPTION KEY ENCRYPTION BY SERVER CERTIFICATE [yeni] ile yeniden şifrele (veri yeniden şifrelenmez, yalnız DEK). encryption_state_desc ve encryption_scan_state_desc 2019+ sütunlarıdır; eski sürümde encryption_state (3 = encrypted, 2 = in progress) kullan. TDE Standard edition'da 2019+ ile mevcuttur.","tags":["tde","transparent data encryption","sertifika","backup certificate","sifreleme","dek"]},{"id":"sql-server-audit","task":"SQL Server Audit kur: login, yetki değişikliği ve tablo erişimi denetimi","category":"Güvenlik","command":"USE master;\nCREATE SERVER AUDIT [Audit_DBA]\nTO FILE (FILEPATH = N'D:\\Audit\\', MAXSIZE = 256 MB, MAX_ROLLOVER_FILES = 20, RESERVE_DISK_SPACE = OFF)\nWITH (QUEUE_DELAY = 1000, ON_FAILURE = CONTINUE);\nALTER SERVER AUDIT [Audit_DBA] WITH (STATE = ON);\n\n-- Sunucu geneli (tum veritabanlari dahil):\nCREATE SERVER AUDIT SPECIFICATION [AuditSpec_Server]\nFOR SERVER AUDIT [Audit_DBA]\n    ADD (FAILED_LOGIN_GROUP),\n    ADD (SERVER_ROLE_MEMBER_CHANGE_GROUP),\n    ADD (DATABASE_ROLE_MEMBER_CHANGE_GROUP),\n    ADD (SERVER_PRINCIPAL_CHANGE_GROUP),\n    ADD (DATABASE_PRINCIPAL_CHANGE_GROUP),\n    ADD (SERVER_PERMISSION_CHANGE_GROUP),\n    ADD (DATABASE_PERMISSION_CHANGE_GROUP),\n    ADD (AUDIT_CHANGE_GROUP)\nWITH (STATE = ON);\n\n-- Veritabani: hassas tabloya erisim:\nUSE [Musteri];\nCREATE DATABASE AUDIT SPECIFICATION [AuditSpec_Musteri]\nFOR SERVER AUDIT [Audit_DBA]\n    ADD (SELECT, INSERT, UPDATE, DELETE ON OBJECT::[dbo].[Siparis] BY [public])\nWITH (STATE = ON);\n\n-- Oku:\nSELECT event_time, action_id, succeeded, server_principal_name, database_name,\n       schema_name, object_name, LEFT(statement, 200) AS stmt, client_ip, application_name\nFROM   sys.fn_get_audit_file(N'D:\\Audit\\Audit_DBA_*.sqlaudit', DEFAULT, DEFAULT)\nWHERE  event_time >= DATEADD(HOUR, -24, SYSUTCDATETIME())\nORDER BY event_time DESC;","what":"Dosyaya yazan bir server audit oluşturur; başarısız login'leri, rol üyeliği, principal ve yetki değişikliklerini sunucu genelinde, seçilen tabloya SELECT/DML erişimini veritabanı düzeyinde kaydeder ve kayıtları T-SQL ile okur.","when":"Denetim/uyum (KVKK, PCI, SOX) gereksiniminde, \"bu tabloyu kim okudu/değiştirdi\" sorusunda, yetki yükseltme şüphesinde.","caution":"Yoğun tabloda SELECT denetimi çok hızlı log üretir ve performansı etkiler; kapsamı nesne ve principal ile daralt. ON_FAILURE = SHUTDOWN, audit yazılamazsa sunucuyu kapatır; yalnız zorunluysa kullan. Audit klasörü SQL Server servis hesabının yazabileceği, DBA dışı kişilerin silemeyeceği bir yer olmalı. event_time UTC'dir. Database audit specification veritabanıyla birlikte restore edilir ama server audit GUID'i eşleşmezse orphan kalır.","note":"Database audit specification Standard edition'da 2016 SP1+ ile kullanılabilir. Değişiklikleri denetlemek için AUDIT_CHANGE_GROUP mutlaka ekli olmalı; audit'i kapatmak da kayda geçer.","tags":["sql server audit","server audit","audit specification","fn_get_audit_file","denetim","uyum"]},{"id":"orphaned-users-fix","task":"Orphaned user'ları bul ve login'e bağla (restore / AG sonrası)","category":"Güvenlik","command":"USE [Musteri];\n-- Login'i olmayan veritabani kullanicilari:\nSELECT dp.name AS user_name, dp.type_desc, dp.authentication_type_desc, dp.sid, dp.create_date\nFROM   sys.database_principals dp\n  LEFT JOIN sys.server_principals sp ON sp.sid = dp.sid\nWHERE  sp.sid IS NULL\n  AND  dp.type IN ('S', 'U', 'G')\n  AND  dp.authentication_type_desc IN (N'INSTANCE', N'WINDOWS')\n  AND  dp.principal_id > 4;\n\n-- Ayni isimli login varsa SID'i eslestir:\nALTER USER [app_user] WITH LOGIN = [app_user];\n\n-- Kalici cozum: kaynak sunucuda SID + parola hash ile CREATE LOGIN uret, hedefte calistir:\nSELECT N'CREATE LOGIN ' + QUOTENAME(sp.name)\n     + N' WITH PASSWORD = ' + CONVERT(NVARCHAR(MAX), LOGINPROPERTY(sp.name, 'PasswordHash'), 1)\n     + N' HASHED, SID = ' + CONVERT(NVARCHAR(MAX), sp.sid, 1)\n     + N', CHECK_POLICY = OFF;' AS create_login_stmt\nFROM   sys.server_principals sp\nWHERE  sp.type = 'S' AND sp.name = N'app_user';","what":"Veritabanındaki kullanıcının SID'i sunucudaki hiçbir login'le eşleşmediği (orphaned) durumları bulur; kullanıcıyı mevcut login'e yeniden bağlar ve login'leri diğer sunucuda aynı SID ve parola hash'iyle yeniden oluşturacak script üretir.","when":"Veritabanını başka sunucuya restore/attach ettikten sonra, AG/log shipping failover'ında uygulama \"Login failed for user\" alırken, sunucu migration'ında.","caution":"ALTER USER ... WITH LOGIN kullanıcının SID'ini login'inkine çevirir; AG'de bu değişiklik primary'den secondary'lere taşınır, ama secondary sunuculardaki login SID'leri farklıysa sonraki failover'da sorun geri gelir. Kalıcı çözüm login'leri tüm replikalarda aynı SID ile oluşturmaktır. Parola hash'i hassas veridir; scripti güvenli sakla. Contained database user'ları (authentication_type = DATABASE) login gerektirmez ve listede yer almaz.","note":"sp_change_users_login deprecated'dır; ALTER USER WITH LOGIN kullan. dbo kullanıcısının orphan olması (DB sahibi login'i yok) için ALTER AUTHORIZATION ON DATABASE::[Musteri] TO [sa]; kullanılır. Toplu login taşıma için PowerShell dbatools: Copy-DbaLogin -Source SQL01 -Destination SQL02.","tags":["orphaned user","alter user with login","sid","login failed","restore sonrasi","sp_change_users_login"]},{"id":"permission-audit","task":"Login ve yetki denetimi: sysadmin üyeleri, riskli yetkiler, zayıf parolalar","category":"Güvenlik","command":"-- 1) Sunucu rol uyelikleri:\nSELECT r.name AS server_role, m.name AS member, m.type_desc, m.is_disabled, m.create_date\nFROM   sys.server_role_members rm\n  JOIN sys.server_principals r ON r.principal_id = rm.role_principal_id\n  JOIN sys.server_principals m ON m.principal_id = rm.member_principal_id\nORDER BY r.name, m.name;\n\n-- 2) Riskli sunucu yetkileri:\nSELECT pr.name AS grantee, pr.type_desc, pe.permission_name, pe.state_desc\nFROM   sys.server_permissions pe\n  JOIN sys.server_principals pr ON pr.principal_id = pe.grantee_principal_id\nWHERE  pe.permission_name IN (N'CONTROL SERVER', N'IMPERSONATE ANY LOGIN', N'ALTER ANY LOGIN',\n                              N'ALTER ANY SERVER ROLE', N'ALTER SETTINGS', N'IMPERSONATE')\n   OR  pe.state_desc = N'GRANT_WITH_GRANT_OPTION';\n\n-- 3) SQL login saglik kontrolu (policy, kilit, parola = login adi):\nSELECT sl.name, sl.is_disabled, sl.is_policy_checked, sl.is_expiration_checked,\n       LOGINPROPERTY(sl.name, 'PasswordLastSetTime') AS pwd_last_set,\n       LOGINPROPERTY(sl.name, 'IsLocked')            AS is_locked,\n       LOGINPROPERTY(sl.name, 'BadPasswordCount')    AS bad_pwd_count,\n       PWDCOMPARE(sl.name, sl.password_hash)         AS pwd_equals_name,\n       PWDCOMPARE(N'', sl.password_hash)             AS pwd_empty\nFROM   sys.sql_logins sl;\n\n-- 4) Veritabani rol uyelikleri ve acik nesne yetkileri:\nUSE [Musteri];\nSELECT r.name AS db_role, m.name AS member, m.type_desc\nFROM   sys.database_role_members rm\n  JOIN sys.database_principals r ON r.principal_id = rm.role_principal_id\n  JOIN sys.database_principals m ON m.principal_id = rm.member_principal_id\nWHERE  m.name <> N'dbo'\nORDER BY r.name, m.name;\n\nSELECT pr.name AS grantee, pe.class_desc, pe.permission_name, pe.state_desc,\n       OBJECT_SCHEMA_NAME(pe.major_id) AS schema_name,\n       CASE pe.class WHEN 1 THEN OBJECT_NAME(pe.major_id) WHEN 3 THEN SCHEMA_NAME(pe.major_id) END AS object_name\nFROM   sys.database_permissions pe\n  JOIN sys.database_principals pr ON pr.principal_id = pe.grantee_principal_id\nWHERE  (pr.name NOT IN (N'public', N'dbo') AND NOT (pe.class = 0 AND pe.permission_name = N'CONNECT'))\n   OR  (pr.name = N'public' AND OBJECT_SCHEMA_NAME(pe.major_id) <> N'sys')\nORDER BY pr.name, pe.class_desc;","what":"Sunucu rol üyeliklerini, CONTROL SERVER/IMPERSONATE gibi riskli yetkileri, parola politikası kapalı, kilitli, parolası login adıyla aynı veya boş SQL login'lerini; veritabanında rol üyeliklerini ve sistem dışı açık nesne yetkilerini listeler.","when":"Periyodik yetki gözden geçirmesinde, denetim öncesi, ekipten ayrılan kişi sonrası, güvenlik olayı şüphesinde.","caution":"Windows grupları üzerinden gelen yetkiler grup adıyla görünür; kişileri görmek için EXEC xp_logininfo N'DOMAIN\\Grup', 'members'; kullan. Bir yetkiyi kaldırmadan önce uygulama bağımlılığını doğrula. PWDCOMPARE yalnız SQL login'lerinde çalışır ve sorguyu çalıştırmak için CONTROL SERVER gerekir. Sadece sorgu; risksiz.","note":"Bir principal'ın efektif yetkileri için: EXECUTE AS USER = N'app_user'; SELECT * FROM fn_my_permissions(NULL, 'DATABASE'); REVERT;. 2022'de yeni granular roller (##MS_ServerStateReader##, ##MS_DefinitionReader## vb.) sysadmin vermeden izleme yetkisi sağlar.","tags":["yetki denetimi","sysadmin","server_role_members","database_permissions","pwdcompare","guvenlik"]},{"id":"ledger-tables","task":"Ledger tablo oluştur, değişiklik geçmişini oku ve bütünlüğü doğrula","category":"Güvenlik","command":"USE [Musteri];\n-- Ledger dogrulamasi snapshot isolation ister:\nALTER DATABASE [Musteri] SET ALLOW_SNAPSHOT_ISOLATION ON;\n\n-- Updatable ledger tablo (gecmis tablo otomatik tutulur):\nCREATE TABLE dbo.Hesap (\n    HesapId int           NOT NULL PRIMARY KEY,\n    Bakiye  decimal(18,2) NOT NULL\n)\nWITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.Hesap_History), LEDGER = ON);\n\n-- Append-only ledger (UPDATE/DELETE engellenir):\nCREATE TABLE dbo.IslemLog (Id bigint IDENTITY, Mesaj nvarchar(400))\nWITH (LEDGER = ON (APPEND_ONLY = ON));\n\n-- Kim, ne zaman, ne degistirdi:\nSELECT t.commit_time, t.principal_name, l.HesapId, l.Bakiye, l.ledger_operation_type_desc\nFROM   dbo.Hesap_Ledger l\n  JOIN sys.database_ledger_transactions t ON t.transaction_id = l.ledger_transaction_id\nORDER BY t.commit_time DESC;\n\n-- Digest al (guvenli disaridaki bir yere sakla) ve dogrula:\nEXEC sys.sp_generate_database_ledger_digest;\nEXEC sys.sp_verify_database_ledger\n     N'{\"database_name\":\"Musteri\",\"block_id\":0,\"hash\":\"0x...\",\"last_transaction_commit_time\":\"...\",\"digest_time\":\"...\"}';","what":"Satır değişikliklerini kriptografik hash zinciriyle kaydeden ledger tablo oluşturur; _Ledger view üzerinden her INSERT/UPDATE/DELETE'in kim tarafından ve ne zaman yapıldığını gösterir, saklanan digest ile verinin sonradan (DBA dahil) değiştirilmediğini doğrular.","when":"Finansal kayıt, denetim izi, sözleşme/onay kayıtları gibi değişmezliği kanıtlanması gereken verilerde.","caution":"Ledger özelliği tablo oluşturulduktan sonra kapatılamaz; ledger tablo normal tabloya çevrilemez ve DROP edilen ledger tablo silinmez, dropped ledger olarak saklanır. Updatable ledger her değişiklikte geçmiş tablosuna satır yazar ve depolama büyür. Digest'ler veritabanı dışında, değiştirilemez bir yerde (WORM depolama, Azure immutable blob) saklanmazsa doğrulama kanıt değeri taşımaz. sp_verify_database_ledger snapshot isolation olmadan 37498 hatası verir.","since":"2022","note":"sp_generate_database_ledger_digest çıktısı JSON'dur; sp_verify_database_ledger tek digest veya JSON dizisi kabul eder ve @table_name ile tek tabloyu doğrulayabilir. Otomatik digest saklama için ALTER DATABASE SCOPED CONFIGURATION SET LEDGER_DIGEST_STORAGE_ENDPOINT = '<blob url>'. CREATE DATABASE ... WITH LEDGER = ON tüm tabloları varsayılan ledger yapar.","tags":["ledger","append-only","sp_verify_database_ledger","digest","degistirilemez","tamper-evident"]},{"id":"agent-job-failures","task":"SQL Agent job hata geçmişi ve son çalışma durumu","category":"SQL Agent","command":"-- Son 24 saatte basarisiz / iptal edilen job adimlari:\nSELECT j.name AS job_name, h.step_id, h.step_name,\n       msdb.dbo.agent_datetime(h.run_date, h.run_time) AS run_at,\n       STUFF(STUFF(RIGHT('000000' + CAST(h.run_duration AS VARCHAR(6)), 6), 3, 0, ':'), 6, 0, ':') AS duration_hhmmss,\n       CASE h.run_status WHEN 0 THEN 'Failed' WHEN 1 THEN 'Succeeded' WHEN 2 THEN 'Retry'\n                         WHEN 3 THEN 'Canceled' WHEN 4 THEN 'In progress' END AS status,\n       h.sql_message_id, h.sql_severity,\n       LEFT(h.message, 500) AS message\nFROM   msdb.dbo.sysjobhistory h\n  JOIN msdb.dbo.sysjobs j ON j.job_id = h.job_id\nWHERE  h.run_status IN (0, 3)\n  AND  msdb.dbo.agent_datetime(h.run_date, h.run_time) >= DATEADD(HOUR, -24, GETDATE())\nORDER BY run_at DESC;\n\n-- Her job'in son sonucu, su an calisiyor mu, sonraki calisma:\nSELECT j.name, j.enabled,\n       CASE lr.run_status WHEN 0 THEN 'Failed' WHEN 1 THEN 'Succeeded' WHEN 3 THEN 'Canceled' END AS last_outcome,\n       lr.run_at AS last_run_at,\n       CASE WHEN a.start_execution_date IS NOT NULL AND a.stop_execution_date IS NULL THEN 'RUNNING' END AS running_now,\n       a.next_scheduled_run_date\nFROM   msdb.dbo.sysjobs j\n  LEFT JOIN msdb.dbo.sysjobactivity a\n         ON a.job_id = j.job_id AND a.session_id = (SELECT MAX(session_id) FROM msdb.dbo.syssessions)\n  OUTER APPLY (SELECT TOP (1) h.run_status, msdb.dbo.agent_datetime(h.run_date, h.run_time) AS run_at\n               FROM msdb.dbo.sysjobhistory h\n               WHERE h.job_id = j.job_id AND h.step_id = 0\n               ORDER BY h.instance_id DESC) lr\nORDER BY j.name;\n\n-- Agent servisi calisiyor mu:\nSELECT servicename, status_desc, startup_type_desc FROM sys.dm_server_services;","what":"Son 24 saatte başarısız veya iptal edilen job adımlarını hata mesajıyla; her job'ın son sonucunu, şu an çalışıp çalışmadığını ve sonraki zamanlanmış çalışmasını; Agent servisinin durumunu gösterir.","when":"Sabah kontrolünde, yedek/bakım job'ı alarmında, \"gece job'ı çalıştı mı\" sorusunda, failover sonrası job'ların doğru replikada çalıştığını doğrularken.","caution":"Job geçmişi msdb'de sınırlıdır (varsayılan toplam 1.000 satır, job başına 100); sık çalışan job'lar eski hataları hızla siler, Agent özelliklerinden limiti artır. message alanı 4.000 karakterde kesilir; uzun çıktılar için job adımına output file tanımla. Agent servisi durmuşsa zamanlanmış hiçbir job çalışmaz ve hata da üretmez. Sadece sorgu; risksiz.","note":"msdb.dbo.agent_datetime belgelenmemiş ama yaygın kullanılan bir yardımcı fonksiyondur. AG ortamında job'lar her replikada tanımlı olmalı ve ilk adımda sys.fn_hadr_is_primary_replica(N'Musteri') ile rol kontrolü yapmalıdır. dbatools: Get-DbaAgentJobHistory -SqlInstance SQL01 -StartDate (Get-Date).AddDays(-1) -OutcomeType Failed.","tags":["sql agent","job history","sysjobhistory","job hatasi","msdb","zamanlanmis gorev"]}]},"recipes/mongodb.json":{"engineId":"mongodb","engine":"MongoDB","order":5,"recipes":[{"id":"rs-add-member","task":"Replica set'e üye ekle","category":"Replica Set","command":"rs.add({ host: \"mongo2:27017\", priority: 1, votes: 1 })","what":"Mevcut replica set'e yeni bir üye (secondary) ekler ve initial sync başlatır.","when":"Okuma kapasitesini artırmak veya yedeklilik için yeni bir düğüm eklerken.","caution":"Yeni üye initial sync sırasında primary'den veri çeker; büyük veri setlerinde ağ ve disk yükü oluşturur.","tags":["replica","rs.add","member","uye","ekle"]},{"id":"rs-remove-member","task":"Replica set'ten üye çıkar","category":"Replica Set","command":"rs.remove(\"mongo2:27017\")","what":"Belirtilen host'u replica set konfigürasyonundan kaldırır.","when":"Bir düğümü hizmetten alırken veya donanımı değiştirirken.","caution":"Primary'yi çıkarmayın; çoğunluğu (majority) bozacak şekilde üye çıkarmak set'i okuma-yazmaya kapatabilir.","tags":["replica","rs.remove","member","uye","cikar"]},{"id":"rs-step-down","task":"Primary'yi indir (stepDown)","category":"Replica Set","command":"rs.stepDown(60)","what":"Mevcut primary'yi belirtilen saniye boyunca secondary'ye düşürür ve yeni bir seçim tetikler.","when":"Planlı bakım öncesi primary rolünü başka düğüme devretmek için.","caution":"StepDown sırasında kısa süreli yazma kesintisi olur; uygulama tekrar bağlanmalıdır.","tags":["replica","stepdown","primary","failover","indir"]},{"id":"rs-set-priority","task":"Üye önceliğini değiştir","category":"Replica Set","command":"cfg = rs.conf(); cfg.members[1].priority = 2; rs.reconfig(cfg)","what":"Belirtilen üyenin seçimlerde primary olma önceliğini değiştirir.","when":"Belirli bir düğümün tercihen primary olmasını istediğinizde.","caution":"reconfig seçim tetikleyebilir ve kısa süreli primary değişimi/yazma kesintisi yaratabilir.","tags":["replica","priority","reconfig","oncelik","secim"]},{"id":"rs-status","task":"Replica set durumunu gör","category":"Replica Set","command":"rs.status()","what":"Set üyelerinin durumunu, rollerini, replikasyon gecikmesini ve health bilgisini gösterir.","when":"Replikasyon sağlığını ve gecikmeyi kontrol ederken.","caution":"Salt okunur komuttur; risk yoktur.","tags":["replica","status","durum","health","rs.status"]},{"id":"rs-hidden-member","task":"Gizli / oysuz üye ayarla","category":"Replica Set","command":"cfg = rs.conf(); cfg.members[2].hidden = true; cfg.members[2].priority = 0; cfg.members[2].votes = 0; rs.reconfig(cfg)","what":"Bir üyeyi gizli (uygulamaya görünmez), oysuz ve önceliksiz yaparak yalnızca yedek/analitik amaçlı kullanır.","when":"Yedekleme veya analitik sorguları izole etmek istediğinizde.","caution":"hidden üyenin priority değeri 0 olmalıdır; aksi halde reconfig hata verir.","tags":["replica","hidden","votes","gizli","oysuz"]},{"id":"rs-resync","task":"Üyeyi baştan senkronize et (resync)","category":"Replica Set","command":"// Yeniden senkronize edilecek SECONDARY üzerinde (PRIMARY'de ASLA):\ndb.getSiblingDB(\"admin\").shutdownServer()\n// İşletim sisteminde: dbPath içeriğini boşaltın (ya da yedek olarak başka yere taşıyın)\n// ve mongod'u aynı yapılandırmayla yeniden başlatın; üye otomatik olarak initial sync başlatır.\n// İlerlemeyi izleyin (stateStr: STARTUP2 -> SECONDARY):\nrs.status()","what":"MongoDB'de ayrı bir resync komutu yoktur; secondary'yi durdurup veri dizinini boşaltarak yeniden başlatmak, primary'den (veya bir sync kaynağından) yeni bir initial sync başlatır.","when":"Bir üye oplog penceresinin dışına düşecek kadar geride kaldığında (RECOVERING / too stale) veya verisi tutarsız hale geldiğinde.","caution":"Üyenin tüm yerel verisi silinip yeniden çekilir; yalnızca secondary'de yapın ve çoğunluğun (majority) ayakta kaldığından emin olun. Senkron süresi ve ağ/disk yükü yüksektir; çok büyük veri setlerinde sağlıklı bir üyenin dosya sistemi snapshot'ından başlatmak daha hızlıdır.","tags":["replica","resync","initialsync","senkron","yeniden"]},{"id":"sh-add-shard","task":"Cluster'a shard ekle","category":"Sharding","command":"sh.addShard(\"shardRS/mongoShard1:27018\")","what":"Sharded cluster'a yeni bir shard (replica set) ekler.","when":"Depolama veya throughput kapasitesini yatay olarak büyütürken.","caution":"Shard ekledikten sonra balancer chunk'ları taşımaya başlar; bu ek IO yükü oluşturur.","tags":["sharding","addshard","shard","ekle","cluster"]},{"id":"sh-shard-collection","task":"Koleksiyonu shard'la","category":"Sharding","command":"sh.shardCollection(\"shop.musteri\", { musteriId: \"hashed\" })","what":"Belirtilen koleksiyonu verilen shard anahtarına göre shard'lar (sharding).","when":"Büyüyen bir koleksiyonu birden fazla shard'a dağıtmak istediğinizde.","caution":"Shard anahtarı 5.0+ sürümlerde reshardCollection ile değiştirilebilir (4.4+ refineCollectionShardKey ile genişletilebilir), ancak bu işlem verinin tamamını yeniden dağıttığı için pahalıdır; kötü anahtar seçimi dengesiz dağılıma yol açar.","tags":["sharding","shardcollection","key","musteri","anahtar"]},{"id":"sh-start-balancer","task":"Balancer'ı başlat","category":"Sharding","command":"sh.startBalancer()","what":"Chunk dağıtımını yapan balancer sürecini etkinleştirir.","when":"Bakım sonrası dengelenmeyi tekrar açmak istediğinizde.","caution":"Balancer chunk taşırken IO ve ağ yükü oluşturur; yoğun saatlerde bir bakım penceresi (window) tanımlayın.","tags":["sharding","balancer","start","baslat","dengele"]},{"id":"sh-stop-balancer","task":"Balancer'ı durdur","category":"Sharding","command":"sh.stopBalancer()","what":"Chunk taşımalarını yapan balancer'ı devre dışı bırakır.","when":"Yedekleme, bakım veya toplu veri yükleme öncesi taşımayı durdurmak için.","caution":"Uzun süre kapalı kalırsa shard'lar dengesizleşir; işlem sonrası tekrar açmayı unutmayın.","tags":["sharding","balancer","stop","durdur","bakim"]},{"id":"sh-status","task":"Sharding durumunu gör","category":"Sharding","command":"sh.status()","what":"Shard'ları, veritabanlarını, sharded koleksiyonları ve chunk dağılımını özetler.","when":"Cluster'ın dağıtım durumunu ve balancer sağlığını incelerken.","caution":"Salt okunur komuttur; risk yoktur.","tags":["sharding","status","durum","chunk","sh.status"]},{"id":"sh-add-zone","task":"Zone (tag) ekle ve aralık ata","category":"Sharding","command":"sh.addShardToZone(\"shard0000\", \"TR\"); sh.updateZoneKeyRange(\"shop.musteri\", { bolge: \"TR\" }, { bolge: \"TR~\" }, \"TR\")","what":"Bir shard'ı zone'a atar ve belirli anahtar aralığını o zone'a bağlar (zone sharding).","when":"Veriyi coğrafi veya donanım bazlı olarak belirli shard'larda tutmak istediğinizde.","caution":"Zone aralıkları shard anahtarıyla uyumlu olmalı; yanlış aralık chunk'ların taşınamamasına yol açar.","tags":["sharding","zone","tag","bolge","aralik"]},{"id":"sh-move-chunk","task":"Chunk'ı manuel taşı","category":"Sharding","command":"sh.moveChunk(\"shop.musteri\", { musteriId: 1000 }, \"shard0001\")","what":"Belirtilen anahtarı içeren chunk'ı hedef shard'a manuel olarak taşır.","when":"Dengesiz dağılımı düzeltmek veya belirli veriyi konumlandırmak için.","caution":"Manuel taşıma balancer ile çakışabilir; büyük chunk taşımaları IO yükü ve kısa kilitlenmeler oluşturur.","tags":["sharding","movechunk","chunk","tasi","manuel"]},{"id":"compact-collection","task":"Koleksiyonu compact et","category":"Bakım","command":"db.runCommand({ compact: \"musteri\" })","what":"Koleksiyon ve index'lerdeki boş alanı geri kazanarak diskte yeniden düzenler.","when":"Çok sayıda silme/güncelleme sonrası disk alanını geri kazanmak istediğinizde.","caution":"4.4+ sürümlerde compact okuma/yazmayı engellemez, yalnızca aynı koleksiyon üzerindeki bazı DDL işlemlerini (drop, createIndex, dropIndex vb.) bloklar; yine de yoğun IO üretir ve alanı işletim sistemine her zaman iade etmeyebilir. Mümkünse secondary üzerinde ve bakım penceresinde çalıştırın.","tags":["compact","storage","bakim","disk","depolama"]},{"id":"create-index-background","task":"Index oluştur (engellemeyen)","category":"Bakım","command":"db.musteri.createIndex({ email: 1 }, { name: \"idx_email\" })","what":"Belirtilen alanda index oluşturur; MongoDB 4.2+ index yapımı varsayılan olarak yazmaları engellemez.","when":"Sorgu performansını iyileştirmek için yeni bir index eklerken.","caution":"Büyük koleksiyonlarda index yapımı CPU ve IO tüketir; primary yükü artabilir.","since":"MongoDB 4.2","note":"MongoDB 4.2 ile yeni bir index yapım yöntemi geldi ve index oluşturma varsayılan olarak yazmaları engellemez oldu; bu yüzden eski { background: true } seçeneği artık gereksizdir ve 4.2'den itibaren yok sayılır.","tags":["index","createindex","background","olustur","performans"]},{"id":"collection-stats","task":"Index ve koleksiyon boyutlarını gör","category":"Bakım","command":"db.musteri.stats({ indexDetails: true })","what":"Koleksiyon boyutunu, depolama boyutunu ve her index'in boyutunu raporlar.","when":"Depolama kullanımını ve index maliyetini analiz ederken.","caution":"Salt okunur komuttur; risk yoktur.","tags":["stats","index","boyut","koleksiyon","depolama"]},{"id":"log-rotate","task":"Log dosyasını döndür","category":"Bakım","command":"db.adminCommand({ logRotate: 1 })","what":"Mevcut log dosyasını kapatıp yenisini açar (log rotation).","when":"Log dosyası büyüdüğünde veya arşivleme öncesi.","caution":"İşletim sistemi log rotasyonuyla birlikte kullanılıyorsa çakışmayı önlemek için yapılandırmayı kontrol edin.","tags":["log","logrotate","dondur","bakim","arsiv"]},{"id":"current-op-long","task":"Uzun süren işlemleri bul","category":"Bakım","command":"db.currentOp({ \"active\": true, \"secs_running\": { $gt: 5 } })","what":"5 saniyeden uzun süredir çalışan aktif işlemleri listeler.","when":"Yavaşlık veya kilitlenme yaşandığında sorunlu sorguları tespit ederken.","caution":"Salt okunur komuttur; risk yoktur.","tags":["currentop","long","uzun","islem","tani"]},{"id":"kill-op","task":"Bir işlemi öldür","category":"Bakım","command":"db.killOp(12345)","what":"Belirtilen opid'ye sahip çalışan işlemi sonlandırır.","when":"Bir sorgu sistemi kilitlediğinde veya çok uzun sürdüğünde.","caution":"Yazma işlemini öldürmek kısmi değişiklik bırakabilir; sistem/replikasyon işlemlerini öldürmekten kaçının.","tags":["killop","kill","islem","oldur","tani"]},{"id":"set-parameter","task":"Çalışma zamanı parametresi değiştir","category":"Parametre","command":"db.adminCommand({ setParameter: 1, cursorTimeoutMillis: 600000 })","what":"Sunucuyu yeniden başlatmadan bir çalışma zamanı parametresini değiştirir.","when":"Geçici olarak bir sunucu davranışını ayarlamak istediğinizde.","caution":"Değişiklik kalıcı değildir; yeniden başlatmada config dosyasındaki değere döner. Yanlış değer performansı bozabilir.","tags":["setparameter","parametre","runtime","ayar","admin"]},{"id":"set-profiling","task":"Profiling seviyesini ayarla","category":"Parametre","command":"db.setProfilingLevel(1, { slowms: 100 })","what":"Yavaş sorguları (100 ms üstü) system.profile koleksiyonuna kaydeder (seviye 1).","when":"Yavaş sorguları teşhis etmek istediğinizde.","caution":"Seviye 2 tüm işlemleri kaydeder ve önemli overhead getirir; profiling verisi diskte yer kaplar.","tags":["profiling","slowms","profil","yavas","tani"]}]},"recipes/mongodb-ext.json":{"engineId":"mongodb","engine":"MongoDB","order":2,"recipes":[{"id":"rs-oplog-window","task":"Oplog penceresini ve replication lag'i ölç","category":"Replica Set","command":"// Oplog boyutu ve kapsadigi sure (oplog window):\nrs.printReplicationInfo()\n// Her secondary'nin primary'ye gore gecikmesi:\nrs.printSecondaryReplicationInfo()\n// Izleme/script icin saniye cinsinden lag ve sync kaynagi:\nconst s = rs.status(); const p = s.members.find(m => m.stateStr === \"PRIMARY\");\ns.members.filter(m => m.stateStr === \"SECONDARY\").map(m => ({ host: m.name, lagSec: (p.optimeDate - m.optimeDate) / 1000, syncSource: m.syncSourceHost }))\n// Pencere (saat):\ndb.getReplicationInfo().timeDiffHours","what":"Oplog'un kaç saatlik yazmayı tuttuğunu (oplog window) ve her secondary'nin primary'nin kaç saniye gerisinde olduğunu, sync kaynağıyla birlikte gösterir.","when":"Replication lag alarmında, planlı bakımdan önce bir üyenin ne kadar süre kapalı kalabileceğini hesaplarken ve toplu yazma işlerinden sonra.","caution":"Bir üyenin kapalı kalma süresi oplog window'u aşarsa üye 'too stale' olur ve initial sync gerekir. Toplu update/delete işleri pencereyi saatler içinde daraltabilir; window'u yoğun saatteki değerine göre değerlendir. Lag hesabı optimeDate farkına dayanır; primary'ye hiç yazma gelmiyorsa lag yüksek görünmez ama pencere yine daralmaz.","since":"MongoDB 4.4","note":"rs.printSlaveReplicationInfo() 4.4 ile rs.printSecondaryReplicationInfo() olarak yeniden adlandırıldı. Pencere yetersizse oplog boyutunu replSetResizeOplog ile büyüt (bkz. rs-oplog-resize). Delayed üyeler secondaryDelaySecs (4.4'te slaveDelay) kadar geride görünür; lag alarmından hariç tut.","tags":["oplog","oplog window","replication lag","gecikme","secondary","printReplicationInfo"],"untested":true},{"id":"rs-oplog-resize","task":"Oplog boyutunu online değiştir (replSetResizeOplog)","category":"Replica Set","command":"// Mevcut oplog boyutu (MB):\ndb.getSiblingDB(\"local\").oplog.rs.stats().maxSize / 1024 / 1024\n// Oplog'u 50 GB yap (MB cinsinden; her uyede ayri calistirilir, once secondary'ler):\ndb.adminCommand({ replSetResizeOplog: 1, size: 51200 })\n// Boyuttan bagimsiz asgari saklama suresi (saat):\ndb.adminCommand({ replSetResizeOplog: 1, minRetentionHours: 48 })\n// Sonucu dogrula:\nrs.printReplicationInfo()","what":"Çalışan bir üyenin oplog'unu restart gerektirmeden büyütür veya küçültür; minRetentionHours ile oplog girdilerinin boyut sınırı aşılsa bile asgari süre tutulmasını sağlar.","when":"Oplog window bakım süresini veya initial sync süresini karşılamadığında, toplu yazma işleri pencereyi daralttığında.","caution":"Komut yalnızca çalıştırıldığı üyeyi etkiler, replike edilmez; her üyede ayrı uygula. Pencerenin sync kaynağı olan üyelerde de yeterli olması gerekir. Küçültme disk alanını hemen işletim sistemine iade etmez; alan için oplog.rs üzerinde compact gerekir. minRetentionHours ile oplog yazma yoğunluğuna bağlı olarak size değerinin üzerine çıkabilir; diski buna göre planla.","since":"MongoDB 4.4","note":"Yeni size restart sonrası korunur; komutla verilen minRetentionHours korunmaz, kalıcı olması için storage.oplogMinRetentionHours'a da yaz. size en az 990 MB olmalıdır. Oplog boyutunun yapılandırmadaki replication.oplogSizeMB ile değiştirilmesi yalnızca oplog ilk oluşturulurken etkilidir.","tags":["oplog","resize","replSetResizeOplog","minRetentionHours","boyut","oplog window"],"untested":true},{"id":"rs-force-reconfig","task":"Çoğunluk kaybında replica set'i zorla yeniden yapılandır (force reconfig)","category":"Replica Set","command":"// Ayakta kalan ve en guncel optime'a sahip uyede (secondary olarak calisir):\nrs.status().members.map(m => ({ host: m.name, state: m.stateStr, health: m.health, optime: m.optimeDate }))\ncfg = rs.conf()\ncfg.members.map((m, i) => ({ i: i, host: m.host }))\n// Yalnizca erisilebilen uyeleri birak (ornek: 0 ve 2 numarali uyeler):\ncfg.members = [cfg.members[0], cfg.members[2]]\nrs.reconfig(cfg, { force: true })\n// Yeni primary secimini dogrula:\nrs.status().members.map(m => ({ host: m.name, state: m.stateStr }))","what":"Oy veren üyelerin çoğunluğu kalıcı olarak kaybedildiğinde (ör. bir veri merkezi tamamen gitti), ayakta kalan üyelerden yeni bir config oluşturup set'in tekrar primary seçebilmesini sağlar.","when":"Yalnızca felaket senaryosunda: çoğunluk geri gelmeyecek ve set salt okunur kaldığında.","caution":"Son çare işlemidir. Kaybedilen üyeler sonradan geri gelirse eski config ile split-brain ve rollback oluşabilir; onları ağdan izole et, geri alırken verilerini silip initial sync ile ekle. En güncel optime'a sahip üyeyi seç; aksi halde diğer üyelerde majority commit edilmemiş yazmalar rollback'e düşer. Normal üye değişikliğinde force kullanma.","since":"MongoDB 4.4","note":"force reconfig, config version'ı rastgele büyük bir artışla yükseltir ve secondary üzerinde çalıştırılabilen tek reconfig biçimidir. 4.4+ sürümlerde normal reconfig'ler tek seferde en fazla bir oy veren üye ekleyip çıkarabilir; force bu kısıta tabi değildir.","tags":["force reconfig","majority","disaster","felaket","split-brain","rs.reconfig"],"untested":true},{"id":"rs-rolling-maintenance","task":"Replica set'te rolling bakım (restart, OS patch, minor upgrade)","category":"Replica Set","command":"// 1) Baslamadan once: tum uyeler saglikli, lag dusuk ve oplog window bakim suresinden uzun olmali\nrs.printSecondaryReplicationInfo()\n// 2) Bakim yapilacak SECONDARY'de temiz kapanis (sonra OS/binary bakimi, ayni yapilandirmayla baslat):\ndb.getSiblingDB(\"admin\").shutdownServer({ timeoutSecs: 60 })\n// 3) Uye SECONDARY olup lag kapanana kadar bekle, sonra siradaki secondary'ye gec:\nrs.status().members.map(m => ({ host: m.name, state: m.stateStr, health: m.health }))\n// 4) Tum secondary'ler bitince PRIMARY'de: 30 sn icinde yetisen bir secondary'ye devret\nrs.stepDown(120, 30)\n// 5) Eski primary artik SECONDARY: 2. ve 3. adimi onun icin uygula","what":"Üyeleri tek tek, önce secondary'ler sonra primary olacak şekilde bakıma alarak set'i hizmet dışı bırakmadan restart, OS patch veya binary güncellemesi yapma sırasını verir.","when":"Planlı OS/kernel güncellemesi, minor sürüm yükseltmesi, mongod parametre değişikliği veya disk/donanım bakımında.","caution":"Aynı anda birden fazla üyeyi kapatma; 3 üyeli sette iki üye kapanırsa majority kaybolur. Her üyeden sonra SECONDARY durumunu ve lag'in kapandığını gör. stepDown sırasında kısa bir yazma kesintisi olur; driver'ların retryable writes ile yeniden bağlanabildiğinden emin ol. Arbiter varsa onu da aynı sırayla ele al.","since":"MongoDB 4.4","note":"rs.stepDown(stepDownSecs, secondaryCatchUpPeriodSecs): ikinci parametre, primary'nin bir secondary'nin yetişmesini bekleyeceği süredir; yetişen yoksa stepDown başarısız olur ve primary yerinde kalır. Belirli bir üyenin primary olmamasını istiyorsan bakım süresince o üyede rs.freeze(saniye) kullan.","tags":["rolling","bakım","restart","stepDown","upgrade","maintenance"],"untested":true},{"id":"sh-balancer-window","task":"Balancer durumu, çalışma penceresi (activeWindow) ve koleksiyon bazında dengeleme","category":"Sharding","command":"// Balancer acik mi, su an tur atiyor mu:\nsh.getBalancerState()\ndb.adminCommand({ balancerStatus: 1 })\n// Balancer'i yalnizca 01:00-05:00 arasinda calistir (mongos uzerinde):\ndb.getSiblingDB(\"config\").settings.updateOne({ _id: \"balancer\" }, { $set: { activeWindow: { start: \"01:00\", stop: \"05:00\" } } }, { upsert: true })\n// Pencereyi kaldir:\ndb.getSiblingDB(\"config\").settings.updateOne({ _id: \"balancer\" }, { $unset: { activeWindow: true } })\n// Tek bir koleksiyon icin dengelemeyi kapat / ac:\nsh.disableBalancing(\"shop.musteri\")\nsh.enableBalancing(\"shop.musteri\")\n// Koleksiyonun dengeli olup olmadigi (4.4+):\ndb.adminCommand({ balancerCollectionStatus: \"shop.musteri\" })","what":"Balancer'ın açık olup olmadığını ve tur atıp atmadığını gösterir, chunk taşımalarını belirli saat aralığıyla sınırlar ve tek bir koleksiyonun dengelemesini kapatıp açar.","when":"Chunk migration'ların gün içi performansı etkilediği durumlarda, yedekleme penceresinde veya tek bir koleksiyonda migration sorununu izole ederken.","caution":"Pencere çok dar tutulursa veri büyüme hızına yetişemez ve shard'lar dengesizleşir; balancerCollectionStatus ile dengeyi düzenli kontrol et. Pencere dışında başlamış bir migration tamamlanana kadar sürer. Koleksiyon bazında kapatılan dengeleme unutulursa o koleksiyon tek shard'da büyümeye devam eder.","since":"MongoDB 6.0","note":"activeWindow saatleri config server replica set'inin primary'sinin yerel saat dilimine göre değerlendirilir. 6.0.3+ sürümlerde balancer chunk sayısına değil shard'lar arasındaki veri boyutu farkına göre karar verir; sh.status() içindeki chunk sayıları dengesiz görünse de veri dengeli olabilir.","tags":["balancer","activeWindow","pencere","migration","sharding","balancerCollectionStatus"],"untested":true},{"id":"sh-jumbo-chunks","task":"Jumbo chunk'ları bul, böl ve bayrağını temizle","category":"Sharding","command":"// Jumbo isaretli chunk'lar (5.0+ config.chunks koleksiyona uuid ile baglanir):\nconst uuid = db.getSiblingDB(\"config\").collections.findOne({ _id: \"shop.musteri\" }).uuid;\ndb.getSiblingDB(\"config\").chunks.find({ uuid: uuid, jumbo: true }, { min: 1, max: 1, shard: 1 })\n// Chunk bolunebiliyorsa ortadan bol:\nsh.splitFind(\"shop.musteri\", { musteriId: 1000 })\n// Bolunemeyen chunk icin son care, bayragi elle kaldir (basarili split bayragi zaten kaldirir):\ndb.adminCommand({ clearJumboFlag: \"shop.musteri\", find: { musteriId: 1000 } })\n// Tek bir key degeri cok buyukse key'i genislet (4.4+):\ndb.adminCommand({ refineCollectionShardKey: \"shop.musteri\", key: { musteriId: 1, siparisId: 1 } })","what":"Balancer'ın taşıyamadığı için jumbo olarak işaretlenen chunk'ları listeler, bölünebilenleri böler ve jumbo bayrağını kaldırır; tek değerli dev chunk'lar için shard key'i genişletme yolunu gösterir.","when":"Bir shard diğerlerinden belirgin şekilde büyük kaldığında, sh.status() çıktısında jumbo görüldüğünde veya balancer migration hatası verdiğinde.","caution":"Tüm belgeleri aynı shard key değerine sahip bir chunk bölünemez; bu durumda tek kalıcı çözüm shard key'i refineCollectionShardKey veya reshardCollection ile değiştirmektir. refineCollectionShardKey yeni key için uygun bir index'in önceden var olmasını ister. Jumbo bayrağını bölmeden kaldırmak, balancer'ın aynı chunk'ı tekrar deneyip yine başarısız olmasına yol açar.","since":"MongoDB 5.0","note":"Düşük cardinality'li veya tek değerde yoğunlaşan (ör. durum, ülke) shard key'ler jumbo chunk'ların en sık nedenidir. 5.0'dan önce config.chunks belgeleri ns alanıyla aranır. clearJumboFlag 4.2.3/4.0.15 ile geldi.","tags":["jumbo","chunk","split","clearJumboFlag","shard key","refineCollectionShardKey"],"untested":true},{"id":"sh-shard-key-check","task":"Shard key seçimini ve veri dağılımını kontrol et (getShardDistribution, analyzeShardKey)","category":"Sharding","command":"// Koleksiyonun shard'lara veri ve belge dagilimi:\ndb.getSiblingDB(\"shop\").musteri.getShardDistribution()\n// Mevcut veya aday shard key'in cardinality, frequency ve monotonicity analizi:\ndb.adminCommand({ analyzeShardKey: \"shop.musteri\", key: { musteriId: 1 }, keyCharacteristics: true, readWriteDistribution: false })\n// Okuma/yazma dagilimi icin once sorgu ornekleme ac (saniyede 10 ornek):\ndb.adminCommand({ configureQueryAnalyzer: \"shop.musteri\", mode: \"full\", samplesPerSecond: 10 })\ndb.adminCommand({ analyzeShardKey: \"shop.musteri\", key: { musteriId: 1 }, keyCharacteristics: false, readWriteDistribution: true })\n// Ornekleme bitince kapat:\ndb.adminCommand({ configureQueryAnalyzer: \"shop.musteri\", mode: \"off\" })","what":"Bir koleksiyonun shard'lar arasındaki veri yüzdesini gösterir; analyzeShardKey ile mevcut veya aday shard key'in cardinality, sık tekrar eden değerleri, monoton artış eğilimi ve örneklenmiş sorguların tek shard'a mı yoksa tüm shard'lara mı (scatter-gather) gittiğini raporlar.","when":"Yeni bir koleksiyonu shard'lamadan önce, hot shard veya dengesiz büyüme fark edildiğinde ve reshardCollection kararı öncesinde.","caution":"analyzeShardKey key'i destekleyen bir index ister ve büyük koleksiyonlarda belge örnekleyerek çalışır; yoğun saatte okuma yükü ekler. Query sampling açıkken örnekler config.sampledQueries koleksiyonuna yazılır; analiz bitince kapat. Monoton artan key (ObjectId, zaman damgası) tüm insert'leri tek shard'a yığar.","since":"MongoDB 7.0","note":"analyzeShardKey ve configureQueryAnalyzer 7.0 ile geldi ve replica set'lerde de çalışır. İyi bir shard key: yüksek cardinality, düşük frequency, monoton olmayan ve sık sorguların filtresinde yer alan alan(lar)dır. Hashed key dağılımı düzeltir ama aralık sorgularını scatter-gather yapar.","tags":["shard key","analyzeShardKey","getShardDistribution","cardinality","dağılım","hot shard"],"untested":true},{"id":"explain-execstats","task":"Sorgu planını gerçek çalışma istatistikleriyle incele (explain executionStats)","category":"Performans","command":"db.musteri.find({ sehir: \"Ankara\", durum: \"aktif\" }).sort({ kayitTarihi: -1 }).explain(\"executionStats\")\n// Ozet: kazanan plan, donen belge, taranan key/belge ve sure\nconst e = db.musteri.find({ sehir: \"Ankara\", durum: \"aktif\" }).sort({ kayitTarihi: -1 }).explain(\"executionStats\");\n({ plan: e.queryPlanner.winningPlan, n: e.executionStats.nReturned, keys: e.executionStats.totalKeysExamined, docs: e.executionStats.totalDocsExamined, ms: e.executionStats.executionTimeMillis })\n// Aggregation icin:\ndb.musteri.explain(\"executionStats\").aggregate([{ $match: { sehir: \"Ankara\" } }, { $group: { _id: \"$durum\", n: { $sum: 1 } } }])","what":"Sorguyu çalıştırarak kazanan planı (IXSCAN/COLLSCAN, SORT aşaması), dönen belge sayısını, taranan index key ve belge sayısını ve süreyi gösterir.","when":"Profiler veya log'da yavaş görünen bir sorguyu analiz ederken ve yeni bir index'in gerçekten kullanıldığını doğrularken.","caution":"executionStats sorguyu gerçekten çalıştırır; ağır bir sorguyu yoğun saatte explain etmek de yük getirir. Yazma komutlarında (update/delete/findAndModify) explain veriyi değiştirmez ama planı çalıştırır. totalDocsExamined/nReturned oranı yüksekse veya planda bellek içi SORT aşaması varsa index uygun değildir.","since":"MongoDB 4.4","note":"Compound index tasarımında ESR kuralını uygula: önce eşitlik (Equality) alanları, sonra sıralama (Sort), en son aralık (Range). Reddedilen planları da görmek için explain(\"allPlansExecution\") kullan. 7.0+ sürümlerde sorgu Slot-Based Engine ile çalışırsa winningPlan altında queryPlan ve slotBasedPlan alanları yer alır.","tags":["explain","executionStats","IXSCAN","COLLSCAN","plan","index"]},{"id":"profiler-analyze","task":"Profiler verisinden en yavaş sorguları ve sorgu şekillerini çıkar","category":"Performans","command":"// Son yavas islemler (profiling acik olan db'de; bkz. set-profiling):\ndb.system.profile.find({ millis: { $gte: 100 } }, { ts: 1, ns: 1, op: 1, millis: 1, planSummary: 1, keysExamined: 1, docsExamined: 1, nreturned: 1, appName: 1 }).sort({ ts: -1 }).limit(20)\n// Sorgu sekline gore toplam sure (zamani en cok harcayanlar):\ndb.system.profile.aggregate([\n  { $group: { _id: { ns: \"$ns\", plan: \"$planSummary\", shape: \"$queryHash\" }, n: { $sum: 1 }, totalMs: { $sum: \"$millis\" }, maxMs: { $max: \"$millis\" }, avgDocs: { $avg: \"$docsExamined\" } } },\n  { $sort: { totalMs: -1 } },\n  { $limit: 10 }\n])\n// Index kullanmayan (COLLSCAN) sorgular:\ndb.system.profile.find({ planSummary: \"COLLSCAN\" }, { ns: 1, millis: 1, command: 1 }).sort({ millis: -1 }).limit(10)","what":"system.profile koleksiyonundaki kayıtlardan son yavaş işlemleri, aynı sorgu şekline (queryHash) göre toplam süreyi ve index kullanmayan COLLSCAN sorgularını listeler.","when":"Yavaşlık şikâyetinde hangi sorgunun sunucu zamanını harcadığını bulmak ve index ihtiyacını belirlemek için.","caution":"system.profile varsayılan 1 MB'lık capped bir koleksiyondur ve db bazındadır; yoğun sistemde kayıtlar dakikalar içinde döner, analizi profiling açıkken veya hemen sonra yap. Profiling seviye 2 veya slowms 0 her işlemi yazar ve ciddi overhead getirir. Kayıtlar yalnızca çalıştığı üyede tutulur, replike edilmez.","since":"MongoDB 4.4","note":"Profiling kapalıyken de slowms (varsayılan 100 ms) üzerindeki işlemler mongod log'una 'Slow query' olarak yazılır; log'daki attr.durationMillis ve attr.planSummary aynı teşhisi sağlar. 8.0+ sürümlerde sorgu şekli için planCacheShapeHash alanı da yazılır.","tags":["profiler","system.profile","yavaş sorgu","slow query","COLLSCAN","queryHash"]},{"id":"index-usage-hide","task":"Kullanılmayan index'leri bul ve silmeden önce gizle (hideIndex)","category":"Performans","command":"// Index basina kullanim sayaci (bu uyede, son restart'tan beri):\ndb.musteri.aggregate([{ $indexStats: {} }, { $project: { name: 1, ops: \"$accesses.ops\", since: \"$accesses.since\" } }, { $sort: { ops: 1 } }])\n// Silmeden once planner'dan gizle (index guncellenmeye devam eder):\ndb.musteri.hideIndex(\"idx_email\")\n// Sorun cikarsa aninda geri al:\ndb.musteri.unhideIndex(\"idx_email\")\n// Gozlem suresi sorunsuz gecerse:\ndb.musteri.dropIndex(\"idx_email\")","what":"$indexStats ile her index'in kaç kez kullanıldığını gösterir; hideIndex ile index'i silmeden sorgu planner'ından gizleyerek kaldırmanın etkisini geri alınabilir biçimde test eder.","when":"Yazma performansını ve depolamayı artıran gereksiz index'leri temizlerken.","caution":"Sayaçlar üye bazındadır ve restart'ta sıfırlanır; secondary'lerden okuma yapılıyorsa tüm üyelerde kontrol et ve yeterince uzun bir dönemi (ay sonu raporları dahil) gözle. ops değeri 0 olan unique veya TTL index'ler yine de gereklidir: unique constraint'i ve TTL silmesi sayaçta görünmez. Gizli index yazmalarda güncellenmeye devam eder, unique ise constraint'i uygulamaya devam eder.","since":"MongoDB 4.4","note":"hideIndex için featureCompatibilityVersion en az 4.4 olmalıdır. _id index'i gizlenemez. Gizli index'i unhideIndex ile açmak yeniden build gerektirmez, anında devreye girer.","tags":["indexStats","hideIndex","kullanılmayan index","unused index","dropIndex","index"]},{"id":"connections-by-app","task":"Bağlantıları uygulama ve istemciye göre say (bağlantı fırtınası teşhisi)","category":"Performans","command":"// Toplam, kullanilabilir ve reddedilen baglanti sayisi:\ndb.serverStatus().connections\n// Baglantilari uygulama adi ve istemci IP'sine gore say:\ndb.getSiblingDB(\"admin\").aggregate([\n  { $currentOp: { allUsers: true, idleConnections: true } },\n  { $group: { _id: { app: \"$appName\", client: { $arrayElemAt: [{ $split: [\"$client\", \":\"] }, 0] } }, conns: { $sum: 1 }, active: { $sum: { $cond: [\"$active\", 1, 0] } } } },\n  { $sort: { conns: -1 } },\n  { $limit: 20 }\n])","what":"Sunucudaki toplam ve kullanılabilir bağlantı sayısını, ardından açık bağlantıları appName ve istemci IP'sine göre gruplayıp aktif olanlarla birlikte gösterir.","when":"Bağlantı sayısı aniden arttığında, 'connection refused' veya pool timeout hatalarında, hangi uygulama sunucusunun bağlantı sızdırdığını bulmak için.","caution":"idleConnections: true tüm boşta bağlantıları da döndürdüğü için binlerce bağlantılı sistemde çıktı büyüktür; $group ile özetlemek bu yüzden önemlidir. client alanı null olan satırlar iç thread'lerdir. Her bağlantı yaklaşık 1 MB bellek tüketir; bağlantı fırtınası WiredTiger cache dışındaki belleği de büyütür.","since":"MongoDB 4.4","note":"Kalıcı çözüm genellikle driver tarafındadır: maxPoolSize, maxIdleTimeMS ve uygulama instance sayısı. Uygulamalar appName ayarlamazsa ayırt etmek zorlaşır; connection string'e appName=<servis> eklenmesini iste. net.maxIncomingConnections ve işletim sistemi ulimit -n değeri sert üst sınırı belirler.","tags":["connections","bağlantı","currentOp","appName","connection storm","pool"]},{"id":"index-build-monitor","task":"Devam eden index build ilerlemesini izle ve iptal et","category":"Bakım","command":"// Devam eden index build'ler ve ilerleme yuzdesi:\ndb.getSiblingDB(\"admin\").aggregate([\n  { $currentOp: { allUsers: true } },\n  { $match: { $or: [{ \"command.createIndexes\": { $exists: true } }, { desc: /^IndexBuildsCoordinator/ }] } },\n  { $project: { opid: 1, desc: 1, ns: 1, secs_running: 1, msg: 1, progress: 1, \"command.indexes.name\": 1 } }\n])\n// Build'i iptal et (primary'de; replica set'te tum uyelerde durur):\ndb.musteri.dropIndex(\"idx_email\")","what":"Çalışan index build'leri, taradığı belge sayısı ve yüzde ilerlemesiyle (progress.done / progress.total) listeler; gerekirse build'i dropIndex ile iptal eder.","when":"Büyük koleksiyonda başlatılan bir createIndex'in ne zaman biteceğini kestirmek veya yoğun saatte yük oluşturan build'i durdurmak için.","caution":"Index build'i killOp ile değil dropIndex/dropIndexes ile iptal et; replica set'te iptalin tüm üyelere yayılması için komutu primary'de çalıştır. Build sırasında koleksiyon üzerindeki bazı DDL işlemleri bekler. Build'in sonunda kısa süreli exclusive lock alınır; çok yoğun yazmada bu an gecikme yaratabilir.","since":"MongoDB 4.4","note":"4.4+ replica set'lerde index build tüm data-bearing üyelerde eşzamanlı yürür ve commitQuorum (varsayılan votingMembers) sağlanınca commit edilir; bir secondary geride kalırsa build primary'de de bitmez. 5.0+ sürümlerde temiz kapanışta yarım kalan build restart sonrası kaldığı yerden devam eder.","tags":["index build","createIndex","ilerleme","progress","dropIndex","commitQuorum"]},{"id":"rolling-index-build","task":"Replica set'te rolling index build (üye üye)","category":"Bakım","command":"// 1) Bir SECONDARY'yi kapat; replication.replSetName satirini yorum yap, farkli portta standalone baslat:\n//    mongod --config /etc/mongod.conf --port 27217 --setParameter disableLogicalSessionCacheRefresh=true\n// 2) Standalone uyede index'i olustur:\ndb.getSiblingDB(\"shop\").musteri.createIndex({ email: 1 }, { name: \"idx_email\" })\n// 3) Normal yapilandirmayla geri baslat; SECONDARY olup lag kapanana kadar bekle:\nrs.printSecondaryReplicationInfo()\n// 4) Tum secondary'ler bitince primary'yi indir ve 1-3. adimlari eski primary'de uygula:\nrs.stepDown(120, 30)","what":"Index'i her üyede ayrı ayrı, üyeyi geçici olarak set dışında standalone çalıştırarak oluşturur; primary hiçbir anda build yükü taşımaz.","when":"Çok büyük bir koleksiyonda varsayılan dağıtık build'in primary'ye ve replication lag'e etkisi kabul edilemez olduğunda.","caution":"Her üyenin bakım süresi oplog window'dan kısa olmalı; aksi halde üye geri döndüğünde too stale olur. Unique index'i rolling yöntemle kurarken build boyunca koleksiyona yazmayı durdur; aksi halde bazı üyelerde ihlal eden belge oluşabilir. Standalone üye farklı portta açılmalı ki uygulamalar bağlanmasın.","since":"MongoDB 4.4","note":"4.4+ sürümlerde varsayılan build zaten engellemeyen ve tüm üyelerde eşzamanlı yürüyen bir build'dir; rolling yöntem yalnızca bu yük kabul edilemediğinde gerekir. Sharded cluster'da işlem her shard replica set'i için ayrı yapılır ve balancer önceden durdurulur.","tags":["rolling index","index build","standalone","replica","createIndex","bakım"],"untested":true},{"id":"ttl-index","task":"TTL index oluştur, süresini değiştir ve TTL silmesini izle","category":"Bakım","command":"// Belgeleri lastSeen + 3600 sn sonra otomatik sil:\ndb.oturum.createIndex({ lastSeen: 1 }, { expireAfterSeconds: 3600, name: \"ttl_lastSeen\" })\n// Sureyi index'i yeniden olusturmadan degistir:\ndb.runCommand({ collMod: \"oturum\", index: { name: \"ttl_lastSeen\", expireAfterSeconds: 7200 } })\n// Koleksiyondaki TTL index'ler ve sureleri:\ndb.oturum.getIndexes().filter(i => i.expireAfterSeconds !== undefined)\n// TTL monitor istatistikleri (silinen belge, tur sayisi):\ndb.serverStatus().metrics.ttl","what":"Tarih alanına göre belgeleri belirtilen süre sonunda otomatik silen TTL index'i oluşturur, süresini collMod ile yeniden build etmeden değiştirir ve TTL monitor'ün sildiği belge sayısını gösterir.","when":"Oturum, log, geçici token gibi süreli veriyi uygulama tarafında silme işi yazmadan temizlemek ve şişen koleksiyonların neden küçülmediğini incelemek için.","caution":"TTL monitor varsayılan 60 saniyede bir çalışır; silme anlık değildir. Alan Date tipinde (veya Date dizisi) olmalıdır; string tarih veya alanı olmayan belgeler hiç silinmez. Süreyi kısaltmak çok sayıda belgenin aynı anda silinmesine, yazma yüküne ve replication lag'e yol açar. Silmeler yalnızca primary'de yapılır ve oplog'a yazılır.","since":"MongoDB 5.1","note":"TTL index tek alanlı olmalıdır (compound TTL desteklenmez). TTL olmayan tek alanlı mevcut bir index'e collMod ile expireAfterSeconds eklemek 5.1+ ile mümkündür; var olan TTL süresini değiştirmek daha eski sürümlerde de çalışır. Sabit bir tarihte silme için expireAfterSeconds: 0 ve alana silinme zamanını yaz.","tags":["ttl","expireAfterSeconds","collMod","otomatik silme","index","metrics.ttl"]},{"id":"wt-cache-pressure","task":"WiredTiger cache baskısını ölç (doluluk, dirty oranı, application eviction)","category":"Performans","command":"const c = db.serverStatus().wiredTiger.cache;\nconst max = c[\"maximum bytes configured\"];\n({\n  maxGB: (max / 1024 ** 3).toFixed(1),\n  usedPct: (100 * c[\"bytes currently in the cache\"] / max).toFixed(1),\n  dirtyPct: (100 * c[\"tracked dirty bytes in the cache\"] / max).toFixed(1),\n  appThreadEvictedPages: c[\"pages evicted by application threads\"],\n  pagesReadIntoCache: c[\"pages read into cache\"]\n})\n// Read/write ticket kullanimi ve kuyruk:\ndb.serverStatus().wiredTiger.concurrentTransactions","what":"WiredTiger cache'in boyutunu, doluluk ve dirty yüzdesini, uygulama thread'lerinin eviction yapmak zorunda kaldığı sayfa sayısını ve read/write ticket durumunu gösterir.","when":"Disk okuma artışı, ani gecikme sıçramaları veya yazma throughput düşüşü yaşandığında; cache boyutlandırması yaparken.","caution":"Doluluk %80'i (eviction_target) aşınca arka plan eviction başlar, %95'e (eviction_trigger) ulaşınca uygulama thread'leri de eviction'a girer ve sorgular yavaşlar. Dirty oranı %5 hedef, %20 tetikleme eşiğidir; sürekli %20'ye yakınsa disk yazma kapasitesi yetmiyor demektir. pages evicted by application threads sayacının artması doğrudan kullanıcıya yansıyan gecikmedir. Değerler kümülatif sayaçlardır; iki ölçüm arasındaki farka bak.","since":"MongoDB 7.0","note":"Varsayılan cache boyutu (RAM - 1 GB) / 2 veya 256 MB'tan büyük olandır; konteynerde cgroup limitine göre hesaplanır. storage.wiredTiger.engineConfig.cacheSizeGB'ı artırmak OS page cache'i azaltır; RAM'in yarısını aşmak genelde fayda vermez. 7.0'da ticket sayısı dinamik ayarlanır; 8.0+ sürümlerde ticket metrikleri serverStatus().queues.execution altında da yer alır.","tags":["wiredtiger","cache","eviction","dirty","tickets","bellek"]},{"id":"dump-restore-archive","task":"mongodump/mongorestore ile arşiv yedeği al ve tek koleksiyonu geri yükle","category":"Yedekleme","command":"# Tek veritabani, sikistirilmis tek arsiv dosyasi (sifre sorulur):\nmongodump --uri=\"mongodb://admin@mongo1:27017/?authSource=admin\" --db=shop --gzip --archive=/backup/shop_$(date +%F).archive.gz\n# Arsivi baska isimle geri yuklemeden once kuru calistirma:\nmongorestore --uri=\"mongodb://admin@mongo1:27017/?authSource=admin\" --gzip --archive=/backup/shop_2026-10-08.archive.gz --nsFrom=\"shop.*\" --nsTo=\"shop_restore.*\" --dryRun\n# Arsivden tek koleksiyonu yeni isimle geri yukle:\nmongorestore --uri=\"mongodb://admin@mongo1:27017/?authSource=admin\" --gzip --archive=/backup/shop_2026-10-08.archive.gz --nsInclude=\"shop.musteri\" --nsFrom=\"shop.*\" --nsTo=\"shop_restore.*\" --numInsertionWorkersPerCollection=4\n# Ayni isimle, mevcut koleksiyonu silerek geri yukle:\nmongorestore --uri=\"mongodb://admin@mongo1:27017/?authSource=admin\" --gzip --archive=/backup/shop_2026-10-08.archive.gz --nsInclude=\"shop.musteri\" --drop","what":"Bir veritabanını tek bir gzip arşiv dosyasına yedekler; arşivden tüm veritabanını veya tek bir koleksiyonu, isterse farklı bir isim altında (nsFrom/nsTo) geri yükler.","when":"Mantıksal yedek, ortamlar arası veri taşıma veya yanlışlıkla silinen/bozulan tek bir koleksiyonu kurtarma ihtiyacında.","caution":"mongodump mantıksal yedektir: büyük veri setlerinde yavaştır ve index'ler restore sırasında yeniden build edilir. --oplog olmadan alınan dump, çalışan bir sistemde nokta-zaman tutarlı değildir. --drop hedef koleksiyonu restore başlamadan siler; önce nsTo ile farklı isme yükleyip doğrula. Restore yükü primary'ye yazar ve replication lag yaratabilir.","since":"MongoDB 4.4","note":"Database tools (mongodump/mongorestore) 4.4'ten itibaren sunucudan ayrı sürümlenir (100.x). Yedek sırasında okuma yükünü primary'den almak için URI'ye readPreference=secondary ekle. Kullanıcı ve rolleri de taşımak için tam instance dump'ı ile --restoreDbUsersAndRoles veya admin veritabanını ayrıca yedekle.","tags":["mongodump","mongorestore","yedek","archive","nsFrom","restore"]},{"id":"pitr-oplog-replay","task":"Oplog replay ile point-in-time restore (yanlış drop/delete öncesine dön)","category":"Yedekleme","command":"# 1) Tam yedek + yedek suresince olusan oplog (tum instance, replica set uyesinden):\nmongodump --uri=\"mongodb://admin@mongo2:27017/?authSource=admin&readPreference=secondary\" --oplog --gzip --out=/backup/full\n# 2) Hatali islemin zamanini bul (mongosh): db.getSiblingDB(\"local\").oplog.rs.find({ \"o.drop\": \"musteri\" }).sort({ $natural: -1 }).limit(1)\n# 3) Yedekten sonraki oplog'u al (t: tam yedegin baslangic zamani, epoch saniye):\nmongodump --uri=\"mongodb://admin@mongo2:27017/?authSource=admin\" --db=local --collection=oplog.rs --query='{\"ts\":{\"$gte\":{\"$timestamp\":{\"t\":1791400000,\"i\":1}}}}' --out=/backup/oplog\n# 4) Tam yedegi kendi oplog'uyla birlikte yukle:\nmongorestore --uri=\"mongodb://admin@target:27017/?authSource=admin\" --gzip --oplogReplay /backup/full\n# 5) Oplog'u hatali isleme kadar uygula (oplogLimit haric tutulur):\nmkdir /backup/pitr && mv /backup/oplog/local/oplog.rs.bson /backup/pitr/oplog.bson\nmongorestore --uri=\"mongodb://admin@target:27017/?authSource=admin\" --oplogReplay --oplogLimit=1791403600:1 /backup/pitr","what":"Tam yedeği --oplog ile tutarlı hale getirir, ardından yedekten sonra biriken oplog'u hatalı işlemin (drop, toplu delete) timestamp'ine kadar uygulayarak veriyi o ana geri getirir.","when":"Yanlışlıkla bir koleksiyon drop edildiğinde veya hatalı bir toplu update/delete çalıştığında, hasar öncesi son duruma dönmek gerektiğinde.","caution":"Restore'u canlı sisteme değil ayrı bir hedefe yap, doğrulandıktan sonra gereken veriyi taşı. Yedeğin başlangıcından hatalı işleme kadarki oplog oplog window içinde kalmalıdır; pencere dışına düşen işlemler kurtarılamaz. --oplog yalnızca tam instance dump'ında çalışır (--db ile kullanılamaz). Sharded cluster'da mongodump ile tutarlı PITR yapılamaz; dosya sistemi snapshot'ı veya bir backup ürünü gerekir.","since":"MongoDB 4.4","note":"--oplogLimit=<saniye>:<sıra> verilen timestamp'teki ve sonrasındaki girdileri uygulamaz; hatalı işlemin ts değerini doğrudan vermek onu dışarıda bırakır. ts değerleri oplog'da Timestamp(t, i) biçimindedir. Oplog'u hatalı işlem gerçekleştikten sonra, pencere kapanmadan hemen dump et.","tags":["pitr","point in time","oplogReplay","oplogLimit","geri dönüş","mongorestore"],"untested":true},{"id":"user-role-admin","task":"Özel rol tanımla, kullanıcı oluştur, rol ver/geri al ve şifre değiştir","category":"Güvenlik","command":"use admin\ndb.createRole({\n  role: \"opsRead\",\n  privileges: [\n    { resource: { db: \"shop\", collection: \"\" }, actions: [\"find\", \"listCollections\", \"listIndexes\", \"collStats\", \"dbStats\"] },\n    { resource: { cluster: true }, actions: [\"serverStatus\", \"inprog\"] }\n  ],\n  roles: []\n})\ndb.createUser({ user: \"shop_app\", pwd: passwordPrompt(), roles: [{ role: \"readWrite\", db: \"shop\" }, { role: \"opsRead\", db: \"admin\" }] })\ndb.grantRolesToUser(\"shop_app\", [{ role: \"clusterMonitor\", db: \"admin\" }])\ndb.revokeRolesFromUser(\"shop_app\", [{ role: \"clusterMonitor\", db: \"admin\" }])\ndb.changeUserPassword(\"shop_app\", passwordPrompt())\ndb.getUser(\"shop_app\", { showPrivileges: true })\ndb.runCommand({ usersInfo: { forAllDBs: true } })","what":"Belirli veritabanı ve cluster aksiyonlarını içeren özel bir rol tanımlar, kullanıcıyı bu rol ve yerleşik rollerle oluşturur, rol ekleyip çıkarır, şifreyi değiştirir ve tüm veritabanlarındaki kullanıcıları listeler.","when":"Uygulama ve izleme hesaplarını en az yetki ilkesine göre açarken, yetki denetiminde veya şifre rotasyonunda.","caution":"Kullanıcının tanımlandığı veritabanı (burada admin) authSource olarak kullanılır; uygulamanın bağlantı dizgesiyle aynı olmalıdır. root/dbOwner gibi geniş rolleri uygulama hesaplarına verme. Rol değişikliği mevcut oturumlara hemen yansır; şifre değişikliği açık bağlantıları kesmez, yeni bağlantılarda geçerli olur.","since":"MongoDB 4.4","note":"passwordPrompt() şifreyi shell geçmişine ve process listesine düşürmeden sorar. Replica set ve sharded cluster'da kullanıcılar primary/mongos üzerinden yönetilir ve replike edilir. Bir kullanıcının efektif yetkilerini görmek için getUser'da showPrivileges: true kullan.","tags":["createUser","createRole","grantRolesToUser","yetki","rbac","şifre"]},{"id":"fcv-upgrade","task":"featureCompatibilityVersion (fCV) kontrolü ve major upgrade sırası","category":"Upgrade","command":"// 1) Mevcut fCV (tum uyelerde ayni olmali; yarim kalmis gecis varsa targetVersion gorunur):\ndb.adminCommand({ getParameter: 1, featureCompatibilityVersion: 1 })\n// 2) Binary'leri rolling olarak yukselt (secondary'ler -> stepDown -> eski primary); fCV eski kalir\ndb.version()\n// 3) Gozlem suresi sonunda primary'de (sharded cluster'da mongos'ta) fCV'yi yukselt:\ndb.adminCommand({ setFeatureCompatibilityVersion: \"7.0\", confirm: true })\n// 4) Geri donus gerekirse binary'den ONCE fCV indirilir:\ndb.adminCommand({ setFeatureCompatibilityVersion: \"6.0\", confirm: true })","what":"Çalışan fCV'yi gösterir; binary yükseltmesi ile fCV yükseltmesinin ayrı adımlar olduğunu ve hangi sırayla yapılacağını verir.","when":"Major sürüm yükseltmesi (ör. 6.0 -> 7.0) planlarken, yükseltme sonrası yeni özellikler açılmadığında veya bir sonraki major'a geçmeden önce.","caution":"Major sürümler atlanamaz: 5.0 -> 7.0 için önce 6.0'a geçilip fCV 6.0 yapılmalıdır. fCV yükseltildikten sonra veri dosyaları yeni formata geçebilir ve binary downgrade'i zorlaşır; fCV'yi yeni sürüm birkaç gün sorunsuz çalıştıktan sonra yükselt. 7.0+ Community sürümlerde binary downgrade resmi olarak desteklenmez; geri dönüş planını yedek üzerinden kur. Driver uyumluluğunu yükseltmeden önce kontrol et.","since":"MongoDB 7.0","note":"7.0 ile setFeatureCompatibilityVersion için confirm: true zorunlu hale geldi. fCV geçişi sırasında hata olursa getParameter çıktısında targetVersion/previousVersion görünür; aynı komutu tekrar çalıştırarak tamamla. fCV değeri replica set içinde replike edilir.","tags":["fcv","featureCompatibilityVersion","upgrade","yükseltme","major","downgrade"]}]},"recipes/redis.json":{"engineId":"redis","engine":"Redis","order":6,"recipes":[{"id":"bgrewriteaof","task":"AOF dosyasını yeniden yaz (sıkıştır)","category":"Kalıcılık","command":"BGREWRITEAOF","what":"AOF dosyasını arka planda daha kompakt biçimde yeniden yazar.","when":"AOF dosyası şiştiğinde, yeniden başlatma süresini kısaltmak için.","caution":"Fork sırasında bellek ve IO kullanımı artar; yoğun saatlerde dikkat.","tags":["aof","rewrite","persistence","kalicilik"]},{"id":"bgsave","task":"Arka planda RDB snapshot al","category":"Kalıcılık","command":"BGSAVE","what":"Fork edilen bir alt süreçle RDB snapshot'ını arka planda diske yazar.","when":"Yedek almak veya snapshot oluşturmak istediğinizde.","caution":"Fork anında copy-on-write nedeniyle bellek kullanımı geçici olarak yükselebilir.","tags":["rdb","bgsave","snapshot","kalicilik","yedek"]},{"id":"save","task":"Senkron RDB snapshot al","category":"Kalıcılık","command":"SAVE","what":"RDB snapshot'ını ana thread üzerinde senkron olarak diske yazar.","when":"Yalnızca bakım/kapanış öncesi, hiçbir istemci hizmet almazken.","caution":"SAVE tüm sunucuyu bloklar ve işlem bitene kadar hiçbir komut işlenmez; üretimde BGSAVE tercih edin.","tags":["rdb","save","snapshot","blok","kalicilik"]},{"id":"lastsave","task":"Son başarılı snapshot zamanını gör","category":"Kalıcılık","command":"LASTSAVE","what":"En son başarılı RDB kaydının Unix zaman damgasını döndürür.","when":"BGSAVE'in tamamlanıp tamamlanmadığını kontrol etmek için.","caution":"Salt okunur komuttur; risk yoktur.","tags":["lastsave","rdb","zaman","kontrol","kalicilik"]},{"id":"config-rewrite","task":"Çalışan yapılandırmayı diske yaz","category":"Kalıcılık","command":"CONFIG REWRITE","what":"Çalışma zamanında CONFIG SET ile yapılan değişiklikleri redis.conf dosyasına kalıcı olarak yazar.","when":"Runtime değişikliklerinin yeniden başlatmada da kalıcı olmasını istediğinizde.","caution":"Mevcut redis.conf dosyasının üzerine yazar; dosyanın yazılabilir ve tanımlı olması gerekir.","tags":["config","rewrite","kalici","conf","ayar"]},{"id":"config-appendonly","task":"AOF'u aç veya kapat","category":"Kalıcılık","command":"CONFIG SET appendonly yes","what":"AOF kalıcılığını çalışma zamanında etkinleştirir (yes) veya devre dışı bırakır (no).","when":"AOF kalıcılığını yeniden başlatmadan açıp kapatmak istediğinizde.","caution":"AOF'u kapatmak kalıcılık garantisini düşürür; açtığınızda ilk AOF yeniden yazımı IO yükü oluşturur.","tags":["aof","appendonly","config","kalicilik","ayar"]},{"id":"config-save-rdb","task":"RDB snapshot kurallarını ayarla","category":"Kalıcılık","command":"CONFIG SET save \"900 1 300 10 60 10000\"","what":"RDB otomatik snapshot tetikleme kurallarını (saniye/değişiklik sayısı) ayarlar.","when":"Otomatik snapshot sıklığını değiştirmek istediğinizde.","caution":"Boş bir değer (\"\") verirseniz otomatik RDB kaydı tamamen kapanır ve kalıcılık kaybolabilir.","tags":["rdb","save","config","snapshot","ayar"]},{"id":"replicaof","task":"Bir düğümü replika yap","category":"Replikasyon","command":"REPLICAOF redis-master 6379","what":"Bu düğümü belirtilen host ve port'taki master'ın replikası yapar ve senkronizasyon başlatır.","when":"Yeni bir okuma replikası eklerken veya rol atarken.","caution":"Replika olan düğümün mevcut verisi silinir ve master'dan tam senkron çekilir.","since":"Redis 5.0","note":"REPLICAOF komutu Redis 5.0 ile SLAVEOF'un yerini aldı; eski SLAVEOF komutu hâlâ takma ad olarak çalışır.","tags":["replicaof","replica","replikasyon","master","senkron"]},{"id":"replicaof-no-one","task":"Replikayı master yap","category":"Replikasyon","command":"REPLICAOF NO ONE","what":"Düğümün replika bağlantısını keserek onu bağımsız bir master haline getirir.","when":"Failover senaryosunda bir replikayı yükseltmek (promote) istediğinizde.","caution":"Promote sonrası eski master ile veri ıraksaması (split-brain) olmaması için topolojiyi dikkatle yönetin.","since":"Redis 5.0","note":"REPLICAOF NO ONE, Redis 5.0 ile SLAVEOF NO ONE'ın yerini aldı; eski SLAVEOF NO ONE hâlâ takma ad olarak çalışır.","tags":["replicaof","promote","master","failover","replikasyon"]},{"id":"cluster-failover","task":"Manuel failover yap","category":"Cluster","command":"CLUSTER FAILOVER","what":"Bir replika üzerinde çalıştırıldığında o replikayı master'a yükselterek kontrollü failover başlatır.","when":"Bakım öncesi master rolünü replikaya devretmek istediğinizde.","caution":"Bu komut master'ın kendisinde değil, hedef replikada çalıştırılmalıdır.","tags":["cluster","failover","promote","bakim","replikasyon"]},{"id":"cluster-meet","task":"Cluster'a düğüm ekle","category":"Cluster","command":"CLUSTER MEET 10.0.0.12 6379","what":"Belirtilen IP ve port'taki düğümü cluster gossip ağına dahil eder.","when":"Cluster'a yeni bir düğüm eklerken (ölçeklendirme).","caution":"Düğüm eklendikten sonra slot ataması (ADDSLOTS) veya reshard yapılmazsa düğüm veri almaz.","tags":["cluster","meet","node","ekle","dugum"]},{"id":"cluster-addslots","task":"Cluster slotlarını ata","category":"Cluster","command":"CLUSTER ADDSLOTS 0 1 2 3 4 5","what":"Belirtilen hash slot'larını bu master düğüme atar.","when":"Yeni bir master düğümü elle yapılandırırken veya slot dağıtımını düzeltirken.","caution":"Aynı slot birden fazla düğüme atanamaz; toplam 16384 slot eksiksiz atanmazsa cluster down durumuna geçer.","tags":["cluster","addslots","slot","ata","dugum"]},{"id":"info-replication","task":"Replikasyon durumunu gör","category":"Cluster","command":"INFO replication","what":"Rol (master/replica), bağlı replikalar ve replikasyon offset bilgisini gösterir.","when":"Replikasyon gecikmesini ve bağlantı durumunu kontrol ederken.","caution":"Salt okunur komuttur; risk yoktur.","tags":["info","replication","durum","replikasyon","gecikme"]},{"id":"cluster-info","task":"Cluster durumunu gör","category":"Cluster","command":"CLUSTER INFO","what":"Cluster'ın genel durumunu (ok/fail), atanmış slot sayısını ve bilinen düğüm sayısını gösterir.","when":"Cluster sağlığını ve slot bütünlüğünü doğrularken.","caution":"Salt okunur komuttur; risk yoktur.","tags":["cluster","info","durum","slot","saglik"]},{"id":"config-maxmemory","task":"maxmemory ve politika ayarla","category":"Bellek","command":"CONFIG SET maxmemory 4gb maxmemory-policy allkeys-lru","what":"Bellek üst sınırını ve sınır aşıldığında uygulanacak eviction politikasını ayarlar. Redis 7.0+ tek CONFIG SET'te birden çok parametre kabul eder; eski sürümlerde iki ayrı CONFIG SET çalıştır.","when":"Bellek kullanımını sınırlamak ve eviction davranışını belirlemek istediğinizde.","caution":"noeviction politikasında sınıra ulaşınca yazmalar hata verir; yanlış limit veri kaybına/kesintiye yol açabilir.","tags":["maxmemory","policy","bellek","eviction","config"]},{"id":"memory-doctor","task":"Bellek analizi yap","category":"Bellek","command":"MEMORY DOCTOR","what":"Bellek kullanımını analiz eder ve olası sorunlar hakkında insan-okunur bir rapor verir.","when":"Yüksek bellek kullanımı veya fragmentasyon şüphesinde teşhis için.","caution":"Salt okunur analizdir; detay için MEMORY STATS komutunu da kullanabilirsiniz.","tags":["memory","doctor","bellek","analiz","tani"]},{"id":"slowlog-get","task":"Yavaş komut kaydını gör","category":"Bakım","command":"SLOWLOG GET 10","what":"Slowlog'daki en son 10 yavaş komut kaydını (süre, zaman, argümanlar) döndürür.","when":"Yavaş komutları tespit edip performans darboğazlarını incelerken.","caution":"Salt okunur komuttur; kayıtları temizlemek için SLOWLOG RESET kullanın.","tags":["slowlog","get","yavas","tani","performans"]},{"id":"slowlog-config","task":"Yavaş komut eşiğini ayarla","category":"Bakım","command":"CONFIG SET slowlog-log-slower-than 10000","what":"Bir komutun slowlog'a kaydedilmesi için gereken süre eşiğini mikrosaniye cinsinden ayarlar (10000 = 10 ms).","when":"Slowlog hassasiyetini ayarlamak istediğinizde.","caution":"Değeri 0 yapmak tüm komutları kaydeder ve overhead getirir; -1 slowlog'u kapatır.","tags":["slowlog","threshold","esik","config","yavas"]},{"id":"slowlog-reset","task":"Yavaş komut kaydını sıfırla","category":"Bakım","command":"SLOWLOG RESET","what":"Slowlog içindeki tüm kayıtları temizler.","when":"Yeni bir gözlem penceresi başlatmak için kayıtları temizlerken.","caution":"Mevcut yavaş komut geçmişi kalıcı olarak silinir.","tags":["slowlog","reset","sifirla","temizle","bakim"]},{"id":"client-kill","task":"Bir istemci bağlantısını öldür","category":"Bakım","command":"CLIENT KILL ADDR 10.0.0.5:53210","what":"Belirtilen adresteki istemci bağlantısını sonlandırır.","when":"Takılı kalmış veya kötü davranan bir istemciyi sonlandırmak istediğinizde.","caution":"Bağlantı anında kesilir; devam eden işlemler yarıda kalabilir. Doğru adresi seçtiğinizden emin olun.","tags":["client","kill","istemci","oldur","bakim"]},{"id":"client-list","task":"Bağlı istemcileri listele","category":"Bakım","command":"CLIENT LIST","what":"Bağlı tüm istemcileri adres, boşta kalma süresi ve son komut gibi detaylarla listeler.","when":"Bağlantıları incelerken veya sorunlu istemciyi bulurken.","caution":"Salt okunur komuttur; risk yoktur.","tags":["client","list","istemci","liste","baglanti"]},{"id":"config-get","task":"Parametre değerini gör","category":"Runtime","command":"CONFIG GET maxmemory-policy","what":"Bir veya birden fazla yapılandırma parametresinin güncel değerini döndürür (glob desteklenir).","when":"Bir ayarın çalışma zamanı değerini doğrularken.","caution":"Salt okunur komuttur; risk yoktur.","tags":["config","get","parametre","goruntule","runtime"]},{"id":"config-set","task":"Parametre değerini değiştir","category":"Runtime","command":"CONFIG SET appendfsync everysec","what":"Bir yapılandırma parametresini çalışma zamanında yeniden başlatmadan değiştirir.","when":"Bir sunucu davranışını anında ayarlamak istediğinizde.","caution":"Değişiklik geçicidir; kalıcı olması için CONFIG REWRITE çalıştırın. Yanlış değer performansı/kalıcılığı bozabilir.","tags":["config","set","parametre","runtime","ayar"]}]},"recipes/redis-ext.json":{"engineId":"redis","engine":"Redis","order":2,"recipes":[{"id":"mem-fragmentation","task":"Bellek kullanımını ve fragmentation'ı analiz et, active defrag'i aç","category":"Bellek","command":"INFO memory\n# Bakilacak alanlar: used_memory_human, used_memory_rss_human, mem_fragmentation_ratio, mem_fragmentation_bytes, allocator_frag_ratio\nMEMORY STATS\n# Fragmentation yuksek ve kalici ise active defrag'i ac (jemalloc gerekir):\nCONFIG SET activedefrag yes\nCONFIG SET active-defrag-ignore-bytes 100mb\nCONFIG SET active-defrag-threshold-lower 10\n# Allocator'in bos sayfalari isletim sistemine iade etmesini iste:\nMEMORY PURGE","what":"Redis'in veri için ayırdığı bellek (used_memory) ile işletim sisteminin gördüğü RSS arasındaki farkı, fragmentation oranını ve bellek dağılımını gösterir; gerekirse active defrag'i çalışma zamanında açar.","when":"RSS, dataset boyutundan belirgin şekilde büyük olduğunda, toplu silme/expire sonrasında bellek düşmediğinde veya OOM riski oluştuğunda.","caution":"mem_fragmentation_ratio küçük dataset'lerde yanıltıcıdır (ör. 2 MB veride 4.0 görülebilir); mutlak değer için mem_fragmentation_bytes'a bak. Oran 1'in altındaysa fragmentation değil swap söz konusudur ve gecikme yaratır. Active defrag CPU tüketir; active-defrag-cycle-max ile üst sınırı kontrol et. Kalıcı olması için CONFIG REWRITE veya redis.conf gerekir.","since":"Redis 4.0","note":"Active defrag yalnızca Redis ile gelen jemalloc ile derlenmiş sürümlerde çalışır. allocator_frag_ratio, defrag'in giderebileceği iç fragmentation'ı; allocator_rss_ratio ise allocator'ın OS'e iade etmediği alanı gösterir. Değişken boyutlu değerlerin sık güncellendiği iş yüklerinde fragmentation daha hızlı artar.","tags":["memory","bellek","fragmentation","activedefrag","rss","info memory"]},{"id":"bigkeys-memkeys","task":"Büyük key'leri bul (--bigkeys, --memkeys, MEMORY USAGE)","category":"Bellek","command":"# Eleman sayisina gore tip basina en buyuk key'ler:\nredis-cli -h redis1 -p 6379 --bigkeys -i 0.01\n# Bellek boyutuna gore:\nredis-cli -h redis1 -p 6379 --memkeys -i 0.01\n# Boyut ve uzunluk birlikte, ilk 20 key (redis-cli 7.4+):\nredis-cli -h redis1 -p 6379 --keystats --top 20 -i 0.01\n# Supheli tek key'in bellek kullanimi (SAMPLES 0: tum elemanlar) ve encoding'i:\nredis-cli -h redis1 -p 6379 MEMORY USAGE kullanici:1001:sepet SAMPLES 0\nredis-cli -h redis1 -p 6379 OBJECT ENCODING kullanici:1001:sepet","what":"Keyspace'i SCAN ile tarayarak tip başına en çok elemana ve en çok belleğe sahip key'leri raporlar; şüpheli bir key'in gerçek bellek tüketimini ve encoding'ini gösterir.","when":"Bellek beklenmedik şekilde arttığında, tek bir komutun (HGETALL, SMEMBERS, DEL) gecikme yarattığı veya cluster'da bir düğümün diğerlerinden fazla bellek kullandığı durumlarda.","caution":"Tarama SCAN kullanır ve sunucuyu bloklamaz ama tüm keyspace'i dolaşır; -i 0.01 her 100 SCAN çağrısında bekleyerek yükü azaltır. Büyük key'i DEL ile silmek ana thread'i bloklar; UNLINK kullan. MEMORY USAGE büyük koleksiyonlarda SAMPLES 0 ile O(N)'dir. Replika üzerinde çalıştırmak master'ı yormaz.","since":"Redis 6.0","note":"--bigkeys eleman sayısına, --memkeys MEMORY USAGE değerine bakar; liste/hash gibi tiplerde ikisi farklı key'leri öne çıkarabilir. Küçük hash/zset/list'ler listpack encoding ile çok daha az bellek tutar; hash-max-listpack-entries gibi eşikler aşılınca hashtable'a geçer. Cluster'da her master düğümde ayrı çalıştırılır.","tags":["bigkeys","memkeys","büyük key","memory usage","keystats","big key"]},{"id":"hotkeys-lfu","task":"Sıcak key'leri bul (--hotkeys, OBJECT FREQ)","category":"Performans","command":"# LFU tabanli politika gerekir; mevcut politikayi not et:\nCONFIG GET maxmemory-policy\nCONFIG SET maxmemory-policy allkeys-lfu\n# Erisim sikligina gore en sicak key'ler:\nredis-cli -h redis1 -p 6379 --hotkeys -i 0.01\n# Tek key'in LFU sayaci:\nOBJECT FREQ urun:populer:liste\n# Analiz bitince eski politikaya don:\nCONFIG SET maxmemory-policy noeviction","what":"LFU sayaçlarını kullanarak en sık erişilen key'leri listeler; tek bir key'in erişim sıklığı sayacını gösterir.","when":"Tek bir düğümün CPU'su %100'e yaklaştığında, cluster'da bir slot/düğüm diğerlerinden çok daha fazla trafik aldığında veya ağ bant genişliği tek bir key yüzünden dolduğunda.","caution":"--hotkeys yalnızca maxmemory-policy *-lfu iken çalışır. Politikayı değiştirmek eviction davranışını da değiştirir: maxmemory tanımlıysa ve önceki politika volatile-* veya noeviction ise allkeys-lfu TTL'siz key'leri de silebilir. Analizi kısa tut ve politikayı geri al. LFU sayaçları logaritmiktir ve zamanla azalır; mutlak erişim sayısı değildir.","since":"Redis 4.0","note":"Politika değişikliğinden sonra LFU sayaçlarının anlamlı hale gelmesi için bir süre trafik gerekir. Politikayı değiştirmek mümkün değilse kısa bir MONITOR örneklemesi alternatiftir ama MONITOR çok yüklü sistemlerde throughput'u ciddi düşürür. Sıcak okuma key'leri için client-side caching (CLIENT TRACKING) veya key'i parçalara bölmek kalıcı çözümdür.","tags":["hotkeys","sıcak key","lfu","object freq","hot key","cpu"]},{"id":"scan-unlink-pattern","task":"Desene uyan key'leri KEYS kullanmadan bul ve güvenle sil (SCAN + UNLINK)","category":"Bakım","command":"# KEYS yerine imlecle tarama (0 donene kadar donen imlecle tekrar cagir):\nSCAN 0 MATCH oturum:* COUNT 1000 TYPE string\n# Desene uyan key sayisi:\nredis-cli -h redis1 -p 6379 --scan --pattern 'oturum:*' --count 1000 | wc -l\n# Bellegi arka planda serbest birakarak 500'erli toplu sil:\nredis-cli -h redis1 -p 6379 --scan --pattern 'oturum:*' --count 1000 | xargs -r -n 500 redis-cli -h redis1 -p 6379 UNLINK","what":"Keyspace'i sunucuyu bloklamadan imleçle tarar, desene ve tipe uyan key'leri sayar ve bunları UNLINK ile belleği arka planda serbest bırakarak toplu siler.","when":"Eski bir uygulama sürümünün bıraktığı key'leri temizlerken, bir prefix altındaki key sayısını öğrenirken veya üretimde KEYS komutuna ihtiyaç duyulduğunda.","caution":"KEYS tüm keyspace'i tek seferde döner ve büyük veride sunucuyu saniyelerce bloklar; üretimde kullanma. SCAN tarama sırasında eklenen/silinen key'ler için tam garanti vermez ve aynı key'i birden fazla döndürebilir. Boşluk veya tırnak içeren key adları xargs ile bozulur. Silmeden önce sayıyı ve birkaç örneği kontrol et; geri alma yoktur.","since":"Redis 4.0","note":"SCAN'deki TYPE seçeneği 6.0 ile geldi. COUNT bir ipucudur, dönen eleman sayısını garanti etmez. Cluster'da --scan yalnızca bağlanılan düğümü tarar; her master'da ayrı çalıştır. UNLINK, lazyfree ile büyük değerleri ayrı thread'de serbest bırakır; küçük key'lerde DEL ile aynı maliyettedir.","tags":["scan","unlink","keys","toplu silme","pattern","match"]},{"id":"latency-diagnosis","task":"Gecikme kaynağını teşhis et (LATENCY DOCTOR, histogram, commandstats)","category":"Performans","command":"# Latency monitor'u ac (100 ms ustu olaylari kaydet):\nCONFIG SET latency-monitor-threshold 100\nLATENCY LATEST\nLATENCY HISTORY command\nLATENCY DOCTOR\n# Komut bazinda gecikme dagilimi ve yuzdelikler:\nLATENCY HISTOGRAM GET SET HGETALL\nINFO latencystats\n# Toplam CPU suresine gore en pahali komutlar:\nredis-cli -h redis1 -p 6379 INFO commandstats | sort -t= -k3 -rn | head\n# Sunucu host'unda, Redis disi taban gecikmesi (VM/steal tespiti, 30 sn):\nredis-cli --intrinsic-latency 30\nLATENCY RESET","what":"Latency monitor ile fork, AOF fsync, expire döngüsü ve yavaş komut gibi olayların gecikme sıçramalarını kaydeder; komut bazında yüzdelik gecikmeleri ve toplam CPU süresine göre en pahalı komutları gösterir; host seviyesindeki taban gecikmeyi ölçer.","when":"Uygulamada p99 gecikme sıçramaları görüldüğünde ve SLOWLOG temiz olduğu halde yavaşlık şikâyeti sürdüğünde.","caution":"latency-monitor-threshold varsayılan 0'dır (kapalı); teşhis bitince eski değerine al. SLOWLOG yalnızca komutun çalışma süresini ölçer, ağ ve kuyruk beklemesini görmez; LATENCY olayları ise fork, fsync gibi sunucu içi duraksamaları da yakalar. --intrinsic-latency CPU tüketir ve Redis sunucusunun çalıştığı makinede çalıştırılmalıdır.","since":"Redis 7.0","note":"LATENCY HISTOGRAM ve INFO latencystats 7.0 ile geldi (latency-tracking varsayılan açık). LATENCY HISTORY'de fork olayları yüksekse büyük dataset ve THP (transparent huge pages) etkisine; aof-fsync-always/aof-write olayları yüksekse disk gecikmesine bak. commandstats'ta usec_per_call yüksek komutlar O(N) kullanım işaretidir.","tags":["latency","gecikme","latency doctor","histogram","commandstats","intrinsic-latency"]},{"id":"eviction-oom-diag","task":"Eviction, expire ve OOM hatalarını teşhis et","category":"Bellek","command":"INFO stats\n# Bakilacak alanlar: evicted_keys, expired_keys, expired_stale_perc, keyspace_hits, keyspace_misses, total_eviction_exceeded_time (7.0+)\nINFO keyspace\nCONFIG GET maxmemory\nCONFIG GET maxmemory-policy\nINFO memory\n# Eviction'i tetikleyen deger: used_memory - mem_not_counted_for_evict, maxmemory ile karsilastirilir","what":"Silinen (evicted) ve süresi dolan (expired) key sayılarını, cache hit oranını, TTL'li key oranını ve maxmemory ile eviction'ı tetikleyen bellek değerini birlikte gösterir.","when":"Uygulama 'OOM command not allowed when used memory > maxmemory' hatası aldığında, cache hit oranı düştüğünde veya key'lerin beklenmedik şekilde kaybolduğu bildirildiğinde.","caution":"noeviction politikasında maxmemory dolunca yazma komutları OOM hatası alır, okumalar çalışmaya devam eder. volatile-* politikalarında TTL'si olmayan key'ler silinmez; TTL'li key yoksa davranış noeviction gibidir (INFO keyspace'te expires değerine bak). maxmemory'yi fiziksel RAM'e çok yakın ayarlama: replication buffer ve fork sırasında copy-on-write için pay bırak.","since":"Redis 6.0","note":"Hit oranı = keyspace_hits / (keyspace_hits + keyspace_misses). evicted_keys sürekli artıyor ve hit oranı düşüyorsa bellek yetersizdir. expired_stale_perc yüksekse süresi dolmuş ama henüz silinmemiş key oranı yüksektir; active-expire-effort ile expire döngüsü hızlandırılabilir. Replika buffer'ları ve AOF buffer'ı mem_not_counted_for_evict'e dahildir.","tags":["eviction","oom","maxmemory","expire","hit ratio","evicted_keys"]},{"id":"client-memory","task":"Belleği şişiren bağlantıları bul (output buffer, query buffer, maxmemory-clients)","category":"Bellek","command":"INFO clients\n# tot-mem'e gore en cok bellek tutan 10 baglanti (tot-mem, omem, qbuf, id, addr, user, cmd, age):\nredis-cli -h redis1 -p 6379 CLIENT LIST | awk '{for(i=1;i<=NF;i++){split($i,a,\"=\"); f[a[1]]=a[2]} print f[\"tot-mem\"], f[\"omem\"], f[\"qbuf\"], f[\"id\"], f[\"addr\"], f[\"user\"], f[\"cmd\"], f[\"age\"]}' | sort -rn | head -10\nCLIENT LIST TYPE pubsub\nCONFIG GET client-output-buffer-limit\n# Tum client'larin toplam bellegi icin ust sinir (asilirsa en buyuk client'lar kapatilir):\nCONFIG SET maxmemory-clients 5%","what":"Bağlantıları toplam bellek (tot-mem), output buffer (omem) ve query buffer (qbuf) kullanımına göre sıralar; pub/sub bağlantılarını ve buffer limitlerini gösterir; client belleğine toplam üst sınır koyar.","when":"used_memory veri büyümeden arttığında, mem_clients_normal yüksek göründüğünde veya yavaş tüketen bir pub/sub/MONITOR client'ı belleği doldurduğunda.","caution":"Büyük omem genellikle sonucu yavaş okuyan client'ı (büyük KEYS/HGETALL yanıtı, yavaş pub/sub abonesi, açık kalmış MONITOR) gösterir. maxmemory-clients aşıldığında en çok bellek tutan client'lar uyarısız kapatılır; replika ve master bağlantıları hariçtir ama uygulama bağlantıları kopabilir. Kritik bağlantılar için CLIENT NO-EVICT on kullan.","since":"Redis 7.0","note":"maxmemory-clients 7.0 ile geldi ve varsayılan 0 (sınırsız). client-output-buffer-limit pubsub ve replica sınıfları için hard/soft limit uygular; normal client'lar için varsayılan sınırsızdır. Sorunlu bağlantıyı CLIENT KILL ID <id> ile kapat (bkz. client-kill).","tags":["client list","omem","output buffer","maxmemory-clients","bağlantı","pubsub"]},{"id":"persistence-health","task":"RDB/AOF hata durumunu, fork süresini ve MISCONF nedenini teşhis et","category":"Kalıcılık","command":"INFO persistence\n# Kritik alanlar: rdb_last_bgsave_status, aof_last_bgrewrite_status, aof_last_write_status, rdb_changes_since_last_save, aof_delayed_fsync\nINFO stats\n# latest_fork_usec: son fork suresi (mikrosaniye), total_forks\nCONFIG GET stop-writes-on-bgsave-error\nCONFIG GET dir\nCONFIG GET appendfsync","what":"Son RDB snapshot ve AOF rewrite/yazma işlemlerinin başarılı olup olmadığını, son kayıttan beri değişen key sayısını, geciken fsync sayısını ve fork süresini gösterir.","when":"Uygulama 'MISCONF Redis is configured to save RDB snapshots, but it's currently unable to persist to disk' hatası aldığında, BGSAVE/BGREWRITEAOF başarısız olduğunda veya fork kaynaklı gecikme görüldüğünde.","caution":"stop-writes-on-bgsave-error yes iken (varsayılan) başarısız BGSAVE sonrası tüm yazmalar reddedilir. Hatayı 'no' yaparak susturmak veri kaybı riskini gizler; önce nedeni çöz: disk dolu, dir dizininde yazma izni yok veya fork belleği alamıyor (vm.overcommit_memory=0). Fork süresi büyük dataset'te yüzlerce milisaniyeyi bulabilir ve bu sırada Redis yanıt vermez.","since":"Redis 7.0","note":"Linux'ta vm.overcommit_memory=1 ve transparent huge pages kapalı olması Redis'in resmi önerisidir. aof_delayed_fsync artıyorsa disk fsync'e yetişemiyor demektir (appendfsync everysec). Hata ayrıntısı Redis log'undadır ('Background saving error', 'Can't save in background: fork').","tags":["misconf","bgsave","aof","fork","persistence","kalıcılık"]},{"id":"aof-repair","task":"Bozuk AOF yüzünden açılmayan Redis'i onar (redis-check-aof, redis-check-rdb)","category":"Kalıcılık","command":"# Redis kapaliyken, once dosyalarin kopyasini al:\ncp -a /var/lib/redis/appendonlydir /var/lib/redis/appendonlydir.bak\n# Kontrol (7.0+ multi-part AOF: manifest dosyasi verilir):\nredis-check-aof /var/lib/redis/appendonlydir/appendonly.aof.manifest\n# Ilk bozuk noktadan sonrasini kirparak onar (onay sorar):\nredis-check-aof --fix /var/lib/redis/appendonlydir/appendonly.aof.manifest\n# RDB dosyasini dogrula:\nredis-check-rdb /var/lib/redis/dump.rdb","what":"AOF dosyalarını (base + incr + manifest) ve RDB dosyasını doğrular; AOF'un sonundaki yarım kalmış veya bozuk kısmı kırparak Redis'in tekrar açılabilmesini sağlar.","when":"Elektrik kesintisi, disk dolması veya ani kapanma sonrası Redis 'Bad file format reading the append only file' ya da 'Unexpected EOF' hatasıyla başlamadığında.","caution":"--fix ilk bozuk noktadan dosya sonuna kadar her şeyi siler; bozulma dosyanın ortasındaysa sonrasındaki tüm yazmalar kaybolur. Kırpılacak bayt miktarını onaydan önce çıktıda (ok_up_to, diff) kontrol et. Yarım kalan son komut (ör. büyük bir HSET) tamamen atılır. Her zaman önce kopya al.","since":"Redis 7.0","note":"aof-load-truncated yes (varsayılan) iken yalnızca sondan kesilmiş AOF, başlangıçta otomatik kırpılarak yüklenir; redis-check-aof genelde dosyanın ortasında bozulma olduğunda gerekir. 7.0+ multi-part AOF'ta dosyalar appenddirname dizinindedir ve base dosyası RDB formatında olabilir. Bozuk RDB için redis-check-rdb yalnızca teşhis yapar, onarmaz.","tags":["aof","redis-check-aof","bozuk","corrupt","repair","redis-check-rdb"]},{"id":"replication-backlog","task":"Replikasyon kopmasını ve sonsuz full resync döngüsünü çöz (backlog, replica buffer)","category":"Replikasyon","command":"INFO replication\n# Master: connected_slaves, slaveN:...,state=online,offset=,lag=  Replika: master_link_status, master_last_io_seconds_ago, master_sync_in_progress\nINFO stats\n# sync_full / sync_partial_ok / sync_partial_err: tekrarlayan full sync = backlog yetersiz\nCONFIG GET repl-backlog-size\nCONFIG SET repl-backlog-size 256mb\n# Full sync sirasinda replika buffer'i limiti asarsa baglanti kopar ve sync bastan baslar:\nCONFIG GET client-output-buffer-limit\nCONFIG SET client-output-buffer-limit \"replica 1gb 512mb 120\"","what":"Master ve replika tarafında link durumunu, offset farkını ve partial/full sync sayaçlarını gösterir; kısa kopmaların full sync'e dönmemesi için replication backlog'u, full sync'in yarıda kesilmemesi için replica output buffer limitini büyütür.","when":"Replika sürekli 'MASTER <-> REPLICA sync started' döngüsüne girdiğinde, sync_full sayacı arttığında veya master log'unda 'scheduled to be closed ASAP for overcoming of output buffer limits' görüldüğünde.","caution":"Her full sync master'da fork + RDB üretimi demektir; döngü master'ın belleğini ve diskini zorlar. repl-backlog-size master belleğinden ayrılır. Replica buffer limitini büyütmek, full sync sırasında master'da o kadar ek bellek kullanılabileceği anlamına gelir; maxmemory hesabına dahil et. Değişiklikleri kalıcı yapmak için CONFIG REWRITE veya redis.conf gerekir.","since":"Redis 4.0","note":"Backlog boyutu için kaba hesap: master'ın saniyedeki yazma hacmi (master_repl_offset artışı) x tolere edilecek kopma süresi. client-output-buffer-limit'te 'replica' sınıf adı 5.0+ ile 'slave' yerine kabul edilir; CONFIG GET çıktısında hâlâ slave görünebilir. Disk yavaşsa repl-diskless-sync yes (7.0+ varsayılan) RDB'yi diske yazmadan soket üzerinden aktarır.","tags":["replication","backlog","full sync","psync","replikasyon","output buffer"]},{"id":"sentinel-status","task":"Sentinel durumunu, mevcut master'ı ve quorum'u kontrol et","category":"Sentinel","command":"redis-cli -p 26379 SENTINEL MASTERS\nredis-cli -p 26379 SENTINEL GET-MASTER-ADDR-BY-NAME mymaster\nredis-cli -p 26379 SENTINEL REPLICAS mymaster\nredis-cli -p 26379 SENTINEL SENTINELS mymaster\n# Failover icin yeterli sentinel (quorum ve majority) var mi:\nredis-cli -p 26379 SENTINEL CKQUORUM mymaster\nredis-cli -p 26379 INFO sentinel","what":"Sentinel'in izlediği master'ları, güncel master adresini, bilinen replikaları ve diğer sentinel'leri listeler; failover için gereken quorum ve majority'nin sağlanıp sağlanmadığını doğrular.","when":"Uygulama yanlış düğüme bağlandığında, failover sonrası topolojiyi doğrularken ve her bakım öncesinde.","caution":"Her sentinel kendi görüşünü raporlar; tüm sentinel'lerde GET-MASTER-ADDR-BY-NAME aynı adresi dönmeli, farklıysa ağ bölünmesi veya yapılandırma tutarsızlığı vardır. flags alanında s_down/o_down veya replikada disconnected görmek acil incelenmeli. Sentinel portu (26379) güvenlik duvarında yalnızca sentinel'ler ve client'lar arasında açık olmalıdır.","since":"Redis 5.0","note":"SENTINEL REPLICAS 5.0 ile SENTINEL SLAVES'in yerine geldi (eski ad hâlâ çalışır). Sentinel sayısı tek ve en az 3 olmalı, farklı hata alanlarına (host/rack/AZ) dağıtılmalıdır. Sentinel ACL/şifre kullanıyorsa sentinel.conf'ta sentinel auth-user/auth-pass tanımlı olmalıdır.","tags":["sentinel","master","quorum","ckquorum","topoloji","failover"],"untested":true},{"id":"sentinel-failover","task":"Sentinel ile manuel failover yap ve topolojiyi temizle","category":"Sentinel","command":"# Once quorum ve uygun replika kontrolu:\nredis-cli -p 26379 SENTINEL CKQUORUM mymaster\nredis-cli -p 26379 SENTINEL REPLICAS mymaster\n# Diger sentinel'lerin onayini beklemeden manuel failover:\nredis-cli -p 26379 SENTINEL FAILOVER mymaster\n# Yeni master'i dogrula (tum sentinel'lerde ayni olmali):\nredis-cli -p 26379 SENTINEL GET-MASTER-ADDR-BY-NAME mymaster\n# Eski/kaldirilmis replikalar listede kaldiysa, sentinel'leri tek tek ve 30 sn arayla sifirla:\nredis-cli -p 26379 SENTINEL RESET mymaster","what":"Master sağlıklıyken bile master rolünü en uygun replikaya devreder; sonrasında yeni master'ı doğrular ve artık var olmayan replikaları sentinel'lerin hafızasından temizler.","when":"Master'ın bulunduğu host'ta planlı bakım öncesinde, failover tatbikatında veya master'ı başka bir veri merkezine taşırken.","caution":"Failover sırasında birkaç saniyelik yazma kesintisi olur ve master'a yazılıp replikaya ulaşmamış veri kaybolabilir. replica-priority 0 olan replikalar seçilmez; uygun replika yoksa komut hata döner. SENTINEL RESET tüm sentinel'lerde aynı anda çalıştırılırsa topoloji bilgisi geçici olarak kaybolur; her birinde ayrı ve arayla çalıştır. Client'ların master adresini sentinel'den sorgulayan bir driver kullandığından emin ol.","since":"Redis 5.0","note":"Sentinel FAILOVER diğer sentinel'lerden onay istemez ama yeni config epoch'u yayar. Seçim sırası: replica-priority (düşük önce), replikasyon offset'i (büyük önce), run ID. Failover sonrası eski master geri geldiğinde sentinel onu otomatik olarak yeni master'ın replikası yapar.","tags":["sentinel","failover","manuel failover","master","reset","switchover"],"untested":true},{"id":"cluster-check-fix","task":"Cluster sağlığını kontrol et ve slot tutarsızlığını onar (--cluster check/fix)","category":"Cluster","command":"redis-cli -h node1 -p 6379 CLUSTER INFO\nredis-cli -h node1 -p 6379 CLUSTER NODES\nredis-cli -h node1 -p 6379 CLUSTER SHARDS\n# Slot kapsamasi, acik (migrating/importing) slot ve dugum tutarliligi:\nredis-cli --cluster check node1:6379\n# Acik veya sahipsiz slot varsa onar:\nredis-cli --cluster fix node1:6379\n# Bir key hangi slot ve dugumde (-c: yonlendirmeyi takip et):\nredis-cli -h node1 -p 6379 CLUSTER KEYSLOT kullanici:1001\nredis-cli -c -h node1 -p 6379 GET kullanici:1001","what":"Tüm düğümlerin aynı slot haritasını gördüğünü, 16384 slot'un tamamının atanmış olduğunu ve yarım kalmış (migrating/importing) slot olmadığını kontrol eder; bulunan sorunları düzeltir ve bir key'in hangi slot/düğümde olduğunu gösterir.","when":"cluster_state:fail görüldüğünde, client'lar CLUSTERDOWN veya sürekli MOVED/ASK hatası aldığında ve yarıda kesilen bir reshard sonrasında.","caution":"--cluster fix sahipsiz slot'ları rastgele düğümlere atayabilir ve açık slot'larda key taşıyabilir; önce check çıktısını incele. Bir master ve tüm replikaları kaybolduysa o slot'lardaki veri gitmiştir, fix yalnızca slot'u boş olarak başka düğüme atar. cluster-require-full-coverage yes (varsayılan) iken tek bir sahipsiz slot tüm cluster'ı yazmaya kapatır.","since":"Redis 7.0","note":"CLUSTER SHARDS 7.0 ile geldi ve CLUSTER SLOTS'un yerini alır. Kimlik doğrulama varsa --cluster komutlarına -a <şifre> veya --user/--pass ekle. CLUSTER NODES çıktısındaki fail/pfail bayrakları düğümün diğerlerince erişilemez görüldüğünü gösterir.","tags":["cluster","check","fix","slot","clusterdown","cluster nodes"],"untested":true},{"id":"cluster-reshard","task":"Cluster'a düğüm ekle, slot taşı ve düğüm çıkar (add-node, reshard, rebalance)","category":"Cluster","command":"# Yeni master'i cluster'a ekle (bos, slot'suz katilir):\nredis-cli --cluster add-node node7:6379 node1:6379\n# Yeni replikayi belirli bir master'a bagla:\nredis-cli --cluster add-node node8:6379 node1:6379 --cluster-slave --cluster-master-id <master-node-id>\n# 1000 slot'u tum master'lardan yeni dugume tasi:\nredis-cli --cluster reshard node1:6379 --cluster-from all --cluster-to <node7-id> --cluster-slots 1000 --cluster-yes\n# Ya da otomatik dengele (bos master'lara da slot ver):\nredis-cli --cluster rebalance node1:6379 --cluster-use-empty-masters\n# Slot'lari bosaltilmis dugumu cikar:\nredis-cli --cluster del-node node1:6379 <node-id>","what":"Cluster'a yeni master veya replika ekler, slot'ları ve içindeki key'leri düğümler arasında online taşır, slot dağılımını otomatik dengeler ve boşaltılmış düğümü cluster'dan çıkarır.","when":"Bellek/throughput kapasitesini yatay büyütürken, sıcak bir düğümün yükünü dağıtırken veya bir düğümü hizmetten alırken.","caution":"Slot taşıma key'leri MIGRATE ile tek tek aktarır; büyük key'ler taşınırken iki düğüm de kısa süre bloklanabilir. Taşıma sırasında client'lar ASK yönlendirmesi alır; cluster destekli bir client gerekir. Reshard yarıda kesilirse slot'lar migrating/importing durumda kalır; --cluster fix ile tamamla. Slot'u olan bir master'ı del-node ile çıkarma; önce slot'larını taşı.","since":"Redis 5.0","note":"Node ID'leri CLUSTER NODES veya CLUSTER MYID ile alınır. --cluster-pipeline ile her MIGRATE çağrısında taşınan key sayısı ayarlanır (varsayılan 10). --cluster rebalance --cluster-weight ile düğümlere farklı ağırlık verilebilir. redis-cli --cluster komutları 5.0 ile redis-trib.rb'nin yerini aldı.","tags":["cluster","reshard","rebalance","add-node","slot","del-node"],"untested":true},{"id":"acl-users","task":"ACL kullanıcıları oluştur, yetkiyi test et ve kalıcı yap","category":"Güvenlik","command":"# Uygulama kullanicisi: yalnizca app:* key'leri ve kanallari, tehlikeli komutlar haric:\nACL SETUSER app_rw on >S3cret-Change ~app:* resetchannels &app:* +@read +@write -@dangerous\n# Izleme kullanicisi: key erisimi yok, yalnizca belirli komutlar:\nACL SETUSER monitor on >M0n-Secret resetkeys resetchannels -@all +info +ping +client|list +slowlog|get +latency +config|get\n# Komutu calistirmadan yetkiyi test et:\nACL DRYRUN app_rw GET app:1001\nACL GETUSER app_rw\nACL LIST\n# Kalici yap: aclfile tanimliysa ACL SAVE, degilse redis.conf'a CONFIG REWRITE\nACL SAVE","what":"Key prefix'i, pub/sub kanalı ve komut kategorisi bazında yetkilendirilmiş uygulama ve izleme kullanıcıları oluşturur; DRYRUN ile bir komutun izinli olup olmadığını çalıştırmadan test eder ve ACL'leri diske yazar.","when":"Tek şifreli (requirepass) yapıdan kullanıcı bazlı erişime geçerken, uygulamaları birbirinin key'lerinden izole ederken veya izleme aracına salt okunur hesap açarken.","caution":"Kural sırası önemlidir: resetchannels kendisinden önce verilen &kanal kurallarını siler. -@dangerous KEYS, FLUSHALL, CONFIG, DEBUG gibi komutları da kapatır; uygulamanın kullandığı komutları DRYRUN ile doğrula. default kullanıcı nopass ve +@all ile açık kalırsa ACL'ler koruma sağlamaz; yönetici kullanıcıyı oluşturduktan sonra ACL SETUSER default off yap. redis-cli'de --user/--pass ile AUTH başarısız olursa bağlantı default kullanıcıyla devam eder ve komut yine çalışır; yetki testlerini bu yüzden DRYRUN ile yap.","since":"Redis 7.0","note":"ACL'ler 6.0 ile geldi; ACL DRYRUN, selector'lar ve alt komut kuralları (client|list) 7.0 ile eklendi. aclfile ile redis.conf içindeki user satırları birlikte kullanılamaz. Şifreler SHA-256 hash olarak saklanır; ACL GETUSER düz şifreyi göstermez.","tags":["acl","setuser","kullanıcı","yetki","dryrun","security"]},{"id":"acl-log-denied","task":"NOPERM ve WRONGPASS hatalarını incele (ACL LOG)","category":"Güvenlik","command":"# Son 10 yetki reddi ve hatali giris (reason: auth/command/key/channel):\nACL LOG 10\n# Bu baglantinin kullanicisi:\nACL WHOAMI\n# Kumulatif red sayaclari:\nINFO stats\n# acl_access_denied_auth, acl_access_denied_cmd, acl_access_denied_key, acl_access_denied_channel\nACL LOG RESET","what":"Reddedilen komut, key, kanal erişimlerini ve başarısız AUTH denemelerini; kullanıcı adı, nesne, tekrar sayısı ve client bilgisi (IP, son komut) ile listeler; kümülatif red sayaçlarını gösterir.","when":"Uygulama deploy sonrası NOPERM veya WRONGPASS hatası aldığında, ACL kuralı daraltıldıktan sonra kırılan komutu bulmak veya şifre deneme saldırısını tespit etmek için.","caution":"ACL LOG bellekte tutulur, restart'ta silinir ve acllog-max-len (varsayılan 128) girdiyle sınırlıdır; aynı hata tekrarlandığında count artar, yeni satır açılmaz. client-info alanı istemcinin IP'sini ve kullandığı kullanıcıyı içerir; reset öncesinde gerekli bilgiyi kaydet.","since":"Redis 7.0","note":"acl_access_denied_* sayaçları 7.2 ile INFO stats'a eklendi; izleme sistemine bağlanarak artış alarmı kurulabilir. entry-id ve timestamp-created/last-updated alanları 7.2 ile geldi. Yanlış şifre denemeleri reason=auth, eksik komut yetkisi reason=command olarak görünür.","tags":["acl log","noperm","wrongpass","yetki reddi","auth","security"]},{"id":"keyspace-notifications","task":"Keyspace notifications ile key silinme ve expire olaylarını izle","category":"Bakım","command":"CONFIG GET notify-keyspace-events\n# E: keyevent kanali, x: expire olaylari, g: genel komutlar (DEL, EXPIRE, RENAME):\nCONFIG SET notify-keyspace-events Exg\n# db 0'daki expire ve del olaylarini dinle:\nredis-cli -h redis1 -p 6379 --csv PSUBSCRIBE '__keyevent@0__:expired' '__keyevent@0__:del'\n# Kapat:\nCONFIG SET notify-keyspace-events \"\"","what":"Key'ler üzerindeki olayları (expire, del, set vb.) pub/sub kanallarına yayınlatır; böylece hangi key'in ne zaman silindiği veya süresinin dolduğu canlı izlenebilir.","when":"Key'lerin 'kendiliğinden kaybolduğu' şikâyetinde silen komutu veya expire'ı kanıtlamak, ya da expire olayına bağlı iş akışlarını (oturum kapanışı) beslemek için.","caution":"Olaylar CPU ve ağ yükü getirir; özellikle 'A' (tüm sınıflar) yoğun sistemlerde pahalıdır, yalnızca gereken sınıfları aç ve iş bitince kapat. Pub/sub fire-and-forget'tir: bağlı olmayan abone olayı kaçırır, kalıcı değildir. expired olayı TTL anında değil, key gerçekten silindiğinde (erişimde veya arka plan expire döngüsünde) üretilir.","since":"Redis 2.8","note":"Eviction ile silinen key'ler için e (evicted) sınıfını ekle. Cluster'da olaylar yalnızca key'in bulunduğu düğümde yayınlanır; her master'a ayrı abone ol. Kalıcı ayar için redis.conf'ta notify-keyspace-events tanımla.","tags":["keyspace notifications","notify-keyspace-events","expired","pubsub","olay","psubscribe"]}]},"recipes/elasticsearch.json":{"engineId":"elasticsearch","engine":"Elasticsearch","order":7,"recipes":[{"id":"flush","task":"Index'i flush et","category":"Index Yaşam Döngüsü","command":"POST /musteri/_flush","what":"Lucene commit yapar: bellekteki indeksleme verisini segment olarak diske kalıcı yazar ve artık gerekmeyen translog kayıtlarını kırpar.","when":"Bakım veya yeniden başlatma öncesi translog'u küçültmek için.","caution":"Genellikle otomatik yapılır; manuel flush sırasında hafif IO artışı olur.","tags":["flush","translog","index","musteri","bakim"]},{"id":"force-merge","task":"Index segmentlerini birleştir (force merge)","category":"Index Yaşam Döngüsü","command":"POST /musteri/_forcemerge?max_num_segments=1","what":"Index segmentlerini birleştirerek segment sayısını düşürür ve okuma performansını artırır.","when":"Yalnızca yazımı bitmiş (read-only) index'lerde, sorgu performansını iyileştirmek için.","caution":"Yoğun IO ve CPU tüketir; aktif yazılan index'lerde asla çalıştırmayın, uzun sürebilir ve iptal edilemez.","tags":["forcemerge","segment","merge","birlestir","performans"]},{"id":"rollover","task":"Alias üzerinden rollover yap","category":"Index Yaşam Döngüsü","command":"POST /musteri-alias/_rollover\n{\n  \"conditions\": {\n    \"max_age\": \"7d\",\n    \"max_docs\": 100000000,\n    \"max_primary_shard_size\": \"50gb\"\n  }\n}","what":"Alias'ın işaret ettiği yazma index'i koşulları sağladığında yeni bir index oluşturup alias'ı ona yönlendirir.","when":"Zaman serisi verilerinde index boyutunu yönetmek için (ILM alternatifi/tamamlayıcısı).","caution":"Alias'ın is_write_index ile tek yazma index'ine sahip olması gerekir; yanlış yapılandırma rollover'ı engeller.","tags":["rollover","alias","index","zamanserisi","ilm"]},{"id":"set-refresh-interval","task":"Refresh aralığını değiştir","category":"Index Yaşam Döngüsü","command":"PUT /musteri/_settings\n{\n  \"index\": { \"refresh_interval\": \"30s\" }\n}","what":"Index'in yeni belgeleri aranabilir hale getirme (refresh) sıklığını ayarlar.","when":"Toplu yükleme (bulk) sırasında indeksleme hızını artırmak için aralığı büyütürken.","caution":"-1 refresh'i tamamen kapatır; belgeler aranabilir olmaz. Yükleme sonrası tekrar makul bir değere alın.","tags":["refresh","interval","settings","bulk","aralik"]},{"id":"set-replicas","task":"Replika sayısını değiştir","category":"Index Yaşam Döngüsü","command":"PUT /musteri/_settings\n{\n  \"index\": { \"number_of_replicas\": 2 }\n}","what":"Index'in replika shard sayısını dinamik olarak değiştirir.","when":"Yedekliliği veya okuma kapasitesini artırmak/azaltmak için.","caution":"Replika artırmak ek disk ve ağ trafiği (recovery) oluşturur; 0'a düşürmek yedekliliği kaldırır.","tags":["replica","settings","number_of_replicas","yedek","kapasite"]},{"id":"open-close-index","task":"Index'i aç veya kapat","category":"Index Yaşam Döngüsü","command":"POST /musteri/_close\nPOST /musteri/_open","what":"Index'i kapatarak okuma/yazmaya kapatır (kaynak serbest bırakır) veya tekrar açar.","when":"Nadiren kullanılan index'lerin kaynak tüketimini azaltmak veya bazı ayarları değiştirmek için.","caution":"Kapalı index sorgulanamaz ve yazılamaz; kapalıyken snapshot dışında erişilemez.","tags":["open","close","index","ac","kapat"]},{"id":"node-join-note","task":"Cluster'a düğüm ekle","category":"Cluster/Node","command":"GET /_cat/nodes?v","what":"Yeni düğümün elasticsearch.yml'de aynı cluster.name ve doğru discovery.seed_hosts ile başlatılması yeterlidir; bu komut düğümün katıldığını doğrular.","when":"Cluster'a yeni bir düğüm eklerken katılımı doğrulamak için.","caution":"7.0+ sürümlerde minimum_master_nodes yoktur; oylama yapılandırması (voting configuration) otomatik yönetilir. Master-eligible düğümleri tek tek ekleyip çıkarın, aynı anda yarısını veya daha fazlasını kaldırmayın; birden fazla master-eligible düğümü kalıcı olarak çıkarırken önce POST _cluster/voting_config_exclusions?node_names=... kullanın.","tags":["node","join","cluster","cat","dugum"]},{"id":"node-decommission","task":"Düğümü boşalt (decommission)","category":"Cluster/Node","command":"PUT /_cluster/settings\n{\n  \"persistent\": {\n    \"cluster.routing.allocation.exclude._name\": \"node-3\"\n  }\n}","what":"Belirtilen düğümdeki shard'ları diğer düğümlere taşıyarak düğümü güvenle boşaltır.","when":"Bir düğümü hizmetten almadan önce verisini boşaltmak için.","caution":"Shard taşıması yoğun ağ/IO oluşturur; kalan düğümlerde yeterli disk ve kapasite olduğundan emin olun. Düğüm çıkarıldıktan sonra ayarı null ile kaldırın. transient ayarlar 7.16'dan beri deprecated'dır; persistent kullanın.","tags":["decommission","exclude","allocation","bosalt","dugum"]},{"id":"reroute-shard","task":"Shard'ı manuel taşı (reroute)","category":"Cluster/Node","command":"POST /_cluster/reroute\n{\n  \"commands\": [\n    {\n      \"move\": {\n        \"index\": \"musteri\",\n        \"shard\": 0,\n        \"from_node\": \"node-1\",\n        \"to_node\": \"node-2\"\n      }\n    }\n  ]\n}","what":"Belirli bir shard'ı bir düğümden diğerine manuel olarak taşır.","when":"Dengesiz shard dağılımını düzeltmek veya belirli bir düğümü boşaltmak için.","caution":"Otomatik dengeleme ile çakışabilir; büyük shard taşıması ağ ve IO yükü oluşturur.","tags":["reroute","shard","move","tasi","cluster"]},{"id":"allocation-enable","task":"Shard allocation'ı aç veya kapat","category":"Cluster/Node","command":"PUT /_cluster/settings\n{\n  \"persistent\": {\n    \"cluster.routing.allocation.enable\": \"primaries\"\n  }\n}","what":"Cluster genelinde shard allocation'ı kısıtlar (primaries: yalnız primary'ler atanır, none: hiçbiri) veya varsayılana (all / null) döndürür.","when":"Rolling restart öncesi gereksiz replica taşımalarını önlemek için (resmi önerilen değer \"primaries\").","caution":"İşlem sonrası ayarı null (veya \"all\") ile geri almayı unutmayın; kısıtlı kalırsa replica'lar unassigned kalır. transient ayarlar deprecated'dır; persistent kullanın.","tags":["allocation","enable","restart","shard","cluster"]},{"id":"cluster-settings","task":"Cluster ayarını değiştir","category":"Cluster/Node","command":"PUT /_cluster/settings\n{\n  \"persistent\": {\n    \"indices.recovery.max_bytes_per_sec\": \"100mb\"\n  }\n}","what":"Cluster genelinde kalıcı (persistent) veya geçici (transient) bir ayarı değiştirir.","when":"Recovery hızı gibi cluster davranışlarını ayarlarken.","caution":"persistent ayarlar yeniden başlatmada korunur; transient ayarlar kaybolur ve 7.16'dan beri deprecated'dır, kullanmayın. Bir ayarı varsayılana döndürmek için değerini null verin. Yanlış değer cluster kararlılığını etkiler.","tags":["cluster","settings","persistent","transient","ayar"]},{"id":"snapshot-repo","task":"Snapshot deposu tanımla","category":"Snapshot","command":"PUT /_snapshot/yedek_repo\n{\n  \"type\": \"fs\",\n  \"settings\": {\n    \"location\": \"/mnt/es_backups\"\n  }\n}","what":"Snapshot'ların saklanacağı bir depo (repository) kaydeder.","when":"Yedekleme altyapısını ilk kez kurarken.","caution":"fs tipi depo yolu tüm master ve data düğümlerinde path.repo ile tanımlı ve erişilebilir olmalıdır.","tags":["snapshot","repository","repo","yedek","tanimla"]},{"id":"snapshot-create","task":"Snapshot al","category":"Snapshot","command":"PUT /_snapshot/yedek_repo/snap1?wait_for_completion=false\n{\n  \"indices\": \"musteri\",\n  \"include_global_state\": false\n}","what":"Belirtilen index'lerin anlık yedeğini (snapshot) depoya alır.","when":"Düzenli yedekleme veya büyük değişiklik öncesi güvenlik yedeği için.","caution":"wait_for_completion=true büyük index'lerde HTTP bağlantısını uzun süre bekletir; büyük snapshot'larda false kullanın.","tags":["snapshot","create","backup","yedek","al"]},{"id":"snapshot-restore","task":"Snapshot'tan geri yükle","category":"Snapshot","command":"POST /_snapshot/yedek_repo/snap1/_restore\n{\n  \"indices\": \"musteri\",\n  \"rename_pattern\": \"musteri\",\n  \"rename_replacement\": \"musteri_restored\"\n}","what":"Bir snapshot'taki index'leri cluster'a geri yükler (isteğe bağlı yeniden adlandırarak).","when":"Veri kaybı sonrası kurtarma veya bir yedeği test ortamına taşırken.","caution":"Aynı isimle geri yükleme için hedef index kapalı veya silinmiş olmalı; açık index'in üzerine restore yapılamaz.","tags":["snapshot","restore","gerialma","kurtarma","yedek"]},{"id":"cache-clear","task":"Cache'i temizle","category":"Bakım","command":"POST /musteri/_cache/clear","what":"Index'in query, request ve fielddata cache'lerini temizler.","when":"Bellek baskısını azaltmak veya fielddata sorunlarını gidermek için.","caution":"Cache temizlendikten sonra ilk sorgular yeniden ısınana kadar daha yavaş çalışır.","tags":["cache","clear","temizle","fielddata","bakim"]},{"id":"pending-tasks","task":"Bekleyen cluster görevlerini gör","category":"Bakım","command":"GET /_cluster/pending_tasks","what":"Master düğümde işlenmeyi bekleyen cluster seviyesindeki görevleri listeler.","when":"Cluster yavaşladığında veya güncellemeler takıldığında master yükünü teşhis etmek için.","caution":"Salt okunur komuttur; risk yoktur.","tags":["pending","tasks","master","tani","bekleyen"]},{"id":"hot-threads","task":"Hot threads analizini al","category":"Bakım","command":"GET /_nodes/hot_threads","what":"Düğümlerde en çok CPU tüketen thread'lerin stack trace'lerini gösterir.","when":"Yüksek CPU kullanımının kaynağını teşhis ederken.","caution":"Salt okunur komuttur; çıktı uzun olabilir, thread_type parametresiyle daraltabilirsiniz.","tags":["hotthreads","cpu","tani","thread","performans"]},{"id":"cat-shards","task":"Shard dağılımını gör","category":"Bakım","command":"GET /_cat/shards?v&s=state","what":"Tüm shard'ları; index, tip (primary/replica), durum ve bulunduğu düğüm ile listeler.","when":"Shard yerleşimini ve unassigned shard'ları incelerken.","caution":"Salt okunur komuttur; risk yoktur.","tags":["cat","shards","dagilim","durum","shard"]},{"id":"allocation-explain","task":"Unassigned shard nedenini bul","category":"Bakım","command":"GET /_cluster/allocation/explain\n{\n  \"index\": \"musteri\",\n  \"shard\": 0,\n  \"primary\": true\n}","what":"Belirli bir shard'ın neden atanamadığını (unassigned) ayrıntılı olarak açıklar.","when":"Sarı/kırmızı cluster durumunda atanamayan shard'ların nedenini bulurken.","caution":"Salt okunur teşhis komutudur; risk yoktur.","tags":["allocation","explain","unassigned","tani","shard"]},{"id":"cluster-health","task":"Cluster sağlığını gör","category":"Bakım","command":"GET /_cluster/health","what":"Cluster'ın genel sağlığını (green/yellow/red), aktif ve unassigned shard sayısını gösterir.","when":"Cluster durumunu hızlıca kontrol ederken.","caution":"Salt okunur komuttur; risk yoktur.","tags":["cluster","health","saglik","durum","green"]},{"id":"refresh-index","task":"Index'i manuel refresh et","category":"Index Yaşam Döngüsü","command":"POST /musteri/_refresh","what":"Index'te bekleyen değişiklikleri hemen aranabilir hale getirir.","when":"Toplu yükleme sonrası verinin anında sorgulanabilir olmasını istediğinizde.","caution":"Sık manuel refresh çok sayıda küçük segment üreterek performansı düşürebilir.","tags":["refresh","index","ara","segment","musteri"]}]},"recipes/elasticsearch-ext.json":{"engineId":"elasticsearch","engine":"Elasticsearch","order":2,"recipes":[{"id":"red-yellow-triage","task":"Red/yellow cluster teşhis akışı (hangi index, hangi shard, neden)","category":"Cluster/Node","command":"GET _cluster/health?filter_path=status,unassigned_shards,initializing_shards,delayed_unassigned_shards,number_of_pending_tasks\nGET _health_report?verbose=false\nGET _cat/indices?v&health=red&h=health,index,pri,rep,docs.count,store.size\nGET _cat/indices?v&health=yellow&h=health,index,pri,rep\nGET _cat/shards?v&h=index,shard,prirep,state,unassigned.reason,unassigned.for,node&s=state\n# Govdesiz cagri ilk unassigned shard'i aciklar:\nGET _cluster/allocation/explain","what":"Cluster durumundan başlayıp sorunlu index'lere, oradan unassigned shard'lara ve atanamama nedenine (unassigned.reason, allocation explain) inen sıralı bir teşhis akışı verir; _health_report hangi göstergenin (disk, shard availability, master) sorunlu olduğunu özetler.","when":"Cluster red veya yellow olduğunda ilk müdahale olarak.","caution":"Red: en az bir primary shard atanmamış, o index'e yazma ve o shard'a düşen aramalar başarısız olur. Yellow: tüm primary'ler var ama replica eksik; veri erişilebilir ama yedeklilik yok. Tek düğümlü cluster'da replica > 0 olan index'ler kalıcı olarak yellow kalır (same_shard kararı). Düğüm yeni ayrıldıysa delayed_unassigned_shards, index.unassigned.node_left.delayed_timeout (varsayılan 1m) dolana kadar bilerek bekletilir.","since":"Elasticsearch 8.7","note":"_health_report 8.7 ile geldi; daha eski sürümlerde ilk dört adımı kullan. unassigned.reason değerleri: NODE_LEFT (düğüm ayrıldı), ALLOCATION_FAILED (deneme limiti doldu, bkz. retry-failed-allocation), INDEX_CREATED, CLUSTER_RECOVERED. Belirli shard için index/shard/primary gövdesiyle allocation-explain reçetesini kullan.","tags":["red","yellow","cluster health","unassigned","health report","teşhis"]},{"id":"retry-failed-allocation","task":"Deneme limitine takılan shard'ları yeniden ata (reroute retry_failed)","category":"Cluster/Node","command":"# Deneme sayisi ve son hata ayrintisi:\nGET _cluster/allocation/explain?filter_path=index,shard,unassigned_info.reason,unassigned_info.failed_allocation_attempts,unassigned_info.details,allocate_explanation\n# Nedeni giderdikten sonra limiti dolan shard'lari yeniden dene:\nPOST _cluster/reroute?retry_failed=true&metric=none\n# Recovery ilerlemesi:\nGET _cat/recovery?v&active_only=true&h=index,shard,stage,source_node,target_node,bytes_percent,translog_ops_percent","what":"Ardışık hatalar yüzünden allocation denemesi durdurulmuş (ALLOCATION_FAILED, max_retry) shard'lar için hata ayrıntısını gösterir ve allocation'ı yeniden tetikler; recovery ilerlemesini izler.","when":"allocation explain çıktısında 'shard has exceeded the maximum number of retries' görüldüğünde; disk doluluğu, bozuk translog veya geçici ağ sorunu giderildikten sonra.","caution":"Nedeni gidermeden retry_failed çalıştırmak shard'ın yine 5 kez deneyip düşmesine yol açar; önce unassigned_info.details'teki hatayı çöz. Aynı anda çok sayıda shard recovery'ye girerse ağ ve disk yükü artar; cluster.routing.allocation.node_concurrent_recoveries ve indices.recovery.max_bytes_per_sec ile sınırlanır.","since":"Elasticsearch 7.0","note":"Deneme limiti index.allocation.max_retries (varsayılan 5) ile belirlenir. Elasticsearch periyodik olarak da yeniden dener ama retry_failed beklemeyi kaldırır. metric=none yanıttaki büyük cluster state'i bastırır.","tags":["reroute","retry_failed","allocation failed","max_retries","unassigned","recovery"]},{"id":"allocate-stale-primary","task":"Kayıp primary shard'ı son çare olarak ata (allocate_stale_primary)","category":"Cluster/Node","command":"# Primary'nin kopyalari hangi dugumlerde duruyor (allocation id, store hatasi):\nGET _shard_stores/musteri?status=red\n# Son care: eski (stale) kopyayi primary yap; veri kaybi kabul edilir:\nPOST _cluster/reroute\n{\n  \"commands\": [\n    {\n      \"allocate_stale_primary\": {\n        \"index\": \"musteri\",\n        \"shard\": 0,\n        \"node\": \"node-2\",\n        \"accept_data_loss\": true\n      }\n    }\n  ]\n}","what":"Güncel primary kopyasını taşıyan düğüm kalıcı olarak kaybolduğunda, başka bir düğümde duran eski (in-sync olmayan) kopyayı primary olarak atayarak index'i red durumundan çıkarır.","when":"Yalnızca primary'yi barındıran düğüm geri getirilemeyecekse ve snapshot'tan restore seçeneği yoksa veya daha uzun sürecekse.","caution":"Stale kopya en son yazmaları içermez; o kopyadan sonra yapılan tüm yazmalar kalıcı olarak kaybolur. Kayıp düğüm sonradan geri gelirse onun üzerindeki daha güncel kopya silinir. Önce düğümü kurtarmayı ve snapshot restore'u değerlendir. allocate_empty_primary ise shard'ı tamamen boş oluşturur ve o shard'daki tüm veriyi siler; yalnızca hiçbir kopya kalmadığında kullanılır.","since":"Elasticsearch 7.0","note":"_shard_stores çıktısında allocation türü 'primary', 'replica' veya 'unused' olarak görünür; store_exception içeren kopyaları seçme. Komutu ?dry_run=true&explain=true ile önce kararları görerek çalıştırabilirsin. İşlem sonrası veri kaybını uygulama tarafında yeniden indexleme ile kapat.","tags":["allocate_stale_primary","red","primary","veri kaybı","shard_stores","reroute"],"untested":true},{"id":"disk-watermark","task":"Disk watermark'larını yönet ve flood-stage yazma kilidini kaldır","category":"Cluster/Node","command":"GET _cat/allocation?v&h=node,shards,disk.indices,disk.used,disk.avail,disk.percent&s=disk.percent:desc\nGET _cluster/settings?include_defaults=true&filter_path=*.cluster.routing.allocation.disk\n# Gecici olarak esikleri ayarla (null ile varsayilana doner):\nPUT _cluster/settings\n{\n  \"persistent\": {\n    \"cluster.routing.allocation.disk.watermark.low\": \"85%\",\n    \"cluster.routing.allocation.disk.watermark.high\": \"90%\",\n    \"cluster.routing.allocation.disk.watermark.flood_stage\": \"95%\"\n  }\n}\n# Yer acildiktan sonra flood-stage yazma kilidini kaldir:\nPUT _all/_settings\n{\n  \"index.blocks.read_only_allow_delete\": null\n}","what":"Düğüm bazında disk doluluğunu ve geçerli watermark değerlerini gösterir; low/high/flood_stage eşiklerini ayarlar ve flood-stage'de index'lere konan read_only_allow_delete kilidini kaldırır.","when":"Yazmalar 'TOO_MANY_REQUESTS/12/disk usage exceeded flood-stage watermark, index has read-only-allow-delete block' hatasıyla reddedildiğinde, yeni shard'lar atanmadığında veya shard'lar dolu düğümden taşınmaya başladığında.","caution":"low aşılınca düğüme yeni shard atanmaz, high aşılınca shard'lar düğümden taşınır, flood_stage aşılınca o düğümde shard'ı olan index'ler salt okunur olur. Eşikleri yükseltmek yalnızca zaman kazandırır; kalıcı çözüm eski index'leri silmek, replica azaltmak veya disk/düğüm eklemektir. Disk tamamen dolarsa shard'lar bozulabilir.","since":"Elasticsearch 8.5","note":"7.4+ sürümlerde disk kullanımı high watermark'ın altına inince kilit otomatik kaldırılır; manuel kaldırma beklemeyi kısaltır. 8.5+ sürümlerde büyük disklerde yüzde yerine max_headroom (low 200GB, high 150GB, flood 100GB) ile mutlak boş alan esas alınır; bu varsayılan headroom yalnızca watermark'lar varsayılanda bırakıldığında geçerlidir, yukarıdaki gibi açıkça yüzde verilirse devre dışı kalır. Tek data düğümlü cluster'larda da watermark'lar uygulanır.","tags":["disk watermark","flood_stage","read_only_allow_delete","disk dolu","allocation","cat allocation"]},{"id":"rolling-restart","task":"Rolling restart / rolling upgrade (düğüm düğüm, gereksiz shard taşımadan)","category":"Cluster/Node","command":"# 1) Replica allocation'i kapat (yalnizca primary'ler atanir):\nPUT _cluster/settings\n{\n  \"persistent\": { \"cluster.routing.allocation.enable\": \"primaries\" }\n}\n# 2) Opsiyonel: indexing'i durdur ve flush ile recovery'yi hizlandir:\nPOST _flush\n# 3) Bir dugumu durdur, bakimi yap, baslat; katildigini dogrula:\nGET _cat/nodes?v&h=name,version,node.role,master,heap.percent\n# 4) Allocation'i geri ac:\nPUT _cluster/settings\n{\n  \"persistent\": { \"cluster.routing.allocation.enable\": null }\n}\n# 5) Siradaki dugume gecmeden green'i bekle:\nGET _cluster/health?wait_for_status=green&timeout=10m","what":"Bir düğüm kapalıyken replica'ların diğer düğümlere yeniden kopyalanmasını engelleyerek düğümleri tek tek yeniden başlatma veya yükseltme sırasını verir; düğüm döndüğünde shard'lar yerel kopyadan hızlı recovery yapar.","when":"OS patch, JVM/heap ayarı, elasticsearch.yml değişikliği veya minor/major sürüm yükseltmesi için düğümleri sırayla yeniden başlatırken.","caution":"Her düğümden sonra green'i beklemeden diğerine geçme; iki düğüm aynı anda kapalıyken bir shard'ın tüm kopyaları gidebilir. Master-eligible düğümleri en son ve tek tek yeniden başlat; çoğunluk kaybolursa cluster master seçemez. allocation.enable'ı geri açmayı unutursan replica'lar unassigned kalır. Upgrade'de önce data düğümleri (önce frozen/cold, en son hot), sonra master'lar yükseltilir.","since":"Elasticsearch 7.16","note":"ML job'ları varsa başta POST _ml/set_upgrade_mode?enabled=true, sonda enabled=false çalıştır. Synced flush 8.0'da kaldırıldı; normal _flush yeterlidir. transient ayarlar 7.16'dan beri deprecated olduğundan persistent kullan. Kısa yeniden başlatmalarda allocation kapatmak yerine index.unassigned.node_left.delayed_timeout'u artırmak da işe yarar.","tags":["rolling restart","rolling upgrade","allocation","primaries","bakım","upgrade"],"untested":true},{"id":"shard-sizing","task":"Shard boyutlarını ve shard sayısını denetle (oversharding / dev shard tespiti)","category":"Bakım","command":"# En buyuk shard'lar (GB):\nGET _cat/shards?v&h=index,shard,prirep,state,docs,store,node&s=store:desc&bytes=gb\n# Primary boyutuna gore index'ler:\nGET _cat/indices?v&h=index,pri,rep,docs.count,pri.store.size,store.size&s=pri.store.size:desc&bytes=gb\n# Dugum basina shard sayisi ve disk:\nGET _cat/allocation?v&h=node,shards,disk.indices,disk.percent&s=shards:desc\nGET _cluster/stats?filter_path=indices.shards.total,indices.shards.primaries,nodes.count.data\nGET _cluster/settings?include_defaults=true&filter_path=*.cluster.max_shards_per_node","what":"En büyük shard'ları, index'lerin primary boyutlarını, düğüm başına shard sayısını, toplam shard sayısını ve cluster.max_shards_per_node limitini listeler.","when":"Kapasite planlamasında, recovery sürelerinin uzadığı veya heap baskısının arttığı durumlarda ve 'this action would add [x] shards, but this cluster currently has [y]/[z] maximum normal shards open' hatasında.","caution":"Çok küçük ve çok sayıda shard (oversharding) master'ı ve heap'i zorlar; çok büyük shard'lar ise recovery ve rebalance'ı saatlerce uzatır. Primary shard sayısı index oluşturulduktan sonra değişmez; düzeltme için shrink, split veya reindex gerekir. max_shards_per_node'u yükseltmek limiti kaldırır ama sorunu çözmez.","since":"Elasticsearch 8.3","note":"Elastic'in genel önerisi: shard başına 10-50 GB ve en fazla yaklaşık 200 milyon belge. 8.3+ sürümlerde eski 'GB heap başına 20 shard' kuralının yerini mapping'deki alan sayısına dayalı heap hesabı aldı. Zaman serisinde shard boyutunu rollover'daki max_primary_shard_size ile sabitle.","tags":["shard size","oversharding","cat shards","max_shards_per_node","kapasite","boyut"]},{"id":"shrink-index","task":"Fazla shard'lı index'i küçült (shrink)","category":"Index Yaşam Döngüsü","command":"# 1) Kaynagi yazmaya kapat ve tum shard kopyalarini tek dugumde topla:\nPUT log-2026.09/_settings\n{\n  \"index.number_of_replicas\": 0,\n  \"index.routing.allocation.require._name\": \"node-1\",\n  \"index.blocks.write\": true\n}\nGET _cluster/health/log-2026.09?wait_for_no_relocating_shards=true&timeout=30m\n# 2) Daha az shard'li yeni index olustur (hedef sayi kaynagin bolenleri olmali):\nPOST log-2026.09/_shrink/log-2026.09-shrunk\n{\n  \"settings\": {\n    \"index.number_of_shards\": 1,\n    \"index.number_of_replicas\": 1,\n    \"index.routing.allocation.require._name\": null,\n    \"index.blocks.write\": null,\n    \"index.codec\": \"best_compression\"\n  }\n}","what":"Yazımı bitmiş bir index'in primary shard sayısını, segment'leri hard-link ile yeni index'e aktararak azaltır; heap ve shard sayısı yükünü düşürür.","when":"Günlük index'ler gereğinden fazla shard ile açıldığında, shard sayısı limitine yaklaşıldığında veya eski index'leri warm katmana taşımadan önce.","caution":"Kaynak index shrink boyunca yazmaya kapalıdır; yalnızca yazımı bitmiş index'lerde uygula. Hedef shard sayısı kaynak sayının böleni olmalıdır (8 -> 4, 2 veya 1). Tüm kopyaların toplandığı düğümde kaynak index kadar boş disk olmalıdır. Replica 0 iken kaynak shard'ın tek kopyası vardır; işlem bitip yeni index green olana kadar kaynağı silme.","since":"Elasticsearch 7.0","note":"Shrink sonrası kaynağı sil veya alias'ı yeni index'e çevir. Aynı düğüm aynı dosya sisteminde hard-link kullanabildiği için işlem genellikle hızlıdır; aksi halde dosyalar kopyalanır. Shard sayısını artırmak için _split, ILM ile otomatik yapmak için warm fazındaki shrink action kullanılır.","tags":["shrink","shard sayısı","oversharding","index","blocks.write","warm"]},{"id":"ilm-policy-bootstrap","task":"ILM policy tanımla, template'e bağla ve rollover zincirini başlat","category":"Index Yaşam Döngüsü","command":"PUT _ilm/policy/log-policy\n{\n  \"policy\": {\n    \"phases\": {\n      \"hot\": { \"actions\": { \"rollover\": { \"max_primary_shard_size\": \"50gb\", \"max_age\": \"1d\" }, \"set_priority\": { \"priority\": 100 } } },\n      \"warm\": { \"min_age\": \"7d\", \"actions\": { \"shrink\": { \"number_of_shards\": 1 }, \"forcemerge\": { \"max_num_segments\": 1 }, \"set_priority\": { \"priority\": 50 } } },\n      \"delete\": { \"min_age\": \"30d\", \"actions\": { \"delete\": {} } }\n    }\n  }\n}\nPUT _index_template/log\n{\n  \"index_patterns\": [\"log-*\"],\n  \"priority\": 500,\n  \"template\": {\n    \"settings\": {\n      \"number_of_shards\": 1,\n      \"number_of_replicas\": 1,\n      \"index.lifecycle.name\": \"log-policy\",\n      \"index.lifecycle.rollover_alias\": \"log\"\n    }\n  }\n}\n# Ilk index'i yazma alias'iyla olustur (adi -000001 gibi sayiyla bitmeli):\nPUT log-000001\n{\n  \"aliases\": { \"log\": { \"is_write_index\": true } }\n}","what":"hot (rollover), warm (shrink + force merge) ve delete fazlarından oluşan bir ILM policy oluşturur, yeni index'lere policy'yi ve rollover alias'ını template ile uygular ve zincirin ilk index'ini yazma alias'ıyla açar.","when":"Log/metrik gibi zaman serisi verilerinde index boyutu, saklama süresi ve silme işlerini otomatikleştirirken.","caution":"min_age warm ve delete fazlarında index'in oluşturulduğu andan değil rollover anından itibaren sayılır. Policy değişikliği mevcut index'lere yalnızca bulundukları faz bittikten sonra yansır. warm fazındaki shrink ve forcemerge yoğun IO üretir; force merge bitene kadar index'e yazılmamalıdır. ILM varsayılan 10 dakikada bir çalışır, koşullar anında değerlendirilmez.","since":"Elasticsearch 7.8","note":"Yeni projelerde aynı amaçla data stream kullanmak daha basittir: index template'e \"data_stream\": {} eklenir, rollover alias ve bootstrap index gerekmez. Rollover koşulları refresh edilmiş istatistiklere göre değerlendirilir. Composable index template (_index_template) 7.8 ile geldi; eski _template API'si deprecated'dır.","tags":["ilm","lifecycle","rollover","policy","index template","retention"]},{"id":"ilm-explain-retry","task":"Takılan ILM adımını teşhis et ve yeniden dene (_ilm/explain, _ilm/retry)","category":"Index Yaşam Döngüsü","command":"# Hata adiminda bekleyen index'ler:\nGET log-*/_ilm/explain?only_errors=true\n# Tek index'in faz/aksiyon/adim durumu ve hata nedeni:\nGET log-000003/_ilm/explain?filter_path=indices.*.phase,indices.*.action,indices.*.step,indices.*.failed_step,indices.*.step_info,indices.*.is_auto_retryable_error\n# Nedeni giderdikten sonra (ornek: eksik rollover alias ayari):\nPUT log-000003/_settings\n{\n  \"index.lifecycle.rollover_alias\": \"log\"\n}\nPOST log-000003/_ilm/retry\n# ILM calisiyor mu (STOPPED ise POST _ilm/start):\nGET _ilm/status","what":"ERROR adımında bekleyen index'leri, hangi faz/aksiyon/adımda takıldıklarını ve hata nedenini (step_info) gösterir; neden giderildikten sonra başarısız adımı yeniden çalıştırır.","when":"Rollover gerçekleşmediğinde, eski index'ler silinmediğinde veya disk ILM'nin silmesi gereken index'lerle dolduğunda.","caution":"_ilm/retry yalnızca ERROR adımındaki index'ler için çalışır; aksi halde 'has not encountered an error' hatası döner. Sık nedenler: rollover_alias ayarı yok veya alias başka index'te is_write_index, shrink için tek düğümde yeterli disk yok, allocation kuralı (_tier_preference) karşılanmıyor. Policy'yi silmek index'lerdeki ILM yönetimini kaldırmaz; önce index'lerden policy ayarını kaldır.","since":"Elasticsearch 7.0","note":"is_auto_retryable_error true olan hatalar ILM tarafından kendiliğinden tekrar denenir (failed_step_retry_count artar). ILM kontrol aralığı indices.lifecycle.poll_interval (varsayılan 10m) ile belirlenir. Bir index'i ILM'den çıkarmak için POST <index>/_ilm/remove kullanılır.","tags":["ilm","explain","retry","error step","rollover","lifecycle"]},{"id":"index-template-component","task":"Component template ile index template kur ve sonucu simüle et","category":"Index Yaşam Döngüsü","command":"PUT _component_template/app-mappings\n{\n  \"template\": {\n    \"mappings\": {\n      \"dynamic\": \"strict\",\n      \"properties\": {\n        \"@timestamp\": { \"type\": \"date\" },\n        \"level\": { \"type\": \"keyword\" },\n        \"msg\": { \"type\": \"text\" }\n      }\n    }\n  }\n}\nPUT _index_template/app-events\n{\n  \"index_patterns\": [\"app-events-*\"],\n  \"priority\": 500,\n  \"composed_of\": [\"app-mappings\"],\n  \"template\": { \"settings\": { \"number_of_shards\": 1, \"refresh_interval\": \"5s\" } }\n}\n# Index olusmadan once uygulanacak nihai ayar ve mapping'i gor:\nPOST _index_template/_simulate_index/app-events-000001\nGET _cat/templates?v&s=name","what":"Tekrar kullanılabilir bir mapping component template'i tanımlar, bunu bir index template'te birleştirir ve belirli bir index adı için uygulanacak nihai ayarları ve mapping'i index oluşturmadan gösterir.","when":"Yeni index'lerin yanlış mapping veya shard sayısıyla açıldığı (dinamik mapping patlaması, keyword yerine text) durumlarda ve template değişikliğini canlıya almadan önce.","caution":"Template yalnızca yeni oluşturulan index'lere uygulanır; mevcut index'lerin mapping'i değişmez (bkz. reindex-alias-swap). Aynı pattern'e uyan iki template varsa yalnızca en yüksek priority'li olan kullanılır; birleştirme yapılmaz. dynamic: strict tanımsız alan içeren belgeleri reddeder; uygulama yeni alan gönderiyorsa indexing hata alır.","since":"Elasticsearch 7.8","note":"_simulate_index çıktısındaki overlapping alanı, aynı pattern'e uyan ve ezilen diğer template'leri gösterir. Yerleşik template'lerle (logs-*-*, metrics-*-*) çakışmamak için priority'yi 200'ün üzerinde tut. Composable template'ler eski _template API'sine göre önceliklidir.","tags":["index template","component template","simulate","mapping","priority","dynamic strict"]},{"id":"reindex-alias-swap","task":"Mapping değişikliğini sıfır kesintiyle yap (reindex + atomik alias geçişi)","category":"Index Yaşam Döngüsü","command":"# 1) Yeni mapping ile hedef index (yukleme icin refresh kapali, replica 0):\nPUT musteri-v2\n{\n  \"settings\": { \"number_of_shards\": 1, \"number_of_replicas\": 0, \"refresh_interval\": \"-1\" },\n  \"mappings\": { \"properties\": { \"kod\": { \"type\": \"keyword\" }, \"adet\": { \"type\": \"long\" } } }\n}\n# 2) Arka planda reindex (donen task id ile izlenir):\nPOST _reindex?wait_for_completion=false&slices=auto\n{\n  \"source\": { \"index\": \"musteri-v1\", \"size\": 1000 },\n  \"dest\": { \"index\": \"musteri-v2\", \"op_type\": \"create\" },\n  \"conflicts\": \"proceed\"\n}\nGET _tasks/<task_id>\n# 3) Ayarlari geri al ve belge sayilarini karsilastir:\nPUT musteri-v2/_settings\n{\n  \"index\": { \"refresh_interval\": null, \"number_of_replicas\": 1 }\n}\nPOST musteri-v2/_refresh\nGET _cat/indices/musteri-v1,musteri-v2?v&h=index,docs.count,pri.store.size\n# 4) Alias'i tek atomik islemde yeni index'e cevir:\nPOST _aliases\n{\n  \"actions\": [\n    { \"remove\": { \"index\": \"musteri-v1\", \"alias\": \"musteri\" } },\n    { \"add\": { \"index\": \"musteri-v2\", \"alias\": \"musteri\", \"is_write_index\": true } }\n  ]\n}","what":"Yeni mapping'li bir index oluşturur, veriyi arka planda reindex ile kopyalar, belge sayılarını karşılaştırır ve uygulamanın kullandığı alias'ı tek atomik işlemle yeni index'e çevirir.","when":"Var olan bir alanın tipini değiştirmek (text -> keyword, integer -> long), analyzer değiştirmek veya shard sayısını yeniden belirlemek gerektiğinde; bunlar mevcut index'te yerinde yapılamaz.","caution":"Uygulama index adına değil alias'a bağlanmış olmalıdır; aksi halde geçiş için deploy gerekir. Reindex sürerken kaynağa gelen yeni yazmalar hedefe geçmez: yazmaları durdur veya geçişten hemen önce op_type create + conflicts proceed ile reindex'i tekrar çalıştırıp farkı kapat (güncellemeler ve silmeler bu yolla taşınmaz). Reindex kaynak cluster'da okuma, hedefte yazma yükü oluşturur; requests_per_second ile kısıtla.","since":"Elasticsearch 7.0","note":"refresh_interval -1 iken yüklenen belgeler refresh olmadan sayımda görünmez; karşılaştırmadan önce _refresh çalıştır. _cat/count'a virgülle birden fazla index verilirse toplamı döner; index bazında karşılaştırma için _cat/indices kullan. Çalışan reindex'in hızı POST _reindex/<task_id>/_rethrottle?requests_per_second=500 ile değiştirilebilir. wait_for_completion=false sonuçları .tasks index'ine yazar; GET _tasks/<task_id> ile response.failures alanını kontrol et.","tags":["reindex","alias","mapping değişikliği","zero downtime","_aliases","sıfır kesinti"]},{"id":"tasks-cancel","task":"Uzun süren arama ve reindex task'larını bul, iptal et veya yavaşlat","category":"Bakım","command":"# En uzun suren task'lar:\nGET _cat/tasks?v&detailed&h=action,task_id,parent_task_id,running_time,node,description&s=running_time:desc\n# Arama, reindex ve by-query task'lari, parent'a gore gruplu:\nGET _tasks?actions=*search*,*reindex*,*byquery*&detailed=true&group_by=parents\n# Tek bir task'i iptal et:\nPOST _tasks/<task_id>/_cancel\n# Tum arama task'larini iptal et (dikkatle):\nPOST _tasks/_cancel?actions=*search*\n# Calisan reindex/update_by_query'yi yavaslat:\nPOST _reindex/<task_id>/_rethrottle?requests_per_second=500","what":"Cluster'da çalışan task'ları süreye göre sıralar, arama ve toplu işlemleri sorgu açıklamasıyla birlikte gösterir; seçilen task'ı veya tüm aramaları iptal eder, reindex/by-query işlerini yavaşlatır.","when":"Search thread pool dolduğunda, CPU aniden yükseldiğinde, bir dashboard ağır bir aggregation ile cluster'ı yorduğunda veya bir update_by_query üretimi etkilediğinde.","caution":"İptal kooperatiftir: task bir sonraki kontrol noktasında durur; bazı aşamalar (ör. force merge) iptal edilemez. Tüm aramaları iptal etmek kullanıcılara hata döndürür. İptal edilen reindex/by-query o ana kadarki değişiklikleri geri almaz; hedef kısmi veri içerir. Parent task iptal edildiğinde child task'lar da iptal edilir.","since":"Elasticsearch 7.0","note":"detailed parametresi arama task'larında sorgu gövdesini description alanına yazar. Kalıcı koruma için search.default_search_timeout, arama isteğinde timeout ve büyük aggregation'larda search.max_buckets kullan. 7.x+ sürümlerde HTTP bağlantısı kapanan aramalar otomatik iptal edilir.","tags":["tasks","cancel","iptal","rethrottle","uzun sorgu","search"]},{"id":"search-slowlog","task":"Search ve indexing slow log'u aç (index bazında eşik)","category":"Performans","command":"PUT musteri/_settings\n{\n  \"index.search.slowlog.threshold.query.warn\": \"2s\",\n  \"index.search.slowlog.threshold.query.info\": \"500ms\",\n  \"index.search.slowlog.threshold.fetch.warn\": \"1s\",\n  \"index.indexing.slowlog.threshold.index.warn\": \"1s\",\n  \"index.indexing.slowlog.source\": \"200\"\n}\nGET musteri/_settings/index.*slowlog*?flat_settings=true\n# Kapatmak icin esikleri null yap:\nPUT musteri/_settings\n{\n  \"index.search.slowlog.threshold.query.warn\": null,\n  \"index.search.slowlog.threshold.query.info\": null,\n  \"index.search.slowlog.threshold.fetch.warn\": null,\n  \"index.indexing.slowlog.threshold.index.warn\": null,\n  \"index.indexing.slowlog.source\": null\n}","what":"Belirli bir index için query ve fetch aşamaları ile indexing işlemlerinde eşiği aşan istekleri, sorgu gövdesiyle birlikte slow log'a yazdırır.","when":"Yavaş aramanın hangi sorgudan kaynaklandığını bulmak, belirli bir dashboard'un veya client'ın ağır sorgularını yakalamak için.","caution":"Eşik shard bazında ölçülür: çok shard'lı index'te her shard ayrı satır yazabilir. Çok düşük eşik (0ms) log hacmini ve IO'yu ciddi artırır; teşhis bitince null ile kapat. indexing.slowlog.source belge kaynağını log'a yazar; hassas veri içeriyorsa false yap. Ayar yalnızca belirtilen index'e uygulanır; yeni index'ler için template'e ekle.","since":"Elasticsearch 8.0","note":"Slow log dosyaları logs dizininde <cluster>_index_search_slowlog.json ve <cluster>_index_indexing_slowlog.json adıyla yazılır; log4j2 konsola yönlendirilmişse stdout akışına gider. index.search.slowlog.level ayarı 8.0'da kaldırıldı; seviye eşiklerle (warn/info/debug/trace) belirlenir. 8.14+ sürümlerde index.search.slowlog.include.user: true ile isteği yapan kullanıcı da log'a yazılır. Tek bir sorguyu ayrıntılı incelemek için arama isteğine \"profile\": true ekle.","tags":["slowlog","slow log","yavaş arama","search","indexing","threshold"]},{"id":"rejections-heap-breaker","task":"429 rejection, heap ve circuit breaker baskısını teşhis et","category":"Performans","command":"# Thread pool kuyruk ve rejection sayilari (429 kaynagi):\nGET _cat/thread_pool/write,search,get?v&h=node_name,name,active,queue,rejected,completed,size,queue_size&s=rejected:desc\nGET _cat/nodes?v&h=name,node.role,heap.percent,ram.percent,cpu,load_1m,disk.used_percent,master&s=heap.percent:desc\n# Circuit breaker tetiklenmeleri ve parent breaker dolulugu:\nGET _nodes/stats/breaker?filter_path=nodes.*.name,nodes.*.breakers.*.tripped,nodes.*.breakers.parent\nGET _nodes/stats/jvm?filter_path=nodes.*.name,nodes.*.jvm.mem.heap_used_percent,nodes.*.jvm.gc.collectors.old\n# Fielddata bellek kullanimi (alan bazinda):\nGET _nodes/stats/indices/fielddata?fields=*&filter_path=nodes.*.indices.fielddata","what":"Write/search thread pool'larında kuyruk dolduğu için reddedilen istekleri, düğüm bazında heap/CPU durumunu, circuit breaker tetiklenmelerini, old GC sayısını ve fielddata bellek kullanımını gösterir.","when":"Client'lar 429 Too Many Requests veya es_rejected_execution_exception aldığında, CircuitBreakingException ([parent] Data too large) görüldüğünde veya düğümler uzun GC duraksamaları yaşadığında.","caution":"rejected sayaçları düğüm açıldığından beri kümülatiftir; iki ölçüm arasındaki artışa bak. queue_size'ı büyütmek rejection'ı gizler ama heap'i ve gecikmeyi artırır; asıl çözüm bulk boyutunu/eşzamanlılığı azaltmak veya kapasite eklemektir. Heap sürekli %85 üzerindeyse ve old GC sık çalışıyorsa düğüm OOM'a yaklaşıyordur. text alanında fielddata açmak heap'i hızla tüketir.","since":"Elasticsearch 7.0","note":"Parent breaker varsayılan olarak heap'in %95'idir (real memory circuit breaker, 7.0+). Write rejection'ları genelde tek bir sıcak düğümde yoğunlaşır: shard dağılımını ve yönlendirmeyi (_routing) kontrol et. Fielddata'yı geçici olarak boşaltmak için POST _cache/clear?fielddata=true kullanılır (bkz. cache-clear).","tags":["429","rejected","thread pool","circuit breaker","heap","fielddata"]},{"id":"slm-snapshot-monitor","task":"SLM ile otomatik snapshot ve saklama, snapshot ilerlemesini izle","category":"Snapshot","command":"# Her gece 01:30'da snapshot al, 30 gun sakla (en az 7, en fazla 60 snapshot):\nPUT _slm/policy/gece-yedek\n{\n  \"schedule\": \"0 30 1 * * ?\",\n  \"name\": \"<gece-{now/d}>\",\n  \"repository\": \"yedek_repo\",\n  \"config\": { \"indices\": [\"*\"], \"include_global_state\": true },\n  \"retention\": { \"expire_after\": \"30d\", \"min_count\": 7, \"max_count\": 60 }\n}\n# Policy'yi hemen calistir ve basari/hata istatistiklerini gor:\nPOST _slm/policy/gece-yedek/_execute\nGET _slm/stats\n# Devam eden snapshot ve shard bazinda ilerleme:\nGET _snapshot/yedek_repo/_current\nGET _snapshot/yedek_repo/_status\nGET _cat/snapshots/yedek_repo?v&s=end_epoch:desc\n# Deponun tum dugumlerden yazilabilir oldugunu dogrula:\nPOST _snapshot/yedek_repo/_verify","what":"Cron zamanlamasıyla düzenli snapshot alan ve eski snapshot'ları saklama kuralına göre silen bir SLM policy tanımlar; çalışan snapshot'ın shard bazında ilerlemesini, geçmiş snapshot'ları ve deponun erişilebilirliğini gösterir.","when":"Düzenli yedekleme kurarken, gece snapshot'ının başarısız olduğu alarmında veya uzun süren bir snapshot'ın ne zaman biteceğini kestirirken.","caution":"Schedule ifadesi UTC'ye göre değerlendirilir. Aynı depoya birden fazla cluster yazıyorsa veya depo başka cluster'da da yazılabilir kayıtlıysa depo bozulabilir; diğer cluster'larda readonly: true kullan. Retention yalnızca SLM'nin aldığı snapshot'ları siler. include_global_state true, restore sırasında template ve kalıcı cluster ayarlarını da geri yükleyebilir.","since":"Elasticsearch 7.5","note":"Snapshot'lar artımlıdır: yalnızca önceki snapshot'ta olmayan segment'ler kopyalanır, bu yüzden sık snapshot depoda orantılı yer kaplamaz. SLM 7.4, retention 7.5 ile geldi. _status çağrısı depo adı olmadan cluster'daki tüm çalışan snapshot'ları döndürür; geçmiş bir snapshot için ad verilirse depodan okunduğu için yavaş olabilir.","tags":["slm","snapshot","retention","yedek","schedule","snapshot status"],"untested":true},{"id":"security-user-role","task":"Rol ve native kullanıcı oluştur, şifre değiştir, API key üret","category":"Güvenlik","command":"POST _security/role/log_okuma\n{\n  \"cluster\": [\"monitor\"],\n  \"indices\": [\n    { \"names\": [\"log-*\"], \"privileges\": [\"read\", \"view_index_metadata\"] }\n  ]\n}\nPOST _security/user/rapor_kullanici\n{\n  \"password\": \"Degistir-123!\",\n  \"roles\": [\"log_okuma\"],\n  \"full_name\": \"Rapor Servisi\"\n}\nGET _security/user/rapor_kullanici\n# Bu istegi yapan kullanici ve rolleri:\nGET _security/_authenticate\nPOST _security/user/rapor_kullanici/_password\n{\n  \"password\": \"Yeni-Sifre-456!\"\n}\n# Sureli, yetkisi kisitli API key:\nPOST _security/api_key\n{\n  \"name\": \"rapor-key\",\n  \"expiration\": \"30d\",\n  \"role_descriptors\": { \"log_okuma\": { \"indices\": [ { \"names\": [\"log-*\"], \"privileges\": [\"read\"] } ] } }\n}\n# elastic kullanicisinin sifresi unutulduysa (dugum uzerinde shell):\n# bin/elasticsearch-reset-password -u elastic -i","what":"Index pattern bazında okuma yetkili bir rol ve bu role sahip native realm kullanıcısı oluşturur, şifreyi değiştirir, çağıran kullanıcının kimliğini doğrular ve süreli, yetkisi daraltılmış bir API key üretir.","when":"Raporlama, uygulama veya izleme hesaplarını en az yetkiyle açarken, şifre rotasyonunda ve servisler için kullanıcı yerine API key'e geçerken.","caution":"elastic süper kullanıcısını uygulamalarda kullanma. API key'in yetkisi, onu oluşturan kullanıcının yetkisini aşamaz; role_descriptors yalnızca daraltır. API key, oluşturulduğu andaki sahip yetkilerinin point-in-time snapshot'ıyla sınırlıdır; kullanıcının rolleri sonradan değişse de mevcut key'ler etkilenmez. Şifre değişikliği sonrası eski şifreyle çalışan servisler 401 alır; geçişi planla. API key yanıtındaki encoded değer yalnızca bir kez döner, sakla.","since":"Elasticsearch 8.0","note":"Security 8.0+ sürümlerde varsayılan olarak açıktır ve ilk açılışta elastic şifresi üretilir. elasticsearch-reset-password aracı 8.0 ile geldi. API key'leri GET _security/api_key?name=rapor-key ile listele, DELETE _security/api_key ile iptal et. LDAP/AD/SAML realm'lerindeki kullanıcılar için rol eşlemesi _security/role_mapping ile yapılır.","tags":["security","kullanıcı","rol","api key","şifre","rbac"],"untested":true}]},"solver/slow-query.json":{"id":"slow-query","title":"Yavaş sorgu — derinlemesine tanı","icon":"🐢","category":"Performans","intro":"Bir sorgu ya da sistem yavaş. Adım adım daralt: her düğümde bir kontrol çalıştır, sonucuna göre dalı seç. Sonunda kök neden + çözüm.","start":"scope","nodes":{"scope":{"kind":"step","title":"Yavaş olan ne?","detail":"Belirli bir/birkaç sorgu mu yavaş, yoksa tüm sistem mi? Bu, aramayı 'sorgu odaklı' ya da 'kaynak/darboğaz odaklı' iki koldan birine ayırır.","choices":[{"label":"Belirli bir/birkaç sorgu yavaş","next":"running"},{"label":"Tüm sistem geneli yavaş","next":"system"}]},"running":{"kind":"step","title":"Sorgu şu an mı çalışıyor?","detail":"O an çalışan/takılı bir sorgu mu, yoksa 'genelde yavaş' bir sorgu mu? Aktif oturumlara bak.","command":{"oracle":"SELECT sid, serial#, sql_id, last_call_et AS running_sec, event, blocking_session\nFROM v$session WHERE status='ACTIVE' AND type='USER' ORDER BY last_call_et DESC;","postgres":"SELECT pid, now()-query_start AS dur, state, wait_event, query\nFROM pg_stat_activity WHERE state='active' ORDER BY query_start;","mysql":"SELECT id, time, state, info FROM information_schema.processlist WHERE command='Query' ORDER BY time DESC;","mssql":"SELECT session_id, total_elapsed_time/1000 AS sec, status, wait_type, blocking_session_id\nFROM sys.dm_exec_requests WHERE session_id IN (SELECT session_id FROM sys.dm_exec_sessions WHERE is_user_process = 1) ORDER BY total_elapsed_time DESC;"},"choices":[{"label":"Şu an çalışıyor / takılı","next":"blocked"},{"label":"Genelde yavaş — planına bakmak istiyorum","next":"plan"}]},"blocked":{"kind":"step","title":"Sorgu bir şey mi bekliyor?","detail":"Aktif ama ilerlemiyorsa büyük ihtimalle bekliyordur. blocking_session / wait_event dolu mu?","command":{"oracle":"SELECT sid, blocking_session, event, seconds_in_wait\nFROM v$session WHERE sid=&hedef_sid;","postgres":"SELECT pid, pg_blocking_pids(pid) AS blocked_by, wait_event_type, wait_event\nFROM pg_stat_activity WHERE pid=&hedef_pid;","mssql":"SELECT session_id, blocking_session_id, wait_type, wait_resource\nFROM sys.dm_exec_requests WHERE session_id=&hedef;"},"choices":[{"label":"Başka bir oturum tarafından bloklanıyor","next":"sol_blocking"},{"label":"Bir kaynağı bekliyor (IO / log / latch)","next":"wait"},{"label":"Bekleme yok, aktif CPU yiyor","next":"plan"}]},"wait":{"kind":"step","title":"Hangi bekleme baskın?","detail":"Baskın wait event darboğazın türünü söyler.","command":{"oracle":"SELECT event, total_waits, time_waited FROM v$session_event WHERE sid=&hedef_sid ORDER BY time_waited DESC FETCH FIRST 5 ROWS ONLY;","postgres":"SELECT wait_event_type, wait_event, count(*) FROM pg_stat_activity WHERE state='active' GROUP BY 1,2 ORDER BY 3 DESC;","mssql":"SELECT TOP 5 wait_type, waiting_tasks_count, wait_time_ms FROM sys.dm_os_wait_stats ORDER BY wait_time_ms DESC;"},"choices":[{"label":"IO bekleme (db file read / PAGEIOLATCH)","next":"sol_io"},{"label":"Log / commit bekleme (log file sync / WRITELOG)","next":"sol_log"},{"label":"Lock / enqueue (enq: TX / LCK)","next":"sol_blocking"}]},"plan":{"kind":"step","title":"Çalışma planını (EXPLAIN) al","detail":"Planı çıkar. Tam tablo taraması (full scan), beklenmedik join sırası, ya da tahmini-vs-gerçek satır farkı var mı?","command":{"oracle":"SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('&sql_id', NULL, 'ALLSTATS LAST'));","postgres":"EXPLAIN (ANALYZE, BUFFERS) <sorgu>;","mysql":"EXPLAIN ANALYZE <sorgu>;","mssql":"SET STATISTICS PROFILE ON; <sorgu>; SET STATISTICS PROFILE OFF;","mongodb":"db.koleksiyon.find({...}).explain('executionStats')  // COLLSCAN mı IXSCAN mı?"},"choices":[{"label":"Full scan / eksik index var","next":"sol_index"},{"label":"Dün hızlıydı, plan aniden değişti","next":"sol_planchange"},{"label":"Çok fazla satır işliyor / N+1","next":"sol_rewrite"},{"label":"Plan iyi görünüyor ama yavaş","next":"stats"}]},"stats":{"kind":"step","title":"İstatistikler güncel mi?","detail":"Tahmini satır ile gerçek satır (E-rows vs A-rows) arasında büyük fark, bayat istatistiğin işaretidir.","command":{"oracle":"SELECT table_name, num_rows, last_analyzed FROM dba_tables WHERE table_name='&TABLO';","postgres":"SELECT relname, last_analyze, last_autoanalyze, n_live_tup FROM pg_stat_user_tables WHERE relname='&tablo';","mysql":"SELECT table_name, table_rows, update_time FROM information_schema.tables WHERE table_name='&tablo';","mssql":"SELECT name, STATS_DATE(object_id, stats_id) AS son_guncelleme FROM sys.stats WHERE object_id=OBJECT_ID('&tablo');"},"choices":[{"label":"İstatistik bayat / eski","next":"sol_stats"},{"label":"İstatistik güncel ama yine yavaş","next":"sol_deep"}]},"system":{"kind":"step","title":"Sistem geneli — darboğaz neresi?","detail":"Tek sorgu değil her şey yavaşsa kaynak darboğazına bak: CPU mu, IO mu, bellek mi, yoksa yaygın bloklama mı?","command":{"oracle":"SELECT metric_name, value FROM v$sysmetric WHERE metric_name IN ('Host CPU Utilization (%)','Average Active Sessions') AND intsize_csec=(SELECT MAX(intsize_csec) FROM v$sysmetric);","postgres":"SELECT state, wait_event_type, count(*) FROM pg_stat_activity GROUP BY 1,2 ORDER BY 3 DESC;","mssql":"SELECT TOP 5 wait_type, wait_time_ms FROM sys.dm_os_wait_stats ORDER BY wait_time_ms DESC;"},"choices":[{"label":"CPU %100'e yakın","next":"sol_cpu"},{"label":"IO bekleme yüksek","next":"sol_io"},{"label":"Bellek baskısı / düşük cache hit","next":"sol_mem"},{"label":"Çok sayıda bloklama","next":"sol_blocking"}]},"sol_blocking":{"kind":"solution","title":"Kök neden: Bloklama","detail":"Sorgu, başka bir oturumun tuttuğu lock'u bekliyor. Zincirin başındaki (root blocker) oturumu bul ve çöz.","steps":["Bloklama zincirinin başını bul (kendisi beklemeyen ama başkalarını bekleten oturum).","Root blocker ne yapıyor anla: commit edilmemiş uzun transaction mı, 'idle in transaction' mı?","Uygulama commit/rollback yapabiliyorsa onu tetikle; yoksa ve iş duruyorsa root blocker'ı sonlandır.","Kök nedeni çöz: eksik index geniş lock yaratıyor olabilir, transaction'ları kısalt, izolasyonu gözden geçir."],"related":["blocking-sessions","kill-session"],"playbook":"blocking"},"sol_io":{"kind":"solution","title":"Kök neden: IO darboğazı","detail":"Sorgu diskten çok okuyor. Genelde full scan (eksik index) ya da yetersiz bellek (buffer cache) yüzünden.","steps":["Full scan'e yol açan filtre için uygun index'i ekle (plan IXSCAN'e dönmeli).","Buffer cache / buffer pool hit oranını kontrol et; düşükse belleği artır.","Gereksiz kolon/satır okumayı azalt (SELECT * yerine gerekli kolonlar, sayfalama).","Depolama gerçekten yavaşsa (yüksek IO latency) disk katmanını iyileştir."],"related":["cache-hit-ratio","create-index"]},"sol_log":{"kind":"solution","title":"Kök neden: Commit / log darboğazı","detail":"'log file sync' / 'WRITELOG' baskınsa, commit'ler redo/WAL yazımını bekliyordur.","steps":["Sık tek-satır commit'leri toplu commit'e çevir (batch), gereksiz commit'i azalt.","Redo/WAL diskini hızlandır (ayrı, hızlı disk); log dosyası boyut/sayısını gözden geçir.","synchronous_commit / commit_write ayarlarını iş yükü ve dayanıklılık dengesine göre değerlendir."],"related":["show-config-param"]},"sol_index":{"kind":"solution","title":"Kök neden: Eksik index","detail":"Plan full scan yapıyor. Filtre/join kolonlarına uygun index büyük hızlanma sağlar.","steps":["WHERE/JOIN kolonlarına uygun index'i (gerekiyorsa birleşik) online ekle.","Index'i ekledikten sonra planı tekrar al, IXSCAN'e döndüğünü doğrula.","Yazma yükü ağırsa index maliyetini tart; gereksiz index'leri temizle.","Çok seçici olmayan kolonlarda index işe yaramaz — seçiciliği kontrol et."],"related":["create-index","explain-plan"]},"sol_planchange":{"kind":"solution","title":"Kök neden: Plan regresyonu","detail":"Sorgu dün hızlıydı, bugün değil — plan değişmiş. Genelde bayat istatistik veya parametre değişimi.","steps":["Önce taze istatistik topla (bayat istatistik en sık neden).","Doğru planı sabitle: Oracle SQL Plan Baseline / hint, MSSQL Query Store 'force plan', PG ayarları.","Yakın zamanda bir upgrade/patch/parametre değişimi olduysa onu gözden geçir (optimizer davranışı)."],"related":["update-statistics"]},"sol_rewrite":{"kind":"solution","title":"Kök neden: Sorgu tasarımı","detail":"Plan mantıklı ama sorgu doğası gereği çok iş yapıyor (çok satır, N+1, gereksiz join).","steps":["Sonuç kümesini küçült: sayfalama (LIMIT/OFFSET veya keyset), erken filtreleme.","N+1 desenini tek toplu sorguya çevir; gereksiz join/alt sorguları sadeleştir.","Tekrarlayan ağır raporlar için materialized view / özet tablo düşün."],"related":["explain-plan","materialized-view"]},"sol_stats":{"kind":"solution","title":"Kök neden: Bayat istatistik","detail":"Optimizer yanlış tahmin ediyor çünkü istatistikler güncel değil.","steps":["İlgili tablo(lar) için istatistikleri elle topla.","Otomatik toplama işinin (autovacuum/auto stats/gather job) çalıştığını doğrula.","Ani büyük veri yüklemelerinden sonra istatistik toplamayı iş akışına ekle."],"related":["update-statistics"]},"sol_deep":{"kind":"solution","title":"Derinlemesine analiz","detail":"Plan ve istatistik iyi ama hâlâ yavaşsa daha derine in.","steps":["Oturum düzeyinde iz (trace) aç: Oracle 10046, PG auto_explain, MySQL profiling, MSSQL Extended Events.","Paralellik, bellek grant'i, sort/hash spill (tempdb/temp) durumunu incele.","Donanım/OS katmanını (CPU steal, IO latency, ağ) dışla.","Bağlantı sayısı ve eşzamanlılık kaynaklı çekişmeyi değerlendir."],"related":["session-trace","top-wait-events"]},"sol_cpu":{"kind":"solution","title":"Kök neden: CPU darboğazı","detail":"Tüm sistem CPU'ya takılı. Genelde birkaç kötü planlı sorgu CPU'yu yakar.","steps":["CPU'yu en çok yiyen ilk 10 sorguyu bul ve planlarını düzelt (index/istatistik).","Kaçak sorguları sınırla (Resource Manager / Resource Governor).","Sürekli doluluk varsa ölçekle (CPU ekle, okumayı read replica'ya dağıt)."],"related":["top-slow-queries"],"playbook":"high-cpu"},"sol_mem":{"kind":"solution","title":"Kök neden: Bellek baskısı","detail":"Düşük cache hit ve/veya swap: bellek yetersiz ya da yanlış dağıtılmış.","steps":["Buffer pool / SGA ve oturum belleğini (work_mem/PGA) doğru boyutlandır (Araçlar > Bellek hesaplayıcısı).","Bellek yiyen kaçak sorguyu bul ve düzelt.","Swap'a düşülüyorsa öncelik oradan çıkmak; gerekirse RAM ekle."],"related":["cache-hit-ratio","show-config-param"],"playbook":"memory-pressure"}}},"solver/deadlock.json":{"id":"deadlock","title":"Deadlock / lock çakışması (ORA-00060, 1213, 40P01)","icon":"♻️","category":"Kilitler","intro":"Deadlock aldın (Oracle ORA-00060, MySQL 1213, PG 40P01, MSSQL 1205). Grafiği yakala, deseni çöz, tekrarı önle. Deadlock tasarım gereği çözülür — amaç sıklığı düşürmek.","start":"capture","nodes":{"capture":{"kind":"step","title":"Önce deadlock grafiğini yakala","detail":"Hangi iki (veya daha çok) oturum, hangi kaynaklar, hangi lock modları çakıştı? Bunu görmeden kör düzeltme yapma.","command":{"oracle":"-- Alert log'daki trace dosyasına bak (deadlock graph). Geçmiş için:\nSELECT * FROM dba_hist_active_sess_history WHERE event LIKE 'enq: TX%' ORDER BY sample_time DESC FETCH FIRST 20 ROWS ONLY;","mysql":"SHOW ENGINE INNODB STATUS\\G  -- 'LATEST DETECTED DEADLOCK' bölümü","postgres":"-- Deadlock hataları postgresql.log'a her zaman ERROR olarak yazılır (log_lock_waits gerekmez); log_lock_waits=on ise deadlock_timeout'u aşan kilit beklemelerini de loglar.","mssql":"SELECT XEvent.query('.') FROM (SELECT CAST(target_data AS XML) td FROM sys.dm_xe_session_targets t JOIN sys.dm_xe_sessions s ON s.address=t.event_session_address WHERE s.name='system_health') x CROSS APPLY td.nodes('//event[@name=\"xml_deadlock_report\"]') AS q(XEvent);"},"choices":[{"label":"Grafiği aldım — iki transaction ters sırada kaynak kilitliyor","next":"sol_order"},{"label":"Tek satır/tabloya çok sayıda işlem yığılıyor (hotspot)","next":"sol_hotspot"},{"label":"Geniş range lock'ları var (çok satır kilitleniyor)","next":"index_check"}]},"index_check":{"kind":"step","title":"Kilitlenen sorgu index kullanıyor mu?","detail":"Index olmadan bir UPDATE/DELETE, WHERE'i karşılamak için çok satır (hatta tüm tabloyu) kilitler → deadlock kaynağı. Planına bak.","command":{"mysql":"EXPLAIN <deadlock'a giren UPDATE/DELETE>;  -- type=ALL ise tam tarama, indeks yok","postgres":"EXPLAIN <sorgu>;  -- Seq Scan mı Index Scan mı?","oracle":"SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('&sql_id'));"},"choices":[{"label":"Index yok / full scan yapıyor","next":"sol_index"},{"label":"Index var, yine de çakışıyor","next":"sol_order"}]},"sol_order":{"kind":"solution","title":"Kök neden: Ters lock sırası","detail":"En yaygın deadlock nedeni: iki transaction kaynaklara farklı sırada erişiyor. A→B ve B→A aynı anda olunca kilitlenirler.","steps":["Tüm kod yollarında kaynaklara AYNI sırada eriş (ör. her zaman düşük id → yüksek id).","Transaction'ları kısa tut; kullanıcı etkileşimini/uzun işi transaction dışına çıkar.","Gerekiyorsa deterministik sırada erken lock al (SELECT ... FOR UPDATE ile sıralı).","Uygulamada deadlock kurbanı için otomatik yeniden deneme (retry + backoff) ekle — bu şarttır."],"related":["blocking-sessions","open-transactions"]},"sol_index":{"kind":"solution","title":"Kök neden: Eksik index → geniş lock","detail":"Index'siz UPDATE/DELETE gereğinden çok satır kilitliyor ve deadlock olasılığını patlatıyor.","steps":["WHERE koşulundaki kolona index ekle; lock sadece etkilenen satırlarla sınırlanır.","Planı tekrar al, tam taramanın (Seq Scan / type=ALL) index erişimine döndüğünü doğrula.","Toplu güncellemeleri küçük partiler (chunk) hâlinde çalıştır."],"related":["create-index","list-indexes"]},"sol_hotspot":{"kind":"solution","title":"Kök neden: Hotspot","detail":"Tek bir sayaç satırı/anahtar gibi bir kaynağa aynı anda çok işlem yığılıyor.","steps":["Hot row'u dağıt: sequence/identity kullan, sayaçları parçala (sharded counter).","Transaction süresini kısalt ki lock daha az tutulsun.","Mümkünse iyimser kilitleme (versiyon/timestamp) veya kuyruk deseni kullan."],"related":["sequence","open-transactions"]}}},"solver/disk-full.json":{"id":"disk-full","title":"Disk / tablespace doldu","icon":"💽","category":"Kapasite","intro":"'unable to extend', 'disk full', 'could not extend', 'log full' aldın. Panik yapma: önce NEYİN dolduğunu bul, güvenli alan kazan, sonra kalıcı çöz.","start":"what","nodes":{"what":{"kind":"step","title":"Ne doldu?","detail":"Yanlış yeri temizlemek işe yaramaz. Önce doluluğu ölç: data file mı, transaction log mu, arşiv/redo mu, temp mi, yoksa OS diski mi?","command":{"oracle":"SELECT d.tablespace_name, ROUND((1-(d.alloc-NVL(f.free,0))/d.maxb)*100,1) AS pct_free\nFROM (SELECT tablespace_name, SUM(bytes) alloc, SUM(GREATEST(bytes,maxbytes)) maxb FROM dba_data_files GROUP BY tablespace_name) d LEFT JOIN (SELECT tablespace_name, SUM(bytes) free FROM dba_free_space GROUP BY tablespace_name) f ON f.tablespace_name = d.tablespace_name ORDER BY pct_free;","postgres":"SELECT datname, pg_size_pretty(pg_database_size(datname)) FROM pg_database ORDER BY 2 DESC;  -- OS diski: df -h","mssql":"SELECT name, size/128.0 AS size_mb, size/128.0 - CAST(FILEPROPERTY(name,'SpaceUsed') AS int)/128.0 AS free_mb, type_desc\nFROM sys.database_files;","mysql":"SELECT table_schema, ROUND(SUM(data_length+index_length)/1048576,1) AS mb FROM information_schema.tables GROUP BY table_schema ORDER BY mb DESC;"},"choices":[{"label":"Data file / tablespace dolu","next":"data"},{"label":"Transaction log / arşiv-redo dolu","next":"log"},{"label":"Temp / undo dolu","next":"sol_temp"},{"label":"OS diski dolu (DB değil)","next":"sol_os"}]},"data":{"kind":"step","title":"En büyük tüketici ne?","detail":"Çoğu zaman tek bir kaçak tablo/segment suçludur. En büyükleri bul.","command":{"oracle":"SELECT segment_name, segment_type, ROUND(bytes/1048576,1) AS mb FROM dba_segments ORDER BY bytes DESC FETCH FIRST 10 ROWS ONLY;","postgres":"SELECT relname, pg_size_pretty(pg_total_relation_size(relid)) FROM pg_statio_user_tables ORDER BY pg_total_relation_size(relid) DESC LIMIT 10;","mssql":"SELECT TOP 10 OBJECT_NAME(object_id) AS tablo, SUM(reserved_page_count)*8/1024 AS mb FROM sys.dm_db_partition_stats GROUP BY object_id ORDER BY mb DESC;"},"choices":[{"label":"Beklenmedik büyük/kaçak tablo var","next":"sol_runaway"},{"label":"Normal büyüme, yer gerçekten bitti","next":"sol_extend"},{"label":"Çok fazla dead tuple / bloat var","next":"sol_reclaim"}]},"log":{"kind":"step","title":"Log neden büyüyor?","detail":"Log/arşiv, en eski aktif işlem/yedek bitene kadar temizlenemez. Neden birikmiş?","command":{"mssql":"SELECT name, log_reuse_wait_desc FROM sys.databases WHERE name=DB_NAME();  -- neden truncate edilemiyor?","postgres":"SELECT slot_name, active, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS tutulan FROM pg_replication_slots ORDER BY 3 DESC;","oracle":"SELECT * FROM v$flash_recovery_area_usage;  -- FRA (arşiv) doluluğu"},"choices":[{"label":"MSSQL: log yedeği alınmıyor (LOG_BACKUP)","next":"sol_logbackup"},{"label":"PG: ilerlemeyen replication slot WAL biriktiriyor","next":"sol_slot"},{"label":"Oracle: arşiv log alanı (FRA) dolu","next":"sol_archive"},{"label":"Uzun açık transaction log'u tutuyor","next":"sol_longtxn"}]},"sol_runaway":{"kind":"solution","title":"Kök neden: Kaçak tablo/segment","detail":"Tek bir nesne beklenmedik şekilde büyümüş (kontrolsüz insert, temizlenmeyen kuyruk/log tablosu).","steps":["Nesnenin gerçekten gerekli olup olmadığını doğrula; log/kuyruk tablosuysa retention uygula.","Gereksiz eski veriyi partition drop / TRUNCATE ile temizle (yedek/onay sonrası).","Uygulamadaki kontrolsüz büyümeyi durdur; büyüme alarmı kur."],"related":["largest-tables","create-partition"]},"sol_extend":{"kind":"solution","title":"Kök neden: Gerçek kapasite ihtiyacı","detail":"Normal büyüme; alan eklemek gerekiyor.","steps":["Data file'a alan ekle veya AUTOEXTEND aç (Oracle: ALTER DATABASE DATAFILE ... AUTOEXTEND ON MAXSIZE).","Gerekirse yeni datafile/tablespace ekle veya diski büyüt.","%80/%90 doluluk alarmı kur ki bir daha sürpriz olmasın."],"related":["free-space"]},"sol_reclaim":{"kind":"solution","title":"Kök neden: Bloat (dead tuple)","detail":"Silinen/güncellenen satırların yeri geri kazanılmamış.","steps":["Alanı geri kazan: PG VACUUM (gerekirse pg_repack), Oracle SHRINK SPACE, MySQL OPTIMIZE TABLE, Mongo compact.","Autovacuum/otomatik bakım ayarlarını agresifleştir.","VACUUM FULL / OPTIMIZE tabloyu kilitler — yoğun saat dışında yap."],"related":["reclaim-space","free-space"]},"sol_temp":{"kind":"solution","title":"Kök neden: Temp / undo dolu","detail":"Büyük sort/hash veya uzun açık transaction geçici alanı doldurdu.","steps":["Temp'i patlatan sorguyu bul (büyük sort/hash spill) ve optimize et.","Uzun açık transaction'ı bul; undo'yu (Oracle) o tutuyordur.","Gerekirse temp/undo alanını büyüt; retention ayarını gözden geçir."],"related":["open-transactions","reclaim-space"]},"sol_os":{"kind":"solution","title":"Kök neden: OS diski dolu","detail":"Sorun DB değil işletim sistemi diskinde. Loglar, core dump, eski yedekler, trace dosyaları yer kaplıyor olabilir.","steps":["df -h ile dolu bölümü bul; en büyük dizinleri tara (du -sh *).","Eski log/trace/core dump/yedek dosyalarını (onaylı biçimde) temizle.","DB diyagnostik dizinlerini (Oracle ADR, PG log) rotasyona bağla."]},"sol_logbackup":{"kind":"solution","title":"Kök neden: Log yedeği alınmıyor (SQL Server)","detail":"FULL recovery modelinde log yedeği alınmazsa log sonsuz büyür.","steps":["Log yedeği al (BACKUP LOG) — bu log'u yeniden kullanılabilir yapar.","Recovery model gerçekten SIMPLE olmalıysa değiştir.","Sadece gerekiyorsa log dosyasını küçült (DBCC SHRINKFILE) ve düzenli log yedek job'u kur."],"related":["last-backup-status"],"playbook":"log-growth"},"sol_slot":{"kind":"solution","title":"Kök neden: Terk edilmiş replication slot (PG)","detail":"İlerlemeyen (inactive) bir slot, WAL'ın temizlenmesini engeller ve pg_wal'i şişirir.","steps":["Slot'un gerçekten kullanılıp kullanılmadığını doğrula.","Gereksizse düşür: SELECT pg_drop_replication_slot('slot_adi');","Aktif replikayı düzelt ki slot ilerlesin; slot gecikmesi için alarm kur."],"related":["free-space"],"playbook":"log-growth"},"sol_archive":{"kind":"solution","title":"Kök neden: Arşiv log alanı (FRA) dolu (Oracle)","detail":"Arşiv loglar birikmiş ve FRA dolmuş; arşivleyici duruncaya kadar DB yazmayı durdurabilir.","steps":["Yedeği alınmış eski arşiv loglarını RMAN ile temizle (yedeksiz ASLA silme).","FRA boyutunu (db_recovery_file_dest_size) gerekiyorsa artır.","Arşiv log temizleme/backup job'unu düzenli çalışacak şekilde kur."],"related":["last-backup-status"]},"sol_longtxn":{"kind":"solution","title":"Kök neden: Uzun açık transaction","detail":"En eski aktif transaction, log/undo'nun geri kazanılmasını engelliyor.","steps":["En eski açık transaction'ı bul ve commit/rollback yaptır (ya da sahibiyle konuş).","'idle in transaction' bırakan uygulama davranışını düzelt; timeout ayarla.","Uzun raporları ayrı replikaya/pencereye taşı."],"related":["open-transactions"],"playbook":"log-growth"}}},"solver/connection-storm.json":{"id":"connection-storm","title":"Bağlantı fırtınası (too many connections)","icon":"🌊","category":"Kapasite","intro":"'too many connections', 'remaining connection slots reserved', ORA-00018 aldın; yeni bağlantılar reddediliyor. Kaynağı bul, acil rahatlat, kalıcı çöz.","start":"measure","nodes":{"measure":{"kind":"step","title":"Durumu ölç: kaç bağlantı, ne kadarı aktif?","detail":"Önce toplam bağlantı, limit ve aktif/idle dağılımına bak.","command":{"oracle":"SELECT status, COUNT(*) FROM v$session WHERE type='USER' GROUP BY status;\nSELECT name, value FROM v$parameter WHERE name IN ('processes','sessions');","postgres":"SELECT state, count(*) FROM pg_stat_activity GROUP BY state;\nSHOW max_connections;","mysql":"SHOW STATUS LIKE 'Threads_connected'; SHOW VARIABLES LIKE 'max_connections';","mssql":"SELECT status, COUNT(*) FROM sys.dm_exec_sessions WHERE is_user_process=1 GROUP BY status;","redis":"INFO clients"},"choices":[{"label":"Çoğu bağlantı idle / idle in transaction","next":"sol_idle"},{"label":"Çoğu aktif — kaynağı bulmalıyım","next":"who"}]},"who":{"kind":"step","title":"Kim/nereden? Bağlantıları kaynağa göre grupla","detail":"Genelde tek bir uygulama sunucusunun pool'u patlamıştır ya da bağlantı sızıntısı vardır. Host/kullanıcı/uygulama bazında dağılıma bak.","command":{"postgres":"SELECT client_addr, usename, application_name, count(*) FROM pg_stat_activity GROUP BY 1,2,3 ORDER BY 4 DESC;","mysql":"SELECT host, user, count(*) FROM information_schema.processlist GROUP BY host, user ORDER BY 3 DESC;","mssql":"SELECT host_name, program_name, login_name, COUNT(*) FROM sys.dm_exec_sessions WHERE is_user_process=1 GROUP BY host_name, program_name, login_name ORDER BY 4 DESC;","oracle":"SELECT machine, program, COUNT(*) FROM v$session WHERE type='USER' GROUP BY machine, program ORDER BY 3 DESC;"},"choices":[{"label":"Tek bir uygulama/host bağlantıları patlatmış (pool)","next":"sol_pool"},{"label":"Yük gerçekten arttı, hepsi meşru ve aktif","next":"sol_scale"}]},"sol_idle":{"kind":"solution","title":"Kök neden: Idle bağlantı yığını / sızıntı","detail":"Bağlantılar açılıp kapatılmıyor ya da 'idle in transaction' bırakılıyor; slotları boşuna tutuyorlar.","steps":["Uzun idle / idle-in-transaction bağlantıları temizle; admin için ayrılmış slotu kullan.","Sunucu tarafı timeout ayarla: PG idle_in_transaction_session_timeout, MySQL wait_timeout, Oracle profil idle_time.","Uygulamada bağlantıların (ve transaction'ların) kapatıldığından emin ol — sızıntıyı kaynağında düzelt."],"related":["open-transactions","kill-session","connection-count"],"playbook":"connection-storm"},"sol_pool":{"kind":"solution","title":"Kök neden: Uygulama pool'u patlamış","detail":"Bir uygulama sunucusunun connection pool'u sınırsız/çok büyük ya da sızdırıyor. Bağlantıları o üretiyor.","steps":["Acil: suçlu uygulamanın idle bağlantılarını kes ve pool'unu yeniden başlat.","Uygulama tarafında makul bir pool boyutu belirle (Araçlar > Connection Pool hesaplayıcısı).","Sunucu ile DB arasına bir pooler koy (PgBouncer / ProxySQL / Oracle DRCP / Connection Manager (CMAN)).","max_connections'ı körlemesine artırma — bellek tüketir ve sorunu erteler."],"related":["connection-count","kill-session"],"playbook":"connection-storm"},"sol_scale":{"kind":"solution","title":"Kök neden: Gerçek yük artışı","detail":"Bağlantılar meşru ve aktif; kapasite gerçekten yetmiyor.","steps":["Bir connection pooler ile bağlantıları çoğullayarak (multiplex) DB'ye düşen sayıyı azalt.","Okuma yükünü read replica'lara dağıt.","Gerekiyorsa max_connections'ı bellek bütçesine göre kontrollü artır; sunucu belleğini de ölçekle."],"related":["connection-count"],"playbook":"connection-storm"}}},"solver/replication-lag.json":{"id":"replication-lag","title":"Replikasyon gecikmesi / durdu","icon":"🔁","category":"Replikasyon","intro":"Standby/replika primary'nin gerisinde kalıyor ya da replikasyon tamamen durdu. Bu ağaç, gecikmenin türünü (artıyor mu, sabit mi, durdu mu) adım adım daraltarak apply hatası, tek-thread darboğazı, recovery çakışması veya bozulma gibi kök nedene götürür.","start":"root","nodes":{"root":{"kind":"step","title":"Gecikme nasıl davranıyor?","detail":"Önce durumu ölç. Replika akışını ve gecikme metriğini gör: lag zamanla artıyor mu, sabit bir seviyede mi takılı, yoksa uygulama (apply) tamamen durmuş mu? Bu, aramayı üç ana kola ayırır.","command":{"postgres":"SELECT client_addr, state, write_lag, flush_lag, replay_lag,\n       pg_wal_lsn_diff(sent_lsn, replay_lsn) AS bytes_behind\nFROM pg_stat_replication;","mysql":"SHOW REPLICA STATUS\\G","oracle":"SELECT name, value, unit FROM v$dataguard_stats WHERE name IN ('apply lag','transport lag');","mssql":"SELECT database_id, is_local, synchronization_state_desc, redo_queue_size, log_send_queue_size\nFROM sys.dm_hadr_database_replica_states;","redis":"INFO replication","elasticsearch":"GET _cluster/health"},"choices":[{"label":"Apply tamamen durdu / hata var","next":"stopped"},{"label":"Lag sürekli artıyor (yetişemiyor)","next":"growing"},{"label":"Lag sabit ama uzun sorgu şüphesi var","next":"standby_query"},{"label":"Çok geride / tutarsız görünüyor","next":"sol_rebuild"}]},"stopped":{"kind":"step","title":"Apply hatası ne diyor?","detail":"Replikasyon durduysa genelde uygulanan bir olayda hata vardır. Hata mesajına bak: hedefte olmayan bir satır/tablo mu, primary key çakışması mı, yoksa bağlantı/ağ kopması mı?","command":{"mysql":"SHOW REPLICA STATUS\\G  -- Last_Error, Last_SQL_Error, Replica_IO_Running, Replica_SQL_Running","postgres":"SELECT status, last_msg_receipt_time, latest_end_lsn, slot_name\nFROM pg_stat_wal_receiver;","oracle":"SELECT process, status, sequence#, block# FROM v$managed_standby WHERE process LIKE 'MRP%';","elasticsearch":"GET _cat/recovery?v&active_only=true"},"choices":[{"label":"Çakışan/eksik satır ya da tablo hatası","next":"sol_apply_error"},{"label":"Ağ/bağlantı koptu, IO thread durdu","next":"sol_connection"}]},"growing":{"kind":"step","title":"Neden yetişemiyor?","detail":"Lag sürekli büyüyorsa replika, primary'nin yazma hızına yetişemiyor demektir. Tek-thread apply mı darboğaz, yoksa replikanın diski/IO'su mu yavaş? Apply worker durumuna ve IO beklemesine bak.","command":{"mysql":"SHOW REPLICA STATUS\\G  -- Seconds_Behind_Source ve apply thread durumu\nSELECT * FROM performance_schema.replication_applier_status_by_worker;","postgres":"SELECT pid, wait_event_type, wait_event, state\nFROM pg_stat_activity WHERE backend_type='startup';","mssql":"SELECT database_id, redo_queue_size, redo_rate, log_send_queue_size\nFROM sys.dm_hadr_database_replica_states;"},"choices":[{"label":"Tek-thread apply + ağır yazma yükü","next":"sol_parallel"},{"label":"Replikanın diski/IO'su yavaş","next":"sol_io"}]},"standby_query":{"kind":"step","title":"Standby'da uzun bir sorgu mu var?","detail":"Salt-okunur standby üzerinde çalışan uzun bir sorgu, apply'ı (recovery) bloklayabilir. PostgreSQL'de recovery conflict bu şekilde ortaya çıkar. Standby'daki aktif sorgulara ve çakışma sayaçlarına bak.","command":{"postgres":"SELECT now()-query_start AS dur, pid, state, query\nFROM pg_stat_activity WHERE state='active' ORDER BY query_start;\nSELECT confl_snapshot, confl_lock, confl_bufferpin FROM pg_stat_database_conflicts WHERE datname=current_database();"},"choices":[{"label":"Evet, uzun sorgu apply'ı blokluyor","next":"sol_recovery_conflict"},{"label":"Hayır, sorgu yok — yine de geride","next":"sol_parallel"}]},"sol_apply_error":{"kind":"solution","title":"Kök neden: Apply hatası (veri çakışması)","detail":"Replika, uygulayamadığı bir olayda takıldı: hedefte olmayan satır, primary key çakışması veya eksik tablo. Kör atlama yerine tutarsızlığın nedenini gider.","steps":["Hatayı ve takılan olayı incele: hangi tablo, hangi işlem (silme/güncelleme/ekleme) başarısız oldu?","Kök nedeni bul: hedefe elle yazılan veri, eksik DDL (tablo/kolon), ya da bozuk bir binlog/WAL girdisi.","Şemayı hizala: eksik tablo/kolonu ekle; çakışan satırı primary ile karşılaştırıp düzelt.","Olayı atlamak zorunda kalırsan (ör. MySQL'de tek olay) bunu belgelendir ve sonrasında replikanın veri tutarlılığını doğrula.","Tekrarı önle: hedefe doğrudan yazımı kapat, DDL'leri ana üzerinden çalıştır."],"related":["replication-status"],"playbook":"replication-lag"},"sol_connection":{"kind":"solution","title":"Kök neden: Bağlantı / ağ kopması","detail":"Alıcı (IO/receiver) thread primary'ye bağlanamıyor. Ağ, kimlik doğrulama veya biriken/temizlenen log segmentleri sorunlu olabilir.","steps":["Ana ile replika arasındaki ağ/erişimi ve replikasyon kullanıcısının yetkilerini doğrula.","Primary'de gerekli WAL/binlog segmentlerinin hâlâ mevcut olduğunu kontrol et (retention/expire).","PostgreSQL'de replication slot'un var ve aktif olduğunu doğrula; slot yoksa WAL erken silinmiş olabilir.","Bağlantıyı yeniden başlat; log'lar tekrar akmaya başlıyorsa lag kapanmalı."],"related":["replication-status","list-replicas"],"playbook":"replication-lag"},"sol_parallel":{"kind":"solution","title":"Kök neden: Tek-thread apply darboğazı","detail":"Primary paralel yazarken replika değişiklikleri tek sırada uyguluyor ve yetişemiyor. Uygulamayı paralelleştir.","steps":["Paralel apply'ı aç: MySQL'de replica_parallel_workers + replica_parallel_type=LOGICAL_CLOCK.","PostgreSQL'de fiziksel replikasyonda apply tek süreçtir; büyük transaction'ları bölerek ana taraftaki üretim hızını düşür.","Ağır toplu (batch) işleri düşük yoğunluklu saatlere kaydır ya da parçala.","Değişiklik sonrası lag metriğini izle; azalarak sıfıra inmeli."],"related":["replication-status"],"playbook":"replication-lag"},"sol_io":{"kind":"solution","title":"Kök neden: Replika IO darboğazı","detail":"Apply thread'i CPU değil diski bekliyor. Replikanın depolaması primary'nin yazma hızını karşılayamıyor.","steps":["Replika diskinin IO gecikmesini/doygunluğunu ölç; primary ile karşılaştır.","Replikanın donanımı zayıfsa (yavaş disk, az RAM) ana ile eşitle — asimetrik donanım sık nedendir.","Redo/WAL uygulaması için diski hızlandır; buffer/cache'i yeterli boyutla.","İyileşmiyorsa yazma yükünü azalt veya okuma trafiğini başka replikaya dağıt."],"related":["replication-status"],"playbook":"replication-lag"},"sol_recovery_conflict":{"kind":"solution","title":"Kök neden: Standby recovery çakışması","detail":"Standby'daki uzun salt-okunur sorgu, primary'den gelen değişikliğin uygulanmasını blokluyor (vacuum/lock çakışması). PostgreSQL bunu gecikme veya sorgu iptaliyle çözer.","steps":["Bloklayan uzun sorguyu bul; gerçekten gerekiyorsa bitmesini bekle, değilse sonlandır.","hot_standby_feedback=on ile primary'nin standby sorgularına saygı göstermesini sağla (primary tarafta bloat pahasına).","Alternatif olarak max_standby_streaming_delay'i iş yüküne göre ayarla (gecikme toleransı vs sorgu iptali dengesi).","Uzun raporları apply'ı bloklamayacak ayrı bir replikaya ya da farklı zamana taşı."],"related":["replication-status","open-transactions"],"playbook":"replication-lag"},"sol_rebuild":{"kind":"solution","title":"Kök neden: Replika çok geride / bozuk — yeniden kur","detail":"Replika kurtarılamayacak kadar geride, gerekli log'lar silinmiş veya veri tutarsız. En güvenli yol taze yedekten yeniden kurmak.","steps":["Primary'den güncel bir temel yedek (base backup) al: PG pg_basebackup, MySQL clone/xtrabackup, Oracle RMAN duplicate.","Yedeği replikaya geri yükle ve replikasyon konfigürasyonunu (slot/kullanıcı/pozisyon) yeniden kur.","Replikasyonu başlat ve ilk senkronizasyon (catch-up) ilerlemesini izle.","Lag sıfıra indikten sonra veri tutarlılığını ve okuma trafiğini doğrula, sonra hizmete al."],"related":["replication-status","list-replicas","last-backup-status"],"playbook":"replication-lag"}}},"solver/ora-01555.json":{"id":"ora-01555","title":"ORA-01555: Snapshot too old (Oracle)","icon":"⏳","category":"Oracle","intro":"Oracle 'ORA-01555: snapshot too old' hatası, bir sorgunun tutarlı okuma için ihtiyaç duyduğu eski (undo) verinin artık üzerine yazılmış olduğunu gösterir. Bu ağaç hatanın kaynağını (uzun sorgu + yetersiz UNDO, yüksek undo devri, yoksa LOB) daraltıp doğru çözüme götürür.","start":"root","nodes":{"root":{"kind":"step","title":"Hata nerede ortaya çıkıyor?","detail":"Önce hatanın bağlamını belirle. Klasik ORA-01555 uzun süren bir SELECT/rapor sırasında mı geliyor, yoksa bir LOB (CLOB/BLOB) kolonuna erişirken mi? LOB kaynaklı ORA-01555 farklı bir mekanizmadır (PCTVERSION/RETENTION) ve ayrı çözülür.","command":{"oracle":"SELECT sql_id, elapsed_time/1e6 AS sec, sql_text\nFROM v$sql ORDER BY elapsed_time DESC FETCH FIRST 10 ROWS ONLY;"},"choices":[{"label":"Uzun süren bir sorgu/rapor sırasında","next":"undo_size"},{"label":"Bir LOB kolonuna erişirken","next":"sol_lob"}]},"undo_size":{"kind":"step","title":"UNDO yeterli mi, retention uygun mu?","detail":"Uzun sorgu, kendisi başladığından beri değişen bloklar için eski görüntüyü UNDO'dan okur. UNDO tablespace küçükse veya undo_retention sorgu süresinden kısaysa eski undo üzerine yazılır. UNDO kullanımını ve retention'ı ölç.","command":{"oracle":"SHOW PARAMETER undo_retention;\nSELECT tablespace_name, SUM(bytes)/1024/1024 AS mb, status\nFROM dba_undo_extents GROUP BY tablespace_name, status;\nSELECT MAX(maxquerylen) AS en_uzun_sorgu_sn, MAX(tuned_undoretention) AS tuned_retention\nFROM v$undostat;"},"choices":[{"label":"UNDO küçük / retention sorgudan kısa","next":"sol_undo"},{"label":"UNDO yeterli ama çok sık commit var","next":"sol_commits"},{"label":"Sorgu aşırı uzun sürüyor","next":"sol_query"}]},"sol_undo":{"kind":"solution","title":"Kök neden: Yetersiz UNDO / retention","detail":"Uzun sorgunun ihtiyaç duyduğu eski undo, retention süresi dolduğu ya da tablespace dolduğu için üzerine yazıldı. UNDO'yu büyüt ve retention'ı sorgu süresini kapsayacak şekilde ayarla.","steps":["En uzun sorgu süresini (v$undostat.maxquerylen) baz alarak undo_retention'ı bunu aşacak değere çıkar: ALTER SYSTEM SET undo_retention=10800;","UNDO tablespace'i retention'ı barındıracak kadar büyüt ya da autoextend aç: ALTER DATABASE DATAFILE '...' AUTOEXTEND ON MAXSIZE ...;","Kritik uzun sorgular için garanti ver: ALTER TABLESPACE undotbs1 RETENTION GUARANTEE;  (dikkat: UNDO dolarsa DML hata alabilir).","Değişiklik sonrası aynı raporu tekrar çalıştırıp ORA-01555'in kaybolduğunu doğrula."],"related":["show-config-param"],"playbook":"ora-01555"},"sol_commits":{"kind":"solution","title":"Kök neden: Yüksek undo devri (sık commit)","detail":"Sistemde çok sık commit yapan yoğun DML, undo bloklarını hızla geri dönüştürüp uzun sorgunun ihtiyaç duyduğu eski görüntüyü siler. 'Commit-cleanout' etkisi bunu ağırlaştırır.","steps":["Gereksiz sık commit'leri azalt: döngü içinde her satırda commit yerine toplu (batch) commit kullan.","Undo devrini yavaşlatmak için ağır DML iş yükünü uzun raporla aynı ana denk getirme.","undo_retention'ı artır ve gerekiyorsa RETENTION GUARANTEE ile eski undo'nun korunmasını sağla.","Raporu, yoğun yazma penceresinin dışına al ya da tutarlı bir okuma anına sabitle."],"related":["open-transactions","show-config-param"],"playbook":"ora-01555"},"sol_query":{"kind":"solution","title":"Kök neden: Aşırı uzun sorgu süresi","detail":"Sorgu o kadar uzun sürüyor ki makul bir undo_retention bile yetmiyor. Kalıcı çözüm sorguyu hızlandırmak ya da yükünü ayırmaktır.","steps":["Sorguyu optimize et: eksik index, kötü plan veya gereksiz full scan'i gider; süresini kısalt.","Büyük işi parçala (tarih/aralık bazlı) ki her parça undo penceresine sığsın.","Ağır raporu bir standby/replika ya da ayrı bir okuma zamanına taşı — böylece aktif DML ile çakışmaz.","Süre kabul edilebilir seviyeye inince undo_retention'ı buna göre ayarla."],"related":["explain-plan"],"playbook":"ora-01555"},"sol_lob":{"kind":"solution","title":"Kök neden: LOB retention / PCTVERSION","detail":"LOB okurken gelen ORA-01555, LOB'un eski sürümünü tutan alanın (RETENTION veya PCTVERSION) yetersiz olduğunu gösterir. LOB için ayrı bir sürümleme mekanizması vardır.","steps":["LOB kolonunun mevcut ayarını gör: SELECT retention, pctversion FROM dba_lobs WHERE table_name='...' AND column_name='...';","AUTO/MANUAL undo moduna göre uygun ayarı yükselt: ALTER TABLE t MODIFY LOB (kolon) (RETENTION);  ya da MANUAL modda PCTVERSION'ı artır.","RETENTION kullanan LOB'lar veritabanı undo_retention değerini baz alır — onu da yeterli tut.","LOB'a erişen uzun işlemleri kısalt; değişiklik sonrası hatayı tekrar test et."],"related":["show-config-param"],"playbook":"ora-01555"}}},"solver/backup-restore.json":{"id":"backup-restore","title":"Yedekleme & geri yükleme kararı","icon":"💾","category":"Yedek & Kurtarma","intro":"Yedekle ilgili ne yapman gerektiğini (yedek al, geri yükle, belirli bir ana dön - PITR, yoksa yedeği doğrula) adım adım seçip her veritabanı için doğru komut ve adımlara götüren karar ağacı.","start":"root","nodes":{"root":{"kind":"step","title":"Ne yapmak istiyorsun?","detail":"Amacını seç. Yeni bir yedek mi alacaksın, mevcut bir yedeği mi geri yükleyeceksin, belirli bir zamana (kesintiden hemen öncesine) mi döneceksin, yoksa elindeki yedeğin sağlam olduğunu mu doğrulayacaksın?","choices":[{"label":"Yedek ALMAK istiyorum","next":"take"},{"label":"Yedeği GERİ yüklemek istiyorum","next":"restore"},{"label":"Belirli bir ana dönmek (PITR)","next":"pitr"},{"label":"Yedeği DOĞRULAMAK istiyorum","next":"verify"}]},"take":{"kind":"step","title":"Yedek türü ne olsun?","detail":"Mantıksal yedek (dump) taşınabilir ve seçici geri yüklemeye uygundur ama büyük veride yavaştır. Fiziksel yedek (dosya/blok düzeyi) büyük veritabanları ve hızlı kurtarma için uygundur. İhtiyacına göre seç.","choices":[{"label":"Mantıksal yedek (dump / export)","next":"sol_logical_backup"},{"label":"Fiziksel / tam yedek","next":"sol_physical_backup"}]},"sol_logical_backup":{"kind":"solution","title":"Mantıksal yedek alma (dump)","detail":"Veriyi SQL/BSON ifadeleri olarak dışa aktarır. Sürümler/platformlar arası taşımada ve tek tablo/koleksiyon geri yüklemede idealdir.","steps":["PostgreSQL: pg_dump -Fc -d veritabani -f yedek.dump  (tüm cluster için pg_dumpall).","Oracle: expdp kullanici/parola directory=DP_DIR dumpfile=yedek.dmp schemas=SEMA logfile=exp.log","MySQL/MariaDB: mysqldump --single-transaction --routines --triggers veritabani > yedek.sql","MongoDB: mongodump --db veritabani --out /yedek/dizin","Redis: BGSAVE ile arka planda RDB snapshot'ı al (dump.rdb).","Elasticsearch: önce snapshot deposu tanımla, sonra PUT _snapshot/depo/anlik1?wait_for_completion=true","Yedeği güvenli bir konuma taşı ve boyut/tamamlanma durumunu kaydet."],"related":["logical-dump","last-backup-status"],"playbook":"backup-restore"},"sol_physical_backup":{"kind":"solution","title":"Fiziksel / tam yedek alma","detail":"Data file'ların blok/dosya düzeyi kopyası. Büyük veritabanlarında hızlı, PITR ve tam kurtarma için temel oluşturur.","steps":["Oracle: RMAN> BACKUP DATABASE PLUS ARCHIVELOG;  (arşiv log'larıyla birlikte).","PostgreSQL: pg_basebackup -D /yedek/base -Fp -Xs -P  (WAL arşivlemesi açıkken).","SQL Server: BACKUP DATABASE [veritabani] TO DISK='D:\\yedek\\db.bak' WITH CHECKSUM, COMPRESSION;","MySQL/MariaDB: xtrabackup --backup --target-dir=/yedek/base  (tutarlı fiziksel kopya).","MongoDB: dosya sistemi snapshot'ı ya da replica set üyesinden tutarlı snapshot al.","Yedeği offline/uzak bir konuma kopyala ve son yedek durumunu kaydet."],"related":["last-backup-status"],"playbook":"backup-restore"},"restore":{"kind":"solution","title":"Yedeği geri yükleme","detail":"Elindeki en uygun yedeği hedefe geri yükle. Önce yedeğin bütünlüğünü ve zaman damgasını doğrula, sonra motora uygun komutla yükle.","steps":["Geri yüklenecek yedeğin tarihini ve sağlamlığını doğrula (kayıp veri penceresini bil).","PostgreSQL: pg_restore -d yeni_db yedek.dump   (SQL dump ise: psql -d yeni_db -f yedek.sql).","Oracle: RMAN> RESTORE DATABASE; RECOVER DATABASE; ALTER DATABASE OPEN;  (impdp ile mantıksal içe aktarma).","MySQL/MariaDB: mysql veritabani < yedek.sql   (fiziksel: xtrabackup --copy-back).","SQL Server: RESTORE DATABASE [veritabani] FROM DISK='D:\\yedek\\db.bak' WITH RECOVERY, REPLACE;","MongoDB: mongorestore --db veritabani /yedek/dizin","Geri yükleme sonrası satır sayısı/uygulama kontrolleriyle veriyi doğrula."],"related":["restore-dump","last-backup-status"],"playbook":"backup-restore"},"pitr":{"kind":"solution","title":"Belirli bir ana dönüş (PITR)","detail":"Yanlış silme/bozulma öncesine, saniye hassasiyetinde dönmek istiyorsun. Tam yedek + o ana kadarki işlem log'ları (arşiv log / WAL / binlog) gerekir.","steps":["Hedef zamanı net belirle (olayın hemen öncesi) ve gerekli log'ların mevcut olduğunu doğrula.","Oracle: RMAN> RESTORE DATABASE; RECOVER DATABASE UNTIL TIME \"TO_DATE('2026-07-04 10:00:00','YYYY-MM-DD HH24:MI:SS')\"; ALTER DATABASE OPEN RESETLOGS;","PostgreSQL: base backup'ı geri yükle, sonra recovery_target_time='2026-07-04 10:00:00' ayarla ve WAL'ı bu ana kadar uygula.","SQL Server: RESTORE ... WITH NORECOVERY; ardından RESTORE LOG ... WITH STOPAT='2026-07-04 10:00:00', RECOVERY;","MySQL/MariaDB: tam yedeği geri yükle, sonra mysqlbinlog --stop-datetime='2026-07-04 10:00:00' ile binlog'u o ana kadar uygula.","Açılıştan sonra verinin beklenen zamanda olduğunu doğrula."],"related":["restore-dump","last-backup-status"],"playbook":"backup-restore"},"verify":{"kind":"solution","title":"Yedeği doğrulama","detail":"Bir yedek, ancak geri yüklenebildiği kanıtlanınca yedektir. Bütünlüğü ve gerçek geri yüklenebilirliği düzenli test et.","steps":["Oracle: RMAN> RESTORE DATABASE VALIDATE;  ve blok tutarlılığı için VALIDATE CHECK LOGICAL DATABASE;","SQL Server: yedekleri WITH CHECKSUM al ve RESTORE VERIFYONLY ... WITH CHECKSUM çalıştır (yalnız yedek dosyasını denetler); asıl kanıt için yedeği test sunucusuna geri yükleyip orada DBCC CHECKDB([veritabani]) WITH NO_INFOMSGS; çalıştır (CHECKDB yedek dosyasını değil, canlı/geri yüklenmiş veritabanını denetler).","PostgreSQL: yedeği ayrı/geçici bir sunucuya gerçekten geri yükleyip pg_restore'un hatasız bittiğini gör.","MySQL/MongoDB: dump'ı test ortamına restore edip satır/koleksiyon sayısını ve örnek veriyi karşılaştır.","Düzenli 'restore tatbikatı' planla — sadece yedek almak yeterli değil, geri yüklemeyi de kanıtla.","Sonuçları ve son başarılı doğrulama tarihini kaydet."],"related":["last-backup-status","restore-dump"],"playbook":"backup-restore"}}},"solver/upgrade-wizard.json":{"id":"upgrade-wizard","title":"Sürüm yükseltme sihirbazı","icon":"⬆️","category":"Yaşam Döngüsü","intro":"Patch mi major mı, yerinde mi taşıyarak mı? Yükseltmeyi adım adım planla; her dalda ön kontrol, yöntem ve sonrası. Prod'a dokunmadan önce burada provasını yap.","start":"kind","nodes":{"kind":{"kind":"step","title":"Ne tür bir yükseltme yapıyorsun?","detail":"Patch/küçük sürüm (aynı ana sürüm içinde, ör. 16.2 → 16.4, ya da bir SQL Server CU) düşük risklidir ve genelde yerinde yapılır. Büyük (major) sürüm (ör. 15 → 16) veri formatı değişimi içerebilir ve daha dikkatli planlama ister.","command":{"oracle":"SELECT * FROM v$version;\nSELECT patch_id, action, status FROM dba_registry_sqlpatch ORDER BY action_time DESC;","postgres":"SELECT version();","mysql":"SELECT VERSION();","mssql":"SELECT SERVERPROPERTY('ProductVersion') AS v, SERVERPROPERTY('ProductUpdateLevel') AS cu;","elasticsearch":"GET /"},"choices":[{"label":"Küçük sürüm / patch (aynı ana sürüm, CU)","next":"patch_prep"},{"label":"Büyük sürüm (major, ana sürüm değişiyor)","next":"major_method"},{"label":"Farkı bilmiyorum, açıkla","next":"explain"}]},"explain":{"kind":"step","title":"Patch mi, major mı?","detail":"Patch: ana sürüm aynı kalır (16.2 → 16.4); data file formatı değişmez, genelde binary değiştir + restart. Major: ana sürüm değişir (15 → 16); katalog/format değişebilir, pg_upgrade / autoupgrade / dump-restore gerekir, uygulama uyumluluğu test edilmeli.","choices":[{"label":"Bende patch (ana sürüm aynı)","next":"patch_prep"},{"label":"Bende major (ana sürüm değişiyor)","next":"major_method"}]},"patch_prep":{"kind":"step","title":"Yedeğin ve geri dönüş planın hazır mı?","detail":"Patch düşük riskli olsa da her yükseltmenin altın kuralı: önce tam yedek (ve mümkünse snapshot). Sorun çıkarsa dönebileceğin bir noktan olmalı.","choices":[{"label":"Evet, yedek + geri dönüş hazır","next":"sol_patch"},{"label":"Hayır, henüz yok","next":"sol_backupfirst"}]},"sol_backupfirst":{"kind":"solution","title":"Önce yedek + geri dönüş planı","detail":"Yükseltmeye başlamadan güvenlik ağını kur.","steps":["Tam yedek al (ve mümkünse depolama snapshot'ı / Oracle guaranteed restore point).","Geri dönüş adımlarını yazılı hale getir: sorun olursa nasıl eski sürüme dönerim?","Bakım penceresi ve iletişim planını netleştir, sonra patch adımına geç."],"related":["logical-dump","last-backup-status"]},"sol_patch":{"kind":"solution","title":"Patch'i uygula","detail":"Aynı ana sürüm içinde yama. Kümede rolling (replikadan başlayarak) uygulamak kesintiyi azaltır.","steps":["Oracle: yeni RU'yu opatch ile kur, sonra 'datapatch -verbose' ile SQL değişikliklerini uygula.","PostgreSQL: minor upgrade = yeni binary'yi kur, servisi yeniden başlat (initdb/dump gerekmez).","MySQL: paketi güncelle; 8.0'da sunucu açılışta otomatik upgrade yapar.","SQL Server: ilgili CU/GDR installer'ını çalıştır, ardından yeniden başlat.","MongoDB/Redis/Elasticsearch: rolling restart — önce secondary düğümler, en son primary.","Sonra sürümü ve uygulamayı doğrula; hata görürsen geri dönüş planını uygula."],"related":["apply-patch","check-version"],"playbook":"upgrade-rollback"},"major_method":{"kind":"step","title":"Major upgrade yöntemi","detail":"İki ana yol: (1) Yerinde — mevcut sunucuda dönüştür (pg_upgrade, Oracle AutoUpgrade/DBUA, MySQL in-place). Hızlı ama geri dönüşü zor. (2) Taşıyarak — yeni sürümde taze bir sunucu kur, veriyi taşı (dump/restore veya replikasyon ile), sonra geçiş yap (cutover). Daha güvenli, minimum kesinti.","choices":[{"label":"Önce hazırlık/uyumluluk kontrolü yapayım","next":"precheck"},{"label":"Yerinde (in-place)","next":"sol_inplace"},{"label":"Yeni sunucuya taşıyarak (minimum kesinti)","next":"sol_migrate"}]},"precheck":{"kind":"step","title":"Uyumluluk / hazırlık kontrolü","detail":"Yükseltmeden önce hedef sürümün uyarılarını çıkar: kaldırılan (deprecated) özellikler, geçersiz nesneler, uyumluluk seviyesi.","command":{"oracle":"-- AutoUpgrade analyze modu: java -jar autoupgrade.jar -config cfg -mode analyze","postgres":"-- pg_upgrade --check   (eski ve yeni binary yollarıyla)","mysql":"-- MySQL Shell: util.checkForServerUpgrade('root@localhost:3306', {targetVersion: '8.4.0'})","mssql":"-- Data Migration Assistant (DMA) ile uyumluluk raporu","elasticsearch":"GET _migration/deprecations"},"choices":[{"label":"Temiz çıktı, devam","next":"major_method"},{"label":"Uyarılar/uyumsuzluklar var","next":"sol_fixwarn"}]},"sol_fixwarn":{"kind":"solution","title":"Önce uyarıları gider","detail":"Rapordaki her uyarıyı yükseltmeden ÖNCE çöz; yoksa upgrade yarıda kalabilir ya da uygulama bozulur.","steps":["Kaldırılan (deprecated) özellik/sözdizimi kullanan nesne ve sorguları güncelle.","Geçersiz nesneleri derle/düzelt; eksik bağımlılıkları gider.","Uyumluluk seviyesi / feature version adımlarını hedef sürüme göre planla.","Uyarılar temizlenince ön kontrolü tekrar çalıştır ve yönteme dön."],"related":["check-upgrade-readiness","set-compatibility"]},"sol_inplace":{"kind":"solution","title":"Yerinde (in-place) major upgrade","detail":"Mevcut sunucuda dönüştür. Hızlı ama geri dönüş genelde yedekten restore demektir — snapshot şart.","steps":["Tam yedek + snapshot/guaranteed restore point al (geri dönüşün tek yolu).","Oracle: AutoUpgrade (deploy modu) veya DBUA. PostgreSQL: pg_upgrade (--link hızlı ama geri dönüşsüz). MySQL: yeni binary + otomatik in-place upgrade. SQL Server: setup /ACTION=upgrade.","Yükseltme sonrası görevleri çalıştır (aşağıdaki related).","Uygulamayı gerçek yükle doğrula; plan regresyonu olursa optimizer'ı sabitle."],"related":["upgrade-major","post-upgrade-tasks"],"playbook":"upgrade-rollback"},"sol_migrate":{"kind":"solution","title":"Taşıyarak upgrade (minimum kesinti)","detail":"Yeni sürümde taze sunucu kur, veriyi taşı, sonra kısa bir cutover ile geçiş yap. En güvenli yöntem; eski sistem sağlam kalır.","steps":["Hedef sürümde yeni sunucuyu kur ve şemayı hazırla.","İlk yükü dump/restore veya replikasyon ile aktar; ardından sürekli çoğaltma (CDC / logical replication) ile senkron tut.","Kısa bakım penceresinde: yazmayı durdur, kalan farkı bekle, uygulamayı yeni sunucuya yönlendir (cutover).","Taşımayı doğrula (satır sayısı/checksum); sorun olursa eski sunucuya an içinde geri dön."],"related":["setup-cdc-replication","verify-migration","export-for-migration"]}}},"solver/migration-wizard.json":{"id":"migration-wizard","title":"Migration sihirbazı (veri/şema taşıma)","icon":"🚚","category":"Yaşam Döngüsü","intro":"Veriyi/şemayı taşıyorsun. Homojen mi heterojen mi, kesinti toleransın ne? Adım adım planla: değerlendir → taşı → doğrula. Cutover öncesi provasını burada yap.","start":"kind","nodes":{"kind":{"kind":"step","title":"Nereden nereye taşıyorsun?","detail":"Homojen: aynı veritabanı motoru (ör. Oracle 19 → Oracle 23, ya da başka sunucuya PostgreSQL). Heterojen: farklı motor (ör. Oracle → PostgreSQL, MySQL → SQL Server). Heterojen çok daha fazla uyumluluk işi ister (veri tipleri, fonksiyonlar, PL/SQL).","choices":[{"label":"Aynı motor, yeni sunucu/sürüm (homojen)","next":"downtime"},{"label":"Farklı motora (heterojen)","next":"hetero"},{"label":"Planlama aşamasındayım, nasıl yaklaşayım?","next":"downtime"}]},"downtime":{"kind":"step","title":"Kesinti toleransın ne?","detail":"Taşımanın yöntemini bu belirler. Bir bakım penceresi varsa en basit yol dump/restore'dur. Sıfıra yakın kesinti gerekiyorsa ilk yükü aktarıp sürekli çoğaltma (CDC) ile senkron tutup kısa bir cutover yaparsın.","choices":[{"label":"Bakım penceresi var (kesinti kabul edilebilir)","next":"sol_offline"},{"label":"Neredeyse sıfır kesinti gerekiyor","next":"sol_online"}]},"hetero":{"kind":"step","title":"Şema ve tip uyumluluğunu değerlendirdin mi?","detail":"Heterojen taşımada asıl iş veriyi kopyalamak değil, farkları çözmektir: veri tipleri (VARCHAR2↔TEXT), fonksiyonlar (NVL↔COALESCE), otomatik artan değerler, PL/SQL ↔ PL/pgSQL, kaldırılmış/farklı özellikler.","choices":[{"label":"Şema/tip farklarını çıkardım","next":"sol_hetero"},{"label":"Henüz değerlendirmedim","next":"sol_assess"}]},"sol_assess":{"kind":"solution","title":"Önce uyumluluğu değerlendir","detail":"Taşımadan önce kaynak ve hedef arasındaki farkları çıkar — bu adım atlanırsa taşıma yarıda kalır.","steps":["Şema farkını çıkar: tablolar, constraint'ler, index'ler, view'lar, prosedürler.","Veri tipi ve fonksiyon eşleştirmesini yap (DBAtlas > Tipler & Fonksiyonlar modülü tam bunun için).","Motora özel özellikleri (identity/sequence, partition, PL/SQL, trigger) hedefte nasıl karşılayacağını belirle.","Bir dönüştürme aracı seç (ora2pg, pgloader, AWS SCT/DMS) ve küçük bir örnekle prova et."],"related":["compare-schema","heterogeneous-migration"]},"sol_offline":{"kind":"solution","title":"Kesintili taşıma (dump / restore)","detail":"En basit ve en güvenilir homojen yöntem: tutarlı bir yedek al, hedefe yükle, doğrula, geçiş yap.","steps":["Kaynaktan TUTARLI dışa aktarım al (pg_dump -Fc, expdp FLASHBACK_SCN, mysqldump --single-transaction, BACKUP, mongodump --oplog).","Hedefe yükle (pg_restore -j, impdp, mysql <, RESTORE, mongorestore).","Taşımayı doğrula: satır sayıları ve kritik checksum'lar kaynak = hedef mi?","Bakım penceresinde uygulamayı hedefe yönlendir (cutover); sorun olursa kaynağa geri dön."],"related":["export-for-migration","import-for-migration","verify-migration"]},"sol_online":{"kind":"solution","title":"Minimum kesinti (CDC / replikasyon)","detail":"İlk yükü aktar, sonra sürekli çoğaltma ile hedefi kaynağa senkron tut; yalnız kısa cutover'da kesinti olur.","steps":["İlk (baseline) yükü dump/restore veya snapshot ile aktar.","Sürekli çoğaltmayı kur: PG logical replication (PUBLICATION/SUBSCRIPTION), MySQL binlog replication, Oracle GoldenGate, MSSQL transactional replication/CDC, Mongo change streams/mongosync.","Hedef kaynağa yetişip lag ~0 olana kadar bekle ve izle.","Kısa cutover: kaynağa yazmayı durdur, kalan farkı bekle, uygulamayı hedefe yönlendir, doğrula."],"related":["setup-cdc-replication","verify-migration"]},"sol_hetero":{"kind":"solution","title":"Heterojen taşıma (farklı motora)","detail":"Şema dönüştür, veriyi taşı, mantığı uyarlat, doğrula. Aşamalı ilerle; tek seferde her şeyi taşıma.","steps":["Şemayı dönüştür: bir araçla (ora2pg, pgloader, AWS SCT) veya elle; tipleri ve constraint'leri hedefe uyarla.","Veriyi taşı: toplu yükleme (bulk load) veya araç; büyük tablolarda partition/chunk'la.","Sunucu tarafı mantığı uyarla: PL/SQL → PL/pgSQL, fonksiyon/trigger karşılıkları.","Kapsamlı doğrula: satır sayısı, örnek veri, kritik sorguların sonuçları; uygulamayı hedefte test et.","Kesintiyi azaltmak gerekiyorsa dönüşüm sonrası bir CDC katmanıyla senkron tut, sonra cutover yap."],"related":["heterogeneous-migration","verify-migration","setup-cdc-replication"]}}},"solver/high-cpu.json":{"id":"high-cpu","title":"Yüksek CPU","icon":"🔥","category":"Performans","intro":"Sunucu CPU'su tavan yapmış. Önce gerçekten veritabanının mı yediğini doğrula, sonra dalları izleyerek kök nedeni bul: kötü planlı sorgular, plan regresyonu, aşırı eşzamanlılık ya da DB dışı bir süreç.","start":"root","nodes":{"root":{"kind":"step","title":"CPU'yu gerçekten veritabanı mı yiyor?","detail":"İşletim sistemi tarafında hangi sürecin CPU yaktığına bak. Yükün büyük kısmı DB süreçlerinde mi, yoksa komşu bir süreçte (yedek, antivirüs, başka uygulama) mi? Bu, aramayı ikiye ayırır.","command":{"oracle":"-- OS tarafı: top -o %CPU  (ya da: top -c)\n-- DB tarafı doğrulama:\nSELECT ROUND(value,1) AS host_cpu_util_pct FROM v$sysmetric WHERE metric_name='Host CPU Utilization (%)' AND rownum=1;","postgres":"-- OS: top -c  /  ps -eo pcpu,pid,cmd --sort=-pcpu | head\n-- DB aktif oturum sayısı:\nSELECT count(*) FROM pg_stat_activity WHERE state='active';","mysql":"-- OS: top -c  /  mysqladmin processlist\nSHOW GLOBAL STATUS LIKE 'Threads_running';","mssql":"-- OS: Görev Yöneticisi / typeperf\nSELECT record_id, SQLProcessUtilization AS sql_cpu_pct, (100 - SystemIdle - SQLProcessUtilization) AS other_cpu_pct FROM (SELECT record.value('(./Record/@id)[1]','int') AS record_id, record.value('(./Record/SchedulerMonitorEvent/SystemHealth/SystemIdle)[1]','int') AS SystemIdle, record.value('(./Record/SchedulerMonitorEvent/SystemHealth/ProcessUtilization)[1]','int') AS SQLProcessUtilization FROM (SELECT CONVERT(xml, record) AS record FROM sys.dm_os_ring_buffers WHERE ring_buffer_type='RING_BUFFER_SCHEDULER_MONITOR') AS x) AS y ORDER BY record_id DESC;","mongodb":"// OS: top -c  |  db.serverStatus().metrics\ndb.serverStatus().opcounters","redis":"INFO cpu","elasticsearch":"GET _nodes/stats/os,process"},"choices":[{"label":"Evet, CPU'yu DB süreçleri yiyor","next":"db_confirm"},{"label":"Hayır, komşu bir süreç / yedek işi yiyor","next":"sol_os"}]},"db_confirm":{"kind":"step","title":"Yük nasıl ortaya çıktı?","detail":"CPU'yu DB yiyorsa deseni belirle: birkaç ağır sorgu mu baskın, sorun bir değişiklikle mi aniden başladı, yoksa yüksek eşzamanlılık/bağlantı çekişmesi mi var?","choices":[{"label":"Birkaç ağır sorgu CPU'yu yakıyor","next":"topcpu"},{"label":"Ani başladı — son deploy / parametre değişimi var","next":"sol_regression"},{"label":"Çok sayıda bağlantı / eşzamanlılık çekişmesi","next":"sol_concurrency"}]},"topcpu":{"kind":"step","title":"En çok CPU harcayan sorguları bul","detail":"CPU'yu toplamda en çok tüketen ilk sorguları çıkar. Sonra tek çağrı başına ağır mı (kötü plan), yoksa çağrı başına ucuz ama çok sık mı çağrılıyor buna karar ver.","command":{"oracle":"SELECT sql_id, executions, ROUND(cpu_time/1e6,1) AS cpu_sec, ROUND(cpu_time/GREATEST(executions,1)/1000,2) AS cpu_ms_per_exec, sql_text\nFROM v$sql ORDER BY cpu_time DESC FETCH FIRST 10 ROWS ONLY;","postgres":"SELECT queryid, calls, ROUND(total_exec_time::numeric,1) AS total_ms, ROUND(mean_exec_time::numeric,2) AS mean_ms, query\nFROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 10;","mysql":"SELECT DIGEST_TEXT, COUNT_STAR AS calls, ROUND(SUM_CPU_TIME/1e12,2) AS cpu_sec, ROUND(SUM_TIMER_WAIT/1e12,2) AS total_sec\nFROM performance_schema.events_statements_summary_by_digest ORDER BY SUM_TIMER_WAIT DESC LIMIT 10;","mssql":"SELECT TOP 10 qs.execution_count, qs.total_worker_time/1000 AS cpu_ms, qs.total_worker_time/qs.execution_count/1000 AS cpu_ms_per_exec, SUBSTRING(st.text,(qs.statement_start_offset/2)+1,50) AS stmt\nFROM sys.dm_exec_query_stats qs CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st ORDER BY qs.total_worker_time DESC;","mongodb":"db.setProfilingLevel(1, { slowms: 100 });  // sonra: db.system.profile.find().sort({ millis: -1 }).limit(10)"},"choices":[{"label":"Çağrı başına ağır — kötü plan / full scan var","next":"sol_query"},{"label":"Çağrı başına ucuz ama çok sık çağrılıyor","next":"sol_frequency"}]},"sol_query":{"kind":"solution","title":"Kök neden: Kötü planlı sorgu CPU yakıyor","detail":"Birkaç sorgu, full scan veya kötü join sırası yüzünden çağrı başına aşırı CPU harcıyor. Planlarını düzeltmek çekirdek çözümdür.","steps":["En çok CPU yiyen sorguların planını çıkar (EXPLAIN); full scan, kötü join sırası veya tahmini-gerçek satır farkını ara.","Filtre/join kolonlarına uygun index ekle; planın IXSCAN'e döndüğünü doğrula.","Optimizer yanlış tahmin ediyorsa taze istatistik topla.","Kaçak sorguları sınırla (Oracle Resource Manager / MSSQL Resource Governor) ve gerekirse sorguyu yeniden yaz."],"related":["top-slow-queries","explain-plan","create-index","update-statistics"],"playbook":"high-cpu"},"sol_frequency":{"kind":"solution","title":"Kök neden: Aşırı çağrı sıklığı","detail":"Sorgular tek tek ucuz ama saniyede binlerce kez çağrılıyor; toplam CPU maliyeti buradan geliyor. Genelde N+1 deseni veya önbelleksiz sıcak yol.","steps":["En sık çağrılan ifadeleri (calls / execution_count) belirle ve çağıran uygulama yolunu bul.","N+1 desenini toplu sorguya çevir; tekrarlı okumaları uygulama/sonuç önbelleğiyle azalt.","Hazırlanmış ifade (prepared statement) kullanarak tekrar tekrar hard parse maliyetini düşür.","Sık ve değişmeyen ağır sorgular için materialized view / özet tablo düşün."],"related":["top-slow-queries","explain-plan"],"playbook":"high-cpu"},"sol_regression":{"kind":"solution","title":"Kök neden: Plan regresyonu / bayat istatistik","detail":"Sistem dün normaldi, bir deploy, parametre değişimi veya veri yüklemesinden sonra CPU fırladı. Optimizer daha kötü bir plana geçmiş olabilir.","steps":["Değişimi belirle: son deploy, upgrade/patch, parametre değişikliği ya da büyük veri yüklemesi.","İlgili tablolar için taze istatistik topla (bayat istatistik en sık nedendir).","Doğru planı sabitle: Oracle SQL Plan Baseline / hint, MSSQL Query Store 'force plan'.","Değişiklik parametre kaynaklıysa geri al ve kontrollü olarak tekrar değerlendir."],"related":["update-statistics","explain-plan","show-config-param"],"playbook":"high-cpu"},"sol_concurrency":{"kind":"solution","title":"Kök neden: Yüksek eşzamanlılık / bağlantı çekişmesi","detail":"Tek tek sorgular kabul edilebilir ama aynı anda çok fazla oturum çalışıyor; CPU çekirdek sayısını aşan aktif oturum sayısı context-switch ve latch/spin çekişmesi yaratıyor.","steps":["Aktif oturum sayısını CPU çekirdek sayısıyla karşılaştır; çekirdekten çok aktif oturum varsa kuyruk oluşur.","Uygulama ile DB arasına bir connection pooler koy (PgBouncer / ProxySQL) ve makul pool boyutu belirle.","Aşırı paralellik varsa paralellik derecesini sınırla (Oracle parallel_degree_limit / parallel_max_servers, MSSQL MAXDOP).","Okuma yükünü read replica'lara dağıtarak primary'nin CPU'sunu rahatlat."],"related":["connection-count","active-sessions"],"playbook":"connection-storm"},"sol_os":{"kind":"solution","title":"Kök neden: DB dışı süreç CPU yiyor","detail":"CPU'yu veritabanı değil komşu bir süreç yiyor: yedekleme/sıkıştırma işi, antivirüs taraması, log gönderici ya da aynı makinedeki başka bir uygulama.","steps":["OS aracıyla (top / Görev Yöneticisi) suçlu süreci kesin olarak tespit et.","Yedek, istatistik toplama veya bakım işi ise yoğun saat dışına zamanla.","Antivirüs/tarama süreçlerinde veri dizinlerini istisna listesine ekle.","Kalıcı çakışma varsa DB'yi kendi kaynağı olan ayrı bir sunucuya taşı."],"related":["os-resource"],"playbook":"high-cpu"}}},"solver/memory-pressure.json":{"id":"memory-pressure","title":"Bellek baskısı / OOM","icon":"🧠","category":"Performans","intro":"Sunucu belleği tükeniyor, swap'a düşülüyor ya da OOM-killer devrede. Önce belleği kimin tükettiğini belirle: ayrılmış bellek (buffer pool/SGA), oturum belleği (work_mem/PGA), OS geneli, yoksa Redis'e özel bir durum mu?","start":"root","nodes":{"root":{"kind":"step","title":"Belleği kim tüketiyor?","detail":"Bellek baskısının kaynağını katmana göre ayır. Ayrılmış (sabit) bellek mi büyük, oturum başına bellek mi patlıyor, DB dışı bir süreç mi yiyor, yoksa Redis'in kendine özgü bellek yönetimi mi devrede?","command":{"oracle":"SELECT component, ROUND(current_size/1024/1024) AS mb FROM v$memory_dynamic_components WHERE current_size>0 ORDER BY current_size DESC;","postgres":"SHOW shared_buffers; SHOW work_mem; SHOW effective_cache_size;\nSELECT count(*) FROM pg_stat_activity WHERE state='active';","mysql":"SHOW VARIABLES LIKE 'innodb_buffer_pool_size';\nSHOW VARIABLES LIKE 'sort_buffer_size'; SHOW VARIABLES LIKE 'join_buffer_size';\nSHOW STATUS LIKE 'Threads_connected';","mssql":"SELECT physical_memory_in_use_kb/1024 AS used_mb, large_page_allocations_kb/1024 AS large_mb FROM sys.dm_os_process_memory;\nSELECT cntr_value/1024 AS target_mb FROM sys.dm_os_performance_counters WHERE counter_name='Target Server Memory (KB)';","mongodb":"db.serverStatus().wiredTiger.cache","redis":"INFO memory","elasticsearch":"GET _nodes/stats/jvm,os"},"choices":[{"label":"Ayrılmış bellek (buffer pool / SGA) baskın","next":"allocated"},{"label":"Oturum belleği (work_mem / PGA) patlıyor","next":"sol_session"},{"label":"DB dışı bir süreç / OS geneli","next":"sol_os"},{"label":"Redis'e özel (maxmemory / eviction / fragmentation)","next":"sol_redis"}]},"allocated":{"kind":"step","title":"Ayarlanmış bellek toplamı fiziksel RAM'i aşıyor mu?","detail":"Sabit ayrılmış bellek büyükse iki olasılık var: ya ayar toplamı (buffer pool + oturum + OS) fiziksel RAM'i aşıyor (over-commit), ya da boyut makul ama cache hit yine de düşük. Ayarları topla ve RAM ile karşılaştır.","command":{"oracle":"SHOW PARAMETER sga_target;  SHOW PARAMETER pga_aggregate_target;\nSELECT ROUND(value/1024/1024/1024,1) AS host_ram_gb FROM v$osstat WHERE stat_name='PHYSICAL_MEMORY_BYTES';","postgres":"SELECT name, setting, unit FROM pg_settings WHERE name IN ('shared_buffers','work_mem','maintenance_work_mem','max_connections');","mysql":"SELECT ROUND(@@innodb_buffer_pool_size/1024/1024/1024,1) AS pool_gb, ROUND((@@sort_buffer_size+@@join_buffer_size)/1024/1024,1) AS per_conn_mb, @@max_connections AS max_conn;","mssql":"SELECT value_in_use AS max_server_mem_mb FROM sys.configurations WHERE name='max server memory (MB)';\nSELECT total_physical_memory_kb/1024 AS ram_mb FROM sys.dm_os_sys_memory;"},"choices":[{"label":"Evet, toplam ayar RAM'i aşıyor (over-commit)","next":"sol_overcommit"},{"label":"Hayır, boyut makul ama cache hit düşük","next":"sol_cache"}]},"sol_overcommit":{"kind":"solution","title":"Kök neden: Bellek over-commit","detail":"buffer pool/SGA + oturum belleği + OS ihtiyacı toplamı fiziksel RAM'i aşıyor. Sistem swap'a düşüyor ya da OOM-killer süreci öldürüyor.","steps":["Bellek bütçesini yeniden çıkar: OS için pay bırak, ardından ayrılmış belleği doğru boyutlandır (Araçlar > Bellek hesaplayıcısı).","buffer pool/SGA hedefini ve oturum belleği tavanını RAM sınırına sığacak şekilde düşür.","Değişiklikleri kontrollü uygula, swap kullanımının ve OOM olaylarının durduğunu doğrula.","Kalıcı olarak kapasite yetmiyorsa RAM ekle ya da yükü böl."],"related":["show-config-param","cache-hit-ratio"],"playbook":"memory-pressure"},"sol_cache":{"kind":"solution","title":"Kök neden: Yetersiz önbellek (düşük cache hit)","detail":"Ayrılmış bellek RAM'i aşmıyor ama iş kümesine göre küçük; buffer cache hit oranı düşük ve DB sürekli diskten okuyor.","steps":["Buffer cache / buffer pool hit oranını ölç; sürekli düşükse (ör. %90 altı) önbellek küçük demektir.","RAM'de yer varsa buffer pool/SGA'yı kontrollü büyüt ve hit oranını yeniden ölç.","Sıcak veri gerçekten büyükse gereksiz okumayı azalt: indeksle, SELECT * yerine gerekli kolonlar, sayfalama.","Büyütme RAM'i zorluyorsa oturum belleği ile ayrılmış bellek dengesini yeniden kur."],"related":["cache-hit-ratio","show-config-param"],"playbook":"memory-pressure"},"sol_session":{"kind":"solution","title":"Kök neden: Oturum belleği patlaması","detail":"work_mem/PGA gibi oturum başına bellek, yüksek eşzamanlılıkla çarpılınca RAM'i tüketiyor. Her sort/hash operasyonu bu belleği ayrı ayrı ayırabilir.","steps":["En kötü durum tahmini yap: oturum belleği × eşzamanlı oturum × operasyon sayısı; bunu RAM ile karşılaştır.","Global oturum belleği ayarını (work_mem / sort_buffer_size / PGA hedefi) düşür.","Gerçekten büyük sort/hash isteyen ağır sorgular için ayarı yalnız o oturum düzeyinde yükselt.","Eşzamanlılığı bir connection pooler ile sınırlayarak toplam bellek talebini düşür."],"related":["show-config-param","connection-count"],"playbook":"memory-pressure"},"sol_redis":{"kind":"solution","title":"Kök neden: Redis bellek yönetimi","detail":"Redis'te bellek used_memory maxmemory'ye dayanmış, eviction devrede ya da fragmentation yüksek (used_memory_rss >> used_memory). Politika ve fragmentasyon çözülmeli.","steps":["INFO memory ile used_memory, maxmemory ve mem_fragmentation_ratio değerlerini oku.","Amaca uygun eviction politikası ayarla: CONFIG SET maxmemory-policy allkeys-lru (önbellek) ya da noeviction (kalıcı veri).","TTL kullanarak süresi geçen anahtarların temizlenmesini sağla ve büyük anahtarları (BIG KEYS) küçült.","Fragmentation yüksekse aktif defrag'ı aç (CONFIG SET activedefrag yes) ya da uygun bakım penceresinde yeniden başlat."],"related":["show-config-param"],"playbook":"memory-pressure"},"sol_os":{"kind":"solution","title":"Kök neden: DB dışı bellek tüketimi","detail":"Belleği veritabanı değil OS geneli ya da komşu bir süreç tüketiyor: başka bir uygulama, dosya sistemi önbelleği baskısı veya bellek sızdıran bir yardımcı süreç.","steps":["OS aracıyla (top / free / Görev Yöneticisi) en çok bellek tüketen süreci belirle.","Suçlu DB dışı bir süreçse taşı, sınırla (cgroup / iş nesnesi) ya da bellek sızıntısını düzelt.","OOM-killer DB sürecini öldürüyorsa OOM ayarını gözden geçir ve DB'ye bellek garantisi ver.","Kalıcı çakışma varsa DB'yi kendi belleğine sahip ayrı bir sunucuya taşı."],"related":["os-resource"],"playbook":"memory-pressure"}}},"solver/install-setup.json":{"id":"install-setup","title":"Yeni kurulum & güvenli başlangıç","icon":"🛠️","category":"Yaşam Döngüsü","intro":"Yeni kurulan bir veritabanını üretime hazırlarken atlanan adımlar en pahalı arızalara yol açar. Hangi aşamada olduğunu seç; ilk yapılandırma, güvenlik sıkılaştırma, dayanıklılık ve izleme için sıralı bir kontrol listesi al.","start":"root","nodes":{"root":{"kind":"step","title":"Hangi aşamadasın?","detail":"Yeni bir kurulumu üretime hazırlamak dört aşamalıdır: ilk yapılandırma, güvenlik sıkılaştırma, dayanıklılık (yedek/replikasyon) ve izleme. Şu an hangisiyle ilgileniyorsun? Sırasıyla hepsini geçmen önerilir.","command":{"oracle":"SELECT banner_full FROM v$version; SHOW PARAMETER compatible;","postgres":"SELECT version(); SHOW server_encoding; SHOW data_directory;","mysql":"SELECT VERSION(); SHOW VARIABLES LIKE 'character_set_server'; SHOW VARIABLES LIKE 'datadir';","mssql":"SELECT @@VERSION; SELECT SERVERPROPERTY('Collation') AS collation;","mongodb":"db.version(); db.serverStatus().host","redis":"INFO server","elasticsearch":"GET /"},"choices":[{"label":"Kurulum sonrası ilk yapılandırma","next":"firstconfig"},{"label":"Güvenlik sıkılaştırma","next":"sol_security"},{"label":"Yedek & dayanıklılık kurulumu","next":"durability"},{"label":"İzleme & alarm kurulumu","next":"sol_monitoring"}]},"firstconfig":{"kind":"step","title":"İlk yapılandırmada öncelik ne?","detail":"İlk yapılandırma iki ana başlığa ayrılır: kaynak/parametre boyutlandırma (bellek, bağlantı) ve kalıcı temeller (karakter seti/collation, veri dizini/dosya yerleşimi). Bunlar sonradan değiştirilmesi en zor kararlardır.","command":{"postgres":"SELECT name, setting, unit FROM pg_settings WHERE name IN ('shared_buffers','work_mem','max_connections','wal_level');","oracle":"SHOW PARAMETER sga_target; SHOW PARAMETER pga_aggregate_target; SHOW PARAMETER processes;","mysql":"SHOW VARIABLES LIKE 'innodb_buffer_pool_size'; SHOW VARIABLES LIKE 'max_connections';","mssql":"SELECT name, value_in_use FROM sys.configurations WHERE name IN ('max server memory (MB)','max degree of parallelism');"},"choices":[{"label":"Bellek / parametre boyutlandırma","next":"sol_sizing"},{"label":"Karakter seti, collation ve dosya yerleşimi","next":"sol_layout"}]},"durability":{"kind":"step","title":"Dayanıklılıkta hangi parçayı kuruyorsun?","detail":"Dayanıklılık iki ayakta durur: doğrulanmış yedek stratejisi (ilk yedek + geri yükleme testi) ve süreklilik (arşiv/log modu, replikasyon). Yedeği test etmeden 'yedeğim var' demek en yaygın yanılgıdır.","command":{"postgres":"SHOW archive_mode; SHOW wal_level;","oracle":"ARCHIVE LOG LIST; SELECT log_mode FROM v$database;","mysql":"SHOW VARIABLES LIKE 'log_bin'; SHOW VARIABLES LIKE 'server_id';","mssql":"SELECT name, recovery_model_desc FROM sys.databases;"},"choices":[{"label":"Yedek stratejisi + ilk yedek + geri yükleme testi","next":"sol_backup"},{"label":"Arşiv/log modu + replikasyon","next":"sol_replication"}]},"sol_sizing":{"kind":"solution","title":"İlk yapılandırma: Bellek ve parametre boyutlandırma","detail":"Varsayılan ayarlar çoğu motor için ihtiyatlıdır; sunucunun RAM ve CPU'suna göre boyutlandırılmalı, ama over-commit'ten kaçınılmalıdır.","steps":["Toplam RAM'i böl: OS için pay bırak, ardından buffer pool/SGA'yı ana önbellek olarak ayarla.","Oturum belleğini (work_mem/PGA) beklenen eşzamanlılığa göre ihtiyatlı belirle; toplam RAM'i aşma.","max_connections'ı gerçek ihtiyaca göre ayarla; yüksek eşzamanlılık için bir connection pooler planla.","Motora özel temel parametreleri gözden geçir (WAL/redo, checkpoint, paralellik) ve değişiklikleri belgele."],"related":["show-config-param","connect-cli"]},"sol_layout":{"kind":"solution","title":"İlk yapılandırma: Karakter seti, collation ve dosya yerleşimi","detail":"Karakter seti/collation ve veri dizini yerleşimi kurulum anında verilir; sonradan değiştirmek genelde yeniden kurulum veya taşıma gerektirir.","steps":["Sunucu düzeyinde Unicode karakter seti seç (ör. UTF-8 / AL32UTF8) ve tutarlı bir collation belirle.","Veri, log/WAL ve yedek dizinlerini ayrı disklere/hacimlere yerleştir; IO çekişmesini ve tek nokta arızasını azalt.","Dosya sistemi ve izinleri sıkılaştır: veri dizinini yalnız DB kullanıcısı okuyabilsin.","Yerleşim ve karakter seti kararlarını, ileride kurulacak düğümlerle aynı olacak şekilde belgele."],"related":["show-config-param","connect-cli"]},"sol_security":{"kind":"solution","title":"Güvenlik sıkılaştırma","detail":"Yeni kurulum varsayılan hesaplar, gevşek ağ erişimi ve açık portlarla gelir. Üretime çıkmadan önce saldırı yüzeyini daraltmak zorunludur.","steps":["Varsayılan/örnek hesapları kaldır veya kilitle; kullanılmayan yönetici hesaplarını devre dışı bırak.","Güçlü parola politikası uygula ve tüm varsayılan parolaları değiştir.","En az yetki ilkesi: her uygulamaya yalnız ihtiyacı olan yetkiyi ver, geniş rollerden kaçın.","TLS'i aç, listener'ı/portu güvenilir ağlarla sınırla ve audit log'u etkinleştir."],"related":["create-user-grant","change-password","enable-audit"]},"sol_backup":{"kind":"solution","title":"Dayanıklılık: Yedek stratejisi ve geri yükleme testi","detail":"Yedek, ancak geri yüklenebildiği kadar iyidir. İlk yedeği al, sürekliliği kur ve mutlaka bir geri yükleme testi yap.","steps":["Kurtarma hedeflerini (RPO/RTO) belirle ve tam + artımlı yedek takvimi kur.","İlk tam yedeği al; yedekleri DB sunucusundan ayrı bir konumda sakla.","Yedeği ayrı bir ortama geri yükleyerek test et — bütünlüğü kanıtlanmamış yedek yok sayılır.","Yedek işini zamanla, çıktısını izlemeye bağla ve son yedek durumunu düzenli kontrol et."],"related":["logical-dump","restore-dump","last-backup-status"]},"sol_replication":{"kind":"solution","title":"Dayanıklılık: Arşiv/log modu ve replikasyon","detail":"Nokta-zamanlı kurtarma ve yüksek erişilebilirlik için arşiv/log modu açık olmalı ve en az bir replika bulunmalıdır.","steps":["Arşiv/log modunu aç (PG archive_mode/wal_level, Oracle ARCHIVELOG, MySQL binlog, MSSQL FULL recovery).","En az bir yatay çoğaltma (standby/replica) kur ve ilk senkronizasyonu tamamla.","Replikasyon gecikmesini izle ve bir gecikme alarmı tanımla.","Kontrollü bir failover/switchover tatbikatı yaparak failover'ı doğrula."],"related":["replication-status","list-replicas"],"playbook":"replication-lag"},"sol_monitoring":{"kind":"solution","title":"İzleme & alarm kurulumu","detail":"Üretim öncesi son adım: sorunları kullanıcıdan önce görmek. Sağlık kontrolleri ve doğru eşiklerle alarmlar kurulmalı.","steps":["Temel sağlık kontrollerini topla: cache hit oranı, aktif/bekleyen oturumlar, en yavaş sorgular.","Kapasite alarmları tanımla: disk doluluğu, bağlantı sayısının limite yaklaşması, replikasyon gecikmesi.","Uyarıları bir kanala bağla (e-posta/sohbet) ve eşikleri gerçek yüke göre kalibre et.","Yedek başarısı ve error log'larını da izlemeye ekleyerek sessiz arızaları yakala."],"related":["cache-hit-ratio","connection-count","free-space"]}}},"solver/corruption-recovery.json":{"id":"corruption-recovery","title":"Veri bozulması kurtarma","icon":"🧯","category":"Kurtarma","intro":"Veri bozulmasında (blok/sayfa checksum hatası, okunamayan tablo, bozuk RDB/AOF) önce bozulmanın kapsamını doğrulayıp; blok düzeyi kurtarma, yedekten tam restore/PITR ve son çare onarım araçları arasında doğru kararı vermeni sağlayan adım adım karar ağacı.","start":"root","nodes":{"root":{"kind":"step","title":"Bozulmanın kapsamı ne?","detail":"Önce bütünlük kontrolü yaparak bozulmanın ne kadar yayıldığını tespit et. Sadece birkaç blok/sayfa mı bozuk, tek bir nesne (tablo/index) mi etkilenmiş, yoksa bozulma yaygın mı? Aşağıdaki komutlarla tarama yapıp kapsamı belirle, sonra uygun dalı seç.","command":{"oracle":"RMAN> BACKUP VALIDATE CHECK LOGICAL DATABASE;  -- ardından: SELECT file#, block#, blocks, corruption_type FROM v$database_block_corruption;","postgres":"pg_amcheck --all --heapallindexed --progress   # tekil tablo: pg_amcheck -d veritabani -t sema.tablo","mysql":"CHECK TABLE sema.tablo EXTENDED;   -- InnoDB için ayrıca: SHOW ENGINE INNODB STATUS\\G","mssql":"DBCC CHECKDB (N'veritabani') WITH NO_INFOMSGS, ALL_ERRORMSGS;","mongodb":"db.tablo.validate({ full: true })","redis":"redis-check-rdb /var/lib/redis/dump.rdb   # AOF (7+, salt-okunur kontrol): redis-check-aof /var/lib/redis/appendonlydir/appendonly.aof.manifest  (--fix dosyayı değiştirir; yalnız kopyası alındıktan sonra)","elasticsearch":"GET _cluster/health?level=shards   # bozuk shard için: GET _cat/shards?v&h=index,shard,state,unassigned.reason"},"choices":[{"label":"Sadece birkaç blok / sayfa bozuk","next":"block_level"},{"label":"Tek bir nesne (tablo/index) etkilenmiş","next":"restore"},{"label":"Bozulma yaygın / birçok nesne","next":"restore"},{"label":"Kontrol araçları çalışmıyor, DB açılmıyor","next":"last_resort"},{"label":"Bozulma tekrar ediyor (kök neden şüphesi)","next":"hardware"}]},"block_level":{"kind":"solution","title":"Kök neden: sınırlı blok/sayfa bozulması → hedefli kurtarma","detail":"Yalnızca birkaç blok/sayfa bozuksa tüm veritabanını restore etmeye gerek yoktur. Motorun blok/sayfa düzeyi kurtarma özelliğiyle sadece bozuk kısımları yedekten/log'dan onararak veri kaybını en aza indir.","steps":["Oracle: bozuk blok listesini v$database_block_corruption'da gördükten sonra (liste güncel değilse önce RMAN> VALIDATE DATABASE;) tek bloğu RMAN> RECOVER DATAFILE 5 BLOCK 1234; ile ya da listedeki tüm blokları RMAN> RECOVER CORRUPTION LIST; ile kurtar.","SQL Server: tek sayfa geri yükleme — RESTORE DATABASE [db] PAGE='5:1234' FROM DISK='D:\\yedek\\db.bak' WITH NORECOVERY;  ardından son log yedeklerini WITH NORECOVERY, en sonuncuyu WITH RECOVERY uygula.","PostgreSQL: blok düzeyi otomatik onarım yoktur; etkilenen tabloyu yedekten kısmi restore et ya da zero_damaged_pages=on ile SADECE veri çıkarmak için geçici olarak aç (bozuk satırlar kaybolur).","MySQL/InnoDB: tekil sayfa onarımı yoktur; etkilenen tabloyu son iyi yedekten geri yükle, gerekiyorsa PITR ile ileri sar.","Onarım sonrası kontrol komutunu (VALIDATE / DBCC CHECKDB / pg_amcheck) tekrar çalıştırıp bozulmanın kalmadığını doğrula.","Kurtarılan bloklardaki iş verisini uygulama tarafında örnekleyerek doğrula."],"related":["restore-dump","last-backup-status"],"playbook":"corruption"},"restore":{"kind":"solution","title":"Kök neden: nesne/yaygın bozulma → yedekten tam restore veya PITR","detail":"Bozulma bir veya birçok nesneye yayıldıysa en güvenli yol, sağlam bir yedekten geri yükleyip mümkünse bozulma anına kadar ileri sarmaktır (PITR). Böylece onarım araçlarının neden olacağı veri kaybından kaçınırsın.","steps":["Bozulmanın başladığı yaklaşık zamanı tespit et (alert log / hata log'u) ki PITR hedefini bunun hemen öncesine koyabilesin.","En son SAĞLAM tam yedeği ve o ana kadarki işlem log'larını (arşiv log / WAL / binlog) doğrula.","Oracle: RMAN> RESTORE DATABASE; RECOVER DATABASE UNTIL TIME \"TO_DATE('2026-07-04 09:59:00','YYYY-MM-DD HH24:MI:SS')\"; ALTER DATABASE OPEN RESETLOGS;","SQL Server: RESTORE DATABASE [db] FROM DISK='...' WITH NORECOVERY; RESTORE LOG [db] FROM DISK='...' WITH STOPAT='2026-07-04 09:59:00', RECOVERY;","PostgreSQL: base backup'ı geri yükle, recovery_target_time='2026-07-04 09:59:00' ayarla ve WAL'ı bu ana kadar uygula.","MySQL/MariaDB: tam yedeği geri yükle, sonra mysqlbinlog --stop-datetime='2026-07-04 09:59:00' ile binlog'u o ana kadar uygula.","MongoDB: sağlam replika/snapshot'tan mongorestore ile geri yükle; Elasticsearch: POST _snapshot/depo/anlik/_restore ile bozuk index'leri geri yükle.","Açılıştan sonra bütünlük kontrolünü tekrar çalıştır ve satır sayısı/uygulama kontrolleriyle veriyi doğrula."],"related":["restore-dump","logical-dump","last-backup-status"],"playbook":"corruption"},"last_resort":{"kind":"step","title":"Yedek yok / DB açılmıyor — son çareye mi geçiyorsun?","detail":"Onarım araçları (REPAIR_ALLOW_DATA_LOSS, innodb_force_recovery, --fix) VERİ KAYBETTİREBİLİR ve bütünlük constraint'lerini bozabilir. Bunlar yalnızca kullanılabilir bir yedek olmadığında ve veritabanı açılamadığında son çaredir. Önce kullanılabilir bir yedeğin gerçekten olmadığından emin ol.","choices":[{"label":"Sağlam bir yedek buldum, restore edeyim","next":"restore"},{"label":"Hiç yedek yok, onarım aracı tek seçenek","next":"repair"}]},"repair":{"kind":"solution","title":"Son çare: veri kaybı riskli onarım araçları","detail":"Bu araçlar veritabanını açılabilir hâle getirmek için bozuk satırları/sayfaları atar. Yalnızca yedek yoksa ve önce mevcut dosyaların bir kopyasını aldıysan uygula. Amaç: veriyi dışa aktarabilecek kadar açmak, sonra temiz bir kopyaya taşımak.","steps":["ÖNCE mevcut data file'ların ham bir kopyasını al (denemeler işi daha da bozabilir).","SQL Server: DBCC CHECKDB (N'db', REPAIR_ALLOW_DATA_LOSS) WITH ALL_ERRORMSGS;  (veritabanı SINGLE_USER modunda olmalı; bu komut veri kaybettirebilir).","MySQL/InnoDB: my.cnf içinde [mysqld] innodb_force_recovery=1 ile başlat; açılmazsa 2,3... diye artır (6'ya kadar), açılınca mysqldump ile veriyi hemen dışa aktar, ardından temiz kuruluma import et ve ayarı kaldır.","PostgreSQL: son çare olarak pg_resetwal (veri kaybı riski yüksek) yalnızca WAL bozulduğunda; ardından pg_dump ile veriyi çıkarıp yeni cluster'a yükle.","Oracle: yedek yoksa Oracle Support ile DBMS_REPAIR / event tabanlı kurtarma değerlendirilir; bloklar 'skip corrupt' ile atlanabilir (veri kaybı).","MongoDB: mongod --repair veya wiredTiger salvage ile aç, sonra veriyi yeni bir replica set'e taşı.","Onarım sonrası MUTLAKA temiz bir kuruluma taşı, bütünlük kontrolünü tekrar çalıştır ve kaybolan veriyi raporla."],"related":["logical-dump","restore-dump"],"playbook":"corruption"},"hardware":{"kind":"solution","title":"Kök neden: donanım/altyapı → kaynağı düzelt ve checksum aç","detail":"Bozulma tekrar ediyorsa asıl neden büyük olasılıkla disk, denetleyici (controller), bellek (RAM) veya kararsız depolama katmanıdır. Sadece veriyi kurtarmak yetmez; kaynağı gidermezsen bozulma geri gelir. Ayrıca erken tespit için checksum/bütünlük doğrulamasını aç.","steps":["Disk sağlığını kontrol et: SMART değerleri (smartctl -a /dev/sdX), RAID denetleyici log'ları ve depolama uyarıları.","Bellek testi çalıştır (memtest86+ veya ECC hata sayaçları); tek bit hataları bozulmanın klasik nedenidir.","OS/filesystem ve donanım hata log'larını incele (dmesg, olay görüntüleyici, storage array uyarıları).","PostgreSQL: initdb --data-checksums ile checksum'lı cluster kur (veya pg_checksums --enable) ki bozulma diske yazılırken yakalansın.","Oracle: DB_BLOCK_CHECKSUM=FULL ve DB_BLOCK_CHECKING=FULL ile blok doğrulamayı aç; DB_LOST_WRITE_PROTECT=TYPICAL ekle.","SQL Server: veritabanı PAGE_VERIFY CHECKSUM olduğundan emin ol (ALTER DATABASE [db] SET PAGE_VERIFY CHECKSUM).","MySQL/InnoDB: innodb_checksum_algorithm=crc32 ve gerekiyorsa innodb_doublewrite=ON ile kısmi yazımlara karşı koru.","Kaynağı giderdikten sonra en son sağlam yedekten temiz bir kopyaya restore et ve izlemeyi sıkılaştır."],"related":["restore-dump","last-backup-status"],"playbook":"corruption"}}},"solver/failover-drill.json":{"id":"failover-drill","title":"Failover tatbikatı / planlı geçiş","icon":"🔀","category":"Replikasyon","intro":"Rol değişiminin türünü (planlı switchover, acil failover ya da prod'a dokunmadan tatbikat) belirleyip; her senaryoda doğru komut sırasını ve doğrulama adımlarını sunan karar ağacı. Amaç: planlıda veri kaybı olmadan, acilde en az kayıpla, tatbikatta ise hiç kesinti olmadan hazır olmak.","start":"root","nodes":{"root":{"kind":"step","title":"Ne yapmak istiyorsun?","detail":"Rol değişiminin bağlamını seç. Primary sağlıklıyken planlı bir geçiş mi yapıyorsun (bakım/taşıma), primary gerçekten öldü ve acil geçiş mi gerekiyor, yoksa üretime dokunmadan bir tatbikat/hazırlık doğrulaması mı yapıyorsun?","choices":[{"label":"Planlı switchover (primary sağlıklı)","next":"planned"},{"label":"Acil failover (primary öldü)","next":"emergency_check"},{"label":"Tatbikat / hazırlık testi (prod'a dokunma)","next":"drill"}]},"planned":{"kind":"step","title":"Planlı geçiş — önce hazır mısın?","detail":"Planlı switchover'da amaç SIFIR veri kaybıdır. Bunun için geçişten önce replikanın primary'yi yakaladığından (lag ~0) ve sağlıklı olduğundan emin olmalısın. Aşağıdaki komutlarla lag'i kontrol et; lag sıfıra yakınsa geçiş adımlarına ilerle.","command":{"oracle":"SELECT thread#, MAX(sequence#) FROM v$archived_log GROUP BY thread#;   -- DG: SELECT name, value FROM v$dataguard_stats WHERE name LIKE '%lag%';","postgres":"SELECT client_addr, state, replay_lag, write_lag FROM pg_stat_replication;","mysql":"SHOW REPLICA STATUS\\G   -- Seconds_Behind_Source ve Replica_SQL_Running kontrol et","mssql":"SELECT ag.name, drs.synchronization_state_desc, drs.log_send_queue_size, drs.redo_queue_size FROM sys.dm_hadr_database_replica_states drs JOIN sys.availability_groups ag ON ag.group_id = drs.group_id;","mongodb":"rs.printSecondaryReplicationInfo()","redis":"redis-cli INFO replication   # master_repl_offset ile slave offset farkına bak","elasticsearch":"GET _cat/recovery?v&active_only=true"},"choices":[{"label":"Lag sıfıra yakın, geçişe hazır","next":"sol_planned"},{"label":"Lag yüksek, önce senkronu bekle","next":"drill"}]},"sol_planned":{"kind":"solution","title":"Planlı switchover (veri kaybısız kontrollü geçiş)","detail":"Primary ve standby sağlıklı ve senkronken rolleri kontrollü şekilde değiştir. Sıra önemlidir: yazımları durdur, kalan değişikliklerin standby'a aktığından emin ol, sonra rolü devret ve uygulamayı yeni primary'ye yönlendir.","steps":["Bakım penceresini duyur ve uygulamayı okuma-yazma açısından kontrollü şekilde beklet.","Oracle Data Guard (12c+): SQL> ALTER DATABASE SWITCHOVER TO standby_db VERIFY; ardından SQL> ALTER DATABASE SWITCHOVER TO standby_db;  (Broker ile: DGMGRL> SWITCHOVER TO 'standby_db'; 11g ve öncesi: COMMIT TO SWITCHOVER TO PHYSICAL STANDBY).","PostgreSQL: primary'yi düzgün kapat (pg_ctl stop -m fast), standby'da SELECT pg_promote(); ile terfi ettir, ardından eski primary'yi yeni standby olarak pg_rewind ile geri bağla.","SQL Server AG: senkron replikada ALTER AVAILABILITY GROUP [ag] FAILOVER;  (veri kaybısız planlı failover; SYNCHRONOUS_COMMIT şart).","MongoDB: rs.stepDown(60) ile mevcut primary'yi 60 sn geri çekilmeye zorla; en güncel secondary otomatik seçilerek primary olur.","Redis: yeni master adayında REPLICAOF NO ONE; sonra diğer node'larda REPLICAOF yeni_master port; (Sentinel varsa SENTINEL FAILOVER master_adi).","Uygulama bağlantı dizesini / yönlendirmeyi yeni primary'ye çevir (VIP, servis adı veya connection string).","Doğrula: yeni primary'ye yazım yapılabiliyor, eski primary standby olarak akış alıyor ve lag ~0, uygulama hatasız."],"related":["promote-failover","replication-status","list-replicas"],"playbook":"replication-lag"},"emergency_check":{"kind":"step","title":"Acil geçiş — primary gerçekten öldü mü?","detail":"Zorla failover'a geçmeden önce primary'nin gerçekten erişilemez olduğunu doğrula ve split-brain riskini değerlendir. Primary aslında yaşıyorsa (ör. geçici ağ kesintisi) zorla geçiş iki ayrı yazılabilir kopyaya (split-brain) yol açar. Ayrıca en güncel standby'ı seçmek için lag'i karşılaştır.","command":{"oracle":"-- primary'ye erişim dene: tnsping primary_db; ve standby'da: SELECT thread#, MAX(sequence#) FROM v$archived_log GROUP BY thread#;","postgres":"SELECT pg_last_wal_receive_lsn(), pg_last_wal_replay_lsn();   -- standby'lar arasında en yüksek LSN'i seç","mysql":"SHOW REPLICA STATUS\\G   -- adaylar arasında en büyük Exec_Source_Log_Pos olanı seç","mssql":"SELECT drs.replica_id, drs.last_hardened_lsn FROM sys.dm_hadr_database_replica_states drs;","mongodb":"rs.status()   -- optime en yüksek üye primary adayıdır","redis":"redis-cli INFO replication   # slave_repl_offset en yüksek olanı seç","elasticsearch":"GET _cat/nodes?v   # master node erişilebilir mi doğrula"},"choices":[{"label":"Evet, primary öldü — zorla geç","next":"emergency"},{"label":"Emin değilim / primary geri gelebilir","next":"planned"}]},"emergency":{"kind":"solution","title":"Acil failover (primary öldü, veri kaybı riskiyle geçiş)","detail":"Primary erişilemez ve geri gelmesini bekleyemiyorsun. Standby'ı zorla terfi ettirmen gerekir; asenkron replikasyonda son işlemlerin bir kısmı kaybolabilir. Önceliğin hizmeti geri getirmek, sonra kayıp penceresini tespit ve eski primary'yi güvenle geri almaktır.","steps":["Primary'nin gerçekten öldüğünü doğrula (split-brain'i önlemek için eski primary'yi ağdan izole et / kapat — fencing/STONITH).","En güncel standby'ı seç: uygulamadan önce lag/offset'i karşılaştır ki en az veri kaybı olanı terfi ettiresin.","Oracle Data Guard: DGMGRL> FAILOVER TO 'standby_db';  (veya SQL> ALTER DATABASE ACTIVATE STANDBY DATABASE;).","PostgreSQL: standby'da SELECT pg_promote(); ile hemen terfi ettir; eski primary geri gelince pg_rewind olmadan primary olarak AÇMA (split-brain riski).","SQL Server AG: ALTER AVAILABILITY GROUP [ag] FORCE_FAILOVER_ALLOW_DATA_LOSS;  (asenkron replikada veri kaybı olabilir).","MongoDB: çoğunluk (majority) kalmadıysa rs.reconfig(cfg, {force:true}) ile ayakta kalan üyeleri yeniden yapılandır.","Redis: Sentinel yoksa yeni master adayında REPLICAOF NO ONE; diğerlerini ona bağla; eski master'ı asla otomatik geri ekleme.","Uygulamayı yeni primary'ye yönlendir; ardından kayıp veri penceresini (kaybolan işlemler) tespit edip raporla ve eski primary'yi temiz şekilde yeni standby olarak geri kur."],"related":["promote-failover","replication-status","list-replicas"],"playbook":"db-down"},"drill":{"kind":"solution","title":"Tatbikat / hazırlık testi (üretime dokunmadan doğrula)","detail":"Gerçek bir geçiş yapmadan, failover'a hazır olduğunu kanıtla. Replikaların sağlığını, lag'in kabul edilebilir olduğunu ve uygulamanın yönlendirilebildiğini prod'u etkilemeden doğrula. İstersen izole bir kopyada gerçek switchover'ı prova et.","steps":["Lag'i ölç ve eşiğin altında olduğunu doğrula (PG: pg_stat_replication.replay_lag; MySQL: Seconds_Behind_Source; Oracle: v$dataguard_stats; Mongo: rs.printSecondaryReplicationInfo()).","Replika sağlığını doğrula: tüm standby'lar akış alıyor, senkron mod beklenen üyelerde aktif (SQL Server: synchronization_state_desc='SYNCHRONIZED').","Okuma/rol testi: standby'da salt-okunur sorgu çalıştırıp gecikmesiz yanıt aldığını gör (PG hot standby, Oracle Active Data Guard, okuma replikası).","Uygulama yönlendirme provası: bağlantı dizesini/servis adını test ortamında yeni primary'ye çevirip uygulamanın sorunsuz bağlandığını doğrula (prod trafiğine dokunma).","İzole kopya üzerinde gerçek switchover'ı baştan sona prova et ve geçiş süresini (RTO) ölç.","Geri dönüş (failback) adımlarını da prova et: pg_rewind / DG reinstate / AG resume ile eski primary'yi geri kurma.","Bulguları, süreleri ve eksikleri kaydet; runbook'u güncelle ve tatbikatı periyodik planla."],"related":["replication-status","list-replicas","promote-failover"],"playbook":"replication-lag"}}},"solver/security-incident.json":{"id":"security-incident","title":"Güvenlik olayı / şüpheli erişim","icon":"🚨","category":"Güvenlik","intro":"Şüpheli bir erişim, beklenmedik yetki değişimi veya olası veri sızıntısında; belirtiye göre doğru müdahale adımlarına (hesabı kilitle, fazla yetkiyi geri al, bağlantıları kes, kapsamı belirle) ve olay sonrası kalıcı sıkılaştırmaya götüren karar ağacı.","start":"root","nodes":{"root":{"kind":"step","title":"Ne fark ettin?","detail":"Olayın türünü seç. Belirti; şüpheli bir giriş ya da başarısız login patlaması mı, beklenmedik bir yetki (GRANT/rol) değişimi mi, olası bir veri sızıntısı / anormal dışa aktarım mı, yoksa olay kapandı ve kalıcı sıkılaştırma mı yapıyorsun? İlk gözleme göre en uygun dalı seç. Önce olay anını ve etkilenen hesabı/kaynağı not al.","choices":[{"label":"Şüpheli giriş / başarısız login patlaması","next":"identity"},{"label":"Beklenmedik yetki (GRANT/rol) değişimi","next":"privilege"},{"label":"Veri sızıntısı / anormal dışa aktarım","next":"data"},{"label":"Olay sonrası kalıcı önlemler (sıkılaştırma)","next":"harden"}]},"identity":{"kind":"step","title":"Kimlik olayı — belirti hangisi?","detail":"Çok sayıda başarısız login, brute-force / kimlik bilgisi deneme saldırısına işaret eder. Buna karşılık başarılı ama beklenmedik bir giriş (alışılmadık IP/saatte) hesabın ele geçirilmiş olabileceğini gösterir. İkisinde de önce kanıt topla, sonra müdahale et.","command":{"oracle":"SELECT username, os_username, userhost, timestamp, returncode FROM dba_audit_session WHERE returncode <> 0 ORDER BY timestamp DESC;","postgres":"-- log dosyasında başarısız girişler: grep 'password authentication failed' postgresql.log | awk '{print $NF}' | sort | uniq -c | sort -rn","mysql":"SELECT * FROM performance_schema.host_cache ORDER BY COUNT_AUTHENTICATION_ERRORS DESC;   -- ayrıca error log'da 'Access denied'","mssql":"-- hata log'unda başarısız login: EXEC xp_readerrorlog 0,1,N'Login failed';  ayrıca SELECT login_name, COUNT(*) FROM sys.dm_exec_sessions GROUP BY login_name;","mongodb":"-- audit log: grep 'authenticate' audit.json | grep '\"result\":18'  (18 = AuthenticationFailed)","redis":"ACL LOG   # başarısız kimlik/komut denemelerini gösterir","elasticsearch":"GET .security-audit-*/_search { \"query\": { \"match\": { \"event.action\": \"authentication_failed\" } } }"},"choices":[{"label":"Başarısız login patlaması (brute-force)","next":"id_bruteforce"},{"label":"Başarılı ama beklenmedik giriş (ele geçirme)","next":"id_compromised"}]},"id_bruteforce":{"kind":"solution","title":"Brute-force → kaynağı engelle ve hesabı koru","detail":"Başarısız login patlamasında henüz erişim sağlanmamış olabilir; amaç kaynağı engelleyip hesabı kilit/gecikme ile korumak ve olası sızmaları elemektir.","steps":["Saldıran IP'leri tespit et (yukarıdaki sorgular) ve ağ düzeyinde engelle: firewall / pg_hba.conf reject / listener ACL / security group.","Hedeflenen hesabı geçici kilitle — Oracle: ALTER USER hedef ACCOUNT LOCK;  PostgreSQL: ALTER ROLE hedef NOLOGIN;  SQL Server: ALTER LOGIN [hedef] DISABLE;  MySQL: ALTER USER 'hedef'@'%' ACCOUNT LOCK;  Redis: ACL SETUSER hedef off.","Login deneme sınırı / kilitlenme politikası uygula — Oracle: profildeki FAILED_LOGIN_ATTEMPTS; PostgreSQL: auth_delay modülü (shared_preload_libraries; kilitlemez, başarısız denemeleri geciktirir); MySQL: FAILED_LOGIN_ATTEMPTS ... PASSWORD_LOCK_TIME.","Hedeflenen hesabın parolasını yine de güçlü bir değerle sıfırla (deneme başarılı olmuş olabilir).","Bir denemenin başarıya ulaşıp ulaşmadığını doğrula: aynı IP'den başarılı bir giriş var mı diye kontrol et; varsa ele geçirme dalını da uygula.","Olayı zaman çizelgesiyle kaydet ve kalıcı önlemler için sıkılaştırma adımını uygula (root'tan 'Olay sonrası kalıcı önlemler')."],"related":["change-password","list-users"],"playbook":"harden-sql"},"id_compromised":{"kind":"solution","title":"Ele geçirilmiş hesap → durdur, incele, kimlik bilgisini döndür","detail":"Beklenmedik başarılı giriş, hesabın ele geçirildiğine işaret eder. Önce hesabı ve oturumlarını durdur, ne yaptığını incele, sonra parolayı sıfırla ve erişim kaynağını daralt.","steps":["Hesabı hemen kilitle (yukarıdaki LOCK/DISABLE komutları) ve aktif oturumları sonlandır — Oracle: ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE;  PostgreSQL: SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE usename='hesap';  SQL Server: KILL <spid>;  MySQL: KILL <id>;  Redis: CLIENT KILL.","Hesabın oturumda ne yaptığını incele: audit/log'da çalıştırdığı sorgular, eriştiği tablolar, yaptığı GRANT/CREATE işlemleri.","Parolayı güçlü bir değerle sıfırla ve ilgili tüm servis/uygulama kimlik bilgilerini döndür (rotate).","Saldırganın açmış olabileceği yeni hesap veya yetki değişikliğini ara (yetki dalını da uygula).","Erişim kaynağını daralt: hesabın yalnızca bilinen IP'lerden bağlanmasına izin ver (pg_hba.conf / listener ACL / firewall).","Kalıcı önlemler için sıkılaştırma adımını uygula (root'tan 'Olay sonrası kalıcı önlemler')."],"related":["change-password","list-users","show-privileges"],"playbook":"harden-sql"},"privilege":{"kind":"solution","title":"Yetki yükseltme → fazla yetkiyi denetle ve geri al","detail":"Beklenmedik bir GRANT, rol ataması ya da yeni bir yüksek yetkili hesap, ele geçirmenin ikinci aşaması (kalıcılık/yetki yükseltme) olabilir. Son yetki değişikliklerini denetleyip meşru olmayanları geri al ve en az yetki ilkesine dön.","steps":["Son yetki değişikliklerini denetle — Oracle: SELECT * FROM dba_audit_trail WHERE action_name IN ('GRANT','REVOKE','CREATE USER') ORDER BY timestamp DESC;  SQL Server: default trace / Server Audit'te GRANT olayları ve SELECT * FROM sys.server_permissions;  MySQL: audit log'da GRANT ve SELECT * FROM mysql.user;  MongoDB: db.getRoles({showPrivileges:true}).","Mevcut yetkileri listele — Oracle: SELECT grantee, privilege FROM dba_sys_privs WHERE grantee='HESAP';  PostgreSQL: SELECT * FROM information_schema.role_table_grants WHERE grantee='hesap';  MySQL: SHOW GRANTS FOR 'hesap'@'%';","Meşru olmayan fazla yetkiyi geri al — Oracle: REVOKE DBA FROM hesap;  PostgreSQL: REVOKE ALL ON ... FROM hesap; ALTER ROLE hesap NOSUPERUSER;  SQL Server: ALTER SERVER ROLE [sysadmin] DROP MEMBER [hesap];  MySQL: REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'hesap'@'%';","Saldırganın açmış olabileceği gizli/yedek hesapları ara ve kaldır (beklenmedik CREATE USER kayıtları).","PUBLIC role'e veya geniş rollere verilmiş aşırı yetkileri gözden geçirip daralt.","Değişikliklerin meşru bir değişiklik talebiyle eşleştiğini doğrula; eşleşmeyen her şeyi olay olarak işle ve sıkılaştırma adımını uygula."],"related":["show-privileges","list-users","create-user-grant"],"playbook":"harden-sql"},"data":{"kind":"solution","title":"Veri sızıntısı → erişimi kes ve kapsamı belirle","detail":"Anormal büyük sorgu/dışa aktarım ya da beklenmedik dış bağlantı, veri sızıntısına işaret eder. Önce aktif tehlikeli bağlantıları kes, sonra audit/log ile hangi verinin, kim tarafından, ne zaman erişildiğini belirleyerek kapsamı çıkar.","steps":["Aktif bağlantı kaynaklarını incele — PostgreSQL: SELECT pid, usename, client_addr, state, query FROM pg_stat_activity WHERE client_addr IS NOT NULL;  Oracle: SELECT sid, serial#, username, machine, program FROM v$session;  SQL Server: SELECT * FROM sys.dm_exec_connections;  MongoDB: db.currentOp(true);  Redis: CLIENT LIST.","Şüpheli/harici bağlantıları hemen kes ve o hesabı kilitle (KILL/LOCK komutları).","Ağ düzeyinde kaynağı engelle: firewall / pg_hba.conf / listener ACL ile şüpheli IP bloğunu kapat.","Audit log'u incele — hangi tablolara SELECT/EXPORT yapıldığını, satır sayısını ve zaman aralığını çıkar (Oracle unified_audit_trail; SQL Server sys.fn_get_audit_file; PostgreSQL pgaudit log'ları; MongoDB auditLog).","Dışa aktarım izlerini ara: büyük sonuç kümeleri, COPY / SELECT ... INTO OUTFILE, mongoexport, toplu okuma desenleri.","Etkilenen veri kapsamını (hangi tablolar, hangi kişisel/gizli alanlar) ve olası veri hacmini belgele; yasal/ihbar yükümlülüklerini değerlendir ve sıkılaştırma adımını uygula."],"related":["show-privileges","list-users"],"playbook":"harden-sql"},"harden":{"kind":"solution","title":"Olay sonrası kalıcı sıkılaştırma","detail":"Acil müdahaleden sonra tekrarı önlemek için kalıcı kontroller uygula: denetimi (audit) aç, en az yetki ilkesini uygula, ağ erişimini kısıtla ve olayı eksiksiz kaydet.","steps":["Denetimi aç: kritik olayları (login, GRANT/REVOKE, hassas tablo erişimi) audit'e al — ayrıntı için 'Denetim (audit) kurulumu' ağacını izle.","En az yetki ilkesi: her hesaba yalnızca gereken yetkiyi ver, paylaşımlı/servis hesaplarını ayrıştır, kullanılmayan hesapları kapat.","Parola/kimlik politikası: güçlü parola, düzenli rotasyon, mümkünse çok faktörlü kimlik doğrulama ve merkezi kimlik (LDAP/Kerberos).","Ağ kısıtlama: veritabanını yalnızca uygulama sunucularına aç (firewall, security group, pg_hba.conf, listener ACL); doğrudan internet erişimini kapat.","Şifreleme: hareket hâlinde TLS, gerekli yerde bekleyen veride (at-rest) şifreleme aç.","İzleme/alarm: başarısız login artışı, yeni GRANT ve anormal veri hacmi için alarm kur.","Olay kaydı: zaman çizelgesi, etkilenen varlıklar, alınan aksiyonlar ve öğrenilen dersleri raporla; runbook'u güncelle."],"related":["list-users","show-privileges","change-password"]}}},"solver/audit-setup.json":{"id":"audit-setup","title":"Denetim (audit) kurulumu","icon":"🧾","category":"Güvenlik","intro":"Neyi denetlemek istediğine (giriş/oturum, DDL/şema değişimi, veri erişimi ya da yetki değişimi) göre doğru veritabanı motorunda audit'i o kapsam için açan, ardından kayıtları okuma ve saklama/rotasyon adımlarını veren karar ağacı.","start":"root","nodes":{"root":{"kind":"step","title":"Neyi denetlemek istiyorsun?","detail":"Denetim kapsamını seç. Her şeyi denetlemek gürültü ve maliyet yaratır; ihtiyacına göre daralt. Giriş/oturum olaylarını mı, DDL/şema değişimlerini mi, veri erişimini (DML/SELECT) mi, yoksa yetki (GRANT/REVOKE) değişimlerini mi izlemek istiyorsun?","choices":[{"label":"Giriş / oturum (login, connect)","next":"login"},{"label":"DDL / şema değişimi (CREATE/ALTER/DROP)","next":"ddl"},{"label":"Veri erişimi (DML / SELECT)","next":"dml"},{"label":"Yetki değişimi (GRANT / REVOKE)","next":"grants"},{"label":"Audit kaydını okuma ve saklama / rotasyon","next":"retention"}]},"login":{"kind":"solution","title":"Giriş / oturum denetimi","detail":"Başarılı ve başarısız girişleri, kim-nereden-ne zaman bağlandığını kaydeder. Yetkisiz erişim ve brute-force tespitinin temelidir. Motor bazında ilgili politikayı aç, sonra kaydı oku ve sakla.","steps":["Oracle (Unified Auditing): CREATE AUDIT POLICY login_pol ACTIONS LOGON, LOGOFF;  AUDIT POLICY login_pol;  (başarısızlar için: AUDIT POLICY login_pol WHENEVER NOT SUCCESSFUL;).","PostgreSQL: postgresql.conf içinde log_connections=on, log_disconnections=on ayarla ve reload et; pgaudit gerekmeden bağlantılar log'a düşer.","MySQL/MariaDB: audit_log eklentisini kur (INSTALL PLUGIN audit_log ...) ve SET GLOBAL audit_log_policy='LOGINS'; (MariaDB: server_audit_events='CONNECT').","SQL Server: Server Audit oluştur (CREATE SERVER AUDIT ...), Server Audit Specification'da FAILED_LOGIN_GROUP ve SUCCESSFUL_LOGIN_GROUP ekle, ikisini de ENABLE et.","MongoDB: --auditDestination file --auditFilter '{ atype: { $in: [\"authenticate\", \"logout\"] } }' ile başlat (Enterprise/Percona).","Redis: ACL LOG ile başarısız kimlik/komut denemelerini izle (ayrıntı için 'notify' değil ACL log'u).","Elasticsearch: elasticsearch.yml içinde xpack.security.audit.enabled: true ve include listesine authentication_success, authentication_failed ekle.","Kaydı okuma ve saklama/rotasyon için root'taki 'Audit kaydını okuma ve saklama / rotasyon' adımını uygula."],"related":["list-users","change-password"]},"ddl":{"kind":"solution","title":"DDL / şema değişimi denetimi","detail":"CREATE/ALTER/DROP gibi şema değişikliklerini kaydeder. İzinsiz nesne değişikliği, gizli tablo/backdoor ve yapı sürüklenmesini (drift) tespit etmek için kullanılır.","steps":["Oracle: CREATE AUDIT POLICY ddl_pol ACTIONS CREATE TABLE, ALTER TABLE, DROP TABLE, CREATE USER, ALTER USER;  AUDIT POLICY ddl_pol;","PostgreSQL (pgaudit): shared_preload_libraries='pgaudit' ile yükle, sonra ALTER SYSTEM SET pgaudit.log='ddl'; SELECT pg_reload_conf();","MySQL/MariaDB: audit_log ile SET GLOBAL audit_log_policy='ALL'; ardından log'da DDL ifadelerini filtrele (MariaDB: server_audit_events='QUERY_DDL').","SQL Server: Database Audit Specification'da SCHEMA_OBJECT_CHANGE_GROUP (ve DATABASE_OBJECT_CHANGE_GROUP) ekle ve ENABLE et.","MongoDB: --auditFilter '{ atype: { $in: [\"createCollection\",\"dropCollection\",\"createIndex\",\"dropIndex\",\"createDatabase\",\"dropDatabase\"] } }'.","Elasticsearch: audit include listesine index_creation/index_deletion ile ilgili olayları ekle; şema (mapping) değişiklikleri için _mapping çağrılarını request olarak logla.","Kaydı okuma ve saklama/rotasyon için root'taki 'Audit kaydını okuma ve saklama / rotasyon' adımını uygula."],"related":["show-privileges"]},"dml":{"kind":"solution","title":"Veri erişimi (DML / SELECT) denetimi","detail":"Hassas tablolardaki okuma/yazma (SELECT/INSERT/UPDATE/DELETE) erişimini kaydeder. Yüksek hacim üretebileceği için denetimi hassas nesnelerle sınırla. Sızıntı ve uyumluluk (KVKK/GDPR) için kritiktir.","steps":["Kapsamı daralt: tüm veriyi değil, yalnızca hassas tabloları/kolonları denetle (gürültü ve maliyet için).","Oracle: CREATE AUDIT POLICY dml_pol ACTIONS SELECT, INSERT, UPDATE, DELETE ON HR.MAASLAR;  AUDIT POLICY dml_pol;","PostgreSQL (pgaudit): nesne düzeyi için ALTER SYSTEM SET pgaudit.log='read,write'; ya da hedefli olarak audit rolüne yalnızca ilgili tablolarda yetki verip pgaudit.role ayarla.","MySQL/MariaDB: audit_log filtresiyle yalnızca ilgili tablo/kullanıcıları logla (audit_log_filter / MariaDB server_audit_events='QUERY_DML').","SQL Server: Database Audit Specification'da SELECT, INSERT, UPDATE, DELETE eylemlerini belirli tablo ve principal (ör. public) için ekle ve ENABLE et.","MongoDB: --auditFilter '{ atype: \"authCheck\", \"param.command\": { $in: [\"find\",\"insert\",\"update\",\"delete\"] }, \"param.ns\": \"db.hassas\" }' (yüksek hacme dikkat).","Elasticsearch: audit include listesine access_granted/access_denied ekle ve emit_request_body ile hangi index'e sorgu gittiğini gör (hassas veride gövdeyi loglarken dikkatli ol).","Kaydı okuma ve saklama/rotasyon için root'taki 'Audit kaydını okuma ve saklama / rotasyon' adımını uygula."],"related":["show-privileges","list-users"]},"grants":{"kind":"solution","title":"Yetki değişimi (GRANT / REVOKE) denetimi","detail":"Yetki ve rol değişikliklerini (GRANT/REVOKE, rol atama, kullanıcı oluşturma) kaydeder. Yetki yükseltme ve backdoor hesap tespitinin temelidir; genellikle düşük hacimli ama yüksek değerli bir denetimdir.","steps":["Oracle: CREATE AUDIT POLICY priv_pol ACTIONS GRANT, REVOKE, CREATE USER, ALTER USER, CREATE ROLE;  AUDIT POLICY priv_pol;","PostgreSQL (pgaudit): ALTER SYSTEM SET pgaudit.log='role'; SELECT pg_reload_conf();  (GRANT/REVOKE/CREATE ROLE olaylarını yakalar).","MySQL/MariaDB: audit_log ile GRANT/REVOKE/CREATE USER ifadelerini logla (policy 'ALL' veya DDL) ve filtrede ACL ifadelerini tut.","SQL Server: Server Audit Specification'da SERVER_PERMISSION_CHANGE_GROUP, SERVER_ROLE_MEMBER_CHANGE_GROUP ve DATABASE_PERMISSION_CHANGE_GROUP ekle ve ENABLE et.","MongoDB: --auditFilter '{ atype: { $in: [\"grantRolesToUser\",\"revokeRolesFromUser\",\"createUser\",\"dropUser\",\"createRole\"] } }'.","Elasticsearch: rol/kullanıcı değişiklikleri için audit'te security ile ilgili request olaylarını (realm/role API çağrıları) logla.","Kaydı okuma ve saklama/rotasyon için root'taki 'Audit kaydını okuma ve saklama / rotasyon' adımını uygula."],"related":["show-privileges","create-user-grant","list-users"]},"retention":{"kind":"solution","title":"Audit kaydını okuma ve saklama / rotasyon","detail":"Denetim ancak okunup saklandığında işe yarar. Kayıtları nasıl sorgulayacağını, nerede tutulduğunu ve büyümesini kontrol altında tutmak için saklama/rotasyon politikasını burada tanımla.","steps":["Kaydı oku — Oracle: SELECT event_timestamp, dbusername, action_name, object_name, sql_text FROM unified_audit_trail ORDER BY event_timestamp DESC;  PostgreSQL: pgaudit çıktısı sunucu log dosyasındadır (log_directory), grep ile 'AUDIT:' satırlarını süz.","SQL Server: SELECT * FROM sys.fn_get_audit_file('D:\\audit\\*.sqlaudit', DEFAULT, DEFAULT);  MySQL: audit_log dosyasını (JSON/XML) veya MariaDB server_audit.log'u oku; MongoDB: audit.json'u parse et; Elasticsearch: .security-audit-* index'lerini sorgula.","Saklama süresini belirle (uyumluluk gereğine göre, ör. 90 gün / 1 yıl) ve bunu politikaya yaz.","Rotasyon/temizlik — Oracle: DBMS_AUDIT_MGMT.SET_LAST_ARCHIVE_TIMESTAMP ve CLEAN_AUDIT_TRAIL ile eski kayıtları arşivle/temizle; PostgreSQL/MySQL/MongoDB dosya log'ları için logrotate ile boyut/zaman bazlı döndür.","Elasticsearch: audit index'leri için ILM politikası (rollover + delete) tanımla.","Audit kayıtlarını değiştirilemez (WORM) ve DBA'dan ayrı erişimli bir konuma yönlendir (görevler ayrılığı); erişimi kısıtla.","Depolama büyümesini izle: audit'in diski doldurmadığını ve performansı aşırı etkilemediğini periyodik kontrol et."],"related":["list-users","show-privileges"]}}},"solver/decide-ha.json":{"id":"decide-ha","title":"Karar: Hangi HA/DR çözümü?","icon":"🧭","category":"Karar Rehberi","intro":"Yüksek erişilebilirlik ve felaket kurtarma çözümü seçmek; teknoloji değil, iş gereksinimleri (RTO/RPO), coğrafi dağıtım ihtiyacı ve maliyet arasındaki dengeyle başlar. Bu ağaç, kesinti ve veri kaybı toleransınızdan yola çıkarak senkron replika, asenkron standby, otomatik failover kümesi ve yedek+PITR seçenekleri arasında sizi doğru yaklaşıma yönlendirir.","start":"root","nodes":{"root":{"kind":"step","title":"Veri kaybı toleransın (RPO) ne kadar?","detail":"Önce en sert kısıttan başla: bir felakette kaç saniyelik veriyi kaybetmeyi göze alabilirsin? Sıfır veri kaybı (RPO=0) gerekiyorsa senkron replikasyon şart; birkaç saniye/dakika kabul edilebiliyorsa asenkron çözümler ve daha ucuz yaklaşımlar açılır. RPO hedefi çoğu zaman diğer tüm kararları belirler.","choices":[{"label":"Sıfır veri kaybı şart (RPO = 0)","next":"rpo_zero"},{"label":"Birkaç saniye/dakika veri kaybı kabul edilebilir","next":"rpo_soft"}]},"rpo_zero":{"kind":"step","title":"Otomatik ve hızlı devralma (düşük RTO) da gerekli mi?","detail":"Sıfır veri kaybı istiyorsun; peki primary düştüğünde ne kadar hızlı ayağa kalkmalısın? Saniyeler içinde otomatik failover mı, yoksa kısa bir elle müdahale penceresi kabul edilebilir mi? Bu, salt senkron replika ile tam otomatik küme arasındaki farkı belirler.","choices":[{"label":"Saniyeler içinde otomatik failover gerekli","next":"sol_cluster"},{"label":"Elle/planlı devralma yeterli, önce sıfır kayıp önemli","next":"sol_sync"}]},"rpo_soft":{"kind":"step","title":"Farklı bir bölge/coğrafya gerekli mi (DR)?","detail":"Biraz veri kaybı kabul edilebiliyorsa asıl soru dayanıklılığın kapsamı: tüm veri merkezini/bölgeyi kaybetme senaryosuna karşı korunmalı mısın, yoksa aynı bölgede tek düğüm arızasına karşı yeterli mi? Coğrafi dağıtım gerekiyorsa asenkron standby öne çıkar; gerekmiyorsa maliyet öncelikli seçenekler değerlendirilir.","choices":[{"label":"Evet, coğrafi felakete karşı ayrı bölge şart","next":"sol_async"},{"label":"Hayır, bütçe ve basitlik öncelikli","next":"budget"}]},"budget":{"kind":"step","title":"Uzun kurtarma süresini (yüksek RTO) kabul eder misin?","detail":"Aynı bölgede kalıyorsun ve veri kaybı toleransın var. En düşük maliyeti mi hedefliyorsun yoksa arıza anında hızlı devreye girecek bir yedek düğüm mü istiyorsun? Kurtarmanın saatler sürmesi kabul edilebiliyorsa yalnızca yedek+PITR en ekonomik yoldur; değilse bir hot standby gerekir.","choices":[{"label":"Evet, saatlerce kurtarma kabul edilebilir (en ucuz)","next":"sol_backup"},{"label":"Hayır, dakikalar içinde devralacak hot standby gerekli","next":"sol_async"}]},"sol_sync":{"kind":"solution","title":"Öneri: Senkron replika (sıfır veri kaybı)","detail":"Primary her commit'i en az bir standby onaylamadan tamamlamaz; böylece primary kaybedilse bile onaylanmış hiçbir işlem yitmez (RPO=0). Aynı bölgede, düşük gecikmeli ağda ideal çözümdür.","steps":["Neden: Onaylanmış transaction'lar standby'a yazılmadan commit tamamlanmaz, bu yüzden veri kaybı matematiksel olarak sıfırdır.","Ne zaman: Finansal/kritik OLTP, aynı bölge (aynı/komşu availability zone), düşük RTT ağ mevcutken.","Örnek: PostgreSQL synchronous_commit + synchronous_standby_names, MySQL Group Replication / semisync, Oracle Data Guard SYNC (Maximum Protection/Availability).","Dikkat: Senkron onay her commit'e ağ gecikmesi ekler; standby yavaşlar/kopar ve tek senkron kopya varsa ana da yazmayı durdurabilir. En az iki standby veya uygun fallback ile tasarla.","Dikkat: Uzak/yüksek gecikmeli bölgeye senkron yapma; yazma performansı çöker. Coğrafi DR için asenkron kullan."],"related":["replication-status","promote-failover"]},"sol_async":{"kind":"solution","title":"Öneri: Asenkron standby (coğrafi DR)","detail":"Standby, değişiklikleri primary'nin commit'ini geciktirmeden akış hâlinde uygular. Yazma performansını düşürmeden farklı bölgeye kopya taşımanın standart yoludur; karşılığında küçük bir veri kaybı penceresi (replikasyon lag'i kadar) kabul edilir.","steps":["Neden: Primary standby onayını beklemez, bu yüzden uzak bölgeye replikasyon yazma gecikmesi yaratmaz.","Ne zaman: Bölge/veri merkezi düzeyinde felaket kurtarma gerektiğinde ve saniyeler mertebesinde veri kaybı kabul edilebiliyorken.","Örnek: PostgreSQL streaming replication (async), MySQL asenkron replikasyon, Oracle Data Guard ASYNC (Maximum Performance).","Dikkat: Failover anında lag kadar veri kaybedebilirsin; replikasyon gecikmesini sürekli izle ve eşik alarmı kur.","Dikkat: Devralma genelde elle veya harici bir orkestrasyonla yapılır; net bir failover prosedürü ve düzenli tatbikat şart."],"related":["replication-status","promote-failover"]},"sol_cluster":{"kind":"solution","title":"Öneri: Otomatik failover kümesi","detail":"Sağlık izleme, lider seçimi ve otomatik devralmayı bir arada sunan küme çözümü; hem düşük RTO (saniyeler içinde otomatik failover) hem de senkron kopyayla düşük/sıfır RPO hedefler. İşletme yükü daha yüksektir ama insan müdahalesini en aza indirir.","steps":["Neden: Küme yöneticisi primary arızasını otomatik algılar, sağlıklı bir kopyayı yükseltir ve trafiği yönlendirir; gece yarısı elle müdahale gerekmez.","Ne zaman: Hem düşük RTO hem düşük RPO şartsa ve operasyon ekibi ek karmaşıklığı yönetebiliyorsa.","Örnek: PostgreSQL için Patroni/etcd, MySQL InnoDB Cluster (Group Replication + MySQL Router), SQL Server Always On Availability Groups, Oracle RAC + Data Guard Fast-Start Failover (otomatik failover için FSFO ve observer gerekir).","Dikkat: Split-brain riski gerçektir; düzgün fencing/quorum (tek sayı düğüm, güvenilir dağıtık depo) olmadan kurma.","Dikkat: Kümenin kendisi yeni bir arıza yüzeyidir; failover'ı düzenli olarak tatbik et ve otomasyonu gerçek koşullarda doğrula."],"related":["promote-failover","replication-status"]},"sol_backup":{"kind":"solution","title":"Öneri: Yedek + PITR (en ekonomik)","detail":"Ayakta duran bir standby yerine yalnızca düzenli yedek ve WAL/arşiv log ile noktaya kadar kurtarma (PITR) tutulur. En düşük maliyetli çözümdür; bedeli, kurtarmanın saatler sürebilmesidir (yüksek RTO).","steps":["Neden: Sürekli çalışan ikinci bir düğümün maliyeti yoktur; yalnızca yedek depolama ve arşiv log tutulur.","Ne zaman: Kesinti toleransı yüksek, kritik olmayan sistemler; dev/test ortamları; bütçe ve basitlik önceliğinde.","Örnek: Fiziksel yedek + arşiv log ile PITR (PG base backup + WAL, Oracle RMAN + archivelog, MySQL xtrabackup + binlog).","Dikkat: RTO yüksektir — geri yükleme + log uygulama süresi veri boyutuyla büyür; kabul ettiğin süreyi ölçerek doğrula.","Dikkat: Test edilmemiş yedek yedek değildir; geri yükleme tatbikatını ve yedek doğrulamayı düzenli yap."],"related":["last-backup-status","logical-dump"]}}},"solver/decide-isolation.json":{"id":"decide-isolation","title":"Karar: Hangi izolasyon seviyesi?","icon":"🧭","category":"Karar Rehberi","intro":"Transaction izolasyon seviyesi, eşzamanlılık ile tutarlılık arasındaki dengeyi belirler. Yüksek izolasyon daha az anomali ama daha çok kilitlenme/çakışma ve yeniden deneme demektir. Bu ağaç, hangi okuma anomalilerine (dirty, non-repeatable, phantom) tolerans gösterdiğine göre Read Committed, Repeatable Read/Snapshot ve Serializable arasında seçim yapmanı sağlar.","start":"root","nodes":{"root":{"kind":"step","title":"Dirty read'e toleransın var mı?","detail":"En temel anomaliyle başla: bir transaction, henüz commit edilmemiş (belki geri alınacak) veriyi okuyabilmeli mi? Neredeyse hiçbir ciddi uygulama bunu istemez; modern motorların çoğunda varsayılan zaten dirty read'i engeller. Yalnızca yaklaşık/analitik kaba sayımlarda ve maksimum hız için gevşetilir.","choices":[{"label":"Hayır, kesinlikle commit'lenmiş veriyi okumalıyım","next":"committed"},{"label":"Evet, kaba/yaklaşık okuma yeterli (nadir)","next":"sol_read_uncommitted"}]},"committed":{"kind":"step","title":"Aynı işlemde tekrar okuduğunda aynı sonucu görmen şart mı?","detail":"Dirty read'i elediysen sıradaki soru: bir transaction içinde aynı satırı iki kez okursan, arada başkası commit'lediği için farklı değer görmen (non-repeatable read) veya yeni satırların belirmesi (phantom) senin için sorun mu? Rapor/hesaplama tutarlılığı gerektiren mantık genelde tutarlı bir snapshot ister.","choices":[{"label":"Hayır, her ifadenin en güncel commit'li veriyi görmesi iyi","next":"sol_read_committed"},{"label":"Evet, transaction boyunca tutarlı bir snapshot gerekli","next":"consistent"}]},"consistent":{"kind":"step","title":"Eşzamanlı işlemler mantıksal olarak tam sıralı mı olmalı?","detail":"Tutarlı okuma istiyorsun; peki bu yeterli mi, yoksa eşzamanlı işlemlerin sanki tek tek, sırayla çalışmış gibi (serileştirilebilir) bir sonuç mu üretmesi şart? Write-skew gibi ince anomalilere (ör. iki işlemin farklı satırları okuyup birbirini geçersiz kılan yazması) tahammülün varsa Snapshot yeter; yoksa tam serileştirme gerekir.","choices":[{"label":"Hayır, tutarlı snapshot yeterli","next":"sol_repeatable_read"},{"label":"Evet, hiçbir eşzamanlılık anomalisi kabul edilemez","next":"sol_serializable"}]},"sol_read_uncommitted":{"kind":"solution","title":"Öneri: Read Uncommitted (yalnızca özel durumlar)","detail":"En düşük izolasyon; dirty read'e izin verir. Lock'ları neredeyse hiç beklemeden okur ama geri alınabilecek veriyi görebilirsin. Genel amaçlı uygulamalarda önerilmez.","steps":["Neden: Okuyucu, yazıcının lock'unu beklemez; maksimum eşzamanlılık ama tutarlılık garantisi yok.","Ne zaman: Yalnızca kesinliği önemsiz kaba metrik/ilerleme sayımı gibi durumlarda.","Dikkat: PostgreSQL'de bu seviye Read Committed gibi davranır, Oracle ise Read Uncommitted'ı hiç sunmaz; asıl dirty read çoğunlukla lock tabanlı SQL Server'da gündeme gelir (NOLOCK).","Dikkat: 'Hız için NOLOCK' kalıcı bir alışkanlık olmamalı; yanlış/çift/eksik satır okuma riski taşır."]},"sol_read_committed":{"kind":"solution","title":"Öneri: Read Committed (varsayılan OLTP)","detail":"Her ifade, o an commit'lenmiş en güncel veriyi görür; dirty read engellenir. Çoğu motorun varsayılanıdır ve tipik OLTP yükleri için eşzamanlılık/tutarlılık dengesi en iyisidir.","steps":["Neden: Dirty read'i engeller ama transaction'ı gereksiz yere uzun süre lock tutmaya zorlamaz; yüksek eşzamanlılık sağlar.","Ne zaman: Kısa, hedefli OLTP işlemleri; web uygulamalarının büyük çoğunluğu için doğru varsayılan.","Örnek: PostgreSQL, SQL Server ve Oracle'ın varsayılanı Read Committed'dır (Oracle'da tutarlılık statement-level snapshot ile sağlanır).","Dikkat: Aynı işlemde iki okuma farklı sonuç verebilir (non-repeatable/phantom); tutarlı raporlama gereken mantığı buna dayandırma.","Dikkat: MySQL/InnoDB'nin varsayılanı Repeatable Read'dir; motor farkını bilerek taşıma yap."]},"sol_repeatable_read":{"kind":"solution","title":"Öneri: Repeatable Read / Snapshot (tutarlı okuma)","detail":"Transaction, başında (veya ilk okumasında) sabitlenen tutarlı bir snapshot üzerinden çalışır; transaction boyunca okumalar değişmez. MVCC ile okuyucular yazıcıları, yazıcılar okuyucuları bloklamaz.","steps":["Neden: Transaction boyunca sabit bir görünüm sağlar; non-repeatable read'i (MVCC motorlarında pratikte phantom'ı da) engeller, çok okumalı rapor/hesap mantığını tutarlı kılar.","Ne zaman: Bir işlemde aynı veriyi birden çok kez okuyup tutarlı sonuç isteyen raporlar, mutabakat ve toplu hesaplamalar.","Örnek: MySQL/InnoDB varsayılanı Repeatable Read; SQL Server SNAPSHOT (row-versioning); PostgreSQL REPEATABLE READ; Oracle SERIALIZABLE aslında snapshot semantiğidir.","Dikkat: Write-skew gibi serileştirme anomalilerini engellemez; iş kuralı bunu gerektiriyorsa Serializable'a çık.","Dikkat: Snapshot/row-versioning tempdb veya undo/version deposu büyümesi yaratabilir; uzun transaction'lar eski sürümleri şişirir."]},"sol_serializable":{"kind":"solution","title":"Öneri: Serializable (tam izolasyon)","detail":"En yüksek izolasyon: eşzamanlı transaction'lar, bir seri (tek tek, sırayla) çalıştırılmış gibi bir sonuç üretir. Tüm okuma anomalilerini ve write-skew'i engeller; bedeli daha fazla çakışma ve yeniden deneme ihtiyacıdır.","steps":["Neden: Sonucun her zaman geçerli bir seri çalıştırmaya eşdeğer olduğunu garanti eder; tüm eşzamanlılık anomalilerini ortadan kaldırır.","Ne zaman: Doğruluğu kritik değişmezler (invariant) taşıyan mantık — bakiye/stok kontrolü, çift rezervasyonun kesinlikle olmaması gereken durumlar.","Örnek: PostgreSQL SSI (Serializable Snapshot Isolation), SQL Server SERIALIZABLE (range lock'ları), Oracle'da gerçek serileştirme uygulama düzeyinde ele alınır.","Dikkat: Serileştirme hatası (ör. PG'de 40001) beklenen davranıştır; uygulamada işlemi otomatik yeniden deneyecek retry mantığı ŞART.","Dikkat: Yoğun çakışan yükte throughput düşebilir; her yere değil yalnızca doğruluğun kritik olduğu işlemlere uygula."]}}},"solver/decide-sqlnosql.json":{"id":"decide-sqlnosql","title":"Karar: SQL mi NoSQL mi (hangi veritabanı ailesi)?","icon":"🧭","category":"Karar Rehberi","intro":"Doğru veritabanı ailesini seçmek, veri modelinin şekliyle, tutarlılık ve ölçek önceliğinle ve sorgu karmaşıklığınla belirlenir. 'NoSQL daha modern' gibi genellemeler yanıltıcıdır; her aile belirli erişim desenleri için tasarlanmıştır. Bu ağaç, verinin yapısından başlayarak ilişkisel, belge, anahtar-değer ve arama motorları arasında sizi doğru araca yönlendirir ve gerektiğinde poliglot yaklaşımı hatırlatır.","start":"root","nodes":{"root":{"kind":"step","title":"Verinin doğası ve baskın erişim deseni ne?","detail":"En belirleyici soruyla başla: veri güçlü ilişkilere sahip yapısal kayıtlar mı, esnek/değişken şemalı belgeler mi, basit anahtar-değer aramaları mı, yoksa metin arama gibi özel bir ihtiyaç mı? Verinin şekli ve onu nasıl sorguladığın, aileyi büyük ölçüde belirler.","choices":[{"label":"İlişkisel, yapısal kayıtlar ve karmaşık sorgular","next":"relational_check"},{"label":"Esnek/değişken şemalı, iç içe belgeler","next":"sol_document"},{"label":"Basit anahtar-değer, çok düşük gecikme/önbellek","next":"sol_keyvalue"},{"label":"Tam metin / faceted arama, log analizi","next":"sol_search"}]},"relational_check":{"kind":"step","title":"Güçlü tutarlılık (ACID) mı yoksa yatay ölçek mi öncelikli?","detail":"Veri ilişkisel görünüyor; ama önceliğin ne? Çok tablolu join'ler, işlem bütünlüğü ve güçlü tutarlılık (ACID) mı esas, yoksa tek düğüme sığmayacak devasa hacmi yatay olarak ölçeklemek mi? İlişkisel model çoğu iş yükü için doğru varsayılandır; sınır, ölçek gerçekten tek düğümü aştığında zorlanır.","choices":[{"label":"ACID, join ve karmaşık sorgu bütünlüğü öncelikli","next":"sol_relational"},{"label":"Ölçek her şeyden önce, ilişki/join zayıf","next":"sol_document"}]},"sol_relational":{"kind":"solution","title":"Öneri: İlişkisel veritabanı (RDBMS)","detail":"Yapısal, güçlü ilişkili veri ve işlem bütünlüğü gerektiren yükler için doğru varsayılan. ACID garantileri, olgun SQL sorgu motoru ve join'lerle karmaşık soruları güvenle yanıtlar.","steps":["Neden: ACID transaction'lar, foreign key bütünlüğü ve güçlü tutarlılık; birden çok tabloyu birleştiren karmaşık sorguları optimize eden olgun bir planlayıcı sunar.","Ne zaman: Finans, sipariş/stok, ERP/CRM gibi ilişkilerin ve tutarlılığın kritik olduğu OLTP ve raporlama yükleri.","Örnek: PostgreSQL, MySQL, Oracle, SQL Server; zaman-serisi ihtiyacında PostgreSQL + TimescaleDB gibi eklentiler.","Dikkat: Şema değişikliği (migration) disiplin ister; sık ve öngörülemez şema değişimi varsa belge modelini değerlendir.","Dikkat: Tek düğüm yazma/veri sınırına ulaşırsan read replica, partition ve gerekiyorsa sharding ile ölçeklendir."],"related":["create-partition"]},"sol_document":{"kind":"solution","title":"Öneri: Belge veritabanı","detail":"Esnek, iç içe ve sık değişen şemalı veriyi doğal biçimde (JSON benzeri belgeler) saklar. Çoğunlukla tek belge üzerinden okunan/yazılan, join'e az ihtiyaç duyan uygulamalar ve yatay ölçek için uygundur.","steps":["Neden: Şema esnektir; belgeler alan ekleyip çıkarabilir, iç içe yapıları tek okuma ile getirir ve yatay ölçeğe (sharding) elverişlidir.","Ne zaman: Katalog, kullanıcı profili, içerik/CMS, olay kayıtları gibi belge merkezli, değişken yapılı ve hızlı evrilen veri modelleri.","Örnek: MongoDB, Couchbase; ilişkisel dünyada da JSONB (PostgreSQL) benzer esnekliği sınırlı ölçüde sunar.","Dikkat: Çok belgeli karmaşık join ve raporlama zayıftır; ilişkiler ağır basıyorsa ilişkisel model daha uygundur.","Dikkat: Tutarlılık ve şema doğrulama sorumluluğu büyük ölçüde uygulamaya kayar; veri kalitesini kod tarafında koru."]},"sol_keyvalue":{"kind":"solution","title":"Öneri: Anahtar-değer deposu / önbellek","detail":"Anahtara göre çok hızlı okuma/yazma gereken, karmaşık sorgu istemeyen yükler için tasarlanmıştır. Genellikle bellek içi çalışır ve mikro-saniye/mili-saniye gecikme sağlar; önbellek, oturum ve sayaç gibi görevlerde idealdir.","steps":["Neden: Basit anahtar erişimi için son derece düşük gecikme ve yüksek throughput; bellek içi yapılarla ilişkisel yükü ortadan kaldırır.","Ne zaman: Önbellek katmanı, oturum deposu, rate-limit sayaçları, sıralama tabloları (leaderboard), geçici kuyruk/pub-sub.","Örnek: Redis, Memcached; Redis ayrıca liste/set/sorted-set gibi zengin yapılar ve kalıcılık seçenekleri sunar.","Dikkat: Genelde tek gerçeklik kaynağı değildir; kaynak veriyi kalıcı bir veritabanında tut, burada türev/önbellek veri sakla.","Dikkat: Bellek sınırlı ve pahalıdır; eviction politikası, TTL ve kalıcılık/dayanıklılık ayarlarını iş ihtiyacına göre planla."]},"sol_search":{"kind":"solution","title":"Öneri: Arama / analiz motoru","detail":"Tam metin arama, alaka sıralaması (relevance), faceted filtreleme ve büyük hacimli log/metin analizi için özelleşmiş ters index (inverted index) tabanlı motor. İlişkisel LIKE sorgularının çözemediği arama deneyimini karşılar.","steps":["Neden: Ters index ve skorlama ile tam metin arama, otomatik tamamlama, faset ve toplulaştırmayı yüksek performansla yapar.","Ne zaman: Ürün/site araması, log ve gözlemlenebilirlik (observability) analizi, alaka sıralı arama deneyimi gereken uygulamalar.","Örnek: Elasticsearch/OpenSearch, Apache Solr; PostgreSQL tsvector orta ölçekli tam metin için yeterli olabilir.","Dikkat: Genelde birincil kayıt deposu değildir; ana veriyi ilişkisel/belge DB'de tut, arama index'ini oradan besle (CDC/senkron).","Dikkat: Gerçek zamanlı güçlü tutarlılık garantisi zayıftır (near-real-time indeksleme); indeksleme gecikmesini tasarımda hesaba kat."],"related":["setup-cdc-replication"]}}},"solver/decide-shard-replica.json":{"id":"decide-shard-replica","title":"Karar: Sharding mi Replikasyon mu (ölçekleme)?","icon":"🧭","category":"Karar Rehberi","intro":"Veritabanı ölçekleme kararı, darboğazın okuma mı yazma mı olduğuna ve verinin tek düğüme sığıp sığmadığına göre değişir. Yanlış strateji, gereksiz karmaşıklık veya çözülmeyen darboğaz demektir. Bu ağaç, önce en ucuz ve basit yolları (dikey ölçek, önbellek) hatırlatarak read replica ile sharding arasında doğru seçimi yapmanı sağlar.","start":"root","nodes":{"root":{"kind":"step","title":"Önce en basit yolu denedin mi: dikey ölçek ve sorgu iyileştirme?","detail":"Dağıtık mimariye geçmeden önce en ucuz kazanımı ele: donanımı büyütmek (CPU/RAM/IOPS), eksik index'leri eklemek ve pahalı sorguları düzeltmek çoğu darboğazı çözer. Karmaşıklığı ancak bunlar tükendiğinde artır.","choices":[{"label":"Hayır / henüz sınıra gelmedim","next":"sol_vertical"},{"label":"Evet, dikey ölçek ve tuning yetmiyor","next":"bottleneck"}]},"bottleneck":{"kind":"step","title":"Darboğaz okuma mı yoksa yazma/veri hacmi mi?","detail":"Ölçek sorununun kaynağını ayır: çok sayıda okuma sorgusu tek düğümü mü boğuyor (okuma ağırlıklı), yoksa yazma hızı veya toplam veri boyutu tek düğümün kapasitesini mi aşıyor (yazma/hacim ağırlıklı)? Bu ayrım, replika ile sharding arasındaki temel farktır.","choices":[{"label":"Okuma trafiği baskın, yazma tek düğüme sığıyor","next":"read_path"},{"label":"Yazma hızı veya veri hacmi tek düğümü aşıyor","next":"sol_sharding"}]},"read_path":{"kind":"step","title":"Okumalar tekrarlı/önbelleklenebilir mi, yoksa taze ve çeşitli mi?","detail":"Okuma darboğazında bir adım daha ayır: aynı sonuçlar tekrar tekrar mı okunuyor (önbellek çok etkili olur), yoksa okumalar çeşitli, geniş ve güncel veri mi istiyor (ek okuma kapasitesi gerekir)? Bu, önbellek katmanı ile read replica arasında seçim yaptırır.","choices":[{"label":"Aynı veriler tekrar okunuyor, hafif eskime kabul","next":"sol_cache"},{"label":"Çeşitli/taze okuma, ham okuma kapasitesi gerek","next":"sol_read_replica"}]},"sol_vertical":{"kind":"solution","title":"Öneri: Önce dikey ölçek + sorgu iyileştirme","detail":"Dağıtık mimariye geçmeden önce başvurulacak ilk ve en ucuz yol. Donanımı büyütmek ve sorguları/index'leri düzeltmek, çoğu ölçek sorununu operasyonel karmaşıklık eklemeden çözer.","steps":["Neden: En düşük karmaşıklık ve risk; tek düğüm kalırsan işlem/tutarlılık modelin değişmez, uygulama kodunu bölmen gerekmez.","Ne zaman: Henüz tek düğümün donanım tavanına ulaşmadıysan veya darboğaz aslında kötü sorgu/eksik index kaynaklıysa.","Adım: Yavaş sorguları profille, eksik index'leri ekle, plan/istatistikleri düzelt; ardından CPU/RAM/IOPS artır.","Dikkat: Dikey ölçek sonludur ve maliyeti üstel artar; tek düğüm hâlâ tek arıza noktasıdır (HA için ayrıca replika kur).","Dikkat: Tavan yaklaşırken bir sonraki adımı (replika/sharding) önceden planla; acele geçişler risklidir."]},"sol_read_replica":{"kind":"solution","title":"Öneri: Read replica (okuma ölçekleme)","detail":"Yazma tek düğümde kalırken (primary), okuma trafiğini bir veya daha çok replikaya dağıtırsın. Okuma ağırlıklı yüklerde ham okuma kapasitesini ve dayanıklılığı artırmanın standart yoludur.","steps":["Neden: Okuma sorguları birden çok kopyaya yayılır; primary yalnızca yazmayla ilgilenir, okuma throughput'u neredeyse doğrusal artar.","Ne zaman: Okuma/yazma oranı yüksek yükler; raporlama ve analitik sorguları primary'den ayırmak; aynı anda HA yedeği kazanmak.","Örnek: PostgreSQL streaming replica, MySQL replika + proxy yönlendirme, uygulamada okuma/yazma ayrımı (read-write split).","Dikkat: Asenkron replikada replikasyon gecikmesi 'kendi yazdığını hemen okuyamama' (read-your-writes) sorunu yaratır; kritik okumaları primary'e yönlendir.","Dikkat: Replika yazma darboğazını çözmez; tek yazıcı düğüm hâlâ sınırdır — yazma da darboğazsa sharding gerekir."],"related":["replication-status"]},"sol_cache":{"kind":"solution","title":"Öneri: Önbellek katmanı (cache)","detail":"Sık ve tekrar okunan sonuçları hızlı bir bellek içi katmanda tutarak veritabanı yükünü kökten azaltır. Doğru desende, veritabanına gitmeden yanıt vererek hem gecikmeyi hem yükü düşürür.","steps":["Neden: Tekrarlı okumalar veritabanına hiç ulaşmadan bellek hızında yanıtlanır; en yüksek kazanç/maliyet oranlı okuma ölçekleme yöntemidir.","Ne zaman: Aynı veriler defalarca okunuyor, hafif eskime (staleness) kabul edilebilir; ör. ürün detayı, ayarlar, referans veriler.","Örnek: Redis/Memcached ile cache-aside deseni; uygulama önce önbelleğe, ıskalarsa (miss) veritabanına gider.","Dikkat: Önbellek geçersizleştirme (invalidation) zordur; TTL ve yazımda güncelleme/temizleme stratejisini net tasarla.","Dikkat: Güçlü tutarlılık gereken (para/stok) okumalarda eskimiş önbelleğe güvenme; bu okumaları kaynaktan al."]},"sol_sharding":{"kind":"solution","title":"Öneri: Sharding (yazma/veri ölçekleme)","detail":"Veriyi bir shard anahtarına göre bölerek birden çok bağımsız düğüme dağıtırsın; her düğüm verinin bir dilimini ve onun yazmalarını üstlenir. Yazma hızını ve toplam veri hacmini ölçeklemenin yoludur, ama önemli karmaşıklık getirir.","steps":["Neden: Yazma ve depolama birden çok düğüme yayılır; tek yazıcı ve tek-düğüm veri sınırı ortadan kalkar, yatay ölçek açılır.","Ne zaman: Yazma throughput'u veya veri boyutu tek düğüme (ve read replica'ya) sığmadığında; başka çare kalmadığında.","Örnek: Uygulama katmanında shard yönlendirme, Vitess (MySQL), Citus (PostgreSQL), belge DB'lerde yerleşik sharding.","Dikkat: Shard anahtarı seçimi kritik ve geri dönüşü zordur; kötü anahtar hotspot ve dengesiz dağılım yaratır. Yüksek kardinaliteli, erişim desenine uygun anahtar seç.","Dikkat: Shard'lar arası join, işlem ve benzersizlik zorlaşır; uygulama karmaşıklığı, resharding ve operasyon yükü ciddi artar."],"related":["create-partition"]}}},"solver/decide-backup.json":{"id":"decide-backup","title":"Karar: Hangi yedekleme stratejisi?","icon":"🧭","category":"Karar Rehberi","intro":"Yedekleme stratejisi; ne kadar veri kaybını göze aldığın (RPO), veri boyutun ve ne kadar hızlı kurtarman gerektiği (RTO) üçlüsünün dengesiyle seçilir. Tek bir yöntem her senaryoya uymaz. Bu ağaç, RPO hedefinden başlayarak mantıksal dump, fiziksel yedek + PITR ve snapshot seçenekleri arasında yönlendirir ve 3-2-1 ile doğrulamanın vazgeçilmez olduğunu hatırlatır.","start":"root","nodes":{"root":{"kind":"step","title":"Veri kaybı hedefin (RPO) nedir?","detail":"En belirleyici kısıtla başla: bir felakette kaç dakikalık/saatlik veriyi kaybetmeyi göze alabilirsin? Neredeyse sıfır veri kaybı isteniyorsa sürekli log arşivi (PITR) şarttır; günlük/haftalık yedek toleransı varsa daha basit yöntemler yeterli olur. RPO, stratejinin çatısını belirler.","choices":[{"label":"Neredeyse sıfır — herhangi bir ana dakikaya dönebilmeliyim","next":"sol_physical_pitr"},{"label":"Günlük/periyodik yedek (birkaç saat kayıp) kabul","next":"size"},{"label":"Önce genel en iyi pratiği (3-2-1 / doğrulama) hatırlat","next":"sol_321"}]},"size":{"kind":"step","title":"Veri boyutu ve taşınabilirlik ihtiyacı ne?","detail":"Periyodik yedek yeterliyse sıradaki soru ölçek ve amaç: veritabanı küçük/orta ve yedeği başka ortama/sürüme taşınabilir olsun mu istiyorsun, yoksa veri büyük ve asıl derdin dakikalar içinde geri dönmek mi? Bu, mantıksal dump ile snapshot arasında seçim yaptırır.","choices":[{"label":"Küçük/orta, taşınabilir ve sürümler arası uyumlu olsun","next":"sol_logical"},{"label":"Büyük veri, kurtarma çok hızlı olmalı (düşük RTO)","next":"sol_snapshot"}]},"sol_logical":{"kind":"solution","title":"Öneri: Mantıksal dump","detail":"Veriyi mantıksal düzeyde (şema tanımları + satırlar) dışa aktarır; çıktı SQL/metin (pg_dump düz biçim, mysqldump) ya da araca özgü ikili dump (pg_dump -Fc, Oracle Data Pump) olabilir. Küçük ve orta boyutlu veritabanları, taşıma, sürüm yükseltme ve seçili tablo/nesne kurtarma için esnek ve taşınabilir bir yöntemdir.","steps":["Neden: Çıktı taşınabilir (metin biçimindeyse okunabilir); farklı sürümler/motorlar arası taşımaya ve tek tablo/nesne bazında geri yüklemeye uygundur.","Ne zaman: Küçük/orta veri, sürüm yükseltme/göç, geliştirme ortamı kopyası, mantıksal (satır düzeyi) kurtarma ihtiyacı.","Örnek: PostgreSQL pg_dump/pg_dumpall, MySQL mysqldump, Oracle Data Pump (expdp/impdp; ikili .dmp üretir, DDL'i metin olarak görmek için impdp SQLFILE=).","Dikkat: Geri yükleme veriyi yeniden işlediği için büyük veritabanlarında hem yedek alma hem geri dönüş çok yavaştır (yüksek RTO).","Dikkat: Tek başına düşük RPO sağlamaz; noktaya kadar kurtarma için fiziksel yedek + log arşivi gerekir. Tutarlı snapshot için uygun tutarlılık seçeneklerini kullan."],"related":["logical-dump","last-backup-status"]},"sol_physical_pitr":{"kind":"solution","title":"Öneri: Fiziksel yedek + WAL/arşiv log (PITR)","detail":"Düzenli fiziksel taban yedek (base backup) alıp sürekli işlem loglarını (WAL/redo/binlog) arşivlersin. Böylece herhangi bir ana kadar noktaya-kadar kurtarma (Point-in-Time Recovery) yapabilir, veri kaybını neredeyse sıfıra indirebilirsin.","steps":["Neden: Sürekli log arşivi sayesinde son taban yedekten sonraki her işleme kadar ilerleyebilir, istenen ana (ör. hatalı komuttan hemen önce) dönebilirsin — en düşük RPO.","Ne zaman: Büyük ve kritik üretim veritabanları; düşük RPO ve makul RTO gereken sistemler.","Örnek: PostgreSQL base backup + WAL arşivi (pgBackRest/barman), Oracle RMAN + archivelog, MySQL fiziksel yedek + binlog (xtrabackup).","Dikkat: Kurulum ve operasyon daha karmaşıktır; arşiv logların kesintisiz ve eksiksiz aktığını sürekli izle — bir boşluk PITR zincirini kırar.","Dikkat: Log arşiv deposu sürekli büyür; saklama (retention) politikası ve depolama planı olmadan disk dolar."],"related":["last-backup-status","logical-dump"]},"sol_snapshot":{"kind":"solution","title":"Öneri: Snapshot","detail":"Depolama veya sanallaştırma katmanında verinin blok düzeyinde snapshot'ını alır. Çok büyük veritabanlarında bile yedek almak ve geri dönmek çok hızlıdır; ancak altyapıya bağımlıdır ve dikkatli kullanım gerektirir.","steps":["Neden: Blok düzeyi kopya neredeyse anında oluşur ve geri yükleme çok hızlıdır; büyük veride en düşük RTO'yu verir.","Ne zaman: Terabaytlarca veri, hızlı kurtarma önceliği; depolama/bulut katmanı snapshot destekliyorsa.","Örnek: SAN/LVM snapshot, bulut disk snapshot (EBS vb.), ZFS/filesystem snapshot; veritabanı motoruyla tutarlı biçimde tetiklenir.","Dikkat: Snapshot depolama sistemine bağımlıdır ve genelde aynı altyapıda durur; tek başına 3-2-1 sağlamaz — dışa (offsite) kopyala.","Dikkat: Uygulama-tutarlı olması için snapshot anında veritabanının uygun modda (fsfreeze/backup mode/hot backup) olması gerekir; yoksa 'çökme-tutarlı' yedek elde edersin."],"related":["last-backup-status"]},"sol_321":{"kind":"solution","title":"Öneri: 3-2-1 kuralı + offsite + zorunlu doğrulama","detail":"Hangi yöntemi seçersen seç, bu prensipler stratejinin üstüne binmelidir. Yedeğin sadece varlığı yetmez; farklı ortamlarda, farklı konumda ve düzenli olarak test edilmiş olması gerekir. Bu, yukarıdaki seçeneklerin hepsini tamamlayan bir çerçevedir.","steps":["3-2-1: En az 3 kopya, 2 farklı ortam/medya, 1 kopya tesis dışında (offsite) tutulur.","Neden offsite: Yangın, sel, fidye yazılımı veya bölge kaybı tek lokasyondaki tüm kopyaları birden yok edebilir; en az bir kopya izole/uzak olmalı.","Doğrulama şart: Test edilmemiş yedek yedek değildir; düzenli olarak gerçek geri yükleme tatbikatı yap ve kurtarma süresini (RTO) ölç.","Değişmezlik (immutability): Fidye yazılımına karşı silinemez/değiştirilemez (immutable/WORM) veya air-gapped kopya bulundur.","Dikkat: Yedeğin bütünlüğünü (checksum) ve kurtarılabilirliğini otomatik izle; başarısız/eskimiş yedeğe alarm kur. Yedeğin kendisini de şifrele."],"related":["last-backup-status"]}}},"solver/decide-index.json":{"id":"decide-index","title":"Karar: Hangi index türü?","icon":"🧭","category":"Karar Rehberi","intro":"Doğru index türü; sorgunun erişim biçimine (eşitlik mi, aralık mı, metin/JSON araması mı), kolonun kardinalitesine ve okuma/yazma dengesine bağlıdır. Yanlış index hem yeri boşa harcar hem yazmayı yavaşlatır. Bu ağaç, sorgu şeklinden başlayarak B-tree, Hash, Bitmap, GIN/GiST, kısmi (partial) ve kapsayan (covering) index seçenekleri arasında yönlendirir ve bileşik index'te kolon sırasının kritik olduğunu hatırlatır.","start":"root","nodes":{"root":{"kind":"step","title":"Sorgun bu kolonu nasıl kullanıyor?","detail":"Index seçiminde en belirleyici şey erişim biçimidir. Kolonda sadece '=' ile mi eşleşiyorsun, aralık/sıralama (>, <, BETWEEN, ORDER BY) mı yapıyorsun, yoksa tam metin, JSON alanı veya geometrik/dizilerde mi arıyorsun? Buradan başla; ihtiyaç netleşmeden index türü seçilmez.","choices":[{"label":"Eşitlik ve aralık/sıralama karışık (=, >, <, BETWEEN, ORDER BY)","next":"cardinality"},{"label":"Yalnızca eşitlik (=), aralık veya sıralama yok","next":"sol_hash"},{"label":"Tam metin, JSON/JSONB alanı, dizi veya geometrik arama","next":"sol_gin_gist"},{"label":"Sorgu hep aynı küçük satır alt kümesine bakıyor (ör. WHERE durum='aktif')","next":"sol_partial"}]},"cardinality":{"kind":"step","title":"Kolonun kardinalitesi (farklı değer sayısı) nasıl?","detail":"Aralık/sıralama gerekiyorsa varsayılan B-tree'dir; ancak çok az sayıda farklı değer içeren (düşük kardinalite: cinsiyet, durum, evet/hayır) kolonlarda ve ağırlıklı okuma yapılan veri ambarında Bitmap index daha iyi olabilir. Kolonda çok sayıda benzersiz değer mi var, yoksa az sayıda tekrar eden değer mi?","choices":[{"label":"Yüksek kardinalite (çok sayıda benzersiz değer) veya OLTP yük","next":"coverage"},{"label":"Düşük kardinalite ve ağırlıklı okuma / veri ambarı (DWH)","next":"sol_bitmap"}]},"coverage":{"kind":"step","title":"Sorgu tablodan sadece index'teki kolonları mı okuyor?","detail":"Erişim biçimi B-tree'ye uygun. Son bir optimizasyon: sorgunun döndürdüğü ve filtrelediği tüm kolonlar index'te bulunursa, motor tabloya hiç gitmeden yalnızca index'ten cevap verebilir (index-only / covering scan). Sorgun az sayıda kolon mu okuyor, yoksa satırın büyük kısmına mı ihtiyaç duyuyor?","choices":[{"label":"Evet, birkaç kolon; tabloya gitmeden cevaplanabilir","next":"sol_covering"},{"label":"Hayır, standart erişim yeterli","next":"sol_btree"}]},"sol_btree":{"kind":"solution","title":"Öneri: B-tree (varsayılan)","detail":"B-tree dengeli bir ağaç yapısıdır ve eşitlik, aralık, sıralama (ORDER BY), ön ek (prefix) ile LIKE 'abc%' ve MIN/MAX gibi geniş bir erişim yelpazesini destekler. Çoğu ilişkisel motorda varsayılan index türüdür ve emin olmadığında doğru başlangıçtır.","steps":["Neden: Tek yapıyla hem eşitlik hem aralık/sıralamayı verimli karşılar; en genel amaçlı index'tir.","Ne zaman: OLTP sorguları, WHERE + aralık + ORDER BY birlikte, primary/unique key'ler.","Bileşik index'te kolon SIRASI kritiktir: en seçici ve eşitlikle kullanılan kolonu başa koy, aralık kolonunu sona bırak. (a,b) index'i 'a' veya 'a,b' filtresine yarar; tek başına 'b' filtresine genelde yaramaz (leftmost-prefix kuralı).","Örnek: PostgreSQL/Oracle/MySQL(InnoDB)/MSSQL hepsinde varsayılan B-tree/B+tree index.","Dikkat: Her index yazma (INSERT/UPDATE/DELETE) maliyetini ve disk yerini artırır; gereksiz veya tekrarlı index tutma."],"related":["slow-query"]},"sol_hash":{"kind":"solution","title":"Öneri: Hash index (yalnız eşitlik)","detail":"Hash index, kolon değerinin hash'ini saklar ve yalnızca tam eşitlik ('=') aramalarında çok hızlıdır. Aralık, sıralama veya ön ek aramalarını desteklemez; bu yüzden dar bir kullanım alanı vardır.","steps":["Neden: Eşitlik aramasında ortalama sabit zamanlı (O(1)) erişim sağlar; belleğe sığan çok büyük eşitlik yüklerinde avantajlı olabilir.","Ne zaman: Kolonda sadece '=' kullanılıyorsa ve aralık/sıralama asla gerekmiyorsa.","Motor farkı: PostgreSQL'de hash index vardır ama pratikte B-tree çoğu durumda yeterli ve daha esnektir; MySQL(InnoDB) hash index'i yalnızca adaptive hash olarak dahili yönetir, MEMORY motorunda açıkça hash kullanılır; Oracle'da cluster/hash cluster bağlamında görülür.","Dikkat: Aralık, BETWEEN, ORDER BY, LIKE 'abc%' desteklenmez — bu ihtiyaçlar doğunca B-tree seç.","Dikkat: Genellikle varsayılan B-tree yeterli olduğundan, ölçmeden hash'e geçme."],"related":["slow-query"]},"sol_bitmap":{"kind":"solution","title":"Öneri: Bitmap index (düşük kardinalite / DWH)","detail":"Bitmap index, her farklı değer için bir bit dizisi tutar ve birden çok düşük kardinaliteli koşulu bit AND/OR ile çok hızlı birleştirir. Veri ambarı ve raporlama gibi ağırlıklı okuma yapılan iş yüklerinde güçlüdür.","steps":["Neden: Az sayıda farklı değere sahip kolonlarda çok az yer kaplar ve birden çok koşulu (WHERE cinsiyet=.. AND bolge=..) bitmap işlemleriyle verimli birleştirir.","Ne zaman: Düşük kardinalite kolonlar, yıldız şema (star schema) sorguları, veri ambarı/raporlama, ağırlıklı okuma.","Motor farkı: Oracle'ın klasik güçlü özelliğidir; PostgreSQL'de kalıcı bitmap index yoktur ama planlayıcı çalışma anında 'bitmap heap scan' üretebilir. MySQL/MSSQL'de doğrudan kalıcı bitmap index yoktur.","Dikkat: Sık güncellenen (OLTP) tablolarda kullanma — bitmap lock'ları satır düzeyi eşzamanlılığı ciddi biçimde düşürür.","Dikkat: Yüksek kardinaliteli kolonlarda avantajı kaybolur; orada B-tree tercih et."],"related":["slow-query"]},"sol_gin_gist":{"kind":"solution","title":"Öneri: GIN / GiST (metin, JSON, dizi, geometri)","detail":"PostgreSQL'de standart B-tree'nin çözemediği erişim tipleri için özel index aileleri vardır. GIN, bir değerin içindeki birçok bileşeni (kelimeler, JSONB anahtarları, dizi elemanları) işaret eder; GiST ise geometrik/aralık/en yakın komşu (nearest-neighbor) gibi sorgulara uygundur.","steps":["Neden: Bu veri tipleri 'içerir/örtüşür/yakınında' gibi sorguları B-tree ile verimli yapamaz; GIN/GiST bunları hızlandırır.","Ne zaman GIN: Tam metin arama (tsvector), JSONB alan/anahtar araması (@>, ?), dizi içerir sorguları — çok okuma, az yazma.","Ne zaman GiST: Geometrik/coğrafi (PostGIS), aralık tipleri (range), en yakın komşu (KNN) sorguları.","Motor farkı: GIN/GiST PostgreSQL'e özgüdür. MySQL'de FULLTEXT index ve SPATIAL (R-tree) index, Oracle'da Oracle Text ve Spatial, MSSQL'de Full-Text Index benzer amaca hizmet eder.","Dikkat: GIN yazmada pahalıdır ve oluşturması yavaştır (fastupdate ile hafifletilebilir); yazma yoğun tablolarda maliyeti ölç."],"related":["slow-query"]},"sol_partial":{"kind":"solution","title":"Öneri: Kısmi / filtrelenmiş (partial) index","detail":"Kısmi index, tablonun tamamı yerine yalnızca bir koşulu (WHERE ...) sağlayan satırları indeksler. Sorgular hep aynı küçük alt kümeye bakıyorsa index çok küçülür, hızlanır ve yazma maliyeti azalır.","steps":["Neden: Yalnızca ilgili satırları indekslediğinden hem yer hem bakım maliyeti düşer; sık sorgulanan 'sıcak' alt küme çok hızlanır.","Ne zaman: WHERE durum='aktif', silinmemis IS NULL, oncelik='yuksek' gibi kalıcı ve dar koşullar.","Motor farkı: PostgreSQL 'partial index' (CREATE INDEX ... WHERE ...), MSSQL 'filtered index' ile bunu doğrudan destekler. Oracle'da tam karşılığı için fonksiyon tabanlı/koşullu index kalıpları kullanılır; MySQL(InnoDB) doğrudan desteklemez.","Dikkat: Index'in WHERE koşulu, sorgunun koşuluyla uyuşmalı; aksi halde planlayıcı index'i kullanamaz.","Dikkat: Alt küme büyürse avantajı azalır; koşulun kalıcılığından emin ol."],"related":["slow-query"]},"sol_covering":{"kind":"solution","title":"Öneri: Kapsayan (covering / INCLUDE) index","detail":"Kapsayan index, sorgunun ihtiyaç duyduğu tüm kolonları index'te barındırarak motorun tabloya (heap) hiç gitmeden yalnızca index'ten cevap vermesini sağlar (index-only scan). Sık çalışan, az kolon döndüren sorgularda ciddi hızlanma verir.","steps":["Neden: Tabloya erişim (heap fetch) ortadan kalkar; disk I/O ve gecikme belirgin düşer.","Ne zaman: Sık çalışan, WHERE + SELECT kolonları belli, dar sonuç kümeli sorgular.","Motor farkı: MSSQL ve PostgreSQL 'INCLUDE' ile aranmayan kolonları index'in yaprağına ekler; MySQL(InnoDB) ikincil index'ler zaten primary key'i içerdiğinden bileşik index ile covering elde edilir; Oracle'da tüm gereken kolonlar index'te ise index-only erişim olur.","Dikkat: INCLUDE edilen fazla/geniş kolonlar index'i şişirir ve yazmayı yavaşlatır; sadece gerçekten gereken kolonları ekle.","Dikkat: PostgreSQL'de index-only scan için görünürlük haritasının (visibility map) güncel olması gerekir; düzenli VACUUM şart."],"related":["slow-query"]}}},"solver/decide-partition.json":{"id":"decide-partition","title":"Karar: Hangi partition stratejisi?","icon":"🧭","category":"Karar Rehberi","intro":"Partition (bölümleme), büyük bir tabloyu tek bir mantıksal isim altında birden çok fiziksel parçaya bölerek eski veriyi kolayca atmayı ve sorgunun yalnızca ilgili parçalara bakmasını (partition pruning) sağlar. Ama küçük tablolarda sadece karmaşıklık ekler. Bu ağaç önce partition'a gerçekten ihtiyaç olup olmadığını sorgular, sonra erişim ve dağıtım biçimine göre Range, List, Hash ve Composite arasında yönlendirir.","start":"root","nodes":{"root":{"kind":"step","title":"Tablo gerçekten partition gerektirecek kadar büyük mü?","detail":"Partition bir performans sihiri değil, ölçek ve bakım (yaşam döngüsü) aracıdır. Tablo yeterince büyük değilse veya sorgular index ile zaten iyi çalışıyorsa, partition sadece plan karmaşıklığı ve yönetim yükü getirir. Tablon on milyonlarca+ satıra/yüzlerce GB'a mı ulaşıyor, yoksa hala küçük/orta mı?","choices":[{"label":"Evet, çok büyük ve/veya eski veriyi toplu silmek/arşivlemek gerekiyor","next":"access"},{"label":"Hayır, küçük/orta tablo veya emin değilim","next":"sol_no_partition"}]},"access":{"kind":"step","title":"Veriye nasıl erişiyorsun ve nasıl bölünmeli?","detail":"Partition anahtarı, sorguların çoğunun filtrelediği kolon olmalı; ancak böyle pruning devreye girer. Erişimin ağırlıklı biçimi ne? Tarih/sıralı aralıklarla mı (son 30 gün), belirli kategori/bölge değerleriyle mi, yoksa belirgin bir filtre yok ama yükü eşit dağıtmak mı istiyorsun?","choices":[{"label":"Tarih/sıra numarası gibi sıralı aralıklar (son X gün, ay bazında)","next":"sol_range"},{"label":"Ayrık kategori/bölge/kiracı gibi belirli değer kümeleri","next":"sol_list"},{"label":"Belirgin aralık/kategori yok; amaç yükü eşit dağıtmak","next":"sol_hash"},{"label":"Hem tarih hem yüksek hacim; iki boyutta bölmek gerekiyor","next":"sol_composite"}]},"sol_no_partition":{"kind":"solution","title":"Öneri: Partition kullanma (henüz)","detail":"Küçük/orta tablolarda partition fayda getirmez; iyi seçilmiş index'ler ve normal bakım yeterlidir. Erken bölümleme, sorgu planlarını karmaşıklaştırır, yanlış anahtarla pruning'i kaçırır ve operasyon yükü ekler.","steps":["Neden: Küçük tabloda tam tarama veya index erişimi zaten hızlıdır; partition ek yönetim ve plan karmaşıklığından başka değer katmaz.","Ne zaman böyle kal: Birkaç milyon satırın altında, eski veriyi toplu atma ihtiyacı yok, sorgular index ile iyi çalışıyor.","Bunun yerine: Doğru index'ler, gerekiyorsa arşiv tablosu, düzenli istatistik/VACUUM/ANALYZE.","Dikkat: 'İleride büyür' varsayımıyla erken partition kurma; büyüme kanıtlanınca ve doğru anahtar netleşince geç.","Motor farkı: Tüm motorlarda geçerli genel ilke; PostgreSQL declarative partitioning, MySQL PARTITION BY, Oracle ve MSSQL partitioning ileride kolayca eklenebilir."],"related":[]},"sol_range":{"kind":"solution","title":"Öneri: Range (aralık) partition","detail":"Range partition, satırları bir kolonun sıralı aralıklarına göre böler (ör. tarih aralıkları: her ay/çeyrek bir partition). Zaman serisi ve sürekli büyüyen tablolarda en yaygın ve en güçlü stratejidir.","steps":["Neden: Sorgular tarih/aralıkla filtrelediğinde motor yalnızca ilgili partition'ları okur (partition pruning); eski veri tek komutla (partition DROP) anında atılır.","Ne zaman: Zaman serisi, log, sipariş/işlem geçmişi; 'son N gün' sorguları ve zaman bazlı arşivleme.","Partition anahtarı: Sorguların ezici çoğunluğunun WHERE'inde bulunan tarih/sıralı kolonu seç; yoksa pruning çalışmaz.","Örnek: PostgreSQL RANGE partition, Oracle range/interval partition (otomatik yeni partition), MySQL PARTITION BY RANGE (tarih için genelde RANGE COLUMNS), MSSQL partition function/scheme.","Dikkat: Gelecek aralıklar için yeni partition oluşturmayı otomatikleştir (Oracle interval veya zamanlanmış iş); dolu 'default/maxvalue' partition hotspot olur."],"related":[]},"sol_list":{"kind":"solution","title":"Öneri: List (liste) partition","detail":"List partition, satırları bir kolonun ayrık ve bilinen değerlerine göre gruplar (ör. bölge = 'TR','EU','US' veya kiracı kimliği). Doğal, sonlu kategoriler varken erişim ve yönetimi netleştirir.","steps":["Neden: Sorgular belirli kategori değerleriyle filtrelediğinde yalnızca o partition okunur; kategori bazında bakım/silme kolaylaşır.","Ne zaman: Bölge/ülke, ürün tipi, durum, çok kiracılı (multi-tenant) ayrımı gibi ayrık ve görece kararlı değer kümeleri.","Partition anahtarı: Değer kümesi sonlu ve öngörülebilir olmalı; sık yeni değer ekleniyorsa List yerine Hash düşün.","Örnek: PostgreSQL LIST partition, Oracle list partition, MySQL PARTITION BY LIST, MSSQL uygun sınırlarla partition scheme.","Dikkat: Tanımsız/yeni değerler için bir 'default' partition bulundur; yoksa satır eklenemez ve hata alırsın."],"related":[]},"sol_hash":{"kind":"solution","title":"Öneri: Hash partition (eşit dağıtım)","detail":"Hash partition, anahtar kolonun hash'ine göre satırları önceden belirlenmiş sayıda partition'a görece eşit dağıtır. Doğal bir aralık/kategori yokken hotspot'u önlemek ve yükü dengelemek için kullanılır.","steps":["Neden: Satırlar dengeli dağılır; tek bir partition'ın veya primary key'in sonuna yığılan yazma hotspot'u azalır.","Ne zaman: Yüksek yazma hacmi, doğal aralık/kategori yok, amaç I/O ve boyutu eşitlemek (ör. yüksek kardinaliteli id).","Partition anahtarı: Yüksek kardinaliteli ve eşit dağılan bir kolon (genelde primary/unique key) seç.","Örnek: PostgreSQL HASH partition, Oracle hash partition, MySQL PARTITION BY HASH/KEY.","Dikkat: Aralık sorgularında pruning sağlamaz (hash sırayı bozar); 'son N gün' gibi sorgular tüm partition'ları tarar. Partition sayısını sonradan değiştirmek yeniden dağıtım gerektirir."],"related":[]},"sol_composite":{"kind":"solution","title":"Öneri: Composite (çok seviyeli) partition","detail":"Composite partition, iki stratejiyi birleştirir: önce üst seviyede böler, sonra her partition'ı alt-partition'lara ayırır (ör. Range-by-Hash veya Range-by-List). Hem zaman bazlı yaşam döngüsü hem de eşit dağıtım/kategori ayrımı aynı anda gerektiğinde kullanılır.","steps":["Neden: Tek bir strateji yetmediğinde iki ihtiyacı birlikte karşılar; örneğin aya göre böl (arşivleme), ay içinde hash ile dağıt (hotspot önleme).","Ne zaman: Çok büyük zaman serisi + yüksek eşzamanlı yazma, veya tarih + bölge/kiracı ikili erişim deseni.","Örnek: Oracle composite (range-hash, range-list, list-hash vb.), PostgreSQL'de partition'ları yeniden partition'layarak (partition of partition) elle kurulur, MySQL subpartition (RANGE/LIST + HASH/KEY).","Dikkat: Yönetim ve şema karmaşıklığı en yüksek seçenektir; sadece iki boyutun da kanıtlı ihtiyaç olduğu durumlarda seç.","Dikkat: Yanlış üst/alt anahtar seçimi pruning'i kaybettirir; her iki seviyenin de sorgu desenine uyduğunu doğrula."],"related":[]}}},"solver/decide-pooling.json":{"id":"decide-pooling","title":"Karar: Bağlantı havuzu (connection pool) nasıl?","icon":"🧭","category":"Karar Rehberi","intro":"Her veritabanı bağlantısı bellek ve zamanlama maliyeti taşır; kontrolsüz artan bağlantı sayısı sunucuyu yavaşlatır, hatta çökertir. Bağlantı havuzu, az sayıda kalıcı bağlantıyı yeniden kullandırarak bunu çözer. Bu ağaç; havuzun nerede duracağı, hangi mod (session/transaction/statement) ve doğru boyut kararlarında yönlendirir ve serverless ortamlarda harici pooler'ın neden şart olduğunu vurgular.","start":"root","nodes":{"root":{"kind":"step","title":"Uygulama mimarin nasıl bağlanıyor?","detail":"Havuz kararı önce mimariyle başlar. Tek bir uzun ömürlü uygulama süreci mi (klasik sunucu), çok sayıda bağımsız süreç/örnek mi (mikroservis, çok pod), yoksa her istekte doğup ölen serverless/Lambda fonksiyonları mı bağlanıyor? Her biri farklı havuz yerleşimi gerektirir.","choices":[{"label":"Tek/az sayıda uzun ömürlü uygulama süreci","next":"sol_app_pool"},{"label":"Çok sayıda süreç/örnek/pod aynı DB'ye bağlanıyor","next":"middleware"},{"label":"Serverless / Lambda / kısa ömürlü fonksiyonlar","next":"sol_serverless"},{"label":"Önce doğru havuz boyutunu nasıl seçerim, onu göster","next":"sol_size"}]},"middleware":{"kind":"step","title":"Ara katman pooler modunu nasıl seçmeli?","detail":"Çok sayıda istemci varsa ara katman pooler (PgBouncer, ProxySQL) bağlantı sayısını DB'de düşük tutar. Ama pool mode uygulamanın kullandığı özelliklere bağlıdır: oturuma bağlı durum (prepared statement, geçici tablo, SET, advisory lock'ları, session-level özellikler) kullanıyor musun, yoksa her şey tek transaction içinde mi bitiyor?","choices":[{"label":"Oturum durumuna bağlıyım (SET, geçici tablo, session prepared statement)","next":"sol_session_mode"},{"label":"İşlemler kısa ve bağımsız; oturum durumu tutmuyorum","next":"sol_txn_mode"}]},"sol_app_pool":{"kind":"solution","title":"Öneri: Uygulama içi bağlantı havuzu","detail":"Uzun ömürlü tek/az sayıda süreçte, uygulama içi bir havuz kütüphanesi (HikariCP, Go database/sql yerleşik havuzu, .NET connection pooling) çoğu ihtiyacı karşılar. Bağlantılar bir kez açılıp tekrar tekrar kullanılır.","steps":["Neden: Bağlantı kurma/kapatma maliyeti ortadan kalkar; sınırlı ve öngörülebilir bağlantı sayısı DB'yi korur.","Ne zaman: Klasik monolit veya az sayıda uygulama örneği; toplam bağlantı ihtiyacı DB kapasitesinin altında.","Örnek: Java HikariCP, .NET SqlConnection/Npgsql pooling, Node pg-pool, Python SQLAlchemy pool.","Boyut için: Havuz boyutunu çekirdek/disk temelli belirle (sonraki karar); 'ne kadar çok o kadar iyi' değildir.","Dikkat: Her uygulama örneği kendi havuzunu açar; örnek sayısı × havuz boyutu, DB max_connections'ı aşmamalı. Aşıyorsa ara katman pooler'a geç."],"related":["connection-storm"]},"sol_size":{"kind":"solution","title":"Öneri: Havuz boyutunu doğru hesapla","detail":"Havuz ne çok küçük (istekler bekler) ne çok büyük olmalı. Çok bağlantı, CPU'da bağlam değişimi (context switch) ve lock çekişmesi yaratıp verimi düşürür. Boyut, sonsuz büyütülecek bir sayı değil, çekirdek ve I/O temelli küçük bir sayıdır.","steps":["Başlangıç formülü: Genel bir başlangıç noktası, havuz boyutu ≈ (çekirdek sayısı × 2) + etkin disk mili (spindle) sayısıdır; SSD/çok çekirdekte 'çekirdek × 2-4' civarı iyi bir başlangıçtır.","Neden küçük tutulur: DB gerçek paralelliği çekirdek sayısıyla sınırlıdır; fazla bağlantı sadece sıraya girer ve bağlam değişimi/lock çekişmesiyle her şeyi yavaşlatır.","Kural: Yüzlerce eşzamanlı istemci varsa çözüm havuzu büyütmek değil, küçük bir havuzu hızlı devretmektir (kısa işlemler + kuyruk).","Toplam sınır: (uygulama örneği sayısı × havuz boyutu) < DB max_connections; süper kullanıcı ve bakım için pay bırak.","Dikkat: Formülle başla ama mutlaka ölç — bekleme süresi, aktif bağlantı, kuyruk derinliği metrikleriyle ayarla."],"related":["connection-storm"]},"sol_session_mode":{"kind":"solution","title":"Öneri: Session (oturum) pool mode","detail":"Session modda bir istemci bağlantısı, oturumu bitene kadar arka uçtaki bir sunucu bağlantısına sabitlenir. Oturum düzeyi durum (SET, geçici tablo, advisory lock, session prepared statement) korunur ama bağlantı paylaşımı en azdır.","steps":["Neden: Oturum boyunca durum korunması gereken uygulamalar için tek güvenli moddur; davranış doğrudan DB'ye bağlanmakla aynıdır.","Ne zaman: SET oturum değişkenleri, geçici tablolar, LISTEN/NOTIFY, session-level prepared statement veya advisory lock'ları kullanan uygulamalar.","Örnek: PgBouncer pool_mode=session; ProxySQL'de oturum-hassas trafiği ayrı yönlendirme.","Dikkat: Bağlantı paylaşımı düşüktür — çok istemcide fayda azalır; mümkünse uygulamayı oturum durumundan arındırıp transaction moda geçmeyi hedefle.","Motor farkı: PostgreSQL için PgBouncer; MySQL tarafında ProxySQL benzeri davranışları farklı yönetir, oturum değişkenleri için dikkat gerekir."],"related":["connection-storm"]},"sol_txn_mode":{"kind":"solution","title":"Öneri: Transaction pool mode","detail":"Transaction modda sunucu bağlantısı yalnızca bir transaction süresince istemciye ödünç verilir; transaction bitince havuza döner. Böylece binlerce istemci, DB'de çok az sayıda gerçek bağlantıyla çalışabilir — en yaygın yüksek ölçek modudur.","steps":["Neden: Bağlantı devri işlem bazında olduğundan paylaşım en yüksektir; az sayıda DB bağlantısıyla çok istemciyi taşırsın.","Ne zaman: Kısa, bağımsız işlemler; oturum durumu tutmayan (veya tutmaması sağlanan) mikroservis/çok pod mimarileri.","Örnek: PgBouncer pool_mode=transaction (en yaygın kurulum), ProxySQL varsayılan multiplexing davranışı.","Dikkat: Oturuma yayılan özellikler kırılır — session-level prepared statement, geçici tablo, SET, advisory lock'ları güvenli değildir. Protokol düzeyi named prepared statement için uygulama/pooler uyumunu doğrula.","Statement mode: Daha da agresif (statement) mod her ifadede devreder; yalnızca çok özel, transaction'sız salt-okuma senaryolarında düşünülür ve çok kısıtlıdır."],"related":["connection-storm"]},"sol_serverless":{"kind":"solution","title":"Öneri: Serverless için harici pooler şart","detail":"Serverless/Lambda fonksiyonları hızla ölçeklenip her örnekte kendi bağlantısını açar; uygulama içi havuz burada işe yaramaz çünkü örnekler kısa ömürlü ve paylaşımsızdır. Aniden yüzlerce/binlerce örnek doğunca DB bağlantı sınırı patlar. Çözüm, DB'nin önünde harici bir bağlantı havuzudur.","steps":["Neden: Kısa ömürlü, paylaşımsız fonksiyon örneklerinde uygulama içi havuz kalıcı olamaz; ölçek anında bağlantı fırtınası (connection storm) oluşur.","Ne zaman: AWS Lambda, Cloud Functions, Azure Functions gibi her istekte örnek doğuran ortamlar.","Örnek: PgBouncer/ProxySQL ayrı bir katman olarak, veya yönetilen pooler (ör. AWS RDS Proxy, PostgreSQL için Data API/harici pooler servisleri).","Mod: Genellikle transaction pool mode tercih edilir; fonksiyon kodunu oturum durumundan arındır.","Dikkat: Fonksiyon başına da eşzamanlılık sınırı (reserved concurrency) koy; pooler'ı ve DB max_connections'ı birlikte boyutlandır, aksi halde pooler'ın kendisi darboğaz olur."],"related":["connection-storm"]}}},"solver/decide-cache.json":{"id":"decide-cache","title":"Karar: Hangi önbellek stratejisi?","icon":"🧭","category":"Karar Rehberi","intro":"Önbellek (cache), sık okunan veriyi veritabanının önünde hızlı bir katmanda (ör. Redis) tutarak gecikmeyi ve DB yükünü düşürür. Ama her veri cache'e uygun değildir ve yanlış geçersiz kılma (invalidation) bayat/yanlış veri riski doğurur. Bu ağaç; önce cache'e gerçekten gerek olup olmadığını, sonra okuma/yazma desenine göre cache-aside, read-through, write-through ve write-behind arasında seçim yapmayı ve stampede'i önlemeyi ele alır.","start":"root","nodes":{"root":{"kind":"step","title":"İş yükün nasıl: okuma mı ağır basıyor, yazma mı?","detail":"Önbellek en çok, aynı verinin defalarca okunduğu (okuma ağırlıklı) ve verinin sık değişmediği durumlarda kazandırır. Önce genel deseni belirle: veri çok okunup az mı değişiyor, sürekli mi güncelleniyor, yoksa cache eklemeye değip değmeyeceğinden emin değil misin?","choices":[{"label":"Okuma çok ağır, veri görece nadir değişiyor","next":"read_pattern"},{"label":"Yazma da yoğun; yazılan veri hemen/çok okunuyor","next":"write_pattern"},{"label":"Emin değilim; cache'e gerçekten gerek var mı?","next":"sol_no_cache"}]},"read_pattern":{"kind":"step","title":"Cache doldurma sorumluluğu kimde olsun?","detail":"Okuma ağırlıklı senaryoda temel seçim, cache'i kimin dolduracağıdır. Uygulaman cache'i açıkça yönetip DB'ye kendisi mi düşsün (esneklik yüksek), yoksa cache katmanı 'ıska' (miss) durumunda arkadaki DB'den veriyi kendisi mi çekip şeffaf biçimde döndürsün?","choices":[{"label":"Uygulama açıkça yönetsin; esneklik ve kontrol isterim","next":"sol_cache_aside"},{"label":"Cache katmanı ıska anında DB'den kendisi çeksin (şeffaf)","next":"sol_read_through"}]},"write_pattern":{"kind":"step","title":"Yazmada tutarlılık mı, yazma hızı mı öncelik?","detail":"Yazma yoğunsa, yazılan verinin cache ile DB arasında ne kadar tutarlı olacağına karar vermelisin. Her yazma anında cache ve DB birlikte güncellenip tutarlılık mı garanti edilsin (biraz daha yavaş yazma), yoksa önce cache'e yazıp DB'ye eşzamansız (arka planda) mı işlensin (çok hızlı yazma ama kayıp riski)?","choices":[{"label":"Tutarlılık önemli; okumalar hep güncel olmalı","next":"sol_write_through"},{"label":"Yazma hızı kritik; kısa gecikmeli tutarlılık ve kayıp riski kabul","next":"sol_write_behind"}]},"sol_no_cache":{"kind":"solution","title":"Öneri: Şimdilik cache ekleme","detail":"Cache bedava değildir: bir tutarlılık problemi (bayat veri), ek altyapı ve geçersiz kılma karmaşıklığı getirir. Sorgu zaten hızlıysa veya veri her istekte değişiyorsa cache fayda değil sadece hata yüzeyi ekler.","steps":["Neden: Cache; tutarlılık, invalidation ve işletme yükü ekler. Getirisi yoksa net zarardır.","Ne zaman gerekmez: Sorgu index ile zaten hızlı, veri her okumada farklı/kişiye özel ve tekrar kullanılmıyor, ya da yazma okumadan çok fazla.","Bunun yerine: Önce index/sorgu optimizasyonu, materialized view veya DB'nin kendi buffer/plan cache'i.","Dikkat: 'Her ihtimale karşı' cache koyma; ölçülen bir okuma darboğazı ve tekrar kullanılan veri olmadan ekleme.","Sonra: Gerçek bir okuma hotspot'u kanıtlandığında cache-aside ile başla."],"related":["slow-query","high-cpu"]},"sol_cache_aside":{"kind":"solution","title":"Öneri: Cache-aside (lazy loading)","detail":"Cache-aside'da uygulama önce cache'e bakar; veri yoksa (miss) DB'den okur, cache'e yazar ve döndürür. En yaygın ve esnek desendir; cache yalnızca gerçekten istenen veriyle dolar.","steps":["Neden: Basit, esnek ve dayanıklı; cache çökse bile uygulama DB'ye düşerek çalışmaya devam eder. Sadece istenen veri cache'lenir.","Ne zaman: Genel amaçlı okuma hızlandırma; okuma çok, yazma orta; Redis/Memcached ile klasik kullanım.","Invalidation: Yazışta ilgili anahtarı güncelle veya sil (write-invalidate); her anahtara makul bir TTL koyarak bayatlığı sınırla.","Örnek: Redis GET → yoksa DB sorgusu → SET key value EX <ttl>.","Dikkat: İlk istek daima ıska olur (soğuk başlangıç). Aynı anahtar aynı anda çok istenirse cache stampede oluşabilir — bkz. stampede önleme (aşağıdaki dikkat).","Stampede: Popüler anahtar aynı anda süresi dolunca binlerce istek DB'ye vurur; lock/tek-uçuş (single-flight), erken yenileme veya jitter'lı TTL ile önle."],"related":["high-cpu","slow-query"]},"sol_read_through":{"kind":"solution","title":"Öneri: Read-through cache","detail":"Read-through'da uygulama yalnızca cache ile konuşur; ıska durumunda veriyi DB'den çekip dolduran taraf cache katmanının kendisidir (bir sağlayıcı/loader üzerinden). Uygulama kodu sadeleşir, doldurma mantığı tek yerde toplanır.","steps":["Neden: Doldurma mantığı cache katmanında merkezileşir; uygulama kodu 'her yerde miss ele al' tekrarından kurtulur.","Ne zaman: Okuma ağırlıklı ve tutarlı bir cache erişim katmanı (kütüphane/servis) kullanabildiğinde.","Örnek: Bir cache kütüphanesi/istemcisi (ör. loader tanımlı yerel cache veya Redis önünde bir erişim katmanı) ıska anında DB'den yükler.","Invalidation: TTL ve yazışta geçersiz kılma yine gerekir; read-through tek başına güncelliği garanti etmez.","Dikkat: Cache-aside'a çok benzer; fark 'kim dolduruyor' sorusudur. Stampede riski burada da vardır, aynı önlemleri uygula.","Motor notu: Redis kendiliğinden read-through yapmaz; bu deseni uygulama/kütüphane katmanı sağlar."],"related":["slow-query"]},"sol_write_through":{"kind":"solution","title":"Öneri: Write-through cache","detail":"Write-through'da her yazma hem cache'e hem DB'ye (senkron) yapılır; ikisi birlikte güncellenir. Böylece cache asla DB'nin gerisinde kalmaz ve okumalar hep güncel veriyi görür.","steps":["Neden: Cache ile DB tutarlı kalır; yazılan veri anında okunacaksa bayat okuma riski olmaz.","Ne zaman: Yazılan verinin hemen ve sık okunduğu, güçlü okuma tutarlılığı istenen senaryolar.","Örnek: Uygulama yazışta önce DB'yi günceller, hemen ardından cache anahtarını yeni değerle set eder (veya siler).","Dikkat: Her yazma iki hedefe gittiği için yazma gecikmesi artar; ayrıca hiç okunmayacak veri de boşuna cache'lenebilir. İki yazımın atomik olmaması (biri başarılı, diğeri hatalı) tutarsızlık doğurabilir — hata durumunda cache'i sil.","İkili yazma tuzağı: DB ve cache'i ayrı ayrı yazmak yerine 'DB'yi yaz, cache'i sil (invalidate)' yaklaşımı çoğu zaman daha güvenlidir."],"related":[]},"sol_write_behind":{"kind":"solution","title":"Öneri: Write-behind (write-back) cache","detail":"Write-behind'de yazma önce cache'e yapılır ve kullanıcıya hemen dönülür; DB'ye yazma arka planda, eşzamansız (toplu/gecikmeli) gerçekleşir. Yazma hızı en yüksektir ama kalıcılık ve tutarlılık riski taşır.","steps":["Neden: Yazma gecikmesi çok düşer ve yazışlar toplanıp (batch) DB'ye verimli aktarılabilir; yazma yoğun yüklerde DB rahatlar.","Ne zaman: Sayaç, metrik, aktivite akışı gibi çok yüksek yazma hacimli ve kısa gecikmeli tutarlılığın kabul edildiği durumlar.","Örnek: Redis'e yaz → kuyruk/arka plan işçi belirli aralıkla DB'ye toplu flush eder.","Dikkat: Cache düğümü DB'ye yazmadan çökerse veri KAYBOLUR; kalıcılık gereken kritik veride kullanma veya dayanıklı kuyruk/AOF ile koru.","Dikkat: DB bir süre bayat kalır; başka sistemler doğrudan DB okuyorsa güncel olmayan veri görür. Tutarlılık gecikmesini ve kayıp penceresini bilinçli kabul et."],"related":[]}}},"solver/decide-datatype.json":{"id":"decide-datatype","title":"Karar: Doğru veri tipini seç","icon":"🧭","category":"Karar Rehberi","intro":"Veri tipi seçimi, sonradan düzeltmesi en pahalı kararlardan biridir: yanlış tip yanlış sonuç (ör. para için float), boşa yer ve yavaş sorgu üretir. Bu ağaç; sayısal, metin, tarih/saat, anahtar (PK), yarı-yapılı (JSON) ve kategori (ENUM) alanları için doğru tipe yönlendirir ve para/karakter kümesi gibi klasik tuzakları vurgular.","start":"root","nodes":{"root":{"kind":"step","title":"Hangi tür veriyi saklıyorsun?","detail":"Doğru tip, verinin doğasına göre belirlenir. Saklayacağın alan hangi kategoriye giriyor: sayı mı, metin mi, tarih/saat mi, tablonun primary key'i mı, esnek/yarı-yapılı (JSON) veri mi, yoksa sınırlı bir kategori kümesi mi?","choices":[{"label":"Sayısal değer (miktar, para, ölçüm, sayaç)","next":"numeric"},{"label":"Metin (isim, açıklama, kod)","next":"sol_text"},{"label":"Tarih ve/veya saat","next":"sol_datetime"},{"label":"Primary key (PK) tasarlıyorum","next":"sol_pk"},{"label":"Esnek/iç içe/değişken alanlar (yarı-yapılı veri)","next":"sol_json"},{"label":"Sınırlı, bilinen kategori kümesi (durum, tip, öncelik)","next":"sol_enum"}]},"numeric":{"kind":"step","title":"Sayı tam sayı mı, ondalık mı — ve para mı?","detail":"Sayısallarda en kritik ayrım kesinliktir. Değer tam sayı mı (adet, kimlik, sayaç), yoksa ondalık mı? Ondalıksa bu bir PARA/finansal tutar mı? Para ve kesinlik gerektiren her yerde ikili kayan nokta (FLOAT/DOUBLE) yuvarlama hatası ürettiği için kesinlikle kullanılmaz.","choices":[{"label":"Tam sayı (adet, sayaç, id)","next":"sol_integer"},{"label":"Para veya kesin ondalık (fiyat, bakiye, oran)","next":"sol_decimal"}]},"sol_integer":{"kind":"solution","title":"Öneri: Tam sayı (SMALLINT / INT / BIGINT)","detail":"Tam sayılar için gereken aralığa göre en küçük yeterli tipi seç. Gereksiz büyük tip yer ve index boyutu israfıdır; ama sayaç/PK gibi büyüyebilen alanlarda taşmayı (overflow) önlemek için yeterli genişlik şarttır.","steps":["Neden: Doğru genişlik hem yeri hem index/bellek ayak izini optimize eder; aritmetik hızlıdır.","Ne zaman SMALLINT/INT: Sınırlı aralık (yaş, adet, küçük sayaç) için SMALLINT/INT yeterli.","Ne zaman BIGINT: Sürekli artan kimlik/sayaç, kayıt sayısı milyarlara ulaşabilecek PK'ler için BIGINT seç — INT taşması üretimde ciddi bir arıza sebebidir.","Motor farkı: MySQL'de INT UNSIGNED aralığı ikiye katlar; PostgreSQL'de UNSIGNED yoktur, BIGINT'e geç. Oracle NUMBER(p), MSSQL INT/BIGINT.","Dikkat: 'Belki büyür' diye her yere BIGINT koyma; ama artan PK'de baştan BIGINT ucuz sigortadır."],"related":[]},"sol_decimal":{"kind":"solution","title":"Öneri: NUMERIC / DECIMAL — para için ASLA FLOAT","detail":"Para ve kesin ondalıklar için sabit-nokta (exact) NUMERIC/DECIMAL kullan. FLOAT/DOUBLE ikili kayan noktadır ve 0.1 gibi değerleri tam saklayamaz; toplama/çarpmada kuruş kayması, yanlış bakiye ve denetim sorunları üretir.","steps":["Neden: NUMERIC/DECIMAL değerleri ondalık olarak tam saklar; para aritmetiği yuvarlama hatası olmadan doğru sonuç verir.","Ne zaman: Fiyat, bakiye, vergi, oran, faiz gibi kesinlik gereken her alan. Uygun ölçek belirt: DECIMAL(precision, scale), ör. tutar için DECIMAL(19,4).","Alternatif: Bazı sistemler parayı en küçük birimde (kuruş/cent) BIGINT olarak tutar; bu da tam kesinlik verir.","Motor farkı: PostgreSQL NUMERIC, MySQL DECIMAL, Oracle NUMBER(p,s), MSSQL DECIMAL/MONEY (MONEY'nin kısıtlarına dikkat).","Dikkat: FLOAT/DOUBLE sadece bilimsel/ölçümsel yaklaşık değerler ve performansın kesinliğe baskın olduğu durumlar içindir — parada asla."],"related":[]},"sol_text":{"kind":"solution","title":"Öneri: Metin — VARCHAR vs TEXT vs CHAR","detail":"Metinde değişken uzunluklu için VARCHAR/TEXT, gerçekten sabit uzunluk için CHAR kullanılır. Modern motorlarda VARCHAR ile TEXT arasında depolama farkı çoğunlukla önemsizdir; asıl karar anlamsal sınır (uzunluk constraint'i) koyup koymamandır.","steps":["VARCHAR(n): Değişken uzunluklu ve mantıklı bir üst sınır varsa (ör. e-posta, ad) VARCHAR(n) — sınır bir veri doğrulama aracıdır.","TEXT: Uzunluğu öngörülemeyen/uzun serbest metin (açıklama, gövde) için TEXT.","CHAR(n): Yalnızca gerçekten sabit uzunlukta (ör. ülke kodu 'TR', sabit 2 hane) kullan; kısa metinde CHAR sağa boşluk doldurur ve genelde gereksizdir.","Motor farkı: PostgreSQL'de VARCHAR ve TEXT performansı aynıdır, sınır sadece constraint'tir. MySQL'de VARCHAR satır içi, TEXT ayrı saklanabilir ve indekslemede prefix sınırı vardır. Oracle VARCHAR2 kullan.","Charset/collation: Emoji ve tam Unicode için MySQL'de mutlaka utf8mb4 (eski 'utf8' 3 baytlıktır, emojiyi bozar); collation'ı (ör. utf8mb4_0900_ai_ci) sıralama/karşılaştırma ihtiyacına göre seç. PostgreSQL genelde UTF-8 veritabanı + uygun collation."],"related":[]},"sol_datetime":{"kind":"solution","title":"Öneri: Tarih/saat — zaman dilimli TIMESTAMP","detail":"Bir anı (olay zamanı) saklıyorsan zaman dilimi bilincine sahip tipi seç. Zaman dilimsiz saklamak, farklı bölge/yaz saati durumlarında yanlış hesaplama ve karşılaştırmaya yol açar.","steps":["Neden: Zaman dilimli tip, anı UTC olarak normalize edip tutarlı karşılaştırma ve dönüşüm sağlar; global sistemlerde şarttır.","Ne zaman TIMESTAMPTZ: Olay/işlem anları için PostgreSQL'de TIMESTAMP WITH TIME ZONE (timestamptz) kullan; UTC sakla, sunumda kullanıcı dilimine çevir.","Sadece tarih/saat: Takvim günü için DATE, saat dilimiyle ilgisi olmayan saat için TIME; süre için INTERVAL (destekleyen motorlarda).","Motor farkı: PostgreSQL timestamptz (aslında UTC saklar). MySQL'de TIMESTAMP zaman dilimine göre dönüştürülür ama aralığı sınırlıdır (2038); DATETIME dönüştürmez — UTC saklama disiplinini uygulamada kur. Oracle TIMESTAMP WITH TIME ZONE, MSSQL DATETIMEOFFSET.","Dikkat: Zamanı metin (VARCHAR) veya epoch INT olarak tutmak sıralama, aralık ve zaman dilimi işlemlerini bozar; gerçek tarih/saat tipini kullan."],"related":[]},"sol_pk":{"kind":"solution","title":"Öneri: Primary key — BIGINT vs UUID","detail":"PK seçiminde iki ana yol vardır: artan sayısal (BIGINT identity/sequence) veya UUID. Sayısal PK küçük ve index dostu ama tahmin edilebilir ve merkezi üretim gerektirir; UUID dağıtık üretilebilir ama daha büyük ve rastgele sırası index'i olumsuz etkileyebilir.","steps":["BIGINT (artan): En küçük, en hızlı index; sıralı ekleme B-tree için idealdir. Tek DB/merkezî üretimde varsayılan tercih; INT yerine baştan BIGINT taşmaya karşı güvenli.","UUID: İstemci/dağıtık sistemlerde çakışmadan üretilebilir, kimlik dışa açıksa numarayı ifşa etmez. Ama 16 bayt (2×BIGINT) yer kaplar.","UUID sırası önemli: Tümüyle rastgele UUID (v4) sıralı olmadığından index'e dağınık ekleme (page split, düşük cache isabeti) yapar; zaman-sıralı UUID (v7/ULID) bunu büyük ölçüde giderir.","Motor farkı: PostgreSQL yerel uuid tipi; MySQL'de UUID'yi BINARY(16) olarak sakla (metin CHAR(36) yerine) ve mümkünse sıralı üret. MSSQL uniqueidentifier + NEWSEQUENTIALID, Oracle RAW(16).","Dikkat: UUID'yi VARCHAR/CHAR(36) metin olarak saklamak yeri ve index'i ~iki-üç katına çıkarır; ikili (binary) sakla."],"related":[]},"sol_json":{"kind":"solution","title":"Öneri: JSON / JSONB — ölçülü kullan","detail":"Şeması esnek, iç içe veya seyrek alanlar için JSON tipi güçlüdür; ama ilişkisel disiplin (constraint, index, tip güvenliği) kaybolabilir. Kural: sabit ve sık sorgulanan alanları normal kolonlara çıkar, gerçekten değişken kısmı JSON'da tut.","steps":["Neden: Değişken/opsiyonel alanları tek kolonda esnek biçimde saklar; şema göçü olmadan alan eklenebilir.","Ne zaman: Dış API yükleri, kullanıcı tanımlı alanlar, ürün özellikleri gibi öngörülemeyen yapılar.","Motor farkı: PostgreSQL'de JSONB kullan (ikili, indekslenebilir, GIN ile @>/? sorguları) — düz JSON yerine tercih et. MySQL'in JSON tipi de ikilidir ve generated column + index ile sorgulanır. Oracle 21c+ JSON tipi/OSON, MSSQL 2025 öncesinde JSON'ı NVARCHAR içinde tutup fonksiyonlarla işler; SQL Server 2025 ve Azure SQL'de yerel (ikili) json tipi vardır.","Dikkat: Sık filtrelenen JSON alanlarını indeksle (PostgreSQL GIN, MySQL generated column index'i); yoksa her sorgu tüm belgeyi tarar.","Dikkat: Her şeyi JSON'a doldurma — ilişkisel bütünlük, foreign key ve tipleme kaybolur. Sorgu/constraint gereken alanlar gerçek kolon olmalı."],"related":["decide-sqlnosql"]},"sol_enum":{"kind":"solution","title":"Öneri: ENUM vs lookup (referans) tablo","detail":"Sınırlı kategori kümeleri için iki yol vardır: motorun ENUM tipi ya da bir lookup tablosu + foreign key. ENUM kompakt ve basittir ama değer eklemek şema değişikliği gerektirir; lookup tablo esnektir ve ek nitelik (açıklama, aktiflik, sıra) taşıyabilir.","steps":["ENUM ne zaman: Değerler çok kararlı ve nadiren değişiyorsa (ör. cinsiyet, gün) ve ek nitelik gerekmiyorsa; kompakt ve okunası.","Lookup tablo ne zaman: Değerler zamanla değişebiliyor, çokdillilik/açıklama/sıra/aktiflik gibi ek alan gerekiyor veya raporlarda birleştirme (join) yapılıyorsa — daha esnektir.","Motor farkı: PostgreSQL ve MySQL yerel ENUM tipi sunar (PostgreSQL'de ENUM'a değer eklemek ALTER TYPE ister, sıralama tanım sırasına göredir). Oracle ve MSSQL'de yerleşik ENUM yoktur; CHECK constraint'i veya lookup tablo kullanılır.","Dikkat: ENUM'da değer eklemek/çıkarmak şema göçüdür ve büyük tabloda lock/masraf yaratabilir; sık değişen kümelerde lookup tabloyu tercih et.","Alternatif: Serbest metin + CHECK constraint'i da küçük, kararlı kümeler için pratik bir orta yoldur."],"related":[]}}},"solver/decide-capacity.json":{"id":"decide-capacity","title":"Karar: Sunucu boyutlandırma (sizing)","icon":"🧭","category":"Karar Rehberi","intro":"Doğru boyutlandırma; iş yükü profilinden (OLTP, veri ambarı, karma) başlar ve gerçek darboğazı (CPU mu, I/O mu, RAM mi) bulmayı gerektirir. Altın kural: sık erişilen veri kümesi (working set) RAM'e sığmalı, önce ölç sonra büyüt ve ani yükler için pay (headroom) bırak. Bu ağaç; iş yükünü belirleyip darboğaza göre kaynağı ve ölçekleme yönünü (dikey/yatay) seçmeye yardım eder.","start":"root","nodes":{"root":{"kind":"step","title":"İş yükü profilin nedir?","detail":"Boyutlandırma iş yüküyle başlar çünkü OLTP ile analitik yükler tamamen farklı kaynak profili ister. Sistemin ağırlıklı işi ne: çok sayıda küçük, hızlı işlem (OLTP) mi, büyük tarama/agregasyon içeren raporlama/analitik (DWH) mi, yoksa ikisinin karışımı mı? Emin değilsen önce ölçmen gerekir.","choices":[{"label":"OLTP — çok sayıda küçük, kısa işlem (web/uygulama)","next":"bottleneck"},{"label":"Analitik / veri ambarı (DWH) — büyük tarama ve agregasyon","next":"sol_dwh"},{"label":"Karma yük veya emin değilim","next":"sol_measure"},{"label":"Darboğazı biliyorum; dikey mi yatay mı büyütmeliyim?","next":"sol_scale"}]},"bottleneck":{"kind":"step","title":"Darboğaz nerede: RAM mi, I/O mu, CPU mu?","detail":"OLTP'de kaynağı körlemesine artırmak yerine gerçek darboğazı bul. Metriklerine bak: sık erişilen veri RAM'e sığmıyor ve disk okuması mı yüksek (RAM/I/O), diskin gecikmesi/IOPS'i mi yetmiyor (I/O), yoksa veri zaten bellekte ama işlemci mi doluyor (CPU)? Yanlış kaynağı büyütmek para ve zaman israfıdır.","choices":[{"label":"Sık erişilen veri RAM'e sığmıyor, disk okuması yüksek","next":"sol_ram"},{"label":"Veri bellekte ama disk gecikmesi/IOPS yetersiz (yazma ağır)","next":"sol_io"},{"label":"Veri bellekte, disk rahat ama CPU sürekli dolu","next":"sol_cpu"}]},"sol_measure":{"kind":"solution","title":"Öneri: Önce ölç, sonra boyutlandır","detail":"Tahminle donanım almak neredeyse her zaman yanlış boyutlandırma üretir. İş yükü profili ve darboğaz, gerçek metriklerle ortaya çıkar. Boyutlandırma bir tahmin değil, ölçüm-temelli bir iterasyondur.","steps":["Neden: OLTP mi DWH mi, darboğaz CPU/I/O/RAM'den hangisi — bunlar ancak gerçek yük altında ölçülünce netleşir; tahmin pahalı hatadır.","Ölç: CPU kullanımı ve run-queue, bellek/cache isabet oranı (buffer cache hit), disk IOPS ve gecikme (latency), aktif bağlantı ve wait event'ler.","Motor araçları: PostgreSQL pg_stat_* ve wait events, Oracle AWR/ASH, MySQL Performance Schema, MSSQL DMV'ler ve wait stats.","Yaklaşım: Temsili yükle test et, en dar kaynağı bul, sadece onu büyüt, tekrar ölç. Kaynağı tek tek değiştir ki etkiyi izole edebilesin.","Sonra: Profil netleşince ilgili karara (OLTP darboğazı, DWH veya yatay/dikey ölçekleme) geç."],"related":["high-cpu","memory-pressure","slow-query"]},"sol_ram":{"kind":"solution","title":"Öneri: RAM'i büyüt — working set belleğe sığmalı","detail":"En kritik OLTP kuralı: sık erişilen veri ve index'ler (working set) belleğe (buffer/cache) sığmalıdır. Sığmazsa her sorgu diske iner, gecikme patlar ve I/O darboğaza dönüşür. Genellikle en yüksek getirili yatırım RAM'dir.","steps":["Neden: Bellekten okuma diskten yüzlerce-binlerce kat hızlıdır; working set RAM'e sığdığında cache isabeti artar, disk I/O çöker.","Ne zaman: Cache isabet oranı düşük, sık 'disk read' wait event'ler, aktif veri kümesi mevcut RAM'den büyük.","Nasıl: DB bellek alanını doğru ayarla — PostgreSQL shared_buffers + OS page cache, MySQL innodb_buffer_pool_size (genelde RAM'in büyük kısmı), Oracle SGA/buffer cache, MSSQL max server memory.","Hedef: İdeali working set + index'ler belleğe sığsın; tamamı sığmıyorsa en sık erişilen 'sıcak' kısım sığmalı.","Dikkat: Buffer pool'u fiziksel RAM'in tamamına verme; OS, bağlantı başına bellek ve diğer süreçlere pay bırak, yoksa takas (swap) her şeyi yavaşlatır."],"related":["memory-pressure","slow-query"]},"sol_io":{"kind":"solution","title":"Öneri: I/O katmanını güçlendir (IOPS/latency)","detail":"Veri bellekte olsa bile yazma-ağırlıklı yükte (commit, WAL/redo/binlog, checkpoint) disk hızı belirleyicidir. Burada mesele kapasite değil, IOPS ve gecikmedir. Yanlış disk sınıfı, hızlı CPU/RAM'e rağmen sistemi dize getirir.","steps":["Neden: Kalıcılık (durability) için her commit diske log yazar; düşük IOPS/yüksek gecikmeli disk, transaction hızını doğrudan sınırlar.","Ne zaman: Yüksek disk gecikmesi, uzun 'log/WAL write' beklemeleri, checkpoint sırasında darboğaz, yazma yoğun OLTP.","Nasıl: NVMe/SSD kullan; transaction log'u veri dosyalarından ayrı hızlı diske al; bulutta yeterli IOPS/throughput sağlanan disk sınıfı (ör. provisioned IOPS) seç.","Hedef: Hem IOPS hem gecikme (latency) hedefi koy — sadece IOPS değil, p99 gecikme de önemlidir. RAID/yazma önbelleği (BBU) yazma gecikmesini düşürebilir.","Dikkat: Bulutta disk throughput'u ve IOPS'i çoğunlukla instance boyutuna da bağlıdır; ağ-bağlı disklerde gecikme yerel NVMe'den yüksektir."],"related":["disk-full","slow-query"]},"sol_cpu":{"kind":"solution","title":"Öneri: CPU darboğazını çöz (önce sorgu, sonra çekirdek)","detail":"Veri bellekte ve disk rahatken CPU doluysa, çoğu zaman kök neden verimsiz sorgular (kötü plan, eksik index, çok sayıda küçük sorgu) veya aşırı eşzamanlılıktır. Çekirdek eklemeden önce yükü azaltmak genelde daha ucuz ve etkilidir.","steps":["Neden: CPU'yu en çok tam tarama, sıralama/hash, plan derleme ve gereğinden fazla bağlantının bağlam değişimi yer. Bunları düzeltmek çekirdekten ucuzdur.","Önce optimize et: En pahalı sorguları bul (pg_stat_statements / AWR / Performance Schema), eksik index'leri ekle, N+1 sorguları azalt, bağlantı havuzunu küçült.","Sonra ölçekle: Sorgular sağlıklıysa ve CPU hâlâ doluysa çekirdek sayısını artır (dikey) — özellikle yüksek eşzamanlı OLTP'de.","Motor notu: Fazla bağlantı = fazla bağlam değişimi; küçük havuz + hızlı devir çoğu zaman daha çok çekirdekten iyi sonuç verir (bkz. bağlantı havuzu kararı).","Dikkat: Lisanslama çekirdek başına ise (Oracle/MSSQL) çekirdek eklemek pahalıdır; önce sorgu optimizasyonu maliyeti düşürür."],"related":["high-cpu","slow-query"]},"sol_dwh":{"kind":"solution","title":"Öneri: Analitik/DWH — throughput, paralellik ve yatay ölçek","detail":"Veri ambarı yükü, büyük tabloları tarayıp agrega eden az sayıda ağır sorgudan oluşur. Burada öncelik düşük gecikme değil, yüksek tarama verimi (throughput), paralellik ve genellikle yatay ölçeklenebilir mimaridir.","steps":["Neden: Sorgular terabaytları tarar; disk/bellek bant genişliği ve paralel çalışan çekirdekler belirleyicidir, tekil işlem gecikmesi değil.","Nasıl: Yüksek I/O throughput'lu depolama, bol RAM (agregasyon/hash join için), çok çekirdek ve paralel sorgu; kolon-temelli (columnar) depo veya MPP mimarisi büyük ölçekte çok verimlidir.","Yatay ölçek: Büyük DWH'de tek makineyi büyütmek yerine dağıtık/MPP (ör. shard'lı analitik motorlar) genelde daha iyi ölçeklenir; partition + partition pruning taramayı küçültür.","Motor notu: OLTP ayarlarını buraya taşıma — DWH'de daha büyük work_mem/sort alanı, paralel derece (parallelism) ve büyük blok/okuma-önden getirme (readahead) tercih edilir.","Dikkat: OLTP ve DWH'yi aynı sunucuda karıştırma; ağır raporlar OLTP'yi boğar. Mümkünse analitiği ayrı replika/veri ambarına al."],"related":["decide-shard-replica","decide-partition"]},"sol_scale":{"kind":"solution","title":"Genel ilke: Dikey mi yatay mı + headroom + önce ölç","detail":"Hangi kaynağı büyüteceğin kadar, nasıl ölçekleyeceğin de önemli. Dikey (daha büyük makine) basittir ama bir tavana ve tek nokta riskine sahiptir; yatay (daha çok makine) ölçeklenir ama karmaşıklık ekler. Her durumda ani yükler için pay bırak ve kararı ölçümle doğrula.","steps":["Dikey (scale-up): Kaynağı (CPU/RAM/IO) tek makinede artır — en basit ve çoğu OLTP için ilk adım; ama fiziksel/maliyet tavanı ve tek arıza noktası vardır.","Yatay (scale-out): Okuma replikaları (okuma yükü için) veya sharding (yazma/veri hacmi için) ekle — sınırsıza yakın ölçek ama tutarlılık ve operasyon karmaşıklığı getirir.","Headroom: Kaynakları %100'e göre planlama; normal tepe yükte ~%30 pay (headroom) bırak ki ani artış, bakım ve büyüme sığsın.","Önce ölç: Büyütmeden önce darboğazı ölçerek doğrula, en dar kaynağı hedefle, değişiklikten sonra tekrar ölç.","Dikkat: Yatay ölçek her sorunu çözmez — dağıtık transaction ve join maliyetlidir; önce dikey büyütme ve optimizasyon tükendiğinde geç."],"related":["decide-shard-replica","decide-ha"]}}},"solver/slow-write.json":{"id":"slow-write","title":"Yavaş yazma (INSERT/UPDATE gecikmesi)","icon":"🐢","category":"Performans","intro":"INSERT/UPDATE/DELETE işlemleri beklenenden yavaş. Önce yazmanın neyi beklediğini (commit/redo, lock, disk ya da satır başına ek maliyet) belirleyip adım adım kök nedene iniyoruz.","start":"root","nodes":{"root":{"kind":"step","title":"Yazma neyi bekliyor?","detail":"Wait event'lere bakarak darboğazı sınıfla: commit/redo (WAL) senkronizasyonu mu, lock mi, disk yazma gecikmesi mi, yoksa satır başına index/trigger maliyeti mi baskın?","command":{"oracle":"SELECT event, total_waits, ROUND(time_waited/100,1) AS sec_waited\nFROM v$system_event\nWHERE event IN ('log file sync','log file parallel write','enq: TX - row lock contention','db file sequential read')\nORDER BY time_waited DESC;","postgres":"SELECT wait_event_type, wait_event, count(*) AS sessions\nFROM pg_stat_activity\nWHERE state='active'\nGROUP BY 1,2 ORDER BY 3 DESC;","mysql":"SHOW GLOBAL STATUS LIKE 'Innodb_row_lock_waits';\nSHOW GLOBAL STATUS LIKE 'Innodb_os_log_pending_fsyncs';\nSHOW ENGINE INNODB STATUS\\G","mssql":"SELECT TOP 10 wait_type, waiting_tasks_count, wait_time_ms\nFROM sys.dm_os_wait_stats\nWHERE wait_type IN ('WRITELOG','PAGEIOLATCH_EX','LCK_M_X','LCK_M_U')\nORDER BY wait_time_ms DESC;"},"choices":[{"label":"Commit / redo (WAL sync) bekliyor","next":"commit"},{"label":"Lock bekliyor","next":"lock"},{"label":"Satır başına ek maliyet (index/trigger) şüphesi","next":"overhead"},{"label":"Disk yazma gecikmesi yüksek","next":"sol_disk"}]},"commit":{"kind":"step","title":"Commit deseni mi, fsync mi?","detail":"Her satırda ayrı commit (autocommit) redo/log senkronizasyonunu satır sayısı kadar tetikler. Aksine commit sayısı makul ama her commit fsync'te bekliyorsa sorun log diskinin gecikmesindedir.","command":{"oracle":"SELECT name, value FROM v$sysstat WHERE name IN ('user commits','redo writes','redo size');\nSELECT ROUND(time_waited_micro/GREATEST(total_waits,1)/1000,2) AS ms_per_sync FROM v$system_event WHERE event='log file sync';","postgres":"SHOW synchronous_commit;\nSELECT wal_records, wal_fpi, wal_bytes, wal_buffers_full FROM pg_stat_wal; -- wal_sync/wal_sync_time PG14–17; PG18+: pg_stat_io (object = 'wal')","mysql":"SHOW VARIABLES LIKE 'innodb_flush_log_at_trx_commit';\nSHOW VARIABLES LIKE 'sync_binlog';\nSHOW GLOBAL STATUS LIKE 'Com_commit';","mssql":"SELECT io_stall_write_ms, num_of_writes, io_stall_write_ms/NULLIF(num_of_writes,0) AS ms_per_write\nFROM sys.dm_io_virtual_file_stats(DB_ID(), 2);"},"choices":[{"label":"Autocommit / her satırda commit var","next":"sol_batch"},{"label":"Commit log senkronizasyonunda (fsync) bekliyor","next":"sol_disk"}]},"lock":{"kind":"step","title":"Lock'u kim tutuyor?","detail":"Yazma bir lock için bekliyorsa: başka bir oturum aynı satırı/index'i tutuyor olabilir, ya da çok sayıda oturum aynı hot row'a yazmaya çalışıyor olabilir.","command":{"oracle":"SELECT s.sid, s.serial#, s.username, s.blocking_session, s.event, s.seconds_in_wait\nFROM v$session s WHERE s.blocking_session IS NOT NULL;","postgres":"SELECT pid, pg_blocking_pids(pid) AS blocked_by, wait_event, left(query,60) AS query\nFROM pg_stat_activity\nWHERE cardinality(pg_blocking_pids(pid)) > 0;","mysql":"SELECT requesting_engine_transaction_id AS waiter, blocking_engine_transaction_id AS blocker,\n       object_name, lock_type, lock_mode\nFROM performance_schema.data_lock_waits w\nJOIN performance_schema.data_locks l ON l.engine_lock_id = w.blocking_engine_lock_id;","mssql":"SELECT session_id, blocking_session_id, wait_type, wait_time, wait_resource\nFROM sys.dm_exec_requests\nWHERE blocking_session_id <> 0;"},"choices":[{"label":"Başka oturum lock'u tutuyor","next":"sol_lock"},{"label":"Çok oturum aynı hot row'a yazıyor","next":"sol_hotrow"}]},"overhead":{"kind":"step","title":"Satır başına ek maliyet nereden?","detail":"Her INSERT/UPDATE, tablodaki tüm index'leri de günceller ve varsa trigger/constraint'leri çalıştırır. Aşırı index sayısı ya da ağır trigger, yazmayı ciddi yavaşlatır.","command":{"oracle":"SELECT index_name, uniqueness FROM user_indexes WHERE table_name='T';\nSELECT trigger_name, triggering_event FROM user_triggers WHERE table_name='T';","postgres":"SELECT indexname, indexdef FROM pg_indexes WHERE tablename='t';\nSELECT tgname FROM pg_trigger WHERE tgrelid='t'::regclass AND NOT tgisinternal;","mysql":"SHOW INDEX FROM t;\nSHOW TRIGGERS LIKE 't';","mssql":"SELECT name, type_desc FROM sys.indexes WHERE object_id=OBJECT_ID('dbo.t');\nSELECT name, is_disabled FROM sys.triggers WHERE parent_id=OBJECT_ID('dbo.t');"},"choices":[{"label":"Tabloda çok fazla / gereksiz index var","next":"sol_index"},{"label":"Ağır trigger veya constraint maliyeti var","next":"sol_trigger"}]},"sol_batch":{"kind":"solution","title":"Kök neden: Autocommit / satır başına commit","detail":"Her satır için ayrı commit, redo/log senkronizasyonunu satır sayısı kadar tekrarlar. Transaction'ları gruplayarak commit sayısını (dolayısıyla fsync sayısını) dramatik biçimde azaltabilirsin.","steps":["Uygulamada autocommit'i kapat ve N (ör. 500-5000) satırda bir commit yapacak şekilde toplu (batch) commit uygula.","Tekil INSERT yerine çok satırlı INSERT / bulk-load yolları kullan (Postgres COPY, Oracle bulk insert, MySQL LOAD DATA, MSSQL BULK INSERT).","Prepared statement kullanarak tekrarlı hard parse maliyetini düşür.","Değişiklikten sonra 'log file sync' / WRITELOG beklemesinin düştüğünü doğrula."],"related":["active-sessions"]},"sol_disk":{"kind":"solution","title":"Kök neden: Yavaş redo/log diski (fsync gecikmesi)","detail":"Her commit, redo/WAL kaydını kalıcı diske yazana (fsync) kadar bekler. Log diski yavaşsa (yüksek yazma gecikmesi, IOPS yetersizliği), her commit bu gecikmeyi öder.","steps":["Log/redo dosyalarını düşük gecikmeli, ayrılmış bir diske (tercihen NVMe SSD) taşı; veri dosyalarından fiziksel olarak ayır.","Depolama gecikmesini ölç (dosya IO istatistikleri); yazma başına ms yüksekse donanım/RAID yazma önbelleğini gözden geçir.","Sanal/bulut ortamda ayrılmış IOPS ve throughput sınırlarını yükselt.","Dayanıklılık gereksinimi izin veriyorsa gruplu commit / commit gecikmesi ayarlarını (ör. Postgres commit_delay) değerlendir; ama veri kaybı riskini tart."],"related":[]},"sol_lock":{"kind":"solution","title":"Kök neden: Başka oturum lock'u tutuyor","detail":"Yazma, başka bir oturumun tuttuğu satır/index lock'unu bekliyor. Genelde uzun süren ya da commit'i unutulmuş bir transaction engelleyicidir.","steps":["Engelleyici (blocker) oturumu tespit et ve ne yaptığını (uzun batch mı, idle-in-transaction mı) incele.","Engelleyici gereksiz uzun/açık kalmışsa uygulamada commit/rollback düzenini düzelt.","Acil durumda engelleyiciyi kontrollü sonlandır (kill session / pg_terminate_backend / KILL).","Transaction'ları kısa tut; transaction içinde kullanıcı etkileşimi bekleme."],"related":["blocking-sessions","current-locks"]},"sol_hotrow":{"kind":"solution","title":"Kök neden: Hot row çekişmesi","detail":"Çok sayıda oturum aynı satıra (ör. bir sayaç, sıra numarası, bakiye) yazmaya çalışıyor; hepsi aynı lock için sıraya giriyor ve yazma serileşiyor.","steps":["Hot counter deseninde değeri paralel bucket'lara böl (sharded counter) ve okurken topla.","Sıra/kimlik üretimini merkezi tek satır yerine sequence/identity mekanizmasına taşı.","Güncelleme sıklığını azalt: ara toplamları uygulamada tampon, periyodik olarak yaz.","İşlem sırasını standartlaştırıp lock süresini kısaltarak çekişmeyi düşür."],"related":["current-locks"]},"sol_index":{"kind":"solution","title":"Kök neden: Aşırı index maliyeti","detail":"Tablodaki her index, her yazmada güncellenir. Çok sayıda ya da kullanılmayan index, INSERT/UPDATE'i doğrudan yavaşlatır.","steps":["Kullanılmayan/çakışan index'leri tespit et (kullanım istatistikleri) ve güvenle kaldır.","Geniş bileşik index'leri sadeleştir; aynı öncül kolonları tekrar eden index'leri birleştir.","Büyük toplu yüklemelerde index'leri geçici devre dışı bırakıp yükleme sonrası yeniden oluşturmayı değerlendir.","Değişiklik sonrası yazma gecikmesini yeniden ölçüp iyileşmeyi doğrula."],"related":["slow-queries"]},"sol_trigger":{"kind":"solution","title":"Kök neden: Ağır trigger / constraint","detail":"Yazma başına çalışan trigger veya doğrulanan constraint (özellikle index'siz foreign key kontrolü) her satıra ek maliyet bindirir.","steps":["Trigger gövdesindeki ağır işleri (ör. senkron log yazımı) asenkron/kuyruk tabanlı hale getir.","Foreign key'lerde referans veren (child) kolonları indeksle; aksi halde parent'taki her DELETE/UPDATE child tabloyu tam tarar.","Satır-satır (row-level) trigger yerine mümkünse ifade (statement-level) düzeyine taşı.","Gereksiz veya iş kuralına dönüşmüş trigger mantığını uygulama katmanına al."],"related":[]}}},"solver/io-bottleneck.json":{"id":"io-bottleneck","title":"Yüksek IO bekleme / disk gecikmesi","icon":"💽","category":"Performans","intro":"Sistem disk IO'sunda bekliyor. Önce yükün okuma mı yazma mı ağırlıklı olduğunu ayırıp, oradan buffer cache yetersizliği, tam tablo taraması, checkpoint fırtınası, IOPS sınırı ya da geçici alana spill nedenlerine iniyoruz.","start":"root","nodes":{"root":{"kind":"step","title":"IO okuma mı yazma mı ağırlıklı?","detail":"Dosya IO istatistiklerine bakarak beklemenin okuma tarafında mı (veri diskten okunuyor) yoksa yazma tarafında mı (redo/checkpoint/veri yazımı) olduğunu belirle. Bu, ağacı ikiye ayırır.","command":{"oracle":"SELECT function_name, small_read_reqs+large_read_reqs AS reads, small_write_reqs+large_write_reqs AS writes,\n       small_read_megabytes+large_read_megabytes+small_write_megabytes+large_write_megabytes AS mb\nFROM v$iostat_function ORDER BY mb DESC;","postgres":"SELECT sum(blks_read) AS reads, sum(blks_hit) AS hits FROM pg_stat_database;\nSELECT buffers_checkpoint, buffers_clean, buffers_backend FROM pg_stat_bgwriter;","mysql":"SHOW GLOBAL STATUS LIKE 'Innodb_data_read';\nSHOW GLOBAL STATUS LIKE 'Innodb_data_written';\nSHOW GLOBAL STATUS LIKE 'Innodb_data_reads';","mssql":"SELECT DB_NAME(database_id) AS db, io_stall_read_ms, io_stall_write_ms, num_of_reads, num_of_writes\nFROM sys.dm_io_virtual_file_stats(NULL, NULL)\nORDER BY io_stall_read_ms + io_stall_write_ms DESC;"},"choices":[{"label":"Ağırlıklı okuma IO","next":"read"},{"label":"Ağırlıklı yazma IO","next":"write"}]},"read":{"kind":"step","title":"Okuma IO'su neden yüksek?","detail":"Fazla fiziksel okuma üç ana nedenden gelir: buffer cache çok küçük (working set RAM'e sığmıyor), sorgular tam tablo taraması yapıyor, ya da büyük sort/hash işlemleri geçici alana taşıyor.","command":{"oracle":"SELECT ROUND((1-(pr.value/(dbg.value+cg.value)))*100,2) AS buffer_hit_pct\nFROM v$sysstat pr, v$sysstat dbg, v$sysstat cg\nWHERE pr.name='physical reads' AND dbg.name='db block gets' AND cg.name='consistent gets';\nSELECT sql_id, disk_reads, executions FROM v$sql ORDER BY disk_reads DESC FETCH FIRST 10 ROWS ONLY;","postgres":"SELECT ROUND(sum(blks_hit)*100.0/nullif(sum(blks_hit)+sum(blks_read),0),2) AS cache_hit_pct FROM pg_stat_database;\nSELECT query, shared_blks_read, temp_blks_read FROM pg_stat_statements ORDER BY shared_blks_read DESC LIMIT 10;","mysql":"SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_read_requests';\nSHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_reads';\nSHOW GLOBAL STATUS LIKE 'Created_tmp_disk_tables';","mssql":"SELECT CAST(100.0 * a.cntr_value / NULLIF(b.cntr_value, 0) AS decimal(5,2)) AS buffer_cache_hit_ratio\nFROM sys.dm_os_performance_counters a\nJOIN sys.dm_os_performance_counters b ON b.object_name = a.object_name AND b.counter_name = 'Buffer cache hit ratio base'\nWHERE a.counter_name = 'Buffer cache hit ratio' AND a.object_name LIKE '%Buffer Manager%';"},"choices":[{"label":"Buffer cache düşük, working set sığmıyor","next":"sol_cache"},{"label":"Sorgular tam tablo taraması yapıyor","next":"sol_scan"},{"label":"Büyük sort/hash geçici alana taşıyor","next":"sol_spill"}]},"write":{"kind":"step","title":"Yazma IO'su neden yüksek?","detail":"Yazma tarafındaki darboğaz ya periyodik checkpoint/flush'ların diski kısa süreliğine boğmasından (checkpoint fırtınası) ya da depolamanın sürekli yükü karşılayacak IOPS/throughput'a sahip olmamasından kaynaklanır.","command":{"oracle":"SELECT event, total_waits, ROUND(time_waited/100,1) AS sec\nFROM v$system_event\nWHERE event IN ('log file parallel write','db file parallel write','checkpoint completed')\nORDER BY time_waited DESC;","postgres":"-- PG17+:\nSELECT num_timed, num_requested, buffers_written FROM pg_stat_checkpointer;\n-- PG16 ve öncesi:\nSELECT checkpoints_timed, checkpoints_req, buffers_checkpoint, maxwritten_clean\nFROM pg_stat_bgwriter;\nSHOW checkpoint_completion_target;","mysql":"SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';\nSHOW GLOBAL STATUS LIKE 'Innodb_os_log_written';\nSHOW ENGINE INNODB STATUS\\G","mssql":"SELECT cntr_value FROM sys.dm_os_performance_counters WHERE counter_name='Checkpoint pages/sec';\nSELECT cntr_value FROM sys.dm_os_performance_counters WHERE counter_name='Page writes/sec';"},"choices":[{"label":"Ani checkpoint/flush dalgaları (checkpoint fırtınası)","next":"sol_checkpoint"},{"label":"Depolama sürekli yüke yetişemiyor (IOPS sınırı)","next":"sol_iops"}]},"sol_cache":{"kind":"solution","title":"Kök neden: Yetersiz buffer cache","detail":"Sık erişilen veri kümesi (working set) buffer cache'e sığmadığından bloklar sürekli diskten yeniden okunuyor. İsabet oranı düşük, fiziksel okuma yüksek.","steps":["Buffer/cache boyutunu büyüt: Oracle db_cache_size/SGA, Postgres shared_buffers, MySQL innodb_buffer_pool_size, MSSQL max server memory.","İsabet oranını ve fiziksel okumaları değişiklik öncesi/sonrası karşılaştır.","RAM fiziksel olarak yetersizse sunucu belleğini artır ya da working set'i azaltacak arşivleme/bölümleme yap.","Gerçek darboğaz tek bir tarama deseninden geliyorsa cache-hit ağacındaki tarama koluna geç."],"related":["cache-hit-ratio"]},"sol_scan":{"kind":"solution","title":"Kök neden: Tam tablo taraması","detail":"Sorgular uygun index olmadığı için büyük tabloları baştan sona tarıyor; bu, hem çok fiziksel okuma yaratır hem de cache'i faydasız bloklarla kirletir.","steps":["En çok fiziksel okuma yapan sorguların planını çıkar (EXPLAIN); full scan noktalarını bul.","Filtre ve join kolonlarına uygun index ekle; planın index erişimine döndüğünü doğrula.","Çok büyük tablolarda tarih/aralık bazlı bölümleme (partitioning) ile taranan veriyi küçült.","Gereksiz 'SELECT *' yerine sadece gereken kolonları seçerek okunan blok sayısını azalt."],"related":["slow-queries"]},"sol_spill":{"kind":"solution","title":"Kök neden: Sort/hash geçici alana taşıyor","detail":"Büyük sıralama, hash join veya group by işlemleri çalışma belleğine sığmayıp geçici alana (temp/tempdb) yazıyor; bu da yoğun okuma/yazma IO'su üretir.","steps":["Çalışma belleği ayarını yükselt: Oracle pga_aggregate_target, Postgres work_mem, MySQL sort_buffer_size/join_buffer_size, MSSQL memory grant.","İşlem hacmini azalt: filtreleri erken uygula, gereksiz sıralamayı kaldır, join sırasını iyileştir.","Sık kullanılan sıralama/gruplama için uygun index ekleyerek diske spill'i önle.","Geçici alanı hızlı bir diske al; kalıcıysa undo/temp baskısı ağacıyla derinleştir."],"related":["slow-queries"]},"sol_checkpoint":{"kind":"solution","title":"Kök neden: Checkpoint fırtınası","detail":"Dirty page'ler uzun süre biriktirilip kısa aralıklarla topluca diske yazılıyor; bu ani yazma dalgaları IO'yu periyodik olarak boğuyor.","steps":["Checkpoint'i zamana yay: Postgres checkpoint_completion_target'ı artır, checkpoint_timeout'u dengele.","MySQL'de innodb_io_capacity / innodb_io_capacity_max'ı depolamaya göre ayarla, adaptive flushing'i düzenle.","MSSQL'de indirect checkpoint (target_recovery_time) ile ani dalgaları tabana yay.","Oracle'da fast_start_mttr_target ile checkpoint sıklığını dengeleyip log dosyalarını büyüt."],"related":[]},"sol_iops":{"kind":"solution","title":"Kök neden: Yetersiz IOPS / throughput","detail":"Depolama, iş yükünün gerektirdiği okuma+yazma isteğini karşılayacak IOPS ya da bant genişliğine sahip değil; kuyruk derinliği ve gecikme sürekli yüksek.","steps":["Disk gecikmesini ölç (istek başına ms) ve donanım/bulut IOPS sınırıyla karşılaştır.","Daha hızlı depolamaya geç (HDD→SSD/NVMe) veya bulutta ayrılmış IOPS/throughput seviyesini yükselt.","Veri, redo/log ve geçici alanı farklı disklere dağıtarak çekişmeyi azalt.","Kalıcı çözüm olarak toplam IO talebini düşür (indeksleme, arşivleme, sorgu optimizasyonu)."],"related":[]}}},"solver/undo-temp-pressure.json":{"id":"undo-temp-pressure","title":"Undo / TempDB / geçici alan baskısı","icon":"🧯","category":"Kapasite","intro":"Undo/rollback alanı, geçici (temp) alan ya da TempDB baskı altında. Baskının nerede olduğunu belirleyip büyük sort/hash, uzun sorgu/transaction veya alan sızıntısı gibi kök nedene iniyoruz.","start":"root","nodes":{"root":{"kind":"step","title":"Baskı nerede: undo mu, temp mi, tempdb çekişmesi mi?","detail":"Alan kullanımına bakarak baskının kaynağını sınıfla: undo/rollback tablespace mi doluyor, genel geçici (temp) alan mı, yoksa MSSQL'de TempDB sayfa tahsis latch çekişmesi mi?","command":{"oracle":"SELECT tablespace_name, ROUND(used_percent,1) AS used_pct\nFROM dba_tablespace_usage_metrics\nWHERE tablespace_name LIKE '%UNDO%' OR tablespace_name LIKE 'TEMP%';","postgres":"SELECT datname, temp_files, pg_size_pretty(temp_bytes) AS temp_written\nFROM pg_stat_database ORDER BY temp_bytes DESC;","mysql":"SELECT * FROM information_schema.INNODB_TEMP_TABLE_INFO;\nSHOW GLOBAL STATUS LIKE 'Created_tmp_disk_tables';","mssql":"SELECT SUM(user_object_reserved_page_count)*8/1024 AS user_obj_mb,\n       SUM(internal_object_reserved_page_count)*8/1024 AS internal_obj_mb,\n       SUM(version_store_reserved_page_count)*8/1024 AS version_store_mb\nFROM sys.dm_db_file_space_usage;"},"choices":[{"label":"Undo/rollback alanı doluyor (ORA-01555 / ORA-30036)","next":"undo"},{"label":"Geçici (temp) alan doluyor (sort/hash spill)","next":"temp"},{"label":"TempDB tahsis latch çekişmesi (PFS/GAM/SGAM)","next":"tempdb"}]},"undo":{"kind":"step","title":"Undo'yu ne tüketiyor?","detail":"Undo baskısı iki tipiktir: uzun bir SORGU başladığı andaki tutarlı görüntü için eski undo'ya ihtiyaç duyuyor (ORA-01555) ya da uzun/açık bir TRANSACTION çok fazla undo üretip alanı doldurup ORA-30036'ya yol açıyor.","command":{"oracle":"SELECT s.sid, s.username, t.used_ublk*8/1024 AS undo_mb, s.status, t.start_time\nFROM v$transaction t JOIN v$session s ON s.taddr=t.addr\nORDER BY undo_mb DESC;\nSELECT MAX(maxquerylen) AS en_uzun_sorgu_sn, MAX(tuned_undoretention) AS tuned_retention FROM v$undostat;","postgres":"SELECT pid, now()-xact_start AS xact_age, state, left(query,60) AS query\nFROM pg_stat_activity WHERE xact_start IS NOT NULL ORDER BY xact_start LIMIT 10;"},"choices":[{"label":"Uzun sorgu eski undo istiyor (ORA-01555)","next":"sol_undo_query"},{"label":"Uzun/açık transaction undo biriktiriyor (ORA-30036)","next":"sol_undo_tx"}]},"temp":{"kind":"step","title":"Geçici alanı ne dolduruyor?","detail":"Temp baskısı ya büyük bir sıralama/hash işleminin diske taşmasından (normal ama devasa) ya da tek bir oturumun temp'i sürekli tutmasından (açık cursor, sızıntı, hiç bitmeyen sorgu) gelir.","command":{"oracle":"SELECT s.sid, s.username, u.tablespace, u.blocks*8/1024 AS temp_mb, u.sqladdr\nFROM v$tempseg_usage u JOIN v$session s ON s.saddr=u.session_addr\nORDER BY temp_mb DESC;","postgres":"SELECT query, temp_blks_written, temp_blks_read\nFROM pg_stat_statements ORDER BY temp_blks_written DESC LIMIT 10;","mysql":"SELECT event_name, current_number_of_bytes_used\nFROM performance_schema.memory_summary_global_by_event_name\nWHERE event_name LIKE '%temptable%' OR event_name LIKE '%sort%';","mssql":"SELECT session_id, request_id, SUM(internal_objects_alloc_page_count)*8/1024 AS internal_mb\nFROM sys.dm_db_task_space_usage GROUP BY session_id, request_id ORDER BY internal_mb DESC;"},"choices":[{"label":"Büyük sort/hash işlemi diske taşıyor","next":"sol_temp_sort"},{"label":"Tek oturum temp'i tutuyor (sızıntı/açık cursor)","next":"sol_temp_leak"}]},"tempdb":{"kind":"step","title":"TempDB çekişmesi tahsis mi yoksa hacim mi?","detail":"MSSQL TempDB'de iki farklı sorun olur: PFS/GAM/SGAM sayfalarında PAGELATCH çekişmesi (çok sayıda küçük geçici nesne) ya da büyük sıralama/version store'un TempDB'yi hacimce doldurması.","command":{"mssql":"SELECT session_id, wait_type, wait_duration_ms, resource_description\nFROM sys.dm_os_waiting_tasks\nWHERE wait_type LIKE 'PAGELATCH%' AND resource_description LIKE '2:%';\nSELECT COUNT(*) AS tempdb_data_files FROM sys.master_files WHERE database_id=2 AND type=0;"},"choices":[{"label":"PFS/GAM/SGAM latch çekişmesi","next":"sol_tempdb_latch"},{"label":"Büyük sıralama/version store TempDB'yi dolduruyor","next":"sol_temp_sort"}]},"sol_undo_query":{"kind":"solution","title":"Kök neden: Uzun sorgu + yetersiz undo (ORA-01555)","detail":"Uzun sorgunun tutarlı okuma için ihtiyaç duyduğu eski undo, retention dolduğu ya da alan yetersiz olduğu için üzerine yazıldı.","steps":["undo_retention'ı en uzun sorgu süresini (v$undostat.maxquerylen) aşacak değere çıkar.","UNDO tablespace'i büyüt veya autoextend aç ki retention süresi alanla desteklensin.","Kritik raporlar için ALTER TABLESPACE undotbs RETENTION GUARANTEE ile eski undo'yu koru (alan dolarsa DML hata alabilir; dikkatli ol).","Kalıcı çözüm için uzun sorguyu optimize et veya bir standby/replikaya taşı."],"related":["slow-queries"]},"sol_undo_tx":{"kind":"solution","title":"Kök neden: Uzun/açık transaction undo doldurdu (ORA-30036)","detail":"Devasa tek bir DML ya da commit'i geciken açık transaction çok fazla undo üretti; UNDO tablespace genişleyemedi ve ORA-30036 alındı.","steps":["En çok undo tutan aktif transaction'ı (v$transaction.used_ublk) tespit et ve sahibini bul.","Devasa tek DML'i tarih/aralık parçalarına bölerek ara commit'lerle çalıştır.","Commit'i unutulmuş / idle-in-transaction oturumları uygulama tarafında düzelt; gerekiyorsa kontrollü sonlandır.","Geçici olarak UNDO tablespace'e alan ekle; kalıcı olarak retention ve alan boyutunu iş yüküne göre planla."],"related":["active-sessions"]},"sol_temp_sort":{"kind":"solution","title":"Kök neden: Büyük sort/hash geçici alanı dolduruyor","detail":"Belleğe sığmayan büyük sıralama/hash/group by işlemleri geçici alana taşıyor ve onu doldurabiliyor.","steps":["Çalışma belleğini yükselt: Oracle pga_aggregate_target, Postgres work_mem, MySQL sort_buffer_size, MSSQL memory grant.","Sorguyu iyileştir: gereksiz sıralamayı kaldır, filtreleri erken uygula, sıralama/gruplama kolonlarına index ekle.","Çok büyük işleri parçalara böl; hepsinin aynı anda temp tutmasını engellemek için eşzamanlılığı sınırla.","Geçici alanı büyüt ve hızlı bir diske al; MSSQL TempDB'yi çekirdeğe göre çok dosyalı yapılandır."],"related":["slow-queries"]},"sol_temp_leak":{"kind":"solution","title":"Kök neden: Oturum temp alanını tutuyor (sızıntı)","detail":"Tek bir oturum, kapanmayan cursor'lar, hiç bitmeyen bir sorgu ya da açık geçici tablolar yüzünden geçici alanı bırakmıyor.","steps":["En çok temp tutan oturumu ve çalıştırdığı SQL'i tespit et.","Uygulamada cursor/sonuç kümesi ve geçici tabloların düzgün kapatıldığından emin ol.","Takılı/aşırı uzun oturumu kontrollü sonlandır ve alanın geri döndüğünü doğrula.","Global geçici tabloları oturum/transaction sonunda otomatik temizlenecek şekilde tanımla."],"related":["active-sessions"]},"sol_tempdb_latch":{"kind":"solution","title":"Kök neden: TempDB PFS/GAM/SGAM latch çekişmesi","detail":"Çok sayıda oturum aynı anda küçük geçici nesneler yarattığında TempDB'nin tahsis haritası sayfalarında (PFS/GAM/SGAM) PAGELATCH çekişmesi oluşur.","steps":["TempDB data file sayısını CPU çekirdek sayısına orantılı ve eşit boyutlu yapılandır (ör. 4-8 dosya, hepsi aynı boyut/autogrowth).","Modern SQL Server'da tahsis çekişmesini azaltan seçenekleri etkinleştir (memory-optimized tempdb metadata).","Geçici tablo yaratımını azalt: gereksiz #temp tablolarını table variable / tek sorgu ile değiştir.","Değişiklik sonrası PAGELATCH bekleme sürelerinin düştüğünü doğrula."],"related":["current-locks"]}}},"solver/long-transaction.json":{"id":"long-transaction","title":"Uzun süren / açık kalan transaction","icon":"⏱️","category":"Kilitler","intro":"Uzun süren ya da açık kalan bir transaction lock, undo ve bloat biriktiriyor. Suçlu transaction'ı bulup türünü (idle-in-transaction, uzun batch, etki) belirleyip güvenle çözüyoruz.","start":"root","nodes":{"root":{"kind":"step","title":"En eski açık transaction hangisi?","detail":"Açık transaction'ları başlangıç zamanına göre listele. En eski olan genellikle sorunun kaynağıdır. Durumuna bak: aktif mi çalışıyor, yoksa 'idle in transaction' olarak commit bekliyor mu?","command":{"oracle":"SELECT s.sid, s.serial#, s.username, s.status, t.start_time, t.used_ublk*8/1024 AS undo_mb\nFROM v$transaction t JOIN v$session s ON s.taddr=t.addr\nORDER BY t.start_time;","postgres":"SELECT pid, state, now()-xact_start AS xact_age, now()-state_change AS since_change, left(query,60) AS query\nFROM pg_stat_activity\nWHERE xact_start IS NOT NULL ORDER BY xact_start LIMIT 20;","mysql":"SELECT trx_id, trx_state, trx_started, TIMESTAMPDIFF(SECOND,trx_started,NOW()) AS secs, trx_mysql_thread_id, trx_rows_locked\nFROM information_schema.INNODB_TRX ORDER BY trx_started;","mssql":"SELECT s.session_id, s.login_name, t.transaction_begin_time,\n       DATEDIFF(second,t.transaction_begin_time,GETDATE()) AS secs\nFROM sys.dm_tran_active_transactions t\nJOIN sys.dm_tran_session_transactions st ON st.transaction_id=t.transaction_id\nJOIN sys.dm_exec_sessions s ON s.session_id=st.session_id\nORDER BY t.transaction_begin_time;"},"choices":[{"label":"idle-in-transaction (commit unutulmuş, boşta bekliyor)","next":"idle"},{"label":"Aktif ama çok uzun süren batch/DML","next":"batch"},{"label":"Transaction devam ederken lock/bloat/undo biriktiriyor","next":"impact"}]},"idle":{"kind":"step","title":"idle-in-transaction neden oluşuyor?","detail":"Oturum bir transaction açmış ama sorgu çalıştırmadan boşta bekliyor; yani commit/rollback unutulmuş. Bu, lock'ları ve undo'yu gereksiz yere tutar. Uygulama düzeltmesi mi yeterli, yoksa acilen sonlandırmak mı gerekiyor?","command":{"postgres":"SELECT pid, now()-state_change AS idle_age, left(query,80) AS last_query\nFROM pg_stat_activity WHERE state='idle in transaction' ORDER BY state_change;","mysql":"SELECT trx.trx_mysql_thread_id, trx.trx_started, p.time AS idle_secs, p.command\nFROM information_schema.INNODB_TRX trx\nJOIN information_schema.PROCESSLIST p ON p.id=trx.trx_mysql_thread_id\nWHERE p.command='Sleep' ORDER BY trx.trx_started;","oracle":"SELECT sid, serial#, status, last_call_et AS idle_secs\nFROM v$session WHERE status='INACTIVE' AND type='USER' AND last_call_et>300;","mssql":"SELECT s.session_id, s.status, DATEDIFF(second,s.last_request_end_time,GETDATE()) AS idle_secs\nFROM sys.dm_exec_sessions s\nWHERE s.session_id IN (SELECT session_id FROM sys.dm_tran_session_transactions)\n  AND s.status='sleeping';"},"choices":[{"label":"Uygulama/bağlantı havuzu commit yapmıyor (kalıcı düzeltme)","next":"sol_idle"},{"label":"Hemen sonlandırmam gerekiyor","next":"sol_kill"}]},"batch":{"kind":"step","title":"Aktif uzun işlem ne yapıyor?","detail":"Oturum gerçekten çalışıyor (aktif). Tek devasa bir DML/rapor mu, yoksa başka oturumları bekleten ve acil kesilmesi gereken bir bloklayıcı mı?","command":{"oracle":"SELECT s.sid, s.serial#, sq.sql_text, s.last_call_et AS running_secs\nFROM v$session s JOIN v$sql sq ON sq.sql_id=s.sql_id\nWHERE s.status='ACTIVE' AND s.type='USER' ORDER BY s.last_call_et DESC;","postgres":"SELECT pid, now()-query_start AS run_time, left(query,80) AS query\nFROM pg_stat_activity WHERE state='active' ORDER BY query_start LIMIT 10;","mysql":"SELECT id, time AS run_secs, state, LEFT(info,80) AS query\nFROM information_schema.PROCESSLIST WHERE command<>'Sleep' ORDER BY time DESC;","mssql":"SELECT r.session_id, r.status, r.total_elapsed_time/1000 AS secs, SUBSTRING(t.text,1,80) AS query\nFROM sys.dm_exec_requests r CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) t\nORDER BY r.total_elapsed_time DESC;"},"choices":[{"label":"Tek dev DML/rapor — parçalamak gerek","next":"sol_batch"},{"label":"Başkalarını bekletiyor, acil sonlandır","next":"sol_kill"}]},"impact":{"kind":"step","title":"Uzun işlem neyi biriktiriyor?","detail":"Uzun transaction'ın yan etkisini belirle: başka oturumları bekleten lock birikimi mi baskın, yoksa eski satır sürümlerini tutup temizliği (VACUUM/undo) engelleyen bloat mı?","command":{"postgres":"SELECT pid, pg_blocking_pids(pid) AS blocked_by FROM pg_stat_activity WHERE cardinality(pg_blocking_pids(pid))>0;\nSELECT max(age(backend_xmin)) AS max_xmin_age FROM pg_stat_activity WHERE backend_xmin IS NOT NULL;","oracle":"SELECT blocking_session, sid, serial#, seconds_in_wait, event\nFROM v$session WHERE blocking_session IS NOT NULL;","mssql":"SELECT session_id, blocking_session_id, wait_type, wait_time\nFROM sys.dm_exec_requests WHERE blocking_session_id<>0;"},"choices":[{"label":"Lock birikimi diğer oturumları bekletiyor","next":"sol_lock_backlog"},{"label":"Eski sürüm birikimi temizliği engelliyor (undo/bloat)","next":"sol_bloat"}]},"sol_idle":{"kind":"solution","title":"Kök neden: Uygulama commit yapmıyor (idle-in-transaction)","detail":"Bağlantı havuzu ya da uygulama, transaction'ı açtıktan sonra commit/rollback yapmadan bağlantıyı boşta tutuyor. Bu lock'ları ve undo'yu gereksiz tutar.","steps":["Uygulama kodunda her transaction'ın açıldığı yolda commit/rollback garanti et; transaction içinde kullanıcı girdisi/uzun IO bekleme.","Boşta transaction'ları otomatik kes: Postgres idle_in_transaction_session_timeout, MySQL bağlantı/timeout ayarları, uygulama havuzu maxLifetime.","Bağlantı havuzunu 'autocommit açık, kısa transaction' ilkesine göre yapılandır.","İzleme kur: uzun idle-in-transaction oturumları uyarı olarak yakala."],"related":["active-sessions","blocking-sessions"]},"sol_kill":{"kind":"solution","title":"Çözüm: Suçlu oturumu güvenle sonlandır","detail":"Engelleyici/uzun oturum başkalarını bekletiyorsa kontrollü biçimde sonlandırmak gerekir. Sonlandırma rollback tetikler; bu da alan/zaman gerektirebilir, dikkatli ol.","steps":["Önce oturumun ne olduğunu (hangi kullanıcı/uygulama, hangi iş) doğrula ki kritik bir işi kesmeyesin.","Sonlandır: Oracle ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE; Postgres SELECT pg_terminate_backend(pid); MySQL KILL thread_id; MSSQL KILL session_id;","Büyük bir yazma transaction'ını kesersen rollback'in tamamlanmasını (undo/log geri alımı) bekle.","Sonlandırma sonrası lock'ların ve bekleyen oturumların temizlendiğini doğrula; kök nedeni (idle/batch) kalıcı çöz."],"related":["blocking-sessions"]},"sol_batch":{"kind":"solution","title":"Kök neden: Tek dev DML/rapor","detail":"Milyonlarca satırı tek transaction'da işleyen bir DML ya da çok uzun rapor, süresi boyunca lock ve undo/bloat biriktirir.","steps":["Büyük DML'i tarih/aralık/anahtar bazlı parçalara böl ve her parçadan sonra commit et.","Ağır raporu yoğun saat dışına al ya da bir standby/read replica'ya taşı.","Uzun sorguyu optimize ederek toplam süresini (dolayısıyla lock/undo tutma süresini) kısalt.","Toplu işi izlenebilir hale getir: ilerlemeyi loglayıp gerektiğinde kaldığı yerden devam edebilir yap."],"related":["slow-queries"]},"sol_lock_backlog":{"kind":"solution","title":"Kök neden: Lock birikimi kuyruğu","detail":"Uzun transaction tuttuğu lock'lar yüzünden arkasında bir bekleme kuyruğu oluşturmuş; birçok oturum aynı kaynağı bekliyor.","steps":["Lock zincirinin başındaki (head blocker) oturumu tespit et — kuyruğu çözecek tek düğüm odur.","Head blocker'ı kısalt (commit/rollback) ya da kontrollü sonlandır; kuyruğun boşaldığını izle.","Lock süresini kısaltmak için transaction'ları küçült ve tutarlı bir erişim sırası belirle.","Uygun yerde daha düşük lock gerektiren yaklaşımlara geç (satır düzeyi, uygun izolasyon seviyesi)."],"related":["blocking-sessions","current-locks"]},"sol_bloat":{"kind":"solution","title":"Kök neden: Eski sürüm birikimi (undo/bloat)","detail":"Uzun süren işlem, kendisinden önceki eski satır sürümlerinin temizlenmesini engelliyor. Postgres'te bu tablo/index bloat'ı, Oracle'da undo baskısı olarak görünür.","steps":["En eski xmin/işlemi tutan oturumu bul (Postgres backend_xmin, Oracle en eski aktif transaction).","Bu transaction'ı kısalt/bitir ki temizlik (VACUUM / undo geri dönüşümü) tekrar ilerleyebilsin.","Postgres'te işlem bittikten sonra bloat'lı tablolarda VACUUM (gerekirse VACUUM FULL/pg_repack) uygula.","Kalıcı olarak uzun işlemleri kısa tutan bir uygulama deseni benimse ve autovacuum'u agresifleştir."],"related":[]}}},"solver/plan-regression.json":{"id":"plan-regression","title":"Sorgu planı bozuldu (aniden yavaşladı)","icon":"📉","category":"Performans","intro":"Dün hızlı olan bir sorgu bugün aniden yavaşladı. Genelde optimizer daha kötü bir plana geçmiştir. Bayat istatistik, parametre duyarlılığı, veri hacmi artışı veya ani plan değişimi arasından kök nedeni bulup planı stabilize ediyoruz.","start":"root","nodes":{"root":{"kind":"step","title":"Plan gerçekten değişti mi, ne zaman?","detail":"Aynı sorgu için birden fazla plan (plan_hash/plan_generation) var mı ve yavaşlama ne zaman başladı? Son deploy, upgrade, parametre değişimi ya da büyük veri yüklemesiyle örtüşüyor mu?","command":{"oracle":"SELECT sql_id, plan_hash_value, executions, ROUND(elapsed_time/GREATEST(executions,1)/1e6,3) AS sec_per_exec, first_load_time\nFROM v$sql WHERE sql_id='&sqlid' ORDER BY first_load_time;","postgres":"EXPLAIN (ANALYZE, BUFFERS) SELECT /* sorgunuz */ 1;\n-- Eğilim: SELECT query, calls, mean_exec_time FROM pg_stat_statements WHERE query LIKE '%...%';","mysql":"EXPLAIN FORMAT=JSON SELECT /* sorgunuz */ 1;\nSELECT DIGEST_TEXT, COUNT_STAR, AVG_TIMER_WAIT/1e9 AS avg_ms\nFROM performance_schema.events_statements_summary_by_digest WHERE DIGEST_TEXT LIKE '%...%';","mssql":"SELECT qs.plan_generation_num, qs.execution_count, qs.total_worker_time/qs.execution_count AS avg_cpu_us, qs.creation_time\nFROM sys.dm_exec_query_stats qs CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) t\nWHERE t.text LIKE '%...%';"},"choices":[{"label":"İstatistikler bayat olabilir","next":"stats"},{"label":"Aynı sorgu parametreye göre farklı davranıyor (sniffing/peeking)","next":"sniff"},{"label":"Veri hacmi belirgin biçimde arttı","next":"sol_datagrowth"},{"label":"Plan bir upgrade/flush sonrası aniden değişti","next":"sol_planflip"}]},"stats":{"kind":"step","title":"İstatistikler güncel mi?","detail":"Optimizer kararlarını istatistiklere dayanarak verir. Son analiz tarihi eski ya da değişiklik sayacı yüksekse tahminler gerçekten sapmış olabilir; bu da kötü plana yol açar.","command":{"oracle":"SELECT table_name, num_rows, last_analyzed, stale_stats\nFROM dba_tab_statistics WHERE table_name='T';","postgres":"SELECT relname, n_live_tup, n_mod_since_analyze, last_analyze, last_autoanalyze\nFROM pg_stat_user_tables WHERE relname='t';","mysql":"SELECT table_name, update_time, table_rows FROM information_schema.tables WHERE table_name='t';\nSHOW INDEX FROM t;","mssql":"SELECT s.name, STATS_DATE(s.object_id,s.stats_id) AS last_updated, p.modification_counter, p.rows\nFROM sys.stats s CROSS APPLY sys.dm_db_stats_properties(s.object_id,s.stats_id) p\nWHERE s.object_id=OBJECT_ID('dbo.t');"},"choices":[{"label":"İstatistik bayat/eksik","next":"sol_stats"},{"label":"İstatistik güncel ama plan yine parametreye duyarlı","next":"sniff"}]},"sniff":{"kind":"step","title":"Parametre duyarlılığı var mı?","detail":"Sorgu ilk çalıştırıldığındaki parametre değerine göre bir plan seçip önbelleğe alıyor (MSSQL parameter sniffing / Oracle bind peeking). O plan, çarpık dağılımlı başka değerler için kötü olabiliyor.","command":{"oracle":"SELECT sql_id, child_number, plan_hash_value, is_bind_sensitive, is_bind_aware\nFROM v$sql WHERE sql_id='&sqlid';","mssql":"SELECT qs.query_hash, qs.execution_count, qs.total_worker_time/qs.execution_count AS avg_cpu_us\nFROM sys.dm_exec_query_stats qs CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) t\nWHERE t.text LIKE '%...%';","postgres":"-- Generic vs custom plan davranışı için:\nPREPARE p AS SELECT /* sorgunuz */ 1;\nEXPLAIN EXECUTE p;"},"choices":[{"label":"Evet, parametreye göre plan iyi/kötü değişiyor","next":"sol_sniff"},{"label":"Doğru plan belli, kalıcı olarak sabitlemek istiyorum","next":"sol_forceplan"}]},"sol_stats":{"kind":"solution","title":"Kök neden: Bayat / eksik istatistik","detail":"Optimizer, gerçekle uyuşmayan eski istatistiklere göre satır sayısını yanlış tahmin edip kötü plan seçti. En sık görülen plan regresyonu nedenidir.","steps":["İlgili tablo ve index'ler için taze istatistik topla: Oracle DBMS_STATS.GATHER_TABLE_STATS, Postgres ANALYZE, MySQL ANALYZE TABLE, MSSQL UPDATE STATISTICS ... WITH FULLSCAN.","Çarpık dağılımlı kolonlarda histogram/genişletilmiş istatistik oluştur.","İstatistik toplama sonrası planı EXPLAIN ile doğrula; iyi plana döndüğünü teyit et.","Tekrarı önlemek için otomatik istatistik toplamayı (autovacuum/auto update stats) uygun eşiklerle etkin tut."],"related":["slow-queries"]},"sol_sniff":{"kind":"solution","title":"Kök neden: Parametre duyarlılığı (sniffing / bind peeking)","detail":"Önbelleğe alınan plan, ilk gelen parametre değerine göre seçildi ve çarpık dağılımlı diğer değerler için kötü. Amaç, değere uygun planın seçilmesini sağlamak.","steps":["MSSQL'de kritik sorguda OPTION (RECOMPILE) veya OPTIMIZE FOR ile hedefli davranış belirle; sık değişen değerlerde recompile tercih et.","Oracle'da adaptive cursor sharing / bind-aware davranışını kullan; gerekirse sorguyu değer aralığına göre ayır.","Postgres'te generic vs custom plan seçimini gözlemle; gerekirse plan_cache_mode ile yönlendir.","Kalıcı ve isabetli tek bir plan gerekiyorsa plan sabitleme çözümüne geç."],"related":["slow-queries"]},"sol_forceplan":{"kind":"solution","title":"Çözüm: Doğru planı sabitle (baseline / force plan)","detail":"Bilinen iyi plan mevcutsa optimizer'ın ondan sapmaması için planı sabitlemek regresyonu kalıcı olarak durdurur.","steps":["Oracle: iyi plan için SQL Plan Baseline oluştur (DBMS_SPM) ya da SQL Plan Management ile kabul et.","MSSQL: Query Store'da iyi planı seç ve sp_query_store_force_plan ile zorla.","MySQL/Postgres: optimizer hint (ör. index hint) veya pg_hint_plan ile planı yönlendir.","Sabitleme sonrası performansı izle; veri deseni köklü değişirse baseline'ı yeniden değerlendir."],"related":[]},"sol_datagrowth":{"kind":"solution","title":"Kök neden: Veri hacmi arttı, plan artık uygun değil","detail":"Tablo büyüdükçe eskiden ideal olan plan (ör. nested loop) artık kötü ölçekleniyor; optimizer büyümeyi doğru yansıtan istatistik ve erişim yollarına ihtiyaç duyuyor.","steps":["Güncel istatistik topla ki optimizer yeni satır sayısını görsün.","Büyüyen tablolar için uygun index ekle; artık kötü ölçeklenen erişim yolunu (ör. full scan/nested loop) düzelt.","Çok büyük tablolarda tarih/aralık bazlı bölümleme (partitioning) ile taranan veriyi sınırla.","Sorguyu büyümeye uygun yeniden yaz (erken filtre, sayfalama, özet/materialized view)."],"related":["slow-queries"]},"sol_planflip":{"kind":"solution","title":"Kök neden: Ani plan değişimi (upgrade / cache flush)","detail":"Plan bir sürüm yükseltmesi, parametre değişikliği ya da plan önbelleğinin boşalması sonrası aniden değişti. Optimizer davranışı ya da ortam koşulları kaymış.","steps":["Değişimin tetikleyicisini belirle: upgrade/patch, optimizer parametreleri, veri yükleme ya da restart/cache flush.","Parametre kaynaklıysa değişikliği geri al ve kontrollü olarak yeniden değerlendir.","Bilinen iyi planı sabitle (baseline / force plan) ki optimizer tekrar sapmasın.","Upgrade sonrası regresyonlar için optimizer uyumluluk/hazırlık ayarlarını gözden geçir."],"related":[]}}},"solver/replica-resync.json":{"id":"replica-resync","title":"Replika bozuldu / yeniden senkron gerek","icon":"🔗","category":"Replikasyon","intro":"Replika/standby ile primary arasındaki senkron bozuldu. Replikasyonun durup durmadığını, ne kadar geride olduğunu ve pozisyon/GTID kopması olup olmadığını belirleyip; hata atlama, bekleme ya da yeniden kurulum (reseed) arasında doğru yola giriyoruz. Split-brain uyarısı dahildir.","start":"root","nodes":{"root":{"kind":"step","title":"Replikasyonun genel durumu ne?","detail":"Önce replikasyon sağlığını oku: uygulama thread'ler çalışıyor mu, gecikme (lag) ne kadar, bir hata var mı? Ayrıca iki düğümün birden yazma kabul etmediğini (split-brain) doğrula.","command":{"mysql":"SHOW REPLICA STATUS\\G\n-- Bak: Replica_IO_Running, Replica_SQL_Running, Seconds_Behind_Source, Last_Error, Retrieved/Executed_Gtid_Set","postgres":"-- Primary'de:\nSELECT client_addr, state, sent_lsn, replay_lsn, pg_wal_lsn_diff(sent_lsn,replay_lsn) AS lag_bytes FROM pg_stat_replication;\n-- Replikada:\nSELECT status, last_msg_receipt_time, latest_end_lsn FROM pg_stat_wal_receiver;","oracle":"SELECT name, value, unit, time_computed FROM v$dataguard_stats WHERE name IN ('transport lag','apply lag');\nSELECT dest_id, status, error, gap_status FROM v$archive_dest_status WHERE status<>'INACTIVE';","mssql":"SELECT ag.name AS ag, drs.synchronization_state_desc, drs.synchronization_health_desc,\n       drs.log_send_queue_size, drs.redo_queue_size\nFROM sys.dm_hadr_database_replica_states drs\nJOIN sys.availability_groups ag ON ag.group_id=drs.group_id;"},"choices":[{"label":"Replikasyon durmuş / hata veriyor","next":"error"},{"label":"Çalışıyor ama çok geride (lag büyük)","next":"lag"},{"label":"GTID/pozisyon kopmuş, tutarsız — yeniden kur","next":"sol_reseed"},{"label":"İki düğüm de primary gibi yazıyor (split-brain şüphesi)","next":"sol_splitbrain"}]},"error":{"kind":"step","title":"Hata onarılabilir mi yoksa yeniden kurulum mu gerek?","detail":"Uygulama hatasını incele. Bazı hatalar (duplicate key, eksik satır) tek olayı güvenle atlayarak çözülebilir; ancak veri tutarsızlığı/bozulma varsa tek doğru yol replikayı yeniden kurmaktır.","command":{"mysql":"SHOW REPLICA STATUS\\G\n-- Bak: Last_SQL_Errno, Last_SQL_Error, Last_IO_Errno, Last_IO_Error","postgres":"-- Replika loglarını incele (PostgreSQL log): recovery / WAL apply hatası mesajları.\nSELECT status, last_msg_receipt_time FROM pg_stat_wal_receiver;","mssql":"SELECT * FROM sys.dm_hadr_automatic_seeding;\nSELECT database_id, synchronization_state_desc, is_suspended, suspend_reason_desc\nFROM sys.dm_hadr_database_replica_states WHERE is_local=1;"},"choices":[{"label":"Tek/az sayıda uygulanabilir hata (atlanabilir)","next":"sol_skiperror"},{"label":"Onarılamaz tutarsızlık / bozulma","next":"sol_reseed"}]},"lag":{"kind":"step","title":"Gecikme geçici mi kalıcı mı?","detail":"Lag'in zaman içindeki eğilimine bak. Geçici bir yük patlamasından sonra kapanıyor (yakalıyor) mu, yoksa sürekli açılıyor ve replika primary'yi asla yakalayamıyor mu?","command":{"mysql":"SHOW REPLICA STATUS\\G\n-- Seconds_Behind_Source değerini birkaç kez ölç: azalıyor mu artıyor mu?","postgres":"-- Replikada tekrar tekrar ölç:\nSELECT now()-pg_last_xact_replay_timestamp() AS replay_lag;","oracle":"SELECT name, value, time_computed FROM v$dataguard_stats WHERE name='apply lag';","mssql":"SELECT drs.redo_queue_size, drs.redo_rate, drs.log_send_queue_size\nFROM sys.dm_hadr_database_replica_states drs WHERE drs.is_local=0;"},"choices":[{"label":"Geçici yük artışı; lag kapanıyor","next":"sol_lag_wait"},{"label":"Sürekli açılıyor; yakalayamıyor","next":"sol_lag_perm"}]},"sol_skiperror":{"kind":"solution","title":"Çözüm: Uygulanabilir hatayı dikkatle atla","detail":"Replikasyon tek bir uygulama hatasında (ör. duplicate key) durmuşsa ve verinin gerçekten tutarlı olduğundan eminsen, o olayı atlayarak akışı sürdürebilirsin. Bu son çare niteliğindedir; kör atlama sessiz veri sapması yaratır.","steps":["Önce hatanın neden oluştuğunu anla ve iki tarafta ilgili satırı karşılaştırarak veri tutarlılığını doğrula.","GTID kullanmayan MySQL'de tek olayı atla: STOP REPLICA; SET GLOBAL sql_replica_skip_counter=1; START REPLICA; (8.0.26 öncesi: sql_slave_skip_counter; dikkatle).","GTID'li kurulumda hatalı transaction'ı atlamak için o GTID'yi boş bir transaction ile işaretle, sonra replikayı başlat.","Atlamadan sonra iki taraf arasında satır bazlı tutarlılık kontrolü (checksum) çalıştır; sapma varsa reseed'e geç."],"related":["replication-status"]},"sol_reseed":{"kind":"solution","title":"Çözüm: Replikayı yeniden kur (reseed / rebuild)","detail":"Pozisyon/GTID kopmuş, veri sapmış ya da onarılamaz hata varsa tek güvenilir yol replikayı primary'den alınan taze bir kopyayla yeniden kurmaktır.","steps":["Primary'den tutarlı bir taban yedeği al: MySQL xtrabackup/mysqldump ya da CLONE, Postgres pg_basebackup, Oracle RMAN duplicate, MSSQL tam+log yedeği.","Replikada eski durumu temizle ve yedeği geri yükle (Postgres pg_basebackup -R, MSSQL RESTORE ... WITH NORECOVERY).","Replikasyonu doğru pozisyon/GTID'den başlat: MySQL CHANGE REPLICATION SOURCE TO ...; START REPLICA; MSSQL veritabanını AG'ye yeniden ekle (otomatik seeding).","Yakalamayı izle; lag sıfıra indikten sonra iki tarafın tutarlılığını checksum ile doğrula."],"related":["replication-status"]},"sol_lag_wait":{"kind":"solution","title":"Kök neden: Geçici yük artışı (lag kapanıyor)","detail":"Replikasyon sağlıklı; primary'deki geçici bir yazma patlaması veya ağ dalgalanması nedeniyle lag açıldı ama replika yakalıyor.","steps":["Lag eğiliminin gerçekten azaldığını birkaç ölçümle doğrula.","Yük penceresi bitene kadar gerekiyorsa yalnızca lag'e duyarlı okumaları primary'ye yönlendir.","Tekrarlıyorsa yazma patlamalarını (toplu iş, ETL) zamana yay ya da yoğun saat dışına al.","Ağ/uygulama gecikmesini izlemeye ekle ki geçici lag'ler kalıcı olana dönüşmeden görülsün."],"related":["replication-status"]},"sol_lag_perm":{"kind":"solution","title":"Kök neden: Replika primary'yi yakalayamıyor","detail":"Uygulama (apply/redo) tarafı, primary'nin ürettiği değişiklik hızına yetişemiyor; lag sürekli büyüyor. Genelde tek thread'li apply, yavaş replika donanımı ya da ağ darboğazı.","steps":["Apply darboğazını bul: tek thread'li uygulama mı, replika diski/CPU'su mu, ağ bant genişliği mi sınırlıyor?","Paralel apply'ı etkinleştir/artır: MySQL çoklu replica worker (replica_parallel_workers), Postgres/Oracle apply kaynaklarını gözden geçir.","Replika donanımını en az primary'ye denk seviyeye çıkar (özellikle disk IOPS).","Replikadaki gereksiz ağır okuma sorgularını azaltarak apply'a kaynak bırak; hâlâ yetişmiyorsa reseed sonrası yeniden değerlendir."],"related":["replication-status"]},"sol_splitbrain":{"kind":"solution","title":"UYARI: Split-brain (iki primary) — veri kaybı riski","detail":"İki düğüm de primary rolde yazma kabul ediyorsa, her iki tarafta çakışan değişiklikler oluşur; bu veri kaybına yol açabilecek en tehlikeli durumdur. Önce yazmayı tek düğüme indirgemek şarttır.","steps":["Derhal yazmayı tek bir düğümde topla: uygulama trafiğini kesin biçimde tek primary'ye yönlendir, diğerini salt-okunur/izole et.","Otoritatif (doğru) düğümü belirle: hangi tarafın verisi iş açısından geçerli kabul edilecek karar ver.","İki taraftaki çakışan (diverjan) değişiklikleri karşılaştır; kaybedilen tarafın kritik değişikliklerini manuel olarak uzlaştır.","Otoritatif düğümü kaynak alarak diğer düğümü reseed ile yeniden kur; ardından çift primary durumunu engelleyen bir fencing/quorum mekanizması kur."],"related":["replication-status"]}}},"solver/cache-hit-low.json":{"id":"cache-hit-low","title":"Önbellek isabet oranı düşük (buffer/cache hit)","icon":"🎯","category":"Performans","intro":"Önbellek isabet oranı düşük; veri sürekli diskten (veya kaynaktan) okunuyor. Sorunun DB buffer/shared cache tarafında mı yoksa Redis/uygulama önbelleği tarafında mı olduğunu belirleyip ölçüp çözüyoruz.","start":"root","nodes":{"root":{"kind":"step","title":"Hangi önbellek düşük isabet veriyor?","detail":"İsabet oranını ölç ve sorunu ayır: veritabanının buffer/shared cache'i mi düşük (fiziksel okuma yüksek), yoksa Redis/uygulama önbelleğinde mi çok kayıp ve eviction var?","command":{"oracle":"SELECT ROUND((1-(pr.value/(dbg.value+cg.value)))*100,2) AS buffer_hit_pct\nFROM v$sysstat pr, v$sysstat dbg, v$sysstat cg\nWHERE pr.name='physical reads' AND dbg.name='db block gets' AND cg.name='consistent gets';","postgres":"SELECT ROUND(sum(blks_hit)*100.0/nullif(sum(blks_hit)+sum(blks_read),0),2) AS cache_hit_pct\nFROM pg_stat_database;","mysql":"SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_read_requests';\nSHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_reads';","mssql":"SELECT cntr_value AS buffer_cache_hit_ratio\nFROM sys.dm_os_performance_counters\nWHERE counter_name='Buffer cache hit ratio' AND object_name LIKE '%Buffer Manager%';","redis":"INFO stats\n# keyspace_hits / keyspace_misses oranına ve INFO memory'de evicted_keys değerine bak"},"choices":[{"label":"DB buffer/shared cache isabet oranı düşük","next":"dbcache"},{"label":"Redis/uygulama önbelleğinde çok kayıp / eviction","next":"rediscache"}]},"dbcache":{"kind":"step","title":"Neden diskten okuyor: boyut mu, tarama deseni mi?","detail":"Düşük buffer isabetinin iki tipik nedeni var: sık erişilen veri kümesi (working set) belleğe sığmıyor (cache küçük), ya da büyük tam tablo taramaları cache'i tek seferlik bloklarla kirletip faydalı sayfaları dışarı atıyor.","command":{"oracle":"SELECT component, current_size/1024/1024 AS mb FROM v$sga_dynamic_components WHERE component LIKE '%buffer cache%';\nSELECT sql_id, disk_reads, executions FROM v$sql ORDER BY disk_reads DESC FETCH FIRST 10 ROWS ONLY;","postgres":"SHOW shared_buffers;\nSELECT pg_size_pretty(pg_database_size(current_database())) AS db_size;\nSELECT query, shared_blks_read FROM pg_stat_statements ORDER BY shared_blks_read DESC LIMIT 10;","mysql":"SHOW VARIABLES LIKE 'innodb_buffer_pool_size';\nSELECT ROUND(SUM(data_length+index_length)/1024/1024) AS data_mb FROM information_schema.tables;","mssql":"SELECT physical_memory_kb/1024 AS server_ram_mb FROM sys.dm_os_sys_info;\nSELECT COUNT(*)*8/1024 AS buffer_pool_mb FROM sys.dm_os_buffer_descriptors;"},"choices":[{"label":"Working set RAM'e sığmıyor (cache küçük)","next":"sol_sizing"},{"label":"Tam tablo taraması cache'i kirletiyor","next":"sol_scan"}]},"rediscache":{"kind":"step","title":"Redis kaybı neden: maxmemory eviction mi, TTL/anahtar yönetimi mi?","detail":"Redis isabet oranı düşükse ya bellek maxmemory'ye dayanmış ve anahtarlar eviction ile atılıyor, ya da anahtarlarda TTL yönetimi/isabetli önbellekleme deseni zayıf (soğuk anahtarlar, düşük yeniden kullanım).","command":{"redis":"INFO memory\n# used_memory, maxmemory, maxmemory_policy, evicted_keys\nCONFIG GET maxmemory-policy\nINFO keyspace\n# db başına anahtar sayısı ve expires (TTL'li anahtar) oranı"},"choices":[{"label":"maxmemory dolu, eviction yüksek","next":"sol_maxmem"},{"label":"TTL/anahtar deseni zayıf (düşük yeniden kullanım)","next":"sol_ttl"}]},"sol_sizing":{"kind":"solution","title":"Kök neden: Önbellek working set için küçük","detail":"Sık erişilen veri, ayrılan buffer/cache'ten büyük olduğu için sürekli evict edilip diskten yeniden okunuyor. İsabet oranı düşük, fiziksel okuma yüksek.","steps":["Cache boyutunu working set'i kapsayacak şekilde büyüt: Oracle db_cache_size/SGA, Postgres shared_buffers, MySQL innodb_buffer_pool_size, MSSQL max server memory.","Fiziksel RAM yetersizse sunucu belleğini artır; DB'nin bellekle ölçeklenen ana kaynağı budur.","Working set'i küçült: eski veriyi arşivle/böl, gereksiz kolon/index'leri sadeleştir.","Değişiklik sonrası isabet oranı ve fiziksel okumaları karşılaştırıp iyileşmeyi doğrula."],"related":["cache-hit-ratio"]},"sol_scan":{"kind":"solution","title":"Kök neden: Tarama deseni cache'i kirletiyor","detail":"Büyük tam tablo taramaları, bir kez kullanılıp atılacak blokları cache'e doldurup hot page'leri dışarı atıyor; bu da isabet oranını düşürüyor.","steps":["En çok fiziksel okuma yapan sorguların planını çıkar ve full scan'leri index erişimine çevir (uygun index ekle).","'SELECT *' yerine gerekli kolonları seç; taranan blok hacmini azalt.","Büyük tablolarda bölümleme (partitioning) ile taramayı ilgili aralığa daralt.","Ağır analitik/tarama işlerini OLTP cache'inden ayır (read replica ya da ayrı zaman penceresi)."],"related":["slow-queries","cache-hit-ratio"]},"sol_maxmem":{"kind":"solution","title":"Kök neden: Redis maxmemory eviction","detail":"Redis belleği maxmemory sınırına dayanmış; yeni anahtarlar için eski anahtarlar evict ediliyor (evicted_keys artıyor). Bu, hâlâ ihtiyaç duyulan girdilerin kaybolmasına ve isabet düşüşüne yol açar.","steps":["maxmemory'yi gerçek çalışma kümesine göre yükselt ya da veri kümesini küçült.","Eviction politikasını kullanım desenine göre seç (ör. LRU/LFU: allkeys-lfu sıcak-soğuk ayrımında sık etkilidir).","Büyük/az kullanılan yapıları ayıkla; değeri küçült, gereksiz alanları kaldır, uygun veri tiplerini kullan.","Kalıcı ihtiyaç varsa Redis'i ölçekle (daha çok RAM ya da cluster/sharding) ve evicted_keys'i izlemeye al."],"related":[]},"sol_ttl":{"kind":"solution","title":"Kök neden: Zayıf TTL / önbellekleme deseni","detail":"Anahtarlar ya hiç TTL almadığından bellek soğuk veriyle doluyor, ya da önbellek deseni yeniden kullanımı düşük olduğundan çoğu istek miss'e düşüyor.","steps":["Önbelleklenen anahtarlara uygun TTL ata; soğuyan veri kendiliğinden düşsün.","Sık okunan (sıcak) veriyi önbellekle; nadir kullanılanları önbelleğe koyma (isabetsiz doldurma yapma).","Cache-aside deseninde miss sonrası doldurmayı doğru uygula ve 'thundering herd' için lock/tekilleştirme kullan.","keyspace_hits/misses oranını izleyip TTL ve anahtar tasarımını verilerle iyileştir."],"related":[]}}},"solver/arch-oltp.json":{"id":"arch-oltp","title":"Referans Mimari: 3-katmanlı OLTP uygulaması","icon":"🏛️","category":"Referans Mimari","intro":"Klasik iş uygulamaları (sipariş, ödeme, envanter) çok sayıda kısa, tekil ve tutarlılık gerektiren işlem yürütür (OLTP). Bu ağaç; yük profilini belirlemekten başlayarak birincil ilişkisel veritabanı seçimi, bağlantı havuzu (connection pooler), okuma replikası, önbellek katmanı, yedekleme + PITR ve izleme bileşenlerinin ne zaman devreye alınacağını adım adım gösterir. Amaç 'her şeyi baştan koymak' değil, darboğaz kanıtlandıkça doğru bileşeni eklemektir.","start":"root","nodes":{"root":{"kind":"step","title":"Yük profilin nasıl: işlem karışımı ve tutarlılık ihtiyacı ne?","detail":"OLTP mimarisinde ilk karar, iş yükünün gerçekten işlemsel (kısa, ACID gerektiren yazma/okuma karışımı) olup olmadığıdır. Verinin doğal olarak ilişkisel ve tutarlılık kritik mi (para, stok, sipariş), yoksa ağırlıklı okuma mı yapılıyor, ya da henüz yük çok mu düşük?","choices":[{"label":"Kısa işlemler, güçlü tutarlılık (para/stok/sipariş)","next":"primary_db"},{"label":"Okuma çok baskın, yazma az ve trafik yükseliyor","next":"scale_reads"},{"label":"Yük çok düşük; en sade kurulum yeterli mi?","next":"sol_single_node"}]},"primary_db":{"kind":"step","title":"Birincil veritabanı motorunu seçtin mi, ölçek endişen var mı?","detail":"İşlemsel çekirdek için ilişkisel bir motor doğru temeldir (PostgreSQL, MySQL/InnoDB, Oracle, SQL Server). Motor seçimi netse sıradaki soru ölçeklemedir: tek örnek şu an yetiyor mu, yoksa bağlantı sayısı ve okuma yükü artıyor mu?","choices":[{"label":"Motor net; şimdilik tek örnek yetiyor","next":"sol_single_node"},{"label":"Bağlantı sayısı çok yükseldi, kaynak tükeniyor","next":"sol_pooler"},{"label":"Okuma yükü büyüyor, yazma ana örneği zorluyor","next":"scale_reads"}]},"scale_reads":{"kind":"step","title":"Okumaları nasıl ölçekleyeceksin: replika mı, önbellek mi?","detail":"Okuma yükü ana örneği zorluyorsa iki tamamlayıcı seçenek var. Raporlama/liste gibi biraz gecikmeli veriyi tolere edebilen okumalar bir okuma replikasına yönlendirilebilir; aynı 'sıcak' veriler defalarca isteniyorsa mikrosaniye gecikmeli bir önbellek (Redis) DB'yi rahatlatır.","choices":[{"label":"Rapor/liste okumaları çok; hafif gecikme kabul","next":"sol_read_replica"},{"label":"Aynı popüler veriler tekrar tekrar okunuyor","next":"sol_cache"}]},"sol_single_node":{"kind":"solution","title":"Öneri: Tek primary + havuz + yedek ile başla","detail":"Erken aşamada mimariyi basit tut: tek bir ilişkisel primary örnek, önünde bir bağlantı havuzu ve düzenli yedek yeterlidir. Karmaşıklığı ancak ölçülen bir darboğaz zorlayınca ekle.","steps":["Primary DB: PostgreSQL veya MySQL/InnoDB gibi ACID destekli ilişkisel motor; şema, constraint'ler ve index'ler doğru kurulsun.","Bağlantı havuzu: Baştan uygulama tarafı havuz (ör. HikariCP) veya sunucu tarafı PgBouncer koy; bağlantı fırtınasını önler.","Yedek + PITR: Günlük tam yedek + WAL/binlog arşivi ile noktasal kurtarma; yedeği ayrı depoya al.","Dikkat: Erken aşamada replika/sharding/cache ekleme — ölçülmemiş sorunu çözmeye çalışma, sadece hata yüzeyi büyür.","İzleme: En baştan gecikme, hata oranı ve bağlantı sayısı metriklerini topla; büyüme sinyalini kaçırma."],"related":["decide-pooling","decide-backup"]},"sol_pooler":{"kind":"solution","title":"Öneri: Bağlantı havuzu (connection pooler) ekle","detail":"OLTP'de her uygulama örneği kendi bağlantılarını açtığında, primary DB binlerce bağlantı altında bellek ve zamanlayıcı yükünden boğulur. Araya bir havuz koyarak az sayıda gerçek DB bağlantısı çok sayıda uygulama isteğine paylaştırılır.","steps":["PostgreSQL: PgBouncer (transaction pooling modu) çok sayıda istemciyi az sayıda backend bağlantısına indirir.","MySQL: ProxySQL benzer şekilde bağlantı çoğullama ve yönlendirme sağlar.","Havuz boyutu: Genelde CPU çekirdek sayısıyla orantılı, birkaç on backend bağlantısı yeterlidir; 'ne kadar çok o kadar iyi' değildir.","Dikkat: Transaction pooling'de oturum-düzeyi özellikler (prepared statement, geçici tablo, oturum değişkeni) kısıtlanır; uygulamayı buna göre yaz.","Sonra: Havuz da doyuyorsa sorun bağlantı değil sorgu/transaction süresidir — yavaş sorgu ve uzun transaction'ları avla."],"related":["decide-pooling","connection-storm"]},"sol_read_replica":{"kind":"solution","title":"Öneri: Okuma replikası (read replica) ekle","detail":"Yazma primary örnekte kalırken, primary'den akan bir veya daha fazla asenkron replikaya salt-okuma trafiği (rapor, liste, arama) yönlendirilir. Böylece primary, yazma ve tutarlılık kritik okumalar için serbest kalır.","steps":["Topoloji: Primary → bir/çok asenkron replika; uygulama okuma/yazmayı ayırıp okumaları replikaya yollar.","Motor: PostgreSQL streaming replication, MySQL replikaları veya yönetilen okuma replikaları.","Ne zaman: Rapor/analiz/liste gibi az gecikmeyi tolere eden okumalar; primary'nin CPU/IO'sunu boşaltmak istediğinde.","Dikkat: Replikasyon gecikmesi (lag) bayat okuma yaratır; 'kendi yazdığını hemen oku' gereken akışları primary'den okut (read-your-writes).","Sonra: Replikalar da yetmezse sıcak veri için önbellek veya yazma tarafında sharding düşün."],"related":["replication-lag","decide-shard-replica"]},"sol_cache":{"kind":"solution","title":"Öneri: Önbellek katmanı (Redis) ekle","detail":"Aynı popüler veriler (oturum, katalog, profil, sayfa parçaları) defalarca okunuyorsa, DB'nin önüne bir bellek-içi önbellek koyup okumaların çoğunu DB'ye hiç ulaştırmadan karşılarsın. Gecikme düşer, primary DB rahatlar.","steps":["Motor: Redis (veya Memcached) ile cache-aside deseni; uygulama önce cache'e bakar, ıskada DB'den çekip cache'e yazar.","TTL + invalidation: Her anahtara makul TTL koy; yazışta ilgili anahtarı sil/güncelle ki bayat veri kalmasın.","Ne zaman: Okuma çok, veri görece nadir değişiyor, aynı anahtarlar tekrar tekrar isteniyor.","Dikkat: Cache stampede — popüler anahtarın süresi dolunca binlerce istek aynı anda DB'ye vurabilir; lock/single-flight ve jitter'lı TTL kullan.","Dikkat: Önbelleği 'gerçek kaynak' sanma; kalıcı gerçek her zaman DB'de, cache çökse de uygulama DB'ye düşerek çalışmalı."],"related":["decide-cache","cache-hit-low"]}}},"solver/arch-dwh.json":{"id":"arch-dwh","title":"Referans Mimari: Veri ambarı / analitik","icon":"🏛️","category":"Referans Mimari","intro":"Analitik sorgular (raporlama, agregasyon, geniş taramalar) OLTP işlemlerinden temelde farklıdır: az sayıda ama çok geniş, uzun süren sorgular çalışır. Bu ağaç; analitiği OLTP'den ayırma kararından başlayarak yükleme yöntemi (ETL vs ELT), kolonsal/columnstore depolama, star schema modelleme, partition + sıkıştırma ve materialized view ile önceden hesaplama gibi bileşenleri; eşzamanlılık (concurrency) ile verim (throughput) ödünleşimini de gözeterek adım adım ele alır.","start":"root","nodes":{"root":{"kind":"step","title":"Analitik yükün OLTP ile aynı veritabanında mı çalışıyor?","detail":"En yaygın hata, ağır raporları canlı işlemsel DB üzerinde çalıştırıp OLTP gecikmesini bozmaktır. İlk karar ayrıştırmadır: analitik hâlâ OLTP örneğinde mi koşuyor, ayrı bir analitik ortam mı kuruyorsun, yoksa veriyi oraya nasıl taşıyacağına mı karar veriyorsun?","choices":[{"label":"Raporlar hâlâ canlı OLTP'de; OLTP'yi yavaşlatıyor","next":"sol_separate"},{"label":"Ayrı ambar var; veriyi nasıl yükleyeceğim?","next":"load_method"},{"label":"Ambar var; sorgular hâlâ yavaş, nasıl modelleyeyim?","next":"model"}]},"load_method":{"kind":"step","title":"Dönüşümü nerede yapacaksın: yüklemeden önce mi, sonra mı?","detail":"Veriyi kaynaklardan ambara taşırken temizleme/dönüştürme işini ayrı bir işlem katmanında yükleme öncesi mi (ETL) yapacaksın, yoksa ham veriyi önce ambara yükleyip güçlü ambar motorunun içinde SQL ile mi dönüştüreceksin (ELT)? Karar; ambarın işlem gücüne ve şema esnekliği ihtiyacına bağlıdır.","choices":[{"label":"Dönüşüm karmaşık/harici; yüklemeden önce yapılsın","next":"sol_etl"},{"label":"Ambar güçlü; ham yükle, içeride SQL ile dönüştür","next":"sol_elt"}]},"model":{"kind":"step","title":"Sorgu darboğazı depolama düzeninde mi, veri modelinde mi?","detail":"Analitik yavaşsa iki temel kaldıraç var. Geniş taramalar satır-tabanlı depolamada tüm satırı okur; kolonsal depolama sadece gereken sütunları okur ve iyi sıkışır. Model tarafında ise normalizasyon fazlaysa çok sayıda join sorguyu yavaşlatır; star schema (fact + dimension) analitik için sadeleştirir.","choices":[{"label":"Geniş agregasyon taramaları yavaş; az sütun okunuyor","next":"sol_columnar"},{"label":"Çok fazla join, karmaşık normalize şema","next":"sol_star"},{"label":"Aynı ağır rapor defalarca aynı sonucu üretiyor","next":"sol_matview"}]},"sol_separate":{"kind":"solution","title":"Öneri: Analitiği OLTP'den ayır","detail":"İşlemsel ve analitik yükler aynı motorda birbirini boğar: uzun raporlar lock/IO tutarak kısa işlemleri geciktirir. Analitiği ayrı bir hedefe (okuma replikası veya ayrı analitik ambar) taşıyarak her iki tarafı da rahatlatırsın.","steps":["İlk adım: Hafif raporlar için OLTP okuma replikasına, ağır analitik için ayrı bir analitik motora yönlendir.","Analitik motor: Kolonsal/analitik motor (ör. columnstore'lu SQL Server, ClickHouse, veya kolonsal ambar) geniş taramalarda satır-tabanlıdan kat kat hızlıdır.","Eşzamanlılık vs verim: OLTP çok sayıda küçük işlem için (yüksek concurrency), ambar az sayıda dev sorgu için (yüksek throughput) ayarlanır — ikisini aynı kutuda optimize edemezsin.","Dikkat: Ambar 'canlının anlık kopyası' değildir; belirli aralıkla yüklenen, gecikmeli ama analiz için düzenlenmiş veridir.","Sonra: Ayırdıktan sonra yükleme yöntemine (ETL/ELT) ve modele (star schema) karar ver."],"related":["decide-sqlnosql","slow-query"]},"sol_etl":{"kind":"solution","title":"Öneri: ETL (yükleme öncesi dönüşüm)","detail":"ETL'de veri kaynaklardan çekilir (Extract), ayrı bir işlem katmanında temizlenip dönüştürülür (Transform) ve ancak sonra ambara yüklenir (Load). Ambara yalnızca temiz, modele uygun veri girer.","steps":["Ne zaman: Dönüşüm karmaşık, birden çok kaynağı birleştirmen gerekiyor veya ambara ham/hassas veri hiç girmesin istiyorsun.","Akış: Kaynak (OLTP/dosya/API) → dönüşüm katmanı → ambara toplu yükleme (batch).","Artı: Ambar depolamasını temiz tutar; hassas veri yüklemeden maskelenebilir.","Eksi: Dönüşüm ayrı bir sistemin gücüne bağlıdır; ambarın SQL esnekliğinden yararlanamaz.","Dikkat: Toplu pencerede yükle (ör. gece); yükleme sırasında ağır sorgularla çakışmayı planla."],"related":["decide-capacity"]},"sol_elt":{"kind":"solution","title":"Öneri: ELT (ambar içinde dönüşüm)","detail":"ELT'de ham veri önce ambara yüklenir, dönüşüm ambarın kendi güçlü SQL motoru içinde yapılır. Modern kolonsal ambarların işlem gücü yüksek olduğundan dönüşümü veriye götürmek yerine veriyi bir kez taşıyıp içeride işlersin.","steps":["Ne zaman: Ambar motoru güçlü ve ölçeklenebilir; ham veriyi de saklamak (audit/yeniden işleme) istiyorsun.","Akış: Kaynak → ham katman (staging) → SQL/dönüşüm view'ları → modellenmiş fact/dimension katmanı.","Artı: Tek motor, esnek; ham veri durduğu için dönüşümü sonradan değiştirip yeniden üretebilirsin.","Eksi: Ham (belki hassas) veri ambara girer — erişim ve maskeleme kontrolü şart.","Dikkat: Katmanlı modelle (raw → staging → mart); dönüşümleri idempotent yaz ki yeniden çalıştırma güvenli olsun."],"related":["decide-capacity"]},"sol_columnar":{"kind":"solution","title":"Öneri: Kolonsal / columnstore depolama + sıkıştırma","detail":"Analitik sorgular tipik olarak birkaç sütunu tüm satırlar üzerinde tarar. Kolonsal depolama veriyi sütun sütun tutar; sadece gereken sütunları okur, benzer değerler yan yana olduğu için çok iyi sıkışır ve IO dramatik düşer.","steps":["Motor/özellik: SQL Server columnstore index, ClickHouse, veya kolonsal ambarlar; PostgreSQL tarafında kolonsal eklentiler.","Sıkıştırma: Kolonsal düzen yüksek sıkıştırma sağlar; daha az disk, daha az okunan bayt, daha hızlı tarama.","Partition: Büyük fact tablolarını tarih/aralığa göre bölerek partition pruning ile alakasız bölümleri hiç okuma.","Dikkat: Kolonsal, çok sayıda tekil satır güncelleme/nokta okuma için kötüdür; OLTP'yi buna taşıma.","Eşzamanlılık vs verim: Kolonsal, az sayıda dev tarama sorgusunda parlar; binlerce küçük eşzamanlı sorgu için değil."],"related":["decide-partition","io-bottleneck"]},"sol_star":{"kind":"solution","title":"Öneri: Star schema (fact + dimension)","detail":"Analitik modelde merkezde ölçümleri tutan fact tablosu, çevresinde tanımlayıcı dimension tabloları bulunur. Aşırı normalize şemaya kıyasla join sayısı azalır, sorgular sadeleşir ve motor daha iyi plan üretir.","steps":["Yapı: Fact (ölçüm + boyut anahtarları) merkezde; dimension'lar (zaman, ürün, müşteri) etrafında yıldız oluşturur.","Ne zaman: Raporlar çok sayıda tabloyu birleştiriyor ve normalize şema join'lerde boğuluyor.","Denormalizasyon: Analitikte bilinçli denormalizasyon normaldir; tutarlılık yükleme sürecinde (ETL/ELT) sağlanır.","Sonra: Sık çalışan ağır agregasyonları materialized view ile önceden hesapla.","Dikkat: OLTP'yi star schema'ya çevirme; bu model analitik için, işlemsel yazma için değil."],"related":["decide-index"]},"sol_matview":{"kind":"solution","title":"Öneri: Materialized view ile önceden hesapla","detail":"Aynı ağır agregasyon (günlük ciro, aylık özet) defalarca çalışıp aynı sonucu üretiyorsa, sonucu bir materialized view'de fiziksel olarak saklayıp raporları hazır sonuçtan okutursun. Ağır hesap bir kez yapılır, sorgular anında döner.","steps":["Ne zaman: Belirli özet sorgular sık ve tekrar tekrar aynı büyük tabloyu tarıyor.","Yenileme: Materialized view'i planlı yenile (ör. gece toplu veya artımlı); tazelik ihtiyacına göre sıklığı ayarla.","Motor: PostgreSQL materialized view (REFRESH), Oracle materialized view (hatta query rewrite), SQL Server indexed view.","Dikkat: View bir tazelik penceresiyle gelir; anlık güncel veri gereken yerde canlı sorgu şart.","Sonra: Yenileme maliyeti yüksekse artımlı yenileme veya partition bazlı yenileme düşün."],"related":["decide-partition"]}}},"solver/arch-microservice.json":{"id":"arch-microservice","title":"Referans Mimari: Mikroservis veri katmanı","icon":"🏛️","category":"Referans Mimari","intro":"Mikroservislerde en kritik karar veri sahipliğidir: her servis kendi verisine sahip olmalı (database-per-service) ve başka servisin tablosuna doğrudan girmemeli. Bu ağaç; paylaşılan DB anti-desenini, servisler arası tutarlılığı dağıtık transaction olmadan sağlamayı (saga + outbox), veriyi CDC ile senkronlamayı ve servisler arası sorguyu (API composition vs CQRS okuma modeli) adım adım ele alır. Amaç; servisleri gerçekten bağımsız ve ayrı deploy edilebilir tutmaktır.","start":"root","nodes":{"root":{"kind":"step","title":"Servisler veriye nasıl sahip: ortak DB mi, her servise ayrı mı?","detail":"Mikroservis mimarisinin bel kemiği veri izolasyonudur. Servisler tek bir paylaşılan veritabanını mı kullanıyor (gizli bağımlılık), her servisin kendi veritabanı mı var (doğru desen), yoksa asıl zorluk servisler arası tutarlılık/sorgu mu? Önce mevcut durumu belirle.","choices":[{"label":"Tüm servisler tek paylaşılan DB'yi kullanıyor","next":"sol_db_per_service"},{"label":"Her servisin DB'si ayrı; ama işlemler servisler arası tutarlılık istiyor","next":"consistency"},{"label":"Her servisin DB'si ayrı; ama birleşik sorgu/rapor gerekiyor","next":"query"}]},"consistency":{"kind":"step","title":"Servisler arası bir iş akışını nasıl tutarlı tutacaksın?","detail":"Birden çok servisi kapsayan bir işlemde (sipariş oluştur → ödeme al → stok düş) klasik dağıtık transaction (2PC) kırılgan ve ölçeklenmez. Bunun yerine akışı yerel transaction + olay adımlarına bölmek (saga) ve olayları güvenle yayınlamak (outbox) gerekir. Hangi problemle uğraşıyorsun?","choices":[{"label":"Çok servisli iş akışını atomik tutmaya çalışıyorum (2PC?)","next":"sol_saga"},{"label":"Yerel yazma ile olay yayınını tutarlı yapamıyorum (ikili yazma)","next":"sol_outbox"}]},"query":{"kind":"step","title":"Birden çok servisin verisini gösteren sorguyu nasıl karşılayacaksın?","detail":"Veri servislere bölününce tek bir join ile birleşik ekran üretemezsin. İki temel yaklaşım var: istek anında ilgili servislerin API'lerini çağırıp sonucu birleştirmek (API composition) veya olaylarla beslenen, önceden birleştirilmiş bir okuma modeli tutmak (CQRS). Sorgunun sıklığı ve karmaşıklığı seçimi belirler.","choices":[{"label":"Basit, seyrek birleşim; birkaç servisi çağırıp birleştir yeter","next":"sol_api_composition"},{"label":"Karmaşık/sık birleşik sorgu; hazır okuma modeli lazım","next":"sol_cqrs"}]},"sol_db_per_service":{"kind":"solution","title":"Öneri: Database-per-service (paylaşılan DB'yi ayır)","detail":"Servislerin tek bir veritabanını paylaşması gizli ve tehlikeli bir bağımlılıktır: bir servisin şema değişikliği diğerlerini kırar, tablolar üzerinde kimin sorumlu olduğu belirsizleşir ve bağımsız deploy imkânsızlaşır. Her servis kendi verisine sahip olmalı.","steps":["İlke: Her servis yalnızca kendi veritabanına yazar/okur; başka servisin tablosuna doğrudan erişemez, sadece o servisin API'sinden ister.","Motor bağımsızlığı: Her servis kendi ihtiyacına göre motor seçebilir (ör. sipariş için PostgreSQL, katalog için MongoDB, arama için Elasticsearch, sepet için Redis).","Anti-desen: 'Paylaşılan veritabanı' — ortak tablolar, çapraz join'ler ve tek şema; bu, mikroservis değil dağıtık bir monolittir.","Ayrıştırma: Önce mantıksal ayrım (ayrı şema/kullanıcı), sonra fiziksel ayrım; çapraz tablo join'lerini kaldır.","Dikkat: Ayrıştıktan sonra tutarlılık (saga/outbox) ve birleşik sorgu (composition/CQRS) sorunları doğar; bunlar bu geçişin doğal bedelidir."],"related":["decide-isolation","decide-sqlnosql"]},"sol_saga":{"kind":"solution","title":"Öneri: Saga deseni (dağıtık transaction'dan kaçın)","detail":"Birden çok servisi kapsayan işlemi tek bir dağıtık transaction (2PC) ile atomik yapmaya çalışma; 2PC lock tutar, tek nokta kırılganlığı ve düşük kullanılabilirlik getirir. Bunun yerine akışı, her biri kendi servisinde yerel transaction olan adımlara böl ve hata olursa telafi (compensation) adımlarıyla geri al.","steps":["İlke: İş akışını yerel transaction + olay zinciri olarak modelle; her adım bir sonrakini tetikler.","Telafi: Bir adım başarısızsa önceki adımları geri alan telafi işlemleri çalıştır (ör. ödeme başarısızsa siparişi iptal et).","Koreografi vs orkestrasyon: Basit akışlarda servisler olaylarla birbirini tetikler (koreografi); karmaşık akışta merkezi bir orkestratör adımları yönetir.","Dikkat: Saga atomik değil, eventual consistency sağlar; ara durumlar dışarıya görünebilir, iş kurallarını buna göre tasarla.","Dikkat: 2PC/XA'yı yüksek ölçekli mikroservislerde kullanma; kilitlenme ve lock süresi sistemi durdurur."],"related":["decide-isolation","long-transaction"]},"sol_outbox":{"kind":"solution","title":"Öneri: Transactional outbox (ikili yazma tuzağı)","detail":"Bir servis hem kendi DB'sine yazıp hem de bir olay yayınlamak istediğinde, ikisini ayrı ayrı yapmak 'ikili yazma' tuzağıdır: biri başarılı, diğeri başarısız olursa sistem tutarsız kalır. Çözüm; olayı iş verisiyle AYNI yerel transaction içinde bir outbox tablosuna yazıp sonra ayrı bir süreçle yayınlamaktır.","steps":["İlke: İş kaydı + olay kaydı tek yerel transaction'da outbox tablosuna yazılır; ya ikisi de olur ya hiçbiri (atomik).","Yayınlama: Ayrı bir relay/CDC süreci outbox satırlarını okuyup mesaj kuyruğuna (ör. Kafka) yayınlar ve işaretler.","CDC ile: Debezium gibi bir CDC aracı DB'nin log'unu (WAL/binlog) okuyarak outbox değişikliklerini güvenilir biçimde Kafka'ya taşır.","Idempotency: Tüketiciler aynı olayı birden çok kez alabilir; olay id'siyle idempotent işle (en-az-bir-kez teslim varsayımı).","Dikkat: 'Önce DB'ye yaz sonra Kafka'ya publish et' yaklaşımını doğrudan kullanma; publish anındaki çökme olay kaybına yol açar."],"related":["replication-lag"]},"sol_api_composition":{"kind":"solution","title":"Öneri: API composition (istek anında birleştir)","detail":"Birleşik veri gereken yerde, çağıran taraf (ör. bir gateway/BFF) ilgili servislerin API'lerini çağırır ve sonuçları bellekte birleştirir. Basit ve az sayıda servisi kapsayan birleşimler için en sade çözümdür; ek veri kopyası tutulmaz.","steps":["İlke: Bir composer (API gateway/BFF) servis-A ve servis-B'yi çağırır, sonucu birleştirip döndürür.","Ne zaman: Birleşim basit, az servisi kapsıyor ve sorgu sıklığı orta; ek okuma modeli bakım yükü istemiyorsun.","Artı: Ekstra veri deposu ve senkron yok; her servis kendi güncel verisini verir.","Dikkat: Çok servisli veya büyük veri kümesi birleşimlerinde gecikme birikir ve bellekte in-memory join maliyetlidir.","Sonra: Birleşim karmaşıklaşır veya çok sıklaşırsa CQRS okuma modeline geç."],"related":[]},"sol_cqrs":{"kind":"solution","title":"Öneri: CQRS okuma modeli (olaylarla beslenen)","detail":"Karmaşık ve sık birleşik sorgular için, servislerin yaydığı olaylarla önceden birleştirilmiş, sorguya optimize bir okuma modeli (materialized view/denormalize kopya) tutulur. Yazma tarafı servislerde kalır; okuma tarafı hazır veriyi tek yerden hızlıca sunar.","steps":["İlke: Servisler durum değişikliklerini olay olarak yayınlar; bir projeksiyon bu olayları dinleyip okuma modelini günceller.","Depo seçimi: Okuma modeli sorgu tipine göre seçilir — arama için Elasticsearch, esnek belge için MongoDB, hızlı anahtar için Redis, ilişkisel rapor için PostgreSQL.","Ne zaman: Birleşik sorgu karmaşık/sık, düşük gecikme gerekiyor ve API composition maliyeti yükseldi.","Dikkat: Okuma modeli eventual consistent'tır; olaylar işlenene kadar hafif gecikmeyle gerisinde kalır.","Idempotency: Projeksiyon aynı olayı iki kez görebilir; olay id'siyle idempotent güncelle, gerekiyorsa sıra/versiyon takip et."],"related":["decide-cache"]}}},"solver/arch-eventdriven.json":{"id":"arch-eventdriven","title":"Referans Mimari: Olay-güdümlü / CQRS","icon":"🏛️","category":"Referans Mimari","intro":"Olay-güdümlü mimaride servisler birbirini doğrudan çağırmak yerine bir olay kaydına (event log, ör. Kafka) olay yayınlar ve tüketiciler bunları asenkron işler. Bu ağaç; olay omurgasını kurmaktan başlayarak event sourcing (durumu olaylardan türetme), CQRS ile komut/sorgu ayrımı, okuma modeli projeksiyonu, idempotency, eventual consistency toleransı ve 'exactly-once teslim' yanılgısını adım adım ele alır. Amaç; gevşek bağlı, ölçeklenebilir ama tutarlılık ödünleşimleri iyi anlaşılmış bir sistem kurmaktır.","start":"root","nodes":{"root":{"kind":"step","title":"Olay-güdümlü mimaride hangi kararla uğraşıyorsun?","detail":"Olay-güdümlü sistemin temeli, servisleri asenkron olaylarla bağlayan dayanıklı bir olay kaydıdır. Henüz omurgayı mı kuruyorsun, durumu olaylardan mı türetmek (event sourcing) istiyorsun, yoksa okuma/yazma yollarını mı ayırıyorsun (CQRS)?","choices":[{"label":"Servisleri bağlayan olay omurgasını kuruyorum","next":"sol_event_log"},{"label":"Durumu olay geçmişinden türetmek istiyorum","next":"sol_event_sourcing"},{"label":"Okuma ve yazma yollarını ayırmak istiyorum (CQRS)","next":"cqrs_split"}]},"cqrs_split":{"kind":"step","title":"CQRS'te okuma tarafını nasıl kuracaksın, tutarlılık toleransın ne?","detail":"CQRS'te komut (yazma) ve sorgu (okuma) tarafları ayrılır; yazma olayları, okuma modelini besleyen projeksiyonu günceller. Kritik soru: okuma modelinin yazmanın gerisinde kalmasını (eventual consistency) tolere edebiliyor musun, yoksa her olayın tam-bir-kez işlenmesini mi bekliyorsun?","choices":[{"label":"Okuma modelini olaylardan projeksiyonla besleyeceğim","next":"sol_read_model"},{"label":"Okuma anında güncel olmalı; gecikme kabul edilemez","next":"sol_consistency"},{"label":"Olaylar 'tam bir kez' işlensin istiyorum","next":"sol_idempotency"}]},"sol_event_log":{"kind":"solution","title":"Öneri: Dayanıklı olay kaydı (event log) omurgası","detail":"Olay-güdümlü mimarinin merkezinde, üreticilerin olay yazdığı ve tüketicilerin kendi hızında okuduğu dayanıklı, sıralı bir olay kaydı (log) bulunur. Bu omurga servisleri zaman ve ölçek olarak birbirinden ayırır.","steps":["Motor: Apache Kafka (veya benzeri log tabanlı platform) — partition'lı, kalıcı, tekrar-okunabilir (replayable) olay günlüğü.","Partition & sıra: Sıra yalnızca partition içinde garanti edilir; aynı varlığın olaylarını aynı anahtara (key) yönlendirerek sırayı koru.","Tüketici bağımsızlığı: Her tüketici grubu kendi offset'ini tutar; üreticiyi etkilemeden yeniden okuyabilir/geri sarabilir.","Saklama: Log'u yeterince uzun sakla ki yeni tüketiciler ve yeniden işleme geçmişi okuyabilsin.","Dikkat: Kafka bir kuyruk değil, tekrar-okunabilir bir günlüktür; teslim en-az-bir-kez varsayılır, tüketiciyi idempotent yaz."],"related":[]},"sol_event_sourcing":{"kind":"solution","title":"Öneri: Event sourcing (durumu olaylardan türet)","detail":"Event sourcing'de bir varlığın güncel durumunu değil, ona olan tüm değişiklik olaylarını (immutable) saklarsın; güncel durum bu olayların sırayla uygulanmasıyla türetilir. Tam denetim geçmişi ve geçmişteki herhangi bir ana geri dönebilme sağlar.","steps":["İlke: Gerçek kaynak olay akışıdır; durum, olayların baştan uygulanmasıyla (veya snapshot + sonrası) yeniden kurulur.","Snapshot: Uzun akışlarda her seferinde baştan oynatmamak için periyodik snapshot al, üzerine sonraki olayları uygula.","Artı: Tam denetim izi, zaman içinde 'nasıl bu duruma gelindi' cevabı, farklı okuma modelleri türetebilme.","Dikkat: Olay şeması evrilir; eski olayları okumak için versiyonlama/upcasting gerekir — olaylar sonsuza dek yaşar.","Dikkat: Her senaryoya gerekmez; sadece güncel durum yetiyorsa klasik CRUD daha basittir. Genelde CQRS ile birlikte kullanılır."],"related":[]},"sol_read_model":{"kind":"solution","title":"Öneri: Okuma modeli projeksiyonu","detail":"CQRS'te yazma tarafı olay üretir; bir projeksiyon bu olayları dinleyip sorguya optimize bir okuma modeli (denormalize görünüm) günceller. Okumalar bu hazır modelden yapılır, yazma yolundan tamamen ayrılır ve her iki taraf bağımsız ölçeklenir.","steps":["İlke: Olaylar → projeksiyon → okuma deposu; okuma sorguları yalnızca bu denormalize modele vurur.","Depo seçimi: Sorgu tipine göre — arama için Elasticsearch, esnek belge için MongoDB, hızlı erişim için Redis, ilişkisel için PostgreSQL.","Yeniden kurulabilirlik: Okuma modeli olaylardan türev olduğu için silinip log tekrar okunarak baştan inşa edilebilir.","Idempotency: Projeksiyon aynı olayı birden çok kez görebilir; olay id/versiyonuyla idempotent güncelle.","Dikkat: Okuma modeli eventual consistent'tır; olay işlenene dek yazmanın gerisinde kalır — arayüzü buna göre tasarla."],"related":["decide-cache"]},"sol_consistency":{"kind":"solution","title":"Öneri: Eventual consistency toleransını tasarla","detail":"Olay-güdümlü/CQRS sistemlerinde okuma modeli yazmanın kısa bir süre gerisinde kalır (eventual consistency). Bunu 'yok etmeye' çalışmak yerine tolere edecek biçimde tasarlamak gerekir; katı anlık tutarlılık gereken az sayıdaki akışı ayrı tutarsın.","steps":["İlke: Çoğu iş akışı kısa gecikmeli tutarlılığı tolere eder; kullanıcıya 'işlem alındı, işleniyor' geri bildirimi ver.","Read-your-writes: Kullanıcının kendi yazdığını hemen görmesi gerekiyorsa o okumayı yazma tarafından/senkron karşıla.","Katı tutarlılık gereken çekirdek: Para bakiyesi gibi mutlak anlık tutarlılık isteyen işi tek bir servis/DB içinde ACID transaction ile tut, olaylarla dağıtma.","Dikkat: Eventual consistency'yi gizleme; ekranlarda ve iş kurallarında ara/geçici durumları açıkça ele al.","Dikkat: 'Tüm sistemi güçlü tutarlı yapayım' hedefi olay-güdümlü mimarinin kazançlarını (ölçek, gevşek bağ) yok eder."],"related":["decide-ha","replication-lag"]},"sol_idempotency":{"kind":"solution","title":"Öneri: Idempotency (exactly-once yanılgısı)","detail":"Dağıtık mesajlaşmada uçtan uca 'exactly-once teslim' pratikte bir yanılgıdır; ağ ve yeniden denemeler nedeniyle mesaj tekrarları kaçınılmazdır. Doğru hedef, işlemeyi idempotent yapmaktır: aynı olayı iki kez işlemek tek kez işlemekle aynı sonucu vermeli.","steps":["İlke: Teslimi en-az-bir-kez (at-least-once) kabul et; tüketicide tekrarları zararsız kıl.","Yöntem: Her olaya benzersiz id ver; işlenen id'leri kaydet ve tekrar gelirse atla (dedup), ya da doğal idempotent işlemler kullan (upsert, set).","Exactly-once semantiği: Kafka'nın 'exactly-once' özelliği yalnızca Kafka içi işlem sınırındadır; harici DB'ye yan etki idempotency olmadan garanti edilmez.","Sıra: Aynı varlığın olaylarını aynı partition anahtarına yönlendirerek sıra bozulmasından kaçın.","Dikkat: 'Exactly-once teslim ayarladım, dedup gerekmez' varsayımı üretimde tutarsızlık üretir — daima idempotent işle."],"related":[]}}},"solver/arch-multiregion.json":{"id":"arch-multiregion","title":"Referans Mimari: Çok-bölgeli / global","icon":"🏛️","category":"Referans Mimari","intro":"Kullanıcılar coğrafi olarak dağıldığında veya bölgesel felakete dayanıklılık gerektiğinde veri birden çok bölgeye yayılır. Bu ağaç; okuma yakınlığı (her bölgeye read replica), yazma topolojisi (tek-lider vs çok-lider vs quorum), veri yerelliği/uyumluluk (GDPR), çakışma çözümü ve RPO/RTO ile gecikme ödünleşimlerini adım adım ele alır. Temel gerçek: fizik yasaları nedeniyle düşük gecikme, güçlü tutarlılık ve çok-bölgeli yazma aynı anda tam sağlanamaz; bilinçli ödünleşim şarttır.","start":"root","nodes":{"root":{"kind":"step","title":"Çok-bölgeliye neden geçiyorsun: okuma yakınlığı mı, yazma/dayanıklılık mı, uyumluluk mu?","detail":"Çok-bölgeli mimari maliyetli ve karmaşıktır; motivasyonu netleştir. Uzak kullanıcılara düşük okuma gecikmesi mi istiyorsun, bölgeler arası yazma/felaket dayanıklılığı mı, yoksa verinin belirli ülkede kalması (yasal yerellik) mi asıl gereksinim?","choices":[{"label":"Uzak kullanıcılara hızlı okuma; yazma tek bölgede kalabilir","next":"sol_read_locality"},{"label":"Bölgeler arası yazma / bölge kaybına dayanıklılık gerekiyor","next":"write_topology"},{"label":"Veri yasal olarak belirli ülkede/bölgede kalmalı","next":"sol_data_residency"}]},"write_topology":{"kind":"step","title":"Yazma topolojisi ne olsun: tek-lider mi, çok-lider mi, quorum mu?","detail":"Bölgeler arası yazmada temel karar liderlik modelidir. Tüm yazmalar tek bir bölgeye mi gidiyor (basit, tutarlı ama uzak yazma yavaş), her bölge yazabiliyor mu (düşük yazma gecikmesi ama çakışma), yoksa yazma bölgelerin çoğunluğunun onayıyla mı kabul ediliyor (quorum: tutarlı ama gecikmeli)?","choices":[{"label":"Tek bölge yazsın, diğerleri okusun (basit ve tutarlı)","next":"sol_single_leader"},{"label":"Her bölge yerel yazabilsin (düşük yazma gecikmesi)","next":"sol_multi_leader"},{"label":"Çoğunluk onayıyla yaz; tutarlılık öncelik","next":"sol_quorum"}]},"sol_read_locality":{"kind":"solution","title":"Öneri: Bölge başına okuma replikası (read locality)","detail":"Yazma tek bir primary bölgede kalırken, her kullanıcı bölgesine o bölgeden beslenen bir okuma replikası yerleştirirsin. Kullanıcılar en yakın replikadan okur, okuma gecikmesi düşer; yazmalar hâlâ tek merkeze gittiği için tutarlılık modeli basit kalır.","steps":["Topoloji: Bir primary bölge (yazma) → her kullanıcı bölgesinde asenkron okuma replikası.","Motor: PostgreSQL streaming replication, MySQL cross-region replikaları veya yönetilen global okuma replikaları.","Yönlendirme: Uygulama okumayı en yakın replikaya, yazmayı primary bölgeye yönlendirir (geo DNS / akıllı router).","Dikkat: Bölgeler arası replikasyon gecikmesi bayat okuma yaratır; read-your-writes gereken akışları primary'den okut.","RPO/RTO: Primary bölge düşerse asenkron replika biraz veri kaybıyla (RPO > 0) terfi ettirilebilir; failover planını önceden hazırla."],"related":["replication-lag","decide-shard-replica"]},"sol_single_leader":{"kind":"solution","title":"Öneri: Tek-lider (single-leader) yazma","detail":"Tüm yazmalar tek bir lider bölgeye gider; diğer bölgeler bu liderden asenkron beslenen okuma replikalarıdır. En basit ve en güçlü tutarlı modeldir; çakışma yoktur çünkü tek yazma noktası vardır. Bedeli, uzak bölgelerden yazmanın yüksek gecikmesidir.","steps":["İlke: Tek yazma otoritesi → çakışma yok, tutarlılık modeli basit.","Ne zaman: Yazma hacmi tek bölgede karşılanabiliyor ve uzak yazma gecikmesi tolere edilebiliyorsa.","Failover: Lider bölge düşerse bir replika lider olarak terfi eder; otomatik/kontrollü failover ve split-brain koruması şart.","RPO/RTO: Asenkron replikasyonda failover'da az miktarda kayıp (RPO) olabilir; senkron replikasyon RPO=0 verir ama yazma gecikmesini artırır.","Dikkat: Uzak kullanıcıların yazması yavaştır; yazma yakınlığı kritikse çok-lider veya quorum'a bak."],"related":["decide-ha","failover-drill"]},"sol_multi_leader":{"kind":"solution","title":"Öneri: Çok-lider (multi-leader) yazma + çakışma çözümü","detail":"Her bölge yerel olarak yazabildiği için yazma gecikmesi düşüktür ve bir bölge kopsa bile diğerleri yazmaya devam eder. Bedeli ağırdır: aynı kaydı iki bölge farklı güncelleyebilir ve çakışma (conflict) çözümü tasarlamak zorundasın.","steps":["İlke: Her bölge lider; yazmalar asenkron olarak diğer bölgelere yayılır ve birleştirilir.","Çakışma çözümü: Last-write-wins (basit ama veri kaybı riski), uygulamaya özel birleştirme (merge) veya CRDT gibi çakışmasız veri tipleri.","Motor örnekleri: Çok-master/çok-lider yapılandırmalar (ör. PostgreSQL için EDB Postgres Distributed (BDR)/pgEdge, Redis Enterprise Active-Active (CRDT), CouchDB). Cassandra multi-leader değil leaderless'tır; LOCAL_ONE/LOCAL_QUORUM ile her bölgede yerel yazmaya izin vererek benzer bir sonuç verir ve çakışmaları last-write-wins (zaman damgası) ile çözer.","Ne zaman: Yerel yazma gecikmesi ve bölge bağımsızlığı, güçlü tutarlılıktan daha önemliyse.","Dikkat: Çakışma çözümünü baştan tasarla; 'çakışma olmaz' varsayımı sessiz veri kaybı üretir. Benzersiz kimlik üretiminde bölge çakışmasına dikkat et."],"related":["decide-ha"]},"sol_quorum":{"kind":"solution","title":"Öneri: Quorum tabanlı yazma (çoğunluk onayı)","detail":"Bir yazma, bölgelerin/kopyaların çoğunluğu (quorum) onayladığında kabul edilir; okuma da çoğunluktan yapılınca güncel değer garanti edilir. Bölge kaybına dayanıklı ve güçlü tutarlıdır; bedeli, her yazmanın çoğunluğa ulaşma gecikmesidir.","steps":["İlke: W + R > N kuralıyla çoğunluk onayı; bir azınlık bölge düşse de sistem tutarlı yazmaya devam eder.","Motor örnekleri: Consensus tabanlı dağıtık DB'ler (ör. Raft/Paxos kullanan sistemler), Cassandra'da QUORUM tutarlılık seviyesi.","Ne zaman: Hem bölge felaketine dayanıklılık hem güçlü tutarlılık şartsa ve yazma gecikmesi artışı kabul ediliyorsa.","RPO/RTO: Çoğunluk kalıcı yazdığından RPO≈0; bir bölge kaybında otomatik yeniden çoğunluk ile RTO düşük olabilir.","Dikkat: Coğrafi olarak uzak bölgeler arasında quorum, ışık hızı gecikmesi nedeniyle her yazmaya onlarca ms ekler; bölge sayısı ve yerleşimini dikkatle seç."],"related":["decide-ha","decide-shard-replica"]},"sol_data_residency":{"kind":"solution","title":"Öneri: Veri yerelliği / uyumluluk (data residency, GDPR)","detail":"Bazı verilerin (kişisel veri, sağlık, finans) yasal olarak belirli bir ülke/bölge sınırları içinde kalması gerekir (ör. GDPR). Bu durumda mimariyi 'her yere kopyala'ya göre değil, veriyi coğrafi olarak sabitleyecek şekilde tasarlarsın.","steps":["İlke: Kişisel/regüle veriyi kaynağının bulunduğu bölgede tut; bölge dışına replikasyonu kısıtla veya yasakla.","Bölgesel bölümleme: Kullanıcıyı kayıtlı olduğu bölgeye yönlendir (geo-partitioning); her bölge kendi vatandaşının verisini tutar.","Küresel vs yerel veri ayrımı: Katalog gibi küresel veri her yere replike edilebilir; kişisel veri bölgede kalır.","Dikkat: Yedekler ve okuma replikaları da veriyi taşır — yedek depolama bölgesi ve DR bölgesi de uyumluluk kapsamındadır.","Dikkat: 'Sadece düşük gecikme için her yere kopyalayalım' kararı, regüle veride yasal ihlal doğurabilir; yerellik kısıtlarını mimariye baştan koy."],"related":["security-incident","audit-setup"]}}},"solver/arch-highscale.json":{"id":"arch-highscale","title":"Referans Mimari: Yüksek ölçek / yüksek trafik","icon":"🏛️","category":"Referans Mimari","intro":"Trafik büyüdükçe veritabanını korumanın doğru sırası vardır: önce basit ve ucuz kaldıraçları, sonra karmaşık olanları. Bu ağaç; dikey büyütme → okuma replikası → sharding sırasını, önbellek desenlerini (cache-aside, write-back), kuyrukla tampon + backpressure, rate limiting ve bulkhead/circuit breaker ile veritabanını izole etmeyi, ayrıca hotspot önlemeyi adım adım ele alır. Temel ilke: sharding gibi geri dönüşü zor kararları en sona sakla, önce ucuz kazanımları tüket.","start":"root","nodes":{"root":{"kind":"step","title":"Darboğaz nerede: tek örnek doyuyor mu, okuma mı yazma mı ağır, yoksa trafik dalgalı mı?","detail":"Ölçek sorununu doğru yerden çözmek için önce darboğazı tanımla. Tek örnek CPU/bellek olarak mı doyuyor, okuma mı baskın, yazma mı sınırı zorluyor, yoksa ani trafik sıçramaları mı veritabanını eziyor? Her biri farklı bir bileşeni işaret eder.","choices":[{"label":"Tek örnek doyuyor; henüz basit kaldıraçları denemedim","next":"scale_path"},{"label":"Okuma çok ağır ve büyüyor","next":"sol_cache"},{"label":"Ani trafik sıçramaları / dalgalı yük DB'yi eziyor","next":"protect"}]},"scale_path":{"kind":"step","title":"Hangi ölçekleme adımındasın: dikey mi, okuma replikası mı, sharding mı?","detail":"Ölçeklemenin doğru sırası vardır. Önce dikey büyütme (daha güçlü donanım) en basitidir; sonra okumaları replikalara dağıtırsın; ancak tek primary yazmayı kaldıramaz hale gelince yatay bölmeye (sharding) geçilir. Hangi noktadasın?","choices":[{"label":"Henüz donanımı büyütmedim / basit ayarları tüketmedim","next":"sol_vertical"},{"label":"Yazma tek örnekte, okuma yükünü dağıtmam lazım","next":"sol_read_replica"},{"label":"Tek primary yazma yükünü artık kaldıramıyor","next":"sol_sharding"}]},"protect":{"kind":"step","title":"Veritabanını yükten nasıl koruyacaksın: tampon mu, sınırlama mı, izolasyon mu?","detail":"Ölçekleme her zaman DB'yi büyütmek değildir; çoğu zaman DB'yi aşırı yükten korumaktır. Ani yazma sıçramalarını bir kuyrukla mı yumuşatacaksın, gelen istek hızını mı sınırlayacaksın (rate limit), yoksa tek bir bağımlılığın tüm sistemi çökertmesini mi engelleyeceksin (bulkhead/circuit breaker)?","choices":[{"label":"Ani yazma sıçramalarını yumuşatmak istiyorum","next":"sol_queue"},{"label":"Gelen istek hızını sınırlamak/adil paylaştırmak istiyorum","next":"sol_ratelimit"},{"label":"Bir bağımlılığın çökmesi tüm sistemi devirmesin istiyorum","next":"sol_bulkhead"}]},"sol_vertical":{"kind":"solution","title":"Öneri: Önce dikey büyütme ve temel ayar","detail":"En ucuz ve en az riskli adım dikey ölçeklemedir: daha fazla CPU/RAM/hızlı disk vermek ve temel ayarları (index, bağlantı havuzu, bellek parametreleri) düzeltmek. Sharding gibi karmaşık kararlardan önce bu kazanımları tüket.","steps":["İlk adım: Donanımı büyüt (CPU/RAM/NVMe), buffer/cache bellek parametrelerini işe göre ayarla.","Ucuz kazanımlar: Eksik index'leri ekle, ağır sorguları düzelt, bağlantı havuzu (PgBouncer/ProxySQL) koy — çoğu 'ölçek' sorunu aslında ayar sorunudur.","Ne zaman yeter: Tek örnek büyütülünce hedef gecikme/verim tutuyorsa dur; daha fazla karmaşıklık ekleme.","Dikkat: Dikey büyütmenin fiziksel ve maliyet tavanı vardır; tavana yaklaşınca okuma replikası ve cache'e geç.","Sonra: Okuma baskınsa replika + cache; yazma baskın ve tavan aşılıyorsa sharding."],"related":["decide-capacity","high-cpu"]},"sol_read_replica":{"kind":"solution","title":"Öneri: Okuma replikalarıyla okumayı dağıt","detail":"Yazma tek primary'de kalırken salt-okuma trafiğini bir veya daha fazla replikaya dağıtırsın. Sharding'e göre çok daha basittir ve okuma baskın yüklerin büyük kısmını çözer; primary yalnızca yazma ve tutarlılık kritik okumalar için kalır.","steps":["Topoloji: Primary (yazma) → çok sayıda asenkron okuma replikası; okumalar bir yük dengeleyiciyle replikalara dağıtılır.","Motor: PostgreSQL streaming replication, MySQL replikaları, yönetilen okuma replikaları.","Ne zaman: Okuma/yazma oranı okuma lehine yüksekse ve yazma tek örnekte hâlâ karşılanıyorsa.","Dikkat: Replikasyon gecikmesi bayat okuma yaratır; read-your-writes gereken okumaları primary'den yap.","Sonra: Replikalar bile yetmiyor veya asıl darboğaz yazmaysa cache ekle, ardından sharding'e bak."],"related":["replication-lag","decide-shard-replica"]},"sol_sharding":{"kind":"solution","title":"Öneri: Sharding (yatay bölme) — en son çare","detail":"Tek primary yazma yükünü kaldıramadığında veriyi bir anahtara göre birden çok bağımsız parçaya (shard) bölersin; her shard yazmanın bir kısmını üstlenir. Güçlü ama geri dönüşü zor bir karardır; çapraz-shard sorgu ve transaction'ları zorlaştırır, bu yüzden en sona bırakılır.","steps":["Shard anahtarı: Yükü ve veriyi eşit dağıtan, çoğu sorgunun tek shard'a düşmesini sağlayan bir anahtar seç (ör. müşteri_id).","Yöntem: Hash tabanlı (eşit dağılım) veya aralık tabanlı (aralık sorgusu kolay ama hotspot riski) bölme.","Motor örnekleri: MongoDB sharding, Citus (PostgreSQL), Vitess (MySQL) veya uygulama katmanı sharding.","Dikkat: Çapraz-shard join/transaction pahalı ve karmaşıktır; şemayı çoğu transaction tek shard'da tamamlanacak şekilde tasarla.","Dikkat: Yanlış anahtar hotspot (bir shard'a yığılma) doğurur; artan id/tarih gibi monoton anahtarlardan kaçın, resharding zordur."],"related":["decide-shard-replica","decide-partition"]},"sol_cache":{"kind":"solution","title":"Öneri: Önbellek desenleri (cache-aside + write-back)","detail":"Okuma baskın yüksek trafikte DB'nin önüne bir bellek-içi önbellek (Redis) koyup okumaların çoğunu DB'ye hiç ulaştırmadan karşılarsın. Yüksek hacimli yazmalarda ise write-back ile yazmayı tamponlayıp DB'ye toplu aktararak primary'yi rahatlatırsın.","steps":["Cache-aside: Uygulama önce Redis'e bakar; ıskada DB'den çekip cache'e yazar. Okuma yükünün büyük kısmını DB'den alır.","Write-back (write-behind): Sayaç/metrik gibi çok yüksek yazma hacminde önce cache'e yaz, arka planda DB'ye toplu flush et.","TTL + invalidation: Anahtarlara makul TTL koy; yazışta ilgili anahtarı güncelle/sil ki bayat veri kalmasın.","Dikkat: Cache stampede — popüler anahtarın süresi dolunca binlerce istek aynı anda DB'ye vurur; lock/single-flight, erken yenileme ve jitter'lı TTL kullan.","Dikkat: Write-back'te cache düğümü DB'ye yazmadan çökerse veri kaybolur; kritik veride dayanıklı kuyruk/AOF ile koru."],"related":["decide-cache","cache-hit-low"]},"sol_queue":{"kind":"solution","title":"Öneri: Kuyrukla tampon (backpressure)","detail":"Ani yazma sıçramaları DB'yi doğrudan ezmesin diye araya dayanıklı bir kuyruk (ör. Kafka/mesaj kuyruğu) koyar, yazmaları DB'nin kaldırabileceği hızda tüketirsin. Kuyruk sıçramayı emer; sistem senkron çökme yerine kontrollü gecikmeyle çalışır (backpressure).","steps":["İlke: Üretici olayı kuyruğa yazar; tüketici DB'ye onun sürdürülebilir hızında (belki toplu) yazar.","Motor: Kafka veya bir mesaj kuyruğu; DB'yi zirve trafikten yalıtan bir tampon görevi görür.","Backpressure: Kuyruk büyüyorsa üreticiyi yavaşlat/geri bildir; sonsuz birikime izin verme, aksi halde gecikme patlar.","Ne zaman: Yazma trafiği çok dalgalı ve anlık senkron işleme zorunlu değilken (asenkron kabul ediliyorsa).","Dikkat: Kuyruk asenkronluk getirir — sonuç eventual consistent olur; tüketiciyi idempotent yaz (tekrar teslim olabilir)."],"related":["connection-storm"]},"sol_ratelimit":{"kind":"solution","title":"Öneri: Rate limiting (istek hızını sınırla)","detail":"Gelen istekleri kaynağa göre sınırlayarak (rate limit) hem kötüye kullanımı hem de tek bir istemcinin tüm kaynağı tüketmesini engellersin. DB'ye ulaşan yükü tavandan keserek sistemi öngörülebilir ve adil tutarsın.","steps":["Konum: Sınırlamayı DB'den önce (API gateway / uygulama kenarı) uygula; DB'ye ancak kabul edilen istekler ulaşsın.","Yöntem: Token bucket / sliding window ile istemci veya kullanıcı başına oran; aşımda 429 döndür.","Adil paylaşım: Kota ile bir 'gürültülü komşunun' tüm kapasiteyi yutmasını önle.","Ne zaman: Trafik ani sıçrayabiliyor veya kötüye kullanım/otomatik istemci riski varsa.","Dikkat: Rate limit ölçekleme değil koruma önlemidir; gerçek kapasite ihtiyacı varsa asıl darboğazı (dikey/replika/shard) da çöz."],"related":["connection-storm"]},"sol_bulkhead":{"kind":"solution","title":"Öneri: Bulkhead + circuit breaker (izolasyon)","detail":"Bir bağımlılığın (ör. yavaşlayan DB veya harici servis) tüm sistemi çökertmesini önlemek için kaynakları bölmelere ayırır (bulkhead) ve sürekli hata veren bağımlılığa çağrıyı geçici keserek (circuit breaker) sistemi korursun. Böylece kısmi arıza tüm sisteme yayılmaz.","steps":["Bulkhead: Farklı iş türleri için ayrı bağlantı havuzu/thread ayır; bir yavaş yol tüm havuzu tüketip diğerlerini aç bırakmasın.","Circuit breaker: Bir bağımlılık eşik üstü hata/gecikme verince devreyi 'aç', bir süre hızlı-başarısız dön; sonra deneme (half-open) ile toparlanmayı yokla.","Zaman aşımı: Her DB/servis çağrısına makul timeout koy; askıda kalan çağrılar havuzu kilitlemesin.","Ne zaman: Çok bağımlılıklı sistemde bir bileşenin yavaşlaması zincirleme çökme (cascading failure) riski taşırken.","Dikkat: Devre açıkken zarif düşüş (graceful degradation) tasarla — cache'ten eski veri döndür veya kısmi sonuç ver, tüm isteği reddetme."],"related":["connection-storm","high-cpu"]}}},"types/types-functions.json":{"schemaVersion":1,"sections":[{"id":"datatypes","title":"Veri Tipleri","icon":"🔤","rows":[{"id":"var-text","concept":"Değişken uzunluklu metin","engines":{"oracle":"VARCHAR2(n)","postgres":"VARCHAR(n) / TEXT","mysql":"VARCHAR(n)","mssql":"NVARCHAR(n)","mongodb":"string","redis":"string (değer)","elasticsearch":"text / keyword"},"note":"ES'te tam metin arama için text, birebir eşleşme/agregasyon için keyword kullanılır."},{"id":"fixed-text","concept":"Sabit uzunluklu metin","engines":{"oracle":"CHAR(n)","postgres":"CHAR(n)","mysql":"CHAR(n)","mssql":"NCHAR(n)","mongodb":"string","redis":"string","elasticsearch":"keyword"},"note":"Belge/anahtar-değer sistemlerinde sabit uzunluk kavramı yoktur, string olarak saklanır."},{"id":"large-text","concept":"Büyük metin (CLOB/TEXT)","engines":{"oracle":"CLOB","postgres":"TEXT","mysql":"LONGTEXT / TEXT","mssql":"NVARCHAR(MAX)","mongodb":"string","redis":"string (512 MB'a kadar)","elasticsearch":"text"}},{"id":"int32","concept":"Tamsayı (32-bit)","engines":{"oracle":"NUMBER(10)","postgres":"INTEGER / INT4","mysql":"INT","mssql":"INT","mongodb":"int (NumberInt / int32)","redis":"string (tamsayı olarak yorumlanır)","elasticsearch":"integer"},"note":"Oracle'da ayrı INT tipi yoktur, NUMBER kullanılır."},{"id":"int64","concept":"Büyük tamsayı (64-bit)","engines":{"oracle":"NUMBER(19)","postgres":"BIGINT / INT8","mysql":"BIGINT","mssql":"BIGINT","mongodb":"long (NumberLong / int64)","redis":"string (INCR 64-bit tamsayı)","elasticsearch":"long"}},{"id":"decimal","concept":"Ondalık/kesin sayı (NUMERIC)","engines":{"oracle":"NUMBER(p,s)","postgres":"NUMERIC(p,s) / DECIMAL","mysql":"DECIMAL(p,s)","mssql":"DECIMAL(p,s) / NUMERIC","mongodb":"decimal (Decimal128)","redis":"yok, string olarak saklanır","elasticsearch":"scaled_float"},"note":"Para gibi kesin değerlerde float yerine bu tipler tercih edilir."},{"id":"float","concept":"Kayan nokta (FLOAT/DOUBLE)","engines":{"oracle":"BINARY_DOUBLE / FLOAT","postgres":"REAL / DOUBLE PRECISION","mysql":"FLOAT / DOUBLE","mssql":"FLOAT / REAL","mongodb":"double","redis":"yok, string (INCRBYFLOAT)","elasticsearch":"float / double"}},{"id":"boolean","concept":"Mantıksal (BOOLEAN)","engines":{"oracle":"NUMBER(1) / CHAR(1) (23c'de BOOLEAN)","postgres":"BOOLEAN","mysql":"TINYINT(1) / BOOL","mssql":"BIT","mongodb":"bool","redis":"yok, 0/1 string veya bit","elasticsearch":"boolean"},"note":"Oracle SQL'de BOOLEAN sütun tipi ancak 23c ile geldi; öncesinde NUMBER/CHAR simüle edilir."},{"id":"date","concept":"Tarih (date)","engines":{"oracle":"DATE (saat de içerir)","postgres":"DATE","mysql":"DATE","mssql":"DATE","mongodb":"Date (ISODate)","redis":"yok (epoch string/number)","elasticsearch":"date (format ile)"},"note":"Oracle DATE tipi hem tarihi hem saati tutar, salt tarih değildir."},{"id":"datetime","concept":"Tarih-saat (timestamp/datetime)","engines":{"oracle":"TIMESTAMP","postgres":"TIMESTAMP","mysql":"DATETIME / TIMESTAMP","mssql":"DATETIME2","mongodb":"Date (ISODate)","redis":"yok (epoch string/number)","elasticsearch":"date"}},{"id":"datetime-tz","concept":"Zaman dilimli tarih-saat","engines":{"oracle":"TIMESTAMP WITH TIME ZONE","postgres":"TIMESTAMPTZ","mysql":"TIMESTAMP (UTC saklar)","mssql":"DATETIMEOFFSET","mongodb":"Date (UTC olarak saklar)","redis":"yok (epoch UTC)","elasticsearch":"date (UTC, zaman dilimi format ile)"},"note":"Mongo ve ES tarihleri UTC olarak saklar; zaman dilimi görüntülemede uygulanır."},{"id":"binary","concept":"Ikili veri (BLOB/binary)","engines":{"oracle":"BLOB / RAW","postgres":"BYTEA","mysql":"BLOB / VARBINARY","mssql":"VARBINARY(MAX)","mongodb":"BinData (binary)","redis":"string (ikili güvenli)","elasticsearch":"binary (base64, aranmaz)"},"note":"Redis string'leri ikili güvenlidir, herhangi bir byte dizisini tutabilir."},{"id":"uuid","concept":"UUID/GUID","engines":{"oracle":"RAW(16) / SYS_GUID()","postgres":"UUID","mysql":"BINARY(16) / CHAR(36)","mssql":"UNIQUEIDENTIFIER","mongodb":"UUID (BinData subtype 4) / ObjectId","redis":"yok, string olarak saklanır","elasticsearch":"keyword"},"note":"Mongo'nun yerel _id'si ObjectId'dir; UUID de BinData ile saklanabilir."},{"id":"json","concept":"JSON","engines":{"oracle":"JSON (21c+) / CLOB","postgres":"JSON / JSONB","mysql":"JSON","mssql":"JSON (2025) / NVARCHAR","mongodb":"object (yerel BSON)","redis":"yok yerel / RedisJSON modülü","elasticsearch":"object / nested / flattened"},"note":"Postgres'te sorgu/index için JSONB tercih edilir; MongoDB zaten belge tabanlıdır."},{"id":"auto-increment","concept":"Otomatik artan (identity/serial)","engines":{"oracle":"GENERATED AS IDENTITY / SEQUENCE","postgres":"SERIAL / GENERATED ... IDENTITY","mysql":"AUTO_INCREMENT","mssql":"IDENTITY(1,1)","mongodb":"yok (ObjectId veya sayaç deseni)","redis":"INCR ile sayaç","elasticsearch":"yok (otomatik _id)"}},{"id":"enum","concept":"Enum/sabit liste","engines":{"oracle":"CHECK constraint'i ile","postgres":"ENUM (CREATE TYPE)","mysql":"ENUM(...)","mssql":"CHECK constraint'i ile","mongodb":"yok (JSON Schema enum ile doğrulama)","redis":"yok, string olarak saklanır","elasticsearch":"keyword"}},{"id":"array","concept":"Dizi (array)","engines":{"oracle":"VARRAY / nested table / collection","postgres":"ARRAY (ör. INTEGER[])","mysql":"yok (JSON dizi ile)","mssql":"yok (JSON / tablo değişkeni)","mongodb":"array (yerel)","redis":"List / Set (yerel)","elasticsearch":"her alan dizi olabilir (yerel)"},"note":"ES'te tüm alanlar örtük olarak dizi tutabilir; ayrı bir dizi tipi yoktur."},{"id":"ip-address","concept":"IP adresi","engines":{"oracle":"VARCHAR2 / UTL_INADDR","postgres":"INET / CIDR","mysql":"VARBINARY(16) / INET6_ATON","mssql":"yok, VARCHAR ile","mongodb":"yok, string olarak saklanır","redis":"yok, string olarak saklanır","elasticsearch":"ip"},"note":"Postgres ve ES yerel IP tipleri aralık/altağ sorgularını destekler."},{"id":"money","concept":"Para","engines":{"oracle":"NUMBER(p,2)","postgres":"MONEY / NUMERIC(p,2)","mysql":"DECIMAL(p,2)","mssql":"MONEY / DECIMAL(p,2)","mongodb":"decimal (Decimal128)","redis":"yok, kuruş cinsinden tamsayı önerilir","elasticsearch":"scaled_float"},"note":"Yuvarlama hatasından kaçınmak için para float yerine DECIMAL/Decimal128 ile tutulur."},{"id":"spatial","concept":"Coğrafi/spatial","engines":{"oracle":"SDO_GEOMETRY (Oracle Spatial)","postgres":"GEOMETRY / GEOGRAPHY (PostGIS)","mysql":"GEOMETRY / POINT","mssql":"GEOGRAPHY / GEOMETRY","mongodb":"GeoJSON object (2dsphere index)","redis":"Geo (GEOADD, sorted set tabanlı)","elasticsearch":"geo_point / geo_shape"}}]},{"id":"functions","title":"Sık Fonksiyonlar","icon":"🧩","rows":[{"id":"coalesce","concept":"NULL ise varsayılan döndür (COALESCE/NVL)","engines":{"oracle":"NVL(x, y) / COALESCE","postgres":"COALESCE(x, y)","mysql":"COALESCE(x, y) / IFNULL","mssql":"COALESCE(x, y) / ISNULL","mongodb":"$ifNull: [x, y]","redis":"yok (uygulama tarafında)","elasticsearch":"?.field / painless ternary"}},{"id":"nullif-replace","concept":"NULL ise değiştir (ISNULL/IFNULL)","engines":{"oracle":"NVL(x, y)","postgres":"COALESCE(x, y)","mysql":"IFNULL(x, y)","mssql":"ISNULL(x, y)","mongodb":"$ifNull: [x, y]","redis":"yok","elasticsearch":"painless: doc[f].size()==0 ? y : x"}},{"id":"now","concept":"Şu anki tarih-saat (NOW/SYSDATE)","engines":{"oracle":"SYSDATE / SYSTIMESTAMP","postgres":"NOW() / CURRENT_TIMESTAMP","mysql":"NOW()","mssql":"GETDATE() / SYSDATETIME()","mongodb":"$$NOW / new Date()","redis":"TIME komutu","elasticsearch":"now (tarih matematiği)"}},{"id":"current-date","concept":"Şu anki tarih","engines":{"oracle":"TRUNC(SYSDATE) / CURRENT_DATE","postgres":"CURRENT_DATE","mysql":"CURDATE()","mssql":"CAST(GETDATE() AS DATE)","mongodb":"$dateTrunc / new Date()","redis":"TIME (epoch)","elasticsearch":"now/d"}},{"id":"concat","concept":"Metin birleştir (concat)","engines":{"oracle":"a || b / CONCAT","postgres":"a || b / CONCAT","mysql":"CONCAT(a, b)","mssql":"CONCAT(a, b) / a + b","mongodb":"$concat: [a, b]","redis":"APPEND","elasticsearch":"painless: a + b"},"note":"MySQL'de || varsayılan olarak OR'dur, birleştirme için CONCAT kullanılır."},{"id":"substring","concept":"Alt metin (substring)","engines":{"oracle":"SUBSTR(s, p, n)","postgres":"SUBSTRING(s, p, n)","mysql":"SUBSTRING(s, p, n)","mssql":"SUBSTRING(s, p, n)","mongodb":"$substrCP: [s, p, n]","redis":"GETRANGE key start end","elasticsearch":"painless: s.substring(p, e)"}},{"id":"length","concept":"Metin uzunluğu","engines":{"oracle":"LENGTH(s)","postgres":"LENGTH(s) / CHAR_LENGTH","mysql":"CHAR_LENGTH(s)","mssql":"LEN(s)","mongodb":"$strLenCP: s","redis":"STRLEN key","elasticsearch":"painless: s.length()"}},{"id":"upper-lower","concept":"Büyük/küçük harf","engines":{"oracle":"UPPER(s) / LOWER(s)","postgres":"UPPER(s) / LOWER(s)","mysql":"UPPER(s) / LOWER(s)","mssql":"UPPER(s) / LOWER(s)","mongodb":"$toUpper / $toLower","redis":"yok (uygulama tarafında)","elasticsearch":"painless: s.toUpperCase() / lowercase analyzer"}},{"id":"trim","concept":"Boşluk kırp (TRIM)","engines":{"oracle":"TRIM(s) / LTRIM / RTRIM","postgres":"TRIM(s)","mysql":"TRIM(s)","mssql":"TRIM(s)","mongodb":"$trim: { input: s }","redis":"yok","elasticsearch":"painless: s.trim() / trim token filter"}},{"id":"replace","concept":"Metin değiştir (REPLACE)","engines":{"oracle":"REPLACE(s, a, b)","postgres":"REPLACE(s, a, b)","mysql":"REPLACE(s, a, b)","mssql":"REPLACE(s, a, b)","mongodb":"$replaceAll / $replaceOne","redis":"SETRANGE (konumsal) / yok","elasticsearch":"painless: s.replace(a, b)"}},{"id":"cast","concept":"Tip dönüştür (CAST/CONVERT)","engines":{"oracle":"CAST(x AS t) / TO_NUMBER","postgres":"CAST(x AS t) / x::t","mysql":"CAST(x AS t) / CONVERT","mssql":"CAST(x AS t) / CONVERT","mongodb":"$convert / $toInt, $toString","redis":"yok (tümü string)","elasticsearch":"painless: Integer.parseInt(...) / runtime field"}},{"id":"date-to-char","concept":"Tarihi metne biçimle (TO_CHAR/FORMAT)","engines":{"oracle":"TO_CHAR(d, 'YYYY-MM-DD')","postgres":"TO_CHAR(d, 'YYYY-MM-DD')","mysql":"DATE_FORMAT(d, '%Y-%m-%d')","mssql":"FORMAT(d, 'yyyy-MM-dd') / CONVERT","mongodb":"$dateToString: { format, date }","redis":"yok","elasticsearch":"date alanı formatı / painless SimpleDateFormat"}},{"id":"parse-date","concept":"Metni tarihe çevir (TO_DATE/PARSE)","engines":{"oracle":"TO_DATE(s, 'YYYY-MM-DD')","postgres":"TO_DATE(s, 'YYYY-MM-DD')","mysql":"STR_TO_DATE(s, '%Y-%m-%d')","mssql":"CONVERT(date, s) / PARSE","mongodb":"$dateFromString: { dateString: s }","redis":"yok","elasticsearch":"date mapping otomatik ayrıştırma"}},{"id":"date-add","concept":"Tarihe ekle (interval/DATEADD)","engines":{"oracle":"d + n / ADD_MONTHS / INTERVAL","postgres":"d + INTERVAL '1 day'","mysql":"DATE_ADD(d, INTERVAL 1 DAY)","mssql":"DATEADD(day, 1, d)","mongodb":"$dateAdd: { startDate, unit, amount }","redis":"yok (epoch'a ekle)","elasticsearch":"tarih matematiği: now+1d"}},{"id":"date-diff","concept":"İki tarih farkı (DATEDIFF)","engines":{"oracle":"d1 - d2 (gün) / MONTHS_BETWEEN","postgres":"d1 - d2 / AGE(d1, d2)","mysql":"DATEDIFF(d1, d2)","mssql":"DATEDIFF(day, d2, d1)","mongodb":"$dateDiff: { startDate, endDate, unit }","redis":"yok (epoch farkı)","elasticsearch":"painless: ChronoUnit.DAYS.between(...)"}},{"id":"extract","concept":"Tarih parçası çıkar (EXTRACT)","engines":{"oracle":"EXTRACT(YEAR FROM d)","postgres":"EXTRACT(YEAR FROM d) / DATE_PART","mysql":"EXTRACT(YEAR FROM d) / YEAR(d)","mssql":"DATEPART(year, d) / YEAR(d)","mongodb":"$year / $month / $dayOfMonth","redis":"yok","elasticsearch":"painless: doc[f].value.year"}},{"id":"round","concept":"Yuvarla (ROUND)","engines":{"oracle":"ROUND(x, n)","postgres":"ROUND(x, n)","mysql":"ROUND(x, n)","mssql":"ROUND(x, n)","mongodb":"$round: [x, n]","redis":"yok","elasticsearch":"painless: Math.round(x)"}},{"id":"mod","concept":"Mod (kalan)","engines":{"oracle":"MOD(a, b)","postgres":"MOD(a, b) / a % b","mysql":"MOD(a, b) / a % b","mssql":"a % b","mongodb":"$mod: [a, b]","redis":"yok","elasticsearch":"painless: a % b"}},{"id":"case","concept":"Koşul (CASE/DECODE)","engines":{"oracle":"CASE ... / DECODE(x, ...)","postgres":"CASE WHEN ... END","mysql":"CASE WHEN ... END / IF()","mssql":"CASE WHEN ... END / IIF()","mongodb":"$cond / $switch","redis":"yok","elasticsearch":"painless: if/else"}},{"id":"greatest-least","concept":"En büyük/küçük (GREATEST/LEAST)","engines":{"oracle":"GREATEST(...) / LEAST(...)","postgres":"GREATEST(...) / LEAST(...)","mysql":"GREATEST(...) / LEAST(...)","mssql":"GREATEST(...) / LEAST(...) (2022+)","mongodb":"$max / $min (ifade)","redis":"yok","elasticsearch":"painless: Math.max / Math.min"}},{"id":"string-agg","concept":"Grup içinde birleştir (STRING_AGG/GROUP_CONCAT/LISTAGG)","engines":{"oracle":"LISTAGG(x, ',')","postgres":"STRING_AGG(x, ',')","mysql":"GROUP_CONCAT(x)","mssql":"STRING_AGG(x, ',')","mongodb":"$push + $reduce / $concatArrays","redis":"yok","elasticsearch":"terms agg / scripted_metric"}},{"id":"row-number","concept":"Satır numarası (ROW_NUMBER)","engines":{"oracle":"ROW_NUMBER() OVER (...)","postgres":"ROW_NUMBER() OVER (...)","mysql":"ROW_NUMBER() OVER (...)","mssql":"ROW_NUMBER() OVER (...)","mongodb":"$setWindowFields: { $documentNumber }","redis":"yok","elasticsearch":"yok (top_hits / bucket_sort)"}},{"id":"limit","concept":"İlk N satır (LIMIT/TOP/ROWNUM)","engines":{"oracle":"FETCH FIRST n ROWS ONLY / ROWNUM","postgres":"LIMIT n","mysql":"LIMIT n","mssql":"TOP n / OFFSET-FETCH","mongodb":"$limit: n / .limit(n)","redis":"LRANGE key 0 n-1","elasticsearch":"size: n"}},{"id":"current-user","concept":"Şu anki kullanıcı","engines":{"oracle":"USER / SYS_CONTEXT","postgres":"CURRENT_USER","mysql":"CURRENT_USER() / USER()","mssql":"CURRENT_USER / SUSER_SNAME()","mongodb":"connectionStatus / $$USER (yok, uygulama)","redis":"ACL WHOAMI","elasticsearch":"_security/_authenticate API"}},{"id":"gen-uuid","concept":"UUID üret","engines":{"oracle":"SYS_GUID()","postgres":"gen_random_uuid()","mysql":"UUID()","mssql":"NEWID()","mongodb":"UUID() / ObjectId()","redis":"yok (uygulama tarafında)","elasticsearch":"otomatik _id / uygulama tarafında"}},{"id":"json-extract","concept":"JSON alanı çıkar","engines":{"oracle":"JSON_VALUE(j, '$.a')","postgres":"j->>'a' / j #>> '{a}'","mysql":"JSON_EXTRACT(j, '$.a') / j->>'$.a'","mssql":"JSON_VALUE(j, '$.a')","mongodb":"doc.a (yerel erişim)","redis":"JSON.GET key $.a (RedisJSON)","elasticsearch":"doc['a'] / alan erişimi (yerel)"}},{"id":"regexp","concept":"Düzenli ifade eşleştir (REGEXP)","engines":{"oracle":"REGEXP_LIKE(s, p)","postgres":"s ~ p / REGEXP_MATCHES","mysql":"s REGEXP p / REGEXP_LIKE","mssql":"REGEXP_LIKE (2025+) / öncesi LIKE / CLR","mongodb":"$regex / $regexMatch","redis":"yok (SCAN MATCH glob deseni)","elasticsearch":"regexp query"},"note":"SQL Server 2025 (ve Azure SQL) REGEXP_LIKE, REGEXP_REPLACE, REGEXP_SUBSTR gibi yerel regex fonksiyonları getirdi (REGEXP_LIKE uyumluluk düzeyi 170 ister); önceki sürümlerde LIKE veya CLR fonksiyonu gerekir."}]}]},"reference/params-oracle.json":{"engineId":"oracle","engine":"Oracle","order":1,"params":[{"name":"sga_target","default":"0","recommended":"Adanmış sunucuda RAM'in ~%60'ı","unit":"byte (K/M/G)","dynamic":"dynamic","desc":"Otomatik paylaşımlı bellek yönetimi (ASMM) için toplam SGA boyutunu belirler; alt havuzları otomatik dağıtır.","tags":["memory","bellek","sga"]},{"name":"sga_max_size","default":"sga_target ile aynı","recommended":"sga_target'e eşit veya biraz üstü","unit":"byte (K/M/G)","dynamic":"restart","desc":"SGA'nın çalışma anında büyüyebileceği üst sınırı belirler; artırmak için instance yeniden başlatılmalıdır.","tags":["memory","bellek","sga"]},{"name":"pga_aggregate_target","default":"10M veya SGA'nın %20'si","recommended":"RAM'in ~%20'si","unit":"byte (K/M/G)","dynamic":"dynamic","desc":"Tüm sunucu süreçlerinin kullanacağı toplam hedef PGA belleğini belirler; sıralama ve hash işlemlerini etkiler.","tags":["memory","bellek","pga","sort"]},{"name":"pga_aggregate_limit","default":"En büyüğü: 2G, pga_aggregate_target'in %200'ü, 3M x processes (fiziksel RAM − SGA'nın %120'sini aşmaz)","recommended":"Varsayılan genelde yeterli","unit":"byte (K/M/G)","dynamic":"dynamic","desc":"Örnek genelinde PGA belleği için kesin üst sınır; aşılırsa en çok tüketen oturumların çağrıları iptal edilir (SYS ve arka plan süreçleri hariç). Oracle 12c ile geldi.","tags":["memory","bellek","pga","limit"]},{"name":"memory_target","default":"0","recommended":"0 (SGA/PGA ayrı yönetimi tercih edilir)","unit":"byte (K/M/G)","dynamic":"dynamic","desc":"Otomatik bellek yönetimi (AMM) ile SGA ve PGA'yı tek hedefte birleştirir; büyük sistemlerde önerilmez.","tags":["memory","bellek","amm"]},{"name":"db_cache_size","default":"0 (otomatik)","recommended":"sga_target kullanılıyorsa 0 bırak","unit":"byte (K/M/G)","dynamic":"dynamic","desc":"Varsayılan blok boyutu için buffer cache'in boyutunu belirler; veri bloklarını bellekte tutar.","tags":["memory","bellek","cache","buffer"]},{"name":"shared_pool_size","default":"0 (otomatik)","recommended":"sga_target kullanılıyorsa 0 bırak","unit":"byte (K/M/G)","dynamic":"dynamic","desc":"SQL/PLSQL ayrıştırma sonuçlarını, sözlük önbelleğini ve kütüphane önbelleğini tutan paylaşımlı havuz boyutu.","tags":["memory","bellek","shared","havuz"]},{"name":"processes","default":"100 / 300 (sürüme göre)","recommended":"Beklenen eşzamanlı bağlantıya göre artır","unit":"tam sayı","dynamic":"restart","desc":"Örneğe bağlanabilecek işletim sistemi süreçlerinin azami sayısı; değişimi yeniden başlatma gerektirir.","tags":["connection","baglanti","process","surec"]},{"name":"sessions","default":"processes'ten türetilir (1.5x+22)","recommended":"Varsayılan türetme genelde yeterli","unit":"tam sayı","dynamic":"restart","desc":"Aynı anda oluşturulabilecek azami oturum sayısı; processes değerinden otomatik türetilir.","tags":["connection","baglanti","session","oturum"]},{"name":"open_cursors","default":"50","recommended":"Uygulama ihtiyacına göre 300-1000","unit":"tam sayı","dynamic":"dynamic","desc":"Bir oturumun aynı anda açık tutabileceği azami cursor sayısını belirler.","tags":["cursor","imlec","session","oturum"]},{"name":"cursor_sharing","default":"EXACT","recommended":"EXACT (bind değişkeni kullan)","unit":"EXACT | FORCE","dynamic":"dynamic","desc":"Literal içeren SQL'lerin bind değişkeniyle paylaşılıp paylaşılmayacağını belirler; FORCE sabitleri değiştirir.","tags":["cursor","imlec","sql","parse"]},{"name":"optimizer_mode","default":"ALL_ROWS","recommended":"ALL_ROWS","unit":"ALL_ROWS | FIRST_ROWS_n","dynamic":"dynamic","desc":"Maliyet tabanlı optimize edicinin hedefini belirler; toplam iş hacmi mi yoksa ilk satır yanıtı mı önceliklenir.","tags":["optimizer","optimize","plan","sql"]},{"name":"undo_retention","default":"900","recommended":"En uzun sorgu/flashback süresine göre","unit":"saniye","dynamic":"dynamic","desc":"Commit edilmiş undo verisinin ne kadar süre saklanmaya çalışılacağını belirler; ORA-01555 riskini etkiler.","tags":["undo","geri-alma","retention","flashback"]},{"name":"undo_tablespace","default":"UNDOTBS1","recommended":"Yeterli boyutlu adanmış undo tablespace","unit":"metin (tablespace adı)","dynamic":"dynamic","desc":"Otomatik undo yönetiminde kullanılacak aktif undo tablespace'ini belirler; online değiştirilebilir.","tags":["undo","geri-alma","tablespace"]},{"name":"db_recovery_file_dest_size","default":"0","recommended":"Arşiv+yedek+flashback'i barındıracak boyut","unit":"byte (K/M/G)","dynamic":"dynamic","desc":"Hızlı kurtarma alanının (FRA) azami disk boyutunu belirler; arşiv logları ve yedekleri barındırır.","tags":["recovery","kurtarma","fra","archive"]},{"name":"db_writer_processes","default":"1 veya CPU sayısına göre","recommended":"CPU/8 civarı (yoğun yazma varsa artır)","unit":"tam sayı","dynamic":"restart","desc":"Dirty block'ları diske yazan database writer (DBWn) süreç sayısını belirler; yazma yükünü paralelleştirir.","tags":["io","yazma","dbwr","writer"]},{"name":"parallel_max_servers","default":"parallel_threads_per_cpu x cpu_count x concurrent_parallel_users (1/2/4) x 5; processes − 15 ile sınırlı","recommended":"İş yükü ve CPU sayısına göre ayarla","unit":"tam sayı","dynamic":"dynamic","desc":"Örnekte aynı anda çalışabilecek azami paralel çalıştırma sunucusu (PX) sayısını sınırlar.","tags":["parallel","paralel","px","query"]},{"name":"statistics_level","default":"TYPICAL","recommended":"TYPICAL","unit":"BASIC | TYPICAL | ALL","dynamic":"dynamic","desc":"AWR/ADDM ve otomatik istatistik toplamanın düzeyini belirler; BASIC birçok tanılamayı devre dışı bırakır.","tags":["statistics","istatistik","awr","monitoring"]},{"name":"deferred_segment_creation","default":"TRUE","recommended":"TRUE (boş tablolarda alan tasarrufu)","unit":"TRUE | FALSE","dynamic":"dynamic","desc":"Boş tablo/index için ilk segmentin ilk satır eklenene kadar ertelenmesini sağlar; alan tasarrufu sağlar.","tags":["segment","segment-erteleme","space","storage"]},{"name":"audit_trail","default":"NONE (DBCA ile oluşturulan veritabanında DB)","recommended":"DB veya unified auditing kullan","unit":"NONE | DB | DB,EXTENDED | OS | XML","dynamic":"restart","desc":"Geleneksel denetim kayıtlarının nereye ve nasıl yazılacağını belirler; değişimi yeniden başlatma gerektirir.","tags":["audit","denetim","security","guvenlik"]},{"name":"compatible","default":"Kurulu sürüm (örn 19.0.0)","recommended":"Yeni sürüm özellikleri stabil olunca yükselt","unit":"sürüm dizgisi","dynamic":"restart","desc":"Hangi sürüm özelliklerinin etkin olacağını belirler; yükseltildikten sonra geri alınamaz, yeniden başlatma gerektirir.","tags":["compatible","uyumluluk","version","surum"]},{"name":"db_block_size","default":"8192","recommended":"8K (OLTP); yalnız oluşturma anında ayarlanır","unit":"byte","dynamic":"restart","desc":"Veritabanının standart blok boyutunu belirler; yalnız veritabanı oluşturulurken belirlenir, sonradan değişmez.","tags":["block","blok","storage","io"]},{"name":"filesystemio_options","default":"none (platforma göre)","recommended":"SETALL (Direct + Async I/O)","unit":"none | asynch | directio | setall","dynamic":"restart","desc":"Dosya sistemi üzerindeki datafile'lar için asenkron ve doğrudan (direct) I/O kullanımını denetler.","tags":["io","gc","async","directio"]},{"name":"log_archive_max_processes","default":"4","recommended":"Arşiv/destinasyon sayısına göre artır","unit":"tam sayı","dynamic":"dynamic","desc":"Redo loglarını arşivleyen ARCn süreçlerinin azami sayısını belirler; arşiv gecikmesini azaltmak için artırılır.","tags":["archive","arsiv","redo","log"]}]},"reference/params-postgres.json":{"engineId":"postgres","engine":"PostgreSQL","order":2,"params":[{"name":"shared_buffers","default":"128MB","recommended":"RAM'in ~%25'i","unit":"byte (kB/MB/GB)","dynamic":"restart","desc":"PostgreSQL'in veri bloklarını önbelleğe almak için ayırdığı paylaşımlı bellek miktarı; değişimi yeniden başlatma gerektirir.","tags":["memory","bellek","cache","buffer"]},{"name":"effective_cache_size","default":"4GB","recommended":"RAM'in ~%50-75'i","unit":"byte (kB/MB/GB)","dynamic":"dynamic","desc":"Planlayıcıya işletim sistemi + PostgreSQL önbelleğinin toplam tahmini boyutunu bildirir; index kullanımını etkiler.","tags":["memory","bellek","planner","cache"]},{"name":"work_mem","default":"4MB","recommended":"16-64MB (bağlantı sayısına dikkat)","unit":"byte (kB/MB/GB)","dynamic":"dynamic","desc":"Sıralama ve hash işlemlerinin diske taşmadan kullanabileceği bellek; her sorgu adımı başına ayrılır.","tags":["memory","bellek","sort","query"]},{"name":"maintenance_work_mem","default":"64MB","recommended":"256MB-1GB","unit":"byte (kB/MB/GB)","dynamic":"dynamic","desc":"VACUUM, CREATE INDEX ve ALTER TABLE gibi bakım işlemlerinin kullanabileceği azami belleği belirler.","tags":["memory","bellek","vacuum","maintenance"]},{"name":"max_connections","default":"100","recommended":"100-200 (üstü için havuzlayıcı kullan)","unit":"tam sayı","dynamic":"restart","desc":"Aynı anda kabul edilecek azami istemci bağlantısı sayısı; değişimi yeniden başlatma gerektirir.","tags":["connection","baglanti","limit"]},{"name":"wal_buffers","default":"-1 (shared_buffers'ın 1/32'si)","recommended":"16MB","unit":"byte (kB/MB/GB)","dynamic":"restart","desc":"Diske yazılmadan önce WAL kayıtlarının tutulduğu shared memory buffer'ının boyutunu belirler. -1 (otomatik) değeri en az 64kB, en fazla bir WAL segmenti (genellikle 16MB) ile sınırlanır.","tags":["wal","memory","bellek","buffer"]},{"name":"max_wal_size","default":"1GB","recommended":"İş yüküne göre 4-16GB","unit":"byte (MB/GB)","dynamic":"dynamic","desc":"Otomatik checkpoint tetiklenmeden önce WAL'ın büyüyebileceği yumuşak üst sınırı belirler.","tags":["wal","checkpoint","disk"]},{"name":"min_wal_size","default":"80MB","recommended":"1-2GB","unit":"byte (MB/GB)","dynamic":"dynamic","desc":"WAL dosyalarının geri dönüştürülmek üzere saklandığı alt sınır; sık yeniden ayırmayı azaltır.","tags":["wal","checkpoint","disk"]},{"name":"checkpoint_completion_target","default":"0.9","recommended":"0.9","unit":"oran (0-1)","dynamic":"dynamic","desc":"Checkpoint yazımının, aralık içinde ne kadarlık bölümüne yayılacağını belirler; I/O tepe yüklerini yumuşatır. Varsayılan PG14 ile 0.9 oldu, öncesinde 0.5'ti.","tags":["checkpoint","io","wal"]},{"name":"checkpoint_timeout","default":"5min","recommended":"15-30min","unit":"süre (s/min)","dynamic":"dynamic","desc":"Otomatik checkpoint'ler arasındaki azami süreyi belirler; artırmak yazma yükünü azaltır ama kurtarma süresini uzatır.","tags":["checkpoint","wal","recovery"]},{"name":"random_page_cost","default":"4.0","recommended":"SSD için 1.1","unit":"ondalık","dynamic":"dynamic","desc":"Rastgele disk erişiminin planlayıcıya göreli maliyetini belirler; SSD'de düşürmek index taramalarını teşvik eder.","tags":["planner","optimize","io","index"]},{"name":"effective_io_concurrency","default":"1","recommended":"SSD için 200","unit":"tam sayı","dynamic":"dynamic","desc":"Diskin aynı anda hizmet verebileceği tahmini eşzamanlı I/O işlemi sayısı; bitmap taramalarında ön okumayı etkiler. Varsayılan PG17 ve öncesinde 1, PG18 ile 16'dır.","tags":["io","gc","ssd","prefetch"]},{"name":"default_statistics_target","default":"100","recommended":"100 (büyük tablolarda kolonda artır)","unit":"tam sayı","dynamic":"dynamic","desc":"ANALYZE'ın toplayacağı istatistik ayrıntı düzeyini belirler; artırmak plan doğruluğunu ve analiz süresini artırır.","tags":["statistics","istatistik","analyze","planner"]},{"name":"autovacuum","default":"on","recommended":"on","unit":"on | off","dynamic":"dynamic","desc":"Dead tuple'ları temizleyen ve istatistik toplayan otomatik vacuum sürecini açar; kapatılması bloat'a yol açar.","tags":["autovacuum","vacuum","bakim","bloat"]},{"name":"autovacuum_vacuum_scale_factor","default":"0.2","recommended":"Büyük tablolarda 0.05-0.1","unit":"oran (0-1)","dynamic":"dynamic","desc":"Bir tablonun vacuum edilmesi için değişmesi gereken satır oranını belirler; düşürmek büyük tabloları sık temizler.","tags":["autovacuum","vacuum","bloat","bakim"]},{"name":"autovacuum_max_workers","default":"3","recommended":"3-6 (çok tablolu sistemlerde artır)","unit":"tam sayı","dynamic":"restart","desc":"Aynı anda çalışabilecek azami autovacuum işçi süreci sayısını belirler; PG17 ve öncesinde değişimi yeniden başlatma gerektirir. PG18'de autovacuum_worker_slots sınırına kadar reload ile değiştirilebilir.","tags":["autovacuum","vacuum","worker","bakim"]},{"name":"synchronous_commit","default":"on","recommended":"on (kritik veri); off (performans önceliği)","unit":"on | off | local | remote_write | remote_apply","dynamic":"dynamic","desc":"Commit'in WAL diske yazılmasını bekleyip beklemeyeceğini belirler; off çökme anında küçük veri kaybı riski taşır.","tags":["wal","commit","durability","performans"]},{"name":"wal_level","default":"replica","recommended":"replica (replikasyon/PITR için)","unit":"minimal | replica | logical","dynamic":"restart","desc":"WAL'a yazılan bilgi miktarını belirler; replikasyon ve mantıksal çoğaltma için gereklidir, değişimi restart ister.","tags":["wal","replication","replikasyon","pitr"]},{"name":"max_wal_senders","default":"10","recommended":"Standby + yedek sayısına göre","unit":"tam sayı","dynamic":"restart","desc":"Aynı anda WAL akışı gönderebilecek azami süreç sayısını (standby'lar ve yedekler için) belirler.","tags":["wal","replication","replikasyon","standby"]},{"name":"wal_keep_size","default":"0","recommended":"Standby gecikmesini karşılayacak boyut","unit":"byte (MB/GB)","dynamic":"dynamic","desc":"Standby'ler için pg_wal içinde saklanacak asgari WAL boyutu; replication slot yoksa gecikmiş standby'yi korur. PG13 ile geldi; öncesinde wal_keep_segments (segment sayısı) kullanılırdı.","tags":["wal","replication","replikasyon","standby"]},{"name":"log_min_duration_statement","default":"-1 (kapalı)","recommended":"Yavaş sorguları yakalamak için 1000ms","unit":"milisaniye","dynamic":"dynamic","desc":"Belirtilen süreden uzun süren sorguları loga yazar; yavaş sorgu tespiti için kullanılır, -1 kapatır.","tags":["logging","log","slow-query","yavas-sorgu"]},{"name":"idle_in_transaction_session_timeout","default":"0 (kapalı)","recommended":"Lock tutmayı önlemek için 60000ms","unit":"milisaniye","dynamic":"dynamic","desc":"Açık transaction içinde belirtilen süre boyunca boşta kalan oturumları sonlandırır; lock ve bloat riskini azaltır.","tags":["timeout","transaction","islem","lock"]},{"name":"statement_timeout","default":"0 (kapalı)","recommended":"Uygulamaya göre (OLTP'de düşük)","unit":"milisaniye","dynamic":"dynamic","desc":"Belirtilen süreyi aşan sorguları otomatik iptal eder; kaçak sorguların kaynak tüketmesini önler.","tags":["timeout","query","sorgu","limit"]},{"name":"shared_preload_libraries","default":"'' (boş)","recommended":"pg_stat_statements (izleme için)","unit":"metin (virgülle liste)","dynamic":"restart","desc":"Sunucu başlangıcında yüklenecek paylaşımlı kütüphaneleri belirler; pg_stat_statements gibi eklentiler burada tanımlanır.","tags":["extension","eklenti","preload","monitoring"]},{"name":"max_parallel_workers_per_gather","default":"2","recommended":"2-4 (CPU sayısına göre)","unit":"tam sayı","dynamic":"dynamic","desc":"Tek bir Gather/GatherMerge düğümünün başlatabileceği azami paralel işçi sayısını belirler; 0 paralelliği kapatır.","tags":["parallel","paralel","worker","query"]}]},"reference/params-mysql.json":{"engineId":"mysql","engine":"MySQL","order":3,"params":[{"name":"innodb_buffer_pool_size","default":"128MB","recommended":"Adanmış sunucuda RAM'in ~%70-80'i","unit":"byte (M/G)","dynamic":"dynamic","desc":"InnoDB'nin veri ve index'leri önbelleğe aldığı ana bellek havuzu; 8.0'da online değişir ama büyük değişimde dikkat gerekir.","tags":["memory","bellek","innodb","buffer"]},{"name":"innodb_buffer_pool_instances","default":"1 (veya boyut>1GB ise 8)","recommended":"Büyük havuzlarda 8","unit":"tam sayı","dynamic":"restart","desc":"Buffer pool'un bölündüğü örnek sayısını belirler; eşzamanlılıkta lock çekişmesini azaltır, değişimi restart ister.","tags":["memory","bellek","innodb","concurrency"]},{"name":"innodb_redo_log_capacity","default":"100MB (8.0.30+)","recommended":"1-8GB (yazma yüküne göre; tepe saatte ~1 saatlik redo)","unit":"byte (M/G)","dynamic":"dynamic","desc":"InnoDB redo log'un toplam diskte kapladığı alanı belirler; büyütmek checkpoint baskısını ve yazma tepe yükünü yumuşatır. MySQL 8.0.30 ile geldi ve SET GLOBAL/SET PERSIST ile restart'sız değişir. Eski innodb_log_file_size (varsayılan 48MB) ve innodb_log_files_in_group 8.0.30'dan beri deprecated'dır; 8.0.30 öncesinde redo boyutu bu ikisiyle ayarlanır ve restart gerektirir.","tags":["innodb","redo","log","io"]},{"name":"innodb_flush_log_at_trx_commit","default":"1","recommended":"1 (tam ACID); 2 (performans)","unit":"0 | 1 | 2","dynamic":"dynamic","desc":"Her commit'te redo log'un diske yazılıp senkronize edilip edilmeyeceğini belirler; 1 tam dayanıklılık, 2/0 kayıp riski taşır.","tags":["innodb","commit","durability","acid"]},{"name":"innodb_flush_method","default":"8.0: fsync (Linux) / 8.4: O_DIRECT (destekleniyorsa); Windows: unbuffered","recommended":"O_DIRECT (Linux)","unit":"fsync | O_DIRECT | O_DIRECT_NO_FSYNC","dynamic":"restart","desc":"InnoDB'nin veri ve log dosyalarını diske nasıl boşalttığını belirler; O_DIRECT çift önbelleklemeyi önler, değişimi restart ister.","tags":["innodb","io","flush","gc"]},{"name":"innodb_io_capacity","default":"8.0: 200 / 8.4: 10000","recommended":"Depolamanın gerçek IOPS'una göre (8.0'da SSD için 1000-2000)","unit":"tam sayı (IOPS)","dynamic":"dynamic","desc":"InnoDB'nin arka plan işlemlerinin (flush, merge) kullanacağı tahmini disk IOPS kapasitesini belirler. MySQL 8.4'te varsayılanlar innodb_io_capacity=10000 ve innodb_io_capacity_max=20000 olarak yükseltildi (8.0'da 200/2000).","tags":["innodb","io","iops","ssd"]},{"name":"innodb_read_io_threads","default":"8.0: 4 / 8.4: mantıksal CPU sayısının yarısı (en az 4)","recommended":"4-8 (okuma yüküne göre)","unit":"tam sayı","dynamic":"restart","desc":"InnoDB'de okuma I/O isteklerini işleyen arka plan thread sayısını belirler; değişimi restart gerektirir.","tags":["innodb","io","thread","okuma"]},{"name":"innodb_write_io_threads","default":"4","recommended":"4-8 (yazma yüküne göre)","unit":"tam sayı","dynamic":"restart","desc":"InnoDB'de yazma I/O isteklerini işleyen arka plan thread sayısını belirler; değişimi restart gerektirir.","tags":["innodb","io","thread","yazma"]},{"name":"max_connections","default":"151","recommended":"İş yüküne göre 200-500","unit":"tam sayı","dynamic":"dynamic","desc":"Aynı anda izin verilen azami istemci bağlantısı sayısını belirler; online değiştirilebilir.","tags":["connection","baglanti","limit"]},{"name":"thread_cache_size","default":"-1 (otomatik)","recommended":"Otomatik; yoğun kısa bağlantıda artır","unit":"tam sayı","dynamic":"dynamic","desc":"Yeniden kullanım için önbellekte tutulan thread sayısını belirler; yeni bağlantılarda parçacık oluşturmayı azaltır.","tags":["connection","baglanti","thread","cache"]},{"name":"table_open_cache","default":"4000","recommended":"Açık tablo sayısına göre 4000-8000","unit":"tam sayı","dynamic":"dynamic","desc":"Tüm thread'ler için açık tablo tanıtıcılarının önbellek boyutunu belirler; tablo yeniden açma yükünü azaltır.","tags":["cache","table","tablo","open"]},{"name":"tmp_table_size","default":"16MB","recommended":"64-256MB","unit":"byte (M/G)","dynamic":"dynamic","desc":"Bellek içi geçici tablonun diske dönüşmeden önceki azami boyutunu belirler; max_heap_table_size ile birlikte etki eder.","tags":["memory","bellek","temp","gecici"]},{"name":"max_heap_table_size","default":"16MB","recommended":"tmp_table_size ile aynı","unit":"byte (M/G)","dynamic":"dynamic","desc":"MEMORY motoru tablolarının ve bellek içi geçici tabloların büyüyebileceği azami boyutu belirler.","tags":["memory","bellek","temp","heap"]},{"name":"sort_buffer_size","default":"256KB","recommended":"256KB-2MB (bağlantı başına dikkat)","unit":"byte (K/M)","dynamic":"dynamic","desc":"ORDER BY ve GROUP BY sıralamaları için her oturuma ayrılan buffer boyutu; aşırı büyütmek bellek tüketir.","tags":["memory","bellek","sort","buffer"]},{"name":"join_buffer_size","default":"256KB","recommended":"256KB-1MB (index ile çözmeyi tercih et)","unit":"byte (K/M)","dynamic":"dynamic","desc":"Index'siz join taramaları için her oturuma ayrılan buffer boyutu; kalıcı çözüm uygun index eklemektir.","tags":["memory","bellek","join","buffer"]},{"name":"sync_binlog","default":"1","recommended":"1 (tam güvenlik); yüksek yükte 100-1000","unit":"tam sayı","dynamic":"dynamic","desc":"Binary log'un kaç commit'te bir diske senkronize edileceğini belirler; 1 en güvenli, yüksek değer performans/kayıp dengesidir.","tags":["binlog","replication","durability","commit"]},{"name":"binlog_expire_logs_seconds","default":"2592000 (30 gün)","recommended":"Yedek/replikasyon penceresine göre","unit":"saniye","dynamic":"dynamic","desc":"Binary log dosyalarının otomatik silinmeden önce saklanacağı süreyi belirler; disk kullanımını denetler.","tags":["binlog","log","retention","replication"]},{"name":"long_query_time","default":"10","recommended":"1 (yavaş sorguları yakala)","unit":"saniye","dynamic":"dynamic","desc":"Bir sorgunun yavaş sorgu loguna kaydedilmesi için aşması gereken süreyi belirler; ondalık değer alabilir.","tags":["slow-query","yavas-sorgu","log","performans"]},{"name":"slow_query_log","default":"OFF","recommended":"ON (tanılama için)","unit":"ON | OFF","dynamic":"dynamic","desc":"long_query_time'ı aşan sorguların yavaş sorgu loguna yazılıp yazılmayacağını denetler; performans analizi için açılır.","tags":["slow-query","yavas-sorgu","log","monitoring"]},{"name":"wait_timeout","default":"28800 (8 saat)","recommended":"Uygulama havuzuna göre (örn 600)","unit":"saniye","dynamic":"dynamic","desc":"Etkileşimsiz bir bağlantının kapatılmadan önce boşta bekleyebileceği azami süreyi belirler; boşta bağlantıları temizler.","tags":["timeout","connection","baglanti","idle"]},{"name":"max_allowed_packet","default":"64MB","recommended":"Büyük BLOB/satır için 64-256MB","unit":"byte (M/G)","dynamic":"dynamic","desc":"Tek bir paketin veya oluşturulan/ara satırın azami boyutunu belirler; büyük BLOB aktarımlarında artırılır.","tags":["packet","paket","blob","network"]},{"name":"innodb_lock_wait_timeout","default":"50","recommended":"OLTP için 10-50","unit":"saniye","dynamic":"dynamic","desc":"Bir InnoDB işleminin row lock beklerken zaman aşımına uğramadan önce bekleyeceği süreyi belirler.","tags":["innodb","lock","kilit","timeout"]},{"name":"character_set_server","default":"utf8mb4","recommended":"utf8mb4","unit":"metin (karakter seti)","dynamic":"dynamic","desc":"Sunucunun varsayılan karakter setini belirler; utf8mb4 tam Unicode (emoji dahil) desteği sağlar.","tags":["charset","karakter-seti","unicode","utf8mb4"]}]},"reference/params-mssql.json":{"engineId":"mssql","engine":"SQL Server","order":4,"params":[{"name":"max server memory (MB)","default":"2147483647","recommended":"Toplam RAM - OS ve diğer servisler için ayrılan pay (~%10-25)","unit":"MB","dynamic":"dynamic","desc":"SQL Server buffer pool ve diğer bellek tüketicilerinin kullanabileceği azami bellek miktarını belirler. Varsayılan değer sınırsıza yakındır; sunucuda başka servisler varsa işletim sistemine yeterli bellek bırakmak için mutlaka düşürülmelidir. sp_configure ile ayarlanır ve RECONFIGURE ile anında etkinleşir.","tags":["memory","bellek","buffer pool"]},{"name":"min server memory (MB)","default":"0","recommended":"Kritik örneklerde max değerin makul bir alt sınırı","unit":"MB","dynamic":"dynamic","desc":"SQL Server'ın ayırdıktan sonra işletim sistemine geri vermeyeceği asgari bellek miktarıdır. Bellek baskısı altında SQL Server'ın çok fazla bellek bırakmasını önlemek için kullanılır. sp_configure ile ayarlanır ve RECONFIGURE ile geçerli olur.","tags":["memory","bellek"]},{"name":"max degree of parallelism","default":"0","recommended":"Genelde 8 veya NUMA düğümündeki fiziksel çekirdek sayısı","unit":"adet","dynamic":"dynamic","desc":"Tek bir sorgunun paralel yürütmede kullanabileceği azami işlemci (çekirdek) sayısını sınırlar. 0 değeri tüm çekirdeklerin kullanılabileceği anlamına gelir; OLTP yüklerinde aşırı paralellikten kaçınmak için sınırlandırılır. sp_configure + RECONFIGURE ile anında etkilidir.","tags":["parallelism","paralellik","maxdop","cpu"]},{"name":"cost threshold for parallelism","default":"5","recommended":"Modern donanımda 25-50 arası","unit":"maliyet","dynamic":"dynamic","desc":"Bir sorgu planının paralel çalıştırılması için gereken asgari tahmini maliyet eşiğidir. Varsayılan 5 çok düşüktür ve küçük sorguların gereksiz yere paralelleşmesine yol açar; değeri artırmak sunucu genelinde paralellik davranışını iyileştirir. sp_configure + RECONFIGURE ile anında geçerlidir.","tags":["parallelism","paralellik","cpu"]},{"name":"max worker threads","default":"0","recommended":"0 (SQL Server otomatik hesaplasın)","unit":"adet","dynamic":"dynamic","desc":"SQL Server'ın istemci isteklerini işlemek için oluşturabileceği azami worker thread sayısını belirler. 0 değeri işlemci sayısına ve mimariye göre otomatik hesaplama yapılmasını sağlar. Gelişmiş (advanced) bir seçenektir; sp_configure + RECONFIGURE ile restart gerektirmeden uygulanır (sys.configurations.is_dynamic = 1).","tags":["threads","worker","cpu","concurrency"]},{"name":"optimize for ad hoc workloads","default":"0","recommended":"1 (açık)","unit":"0/1","dynamic":"dynamic","desc":"Yalnızca bir kez çalışan ad hoc sorgular için ilk çalıştırmada tam plan yerine küçük bir plan taslağı (stub) önbelleğe alınmasını sağlar. Plan önbelleğinin tek kullanımlık planlarla dolmasını önler ve bellek kullanımını iyileştirir. sp_configure + RECONFIGURE ile anında etkilidir.","tags":["plan cache","memory","bellek"]},{"name":"backup compression default","default":"0","recommended":"1 (açık)","unit":"0/1","dynamic":"dynamic","desc":"Yeni yedeklerin varsayılan olarak sıkıştırılmasını sağlar. Sıkıştırma yedek boyutunu ve yedekleme süresini önemli ölçüde azaltır, karşılığında bir miktar CPU tüketir. sp_configure + RECONFIGURE ile anında geçerlidir.","tags":["backup","yedek","compression","sıkıştırma"]},{"name":"fill factor (%)","default":"0","recommended":"0 veya 90-100 (iş yüküne göre)","unit":"%","dynamic":"restart","desc":"Index oluşturulurken veya yeniden inşa edilirken (REBUILD) yaprak seviyesindeki sayfaların ne kadar doldurulacağını yüzde olarak belirler. 0 ve 100 sayfaları tamamen doldurur; düşük değerler page split'leri azaltır ancak disk ve bellek kullanımını artırır. Sunucu düzeyindeki varsayılan sp_configure ile değiştirilir ancak servis yeniden başlatılana kadar etkinleşmez (is_dynamic = 0); index bazında FILLFACTOR seçeneği ise anında kullanılabilir.","tags":["index","indeks","storage","depolama"]},{"name":"recovery interval (min)","default":"0","recommended":"0 (otomatik)","unit":"dakika","dynamic":"dynamic","desc":"Otomatik checkpoint sıklığını, kurtarma için hedeflenen azami süre cinsinden belirler. 0 değeri SQL Server'ın veritabanı bazında hedef kurtarma süresini otomatik yönetmesini sağlar. sp_configure + RECONFIGURE ile anında etkilidir.","tags":["checkpoint","recovery","kurtarma"]},{"name":"remote query timeout (s)","default":"600","recommended":"İş yüküne göre 600 veya 0 (sınırsız)","unit":"saniye","dynamic":"dynamic","desc":"Uzak sorgular (linked server üzerinden) için sunucunun yanıt beklerken zaman aşımına uğramadan önce bekleyeceği süredir. 0 değeri sınırsız beklemeyi ifade eder. sp_configure + RECONFIGURE ile anında geçerlidir.","tags":["timeout","remote","linked server"]},{"name":"network packet size (B)","default":"4096","recommended":"4096 (özel durumlar dışında değiştirmeyin)","unit":"bayt","dynamic":"dynamic","desc":"Ağ üzerinden veri aktarımında kullanılan paket boyutudur. Çok büyük veri aktaran özel toplu işlemler dışında varsayılan değer önerilir; yanlış ayar performansı düşürebilir. sp_configure + RECONFIGURE ile geçerlidir.","tags":["network","ağ","packet"]},{"name":"database compatibility level (ALTER DATABASE)","default":"Sunucu sürümüne göre","recommended":"Test edilmiş en güncel seviye","unit":"seviye","dynamic":"dynamic","desc":"Bir veritabanının hangi SQL Server sürümü davranışlarıyla ve sorgu iyileştirici modeliyle çalışacağını belirler. ALTER DATABASE ... SET COMPATIBILITY_LEVEL komutuyla veritabanı bazında ayarlanır ve anında geçerli olur; kardinalite tahmini gibi iyileştirici özelliklerini etkiler.","tags":["database","veritabanı","optimizer","uyumluluk"]},{"name":"MAXDOP (database scoped configuration)","default":"0 (sunucu ayarını miras alır)","recommended":"Veritabanı iş yüküne göre uygun değer","unit":"adet","dynamic":"dynamic","desc":"Sunucu genelindeki max degree of parallelism ayarını veritabanı seviyesinde geçersiz kılmayı sağlar. ALTER DATABASE SCOPED CONFIGURATION SET MAXDOP komutuyla ayarlanır ve anında geçerli olur; farklı veritabanları için farklı paralellik davranışı tanımlamaya olanak tanır.","tags":["parallelism","paralellik","maxdop","database scoped"]},{"name":"tempdb dosya sayısı (öneri)","default":"SQL Server 2016+ kurulumu: mantıksal çekirdek sayısı kadar, en fazla 8 (öncesinde 1)","recommended":"Mantıksal çekirdek sayısı kadar, en fazla 8 (gerekirse 4'er artır)","unit":"adet","dynamic":"dynamic","desc":"tempdb veritabanının data file sayısı, ayırma sayfası çekişmesini (allocation contention) azaltmak için önemlidir. Genel öneri, çekirdek sayısına kadar (azami 8) eşit boyutlu dosya kullanmaktır. ALTER DATABASE tempdb ADD FILE ile eklenen dosya restart gerektirmeden hemen kullanılmaya başlar; ancak mevcut dosyalar doluysa proportional fill dengesi için tüm dosyaları eşit boyuta getirin. tempdb dosyası kaldırmak (REMOVE FILE) çoğu zaman dosya boşalmadığından restart sonrasında mümkün olur.","tags":["tempdb","storage","depolama","contention"]},{"name":"Trace Flag 1117 / 1118 (not)","default":"SQL 2016+ tempdb için varsayılan davranış","recommended":"SQL 2016+ genelde gereksiz; eski sürümlerde açık","unit":"bayrak","dynamic":"restart","desc":"TF 1117 bir dosya grubundaki tüm dosyaların birlikte büyümesini, TF 1118 ise karışık extent yerine tam extent ayrımını zorlar. SQL Server 2016 ve sonrasında bu davranışlar tempdb için varsayılan hale geldiğinden bayraklar genellikle gereksizdir. Başlangıç bayrağı olarak eklendiğinde yeniden başlatma gerektirir.","tags":["trace flag","tempdb","not"]},{"name":"Trace Flag 3226","default":"Kapalı","recommended":"Açık (başarılı yedek bildirimlerini bastırır)","unit":"bayrak","dynamic":"dynamic","desc":"Başarılı yedekleme işlemlerinin SQL Server error log'una ve Windows Event Log'a yazılmasını engeller. Sık log yedekleri alan sistemlerde log'ların gereksiz bildirimlerle dolmasını (log spam) önler. Çalışırken DBCC TRACEON(3226, -1) ile hemen açılabilir; restart sonrası kalıcı olması için -T3226 başlangıç parametresi olarak da eklenmelidir.","tags":["trace flag","backup","yedek","log"]},{"name":"lock pages in memory (Windows ilkesi notu)","default":"Kapalı","recommended":"Belirli senaryolarda hizmet hesabına verilir","unit":"ilke","dynamic":"restart","desc":"SQL Server hizmet hesabının bellek sayfalarının işletim sistemi tarafından diske sayfalanmasını (paging) önlemesine izin veren bir Windows kullanıcı hakkı ilkesidir. Bellek baskısı altında performans dalgalanmalarını azaltabilir ancak dikkatli yapılandırılmalıdır. İlke değişikliği için hizmetin yeniden başlatılması gerekir.","tags":["memory","bellek","windows","policy","not"]}]},"reference/params-mongodb.json":{"engineId":"mongodb","engine":"MongoDB","order":5,"params":[{"name":"storage.wiredTiger.engineConfig.cacheSizeGB","default":"(RAM - 1GB) * 0.5","recommended":"Varsayılanı bırakın veya kullanılabilir RAM'in ~%50'si","unit":"GB","dynamic":"restart","desc":"WiredTiger depolama motorunun iç önbelleği için ayrılan bellek miktarını gigabayt cinsinden belirler. Varsayılan olarak (toplam RAM - 1GB) değerinin yarısı kullanılır. Değeri elle ayarlamak yalnızca özel durumlarda gerekir ve mongod'un yeniden başlatılmasını ister.","tags":["memory","bellek","cache","wiredtiger"]},{"name":"net.maxIncomingConnections","default":"1000000 (fiilen OS sınırlarıyla kısıtlı)","recommended":"İş yüküne ve işletim sistemi ulimit değerine göre","unit":"adet","dynamic":"restart","desc":"mongod veya mongos örneğinin kabul edeceği azami eşzamanlı gelen bağlantı sayısını sınırlar. Değer işletim sisteminin dosya tanıtıcısı/bağlantı sınırından (ulimit) yüksekse etkisi olmaz; fiilî üst sınırı OS belirler (db.serverStatus().connections içindeki current + available ile görülebilir). Değişiklik yapılandırma dosyasında güncellenir ve yeniden başlatma gerektirir.","tags":["network","ağ","connections","bağlantı"]},{"name":"operationProfiling.slowOpThresholdMs","default":"100","recommended":"İş yüküne göre 100 veya daha düşük","unit":"ms","dynamic":"dynamic","desc":"Bir işlemin yavaş sayılıp profiler'a ve log'a kaydedilmesi için gereken süre eşiğini milisaniye cinsinden belirler. Bu eşiği aşan işlemler tanılamayı kolaylaştırmak için kayıt altına alınır. db.setProfilingLevel() ile çalışırken anında değiştirilebilir.","tags":["profiling","slow query","yavaş sorgu","monitoring"]},{"name":"replication.oplogSizeMB","default":"Disk boyutunun ~%5'i (azami 50GB)","recommended":"Bakım penceresini karşılayacak kadar büyük","unit":"MB","dynamic":"dynamic","desc":"Replica set üyelerinde işlemleri saklayan oplog koleksiyonunun azami boyutunu megabayt cinsinden belirler. Yeterince büyük bir oplog, geride kalan üyelerin tam senkronizasyona ihtiyaç duymadan yakalanmasına olanak tanır. Çalışan replica set'te replSetResizeOplog komutuyla anında değiştirilebilir.","tags":["replication","oplog","replica set"]},{"name":"security.authorization","default":"disabled","recommended":"enabled (rol tabanlı erişim denetimi)","unit":"enabled/disabled","dynamic":"restart","desc":"Rol tabanlı erişim denetimini (RBAC) etkinleştirir; etkin olduğunda istemcilerin kimlik doğrulaması yapması ve yetkilendirilmesi gerekir. Üretim ortamlarında mutlaka etkinleştirilmelidir. Yapılandırma dosyasında ayarlanır ve yeniden başlatma gerektirir.","tags":["security","güvenlik","authorization","yetkilendirme","rbac"]},{"name":"net.compression.compressors","default":"snappy,zstd,zlib","recommended":"snappy,zstd (varsayılan uygundur)","unit":"liste","dynamic":"restart","desc":"İstemci ve küme içi ağ trafiğinde kullanılabilecek sıkıştırma algoritmalarını ve tercih sırasını belirler. Ağ bant genişliği kullanımını azaltırken bir miktar CPU maliyeti getirir. Yapılandırma dosyasında ayarlanır ve yeniden başlatma gerektirir.","tags":["network","ağ","compression","sıkıştırma"]},{"name":"storage.wiredTiger.collectionConfig.blockCompressor","default":"snappy","recommended":"snappy (hız) veya zstd (yüksek sıkıştırma)","unit":"algoritma","dynamic":"restart","desc":"WiredTiger'ın koleksiyon verilerini diske yazarken kullandığı blok sıkıştırma algoritmasını belirler. snappy hız, zlib ve zstd ise daha yüksek sıkıştırma oranı sağlar. Yalnızca ayardan sonra oluşturulan koleksiyonlara uygulanır ve yeniden başlatma gerektirir.","tags":["storage","depolama","compression","sıkıştırma","wiredtiger"]},{"name":"storage.directoryPerDB","default":"false","recommended":"Diskleri ayırmak isteniyorsa true","unit":"true/false","dynamic":"restart","desc":"Her veritabanının verilerinin ayrı bir alt dizinde saklanmasını sağlar; bu sayede farklı veritabanları farklı disk birimlerine yerleştirilebilir. Yalnızca boş bir veri dizininde etkinleştirilebilir. Değişiklik yapılandırma dosyasında yapılır ve yeniden başlatma gerektirir.","tags":["storage","depolama","directory"]},{"name":"setParameter.cursorTimeoutMillis","default":"600000","recommended":"İş yüküne göre varsayılan (10 dakika)","unit":"ms","dynamic":"dynamic","desc":"Kullanılmayan (idle) cursor'ların sunucu tarafından otomatik olarak kapatılmadan önce bekleyeceği süreyi milisaniye cinsinden belirler. Terk edilmiş cursor'ların kaynak tüketmesini önler. db.adminCommand({setParameter:1}) ile çalışırken anında değiştirilebilir.","tags":["cursor","timeout","setparameter"]},{"name":"setParameter.transactionLifetimeLimitSeconds","default":"60","recommended":"Uzun işlemler gerekmedikçe varsayılan","unit":"saniye","dynamic":"dynamic","desc":"Çok belgeli bir transaction'ın otomatik olarak iptal edilmeden önce açık kalabileceği azami süreyi saniye cinsinden belirler. Uzun süren transaction'ların kaynakları ve WiredTiger önbelleğini kilitlemesini önler. setParameter ile anında değiştirilebilir.","tags":["transaction","işlem","setparameter"]},{"name":"setParameter.maxTransactionLockRequestTimeoutMillis","default":"5","recommended":"Lock çekişmesi durumuna göre varsayılan","unit":"ms","dynamic":"dynamic","desc":"Bir transaction'ın ihtiyaç duyduğu lock'u elde etmek için beklerken zaman aşımına uğramadan önce bekleyeceği azami süreyi milisaniye cinsinden belirler. Lock bekleme davranışını ayarlayarak transaction'ların çok uzun süre engellenmesini önler. setParameter ile anında değiştirilebilir.","tags":["transaction","lock","kilit","setparameter"]},{"name":"net.tls.mode","default":"disabled","recommended":"requireTLS (üretimde)","unit":"mod","dynamic":"restart","desc":"Sunucunun TLS/SSL şifreli bağlantı kullanımını belirler. requireTLS tüm bağlantıların şifreli olmasını zorlar; preferTLS ve allowTLS geçiş dönemleri için ara modlar sunar. Sertifika yapılandırmasıyla birlikte kullanılır ve yeniden başlatma gerektirir.","tags":["security","güvenlik","tls","ssl","encryption"]},{"name":"storage.syncPeriodSecs","default":"60","recommended":"60 (varsayılanı değiştirmeyin)","unit":"saniye","dynamic":"dynamic","desc":"WiredTiger'ın checkpoint alma sıklığını, yani bellek içindeki verilerin diske eşitlenmesi arasındaki süreyi saniye cinsinden belirler. Varsayılan değer çoğu iş yükü için uygundur ve değiştirilmesi genellikle önerilmez. Yapılandırma dosyasında ayarlanır; çalışırken db.adminCommand({ setParameter: 1, syncdelay: <saniye> }) ile yeniden başlatmadan da değiştirilebilir.","tags":["storage","depolama","checkpoint","sync"]},{"name":"replication.enableMajorityReadConcern","default":"true","recommended":"true (5.0+ sürümlerde değiştirilemez)","unit":"true/false","dynamic":"restart","desc":"Çoğunluk (majority) okuma ilgisi düzeyinin kullanılmasına izin verir; bu düzey, çoğunluk üyeye yazılmış ve geri alınmayacak verilerin okunmasını garanti eder. MongoDB 5.0'dan itibaren bu ayar değiştirilemez ve her zaman true'dur; eski sürümlerde (ör. PSA mimarisinde) false yapılabiliyordu. Yapılandırma dosyasında ayarlanır ve yeniden başlatma gerektirir.","tags":["replication","read concern","replica set"]},{"name":"processManagement.fork","default":"false","recommended":"Systemd kullanılıyorsa false, elle daemon için true","unit":"true/false","dynamic":"restart","desc":"mongod sürecinin arka planda bir daemon olarak çatallanıp (fork) çalışmasını sağlar. systemd veya benzeri servis yöneticileri kullanılıyorsa bu genellikle false bırakılır çünkü süreç yönetimini servis yöneticisi üstlenir. Yapılandırma dosyasında ayarlanır ve başlangıç davranışını etkiler.","tags":["process","süreç","daemon","fork"]}]},"reference/params-redis.json":{"engineId":"redis","engine":"Redis","order":6,"params":[{"name":"maxmemory","default":"0 (sınırsız)","recommended":"Fiziksel RAM'in ~%70-75'i","unit":"bayt","dynamic":"dynamic","desc":"Redis'in veri için kullanabileceği azami bellek miktarını belirler. 0 değeri sınırsız kullanım anlamına gelir ve bellek yetersizliğine yol açabilir; bir sınır belirlemek şiddetle önerilir. CONFIG SET maxmemory komutuyla anında değiştirilebilir.","tags":["memory","bellek"]},{"name":"maxmemory-policy","default":"noeviction","recommended":"Önbellek için allkeys-lru, aksi halde noeviction","unit":"politika","dynamic":"dynamic","desc":"maxmemory sınırına ulaşıldığında Redis'in hangi anahtarları nasıl temizleyeceğini (eviction) belirleyen politikadır. noeviction yazma hatası döndürürken allkeys-lru en az kullanılan anahtarları siler. CONFIG SET ile anında değiştirilebilir.","tags":["memory","bellek","eviction","cache"]},{"name":"maxclients","default":"10000","recommended":"İş yüküne ve OS ulimit değerine göre","unit":"adet","dynamic":"dynamic","desc":"Aynı anda kabul edilecek azami istemci bağlantısı sayısını belirler. İşletim sisteminin dosya tanıtıcısı sınırı bu değeri sınırlayabilir. CONFIG SET maxclients komutuyla anında değiştirilebilir.","tags":["connections","bağlantı","clients"]},{"name":"appendonly","default":"no","recommended":"Kalıcılık gerekiyorsa yes","unit":"yes/no","dynamic":"dynamic","desc":"AOF (Append Only File) kalıcılık mekanizmasını etkinleştirir; etkin olduğunda her yazma işlemi AOF log dosyasına eklenir. RDB snapshot'larına göre daha az veri kaybı riski sunar. CONFIG SET appendonly yes komutuyla anında etkinleştirilebilir.","tags":["persistence","kalıcılık","aof"]},{"name":"appendfsync","default":"everysec","recommended":"everysec (denge)","unit":"politika","dynamic":"dynamic","desc":"AOF dosyasının diske eşitlenme (fsync) sıklığını belirler. always her yazmada eşitler ve en güvenlidir ancak yavaştır; everysec saniyede bir eşitleyerek performans ile dayanıklılık arasında denge kurar; no eşitlemeyi işletim sistemine bırakır. CONFIG SET ile anında değiştirilebilir.","tags":["persistence","kalıcılık","aof","fsync"]},{"name":"save","default":"3600 1 300 100 60 10000","recommended":"İş yüküne göre veya devre dışı (yalnızca AOF)","unit":"kural","dynamic":"dynamic","desc":"RDB snapshot'ının hangi koşullarda (belirli sürede belirli sayıda değişiklik) diske kaydedileceğini tanımlar. Boş bir değer ayarlamak RDB snapshot'larını tamamen devre dışı bırakır. CONFIG SET save komutuyla anında değiştirilebilir.","tags":["persistence","kalıcılık","rdb","snapshot"]},{"name":"tcp-keepalive","default":"300","recommended":"300 (varsayılan uygundur)","unit":"saniye","dynamic":"dynamic","desc":"Redis'in istemci bağlantılarına TCP keepalive ACK'leri gönderme aralığını saniye cinsinden belirler. Ölü bağlantıların tespit edilip kapatılmasını ve yarı açık bağlantıların temizlenmesini sağlar. CONFIG SET ile anında değiştirilebilir.","tags":["network","ağ","tcp","keepalive"]},{"name":"timeout","default":"0","recommended":"0 (bağlantı kapatma) veya makul bir idle süresi","unit":"saniye","dynamic":"dynamic","desc":"Bir istemci bağlantısının boşta (idle) kalabileceği azami süreyi saniye cinsinden belirler; süre aşılırsa bağlantı kapatılır. 0 değeri istemcilerin süresiz boşta kalabileceği anlamına gelir. CONFIG SET timeout komutuyla anında değiştirilebilir.","tags":["connections","bağlantı","timeout","idle"]},{"name":"hz","default":"10","recommended":"10 (yoğun sistemlerde 100'e kadar)","unit":"Hz","dynamic":"dynamic","desc":"Redis'in arka plan görevlerini (süresi dolan anahtarların temizlenmesi, istemci zaman aşımı denetimi vb.) saniyede kaç kez çalıştıracağını belirler. Daha yüksek değerler daha hassas denetim sağlar ancak CPU kullanımını artırır. CONFIG SET hz komutuyla anında değiştirilebilir.","tags":["performance","cpu","background"]},{"name":"activedefrag","default":"no","recommended":"Bellek parçalanması yüksekse yes","unit":"yes/no","dynamic":"dynamic","desc":"Aktif bellek birleştirmeyi (defragmentation) etkinleştirir; çalışırken bellekteki parçalanmayı azaltmak için verileri yeniden düzenler. Uzun süre çalışan ve yüksek parçalanma yaşayan örneklerde faydalıdır. CONFIG SET activedefrag yes komutuyla anında etkinleştirilebilir.","tags":["memory","bellek","defragmentation"]},{"name":"maxmemory-samples","default":"5","recommended":"5 (daha doğru eviction için artırılabilir)","unit":"adet","dynamic":"dynamic","desc":"LRU ve LFU eviction algoritmalarının anahtar seçerken örnekleyeceği anahtar sayısını belirler. Daha yüksek değerler gerçek LRU/LFU davranışına daha yakın sonuç verir ancak biraz daha fazla CPU tüketir. CONFIG SET ile anında değiştirilebilir.","tags":["memory","bellek","eviction","lru"]},{"name":"io-threads","default":"1","recommended":"Çok çekirdekli sunucularda 2-4 (çekirdek sayısına göre)","unit":"adet","dynamic":"restart","desc":"İstemci soketlerine yazma ve okuma için kullanılan I/O thread sayısını belirler. Yüksek ağ trafiğine sahip çok çekirdekli sistemlerde verimi artırabilir. Bu ayar yalnızca yapılandırma dosyasından değiştirilebilir ve yeniden başlatma gerektirir.","tags":["performance","threads","io","cpu"]},{"name":"repl-backlog-size","default":"1mb","recommended":"Yazma hızına ve kesinti süresine göre daha büyük","unit":"bayt","dynamic":"dynamic","desc":"Replika bağlantısı koptuğunda kısmi yeniden senkronizasyon için primary'de tutulan replication backlog'un boyutunu belirler. Yeterince büyük bir backlog, kısa kesintilerde tam senkronizasyona gerek kalmadan replikanın yakalanmasını sağlar. CONFIG SET ile anında değiştirilebilir.","tags":["replication","çoğaltma","backlog"]},{"name":"repl-diskless-sync","default":"yes","recommended":"yes (hızlı ağlarda)","unit":"yes/no","dynamic":"dynamic","desc":"Replikalara tam senkronizasyon sırasında RDB verisinin diske yazılmadan doğrudan soket üzerinden gönderilmesini sağlar. Disk I/O darboğazı olan sistemlerde senkronizasyonu hızlandırır. CONFIG SET repl-diskless-sync komutuyla anında değiştirilebilir.","tags":["replication","çoğaltma","diskless","sync"]},{"name":"requirepass","default":"(boş)","recommended":"Güçlü bir parola belirleyin","unit":"parola","dynamic":"dynamic","desc":"İstemcilerin komut çalıştırmadan önce AUTH ile doğrulaması gereken parolayı belirler. Redis'e yetkisiz erişimi önlemek için mutlaka güçlü bir parola ayarlanmalıdır. CONFIG SET requirepass komutuyla anında değiştirilebilir.","tags":["security","güvenlik","authentication","parola"]},{"name":"cluster-enabled","default":"no","recommended":"Yatay ölçekleme gerekiyorsa yes","unit":"yes/no","dynamic":"restart","desc":"Redis Cluster modunu etkinleştirir; etkin olduğunda veriler birden fazla düğüme hash slotları üzerinden dağıtılır. Yatay ölçekleme ve otomatik veri bölümlemesi için kullanılır. Bu ayar yalnızca yapılandırma dosyasından değiştirilebilir ve yeniden başlatma gerektirir.","tags":["cluster","küme","scaling","ölçekleme"]},{"name":"cluster-node-timeout","default":"15000","recommended":"Ağ gecikmesine göre 15000 veya ayarlanmış değer","unit":"ms","dynamic":"dynamic","desc":"Cluster modunda bir düğümün erişilemez (fail) kabul edilmeden önce yanıt vermeden geçebileceği azami süreyi milisaniye cinsinden belirler. Failover davranışını ve küme kararlılığını doğrudan etkiler. CONFIG SET ile anında değiştirilebilir.","tags":["cluster","küme","timeout","failover"]},{"name":"aof-use-rdb-preamble","default":"yes","recommended":"yes (hızlı yeniden yükleme)","unit":"yes/no","dynamic":"dynamic","desc":"AOF yeniden yazma işleminde dosyanın başına kompakt bir RDB snapshot'ı, sonrasına ise artımlı AOF komutlarını yazan hibrit kalıcılık biçimini etkinleştirir. Bu sayede yeniden başlatmada AOF yükleme süresi kısalır. CONFIG SET ile anında değiştirilebilir.","tags":["persistence","kalıcılık","aof","rdb"]}]},"reference/params-elasticsearch.json":{"engineId":"elasticsearch","engine":"Elasticsearch","order":7,"params":[{"name":"-Xms / -Xmx (JVM heap)","default":"Sürüme göre otomatik (RAM'in yarısı)","recommended":"Fiziksel RAM'in %50'si, en fazla ~30-31GB (Xms=Xmx)","unit":"GB","dynamic":"restart","desc":"JVM heap'inin başlangıç (-Xms) ve azami (-Xmx) boyutunu belirler; ikisi eşit ayarlanmalıdır. Toplam RAM'in yarısını ve sıkıştırılmış işaretçilerin devreye girdiği ~32GB sınırını aşmamak önerilir. jvm.options dosyasında ayarlanır ve düğümün yeniden başlatılmasını gerektirir.","tags":["memory","bellek","jvm","heap"]},{"name":"indices.memory.index_buffer_size","default":"10%","recommended":"10% (ağır indeksleme yükünde artırılabilir)","unit":"% / bayt","dynamic":"restart","desc":"İndeksleme sırasında yeni belgeleri tutan indexing buffer'a ayrılan heap oranını belirler. Yoğun yazma iş yüklerinde bu buffer'ı artırmak indeksleme verimini iyileştirebilir. elasticsearch.yml içinde düğüm bazında ayarlanır ve yeniden başlatma gerektirir.","tags":["memory","bellek","indexing","buffer"]},{"name":"thread_pool.write.queue_size","default":"10000","recommended":"10000 (kuyruk reddi yaşanıyorsa dikkatle artırın)","unit":"adet","dynamic":"restart","desc":"İndeksleme, silme ve toplu (bulk) yazma işlemleri için thread pool'unun bekleme kuyruğu uzunluğunu belirler. Kuyruk dolduğunda istekler reddedilir (rejected). Değeri aşırı artırmak bellek baskısına yol açabilir. elasticsearch.yml içinde ayarlanır ve yeniden başlatma gerektirir.","tags":["thread pool","write","queue","kuyruk"]},{"name":"thread_pool.search.queue_size","default":"1000","recommended":"1000 (arama reddi yaşanıyorsa dikkatle artırın)","unit":"adet","dynamic":"restart","desc":"Arama (search) işlemleri için thread pool'unun bekleme kuyruğu uzunluğunu belirler. Eşzamanlı arama sayısı havuz kapasitesini aştığında istekler bu kuyrukta bekler, kuyruk dolarsa reddedilir. elasticsearch.yml içinde ayarlanır ve yeniden başlatma gerektirir.","tags":["thread pool","search","arama","queue"]},{"name":"indices.fielddata.cache.size","default":"sınırsız","recommended":"%20-40 gibi bir sınır (bellek koruması için)","unit":"% / bayt","dynamic":"restart","desc":"Metin alanlarında sıralama ve toplama (aggregation) için kullanılan fielddata önbelleğinin azami boyutunu belirler. Varsayılan sınırsız olduğundan bellek tükenmesini önlemek için bir sınır koymak önerilir. elasticsearch.yml içinde ayarlanır ve yeniden başlatma gerektirir.","tags":["memory","bellek","fielddata","cache"]},{"name":"index.number_of_shards","default":"1","recommended":"Veri hacmine göre; shard başına 10-50GB hedefleyin","unit":"adet","dynamic":"restart","desc":"Bir index'in bölüneceği primary shard sayısını belirler. Statik bir index ayarıdır (yeniden başlatma değil, yalnızca index oluşturma anında verilir): mevcut index'te doğrudan değiştirilemez; yeni index + _reindex ile ya da _split (katına çıkarma) / _shrink (böleninine indirme) API'leriyle yeni bir index üretilerek değiştirilir. Aşırı shard sayısı küme yükünü artırır, az sayıda shard ise ölçeklenmeyi sınırlar.","tags":["index","indeks","shard","scaling"]},{"name":"index.number_of_replicas","default":"1","recommended":"Üretimde en az 1 (yüksek erişilebilirlik için)","unit":"adet","dynamic":"dynamic","desc":"Her primary shard için tutulacak kopya (replica) shard sayısını belirler. Kopyalar hem yüksek erişilebilirlik hem de okuma performansı sağlar. Bu ayar çalışan index'te _settings API'si ile anında değiştirilebilir.","tags":["index","indeks","replica","availability"]},{"name":"index.refresh_interval","default":"1s","recommended":"Ağır indekslemede 30s veya -1 (geçici)","unit":"süre","dynamic":"dynamic","desc":"Yeni indekslenen belgelerin aramada görünür hale gelmesi için yenileme (refresh) işleminin ne sıklıkta yapılacağını belirler. Değeri artırmak veya toplu yükleme sırasında -1 yapmak indeksleme verimini önemli ölçüde artırır. _settings API'si ile anında değiştirilebilir.","tags":["index","indeks","refresh","indexing"]},{"name":"indices.breaker.total.limit","default":"95%","recommended":"95% (varsayılan; dikkatle değiştirin)","unit":"%","dynamic":"dynamic","desc":"Tüm circuit breaker'ların toplamda kullanabileceği azami heap oranını belirleyerek düğümün bellek yetersizliğinden (OutOfMemory) çökmesini önler. _cluster/settings API'si ile küme genelinde anında değiştirilebilir.","tags":["memory","bellek","circuit breaker","stability"]},{"name":"cluster.routing.allocation.disk.watermark.low","default":"85%","recommended":"85% (varsayılan uygundur)","unit":"% / bayt","dynamic":"dynamic","desc":"Bir düğümün disk doluluğu bu eşiği aştığında Elasticsearch o düğüme yeni shard atamayı durdurur (mevcut shard'lar kalır). Disk dolmasının önüne geçmek için ilk uyarı seviyesidir. _cluster/settings API'si ile anında değiştirilebilir.","tags":["disk","allocation","watermark","storage"]},{"name":"cluster.routing.allocation.disk.watermark.high","default":"90%","recommended":"90% (varsayılan uygundur)","unit":"% / bayt","dynamic":"dynamic","desc":"Bir düğümün disk doluluğu bu eşiği aştığında Elasticsearch shard'ları bu düğümden başka düğümlere taşımaya başlar. Diski dolmakta olan düğümlerin yükünü azaltır. _cluster/settings API'si ile anında değiştirilebilir.","tags":["disk","allocation","watermark","storage"]},{"name":"cluster.routing.allocation.disk.watermark.flood_stage","default":"95%","recommended":"95% (varsayılan uygundur)","unit":"% / bayt","dynamic":"dynamic","desc":"Disk doluluğu bu kritik eşiği aştığında, ilgili düğümde shard'ı bulunan index'ler salt-okunur (read-only-allow-delete) moduna alınır ve yazmalar engellenir. Disk tamamen dolmadan verinin bozulmasını önler; 7.4+ sürümlerde disk kullanımı high watermark'ın altına inince blok otomatik kaldırılır. 8.x'te büyük disklerde yüzde yerine max_headroom (varsayılan 100GB boş alan) belirleyicidir. _cluster/settings API'si ile anında değiştirilebilir.","tags":["disk","allocation","watermark","read-only"]},{"name":"index.translog.durability","default":"request","recommended":"request (dayanıklılık) veya async (performans)","unit":"mod","dynamic":"dynamic","desc":"Translog'un diske ne zaman eşitleneceğini (fsync) belirler. request her istekten sonra eşitleyerek veri kaybını en aza indirir; async periyodik eşitleme yaparak performansı artırır ancak çökme durumunda veri kaybı riski taşır. _settings API'si ile anında değiştirilebilir.","tags":["translog","durability","dayanıklılık","indexing"]},{"name":"indices.recovery.max_bytes_per_sec","default":"40mb","recommended":"Ağ ve disk kapasitesine göre artırılabilir","unit":"bayt/s","dynamic":"dynamic","desc":"Shard kurtarma (recovery) işlemleri sırasında düğüm başına kullanılabilecek azami veri aktarım hızını belirler. Değeri artırmak kurtarmayı hızlandırır ancak normal iş yükünün ağ ve disk kaynaklarını tüketebilir. _cluster/settings API'si ile anında değiştirilebilir.","tags":["recovery","kurtarma","throttle","network"]},{"name":"action.destructive_requires_name","default":"true","recommended":"true (yıkıcı joker işlemleri engeller)","unit":"true/false","dynamic":"dynamic","desc":"Joker karakter (*) veya _all kullanarak index silme gibi yıkıcı işlemlerin yapılmasını engeller ve index adının açıkça belirtilmesini zorunlu kılar. Yanlışlıkla tüm index'lerin silinmesini önlemek için önemli bir güvenlik ayarıdır. _cluster/settings API'si ile anında değiştirilebilir.","tags":["security","güvenlik","destructive","safety"]},{"name":"discovery.seed_hosts","default":"(boş / 127.0.0.1)","recommended":"Kümedeki uzman (master-eligible) düğümlerin adresleri","unit":"liste","dynamic":"restart","desc":"Bir düğümün kümeye katılmak için iletişim kuracağı başlangıç ana bilgisayar (master-eligible düğüm) adreslerinin listesini belirler. Küme keşfi (discovery) ve düğümlerin birbirini bulması için gereklidir. elasticsearch.yml içinde ayarlanır ve yeniden başlatma gerektirir.","tags":["discovery","cluster","küme","network"]}]},"reference/waits-oracle.json":{"engineId":"oracle","engine":"Oracle","order":1,"waits":[{"name":"log file sync","kind":"wait","meaning":"Oturum bir COMMIT (veya ROLLBACK) verdi ve LGWR sürecinin redo kayıtlarını online redo log dosyalarına yazıp onaylamasını bekliyor.","causes":"Yavaş redo log I/O'su, çok sık ve küçük commit yapılması, aşırı yüklü LGWR süreci, CPU kıtlığı nedeniyle LGWR'ın gecikmesi, redo log'ların yavaş diskte olması.","action":"Commit sıklığını azaltın (batch commit), redo log dosyalarını hızlı/düşük gecikmeli diske (SSD) taşıyın, gereksiz commit'leri kaldırın, COMMIT NOWAIT/BATCH seçeneklerini yalnızca kaybın tolere edilebildiği işlerde değerlendirin (UYARI: dayanıklılığı azaltır; çökme anında commit edilmiş görünen transaction'lar kaybolabilir), log writer I/O gecikmesini (log file parallel write) ölçün.","tags":["commit","redo","io","lgwr"]},{"name":"db file sequential read","kind":"wait","meaning":"Oturum tek bloklu (single-block) fiziksel okuma yapıyor; genellikle index erişimi veya ROWID ile tablo bloğu okuması sırasında ilgili bloğun diskten buffer cache'e gelmesini bekliyor.","causes":"Index taramaları, verimsiz erişim planları, küçük buffer cache, yavaş disk alt sistemi, yüksek fiziksel okuma nedeniyle blokların cache'te bulunmaması.","action":"SQL ayarlaması yapıp gereksiz okumaları azaltın, uygun index'ler ekleyin, buffer cache boyutunu artırın, I/O alt sistemini iyileştirin, en çok okuyan sorguları AWR/ASH ile tespit edin.","tags":["io","index","single-block","read"]},{"name":"db file scattered read","kind":"wait","meaning":"Oturum çok bloklu (multi-block) fiziksel okuma yapıyor; genellikle full table scan veya fast full index scan sırasında birden çok bloğun diskten okunmasını bekliyor.","causes":"Full table scan'ler, eksik veya kullanılmayan index'ler, verimsiz sorgu planları, büyük tablo taramaları, yanlış optimizer istatistikleri.","action":"Gereksiz full scan'leri index ekleyerek önleyin, sorgu planlarını gözden geçirin, istatistikleri güncelleyin, db_file_multiblock_read_count ayarını inceleyin, gerçekten gereken tam taramaları paralelleştirmeyi değerlendirin.","tags":["io","full-scan","multi-block","read"]},{"name":"direct path read","kind":"wait","meaning":"Oturum blokları buffer cache'i atlayarak doğrudan PGA'ya okuyor; genellikle paralel sorgular, büyük tablo taramaları veya LOB okumaları sırasında görülür.","causes":"Paralel full table scan'ler, seri direct path okuma kararı (adaptive direct read), büyük tablolarda tarama, temp tablespace okumaları, LOB erişimleri.","action":"Büyük taramaların gerekliliğini sorgu ayarlamasıyla azaltın, PGA boyutunu değerlendirin, temp kullanımı yüksekse sıralama/hash işlemlerini optimize edin, I/O bant genişliğini artırın.","tags":["io","direct-path","parallel","read"]},{"name":"direct path write","kind":"wait","meaning":"Oturum blokları buffer cache üzerinden geçmeden doğrudan diske yazıyor; genellikle direct-path insert, sıralama taşmaları veya LOB yazımları sırasında görülür.","causes":"Direct-path INSERT (APPEND) işlemleri, temp tablespace'e sıralama/hash taşması, paralel DML, LOB yazımları, yavaş temp veya veri diskleri.","action":"Sıralama/hash işlemleri için PGA'yı artırıp temp taşmasını azaltın, temp tablespace'i hızlı diske alın, gereksiz direct-path yüklemelerini gözden geçirin, I/O performansını iyileştirin.","tags":["io","direct-path","temp","write"]},{"name":"buffer busy waits","kind":"wait","meaning":"Oturum buffer cache'te bir bloğa erişmek istiyor ancak blok başka bir oturum tarafından uyumsuz bir modda kullanıldığı için serbest kalmasını bekliyor.","causes":"Aynı bloğa yoğun eşzamanlı erişim (hot block), yetersiz freelist/ASSM, sıralı index'te sağ el bloğu çekişmesi (right-hand index growth), yüksek DML yoğunluğu olan segmentler.","action":"Hot block'ları dağıtın (hash partitioning, reverse key index), ASSM kullanın, freelist/freelist group artırın, sıralı anahtar üreten tablolarda sequence cache ve dağıtımı iyileştirin.","tags":["concurrency","buffer","hot-block","contention"]},{"name":"read by other session","kind":"wait","meaning":"Oturumun ihtiyaç duyduğu bloğu başka bir oturum zaten diskten okuyor; bu oturum aynı bloğun okunmasının tamamlanmasını bekliyor.","causes":"Aynı hot block'lara eşzamanlı fiziksel okuma talebi, küçük buffer cache, yavaş I/O, popüler index veya tablo bloklarına çok sayıda oturumun aynı anda erişmesi.","action":"Buffer cache'i artırıp fiziksel okumaları azaltın, hot segment'leri tespit edip erişim planlarını iyileştirin, I/O gecikmesini düşürün, gereksiz tam taramaları giderin.","tags":["io","concurrency","read","hot-block"]},{"name":"latch: cache buffers chains","kind":"wait","meaning":"Oturum buffer cache hash zincirini korumak için gereken latch'i almayı bekliyor; buffer cache içindeki blokları bulma sırasında serileşme yaşanıyor.","causes":"Aşırı mantıksal okuma (logical I/O) üreten verimsiz SQL, hot block'lara yoğun eşzamanlı erişim, nested loop ile aynı bloklara tekrar tekrar erişim, çok popüler index kök/dal blokları.","action":"Mantıksal okumayı azaltmak için SQL'i ayarlayın, gereksiz nested loop erişimlerini giderin, hot block'ları dağıtın, aşırı buffer get üreten sorguları AWR/ASH ile bulup düzeltin.","tags":["latch","concurrency","logical-io","buffer"]},{"name":"cursor: pin S wait on X","kind":"wait","meaning":"Oturum bir cursor'u paylaşımlı (S) modda mutex ile sabitlemek istiyor ancak başka bir oturum aynı cursor'u özel (X) modda tuttuğu için bekliyor.","causes":"Yüksek hard/soft parse oranı, çok sık parse edilen popüler SQL'ler, bind değişkeni kullanmayan literal sorgular, child cursor çoğalması, aynı SQL'e çok sayıda oturumun eşzamanlı parse etmesi.","action":"Bind değişkeni kullanarak parse yükünü düşürün, uygulamada cursor'ları önbelleğe alın (session_cached_cursors), gereksiz yeniden parse'ı azaltın, yüksek versiyon sayılı SQL'leri (version count) düzeltin.","tags":["mutex","parse","cursor","concurrency"]},{"name":"library cache lock","kind":"wait","meaning":"Oturum library cache içindeki bir nesnenin (paket, view, tablo tanımı) handle'ı üzerinde lock almayı bekliyor; genellikle nesne tanımına eşzamanlı erişim/değişiklik sırasında görülür.","causes":"Çalışan nesneler üzerinde DDL yapılması, sürekli yeniden derlenen paketler/view'lar, geçersiz (invalid) nesneler, yoğun eşzamanlı bağlantı ve parse, yetkilendirme (grant) değişiklikleri.","action":"DDL'leri yoğun olmayan zamanlarda çalıştırın, gereksiz derlemeleri önleyin, geçersiz nesneleri düzeltin, uygulama tarafında aşırı bağlantı/parse döngülerini azaltın.","tags":["library-cache","concurrency","ddl","parse"]},{"name":"library cache: mutex X","kind":"wait","meaning":"Oturum library cache'te bir nesneyi özel (X) modda korumak için mutex almayı bekliyor; genellikle yüksek parse ve nesne handle çekişmesinde görülür.","causes":"Aşırı parse (hard/soft), bind kullanmayan literal SQL çeşitliliği, yüksek child cursor sayısı, sık nesne geçersizleşmesi, çok sayıda oturumun aynı nesneye eşzamanlı erişimi.","action":"Parse'ı azaltmak için bind değişkeni ve cursor önbellekleme kullanın, SQL literal'lerini standartlaştırın, yüksek version count sorunlarını giderin, uygulama bağlantı davranışını iyileştirin.","tags":["mutex","library-cache","parse","concurrency"]},{"name":"enq: TX - row lock contention","kind":"wait","meaning":"Oturum başka bir transaction'ın kilitlediği bir satırı değiştirmek istiyor ve o transaction'ın commit/rollback yapıp row lock'u bırakmasını bekliyor.","causes":"Aynı satırlara eşzamanlı UPDATE/DELETE, uzun süren commit yapmayan transaction'lar, kötü tasarlanmış uygulama iş akışı, unique/foreign key üzerinden dolaylı row lock'ları, tıkanan (hung) oturumlar.","action":"Transaction'ları kısa tutun ve zamanında commit edin, çekişen erişim düzenini yeniden tasarlayın, gerekirse SELECT FOR UPDATE ile sıralı erişim sağlayın, tıkayan oturumu ASH ile bulup çözün.","tags":["lock","transaction","row-lock","contention"]},{"name":"enq: TX - allocate ITL entry","kind":"wait","meaning":"Oturum bir blokta işlem yapmak için o bloğun ITL (Interested Transaction List) slotunu almayı bekliyor ancak blokta boş ITL slotu kalmadığı için beklemek zorunda.","causes":"Düşük INITRANS ayarı, küçük blok boyutu, aynı blokta çok sayıda eşzamanlı transaction, yoğun DML gören yoğun paketlenmiş bloklar.","action":"İlgili tablo/index için INITRANS değerini artırın, PCTFREE'yi yükselterek blok başına daha az satır koyun, hot block'ları dağıtın, gerekirse nesneyi yeniden oluşturun.","tags":["lock","transaction","itl","block"]},{"name":"gc buffer busy acquire","kind":"wait","meaning":"RAC ortamında oturum bir bloğu global cache üzerinden almak istiyor ancak aynı instance'ta başka bir oturum aynı blok için zaten global talebi başlattığından bekliyor.","causes":"RAC'te hot block'ların instance'lar arası paylaşımı, yetersiz interconnect performansı, sıralı index sağ el çekişmesi, iyi bölümlenmemiş iş yükü, yoğun global cache trafiği.","action":"İş yükünü instance'lara mantıklı bölün (application affinity/services), hot segment'leri dağıtın (reverse key/partition), interconnect gecikmesini iyileştirin, gc çekişmesini AWR RAC bölümü ve GV$ view'larıyla analiz edin.","tags":["rac","global-cache","concurrency","interconnect"]},{"name":"gc cr block busy","kind":"wait","meaning":"RAC ortamında oturum tutarlı okuma (CR) için başka bir instance'tan blok istedi ve o instance'ın bloğu hazırlayıp interconnect üzerinden göndermesini bekliyor.","causes":"Instance'lar arası hot block paylaşımı, yavaş veya doygun interconnect, yoğun redo/commit trafiği, kötü bölümlenmiş iş yükü, aşırı global cache CR isteği.","action":"İş yükü afinitesini iyileştirin, interconnect bant genişliği ve gecikmesini optimize edin, hot block'ları azaltın, commit ve DML desenlerini gözden geçirin, RAC ayarlaması yapın.","tags":["rac","global-cache","cr","interconnect"]},{"name":"log file switch (checkpoint incomplete)","kind":"wait","meaning":"Oturum yeni bir redo log'a geçmek istiyor ancak sıradaki log dosyasına ait checkpoint henüz tamamlanmadığı için LGWR o log'u tekrar kullanamıyor ve tüm redo üretimi duruyor.","causes":"Çok küçük veya çok az redo log dosyası, yavaş DBWR/checkpoint I/O'su, yüksek redo üretim hızı, yetersiz log group sayısı.","action":"Redo log dosyalarını büyütün ve grup sayısını artırın, DBWR/checkpoint I/O performansını iyileştirin, redo üretimini azaltacak uygulama optimizasyonları yapın, log switch sıklığını izleyin.","tags":["redo","checkpoint","log-switch","io"]},{"name":"free buffer waits","kind":"wait","meaning":"Oturum yeni bir bloğu okumak için buffer cache'te temiz/boş bir buffer arıyor ancak DBWR dirty buffer'ları yeterince hızlı diske yazamadığından boş buffer bekliyor.","causes":"Yavaş DBWR yazma I/O'su, küçük buffer cache, yoğun DML ile hızlı dirty buffer üretimi, yetersiz checkpoint hızı, doymuş disk alt sistemi.","action":"Datafile yazma I/O'sunu hızlandırın, buffer cache boyutunu artırın, DBWR süreç sayısını (db_writer_processes) değerlendirin, DML yoğunluğunu ve checkpoint ayarlarını gözden geçirin.","tags":["buffer","dbwr","io","checkpoint"]},{"name":"Buffer Cache Hit Ratio","kind":"metric","meaning":"İstenen blokların diske gitmeden buffer cache'ten karşılanma oranı; mantıksal okumaların yüzde kaçının fiziksel okuma gerektirmediğini gösterir.","causes":"Düşük oran genellikle küçük buffer cache, verimsiz full scan'ler, soğuk cache veya yüksek fiziksel okuma nedeniyledir. Tek başına yanıltıcı olabilir; yüksek oran da kötü SQL'i gizleyebilir.","action":"Oranı tek başına hedeflemeyin; wait event ve fiziksel okuma trendleriyle birlikte değerlendirin. Verimsiz SQL'i ayarlayın, gereksiz mantıksal okumayı azaltın, cache boyutunu iş yüküne göre ayarlayın.","tags":["metric","buffer-cache","ratio","memory"]},{"name":"Average Active Sessions","kind":"metric","meaning":"Belirli bir aralıkta aynı anda aktif (CPU'da çalışan veya bir olayı bekleyen) oturumların ortalama sayısı; veritabanının genel yük ve darboğaz yoğunluğunu özetler.","causes":"Yüksek AAS; CPU doygunluğu, I/O beklemeleri, lock/latch çekişmesi veya artan eşzamanlılık nedeniyle olabilir. CPU çekirdek sayısına yaklaşan veya aşan değerler kaynak darboğazına işaret eder.","action":"AAS'yi CPU çekirdek sayısı ile karşılaştırın, baskın bekleme sınıfını (CPU/IO/concurrency) ASH ile bulun, en yük üreten SQL ve oturumları ayarlayın, kaynak veya eşzamanlılık sorununu giderin.","tags":["metric","load","ash","sessions"]}]},"reference/waits-postgres.json":{"engineId":"postgres","engine":"PostgreSQL","order":2,"waits":[{"name":"LWLock:WALWrite","kind":"wait","meaning":"Oturum WAL buffer'ı diske yazmak için gereken lightweight lock'u bekliyor; genellikle commit sırasında WAL yazımının serileşmesinden kaynaklanır.","causes":"Yavaş WAL disk I/O'su, çok sık/küçük commit'ler, yüksek yazma yükü, yetersiz WAL yazım bant genişliği, aynı anda çok sayıda backend'in WAL yazması.","action":"WAL'i hızlı/düşük gecikmeli diske alın, commit'leri grupla (synchronous_commit ayarını değerlendir, commit_delay), wal_buffers'ı artırın, gereksiz yazma işlemlerini azaltın.","tags":["wal","lwlock","commit","io"]},{"name":"LWLock:BufferContent","kind":"wait","meaning":"Oturum paylaşımlı buffer havuzundaki bir sayfanın içeriğini korumak için o buffer'a ait hafif lock'u bekliyor; sayfaya eşzamanlı erişim çekişmesini gösterir.","causes":"Aynı sayfaya (hot page) yoğun eşzamanlı okuma/yazma, sıralı index sağ el ucu çekişmesi, yoğun güncelleme gören küçük tablolar, yüksek eşzamanlılık.","action":"Hot page'leri dağıtın (fillfactor ayarı, bölümleme), sıralı anahtar çekişmesini azaltın, yoğun güncellenen satırları düzenleyin, eşzamanlı erişim desenini gözden geçirin.","tags":["lwlock","buffer","concurrency","contention"]},{"name":"Lock:transactionid","kind":"wait","meaning":"Oturum, kilitlediği satırı değiştirmek istediği başka bir transaction'ın bitmesini (commit/rollback) bekliyor; hedef transaction'ın ID'si üzerinde lock bekleniyor.","causes":"Aynı satırlara eşzamanlı UPDATE/DELETE, uzun süren commit yapmayan transaction'lar, idle-in-transaction oturumlar, kötü tasarlanmış çekişmeli iş akışı.","action":"Transaction'ları kısa tutun ve zamanında commit edin, idle-in-transaction oturumlarını sınırlayın (idle_in_transaction_session_timeout), çekişen erişim desenini yeniden tasarlayın, tıkayan sorguyu pg_stat_activity ile bulun.","tags":["lock","transaction","row-lock","contention"]},{"name":"Lock:tuple","kind":"wait","meaning":"Oturum belirli bir tuple (satır) üzerinde lock almayı bekliyor; birden fazla oturum aynı satırı güncellemek/kilitlemek için sıraya girdiğinde görülür.","causes":"Aynı satıra eşzamanlı SELECT FOR UPDATE/UPDATE, hot row çekişmesi (ör. sayaç satırları), uzun tutulan row lock'ları, yüksek eşzamanlılık.","action":"Hot row güncellemelerini dağıtın veya kuyruğa alın, transaction süresini kısaltın, sayaç gibi çekişmeli desenleri yeniden tasarlayın (ör. toplu güncelleme), FOR UPDATE SKIP LOCKED değerlendirin.","tags":["lock","tuple","row-lock","contention"]},{"name":"Lock:relation","kind":"wait","meaning":"Oturum bir tablo/index (relation) üzerinde tablo düzeyi lock almayı bekliyor; genellikle DDL ile DML arasındaki uyumsuz lock modları çekişmesinde görülür.","causes":"Çalışan sorgular üzerinde ALTER/DROP/TRUNCATE gibi DDL, agresif lock gerektiren VACUUM FULL, aynı tabloya uyumsuz modlarda eşzamanlı erişim, uzun süren sorgular.","action":"DDL'leri düşük yoğunluklu zamanlarda ve kısa lock_timeout ile çalıştırın, VACUUM FULL yerine düzenli autovacuum kullanın, uzun sorguları izleyin, tabloya erişimi serileştiren işlemleri gözden geçirin.","tags":["lock","relation","ddl","table-lock"]},{"name":"IO:DataFileRead","kind":"wait","meaning":"Oturum bir data file sayfasını diskten paylaşımlı buffer'a okunmasını bekliyor; istenen sayfa cache'te bulunmadığında oluşan fiziksel okuma beklemesidir.","causes":"Küçük shared_buffers, verimsiz sorgu planları ve büyük taramalar, soğuk cache, yavaş disk alt sistemi, yetersiz index kullanımı.","action":"shared_buffers ve OS sayfa cache'ini iş yüküne göre ayarlayın, verimsiz sorguları ve eksik index'leri düzeltin, I/O performansını iyileştirin, effective_cache_size'ı doğru ayarlayın.","tags":["io","read","buffer","disk"]},{"name":"IO:WALSync","kind":"wait","meaning":"Oturum WAL'in diske kalıcı olarak yazılması (fsync/senkronizasyon) işleminin tamamlanmasını bekliyor; commit dayanıklılığı için WAL'in fiziksel olarak flush edilmesini bekler.","causes":"Yavaş depolama fsync gecikmesi, çok sık commit, düşük performanslı WAL diski, write-back cache olmayan disk, yüksek yazma yükü.","action":"WAL diskini düşük fsync gecikmeli hızlı depolamaya alın, commit'leri gruplayın (commit_delay/commit_siblings), synchronous_commit ayarını iş gereksinimine göre değerlendirin, depolama katmanını iyileştirin.","tags":["wal","io","fsync","commit"]},{"name":"IO:DataFileWrite","kind":"wait","meaning":"Oturum bir dirty page'in diske yazılmasını bekliyor; genellikle buffer havuzunda temiz sayfa bulmak için backend'in kendisi yazma yaptığında görülür.","causes":"Yavaş veri diski yazma I/O'su, checkpoint tıkanıklığı, yetersiz background writer, küçük buffer havuzu, yüksek yazma yükü nedeniyle backend'in kendi yazması.","action":"Checkpoint ayarlarını yumuşatın (checkpoint_completion_target, max_wal_size), background writer'ı ayarlayın (bgwriter_lru_maxpages), disk yazma performansını artırın, shared_buffers'ı gözden geçirin.","tags":["io","write","checkpoint","bgwriter"]},{"name":"Client:ClientRead","kind":"wait","meaning":"Backend, istemciden gelecek bir sonraki komut/veriyi bekliyor; sunucu boşta olup istemcinin veri göndermesini beklerken görülür.","causes":"Yavaş ağ, idle-in-transaction oturumlar, istemci uygulamanın yavaş veri göndermesi/almaması, büyük sonuç kümelerinin yavaş tüketilmesi, bağlantı havuzu sorunları.","action":"Uygulama tarafındaki gecikmeyi ve ağ gecikmesini inceleyin, idle-in-transaction oturumları sınırlayın, sonuçları verimli tüketin (ör. cursor/batch), bağlantı havuzunu iyileştirin. Bu bekleme genellikle veritabanı darboğazı değildir.","tags":["client","network","idle","application"]},{"name":"IPC:ProcArrayGroupUpdate","kind":"wait","meaning":"Oturum, transaction'ının bitişini ProcArray'de toplu (grup) olarak işaretlemek için grup lideri backend'i bekliyor; commit sırasında ProcArray güncellemesinin serileşmesidir.","causes":"Çok yüksek commit/transaction hızı, aşırı eşzamanlı kısa transaction'lar, yüksek bağlantı sayısı, yoğun snapshot/ProcArray erişimi.","action":"Transaction hızını ve eşzamanlı bağlantı sayısını yönetin (bağlantı havuzu), gereksiz kısa transaction'ları azaltın, çok yüksek eşzamanlılıkta bağlantı sayısını sınırlayın, iş yükünü dengeleyin.","tags":["ipc","commit","procarray","concurrency"]},{"name":"LWLock:LockManager","kind":"wait","meaning":"Oturum ağır lock (heavyweight lock) tablosunu koruyan lock manager hafif lock'unu bekliyor; lock alma/bırakma işlemlerinin serileşmesinden kaynaklanır.","causes":"Çok sayıda tablo/partition'a erişen sorgular (fast-path lock sınırının aşılması), yüksek eşzamanlılık, aşırı bölümlenmiş tablolar, çok sayıda lock alan/serbest bırakan iş yükü.","action":"Sorgu başına dokunulan partition/tablo sayısını azaltın (partition pruning), aşırı bölümlemeyi gözden geçirin, eşzamanlılığı bağlantı havuzuyla yönetin, gereksiz lock alan işlemleri sadeleştirin.","tags":["lwlock","lock-manager","concurrency","partitioning"]},{"name":"Timeout:VacuumDelay","kind":"wait","meaning":"Vacuum/autovacuum süreci, maliyet tabanlı gecikme (cost-based vacuum delay) nedeniyle bilinçli olarak duraklatılmış durumda; I/O yükünü sınırlamak için kasıtlı bekleme.","causes":"vacuum_cost_delay/autovacuum_vacuum_cost_delay ayarları nedeniyle throttling, düşük cost_limit, çok sayıda tabloyu temizleyen vacuum, agresif olmayan autovacuum ayarları.","action":"Vacuum çok yavaş kalıyor ve bloat/dead tuple birikiyorsa cost_limit'i artırıp cost_delay'i düşürün, autovacuum çalışan sayısını ve eşiklerini ayarlayın, I/O kapasitesine göre dengeleyin.","tags":["vacuum","timeout","throttle","maintenance"]},{"name":"cache hit ratio","kind":"metric","meaning":"Blok isteklerinin diske gitmeden shared buffers'tan karşılanma oranı; pg_stat_database blks_hit ve blks_read değerlerinden hesaplanır.","causes":"Düşük oran genellikle küçük shared_buffers, verimsiz büyük taramalar, soğuk cache veya yetersiz belleğe işaret eder. OS sayfa cache'i de okumaları karşıladığından oran tek başına yanıltıcı olabilir.","action":"Oranı wait event ve I/O trendleriyle birlikte yorumlayın, shared_buffers ve effective_cache_size'ı ayarlayın, verimsiz sorguları düzeltin, sürekli düşükse bellek ve sorgu planlarını inceleyin.","tags":["metric","cache","ratio","memory"]},{"name":"replication lag","kind":"metric","meaning":"Bir standby/replica sunucunun primary'nin ürettiği WAL'i uygulamada geride kalma miktarı; bayt (LSN farkı) veya saniye cinsinden gecikme olarak ölçülür.","causes":"Yavaş ağ, standby üzerinde ağır sorgu yükü (özellikle replay çakışmaları), yavaş standby disk I/O'su, yüksek primary yazma hızı, uzun süren okuma sorgularının recovery'i geciktirmesi.","action":"pg_stat_replication ile write/flush/replay gecikmesini izleyin, ağ ve standby I/O performansını iyileştirin, çakışan uzun sorguları yönetin (hot_standby_feedback/max_standby_streaming_delay), senkron replikasyon gereksinimini gözden geçirin.","tags":["metric","replication","lag","standby"]}]},"reference/waits-mysql.json":{"engineId":"mysql","engine":"MySQL","order":3,"waits":[{"name":"wait/synch/mutex/innodb/buf_pool_LRU_list_mutex","kind":"wait","meaning":"Thread, InnoDB buffer pool'un LRU listesini koruyan mutex'i bekliyor; sayfa okuma/çıkarma (eviction) sırasında serileşmeyi gösterir. 8.0'da eski tek buf_pool_mutex bölündü; ilgili diğer instrument'lar buf_pool_free_list_mutex, buf_pool_flush_state_mutex ve buf_pool_zip_mutex'tir.","causes":"Yüksek eşzamanlılık altında yoğun buffer pool erişimi, tek buffer pool instance, sık sayfa okuma/çıkarma (eviction), yetersiz buffer pool boyutu.","action":"innodb_buffer_pool_instances değerini artırarak mutex'i bölün, innodb_buffer_pool_size'ı iş kümesine göre büyütün, fiziksel okumaları azaltacak sorgu ayarlaması yapın, eşzamanlılığı yönetin.","tags":["innodb","mutex","buffer-pool","concurrency"]},{"name":"wait/io/file/innodb/innodb_data_file","kind":"wait","meaning":"Thread, InnoDB veri dosyalarına (ibd/ibdata) yönelik fiziksel dosya I/O işleminin (okuma/yazma) tamamlanmasını bekliyor.","causes":"Yavaş disk alt sistemi, küçük buffer pool nedeniyle çok fiziksel okuma, büyük tablo taramaları, checkpoint/flush baskısı, yetersiz I/O kapasitesi.","action":"Buffer pool'u büyütün, verimsiz sorguları ve eksik index'leri düzeltin, hızlı depolamaya (SSD/NVMe) geçin, innodb_io_capacity ayarlarını depolamaya göre yapın, flush davranışını gözden geçirin.","tags":["innodb","io","datafile","disk"]},{"name":"wait/lock/table/sql/handler","kind":"wait","meaning":"Thread, SQL katmanındaki tablo düzeyi handler lock'unu (table lock) almayı bekliyor; tabloya uyumsuz modlarda eşzamanlı erişimde görülür.","causes":"Table lock gerektiren işlemler, MyISAM gibi tablo düzeyi kilitleyen storage engine kullanımı, LOCK TABLES ifadeleri, DDL ile DML çekişmesi, uzun süren sorgular.","action":"Satır düzeyi kilitleyen InnoDB kullanın, LOCK TABLES kullanımını azaltın, DDL'leri düşük yoğunlukta çalıştırın, uzun sorguları optimize edin, tabloya erişimi serileştiren desenleri gözden geçirin.","tags":["lock","table-lock","sql-layer","contention"]},{"name":"wait/synch/mutex/sql/LOCK_open","kind":"wait","meaning":"Thread, açık tablo tanımlarını/nesne sözlüğünü koruyan LOCK_open mutex'ini bekliyor; tablo açma/kapama işlemlerinin serileşmesidir.","causes":"Çok sayıda farklı tabloya sürekli erişim, küçük table_open_cache/table_definition_cache, sık tablo açıp kapama, yüksek eşzamanlılık, çok fazla tablo/partition.","action":"table_open_cache ve table_open_cache_instances değerlerini artırın, table_definition_cache'i ayarlayın, aşırı tablo/partition sayısını gözden geçirin, gereksiz sık tablo açılışını azaltın.","tags":["mutex","table-cache","sql-layer","concurrency"]},{"name":"row lock waits","kind":"wait","meaning":"Bir transaction'ın, başka bir transaction'ın tuttuğu InnoDB row lock'un serbest kalmasını bekleme durumu; satır düzeyi lock çekişmesini gösterir.","causes":"Aynı satırlara eşzamanlı UPDATE/DELETE, uzun süren commit yapmayan transaction'lar, index eksikliği nedeniyle geniş lock aralıkları (gap lock), hot row çekişmesi, deadlock döngüleri.","action":"Transaction'ları kısa tutup zamanında commit edin, uygun index ekleyerek kilitlenen satır aralığını daraltın, çekişen desenleri yeniden tasarlayın, deadlock'ları izleyin (SHOW ENGINE INNODB STATUS), izolasyon seviyesini gözden geçirin.","tags":["innodb","row-lock","transaction","contention"]},{"name":"log file waits","kind":"wait","meaning":"Thread, InnoDB redo log buffer'ında yer açılmasını veya redo log'un diske yazılmasını bekliyor; genellikle log buffer flush/checkpoint baskısında görülür.","causes":"Küçük redo log (8.0.30+ innodb_redo_log_capacity; öncesinde innodb_log_file_size × innodb_log_files_in_group), yavaş log diski, yüksek yazma hızı, sık flush (innodb_flush_log_at_trx_commit=1 ve sık commit), yetersiz log buffer.","action":"Redo kapasitesini (8.0.30+ innodb_redo_log_capacity, dinamik; öncesinde innodb_log_file_size, restart gerekir) ve innodb_log_buffer_size'ı artırın, redo log'u hızlı diske alın, commit desenini gözden geçirin, dayanıklılık gereksinimine göre flush ayarını değerlendirin.","tags":["innodb","redo","log","io"]},{"name":"wait/io/file/innodb/innodb_log_file","kind":"wait","meaning":"Thread, InnoDB redo log dosyalarına yönelik fiziksel I/O'nun (yazma ve fsync) tamamlanmasını bekliyor; commit dayanıklılığı için redo'nun diske yazılmasını bekler.","causes":"Yavaş depolama fsync gecikmesi, çok sık commit ve innodb_flush_log_at_trx_commit=1, düşük performanslı log diski, yüksek yazma yükü.","action":"Redo log diskini düşük gecikmeli hızlı depolamaya alın, mümkünse commit'leri gruplayın, innodb_flush_log_at_trx_commit ayarını iş gereksinimine göre değerlendirin, depolama katmanını iyileştirin.","tags":["innodb","redo","fsync","commit"]},{"name":"wait/synch/mutex/innodb/log_writer_mutex","kind":"wait","meaning":"Thread, InnoDB redo log writer thread'inin yapılarını koruyan mutex'i bekliyor. 8.0'da redo alt sistemi yeniden tasarlandı; eski tek log_sys_mutex yerine log_writer_mutex, log_flusher_mutex, log_checkpointer_mutex gibi ayrı instrument'lar vardır.","causes":"Çok yüksek yazma/commit hızı, yoğun redo üretimi, log writer/flusher thread'leri üzerinde çekişme, yavaş log diski, küçük log buffer.","action":"Yazma yükünü ve commit sıklığını dengeleyin, redo üretimini azaltacak toplu işlemleri değerlendirin, log buffer'ı ayarlayın, MySQL sürümünün redo log ölçeklenebilirlik iyileştirmelerinden yararlanın.","tags":["innodb","mutex","redo","concurrency"]},{"name":"Innodb_buffer_pool_wait_free","kind":"metric","meaning":"Bir thread'in buffer pool'da boş sayfa bulunmadığı için dirty page'lerin yazılmasını bekleyip serbest sayfa beklediği durum sayısı; sürekli artması buffer pool baskısını gösterir.","causes":"Küçük buffer pool, yavaş flush/yazma I/O'su, düşük innodb_io_capacity, yüksek yazma yükü ile hızlı dirty page üretimi, checkpoint gecikmesi.","action":"innodb_buffer_pool_size'ı artırın, innodb_io_capacity/io_capacity_max'ı depolamaya göre ayarlayın, yazma I/O performansını iyileştirin, dirty page oranını (innodb_max_dirty_pages_pct) gözden geçirin.","tags":["metric","innodb","buffer-pool","flush"]},{"name":"Threads_running","kind":"metric","meaning":"O anda boşta olmayıp aktif olarak sorgu çalıştıran thread sayısı; sunucudaki anlık eşzamanlı yürütme ve olası çekişme yoğunluğunu gösterir.","causes":"Ani sorgu artışı, yavaş sorguların birikmesi, lock/mutex çekişmesi nedeniyle thread'lerin tıkanması, CPU doygunluğu, sürü etkisi (thundering herd).","action":"Threads_running ani yükseldiğinde yavaş/kilitli sorguları bulun (SHOW PROCESSLIST), sorgu ayarlaması yapın, bağlantı havuzu ve thread pool kullanarak eşzamanlılığı sınırlayın, çekişme kaynağını giderin.","tags":["metric","concurrency","threads","load"]},{"name":"Innodb_row_lock_time_avg","kind":"metric","meaning":"Bir row lock'un elde edilmesi için beklenen ortalama süre (milisaniye); satır düzeyi lock çekişmesinin şiddetini gösterir.","causes":"Aynı satırlara yoğun eşzamanlı erişim, uzun transaction'lar, index eksikliği nedeniyle geniş lock aralıkları, deadlock/lock wait timeout'a yaklaşan bekleyişler.","action":"Transaction süresini kısaltın, uygun index'lerle lock kapsamını daraltın, çekişen erişim desenini yeniden tasarlayın, innodb_lock_wait_timeout ve izolasyon seviyesini gözden geçirin.","tags":["metric","innodb","row-lock","contention"]},{"name":"history list length","kind":"metric","meaning":"InnoDB undo log'unda henüz purge edilmemiş (eski satır sürümlerini tutan) transaction sayısı; MVCC için tutulan eski sürüm birikimini gösterir.","causes":"Uzun süren açık transaction'lar (özellikle uzun okuma transaction'ları), yavaş purge thread, yüksek DML hızı, commit edilmeyen/idle transaction'lar.","action":"Uzun süren ve idle transaction'ları tespit edip sonlandırın, purge thread sayısını (innodb_purge_threads) ayarlayın, uygulamada transaction'ları kısa tutun; yüksek HLL performans ve bloat sorunlarına yol açar.","tags":["metric","innodb","undo","mvcc"]},{"name":"Innodb_data_reads","kind":"metric","meaning":"InnoDB'nin diskten gerçekleştirdiği fiziksel okuma isteklerinin toplam sayısı; buffer pool tarafından karşılanamayıp diske giden okuma yükünü gösterir.","causes":"Küçük buffer pool, soğuk cache, verimsiz sorgular ve büyük taramalar, eksik index, iş kümesinin bellekten büyük olması.","action":"Buffer pool boyutunu artırın, verimsiz sorguları ve eksik index'leri düzeltin, fiziksel okuma trendini buffer pool hit oranıyla birlikte izleyin, I/O performansını iyileştirin.","tags":["metric","innodb","io","read"]},{"name":"Innodb_buffer_pool_read_requests","kind":"metric","meaning":"InnoDB buffer pool'dan yapılan mantıksal okuma isteklerinin toplam sayısı; Innodb_buffer_pool_reads (buffer pool'da bulunamayıp diskten okunan sayfa sayısı) ile birlikte buffer pool hit oranını hesaplamak için kullanılır.","causes":"Yüksek değer yoğun sorgu aktivitesini gösterir. Innodb_buffer_pool_reads'in bu değere oranı yüksekse (hit oranı düşükse) bellek yetersizliği veya verimsiz erişim söz konusudur.","action":"Buffer pool hit oranını (1 - Innodb_buffer_pool_reads / Innodb_buffer_pool_read_requests) izleyin, düşükse buffer pool'u büyütün ve sorguları optimize edin, aşırı mantıksal okuma üreten verimsiz sorguları ayarlayın.","tags":["metric","innodb","buffer-pool","logical-io"]}]},"reference/waits-mssql.json":{"engineId":"mssql","engine":"SQL Server","order":4,"waits":[{"name":"CXPACKET","kind":"wait","meaning":"Paralel sorgu yürütmede thread'lerin senkronizasyonu sırasında oluşan bekleme; paralel plan operatörleri arasında iş dağılımı/eşleşmesi beklenirken görülür.","causes":"Yüksek paralellik derecesi, dengesiz iş dağılımı (skew), sınırsız/yüksek MAXDOP (0) ve düşük cost threshold for parallelism (varsayılan 5), eksik index nedeniyle büyük paralel taramalar, verimsiz planlar.","action":"cost threshold for parallelism ve MAXDOP değerlerini iş yüküne göre ayarlayın, eksik index'leri ve istatistikleri düzeltin, CXPACKET'i tek başına sorun saymayın; gerçek beklemeyi CXCONSUMER ile ayırt ederek verimsiz paralel planları hedefleyin.","tags":["parallelism","cxpacket","query","cpu"]},{"name":"CXCONSUMER","kind":"wait","meaning":"Paralel planda tüketici (consumer) thread'in üretici (producer) thread'lerden veri gelmesini beklemesi; genellikle zararsız bir paralellik beklemesidir.","causes":"Normal paralel yürütme sırasında tüketici thread'in beklemesi, dengesiz veri akışı, üretici tarafındaki gecikme, verimsiz paralel planlar.","action":"CXCONSUMER çoğunlukla iyi huyludur ve tek başına eyleme gerek yoktur; gerçek darboğazı bulmak için üretici tarafındaki asıl bekleme türlerine (IO, LCK vb.) ve plan verimliliğine odaklanın.","tags":["parallelism","cxconsumer","query","benign"]},{"name":"PAGEIOLATCH_SH","kind":"wait","meaning":"Thread, bir veri sayfasını diskten buffer pool'a okurken sayfayı paylaşımlı (SH) modda korumak için latch bekliyor; okuma amaçlı fiziksel I/O beklemesidir.","causes":"Yavaş disk I/O'su, yetersiz bellek (küçük buffer pool), büyük taramalar ve eksik index, soğuk cache, yüksek fiziksel okuma yükü.","action":"Bellek (max server memory) ve buffer pool'u değerlendirin, verimsiz sorguları ve eksik index'leri düzeltin, depolama I/O gecikmesini iyileştirin, en çok okuyan sorguları tespit edip ayarlayın.","tags":["io","pageiolatch","read","buffer-pool"]},{"name":"PAGEIOLATCH_EX","kind":"wait","meaning":"Thread, diskten okunan bir veri sayfasını özel (EX) modda korumak için latch bekliyor; genellikle yazma amaçlı okunacak sayfanın fiziksel I/O'sunu bekler.","causes":"Yavaş disk I/O'su, yoğun yazma iş yükü, yetersiz bellek, checkpoint/lazy writer baskısı, büyük veri değişikliği yapan işlemler.","action":"Depolama yazma/okuma performansını iyileştirin, buffer pool belleğini artırın, yoğun yazan işlemleri toplu ve verimli hale getirin, tempdb ve veri diski I/O'sunu ayrıştırıp ölçün.","tags":["io","pageiolatch","write","buffer-pool"]},{"name":"PAGELATCH_UP","kind":"wait","meaning":"Thread, bellekte zaten bulunan bir sayfayı güncelleme (UP) modunda korumak için latch bekliyor; fiziksel I/O değil, bellekteki sayfaya eşzamanlı erişim çekişmesidir.","causes":"Hot page'lere çekişme, özellikle tempdb sistem sayfaları (PFS/GAM/SGAM) çekişmesi, yoğun eşzamanlı tempdb nesne oluşturma, son sayfa (hot page) ekleme çekişmesi.","action":"tempdb'yi çekirdek sayısına uygun sayıda eşit data file'a bölün, tempdb çekişmesini azaltın, hot page desenlerini dağıtın, gereksiz tempdb kullanımını (spill vb.) giderin.","tags":["pagelatch","tempdb","concurrency","contention"]},{"name":"PAGELATCH_EX","kind":"wait","meaning":"Thread, bellekteki bir sayfayı özel (EX) modda korumak için latch bekliyor; genellikle artan (sıralı) anahtarlı tablolarda son sayfa ekleme çekişmesinde görülür.","causes":"Sıralı/artan anahtarlı index'lerde son sayfa (last-page insert) çekişmesi, tempdb sistem sayfası çekişmesi, hot page'lere yoğun eşzamanlı yazma, yüksek insert hızı.","action":"Son sayfa çekişmesi için OPTIMIZE_FOR_SEQUENTIAL_KEY = ON (SQL Server 2019+) veya anahtar dağıtımı (hash/GUID/ters index) kullanın, tempdb'yi çoklu dosyaya bölün, yoğun insert desenini yeniden tasarlayın.","tags":["pagelatch","last-page-insert","concurrency","contention"]},{"name":"LCK_M_X","kind":"wait","meaning":"Thread, bir kaynak (satır/sayfa/tablo) üzerinde özel (Exclusive) lock almayı bekliyor; genellikle veri değiştirme (UPDATE/DELETE/INSERT) için diğer lock'ların serbest kalmasını bekler.","causes":"Uzun süren transaction'lar, aynı kaynaklara eşzamanlı değişiklik, lock escalation, eksik index nedeniyle geniş lock kapsamı, tıkayan (blocking) oturumlar.","action":"Transaction'ları kısa tutup zamanında commit edin, uygun index'lerle lock kapsamını daraltın, tıkayan sorguyu bulun (sys.dm_exec_requests/blocking), lock escalation ve izolasyon seviyesini gözden geçirin, gerekirse RCSI değerlendirin.","tags":["lock","exclusive","blocking","transaction"]},{"name":"LCK_M_U","kind":"wait","meaning":"Thread, bir kaynak üzerinde güncelleme (Update) lock'u almayı bekliyor; UPDATE tararken satırı okuyup değiştirmeye hazırlanırken diğer lock'ların serbest kalmasını bekler.","causes":"Aynı satırlara eşzamanlı güncelleme, uzun transaction'lar, eksik index nedeniyle çok satırın taranıp kilitlenmesi, tıkayan oturumlar, lock çekişmesi.","action":"UPDATE sorgularına uygun index ekleyerek taranan/kilitlenen satır sayısını azaltın, transaction süresini kısaltın, tıkayan zinciri analiz edin, izolasyon seviyesi ve RCSI seçeneklerini değerlendirin.","tags":["lock","update-lock","blocking","transaction"]},{"name":"WRITELOG","kind":"wait","meaning":"Thread, transaction log kayıtlarının diske yazılmasını (log flush) bekliyor; genellikle commit anında log'un kalıcı hale gelmesini bekler.","causes":"Yavaş log diski I/O'su, çok sık/küçük commit'ler, yüksek yazma yükü, log diskinin veri diskiyle çekişmesi, senkron Always On replikasyonunun etkisi.","action":"Transaction log'unu düşük gecikmeli hızlı diske alın, commit'leri gruplayın (batch), gereksiz sık commit'leri azaltın, delayed durability'yi (uygunsa) değerlendirin, log I/O gecikmesini ölçün.","tags":["log","writelog","commit","io"]},{"name":"ASYNC_NETWORK_IO","kind":"wait","meaning":"SQL Server sonuçları göndermeye hazır ancak istemci verileri yeterince hızlı tüketmediği için ağ/istemci tarafını bekliyor; genellikle uygulama tarafı darboğazıdır.","causes":"İstemci uygulamanın sonuçları yavaş işlemesi (satır satır tüketim), büyük sonuç kümeleri, yavaş ağ, uygulama tarafında RBAR işleme, yetersiz istemci kaynağı.","action":"Uygulamada sonuçları hızlı ve toplu tüketin, gereksiz büyük sonuç kümelerini azaltın (sadece gereken sütun/satır), ağ gecikmesini kontrol edin. Bu genellikle SQL Server değil istemci/ağ sorunudur.","tags":["network","client","application","async"]},{"name":"SOS_SCHEDULER_YIELD","kind":"wait","meaning":"Bir thread, kendisine ayrılan CPU zaman dilimini (quantum) doldurup schedulera gönüllü olarak yer verdiğinde oluşan bekleme; çoğunlukla CPU baskısı veya yoğun CPU tüketen işleme işaret eder.","causes":"CPU'ya bağlı (CPU-bound) yoğun sorgular, yüksek eşzamanlılık ve CPU doygunluğu, spinlock çekişmesi, çok sayıda mantıksal okuma yapan verimsiz sorgular.","action":"CPU tüketen verimsiz sorguları bulup ayarlayın (eksik index, kötü plan), mantıksal okumayı azaltın, CPU kapasitesini ve eşzamanlılığı değerlendirin, sürekli yüksekse donanım/plan darboğazını inceleyin.","tags":["cpu","scheduler","cpu-bound","yield"]},{"name":"RESOURCE_SEMAPHORE","kind":"wait","meaning":"Sorgu, çalışması için gereken bellek belleği hibesini (memory grant) bekliyor; yeterli sorgu belleği serbest kalana kadar yürütme başlayamıyor.","causes":"Aşırı bellek isteyen sorgular (büyük sıralama/hash), yanlış (şişkin) cardinality tahminleri, yetersiz sunucu belleği, eşzamanlı çok sayıda bellek yoğun sorgu, eski istatistikler.","action":"İstatistikleri güncelleyip aşırı bellek hibesi tahminlerini düzeltin, büyük sıralama/hash gerektiren sorguları optimize edin (index, filtre), Resource Governor ve max server memory ayarlarını gözden geçirin, eşzamanlı bellek yoğun yükü sınırlayın.","tags":["memory","memory-grant","query","resource"]},{"name":"THREADPOOL","kind":"wait","meaning":"Yeni bir görev çalıştıracak worker thread bulunamadığı için görevlerin thread havuzundan boş thread beklemesi; ciddi worker thread tükenmesine işaret eden kritik bir bekleme türüdür.","causes":"Uzun süren tıkanmalar (blocking) nedeniyle thread'lerin tutulması, çok yüksek eşzamanlı bağlantı, yetersiz max worker threads, ağır paralellik, deadlock/uzun lock zincirleri.","action":"Tıkanma (blocking) zincirini acilen çözün, eşzamanlı bağlantı sayısını bağlantı havuzuyla yönetin, uzun süren lock'ları giderin, max worker threads ayarını gözden geçirin; DAC üzerinden bağlanıp kök nedeni bulun.","tags":["threadpool","worker-thread","blocking","critical"]},{"name":"HADR_SYNC_COMMIT","kind":"wait","meaning":"Always On senkron replikada, primary'nin transaction'ı commit etmeden önce log kaydının secondary replikaya sertleşmesini (harden) beklemesi; senkron commit gecikmesidir.","causes":"Secondary replika ile yavaş/gecikmeli ağ, secondary'de yavaş log diski I/O'su, aşırı yüklü secondary, uzak coğrafi replika, yüksek yazma hızı.","action":"Replikalar arası ağ gecikmesi ve bant genişliğini iyileştirin, secondary log disk performansını artırın, secondary yükünü dengeleyin, gecikme kritikse senkron/asenkron replika topolojisini gözden geçirin.","tags":["alwayson","replication","sync-commit","hadr"]},{"name":"Page Life Expectancy","kind":"metric","meaning":"Bir veri sayfasının buffer pool'da ortalama kaç saniye kaldığını (bellekten çıkarılmadan) gösteren metrik; bellek baskısının önemli bir göstergesidir.","causes":"Düşük veya hızla düşen PLE; bellek baskısı, verimsiz büyük taramalar, iş kümesinin bellekten büyük olması veya bellek yetersizliği anlamına gelir. NUMA düğümleri ayrı ayrı da değerlendirilmelidir.","action":"Sabit bir eşik yerine PLE trendine ve ani düşüşlere bakın, buffer pool belleğini (max server memory) değerlendirin, çok bellek tüketen verimsiz sorguları ayarlayın, NUMA başına PLE'yi izleyin.","tags":["metric","memory","buffer-pool","ple"]},{"name":"Buffer cache hit ratio","kind":"metric","meaning":"Veri sayfası isteklerinin diske gitmeden buffer cache'ten karşılanma oranı; sayfaların bellekten okunma yüzdesini gösterir.","causes":"Modern sistemlerde bu oran genellikle çok yüksektir (okuma-ahead sayesinde) ve düşük bir değer belirgin bellek baskısına işaret eder. Yüksek oran tek başına iyi performans garantisi vermez.","action":"Bu metriği tek başına değil PLE, PAGEIOLATCH beklemeleri ve fiziksel okuma trendleriyle birlikte yorumlayın; bellek baskısı belirtileri varsa buffer pool belleğini artırın ve verimsiz sorguları düzeltin.","tags":["metric","memory","buffer-pool","ratio"]}]},"reference/waits-mongodb.json":{"engineId":"mongodb","engine":"MongoDB","order":5,"waits":[{"name":"WiredTiger cache used %","kind":"metric","meaning":"WiredTiger depolama motorunun ayrılan iç cache'inin ne kadarının kullanıldığı; verinin bellekte tutulma baskısını gösterir (varsayılan hedef eşik %80 civarıdır).","causes":"İş kümesinin cache'ten büyük olması, cache boyutunun küçük ayarlanması, büyük taramalar, yoğun okuma/yazma, çok sayıda açık transaction.","action":"WiredTiger cache boyutunu (storage.wiredTiger.engineConfig.cacheSizeGB) ve RAM'i değerlendirin, iş kümesini küçültecek index'ler ekleyin, %80 hedef ve %95 eviction eşiğine yaklaşınca eviction baskısını ve gecikmeyi izleyin.","tags":["metric","wiredtiger","cache","memory"]},{"name":"WiredTiger cache dirty %","kind":"metric","meaning":"WiredTiger cache'inde henüz diske yazılmamış (dirty) veri yüzdesi; yazma baskısını ve checkpoint/eviction yükünü gösterir (dirty eviction eşiği genellikle %20 civarıdır).","causes":"Yüksek yazma yükü, yavaş disk I/O'su, büyük/uzun süren yazma işlemleri, checkpoint baskısı, cache'in yazma hızına yetişememesi.","action":"Dirty yüzdesi eviction eşiğine (%20) yaklaşıyorsa disk yazma performansını iyileştirin, yazma yükünü dengeleyin, cache boyutunu değerlendirin, uzun yazma işlemlerini ve checkpoint aralığını gözden geçirin.","tags":["metric","wiredtiger","cache","write"]},{"name":"tickets available (read/write)","kind":"metric","meaning":"WiredTiger'ın eşzamanlı okuma ve yazma işlemleri için verdiği bilet (concurrency ticket) sayısının kalan miktarı; sıfıra düşerse yeni işlemler bilet için kuyruğa girer.","causes":"Yavaş işlemlerin biletleri uzun tutması, disk I/O darboğazı, lock/çekişme, ani yük artışı, uzun süren sorgular nedeniyle biletlerin tükenmesi.","action":"Kalan bilet sıfıra yaklaşıp kuyruk oluşuyorsa yavaş sorguları optimize edin (index ekleyin), disk I/O'sunu iyileştirin, yükü dengeleyin; ticket tükenmesi genelde daha derin bir I/O/çekişme darboğazının belirtisidir.","tags":["metric","wiredtiger","concurrency","tickets"]},{"name":"global lock queue","kind":"metric","meaning":"Global/veritabanı/koleksiyon lock'unu bekleyen okuma (readers) ve yazma (writers) işlemlerinin kuyruk uzunluğu; lock çekişmesi altında bekleyen işlem sayısını gösterir.","causes":"Uzun tutulan lock'lar, yoğun yazma çekişmesi, uzun süren işlemler, DDL işlemleri ve index oluşturmanın başında/sonunda alınan kısa exclusive koleksiyon lock'u (4.2+ hybrid build; foreground build artık yok), yavaş I/O nedeniyle lock'ların uzun tutulması.","action":"Kuyruk sürekli doluyorsa uzun süren işlemleri (currentOp) bulup optimize edin, index oluşturma ve diğer DDL işlemlerini yoğun olmayan zamanlara alın, I/O'yu iyileştirin, çekişen yazma desenlerini gözden geçirin.","tags":["metric","lock","queue","concurrency"]},{"name":"replication lag (secondary)","kind":"metric","meaning":"Bir secondary üyenin primary'nin oplog'unu uygulamada geride kalma süresi (saniye); replica set üyeleri arasındaki veri gecikmesini gösterir.","causes":"Yavaş ağ, secondary'de yavaş disk I/O'su, secondary üzerinde ağır okuma yükü, yüksek primary yazma hızı, yetersiz secondary donanımı, uzun süren işlemler.","action":"rs.printSecondaryReplicationInfo ile gecikmeyi izleyin, ağ ve secondary I/O performansını iyileştirin, secondary yükünü dengeleyin, oplog boyutunu yeterli tutun, write concern gereksinimini gözden geçirin.","tags":["metric","replication","lag","secondary"]},{"name":"oplog window","kind":"metric","meaning":"Oplog'un tuttuğu en eski ve en yeni işlem arasındaki zaman aralığı (saat); bir secondary'nin senkronizasyonu kaçırmadan ne kadar süre geride kalabileceğini gösterir.","causes":"Küçük oplog boyutu, ani yüksek yazma hızı, uzun süre offline kalan secondary'ler, replikasyon yükü artışı.","action":"Oplog penceresi kısaldıysa oplog boyutunu artırın, secondary gecikmesini pencerenin altında tutun, yazma yükünü ve yedekleme/senkron gereksinimlerini gözden geçirin; pencere kaçarsa full resync gerekir.","tags":["metric","replication","oplog","window"]},{"name":"page faults","kind":"metric","meaning":"İşletim sisteminin bellekte olmayan veri sayfalarını diskten getirmesi gereken sayfa hatası (özellikle hard fault) sayısı; verinin bellekten taşıp diske gidişini gösterir.","causes":"İş kümesinin RAM'den büyük olması, yetersiz bellek, büyük taramalar, cache baskısı, diğer süreçlerin bellek tüketimi.","action":"Sunucu belleğini/çalışma kümesini değerlendirin, index ekleyerek taranan veriyi azaltın, WiredTiger cache ve OS belleğini dengeleyin, hard page fault artışını I/O gecikmesiyle birlikte izleyin.","tags":["metric","memory","page-fault","io"]},{"name":"connections current","kind":"metric","meaning":"Sunucuya o an açık olan istemci bağlantılarının sayısı; bağlantı havuzu kullanımını ve maksimuma yaklaşma durumunu gösterir.","causes":"Bağlantı havuzu yanlış yapılandırması, bağlantı sızıntısı, ani istemci artışı, uzun tutulan bağlantılar, mikroservislerden aşırı bağlantı.","action":"Bağlantı sayısını sunucu limitiyle (maxIncomingConnections) karşılaştırın, uygulama tarafında bağlantı havuzunu doğru boyutlandırın, bağlantı sızıntılarını giderin, ani artışları izleyin.","tags":["metric","connections","pool","capacity"]},{"name":"scanAndOrder / COLLSCAN ratio","kind":"metric","meaning":"Bir index kullanmadan koleksiyonu tam tarayan (COLLSCAN) veya bellekte sıralama yapan (scanAndOrder) sorguların oranı; index verimsizliğinin göstergesidir.","causes":"Eksik veya uygun olmayan index'ler, sorguya uymayan sıralama (sort) anahtarları, geniş filtresiz sorgular, kötü sorgu desenleri.","action":"Yavaş sorguları ve planları (explain) inceleyin, sorgu ve sıralama desenlerine uygun bileşik (compound) index'ler ekleyin, COLLSCAN ve scanAndOrder üreten sorguları düzeltin, taranan/dönen doküman oranını izleyin.","tags":["metric","index","collscan","query"]},{"name":"queued operations","kind":"metric","meaning":"Lock veya kaynak beklediği için kuyruğa alınmış (henüz aktif çalışamayan) okuma ve yazma işlemlerinin sayısı; sistemin talebi karşılayamadığını gösterir.","causes":"Lock çekişmesi, ticket tükenmesi, I/O darboğazı, uzun süren sorgular, ani yük artışı, yavaş disk.","action":"Kuyruk büyüyorsa aktif ve uzun süren işlemleri (currentOp) inceleyip optimize edin, index ve I/O iyileştirmesi yapın, yükü dengeleyin, ticket ve lock çekişmesi metrikleriyle birlikte kök nedeni bulun.","tags":["metric","queue","concurrency","load"]}]},"reference/waits-redis.json":{"engineId":"redis","engine":"Redis","order":6,"waits":[{"name":"keyspace hit ratio","kind":"metric","meaning":"keyspace_hits ve keyspace_misses değerlerinden hesaplanan, anahtar aramalarının bellekte bulunma oranı; Redis'in cache olarak ne kadar etkili çalıştığını gösterir.","causes":"Düşük oran; yetersiz bellek nedeniyle eviction, kısa TTL'ler, soğuk cache, cache'e alınmamış çok sayıda benzersiz anahtar sorgusu veya yanlış anahtar tasarımına işaret eder.","action":"Hit oranını hits/(hits+misses) ile izleyin, düşükse bellek/eviction politikasını ve TTL'leri gözden geçirin, sık erişilen veriyi önceden ısıtın, anahtar tasarımını ve cache stratejisini iyileştirin.","tags":["metric","cache","hit-ratio","keyspace"]},{"name":"evicted_keys","kind":"metric","meaning":"maxmemory sınırına ulaşıldığında eviction politikası gereği bellekten çıkarılan (silinen) anahtar sayısı; bellek baskısının doğrudan göstergesidir.","causes":"maxmemory sınırının aşılması, yetersiz bellek, TTL'siz anahtar birikimi, veri hacminin bellekten büyük olması, uygun olmayan eviction politikası.","action":"Sürekli artan eviction'da belleği artırın veya veri hacmini azaltın, maxmemory-policy'yi (ör. allkeys-lru/volatile-lru) iş yüküne göre seçin, TTL kullanımını ve büyük anahtarları gözden geçirin.","tags":["metric","memory","eviction","maxmemory"]},{"name":"blocked_clients","kind":"metric","meaning":"BLPOP, BRPOP, WAIT, XREAD BLOCK gibi bloklayan komutlarla bir olay/veri bekleyen istemcilerin sayısı; kuyruk tüketici desenlerinde normaldir ancak anormal artış sorun işaretidir.","causes":"Bloklayan liste/stream komutlarını kullanan tüketiciler, üretici tarafında veri gelmemesi, WAIT ile replika onayı beklenmesi, tüketici-üretici dengesizliği.","action":"Bloklayan istemci sayısını beklenen tüketici modeliyle karşılaştırın, anormal artışta üretici tarafını ve replikasyon onaylarını inceleyin, kuyruk tüketim hızını dengeleyin.","tags":["metric","clients","blocking","queue"]},{"name":"mem_fragmentation_ratio","kind":"metric","meaning":"İşletim sisteminin Redis'e ayırdığı fiziksel belleğin (RSS), Redis'in gerçekten kullandığı belleğe oranı; bellek parçalanmasını veya takas (swap) durumunu gösterir.","causes":"1'in belirgin üstü değerler bellek parçalanmasına, 1'in altındaki değerler ise Redis'in swap'e (diske) taşındığına işaret eder. Değişken boyutlu anahtarlar, silme/ekleme döngüleri parçalanmayı artırır.","action":"Yüksek parçalanmada activedefrag'i etkinleştirmeyi veya yeniden başlatmayı değerlendirin, 1'in altındaysa swap'i araştırın ve belleği artırın, allocator (jemalloc) davranışını ve büyük anahtar desenlerini gözden geçirin.","tags":["metric","memory","fragmentation","swap"]},{"name":"instantaneous_ops_per_sec","kind":"metric","meaning":"Redis'in o an saniyede işlediği komut sayısı (anlık throughput); iş yükü yoğunluğunu ve ani trafik değişimlerini gösterir.","causes":"Ani trafik artışı, toplu iş (batch) yükü, verimsiz istemci erişim desenleri, tekil komut yerine pipeline kullanılmaması, yoğun okuma/yazma dalgaları.","action":"Throughput'u gecikme (latency) ve CPU ile birlikte izleyin, ani düşüş/artışları trafik ve yavaş komutlarla ilişkilendirin, pipeline/batch kullanarak verimliliği artırın, kapasiteyi planlayın.","tags":["metric","throughput","ops","load"]},{"name":"rdb_last_bgsave_status","kind":"metric","meaning":"Son RDB arka plan kaydetme (BGSAVE) işleminin başarı durumu; persistence snapshot'ının sağlıklı alınıp alınmadığını gösterir.","causes":"Başarısız (err) durum; disk dolu/yetersiz alan, fork için yetersiz bellek, disk I/O hatası, izin sorunları veya aşırı yük nedeniyle olabilir.","action":"Durum 'err' ise disk alanını, fork için gereken belleği (overcommit ayarı) ve disk sağlığını kontrol edin, log'ları inceleyin; başarısız BGSAVE veri kaybı riski oluşturur, kalıcılık yapılandırmasını gözden geçirin.","tags":["metric","persistence","rdb","bgsave"]},{"name":"master_link_status","kind":"metric","meaning":"Bir replikanın master'a olan replikasyon bağlantısının durumu (up/down); replika ile master arasındaki bağlantının sağlıklı olup olmadığını gösterir.","causes":"'down' durum; ağ kesintisi, master erişilemezliği, replikasyon senkronizasyon hatası, kimlik doğrulama sorunu veya master aşırı yükünden kaynaklanabilir.","action":"Durum 'down' ise ağ bağlantısını, master erişilebilirliğini ve auth ayarlarını kontrol edin, replika log'larını inceleyin, master_repl_offset gecikmesini izleyin, senkronizasyonun tamamlandığını doğrulayın.","tags":["metric","replication","master-link","availability"]},{"name":"latency (slowlog)","kind":"metric","meaning":"Slowlog ve latency izleme ile tespit edilen, belirlenen eşiği aşan yavaş komutların gecikmesi; tek thread'li Redis'te bir komutun diğerlerini tıkama riskini gösterir.","causes":"Yüksek zaman karmaşıklığı olan komutlar (KEYS, büyük SORT, büyük koleksiyonlarda SMEMBERS/HGETALL), büyük anahtarlar, yavaş Lua script'leri, fork/kalıcılık duraklamaları, swap.","action":"SLOWLOG ve LATENCY komutlarıyla yavaş komutları bulun, O(N) komutları (KEYS yerine SCAN) ve büyük anahtarları giderin, script'leri optimize edin, fork/AOF/RDB kaynaklı duraklamaları izleyin.","tags":["metric","latency","slowlog","performance"]},{"name":"expired_keys","kind":"metric","meaning":"TTL süresi dolduğu için silinen anahtarların toplam sayısı; TTL tabanlı sona erme davranışının ve bellek geri kazanımının göstergesidir.","causes":"TTL atanmış anahtarların süresinin dolması normaldir. Ani değişimler TTL politikası değişikliğine, toplu anahtar sona ermesine veya beklenmedik silme desenlerine işaret edebilir.","action":"Expired ve evicted ayrımını yapın (expired sağlıklı TTL, evicted bellek baskısıdır), ani expire dalgalarının cache miss ve yük üzerindeki etkisini izleyin, TTL dağılımını dengeleyin.","tags":["metric","ttl","expiration","keyspace"]},{"name":"connected_clients vs maxclients","kind":"metric","meaning":"O an bağlı istemci sayısının yapılandırılan maxclients sınırına yakınlığı; bağlantı kapasitesinin tükenme riskini gösterir.","causes":"Bağlantı sızıntısı, bağlantı havuzu yanlış yapılandırması, ani istemci artışı, uzun tutulan boşta bağlantılar, çok sayıda mikroservis bağlantısı.","action":"Bağlı istemciyi maxclients ile kıyaslayın, sınıra yaklaşınca bağlantı havuzunu doğru boyutlandırın, bağlantı sızıntılarını giderin, boşta bağlantı zaman aşımını ayarlayın, gerekirse maxclients'ı artırın.","tags":["metric","connections","maxclients","capacity"]}]},"reference/waits-elasticsearch.json":{"engineId":"elasticsearch","engine":"Elasticsearch","order":7,"waits":[{"name":"JVM heap used %","kind":"metric","meaning":"Bir düğümün JVM heap'inin kullanım yüzdesi; yüksek ve sürekli dolu heap, bellek baskısı ve ağır GC riski anlamına gelir.","causes":"Aşırı fielddata/aggregation belleği, çok fazla shard, büyük bulk/sorgu yükü, büyük mapping'ler, yetersiz heap boyutu, bellek sızıntısı desenleri.","action":"Heap kullanımını izleyin (özellikle GC sonrası %75 üstü kalıcıysa müdahale edin), shard sayısını azaltın, ağır aggregation ve fielddata kullanımını sınırlayın, heap'i RAM'in en fazla yarısı ve 32GB altında tutun.","tags":["metric","jvm","heap","memory"]},{"name":"GC duration/frequency","kind":"metric","meaning":"JVM garbage collection (GC) işlemlerinin süresi ve sıklığı; uzun/sık GC duraklamaları düğümün yanıt vermemesine ve performans düşüşüne yol açar.","causes":"Yüksek heap baskısı, büyük eski nesil (old gen) birikimi, ağır aggregation/fielddata, yetersiz heap, çok fazla shard, uzun süren büyük sorgular.","action":"Uzun (özellikle old GC) duraklamaların kök nedeni olan heap baskısını giderin, bellek tüketen sorguları optimize edin, shard sayısını azaltın; sık ve uzun GC düğüm kararsızlığının erken uyarısıdır.","tags":["metric","jvm","gc","pause"]},{"name":"thread_pool write rejected","kind":"metric","meaning":"Write (indexing/bulk) thread havuzunun kuyruğu dolduğu için reddedilen indeksleme isteklerinin sayısı; düğümün yazma yükünü karşılayamadığını gösterir.","causes":"Aşırı bulk/indeksleme hızı, yavaş disk I/O'su, çok küçük bulk yerine çok sayıda küçük istek, yetersiz düğüm kapasitesi, refresh baskısı.","action":"İndeksleme isteklerini uygun boyutlu bulk halinde gönderin, yazma hızını düğüm kapasitesine göre yavaşlatın (backoff), disk I/O'sunu iyileştirin, refresh_interval'i artırın, kapasiteyi ölçekleyin.","tags":["metric","thread-pool","indexing","rejection"]},{"name":"thread_pool search rejected","kind":"metric","meaning":"Search thread havuzunun kuyruğu dolduğu için reddedilen arama isteklerinin sayısı; düğümün sorgu yükünü karşılayamadığını gösterir.","causes":"Aşırı eşzamanlı sorgu, ağır/yavaş aggregation'lar, çok fazla shard'a dokunulması, verimsiz sorgular, yetersiz düğüm/CPU kapasitesi.","action":"Sorgu eşzamanlılığını istemci tarafında sınırlayın, ağır sorguları ve aggregation'ları optimize edin, gereksiz shard'a dokunmayı azaltın (routing/filtreleme), yeni düğüm ekleyip replica shard sayısını artırın (aramalar replica shard'lara da dağılır), kapasiteyi ölçekleyin.","tags":["metric","thread-pool","search","rejection"]},{"name":"indexing/search latency","kind":"metric","meaning":"İndeksleme ve arama işlemlerinin ortalama gecikmesi; index_time_in_millis ve query_time_in_millis metriklerinden türetilen, kullanıcıya yansıyan yanıt süresini gösterir.","causes":"Yavaş disk I/O'su, ağır sorgular/aggregation'lar, GC duraklamaları, yüksek shard sayısı, refresh/merge baskısı, yetersiz kaynak.","action":"Yavaş sorguları slow log ile bulup optimize edin, indeksleme için bulk ve refresh_interval ayarını yapın, disk ve heap performansını iyileştirin, gecikmeyi thread pool reddi ve GC ile birlikte yorumlayın.","tags":["metric","latency","indexing","search"]},{"name":"refresh/flush time","kind":"metric","meaning":"Yeni belgeleri aranabilir yapan refresh ve translog'u Lucene'e kalıcılaştıran flush işlemlerinin harcadığı süre; indeksleme ek yükünü gösterir.","causes":"Çok sık refresh (düşük refresh_interval), yavaş disk I/O'su, yoğun indeksleme, büyük translog, çok sayıda küçük segment.","action":"Yoğun indeksleme sırasında refresh_interval'i artırın (ör. 30s) veya geçici kapatın, disk I/O'sunu iyileştirin, bulk boyutunu ayarlayın, segment birleştirme (merge) davranışını gözden geçirin.","tags":["metric","refresh","flush","indexing"]},{"name":"unassigned shards","kind":"metric","meaning":"Herhangi bir düğüme atanmamış shard sayısı; primary unassigned shard veri erişilemezliği (kırmızı sağlık), replika unassigned ise dayanıklılık/kapasite riski anlamına gelir.","causes":"Düğüm arızası/ayrılması, disk watermark aşımı, yetersiz düğüm sayısı için replika ayarı, allocation kuralları/filtreleri, shard kurtarma sırasındaki gecikmeler.","action":"Cluster allocation explain API ile atanamama nedenini bulun, arızalı düğümleri kurtarın, disk alanı/watermark sorunlarını giderin, replika sayısı ve allocation kurallarını gözden geçirin; kırmızı duruma öncelik verin.","tags":["metric","shards","allocation","cluster-health"]},{"name":"disk watermark %","kind":"metric","meaning":"Düğüm disk kullanımının, Elasticsearch'ün shard yerleşimini etkileyen low/high/flood-stage eşiklerine (varsayılan %85/%90/%95) göre durumu.","causes":"Disk dolması, veri büyümesi, yetersiz depolama, dengesiz shard dağılımı, eski index'lerin temizlenmemesi.","action":"Low watermark'ta düğüme yeni shard atanmaz, high watermark'ta shard'lar başka düğümlere taşınır, flood-stage'de index'ler salt-okunur olur; disk boşaltın (eski index'leri silin/ILM kullanın), depolamayı büyütün, shard dağılımını dengeleyin, watermark eşiklerini izleyin.","tags":["metric","disk","watermark","storage"]},{"name":"fielddata/query cache evictions","kind":"metric","meaning":"Fielddata cache ve query (filter) cache'inden bellek sınırı nedeniyle çıkarılan (eviction) giriş sayısı; cache verimsizliğini ve bellek baskısını gösterir.","causes":"Yüksek fielddata kullanımı (text alanlarda sıralama/aggregation), küçük cache sınırları, çok çeşitli sorgu filtreleri, bellek baskısı, tekrar kullanılmayan filtreler.","action":"Text alanlarda fielddata yerine keyword/doc_values kullanın, ağır fielddata aggregation'larını sınırlayın, cache boyutlarını gözden geçirin, sık eviction heap baskısıyla birlikte değerlendirilmeli.","tags":["metric","cache","fielddata","eviction"]},{"name":"circuit breaker tripped","kind":"metric","meaning":"Bir isteğin belleği aşacağını öngören circuit breaker'ların (parent/fielddata/request breaker) devreye girip isteği reddetme sayısı; düğümü OOM'dan koruyan bir güvenlik mekanizmasıdır.","causes":"Aşırı bellek isteyen aggregation/sorgular, yüksek fielddata kullanımı, büyük bulk istekleri, genel heap baskısı, çok büyük sonuç kümeleri.","action":"Circuit breaker tetiklenmelerini heap baskısı belirtisi olarak alın, bellek tüketen sorguları optimize edin, fielddata/aggregation kullanımını azaltın, bulk boyutunu düşürün, heap'i ve shard sayısını gözden geçirin.","tags":["metric","circuit-breaker","memory","oom"]},{"name":"pending tasks","kind":"metric","meaning":"Master düğümün işlemeyi bekleyen küme durumu (cluster state) güncelleme görevlerinin kuyruğu; master'ın küme yönetim yüküne yetişememesini gösterir.","causes":"Çok sayıda index/shard, sık mapping/ayar değişikliği, master düğüm kaynak yetersizliği, büyük küme durumu, ağ/master seçimi sorunları.","action":"Sürekli dolu kuyrukta shard/index sayısını azaltın, sık dinamik mapping güncellemelerini sınırlayın, ayrı adanmış master düğümleri kullanın, küme durumu boyutunu ve master kaynaklarını gözden geçirin.","tags":["metric","master","cluster-state","queue"]}]},"reference/alerts-oracle.json":{"engineId":"oracle","engine":"Oracle Database","order":1,"alerts":[{"metric":"Buffer cache hit ratio","warn":"< %95","crit":"< %90","tool":"V$SYSSTAT / V$BUFFER_POOL_STATISTICS","note":"Buffer cache hit oranı, veri bloklarının diske gitmeden bellekten okunma yüzdesini gösterir. Düşük değerler fiziksel okumaların arttığına ve SGA'nın küçük kaldığına işaret eder. Tek başına yanıltıcı olabilir; her zaman AWR raporundaki fiziksel okumalarla birlikte değerlendirin.","tags":["bellek","cache","sga"]},{"metric":"Tablespace kullanımı (%used)","warn":"> %85","crit":"> %95","tool":"DBA_TABLESPACE_USAGE_METRICS","note":"Tablespace doluluğu %100'e ulaşırsa yeni extent alınamaz ve işlemler ORA-01653 gibi hatalarla durur. Autoextend açık olsa bile disk sınırına dikkat edin. DBA_TABLESPACE_USAGE_METRICS view'ı hem otomatik büyüyen hem de sabit dosyalar için doğru yüzdeyi verir.","tags":["disk","tablespace","kapasite"]},{"metric":"PGA bellek kullanımı","warn":"> %90 pga_aggregate_target","crit":"> %100 (over-alloc)","tool":"V$PGASTAT / V$PGA_TARGET_ADVICE","note":"PGA hedefi aşıldığında sıralama ve hash işlemleri diske (temp) taşar ve sorgular yavaşlar. over allocation count değerinin sürekli artması hedefin yetersiz olduğunu gösterir. Sunucu belleğine göre pga_aggregate_target ayarını gözden geçirin.","tags":["bellek","pga","temp"]},{"metric":"TEMP tablespace kullanımı","warn":"> %80","crit":"> %95","tool":"V$TEMPSEG_USAGE / V$SORT_SEGMENT / DBA_TEMP_FREE_SPACE","note":"TEMP alanı büyük sıralama, hash join ve global temporary table işlemleri için kullanılır. Dolması durumunda ORA-01652 hatası alınır ve sorgular başarısız olur. Ani dolmalar genellikle kötü plan seçen veya çok fazla veri sıralayan tek bir sorgudan kaynaklanır.","tags":["temp","disk","sirala"]},{"metric":"Average Active Sessions (AAS)","warn":"> CPU çekirdek sayısı","crit":"> 2x CPU çekirdek sayısı","tool":"V$ACTIVE_SESSION_HISTORY / OEM","note":"Ortalama aktif oturum sayısı, veritabanının o anki yükünü tek bir sayıyla özetler. Değer CPU çekirdek sayısını aşarsa oturumlar CPU veya wait event'ler için kuyrukta bekliyor demektir. Sürekli çekirdek sayısının katı seyrediyorsa darboğaz analizi gerekir.","tags":["cpu","yuk","oturum"]},{"metric":"Data Guard apply lag","warn":"> 60 sn","crit":"> 300 sn","tool":"V$DATAGUARD_STATS (apply lag)","note":"Apply lag, standby veritabanının primary'nin gerisinde kaldığı süredir. Yüksek apply lag, failover sırasında uygulanacak redo miktarını artırarak kurtarma süresini (RTO) uzatır; redo standby'a ulaşmışsa veri kaybı olmaz. Olası veri kaybını (RPO) transport lag belirler. Transport lag ile birlikte inceleyerek ağ mı yoksa redo apply mı yavaş belirleyin.","tags":["replikasyon","dataguard","lag"]},{"metric":"Fast Recovery Area (FRA) kullanımı","warn":"> %85","crit":"> %95","tool":"V$RECOVERY_FILE_DEST / V$RECOVERY_AREA_USAGE","note":"FRA dolduğunda arşiv log üretimi durur ve tüm veritabanı asılır (hang). Bu, üretim sistemlerinde en sık görülen kesinti nedenlerinden biridir. RMAN silme politikalarını ve db_recovery_file_dest_size değerini düzenli kontrol edin.","tags":["disk","fra","arsiv"]},{"metric":"Blocking session sayısı","warn":">= 1 (30 sn üzeri)","crit":">= 1 (120 sn üzeri)","tool":"V$LOCK / V$SESSION (blocking_session)","note":"Bir oturumun tuttuğu lock başka oturumları beklettiğinde uygulama genelinde zincirleme yavaşlama oluşur. Uzun süren bloklamalar genellikle commit edilmemiş transaction'lardan veya uygulama hatalarından kaynaklanır. Bloklama zincirinin kök oturumunu bulup gerekirse sonlandırın.","tags":["kilit","bloklama","concurrency"]},{"metric":"Invalid object sayısı","warn":"> 0","crit":"> 50","tool":"DBA_OBJECTS (status='INVALID')","note":"Geçersiz paket, view veya trigger'lar çalışma anında beklenmedik hatalara yol açabilir. Genellikle bir DDL değişikliği sonrası ortaya çıkar. UTL_RECOMP.RECOMP_PARALLEL veya utlrp.sql ile yeniden derleyerek çözün ve kalıcı geçersizlerin kök nedenini araştırın.","tags":["nesne","derleme","bakim"]},{"metric":"En uzun süren sorgu","warn":"> 5 dk","crit":"> 30 dk","tool":"V$SQL / V$SESSION_LONGOPS","note":"Uzun süren tek bir sorgu, kaynakları tekeline alarak diğer işlemleri de yavaşlatabilir. Batch işleri hariç, OLTP sistemlerde dakikalarca süren sorgular genelde eksik index veya kötü plandan kaynaklanır. SQL Monitor raporuyla planı ve gerçek satır sayılarını inceleyin.","tags":["sorgu","performans","sql"]},{"metric":"Alert log ORA hataları","warn":">= 1 (kritik olmayan)","crit":"ORA-00600 / ORA-07445 / ORA-04031","tool":"alert log / V$DIAG_ALERT_EXT","note":"Alert log, veritabanının sağlık günlüğüdür. ORA-00600 ve ORA-07445 iç hatalar olup olası veri bozulmasına, ORA-04031 ise shared pool bellek yetersizliğine işaret eder. Bu hatalar görülürse hemen incelenmeli ve gerekirse Oracle Support ile paylaşılmalıdır.","tags":["hata","alertlog","izleme"]},{"metric":"Redo log switch sıklığı","warn":"> 6 / saat","crit":"> 12 / saat","tool":"V$LOG_HISTORY","note":"Çok sık redo log switch, log dosyalarının küçük olduğuna ve checkpoint baskısına işaret eder. İdeal olarak yoğun saatlerde 15-20 dakikada bir switch beklenir. Aşırı sık switch, IO ve arşivleme yükünü artırır; redo log grup boyutlarını büyütmeyi değerlendirin.","tags":["redo","io","checkpoint"]},{"metric":"Son başarılı RMAN yedeğinin yaşı","warn":"> 24 saat","crit":"> 48 saat","tool":"V$RMAN_BACKUP_JOB_DETAILS","note":"Yedek yaşı, kurtarabileceğiniz en yakın noktayı belirler ve doğrudan veri kaybı riskini gösterir. Başarısız veya atlanmış yedekler fark edilmezse felaket anında geri dönülemez. Arşiv log yedeklerini de ayrıca izleyerek point-in-time recovery kabiliyetini garanti edin.","tags":["yedek","rman","kurtarma"]},{"metric":"Disk IO latency (db file sequential read)","warn":"> 10 ms","crit":"> 20 ms","tool":"V$SYSTEM_EVENT / AWR","note":"Tek blok okumaların ortalama bekleme süresi depolama katmanının performansını gösterir. Modern flash/SSD sistemlerde bu değer birkaç milisaniye olmalıdır. Sürekli yüksek latency, depolama darboğazına veya aşırı fiziksel okumaya işaret eder; SGA ve depolama katmanını birlikte değerlendirin.","tags":["io","disk","latency"]}]},"reference/alerts-postgres.json":{"engineId":"postgres","engine":"PostgreSQL","order":2,"alerts":[{"metric":"Cache hit ratio","warn":"< %99","crit":"< %95","tool":"pg_stat_database / postgres_exporter","note":"Cache hit oranı, blokların yalnızca shared_buffers'tan karşılanma yüzdesidir; işletim sistemi önbelleğinden gelen okumalar da blks_read olarak sayılır, bu yüzden oran gerçek disk okumasını olduğundan kötü gösterebilir. PostgreSQL'de sağlıklı OLTP sistemlerde bu oran %99'un üzerinde olmalıdır. Düşük değerler yetersiz bellek veya soğuk önbelleğe işaret eder; blks_hit ve blks_read oranından hesaplanır.","tags":["bellek","cache"]},{"metric":"Bağlantı sayısı (connections vs max_connections)","warn":"> %80","crit":"> %90","tool":"pg_stat_activity / max_connections","note":"Aktif bağlantıların max_connections limitine yaklaşması yeni bağlantı hatalarına yol açar. Her bağlantı bellek tükettiği için yüksek sayı aynı zamanda bellek baskısı yaratır. PgBouncer gibi bir bağlantı havuzu kullanarak backend sayısını düşük tutmak önerilir.","tags":["baglanti","limit","havuz"]},{"metric":"Replication lag","warn":"> 10 MB","crit":"> 100 MB","tool":"pg_stat_replication (replay_lag / lsn diff)","note":"Replikasyon gecikmesi, standby sunucunun primary'nin gerisinde kaldığı WAL byte miktarıdır. Yüksek lag, okuma replikalarında bayat veri ve failover'da veri kaybı riski demektir. LSN farkını byte olarak ve replay_lag süresini birlikte izleyin.","tags":["replikasyon","lag","standby"]},{"metric":"En uzun transaction yaşı","warn":"> 5 dk","crit":"> 30 dk","tool":"pg_stat_activity (xact_start)","note":"Uzun süren açık transaction'lar, VACUUM'un dead tuple'ları temizlemesini engeller ve tablo bloat'ına yol açar. Ayrıca 'idle in transaction' durumundaki oturumlar lock'ları gereksiz yere tutar. Bu tür oturumları tespit edip idle_in_transaction_session_timeout ile sınırlayın.","tags":["sorgu","vacuum","islem"]},{"metric":"Deadlocks","warn":"> 1 / dk","crit":"> 5 / dk","tool":"pg_stat_database (deadlocks)","note":"Deadlock, iki transaction'ın birbirinin lock'unu beklemesiyle oluşur ve PostgreSQL biri iptal ederek çözer. Ara sıra görülebilir ancak sık deadlock uygulamada tutarsız lock sıralamasına işaret eder. log_lock_waits açarak hangi sorguların çakıştığını inceleyin.","tags":["kilit","deadlock","concurrency"]},{"metric":"Temp file kullanımı","warn":"> 1 GB / saat","crit":"> 10 GB / saat","tool":"pg_stat_database (temp_bytes)","note":"Geçici dosyalar, work_mem'e sığmayan sıralama ve hash işlemlerinin diske taşmasıyla oluşur. Yüksek temp kullanımı hem yavaşlık hem de disk baskısı yaratır. Sık taşma yaşayan sorgular için work_mem değerini artırmayı veya sorguyu optimize etmeyi değerlendirin.","tags":["temp","disk","work_mem"]},{"metric":"Autovacuum gecikmesi (dead tuples)","warn":"> %10 dead tuple","crit":"> %20 dead tuple","tool":"pg_stat_user_tables (n_dead_tup)","note":"Dead tuple oranının yükselmesi autovacuum'un yetişemediğini ve tablo bloat'ının arttığını gösterir. Bloat'lı tablolar hem yer kaplar hem de taramaları yavaşlatır. Yoğun tablolarda autovacuum_vacuum_scale_factor değerini düşürerek daha sık temizlik yapılmasını sağlayın.","tags":["vacuum","bloat","bakim"]},{"metric":"Disk kullanımı (data dizini)","warn":"> %85","crit":"> %95","tool":"df / node_exporter","note":"PostgreSQL disk dolmadan önce kendini koruyan bir mekanizma sunmaz. Veri diski dolunca yazmalar 'could not extend file' / 53100 hatasıyla başarısız olur; WAL (pg_wal) diski dolarsa sunucu PANIC ile kapanır. WAL ve geçici dosyalar ani büyümelere neden olabilir; erken müdahale kritiktir.","tags":["disk","kapasite"]},{"metric":"WAL birikimi (replication slot lag)","warn":"> 1 GB","crit":"> 10 GB","tool":"pg_replication_slots (restart_lsn)","note":"Kullanılmayan veya geri kalan bir replication slot, WAL dosyalarının silinmesini engeller ve pg_wal dizinini şişirir. Bu durum diskin dolmasıyla sonuçlanabilir. Kullanılmayan (inactive) slot'ları tespit edip temizleyin ve max_slot_wal_keep_size ile üst sınır koyun.","tags":["wal","slot","disk"]},{"metric":"Checkpoint sıklığı (requested checkpoints)","warn":"> %10 requested oranı","crit":"> %30 requested oranı","tool":"PG16 ve öncesi: pg_stat_bgwriter (checkpoints_req) / PG17+: pg_stat_checkpointer (num_requested)","note":"İstenen (requested) checkpoint'lerin zamanlanmışlara oranı yükseldiğinde max_wal_size yetersiz kalıyor demektir. Sık checkpoint, IO dalgalanmaları ve performans düşüşü yaratır. max_wal_size ve checkpoint_completion_target ayarlarını gözden geçirerek yükü yayın.","tags":["checkpoint","wal","io"]},{"metric":"Son başarılı yedeğin yaşı","warn":"> 24 saat","crit":"> 48 saat","tool":"pgBackRest / barman info","note":"Yedek yaşı, geri dönebileceğiniz en son noktayı belirler ve doğrudan RPO'nuzu ifade eder. Yedek zincirinin ve WAL arşivinin kesintisiz olması point-in-time recovery için şarttır. Yedeklerin sadece alınması değil, düzenli restore testiyle geçerliliği de doğrulanmalıdır.","tags":["yedek","kurtarma","rpo"]},{"metric":"Disk IO latency","warn":"> 10 ms","crit":"> 20 ms","tool":"node_exporter / iostat","note":"Depolama okuma/yazma gecikmesi, sorgu sürelerini doğrudan etkiler. Modern SSD sistemlerde bu değer birkaç milisaniye olmalıdır. Sürekli yüksek latency, disk darboğazına veya aşırı fiziksel okumaya işaret eder; shared_buffers ve depolama katmanını birlikte değerlendirin.","tags":["io","disk","latency"]},{"metric":"Transaction ID wraparound (age)","warn":"> 1 milyar","crit":"> 1.5 milyar","tool":"pg_database (age(datfrozenxid))","note":"Transaction ID yaşı 2 milyara yaklaşırsa PostgreSQL veri kaybını önlemek için tüm yazmaları durdurur (wraparound koruması). Bu, en tehlikeli PostgreSQL arızalarından biridir. datfrozenxid yaşını izleyin ve autovacuum'un freeze işlemlerini aksatmadığından emin olun.","tags":["wraparound","vacuum","kritik"]}]},"reference/alerts-mysql.json":{"engineId":"mysql","engine":"MySQL","order":3,"alerts":[{"metric":"InnoDB buffer pool hit ratio","warn":"< %99","crit":"< %95","tool":"SHOW ENGINE INNODB STATUS / mysqld_exporter","note":"Buffer pool hit oranı, veri ve index sayfalarının diske gitmeden bellekten okunma yüzdesidir. Düşük değerler innodb_buffer_pool_size'ın çalışma setine göre küçük kaldığını gösterir. Adanmış bir sunucuda genellikle belleğin ~%70-80'i buffer pool'a ayrılır (paylaşımlı sunucuda daha az).","tags":["bellek","cache","innodb"]},{"metric":"Bağlantı sayısı (Threads_connected vs max_connections)","warn":"> %80","crit":"> %90","tool":"SHOW STATUS / max_connections","note":"Bağlantı sayısının max_connections limitine yaklaşması yeni bağlantıların 'Too many connections' hatasıyla reddedilmesine yol açar. Max_used_connections değeri geçmiş tepe noktayı gösterir. Uygulama tarafında bağlantı havuzu kullanarak eş zamanlı bağlantıları kontrol altında tutun.","tags":["baglanti","limit","thread"]},{"metric":"Replica gecikmesi (Seconds_Behind_Source)","warn":"> 30 sn","crit":"> 300 sn","tool":"SHOW REPLICA STATUS","note":"Seconds_Behind_Source, replikanın kaynağın ne kadar gerisinde olduğunu saniye cinsinden verir. Yüksek gecikme okuma replikalarında bayat veri ve failover riski demektir. Değer tek thread'li uygulamada büyük işlemlerde yanıltıcı olabilir; GTID farkıyla birlikte doğrulayın.","tags":["replikasyon","lag","replica"]},{"metric":"InnoDB row lock bekleme süresi","warn":"avg > 1 sn","crit":"avg > 5 sn","tool":"SHOW STATUS (Innodb_row_lock_time_avg)","note":"Ortalama row lock bekleme süresi, transaction'ların birbirini ne kadar beklettiğini gösterir. Yüksek değerler yoğun çakışan güncellemelere veya uzun süren transaction'lara işaret eder. Innodb_row_lock_waits sayısı ile birlikte inceleyerek hangi sorguların çakıştığını performance_schema'dan bulun.","tags":["kilit","bloklama","innodb"]},{"metric":"History list length (undo)","warn":"> 100000","crit":"> 1000000","tool":"SHOW ENGINE INNODB STATUS","note":"History list length, temizlenmemiş undo kayıtlarının sayısıdır ve uzun süren açık transaction'lar yüzünden birikir. Yüksek değer, purge işleminin geri kaldığını ve MVCC nedeniyle okuma performansının düştüğünü gösterir. Uzun süren transaction'ları bulup sonlandırarak listenin küçülmesini sağlayın.","tags":["undo","islem","mvcc"]},{"metric":"Başarısız bağlantılar (Aborted_connects)","warn":"> 5 / dk","crit":"> 20 / dk","tool":"SHOW STATUS (Aborted_connects)","note":"Aborted_connects, kimlik doğrulama veya el sıkışma aşamasında başarısız olan bağlantıları sayar. Ani artışlar yanlış parola, ağ sorunu veya olası saldırı girişimine işaret edebilir. Aborted_clients ile birlikte inceleyerek bağlantının nerede koptuğunu belirleyin.","tags":["baglanti","hata","guvenlik"]},{"metric":"Diske yazılan geçici tablolar","warn":"> %25 oran","crit":"> %50 oran","tool":"SHOW STATUS (Created_tmp_disk_tables)","note":"Bellekteki geçici tabloların diske taşma oranı, sorguların tmp_table_size sınırını aştığını gösterir. Diske yazılan geçici tablolar sorguları belirgin şekilde yavaşlatır. GROUP BY ve BLOB/TEXT içeren sorguları optimize edin ve tmp_table_size ile max_heap_table_size değerlerini artırmayı değerlendirin.","tags":["temp","disk","sorgu"]},{"metric":"Yavaş sorgular (slow queries)","warn":"> 5 / dk","crit":"> 20 / dk","tool":"slow query log / Slow_queries status","note":"long_query_time eşiğini aşan sorgular slow query log'a yazılır ve performans sorunlarının ana kaynağıdır. Sık yavaş sorgu, eksik index veya kötü yazılmış sorgulara işaret eder. pt-query-digest ile logu analiz ederek en pahalı sorguları önceliklendirin.","tags":["sorgu","performans","slowlog"]},{"metric":"CPU kullanımı","warn":"> %80","crit":"> %90","tool":"node_exporter / top","note":"Sürekli yüksek CPU kullanımı, ağır sorgular, index eksikliği veya aşırı bağlantıdan kaynaklanabilir. Kısa tepe noktaları normaldir ancak sürekli doygunluk sorgu kuyruklanmasına yol açar. performance_schema veya slow log ile CPU'yu en çok tüketen sorguları belirleyin.","tags":["cpu","yuk"]},{"metric":"Disk kullanımı (veri dizini)","warn":"> %85","crit":"> %95","tool":"df / node_exporter","note":"Veri dizininin dolması MySQL'in yazma yapamamasına ve tablo hatalarına yol açar. Binlog dosyaları, undo tablespace'leri ve geçici tablespace (ibtmp1) büyümesi ani doluluğa neden olabilir; redo log ise sabit boyutludur (8.0.30+ #innodb_redo, innodb_redo_log_capacity). binlog_expire_logs_seconds ile eski binlog'ların temizlendiğinden emin olun.","tags":["disk","kapasite","binlog"]},{"metric":"En uzun süren sorgu","warn":"> 60 sn","crit":"> 300 sn","tool":"SHOW PROCESSLIST / information_schema.PROCESSLIST","note":"Uzun süren tek bir sorgu, lock'ları tutarak ve kaynak tüketerek diğer işlemleri etkileyebilir. OLTP sistemlerde dakikalarca süren sorgular genellikle sorunlu plandan kaynaklanır. EXPLAIN ile planı inceleyin ve gerekirse sorguyu sonlandırıp optimize edin.","tags":["sorgu","performans"]},{"metric":"Son başarılı yedeğin yaşı","warn":"> 24 saat","crit":"> 48 saat","tool":"xtrabackup / mysqldump job kaydı","note":"Yedek yaşı, geri dönebileceğiniz en son noktayı ve dolayısıyla RPO'yu belirler. Binlog yedekleriyle birlikte point-in-time recovery mümkün olur. Yedeklerin sadece alınmış olması yetmez; düzenli restore testiyle geçerliliğini doğrulayın.","tags":["yedek","kurtarma","rpo"]},{"metric":"Disk IO latency","warn":"> 10 ms","crit":"> 20 ms","tool":"iostat / node_exporter","note":"Depolama gecikmesi doğrudan sorgu sürelerine yansır ve özellikle buffer pool'a sığmayan iş yüklerinde kritiktir. Modern SSD sistemlerde birkaç milisaniye beklenir. Yüksek latency, disk darboğazına veya aşırı fiziksel okumaya işaret eder; buffer pool boyutunu da gözden geçirin.","tags":["io","disk","latency"]}]},"reference/alerts-mssql.json":{"engineId":"mssql","engine":"SQL Server","order":4,"alerts":[{"metric":"Page Life Expectancy (PLE)","warn":"< 900 sn","crit":"< 300 sn","tool":"sys.dm_os_performance_counters","note":"Page Life Expectancy, bir veri sayfasının buffer pool'dan çıkarılmadan (evict edilmeden) bellekte kalabileceği tahmini süreyi saniye cinsinden gösterir. Düşük değerler bellek baskısına ve sayfaların hızla önbellekten atıldığına işaret eder. NUMA düğüm başına ayrı izlenmeli ve ani düşüşler bellek yetersizliği olarak değerlendirilmelidir.","tags":["bellek","cache","ple"]},{"metric":"Buffer cache hit ratio","warn":"< %98","crit":"< %95","tool":"sys.dm_os_performance_counters","note":"Buffer cache hit oranı, sayfaların diske gitmeden bellekten okunma yüzdesidir. SQL Server'da bu değer genellikle çok yüksektir; PLE ile birlikte değerlendirilmelidir. Tek başına yanıltıcı olabileceğinden bellek darboğazı analizinde PLE ana metrik olarak alınmalıdır.","tags":["bellek","cache"]},{"metric":"Bloke olmuş işlem sayısı (blocked processes)","warn":">= 1 (> 5 sn)","crit":">= 1 (> 30 sn)","tool":"sys.dm_exec_requests (blocking_session_id)","note":"Bir oturumun tuttuğu lock diğerlerini beklettiğinde blocking zinciri oluşur ve uygulama genelinde yavaşlama görülür. Uzun süren bloklamalar genellikle commit edilmemiş transaction'lar veya kötü izolasyon seviyesinden kaynaklanır. blocked process report ile kök oturumu tespit edin.","tags":["kilit","bloklama","concurrency"]},{"metric":"Transaction log doluluğu (%used)","warn":"> %75","crit":"> %90","tool":"sys.dm_db_log_space_usage / DBCC SQLPERF(LOGSPACE)","note":"Transaction log dolduğunda veritabanı yazma yapamaz ve 9002 hatasıyla durur. FULL recovery modelinde log backup alınmazsa log sürekli büyür. Log yedekleme sıklığını ve VLF sayısını izleyerek log'un temizlenip yeniden kullanılabildiğinden emin olun.","tags":["log","disk","recovery"]},{"metric":"tempdb doluluğu (%used)","warn":"> %80","crit":"> %95","tool":"sys.dm_db_file_space_usage","note":"tempdb; geçici tablolar, sıralama, version store ve hash işlemleri için ortak kullanılır. Dolması tüm sunucudaki sorguların başarısız olmasına yol açar. Ani dolmalar genellikle büyük bir sorgu veya uzun süren snapshot işleminden kaynaklanır; version store boyutunu ayrıca izleyin.","tags":["tempdb","disk","sirala"]},{"metric":"En uzun süren sorgu","warn":"> 60 sn","crit":"> 300 sn","tool":"sys.dm_exec_requests / Query Store","note":"Uzun süren tek bir sorgu, lock'ları tutarak ve kaynak tüketerek diğer işlemleri etkileyebilir. OLTP sistemlerde dakikalarca süren sorgular genellikle eksik index, parametre sniffing veya kötü plandan kaynaklanır. Query Store ile plan regresyonlarını inceleyin.","tags":["sorgu","performans"]},{"metric":"Availability Group redo queue","warn":"> 1 MB","crit":"> 100 MB","tool":"sys.dm_hadr_database_replica_states","note":"Redo queue, secondary replikada henüz uygulanmayı bekleyen log miktarını gösterir. Yüksek redo queue, failover sonrası kurtarma süresini (RTO) uzatır ve okuma replikalarında bayat veri demektir. redo_rate ile birlikte incelenerek gecikmenin ne zaman kapanacağı öngörülebilir.","tags":["replikasyon","ag","lag"]},{"metric":"Deadlock oranı","warn":"> 1 / dk","crit":"> 5 / dk","tool":"system_health XEvent / Performance counters","note":"Deadlock, iki transaction'ın birbirinin lock'unu beklemesiyle oluşur ve SQL Server birini kurban seçerek çözer. Ara sıra görülebilir ancak sık deadlock tutarsız lock sıralamasına işaret eder. system_health extended event oturumundan deadlock grafiğini çıkarıp çakışan sorguları düzeltin.","tags":["kilit","deadlock","concurrency"]},{"metric":"Worker thread kullanımı","warn":"> %80","crit":"> %90","tool":"sys.dm_os_schedulers / max worker threads","note":"Worker thread havuzu tükendiğinde yeni istekler THREADPOOL beklemesinde kuyruklanır ve sunucu yanıt veremez hale gelebilir. Genellikle uzun süren bloklamalar veya aşırı eş zamanlı bağlantı bu duruma yol açar. Bloklama zincirlerini çözerek thread baskısını azaltın.","tags":["cpu","thread","yuk"]},{"metric":"CPU kullanımı","warn":"> %80","crit":"> %90","tool":"sys.dm_os_ring_buffers / Performance Monitor","note":"Sürekli yüksek CPU, ağır sorgular, eksik index veya kötü planlardan kaynaklanabilir. Kısa tepe noktaları normaldir ancak sürekli doygunluk sorgu kuyruklanması yaratır. sys.dm_exec_query_stats ile CPU'yu en çok tüketen sorguları belirleyin.","tags":["cpu","yuk"]},{"metric":"Son başarılı yedeğin yaşı","warn":"> 24 saat (tam)","crit":"> 48 saat (tam)","tool":"msdb.dbo.backupset","note":"Yedek yaşı, geri dönebileceğiniz en son noktayı ve RPO'yu belirler. FULL recovery modelinde log yedekleriyle point-in-time recovery mümkündür. Tam, diferansiyel ve log yedeklerinin zincirini izleyerek kurtarma kabiliyetini garanti edin ve düzenli restore testi yapın.","tags":["yedek","kurtarma","rpo"]},{"metric":"Disk IO latency (avg read/write)","warn":"> 15 ms","crit":"> 30 ms","tool":"sys.dm_io_virtual_file_stats","note":"Dosya bazında ortalama okuma/yazma gecikmesi depolama performansını gösterir. Data file'lar için 15 ms, log dosyaları için daha düşük değerler beklenir. Sürekli yüksek latency depolama darboğazına işaret eder; sys.dm_io_virtual_file_stats ile en yavaş dosyaları belirleyin.","tags":["io","disk","latency"]}]},"reference/alerts-mongodb.json":{"engineId":"mongodb","engine":"MongoDB","order":5,"alerts":[{"metric":"WiredTiger cache dirty oranı","warn":"> %5","crit":"> %20","tool":"db.serverStatus().wiredTiger.cache","note":"Dirty cache oranı, WiredTiger önbelleğindeki henüz diske yazılmamış değiştirilmiş sayfaların yüzdesidir. %20'yi aşması eviction baskısı ve yazma darboğazı anlamına gelir; MongoDB uygulama thread'leri eviction'a zorlar. Cache boyutunu ve disk yazma hızını birlikte değerlendirin.","tags":["bellek","cache","wiredtiger"]},{"metric":"WiredTiger cache kullanımı (used %)","warn":"> %80","crit":"> %95","tool":"db.serverStatus().wiredTiger.cache","note":"Cache kullanımı %80 eviction hedefini aşınca WiredTiger sayfaları agresif şekilde diske atmaya başlar ve performans düşer. Çalışma seti cache'e sığmıyorsa fiziksel okumalar artar. wiredTigerCacheSizeGB ayarını ve sunucu belleğini gözden geçirin.","tags":["bellek","cache","wiredtiger"]},{"metric":"Kullanılabilir ticket sayısı (read/write tickets)","warn":"available/totalTickets < %20 veya queueLength > 0 (sürekli)","crit":"available = 0 ve queueLength sürekli artıyor","tool":"db.serverStatus().wiredTiger.concurrentTransactions","note":"WiredTiger, eş zamanlı okuma ve yazma işlemlerini ticket sistemiyle sınırlar. 7.0 öncesinde varsayılan sabit 128 ticket vardı; 7.0+ sürümlerde ticket sayısı dinamik olarak ayarlanır (storageEngineConcurrencyAdjustmentAlgorithm: throughputProbing), bu yüzden mutlak sayı yerine available/totalTickets oranını ve queueLength değerini izleyin. Ticket'ların tükenip işlemlerin kuyruğa girmesi ciddi bir darboğaz işaretidir; genellikle yavaş sorgular veya disk IO doygunluğu buna yol açar.","tags":["concurrency","ticket","darbogaz"]},{"metric":"Replikasyon gecikmesi (replication lag)","warn":"> 10 sn","crit":"> 60 sn","tool":"rs.printSecondaryReplicationInfo()","note":"Replikasyon gecikmesi, secondary üyenin primary'nin ne kadar gerisinde olduğunu saniye cinsinden verir. Yüksek lag, okuma tercihine göre bayat veri ve failover'da veri kaybı riski demektir. Genellikle secondary'de disk IO veya ağ darboğazı ya da uzun süren işlemler nedeniyle oluşur.","tags":["replikasyon","lag","replicaset"]},{"metric":"Bağlantı kullanımı (connections %)","warn":"> %80","crit":"> %90","tool":"db.serverStatus().connections","note":"Aktif bağlantıların yapılandırılan üst sınıra yaklaşması yeni bağlantıların reddedilmesine yol açar. Her bağlantı bellek ve thread tükettiği için yüksek sayı ayrıca kaynak baskısı yaratır. Uygulama tarafında bağlantı havuzu boyutunu doğru ayarlayarak bağlantı patlamalarını önleyin.","tags":["baglanti","limit","havuz"]},{"metric":"Page fault oranı","warn":"> 100 / sn","crit":"> 1000 / sn","tool":"db.serverStatus() / extra_info page_faults","note":"Page fault, verinin bellekte bulunmayıp diskten getirilmesi gerektiğinde oluşur. Yüksek fault oranı, çalışma setinin belleğe sığmadığını ve sistemin diske bağımlı çalıştığını gösterir. Sürekli yüksek değerler bellek yükseltmesi veya sorgu/index optimizasyonu gerektirir.","tags":["bellek","disk","pagefault"]},{"metric":"Kuyruktaki işlemler (queued operations)","warn":"> 10","crit":"> 50","tool":"db.serverStatus().globalLock.currentQueue","note":"globalLock currentQueue, lock veya kaynak beklerken kuyrukta bekleyen okuma/yazma sayısını gösterir. Sürekli dolu kuyruk, sunucunun gelen yükü karşılayamadığına işaret eder. Ticket tükenmesi ve disk IO ile birlikte incelenerek darboğazın kaynağı belirlenmelidir.","tags":["concurrency","kuyruk","kilit"]},{"metric":"Oplog penceresi (oplog window)","warn":"< 24 saat","crit":"< 6 saat","tool":"rs.printReplicationInfo()","note":"Oplog penceresi, oplog'un kapsadığı zaman aralığıdır ve bir secondary'nin ne kadar süre bağlantısız kalıp yeniden senkronize olabileceğini belirler. Pencere daralırsa geri kalan üye tam resync gerektirir. Yazma yükü arttıkça pencere kısalır; oplog boyutunu buna göre büyütün.","tags":["oplog","replikasyon","kurtarma"]},{"metric":"En uzun süren sorgu","warn":"> 30 sn","crit":"> 120 sn","tool":"db.currentOp() / slow query log","note":"Uzun süren sorgular kaynak tüketerek ve lock tutarak diğer işlemleri etkiler. Genellikle eksik index nedeniyle koleksiyon taraması (COLLSCAN) yapan sorgulardan kaynaklanır. profiler ve currentOp ile yavaş işlemleri bulup uygun index'leri ekleyin.","tags":["sorgu","performans","indeks"]},{"metric":"CPU kullanımı","warn":"> %80","crit":"> %90","tool":"node_exporter / mongostat","note":"Sürekli yüksek CPU, index'siz sorgular, ağır aggregation işlemleri veya aşırı bağlantıdan kaynaklanabilir. Kısa tepe noktaları normaldir ancak sürekli doygunluk işlem kuyruklanması yaratır. Profiler ile CPU'yu en çok tüketen sorguları belirleyip optimize edin.","tags":["cpu","yuk"]},{"metric":"Disk kullanımı (dbPath)","warn":"> %85","crit":"> %95","tool":"df / node_exporter","note":"Veri dizininin dolması MongoDB'nin yazma yapamamasına ve olası bozulmaya yol açar. WiredTiger sıkıştırması yardımcı olsa da journal ve büyüyen koleksiyonlar diski hızla doldurabilir. Kapasite planlaması yapın ve gereksiz verileri TTL index'leriyle otomatik temizleyin.","tags":["disk","kapasite"]},{"metric":"Son başarılı yedeğin yaşı","warn":"> 24 saat","crit":"> 48 saat","tool":"mongodump / Ops Manager / snapshot kaydı","note":"Yedek yaşı, geri dönebileceğiniz en son noktayı ve RPO'yu belirler. Oplog ile birlikte point-in-time recovery mümkün olur. Sadece yedek almak yetmez; düzenli restore testiyle yedeklerin geçerliliğini doğrulayın ve şard kümelerinde tutarlı snapshot alındığından emin olun.","tags":["yedek","kurtarma","rpo"]}]},"reference/alerts-redis.json":{"engineId":"redis","engine":"Redis","order":6,"alerts":[{"metric":"Bellek kullanımı (used_memory vs maxmemory)","warn":"> %80","crit":"> %95","tool":"INFO memory / redis_exporter","note":"used_memory'nin maxmemory'ye oranı, Redis'in belleğinin ne kadarının dolu olduğunu gösterir. Sınıra ulaşıldığında maxmemory-policy'ye göre anahtarlar atılır (eviction) veya yazmalar reddedilir. Bellek büyümesini izleyerek beklenmedik OOM ve eviction dalgalarını önleyin.","tags":["bellek","maxmemory","kapasite"]},{"metric":"Keyspace hit ratio","warn":"< %90","crit":"< %80","tool":"INFO stats (keyspace_hits/misses)","note":"Hit oranı, istenen anahtarların önbellekte bulunma yüzdesidir ve keyspace_hits ile keyspace_misses'tan hesaplanır. Düşük oran, önbelleğin etkisiz kullanıldığına, yanlış TTL'lere veya soğuk önbelleğe işaret eder. Cache amaçlı kullanımda bu oran mümkün olduğunca yüksek olmalıdır.","tags":["cache","hit","performans"]},{"metric":"Atılan anahtarlar (evicted_keys)","warn":"> 1 / sn","crit":"> 100 / sn","tool":"INFO stats (evicted_keys)","note":"evicted_keys, bellek dolduğu için maxmemory-policy uyarınca silinen anahtar sayısıdır. Sürekli eviction, belleğin yetersiz olduğunu ve önemli verilerin kaybedilebileceğini gösterir. Bellek yükseltmesi, TTL stratejisi veya veri modelini gözden geçirerek eviction'ı azaltın.","tags":["bellek","eviction","maxmemory"]},{"metric":"Bloke olmuş istemciler (blocked_clients)","warn":"> 50","crit":"> 200","tool":"INFO clients (blocked_clients)","note":"blocked_clients, BLPOP/BRPOP/WAIT gibi bloke edici komutlarda bekleyen istemci sayısıdır. Beklenenden yüksek değerler tüketicilerin yetişemediğine veya kuyruk birikimine işaret eder. Kuyruk tabanlı iş yüklerinde üretici/tüketici dengesini kontrol edin.","tags":["istemci","bloklama","kuyruk"]},{"metric":"Bellek parçalanma oranı (mem_fragmentation_ratio)","warn":"> 1.5","crit":"> 2.0","tool":"INFO memory","note":"Parçalanma oranı, işletim sisteminden alınan belleğin Redis'in kullandığı belleğe oranıdır. 1.5'in üzeri aşırı parçalanmaya, 1.0'ın altı ise belleğin swap'e taştığına işaret eder ki bu çok tehlikelidir. activedefrag açarak veya yeniden başlatarak parçalanmayı azaltabilirsiniz.","tags":["bellek","fragmentasyon"]},{"metric":"Master bağlantı durumu (master_link_status)","warn":"down (< 10 sn)","crit":"down (> 30 sn)","tool":"INFO replication (master_link_status)","note":"master_link_status, replikanın master ile bağlantısının durumunu (up/down) gösterir. 'down' değeri replikasyonun koptuğunu ve replikanın bayat veri sunduğunu ifade eder. Uzun süreli kopukluklar tam resync gerektirir; ağ ve master sağlığını hemen kontrol edin.","tags":["replikasyon","master","baglanti"]},{"metric":"Replikasyon gecikmesi (master_repl_offset farkı)","warn":"> 1 MB","crit":"> 10 MB","tool":"INFO replication (offset diff)","note":"Master ve replika offset'leri arasındaki fark, replikanın ne kadar geri kaldığını byte cinsinden gösterir. Yüksek fark, failover'da veri kaybı ve okuma replikalarında tutarsızlık riski demektir. Ağ gecikmesi ve replika yükünü inceleyerek farkın kapandığından emin olun.","tags":["replikasyon","lag","offset"]},{"metric":"Son RDB bgsave durumu (rdb_last_bgsave_status)","warn":"err (son deneme)","crit":"err (> 24 saat)","tool":"INFO persistence","note":"rdb_last_bgsave_status, en son arka plan snapshot işleminin başarılı (ok) olup olmadığını gösterir. Başarısız bgsave, kalıcılığın çalışmadığını ve yeniden başlatmada veri kaybı riskini ifade eder. Genellikle disk dolması veya fork için yetersiz bellekten kaynaklanır.","tags":["yedek","persistence","rdb"]},{"metric":"Bağlantı kullanımı (connected_clients)","warn":"> %80 maxclients","crit":"> %90 maxclients","tool":"INFO clients / maxclients","note":"connected_clients'ın maxclients sınırına yaklaşması yeni bağlantıların reddedilmesine yol açar. Bağlantı sızıntıları veya havuz yanlış yapılandırması ani artışlara neden olabilir. Uygulama tarafında bağlantı havuzunu doğru ayarlayın ve boşta kalan bağlantıları kapatın.","tags":["baglanti","limit","istemci"]},{"metric":"Anlık komut gecikmesi (latency)","warn":"> 1 ms","crit":"> 10 ms","tool":"redis-cli --latency / LATENCY DOCTOR","note":"Redis tek thread'li olduğundan komut gecikmesi genellikle mikrosaniye seviyesindedir. Yükselen latency; yavaş komutlar (KEYS, büyük SORT), fork sırasında bloklama veya swap kullanımından kaynaklanabilir. slowlog ve LATENCY komutlarıyla kaynağını belirleyin.","tags":["latency","performans","slowlog"]},{"metric":"CPU kullanımı","warn":"> %80 (tek çekirdek)","crit":"> %90 (tek çekirdek)","tool":"top / redis_exporter","note":"Redis ana thread tek çekirdek kullandığından bir çekirdeğin doygunluğu tüm sunucuyu yavaşlatır. Yüksek CPU; pahalı komutlar, çok fazla bağlantı veya Lua script'lerinden kaynaklanabilir. SLOWLOG ile pahalı komutları bulun ve gerekirse iş yükünü birden fazla instance'a bölün.","tags":["cpu","yuk"]},{"metric":"Reddedilen bağlantılar (rejected_connections)","warn":"> 0","crit":"> 10 / dk","tool":"INFO stats (rejected_connections)","note":"rejected_connections, maxclients sınırına ulaşıldığı için reddedilen bağlantı sayısıdır. Sıfırdan büyük olması istemcilerin hizmet alamadığını ve uygulamada hatalar oluştuğunu gösterir. maxclients değerini ve bağlantı sızıntılarını hemen inceleyin.","tags":["baglanti","hata","limit"]}]},"reference/alerts-elasticsearch.json":{"engineId":"elasticsearch","engine":"Elasticsearch","order":7,"alerts":[{"metric":"JVM heap kullanımı","warn":"> %75","crit":"> %85","tool":"_nodes/stats/jvm / elasticsearch_exporter","note":"JVM heap kullanımı, düğümün bellek baskısını gösterir ve %75 üzeri sürekli değerler sık GC ve olası OutOfMemory demektir. Heap %85'i aşarsa düğüm yanıt vermeyebilir veya kümeden düşebilir. Heap'i genellikle sunucu belleğinin yarısı ve en fazla 30-31 GB olacak şekilde ayarlayın.","tags":["bellek","jvm","heap"]},{"metric":"Atanmamış shard sayısı (unassigned shards)","warn":">= 1 (replica)","crit":">= 1 (primary)","tool":"_cluster/health / _cat/shards","note":"Atanmamış shard'lar, verinin bir kısmının erişilemez veya çoğaltılmamış olduğu anlamına gelir. Primary shard atanmamışsa veri kaybı riski, replica atanmamışsa yedeklilik kaybı vardır ve küme sarı/kırmızı olur. _cluster/allocation/explain ile atanmama nedenini bulun.","tags":["shard","cluster","saglik"]},{"metric":"Disk watermark kullanımı","warn":"> %85 (low)","crit":"> %90 (high) / > %95 (flood_stage)","tool":"_nodes/stats/fs / _cat/allocation","note":"Elasticsearch disk doluluğuna göre kademeli önlem alır: %85 low watermark'ta o düğüme yeni shard atamaz, %90 high watermark'ta mevcut shard'ları başka düğümlere taşır, %95 flood_stage'de index'lere read_only_allow_delete bloğu koyar. 8.x'te büyük disklerde yüzde yerine max_headroom değerleri (low 200GB / high 150GB / flood 100GB boş alan) belirleyicidir. 7.4+ sürümlerde blok, disk high watermark altına inince otomatik kalkar; yine de diski watermark'lar aşılmadan boşaltın.","tags":["disk","watermark","kapasite"]},{"metric":"Thread pool reddedilen işlemler (rejected)","warn":"> 0 (write/search)","crit":"> 100 / dk","tool":"_cat/thread_pool / _nodes/stats/thread_pool","note":"Bir thread pool'un kuyruğu dolduğunda gelen istekler reddedilir; write havuzunda reddedilen işlem indeksleme kaybı, search havuzunda başarısız sorgu demektir. Sürekli reddedilme, düğümün gelen yükü karşılayamadığına işaret eder. Toplu (bulk) boyutunu ve eş zamanlılığı azaltarak yükü dengeleyin.","tags":["threadpool","rejected","yuk"]},{"metric":"GC duraklama süresi (old gen GC pause)","warn":"> 1 sn","crit":"> 5 sn","tool":"GC logları / _nodes/stats/jvm","note":"Uzun GC duraklamaları sırasında düğüm yanıt veremez ve master ile bağlantısı kopabilir; bu da shard yeniden dağıtımına yol açar. Sık ve uzun old generation GC, heap baskısının belirtisidir. Heap boyutunu, alan tüketen aggregation ve fielddata kullanımını gözden geçirin.","tags":["jvm","gc","duraklama"]},{"metric":"İndeksleme gecikmesi (indexing latency)","warn":"> 50 ms","crit":"> 200 ms","tool":"_nodes/stats/indices (index_time/index_total)","note":"Ortalama indeksleme süresi, belge yazma performansını gösterir ve index_time_in_millis'in index_total'a bölünmesiyle hesaplanır. Yükselen değerler disk IO darboğazına, ağır analiz zincirine veya refresh baskısına işaret eder. Bulk boyutunu ve refresh_interval ayarını optimize edin.","tags":["indeksleme","latency","performans"]},{"metric":"Arama gecikmesi (search latency)","warn":"> 100 ms","crit":"> 500 ms","tool":"_nodes/stats/indices (query_time/query_total)","note":"Ortalama sorgu süresi, kullanıcıların deneyimlediği arama performansını doğrudan yansıtır ve query_time_in_millis'in query_total'a bölünmesiyle hesaplanır. Yükselen değerler ağır aggregation, çok fazla shard veya soğuk önbellekten kaynaklanabilir. Yavaş sorgu logunu açarak pahalı sorguları bulun.","tags":["arama","latency","performans"]},{"metric":"Bekleyen görevler (pending tasks)","warn":"> 10","crit":"> 100","tool":"_cluster/pending_tasks","note":"Bekleyen görevler, master düğümün henüz uygulamadığı küme durumu değişiklikleridir (mapping, shard atama gibi). Sürekli birikme, master'ın aşırı yüklendiğine veya küme durumunun çok büyüdüğüne işaret eder. Aşırı shard sayısını azaltarak master üzerindeki baskıyı hafifletin.","tags":["cluster","master","kuyruk"]},{"metric":"Circuit breaker tetiklenmesi","warn":"> 0 (tripped)","crit":"> 10 / dk","tool":"_nodes/stats/breakers","note":"Circuit breaker'lar, bir işlemin belleği aşırı tüketip düğümü OutOfMemory'ye sürüklemesini önlemek için isteği iptal eder. Sık tetiklenme, ağır aggregation veya büyük istekler nedeniyle bellek baskısı olduğunu gösterir. tripped sayısını izleyip sorunlu sorguları hafifletin.","tags":["bellek","breaker","jvm"]},{"metric":"Küme sağlık durumu (cluster status)","warn":"yellow","crit":"red","tool":"_cluster/health","note":"Küme durumu yeşil (tüm shard'lar atanmış), sarı (replica eksik) veya kırmızı (primary eksik, veri erişilemez) olabilir. Kırmızı durum acil müdahale gerektirir çünkü bazı veriler kayıp veya erişilemez demektir. Sarı durum yedeklilik kaybını gösterir ve göz ardı edilmemelidir.","tags":["cluster","saglik","shard"]},{"metric":"CPU kullanımı","warn":"> %80","crit":"> %90","tool":"_nodes/stats/os / node_exporter","note":"Sürekli yüksek CPU; ağır sorgular, aşırı indeksleme veya merge işlemlerinden kaynaklanabilir. Kısa tepe noktaları normaldir ancak sürekli doygunluk sorgu ve indeksleme kuyruklanması yaratır. Hot threads API'si (_nodes/hot_threads) ile CPU'yu en çok tüketen işlemleri belirleyin.","tags":["cpu","yuk"]},{"metric":"Son başarılı snapshot yaşı","warn":"> 24 saat","crit":"> 48 saat","tool":"_snapshot/_status / SLM","note":"Snapshot yaşı, geri dönebileceğiniz en son noktayı ve RPO'yu belirler. Snapshot Lifecycle Management (SLM) ile otomatik ve düzenli yedekleme sağlanmalıdır. Başarısız veya atlanan snapshot'lar fark edilmezse felaket anında veri kurtarılamaz; snapshot durumunu düzenli doğrulayın.","tags":["yedek","snapshot","rpo"]}]},"cloud/cloud-ops-1.json":{"category":"Bağlantı & Yedek & Replika","categoryId":"cloud-core","order":1,"providers":[{"id":"aws-rds","name":"AWS RDS","color":"#B85C00"},{"id":"aws-aurora","name":"Aurora","color":"#7B3FE4"},{"id":"gcp-cloudsql","name":"Cloud SQL","color":"#C5372C"},{"id":"azure-sql","name":"Azure SQL","color":"#0067B8"},{"id":"mongodb-atlas","name":"Atlas","color":"#00843D"}],"concepts":[{"id":"list-instances","title":"Örnekleri / veritabanlarını listele","aliases":["list","instances","listele"],"providers":{"aws-rds":{"command":"aws rds describe-db-instances --query 'DBInstances[].DBInstanceIdentifier'","note":"Tüm RDS örneklerinin kimliklerini listeler. Bölge için --region ekleyin.","danger":"safe"},"aws-aurora":{"command":"aws rds describe-db-clusters --query 'DBClusters[].DBClusterIdentifier'","note":"Aurora cluster kimliklerini listeler; cluster üyelerini görmek için DBClusterMembers alanına bakın.","danger":"safe"},"gcp-cloudsql":{"command":"gcloud sql instances list","note":"Proje içindeki tüm Cloud SQL örneklerini listeler. Proje için --project ekleyebilirsiniz.","danger":"safe"},"azure-sql":{"command":"az sql db list -g <rg> -s <server>","note":"Belirtilen kaynak grubu (-g) ve mantıksal sunucudaki (-s) veritabanlarını listeler. Sunucuları listelemek için 'az sql server list' kullanın.","danger":"safe"},"mongodb-atlas":{"command":"atlas clusters list","note":"Atlas projesindeki tüm cluster'ları listeler. Proje için --projectId ekleyebilirsiniz.","danger":"safe"}}},{"id":"connect","title":"Örneğe bağlan (endpoint bul + bağlan)","aliases":["connect","endpoint","connection string","bağlan"],"providers":{"aws-rds":{"command":"aws rds describe-db-instances --db-instance-identifier <id> --query 'DBInstances[0].Endpoint.Address'","note":"Örneğin bağlantı adresini (host) döndürür. Portu Endpoint.Port ile alıp psql/mysql istemcisiyle bağlanın.","danger":"safe"},"aws-aurora":{"command":"aws rds describe-db-clusters --db-cluster-identifier <id> --query 'DBClusters[0].Endpoint'","note":"Cluster yazma uç noktasını döndürür. Salt okuma için ReaderEndpoint alanını kullanın.","danger":"safe"},"gcp-cloudsql":{"command":"gcloud sql instances describe <instance> --format='value(ipAddresses[].ipAddress)'","note":"Örneğin IP adres(ler)ini döndürür. Güvenli bağlantı için Cloud SQL Auth Proxy önerilir.","danger":"safe"},"azure-sql":{"command":"az sql db show-connection-string -s <server> -n <db> -c ado.net","note":"Belirtilen istemci türü (-c: ado.net, jdbc, odbc, php vb.) için bağlantı dizesini üretir; kullanıcı/parolayı siz doldurursunuz.","danger":"safe"},"mongodb-atlas":{"command":"atlas clusters connectionStrings describe <clusterName>","note":"Cluster'ın standart ve SRV bağlantı dizelerini döndürür. IP erişim listesi ve veritabanı kullanıcısı gereklidir.","danger":"safe"}}},{"id":"take-snapshot","title":"Manuel yedek / snapshot al","aliases":["snapshot","backup","yedek"],"providers":{"aws-rds":{"command":"aws rds create-db-snapshot --db-instance-identifier <id> --db-snapshot-identifier <snap-id>","note":"Örneğin manuel (elle silinene kadar kalıcı) snapshot'ını alır. Kısa bir I/O askıya alma yaşanabilir.","danger":"caution"},"aws-aurora":{"command":"aws rds create-db-cluster-snapshot --db-cluster-identifier <id> --db-cluster-snapshot-identifier <snap-id>","note":"Aurora cluster'ının manuel snapshot'ını alır. Aurora'da yedekler sürekli olduğundan bu, sabit bir kopyadır.","danger":"caution"},"gcp-cloudsql":{"command":"gcloud sql backups create --instance=<instance>","note":"Örnek için isteğe bağlı yedek oluşturur. İşlem sırasında kısa süreli performans etkisi olabilir.","danger":"caution"},"azure-sql":{"command":"az sql db export -s <server> -n <db> -u <user> -p <pwd> --admin-user <adm> --admin-password <pwd> --storage-key <key> --storage-key-type StorageAccessKey --storage-uri https://<acct>.blob.core.windows.net/<container>/<file>.bacpac","note":"Azure SQL otomatik yedeklidir; manuel taşınabilir yedek için veritabanını BACPAC olarak dışa aktarır. Nokta bazlı geri yükleme için ayrı özellik vardır.","danger":"caution"},"mongodb-atlas":{"command":"atlas backups snapshots create <clusterName>","note":"Cluster için isteğe bağlı yedek snapshot'ı başlatır. Cloud Backup etkin olmalıdır.","danger":"caution"}}},{"id":"restore-pitr","title":"Belirli ana geri dön (point-in-time restore)","aliases":["pitr","restore","point-in-time","geri dön"],"providers":{"aws-rds":{"command":"aws rds restore-db-instance-to-point-in-time --source-db-instance-identifier <src> --target-db-instance-identifier <new> --restore-time 2026-07-03T10:00:00Z","note":"Kaynak örnekten belirtilen ana YENİ bir örnek oluşturur; mevcut örneğin üzerine yazmaz. En son ana dönmek için --use-latest-restorable-time kullanın.","danger":"caution"},"aws-aurora":{"command":"aws rds restore-db-cluster-to-point-in-time --source-db-cluster-identifier <src> --db-cluster-identifier <new> --restore-to-time 2026-07-03T10:00:00Z","note":"Aurora cluster'ını belirtilen ana yeni bir cluster olarak geri yükler. Ardından create-db-instance ile örnek eklemeniz gerekir.","danger":"caution"},"gcp-cloudsql":{"command":"gcloud sql instances clone <src> <new> --point-in-time '2026-07-03T10:00:00Z'","note":"Kaynak örneğin belirtilen andaki klonunu yeni bir örnek olarak oluşturur. Kaynakta binary/WAL loglama etkin olmalıdır.","danger":"caution"},"azure-sql":{"command":"az sql db restore -g <rg> -s <server> -n <db> --dest-name <new-db> --time '2026-07-03T10:00:00'","note":"Veritabanını belirtilen ana YENİ bir veritabanı olarak geri yükler; kaynak veritabanı korunur. Zaman UTC'dir.","danger":"caution"},"mongodb-atlas":{"command":"atlas backups restores start pointInTime --clusterName <cluster> --pointInTimeUTCMillis <ms> --targetClusterName <target> --targetProjectId <projId>","note":"Continuous Cloud Backup ile belirtilen UTC ana geri yükleme başlatır. Hedef cluster'ın üzerine yazılır; dikkatli olun.","danger":"danger"}}},{"id":"read-replica","title":"Okuma replikası oluştur","aliases":["replica","read replica","okuma replikası"],"providers":{"aws-rds":{"command":"aws rds create-db-instance-read-replica --db-instance-identifier <replica-id> --source-db-instance-identifier <src>","note":"Kaynak örnekten eşzamansız bir okuma replikası oluşturur. Farklı bölgeye kopyalamak için --source-region kullanılır.","danger":"caution"},"aws-aurora":{"command":"aws rds create-db-instance --db-instance-identifier <reader-id> --db-cluster-identifier <cluster> --engine aurora-postgresql --db-instance-class db.r6g.large","note":"Aurora'da okuyucu, cluster'a eklenen bir örnektir; ortak depolamayı paylaşır. Engine değerini cluster ile aynı verin (aurora-mysql / aurora-postgresql).","danger":"caution"},"gcp-cloudsql":{"command":"gcloud sql instances create <replica> --master-instance-name=<src> --region=<region>","note":"Primary (master) örnekten okuma replikası oluşturur. Kaynakta binary logging etkin olmalıdır.","danger":"caution"},"azure-sql":{"command":"az sql db replica create -g <rg> -s <server> -n <db> --partner-server <target-server>","note":"Veritabanının başka bir sunucuda etkin coğrafi (geo) okuma replikasını oluşturur. Hedef sunucu var olmalıdır.","danger":"caution"},"mongodb-atlas":{"command":"atlas clusters update <clusterName> --file cluster.json","note":"Atlas cluster'ları zaten çoğaltılmış replica set'lerdir. Ek okuma kapasitesi için replicationSpecs içine readOnly veya analytics düğümleri ekleyip güncelleyin.","danger":"caution"}}},{"id":"failover","title":"Failover / yük devret","aliases":["failover","yük devret","yedeğe geç"],"providers":{"aws-rds":{"command":"aws rds reboot-db-instance --db-instance-identifier <id> --force-failover","note":"Multi-AZ örnekte yeniden başlatmayı zorlayarak standby'a geçişi tetikler. Kısa bir kesinti olur.","danger":"danger"},"aws-aurora":{"command":"aws rds failover-db-cluster --db-cluster-identifier <cluster> --target-db-instance-identifier <reader>","note":"Aurora cluster'ında bir reader'ı yeni writer yapar. Hedef vermezseniz uygun bir replika seçilir; kısa kesinti olur.","danger":"danger"},"gcp-cloudsql":{"command":"gcloud sql instances failover <instance>","note":"HA (yüksek erişilebilirlik) yapılandırılmış örnekte yedek bölgeye devreder. Yalnızca HA etkin örneklerde çalışır; kesinti yaşanır.","danger":"danger"},"azure-sql":{"command":"az sql failover-group set-primary -g <rg> -s <secondary-server> -n <fog-name>","note":"Otomatik failover grubunda primary'yi secondary sunucuya taşır (planlı failover). --allow-data-loss ile zorlanabilir; veri kaybı riski taşır.","danger":"danger"},"mongodb-atlas":{"command":"atlas clusters failover <clusterName>","note":"Atlas otomatik failover yapar; bu komut test amaçlı elle failover'ı tetikler. Primary değişir, uygulama yeniden bağlanmalıdır.","danger":"danger"}}}]},"cloud/cloud-ops-2.json":{"category":"Yapılandırma & Ölçekleme & İzleme","categoryId":"cloud-config","order":2,"providers":[{"id":"aws-rds","name":"AWS RDS","color":"#B85C00"},{"id":"aws-aurora","name":"Aurora","color":"#7B3FE4"},{"id":"gcp-cloudsql","name":"Cloud SQL","color":"#C5372C"},{"id":"azure-sql","name":"Azure SQL","color":"#0067B8"},{"id":"mongodb-atlas","name":"Atlas","color":"#00843D"}],"concepts":[{"id":"scale-instance","title":"Örnek boyutunu değiştir (dikey ölçekle)","aliases":["scale","boyut","resize","ölçekle","dikey"],"providers":{"aws-rds":{"command":"aws rds modify-db-instance --db-instance-identifier <id> --db-instance-class db.r6g.xlarge --apply-immediately","note":"--apply-immediately anında uygular ve örneği yeniden başlatır (kısa kesinti olur). Bu bayrağı vermezseniz değişiklik bir sonraki bakım penceresinde uygulanır. Multi-AZ örneklerde kesinti failover süresi kadar kısalır.","danger":"caution"},"aws-aurora":{"command":"aws rds modify-db-instance --db-instance-identifier <writer-veya-reader-id> --db-instance-class db.r6g.2xlarge --apply-immediately","note":"Aurora'da her örnek (writer ve reader) ayrı ayrı ölçeklenir; cluster değil örnek boyutu değişir. Önce reader'ları büyütüp ardından failover ile writer'ı değiştirirseniz kesintiyi en aza indirirsiniz. Serverless v2 kullanıyorsanız min/max ACU üzerinden ölçeklersiniz.","danger":"caution"},"gcp-cloudsql":{"command":"gcloud sql instances patch <id> --tier db-custom-4-16384","note":"db-custom-CPU-BELLEK biçiminde özel makine tipi verilir (örnek: 4 vCPU, 16384 MB RAM). Değişiklik örneği yeniden başlatır, kısa kesinti oluşur. Hazır tier'lar (örn. db-n1-standard-4) da kullanılabilir.","danger":"caution"},"azure-sql":{"command":"az sql db update -g <rg> -s <server> -n <db> --service-objective S3","note":"DTU modelinde S3/P2 gibi service objective; vCore modelinde --edition GeneralPurpose --family Gen5 --capacity 4 kullanılır. Ölçekleme online yapılır; işlem sonuna doğru birkaç saniyelik kısa bağlantı kopması yaşanabilir.","danger":"caution"},"mongodb-atlas":{"command":"atlas clusters update <name> --tier M30","note":"Atlas replica set üzerinde rolling (sıralı) olarak node'ları yeniden boyutlandırır, bu yüzden kesintisizdir. --projectId bayrağı veya varsayılan proje gerekir. Boyut küçültmede (downgrade) disk ve bellek kısıtlarına dikkat edin.","danger":"caution"}}},{"id":"parameter-group","title":"Parametre değiştir (parameter group / flags / server config)","aliases":["parametre","parameter group","flags","config","ayar"],"providers":{"aws-rds":{"command":"aws rds modify-db-parameter-group --db-parameter-group-name <pg> --parameters \"ParameterName=max_connections,ParameterValue=500,ApplyMethod=pending-reboot\"","note":"ApplyMethod=immediate dinamik parametreler için, pending-reboot statik parametreler için kullanılır. Parametre grubu örneğe atanmış olmalı; statik parametrelerde değişiklik reboot sonrası etkin olur. Grup oluşturmak için create-db-parameter-group kullanın.","danger":"caution"},"aws-aurora":{"command":"aws rds modify-db-cluster-parameter-group --db-cluster-parameter-group-name <cpg> --parameters \"ParameterName=innodb_lock_wait_timeout,ParameterValue=100,ApplyMethod=immediate\"","note":"Aurora'da cluster geneli parametreler DB cluster parameter group ile, örnek özel parametreler DB parameter group (modify-db-parameter-group) ile yönetilir. Statik parametreler cluster genelinde reboot gerektirir.","danger":"caution"},"gcp-cloudsql":{"command":"gcloud sql instances patch <id> --database-flags max_connections=500,log_min_duration_statement=1000","note":"--database-flags TÜM bayrakları tek seferde ayarlar; listede olmayan önceki bayraklar sıfırlanır, bu yüzden hepsini birlikte yazın. Bazı bayraklar örneğin yeniden başlatılmasını gerektirir. Mevcut bayrakları 'gcloud sql instances describe <id>' ile görün.","danger":"caution"},"azure-sql":{"command":"az sql db configure -g <rg> -s <server> -n <db> ...   # DB düzeyi ayarlar T-SQL ile: ALTER DATABASE SCOPED CONFIGURATION SET MAXDOP = 4;","note":"Azure SQL'de klasik server config yerine ayarlar çoğunlukla T-SQL ile yapılır: ALTER DATABASE SCOPED CONFIGURATION ... veya sunucu düzeyi için sp_configure sınırlıdır. Elastik havuz/db seçenekleri için 'az sql db update' bayraklarını kullanın.","danger":"caution"},"mongodb-atlas":{"command":"atlas clusters advancedSettings update <name> --oplogMinRetentionHours 24 --oplogSizeMB 20480","note":"Atlas'ta düşük seviye MongoDB process argümanları 'advancedSettings' ile sınırlı biçimde ayarlanır (oplog, tam metin arama, index derinliği vb.). Çoğu sunucu parametresi Atlas tarafından yönetilir ve doğrudan değiştirilemez.","danger":"caution"}}},{"id":"monitoring","title":"Metrikleri ve performansı gör","aliases":["monitoring","metrik","izleme","performans","insights"],"providers":{"aws-rds":{"command":"aws cloudwatch get-metric-statistics --namespace AWS/RDS --metric-name CPUUtilization --dimensions Name=DBInstanceIdentifier,Value=<id> --start-time 2026-07-05T00:00:00Z --end-time 2026-07-05T01:00:00Z --period 300 --statistics Average","note":"Temel metrikler (CPU, bağlantı, IOPS, gecikme) CloudWatch AWS/RDS namespace'inde bulunur. Sorgu düzeyi analiz için Performance Insights'ı açın: 'aws pi get-resource-metrics --service-type RDS ...' veya konsoldan Performance Insights panelini kullanın.","danger":"safe"},"aws-aurora":{"command":"aws cloudwatch get-metric-statistics --namespace AWS/RDS --metric-name AuroraReplicaLag --dimensions Name=DBInstanceIdentifier,Value=<reader-id> --start-time 2026-07-05T00:00:00Z --end-time 2026-07-05T01:00:00Z --period 60 --statistics Maximum","note":"Aurora'ya özel metrikler (AuroraReplicaLag, VolumeReadIOPs, CommitLatency, buffer cache hit) da AWS/RDS namespace'indedir. Performance Insights Aurora için önerilir ve top SQL, wait event analizini sağlar.","danger":"safe"},"gcp-cloudsql":{"command":"gcloud monitoring time-series list --filter='metric.type=\"cloudsql.googleapis.com/database/cpu/utilization\" AND resource.labels.database_id=\"<proje>:<id>\"' --interval-start-time=2026-07-05T00:00:00Z --interval-end-time=2026-07-05T01:00:00Z","note":"Cloud SQL metrikleri Cloud Monitoring'de cloudsql.googleapis.com/... altında yer alır. Sorgu düzeyi analiz için Cloud SQL Query Insights'ı (konsol veya API) etkinleştirin; en yavaş sorguları ve wait event'leri gösterir.","danger":"safe"},"azure-sql":{"command":"az monitor metrics list --resource <db-resource-id> --metric \"cpu_percent\" --interval PT5M --start-time 2026-07-05T00:00:00Z --end-time 2026-07-05T01:00:00Z","note":"cpu_percent, dtu_consumption_percent, storage_percent, connection_successful gibi metrikler Azure Monitor üzerinden gelir. Sorgu performansı için Query Performance Insight ve Intelligent Insights (Azure SQL Analytics) panellerini kullanın.","danger":"safe"},"mongodb-atlas":{"command":"atlas metrics processes <host>:<port> --granularity PT5M --period P1D --type SYSTEM_CPU_USER,QUERY_TARGETING_SCANNED_OBJECTS_PER_RETURNED","note":"Süreç (process) düzeyi ölçümler 'atlas metrics processes', disk için 'atlas metrics disks' ile alınır. Yavaş sorgu önerileri için Performance Advisor kullanın: 'atlas performanceAdvisor slowQueryLogs list' ve 'atlas performanceAdvisor suggestedIndexes list'.","danger":"safe"}}},{"id":"maintenance-window","title":"Bakım penceresi ve güncelleme yönetimi","aliases":["maintenance","bakım","pencere","güncelleme","patch"],"providers":{"aws-rds":{"command":"aws rds modify-db-instance --db-instance-identifier <id> --preferred-maintenance-window Sun:03:00-Sun:04:00   # bekleyen bakımı hemen uygula: aws rds apply-pending-maintenance-action --resource-identifier <arn> --apply-action system-update --opt-in-type immediate","note":"Pencere UTC ve ddd:hh24:mi-ddd:hh24:mi biçimindedir, en az 30 dakika olmalıdır. Bekleyen bakımları 'aws rds describe-pending-maintenance-actions' ile listeleyip apply-pending-maintenance-action ile hemen ya da sonraki pencerede uygulayabilirsiniz.","danger":"caution"},"aws-aurora":{"command":"aws rds modify-db-cluster --db-cluster-identifier <cluster> --preferred-maintenance-window Sun:03:00-Sun:04:00","note":"Aurora'da cluster düzeyi bakım penceresi modify-db-cluster ile, örnek düzeyi modify-db-instance ile ayarlanır. Bekleyen sürüm/işletim sistemi güncellemeleri apply-pending-maintenance-action ile yönetilir; motor sürüm yükseltmeleri kesinti gerektirebilir.","danger":"caution"},"gcp-cloudsql":{"command":"gcloud sql instances patch <id> --maintenance-window-day SUN --maintenance-window-hour 3 --maintenance-release-channel production","note":"Gün (MON..SUN), saat (0-23, örnek yerel/UTC saatiyle) ve yayın kanalı (production veya preview) ayarlanır. --deny-maintenance-period-* bayraklarıyla bakımın yapılmayacağı bir dönem de tanımlayabilirsiniz.","danger":"caution"},"azure-sql":{"command":"az sql db update -g <rg> -s <server> -n <db> --maint-config-id SQL_Default   # veya özel: /subscriptions/<sub>/providers/Microsoft.Maintenance/publicMaintenanceConfigurations/SQL_<Region>_DB_1","note":"Azure SQL bakım penceresi, önceden tanımlı Maintenance Configuration ataması ile yönetilir (varsayılan yerine hafta içi/sonu akşam pencereleri). Yapılandırmaları 'az maintenance public-configuration list' ile görebilirsiniz.","danger":"caution"},"mongodb-atlas":{"command":"atlas maintenanceWindows update --dayOfWeek 1 --hourOfDay 3 --projectId <projeId>   # ertele: atlas maintenanceWindows defer","note":"dayOfWeek 1=Pazar ... 7=Cumartesi, hourOfDay 0-23 (UTC). Bekleyen bakımı bir hafta ertelemek için 'atlas maintenanceWindows defer', hemen başlatmak için 'atlas maintenanceWindows start' kullanılır.","danger":"caution"}}},{"id":"encryption","title":"Şifreleme (at-rest) durumunu gör/ayarla","aliases":["encryption","şifreleme","at-rest","kms","tde","cmek"],"providers":{"aws-rds":{"command":"aws rds describe-db-instances --db-instance-identifier <id> --query 'DBInstances[0].[StorageEncrypted,KmsKeyId]'   # oluştururken: aws rds create-db-instance ... --storage-encrypted --kms-key-id <kms-arn>","note":"RDS at-rest şifrelemesi yalnızca örnek OLUŞTURULURKEN etkinleştirilebilir; mevcut şifrelenmemiş örnekte açmak için şifreli bir snapshot kopyası alıp ondan geri yüklemeniz gerekir. Anahtar AWS KMS ile yönetilir.","danger":"caution"},"aws-aurora":{"command":"aws rds describe-db-clusters --db-cluster-identifier <cluster> --query 'DBClusters[0].[StorageEncrypted,KmsKeyId]'   # oluştururken: aws rds create-db-cluster ... --storage-encrypted --kms-key-id <kms-arn>","note":"Aurora'da şifreleme cluster düzeyinde ve yalnızca oluşturma anında ayarlanır. Var olan şifrelenmemiş cluster'ı şifrelemek için snapshot'ı şifreli olarak kopyalayıp geri yükleyin. Tüm örnekler ve yedekler aynı KMS anahtarını kullanır.","danger":"caution"},"gcp-cloudsql":{"command":"gcloud sql instances create <id> --disk-encryption-key projects/<proje>/locations/<region>/keyRings/<ring>/cryptoKeys/<key>   # görmek için: gcloud sql instances describe <id> --format='value(diskEncryptionConfiguration.kmsKeyName)'","note":"Cloud SQL varsayılan olarak Google yönetimli anahtarla şifrelidir; müşteri yönetimli anahtar (CMEK) yalnızca örnek oluşturulurken --disk-encryption-key ile atanır. Cloud SQL hizmet hesabına anahtar üzerinde şifre/çöz izni verilmiş olmalıdır.","danger":"caution"},"azure-sql":{"command":"az sql db tde set -g <rg> -s <server> -d <db> --status Enabled   # veya T-SQL: ALTER DATABASE <db> SET ENCRYPTION ON;   # durum: az sql db tde show -g <rg> -s <server> -d <db>","note":"Azure SQL'de at-rest şifreleme Transparent Data Encryption (TDE) ile sağlanır ve yeni veritabanlarında varsayılan olarak açıktır. Kendi anahtarınızı kullanmak için sunucu düzeyinde 'az sql server tde-key set' (Azure Key Vault / BYOK) yapılandırılır.","danger":"caution"},"mongodb-atlas":{"command":"atlas clusters describe <name> --output json | jq '.encryptionAtRestProvider'   # BYOK etkinleştir: atlas encryptionAtRest enable AWS --awsKmsMasterKeyID <keyId> --awsKmsRegion <region> --awsKmsRoleID <roleId>","note":"Atlas'ta veriler varsayılan olarak at-rest şifrelidir. Ek olarak müşteri anahtarıyla (BYOK) zarf şifreleme, AWS KMS / Azure Key Vault / GCP KMS üzerinden 'atlas encryptionAtRest' ile proje genelinde etkinleştirilip cluster'a uygulanır.","danger":"caution"}}},{"id":"storage-autoscale","title":"Depolamayı büyüt / otomatik ölçekle","aliases":["storage","depolama","autoscale","büyüt","disk"],"providers":{"aws-rds":{"command":"aws rds modify-db-instance --db-instance-identifier <id> --allocated-storage 200 --max-allocated-storage 1000 --apply-immediately","note":"--allocated-storage anlık boyutu, --max-allocated-storage ile depolama otomatik ölçekleme (storage autoscaling) üst sınırını belirler. Boyut büyütme online yapılır; ancak iki depolama değişikliği arasında en az 6 saat beklenir ve boyut küçültülemez.","danger":"caution"},"aws-aurora":{"command":"# Aurora depolaması otomatiktir; manuel ayar gerekmez\naws rds describe-db-clusters --db-cluster-identifier <cluster> --query 'DBClusters[0].AllocatedStorage'","note":"Aurora'da depolama tam otomatik ölçeklenir (10 GB adımlarla, motora göre 128 TB'a kadar) ve kullanıldıkça büyür; --allocated-storage / --max-allocated-storage ayarı yapılmaz. Yalnızca kullanımı izlersiniz, boyut yönetimi gerekmez.","danger":"safe"},"gcp-cloudsql":{"command":"gcloud sql instances patch <id> --storage-auto-increase --storage-size 200GB   # üst sınır: --storage-auto-increase-limit 1000","note":"--storage-auto-increase disk dolmaya yaklaşınca otomatik büyümeyi açar, --storage-auto-increase-limit üst sınırı (0 = sınırsız) belirler. Depolama yalnızca büyütülebilir, KÜÇÜLTÜLEMEZ; bu yüzden başlangıç boyutunu ve sınırı dikkatli seçin.","danger":"caution"},"azure-sql":{"command":"az sql db update -g <rg> -s <server> -n <db> --max-size 500GB","note":"Azure SQL'de veritabanı maksimum boyutu --max-size ile ayarlanır; ayrılan alan içinde otomatik büyür. Maksimum boyut seçilen hizmet katmanı/vCore sınırına bağlıdır. Hiperölçek (Hyperscale) katmanında depolama otomatik ve neredeyse sınırsız ölçeklenir.","danger":"caution"},"mongodb-atlas":{"command":"atlas clusters update <name> --diskSizeGB 200   # otomatik ölçekleme için genişletilmiş yapılandırma (advancedSettings / API) ile diskGBEnabled=true","note":"Disk boyutu --diskSizeGB ile artırılır. Atlas'ta depolama otomatik ölçekleme (Auto-scale storage) M10 ve üzeri cluster'larda varsayılan açıktır; disk %90 dolduğunda otomatik büyür. Kapatma/açma cluster yapılandırmasından (autoScaling.diskGBEnabled) yönetilir.","danger":"caution"}}}]},"guide/best-practices.json":{"topics":[{"id":"indexing-strategy","title":"İndeksleme stratejisi","category":"Performans","summary":"Index'ler okuma sorgularını hızlandırır ama yazma ve depolama maliyeti getirir; ihtiyaç bazlı ve ölçülerek eklenmelidir.","points":["WHERE, JOIN ve ORDER BY sütunlarını hedefle; en seçici sütunu bileşik index'te öne al (leftmost-prefix kuralı).","Covering index kullan: sorgunun ihtiyaç duyduğu tüm sütunları index'e dahil ederek tablo erişimini (lookup) ortadan kaldır.","Kullanılmayan ve tekrar eden (mükerrer öncekinin öneki olan) index'leri tespit edip sil; her index INSERT/UPDATE/DELETE'i yavaşlatır.","Düşük kardinaliteli sütunlarda (örn. cinsiyet, boolean) tek başına B-tree index'ten kaçın; gerekirse partial/filtered index kullan.","EXPLAIN/EXPLAIN ANALYZE ile index'in gerçekten kullanıldığını doğrula; fonksiyon veya tip dönüşümü index'i devre dışı bırakır (WHERE UPPER(ad) gibi)."],"level":"junior"},{"id":"normalization","title":"Normalizasyon vs denormalizasyon","category":"Tasarım","summary":"Normalizasyon veri bütünlüğü ve tekrarsızlık sağlar; denormalizasyon okuma performansı için bilinçli bir ödünleşimdir.","points":["OLTP sistemlerinde varsayılan olarak 3NF hedefle; veri tekrarını ve güncelleme anomalilerini önle.","Denormalizasyonu ancak ölçülmüş bir performans darboğazı varken, gerekçelendirerek uygula.","Denormalize edilmiş veride tutarlılığı trigger, materialized view veya uygulama katmanıyla garanti altına al.","Raporlama/analitik yükleri için ayrı bir denormalize şema (star schema) veya okuma replikası düşün.","Erken denormalizasyon teknik borçtur; önce doğru index ve sorguyla çözmeyi dene."],"level":"senior"},{"id":"data-types","title":"Doğru veri tipi seçimi","category":"Tasarım","summary":"Doğru ve mümkün olan en küçük veri tipi depolama, index boyutu ve performansı doğrudan iyileştirir.","points":["İhtiyaca yeten en küçük tipi seç: yaş için SMALLINT, para için DECIMAL/NUMERIC (asla FLOAT değil).","Zaman verisini her zaman zaman dilimli tut (TIMESTAMPTZ / UTC); yerel saat saklamaktan kaçın.","Sabit ve sınırlı değer kümeleri için ENUM veya lookup tablosu kullan; serbest metin yerine kısıtla.","Değişken uzunluklu metinde gereksiz büyük VARCHAR(255) yerine gerçek ihtiyaca göre boyutla veya TEXT kullan.","UUID'yi PK olarak kullanacaksan index parçalanmasına dikkat et; sıralı UUID (v7) veya BIGINT identity değerlendir.","NULL semantiğini bilinçli seç; 'bilinmiyor' ile 'boş' farkını tasarımda netleştir."],"level":"junior"},{"id":"naming-conventions","title":"İsimlendirme kuralları","category":"Tasarım","summary":"Tutarlı isimlendirme okunabilirliği, bakımı ve ekip içi iletişimi kolaylaştırır; baştan standart belirlenmelidir.","points":["Tek bir konvansiyon seç ve her yerde uygula: snake_case yaygın ve büyük/küçük harf sorunlarına dayanıklıdır.","Tablo isimlerinde tekil/çoğul kararını sabitle; sütunlarda anlamlı ve kısaltmasız isimler tercih et.","Foreign key'leri kaynağı belli edecek şekilde adlandır (örn. musteri_id) ve index/constraint'lere önekli standart ver (fk_, ix_, uq_).","Rezerve kelimeleri (order, user, group) tablo/sütun adı olarak kullanmaktan kaçın.","Boolean sütunları is_/has_ önekiyle netleştir; tarih sütunlarına _at, _date gibi tutarlı son ekler ekle."],"level":"junior"},{"id":"partitioning-strategy","title":"Partition (bölümleme) stratejisi","category":"Performans","summary":"Partitioning büyük tabloları yönetilebilir parçalara böler; bakım, silme ve sorgu performansını iyileştirir.","points":["Partition anahtarını sorgu ve arşivleme desenine göre seç; zaman serilerinde tarih bazlı RANGE partition en yaygınıdır.","Partition pruning'in çalıştığını doğrula: sorguların WHERE koşulu partition anahtarını içermeli, yoksa tüm partition'lar taranır.","Eski veriyi silmek yerine partition DROP/DETACH ile anında ve kilitsize yakın temizle.","Aşırı sayıda partition planlama ve metadata maliyeti yaratır; makul granülerlik (aylık/haftalık) seç.","Gelecek partition'ları otomatik oluşturacak bakım işi kur; boş partition'a yazma hatasını önle."],"level":"senior"},{"id":"connection-pooling","title":"Connection pooling","category":"Operasyon","summary":"Bağlantı havuzu, pahalı bağlantı kurma maliyetini ortadan kaldırır ve veritabanını bağlantı taşmasından korur.","points":["Her istekte yeni bağlantı açma; uygulama veya ara katmanda (PgBouncer, HikariCP) havuz kullan.","Havuz boyutunu CPU çekirdeği ve iş yüküne göre boyutla; çok büyük havuz veritabanını boğar (genelde küçük havuz daha iyidir).","Bağlantı yaşam süresi, boşta kalma ve alım zaman aşımı (timeout) değerlerini bilinçli ayarla; sızıntı tespiti aç.","Havuzu veritabanının max_connections limitiyle uyumlu planla; birden çok uygulama örneğinin toplamını hesapla.","Kısa transaction'lar kullan ki bağlantılar havuza hızla dönsün; transaction içinde harici I/O bekleme yapma."],"level":"senior"},{"id":"transaction-design","title":"Transaction tasarımı (kısa ve atomik)","category":"Performans","summary":"Transaction'lar kısa, atomik ve tek bir mantıksal işi kapsayacak şekilde tasarlanmalı; lock süresini en aza indirir.","points":["Transaction'ı olabildiğince kısa tut; kullanıcı etkileşimi, harici API çağrısı veya uzun hesaplama içine alma.","Yalnızca birlikte başarılı/başarısız olması gereken işlemleri tek transaction'da grupla.","Lock çakışmasını azaltmak için satırları her zaman aynı sırada güncelle (deadlock önlemenin temeli).","Gereksiz yere geniş lock'tan kaçın; salt-okuma işlemlerini gereksiz transaction bloğuna sokma.","Hata durumunda net rollback yolu tanımla; kısmi commit veya açık kalan transaction bırakma.","Uzun toplu işlemleri parçalara (batch) bölerek commit et; tek dev transaction WAL/undo şişmesine yol açar."],"level":"senior"},{"id":"isolation-levels","title":"İzolasyon seviyesi seçimi","category":"Performans","summary":"İzolasyon seviyesi tutarlılık ile eşzamanlılık arasındaki dengeyi belirler; iş kuralına göre bilinçli seçilmelidir.","points":["Anomali türlerini bil: dirty read, non-repeatable read, phantom read; hangi seviyenin hangisini önlediğini kavra.","Çoğu OLTP için Read Committed yeterlidir; yalnızca gerçekten gerektiğinde daha yükseğe çık.","Kritik para/stok işlemlerinde Serializable veya açık kilitleme (SELECT ... FOR UPDATE) kullan.","Serializable altında serialization hatalarına karşı otomatik yeniden deneme (retry) mantığı ekle.","MVCC ile lock tabanlı motorların davranış farkını bil; aynı seviye farklı motorlarda farklı garanti verebilir."],"level":"expert"},{"id":"deadlock-prevention","title":"Deadlock önleme","category":"Performans","summary":"Deadlock, transaction'ların kaynakları karşılıklı beklemesiyle oluşur; tasarımla büyük ölçüde önlenebilir.","points":["Kaynaklara/satırlara her zaman tutarlı ve aynı sırada eriş; deadlock'ların en yaygın kaynağı sıra farkıdır.","Transaction'ları kısa tut ve lock sayısını azalt; gereksiz geniş kapsamlı güncellemeden kaçın.","Gerektiğinde erken kilitleme (SELECT ... FOR UPDATE) ile çakışmayı öngörülebilir hale getir.","Uygulamada deadlock hatasını yakala ve transaction'ı otomatik yeniden dene; deadlock'u tamamen sıfırlamak çoğu zaman mümkün değildir.","Deadlock loglarını/grafiğini düzenli incele; tekrar eden desenleri index veya erişim sırası değişikliğiyle gider."],"level":"expert"},{"id":"sharding-strategy","title":"Sharding / yatay ölçekleme stratejisi","category":"Tasarım","summary":"Sharding veriyi birden çok düğüme dağıtarak tek sunucu sınırlarını aşar; ciddi karmaşıklık getirdiği için son çare olmalıdır.","points":["Önce dikey ölçekleme, indeksleme, cache ve okuma replikasını tüket; sharding'i gerçekten gerektiğinde uygula.","Shard anahtarını dikkatle seç: düşük çapraz-shard sorgu ve dengeli dağılım sağlamalı, hotspot oluşturmamalı.","Resharding için tutarlı hashing veya sanal shard'lar kullan; büyümeyi baştan planla.","Çapraz-shard JOIN ve dağıtık transaction pahalıdır; şemayı bunları en aza indirecek şekilde tasarla.","Global benzersiz kimlik üretimini (snowflake vb. sıralı ID) ve shard yönlendirme (routing) katmanını çöz."],"level":"expert"},{"id":"backup-strategy","title":"Yedekleme stratejisi (3-2-1)","category":"Yedek & HA","summary":"Sağlam bir yedekleme stratejisi felaketlere karşı son savunma hattıdır; kural test edilmeden yedek sayılmaz.","points":["3-2-1 kuralını uygula: 3 kopya, 2 farklı ortam, 1 kopya saha dışında (offsite/farklı bölge).","Tam + artımlı yedeği birleştir ve WAL/binlog arşivleme ile point-in-time recovery (PITR) yeteneği kazan.","Yedekleri düzenli olarak GERÇEKTEN geri yükleyerek test et; test edilmemiş yedek yedek değildir.","Yedekleri hem beklemede hem aktarımda şifrele; erişimi kısıtla ve saklama (retention) süresini politikayla belirle.","Fidye yazılımına karşı değiştirilemez (immutable) veya hava boşluklu (air-gapped) bir kopya bulundur."],"level":"junior"},{"id":"hadr-design","title":"HA/DR tasarımı ve RPO/RTO","category":"Yedek & HA","summary":"Yüksek erişilebilirlik ve felaket kurtarma tasarımı, iş hedeflerini RPO ve RTO metrikleriyle netleştirmekle başlar.","points":["RPO (kabul edilebilir veri kaybı) ve RTO (kabul edilebilir kesinti süresi) hedeflerini iş birimiyle birlikte netleştir.","Senkron replikasyon sıfıra yakın RPO verir ama gecikme ekler; asenkron performanslıdır ama veri kaybı riski taşır.","Otomatik failover kur ve düzenli tatbikatla (failover drill) gerçekten çalıştığını doğrula.","Split-brain'i önlemek için quorum/witness mekanizması kullan; iki düğümün ikisinin de master olmasını engelle.","DR ortamını farklı bir fiziksel bölgede tut; tek bölge/veri merkezi arızasına dayanıklı ol."],"level":"expert"},{"id":"capacity-planning","title":"Kapasite planlama ve büyüme","category":"Operasyon","summary":"Kapasite planlama, kaynakların büyüme trendine göre önden ayarlanmasıyla sürpriz kesintileri önler.","points":["Veri büyüme hızını, IOPS, CPU, bellek ve bağlantı kullanımını zaman içinde ölçüp trend çıkar.","Disk doluluğu için erken eşik alarmları kur (örn. %75/%85); tükenmeden önce müdahale et.","Büyümeyi tahmine dayalı planla; en yoğun (peak) yükü ve mevsimsel dalgalanmayı hesaba kat.","Bağlantı sayısı, tablo/index bloat'ı ve arşivleme ihtiyacını düzenli gözden geçir.","Ölçekleme yolunu (dikey mi, replika mı, partition/shard mı) darboğaza ulaşmadan önce kararlaştır."],"level":"senior"},{"id":"migration-strategy","title":"Migration stratejisi (minimum kesinti)","category":"Operasyon","summary":"Şema ve veri geçişleri, geri alınabilir ve kesintiyi en aza indiren bir planla, mümkünse online yapılmalıdır.","points":["Her migration'ı geri alınabilir (reversible) ve idempotent tasarla; rollback planı olmadan üretime çıkma.","Büyük tabloda kilitleyici DDL'den kaçın; online şema değişikliği araçları (PG: pg-osc/pgroll; MySQL: gh-ost, pt-osc) kullan.","Geriye/ileriye uyumlu değişiklikler için expand-contract (genişlet-daralt) desenini uygula: önce ekle, dağıt, sonra eskiyi kaldır.","Büyük veri taşımalarını küçük batch'ler halinde yap; tek seferde dev UPDATE ile lock ve WAL şişmesi yaratma.","Migration'ı önce üretim benzeri ortamda, gerçekçi veri hacmiyle prova et ve süresini ölç.","Kesme (cutover) anını, doğrulama adımlarını ve geri dönüş kararını önceden yazılı plana bağla."],"level":"senior"},{"id":"schema-versioning","title":"Şema versiyonlama (Flyway/Liquibase)","category":"Operasyon","summary":"Şema değişiklikleri koda dahil, versiyonlanmış ve otomatik uygulanan migration'larla yönetilmelidir; elle müdahale hataya açıktır.","points":["Tüm şema değişikliklerini Flyway/Liquibase gibi araçlarla versiyonla ve kaynak kontrolünde tut.","Üretimde elle DDL çalıştırma; her değişiklik gözden geçirilmiş bir migration dosyasından gitmeli.","Migration'ları sıralı ve tekil tut; uygulanan migration dosyasını sonradan değiştirme, yeni migration ile düzelt.","CI/CD hattında migration'ları otomatik uygula ve doğrula; ortamlar arası şema tutarlılığını garanti et.","Uygulama kodu ile şema sürümünü uyumlu ilerlet; geri uyumlu geçiş için expand-contract desenini benimse."],"level":"senior"},{"id":"least-privilege","title":"En az yetki ilkesi","category":"Güvenlik","summary":"Her kullanıcı ve uygulama yalnızca işini yapacak kadar yetkiye sahip olmalı; fazla yetki saldırı yüzeyini büyütür.","points":["Uygulama için ayrı, sınırlı yetkili hesaplar kullan; asla süper kullanıcı/admin ile bağlanma.","Yetkileri doğrudan kullanıcılara değil rollere ver; erişimi rol üyeliğiyle yönet.","Yalnızca gereken tablo ve işlemlere (SELECT/INSERT/UPDATE) izin ver; geniş GRANT ALL'dan kaçın.","Yetkileri periyodik gözden geçir ve kullanılmayanları geri al; çalışan/servis ayrılınca erişimi hemen kaldır.","Gizli bilgileri (parola, bağlantı dizesi) kod içine gömme; sır yöneticisi (vault) kullan ve düzenli döndür (rotate)."],"level":"junior"},{"id":"encryption-basics","title":"Şifreleme temelleri (at-rest/in-transit)","category":"Güvenlik","summary":"Veri hem depolandığında hem aktarıldığında şifrelenmeli; şifreleme uyumluluk ve veri sızıntısına karşı temel korumadır.","points":["Aktarımda TLS'i zorunlu kıl; şifresiz bağlantıları reddet ve sertifika doğrulamasını aç.","Beklemede şifreleme (TDE veya disk/volume şifreleme) uygulayarak çalınan disk/yedeği okunamaz kıl.","Anahtar yönetimini ciddiye al: anahtarları ayrı bir KMS/HSM'de tut ve düzenli döndür.","Kredi kartı, kimlik gibi çok hassas alanları uygulama katmanında ayrıca (alan bazlı) şifrele.","Yedekleri de şifrele; üretimdeki korumayı yedek ve replikalarda da sürdür.","Hassas veriyi test/geliştirme ortamında maskele veya anonimleştir (data masking)."],"level":"senior"},{"id":"monitoring-basics","title":"İzleme temelleri (altın sinyaller)","category":"Operasyon","summary":"Etkili izleme, doğru metrikleri toplayıp anlamlı eşiklerle alarma bağlamaktır; sorunu kullanıcı fark etmeden yakalar.","points":["Altın sinyalleri izle: gecikme (latency), trafik, hata oranı ve doygunluk (saturation).","Veritabanına özel metrikleri ekle: yavaş sorgular, lock/bekleme süreleri, bağlantı sayısı, cache isabet oranı, replikasyon gecikmesi.","Alarmları belirti yerine etkiye ve eyleme dönüştürülebilir eşiklere bağla; gürültülü alarm körlük yaratır.","Yavaş sorgu logunu ve sorgu istatistiklerini (pg_stat_statements gibi) sürekli açık tut ve düzenli incele.","Metrikleri tarihsel olarak sakla; trend ve kapasite planlama için temel (baseline) oluştur.","Diskte kalan alan ve yedek başarısı gibi kritik durumları mutlaka alarma bağla."],"level":"junior"},{"id":"query-design","title":"Sorgu tasarımı ve N+1 önleme","category":"Performans","summary":"Verimli sorgu, yalnızca gereken veriyi minimum gidiş-gelişle çeker; N+1 en yaygın ve en sinsi performans hatasıdır.","points":["SELECT * yerine yalnızca ihtiyaç duyulan sütunları seç; ağ, bellek ve covering index fırsatını iyileştir.","N+1 problemini önle: döngü içinde tekil sorgu yerine JOIN veya toplu (batch/IN) sorgu kullan; ORM'de eager loading aç.","Büyük sonuç kümelerini sayfalandır; OFFSET yerine büyük veride keyset (seek) sayfalama tercih et.","İş mantığını mümkün olduğunca sorguya bırak; tüm tabloyu çekip uygulamada filtreleme/toplama yapma.","EXPLAIN ANALYZE ile gerçek plan ve satır tahminlerini incele; full table scan ve yanlış tahminleri gider.","Sık ve pahalı toplama sorgularını materialized view veya önceden hesaplanmış özet tabloyla destekle."],"level":"junior"},{"id":"large-table-management","title":"Büyük tablo yönetimi (arşivleme/partition)","category":"Performans","summary":"Sürekli büyüyen tablolar zamanla sorgu, bakım ve yedeklemeyi yavaşlatır; arşivleme ve bölümleme ile kontrol altında tutulur.","points":["Sıcak (aktif) ve soğuk (geçmiş) veriyi ayır; eski veriyi arşiv tablosuna veya ucuz depoya taşı.","Tabloyu tarih/aralık bazlı partition'la; eski veriyi DELETE yerine partition DROP ile anında temizle.","Büyük silme/güncellemeyi küçük batch'lerle yap; tek dev DELETE lock, WAL şişmesi ve bloat yaratır.","Bloat'ı ve tablo/index boyutunu düzenli izle; gerekiyorse online yeniden düzenleme (VACUUM/reorg) uygula.","Sık kullanılan sorgulara uygun index'leri koru; büyük tabloda gereksiz index bakımı çok pahalıdır."],"level":"senior"},{"id":"caching-strategy","title":"Önbellekleme (cache) stratejisi","category":"Performans","summary":"Cache tekrar eden okumaları veritabanından uzaklaştırarak gecikmeyi ve yükü düşürür; asıl zorluk geçersiz kılmadır.","points":["Cache'i pahalı ve sık okunan, nadir değişen veriler için kullan; her şeyi cache'lemeye çalışma.","Bir geçersiz kılma (invalidation) stratejisi seç: TTL, yazınca güncelle (write-through) veya yazınca sil (write-invalidate).","Bayat (stale) veri toleransını iş kuralına göre belirle; kritik tutarlılık gerektiren yerde cache'e güvenme.","Cache stampede'i (aynı anda çok isteğin boş cache'i doldurması) lock veya request coalescing ile önle.","Cache isabet oranını (hit ratio) izle; düşük isabet oranı cache'in fayda sağlamadığını gösterir.","Cache kalıcı durum değil, hızlandırma katmanıdır; cache uçtuğunda sistem doğru çalışmaya devam etmeli."],"level":"senior"},{"id":"statistics-maintenance","title":"İstatistik ve bakım disiplini","category":"Operasyon","summary":"Güncel istatistikler ve düzenli bakım, sorgu planlayıcının doğru karar vermesini ve performansın zamanla bozulmamasını sağlar.","points":["İstatistikleri güncel tut (ANALYZE / auto-analyze); bayat istatistik planlayıcıyı yanlış plana iter.","Dead tuple ve bloat'ı temizlemek için düzenli VACUUM/temizleme çalıştır; MVCC motorlarında bu kritiktir.","Index parçalanmasını (fragmentation) izle ve gerektiğinde online yeniden oluştur (REINDEX/rebuild).","Toplu yükleme (bulk load) sonrası istatistikleri elle güncelle; planlayıcının eski dağılımla çalışmasını engelle.","Bakım işlerini düşük trafikli pencerelerde planla ve süre/etkilerini izle; otomasyona bağla.","Plan regresyonlarını (aniden yavaşlayan sorgu) izle; istatistik güncelliği ilk kontrol edilecek noktadır."],"level":"senior"}]},"guide/best-practices-2.json":{"topics":[{"id":"iac","title":"Altyapıyı kod olarak yönet (IaC)","category":"Operasyon","summary":"Veritabanı sunucuları, ağ ve yapılandırma elle değil, versiyonlanmış kodla tanımlanmalı; böylece ortamlar tekrarlanabilir, denetlenebilir ve geri alınabilir olur.","points":["Sunucu, parametre grubu, ağ ve kullanıcı tanımlarını Terraform/Pulumi/CloudFormation gibi araçlarla kod olarak tut ve kaynak kontrolüne al.","Elle konsoldan yapılan (click-ops) değişiklikleri yasakla; drift tespitini çalıştırıp koddan sapan kaynakları düzelt.","Ortamlar arası farkı (dev/stage/prod) değişkenlerle yönet; aynı modülle üretim benzeri ortamlar üret.","State dosyasını uzak ve kilitli tut (örn. S3 + DynamoDB lock); gizli değerleri state içine düz metin olarak sızdırma.","Değişiklikleri plan/apply akışında gözden geçir; üretime otomatik onay kapıları (approval) koy."],"level":"senior"},{"id":"automation-idempotency","title":"Otomasyon ve idempotentlik","category":"Operasyon","summary":"Operasyon işleri elle tekrar edilebilir komutlar yerine, kaç kez çalışırsa çalışsın aynı sonucu veren idempotent otomasyona dönüştürülmelidir.","points":["Her betiği yeniden çalıştırıldığında hata vermeyecek ve durumu bozmayacak şekilde idempotent yaz (CREATE yerine CREATE IF NOT EXISTS gibi).","Tekrarlayan bakım işlerini (yedek, temizlik, istatistik) zamanlanmış ve loglanan otomasyona bağla; elle çalıştırmaya bırakma.","Betiklerde açık ön koşul kontrolü ve güvenli çıkış kur; yarım kalan işlemi tekrar çalıştırınca kaldığı yerden tamamlayabilmeli.","Otomasyonu koddan çalıştır (Ansible/betik + CI); üretimde birinin terminalde komut yazmasına bağımlı olma.","Kritik işlemlerde önce kuru çalıştırma (dry-run) desteği sun; etkiyi uygulamadan önce göster."],"level":"senior"},{"id":"observability","title":"Gözlemlenebilirlik (metrik/log/iz)","category":"Operasyon","summary":"Gözlemlenebilirlik metrik, log ve dağıtık iz (trace) üçlüsünü birleştirerek 'ne oldu' sorusundan 'neden oldu' sorusuna geçmeyi sağlar.","points":["Üç sinyali birlikte topla: metrik (eğilim), log (bağlam), iz (istek yolu); tek başına biri kök nedeni göstermez.","Sorguları uçtan uca izle: uygulama trace'i ile veritabanı gecikmesini ilişkilendir (OpenTelemetry gibi standartlarla).","Logları yapılandırılmış (JSON) ve ilişkilendirme kimliğiyle (correlation/trace id) üret; serbest metin log aramayı zorlaştırır.","Yüksek kardinaliteli etiketlerden kaçın; metrik patlamasını (cardinality explosion) ve maliyeti kontrol et.","Kırmızı çizgi (SLO) belirle ve hata bütçesini (error budget) izle; gözlemi iş hedefine bağla."],"level":"senior"},{"id":"alerting-strategy","title":"Alarm stratejisi (gürültüsüz, eyleme dönük)","category":"Operasyon","summary":"İyi bir alarm stratejisi yalnızca gerçek ve eyleme dönüştürülebilir durumlarda insanı uyandırır; gürültü alarm körlüğü ve tükenmişlik yaratır.","points":["Belirti yerine etkiye ve kullanıcı deneyimine (SLO ihlali) alarm kur; her metrik dalgalanmasını çağrıya bağlama.","Her alarmın net bir sahibi, koşulu ve çalıştırma kitabı (runbook) olsun; ne yapılacağı belli değilse alarm değersizdir.","Eşiklerde histerezis ve süre (for: 5m) kullan; anlık sıçramaların çığlık atmasını engelle.","Sayfalama (page) ile bilgilendirmeyi (ticket/e-posta) ayır; sadece hemen müdahale gerekeni uyandırsın.","Alarmları düzenli gözden geçir; sürekli tetiklenip yok sayılanları düzelt veya kaldır.","Yedek başarısızlığı, disk dolması ve replikasyon durması gibi sessiz felaketleri mutlaka kapsa."],"level":"senior"},{"id":"dr-testing","title":"DR/failover tatbikatı disiplini","category":"Yedek & HA","summary":"Felaket kurtarma planı ancak düzenli ve gerçekçi tatbikatlarla doğrulandığında güvenilirdir; test edilmemiş plan bir varsayımdan ibarettir.","points":["Failover ve geri yükleme tatbikatını takvime bağla ve periyodik yap; yılda bir kağıt üstünde plan yeterli değildir.","Her tatbikatta gerçek RTO ve RPO'yu ölç; hedefle sapmayı raporla ve iyileştir.","Planlı failover'ı üretim benzeri ortamda gerçek trafikle prova et; sadece standby'ı açıp kapatma.","Oyun günü (game day) senaryolarıyla bölge kaybı, disk arızası ve veri bozulması gibi durumları canlandır.","Tatbikat sonrası öğrenilenleri runbook'a işle; el yordamıyla hatırlanan adımları otomasyona dök."],"level":"expert"},{"id":"blue-green-deploy","title":"Mavi-yeşil / sıfır kesinti dağıtım","category":"Operasyon","summary":"Mavi-yeşil ve kanarya dağıtımları, yeni sürümü eskisiyle yan yana çalıştırıp trafiği kademeli devrederek kesintiyi ve riski en aza indirir.","points":["İki üretim ortamı (mavi/yeşil) tut; yeni sürümü boştaki ortama dağıt, doğrula, sonra trafiği tek adımda çevir.","Sorun çıkarsa trafiği anında eski ortama geri al; geri dönüş (rollback) yeniden dağıtım gerektirmesin.","Kanarya ile trafiğin küçük yüzdesini yeni sürüme ver, metrikleri izleyip kademeli artır.","Veritabanı şemasını dağıtımdan ayrıştır: iki kod sürümü de aynı şemayla çalışabilmeli (expand-contract).","Sağlık kontrolü ve otomatik geri alma eşiklerini önceden tanımla; insana bağımlı manuel karar süresini kısalt."],"level":"senior"},{"id":"expand-contract","title":"Geriye uyumlu şema değişimi (expand-contract)","category":"Tasarım","summary":"Expand-contract deseni, şema değişikliğini önce ekleme (expand), sonra taşıma, en son eskiyi kaldırma (contract) olarak parçalayarak sıfır kesintili geçiş sağlar.","points":["Önce genişlet: yeni sütun/tabloyu geriye uyumlu (nullable veya varsayılanlı) olarak ekle, eskiyi bozma.","Uygulamayı hem eski hem yeni şemayla çalışacak şekilde çift-yazma (dual-write) veya çift-okuma yapacak biçimde dağıt.","Arka planda veriyi küçük batch'lerle yeni yapıya taşı ve doğrula; tek dev migration ile kilitleme.","Tüm örnekler yeni sürüme geçtikten ve doğrulama tamamlandıktan sonra daralt: eski sütun/kodu kaldır.","Her adımı ayrı dağıtımda yap; asla 'ekle ve eskiyi aynı anda sil' yapma, geri dönüş imkânsızlaşır.","NOT NULL ve constraint'leri en sonda, veri tutarlı hale geldikten sonra ekle."],"level":"expert"},{"id":"secrets-management","title":"Sır yönetimi (parola/anahtar)","category":"Güvenlik","summary":"Veritabanı parolaları, API anahtarları ve bağlantı dizeleri koda veya konfigürasyona gömülmemeli; merkezi bir sır yöneticisiyle güvenli saklanıp döndürülmelidir.","points":["Sırları kod, repo, ortam dosyası veya imaj içine gömme; Vault, AWS Secrets Manager, KMS gibi bir sır deposu kullan.","Uygulamalara sırları çalışma anında (runtime) enjekte et; disk üzerinde düz metin bırakma.","Parolaları ve anahtarları düzenli döndür (rotate); mümkünse kısa ömürlü, otomatik üretilen kimlik bilgileri kullan.","Erişimi en az yetkiyle ve denetim kaydıyla (audit log) ver; kim hangi sırra ne zaman eriştiği izlenebilsin.","Kod tabanını sır sızıntısına karşı tara (git-secrets, trufflehog); sızan sırrı derhal iptal edip döndür.","İnsan erişimini kişisel değil, geçici ve onaya bağlı (just-in-time) hale getir."],"level":"senior"},{"id":"cost-optimization","title":"Bulut maliyet optimizasyonu","category":"Operasyon","summary":"Bulut veritabanı maliyeti; doğru boyutlandırma, depolama katmanlama ve kullanılmayan kaynakların temizlenmesiyle performanstan ödün vermeden ciddi biçimde düşürülebilir.","points":["Örnekleri gerçek kullanım metriğine göre boyutlandır; sürekli düşük kullanımlı sunucuları küçült (right-sizing).","Öngörülebilir taban yük için ayrılmış kapasite/tasarruf planı (reserved/savings) kullan; değişken yükü isteğe bağlı bırak.","Soğuk veriyi ucuz depolama katmanına taşı; sıcak ve nadir erişilen veriyi ayır.","Kullanılmayan kaynakları temizle: sahipsiz snapshot, boşta replika, terk edilmiş test veritabanı maliyet sızıntısıdır.","Maliyeti etiketlerle (tag) sahiplere ata ve bütçe alarmı kur; sürprizleri ay sonu değil anında gör.","Yedek saklama süresini ve replika sayısını iş ihtiyacına göre gözden geçir; fazlası hem risk hem maliyettir."],"level":"senior"},{"id":"multi-tenancy","title":"Çok kiracılı (multi-tenant) tasarım","category":"Tasarım","summary":"Çok kiracılı sistemlerde izolasyon modeli (paylaşımlı tablo, ayrı şema, ayrı veritabanı) güvenlik, maliyet ve ölçeklenme arasında bilinçli bir ödünleşimdir.","points":["İzolasyon modelini seç: paylaşımlı tablo (tenant_id), kiracı başına şema veya kiracı başına veritabanı; her birinin maliyet/izolasyon dengesi farklıdır.","Paylaşımlı modelde her sorguya tenant_id filtresi uygula; satır seviyesi güvenlik (RLS) ile sızıntıyı motor düzeyinde garanti et.","tenant_id'yi ilgili index'lerin başına koy; kiracılar arası çapraz tarama ve hotspot oluşmasını engelle.","Gürültülü komşu (noisy neighbor) etkisine karşı kaynak sınırı ve kota uygula; bir kiracı diğerlerini boğmamalı.","Büyük veya premium kiracıları ayrı şema/veritabanına taşıyabilecek bir yol (tenant migration) baştan tasarla.","Yedek, silme ve veri taşınabilirliğini kiracı bazında düşün; KVKK/GDPR silme talebini karşılayabilmelisin."],"level":"expert"},{"id":"time-series-design","title":"Zaman-serisi veri tasarımı","category":"Tasarım","summary":"Zaman-serisi veriler yüksek yazma hacmi ve zaman bazlı sorgu deseniyle özeldir; tarih bazlı bölümleme, toplama (rollup) ve saklama politikasıyla tasarlanmalıdır.","points":["Veriyi zaman (timestamp) bazlı RANGE partition ile böl; eski veriyi partition DROP ile ucuza temizle.","Ham veriyi olduğu gibi biriktirmek yerine düzenli aralıklı özetler (rollup/continuous aggregate) üret; sorgular özet üstünden hızlansın.","Zaman ve etiket (tag/kaynak) bileşenlerini index'in başına koy; tipik sorgu 'belirli kaynak, belirli aralık' desenindedir.","Uygun araç seç: yüksek hacimde TimescaleDB, ClickHouse gibi zaman-serisi motorları ilişkiselden çok daha verimli olabilir.","Saklama (retention) politikasını baştan tanımla; ham veriyi kısa, özet veriyi uzun sakla.","Zamanı her zaman UTC olarak sakla; yerel saat ve yaz saati kaymalarını sorgu katmanında çöz."],"level":"senior"},{"id":"event-sourcing","title":"Event sourcing / CQRS temelleri","category":"Tasarım","summary":"Event sourcing durumu değil, durumu değiştiren olayları kayıt altında tutar; CQRS ise okuma ve yazma modellerini ayırarak her birini bağımsız ölçekler.","points":["Güncel durumu üzerine yazmak yerine, değişmez (immutable) olay akışını biriktir; mevcut durumu olayları tekrar oynatarak (replay) türet.","CQRS ile yazma modelini (komut) okuma modelinden (sorgu) ayır; okuma tarafını denormalize projeksiyonlarla hızlandır.","Olay şemasını sürümle ve geriye uyumlu evrimleştir; eski olayları asla silme, upcasting ile yeni sürüme dönüştür.","Okuma projeksiyonlarının nihai tutarlı (eventually consistent) olacağını kabul et ve gecikmeyi tasarımda öngör.","Snapshot al ki uzun olay akışını her seferinde baştan oynatma maliyetinden kaçın.","Bu deseni her yerde değil, denetim izi, karmaşık iş kuralı ve zamanla geçmişi gerektiren alanlarda kullan; getirdiği karmaşıklığı hafife alma."],"level":"expert"},{"id":"data-retention","title":"Veri saklama ve arşivleme politikası","category":"Operasyon","summary":"Her veri sonsuza dek saklanmaz; yasal, iş ve maliyet gereksinimlerine göre tanımlı bir saklama ve arşivleme politikası hem uyumluluk hem performans sağlar.","points":["Her veri türü için saklama süresini iş ve yasal (KVKK/GDPR) gereksinimle netleştir; belirsiz 'her ihtimale karşı sakla' bir politika değildir.","Süresi dolan veriyi otomatik arşivle veya sil; elle temizliğe bırakma, unutulur ve tablolar şişer.","Sıcak veriyi hızlı depoda, arşivi ucuz/soğuk depoda tut; erişim sıklığına göre katmanla.","Kişisel verinin silme/anonimleştirme talebini karşılayacak mekanizmayı baştan tasarla (silme hakkı).","Arşivlenen veriyi geri getirebilir ve gerektiğinde sorgulanabilir tut; arşiv eşittir erişilemez olmamalı.","Silme işlemlerini denetim kaydına yaz; neyin ne zaman neden silindiği izlenebilir olsun."],"level":"senior"},{"id":"change-management","title":"Değişiklik yönetimi ve prod güvenliği","category":"Operasyon","summary":"Üretim veritabanındaki her değişiklik gözden geçirilmiş, geri alınabilir ve izlenebilir olmalı; kontrolsüz elle müdahale en yaygın kesinti nedenidir.","points":["Üretimde elle ad-hoc DDL/DML çalıştırma; her değişiklik gözden geçirilmiş (peer-review) bir migration veya betikten geçsin.","Değişiklikleri düşük trafikli pencerede ve geri alma (rollback) planı hazırken uygula; plansız üretime dokunma.","Riskli komutları önce üretim benzeri ortamda gerçek veri hacmiyle prova et; süresini ve lock etkisini ölç.","Üretime erişimi kısıtla ve denetle: kim, ne zaman, hangi komutu çalıştırdı loglanmalı (just-in-time erişim).","Silme/güncelleme öncesi WHERE koşulunu ve etkilenecek satır sayısını doğrula; transaction içinde çalışıp önce SELECT ile teyit et.","Değişiklikleri takvime ve iletişime bağla; sürpriz üretim değişikliğiyle diğer ekipleri şaşırtma."],"level":"senior"}]},"guide/best-practices-3.json":{"topics":[{"id":"plan-reading-expert","title":"Sorgu planı nasıl okunur","category":"Performans","summary":"Yürütme planı, optimizatörün tahminlerini ve seçtiği fiziksel operatörleri gösterir; darboğaz tahmin (estimated) ile gerçek (actual) satır sayısı arasındaki sapmada gizlidir.","points":["Erişim yöntemini ayırt et: Full/Table Scan büyük tabloda geniş okuma içindir, Index Seek/Range Scan seçici koşullar için, Index Full Scan sıralı okuma için; Rows Removed by Filter veya predicate/access ayrımı seçiciliğin nerede kaybedildiğini gösterir.","Join yöntemini yükle eşleştir: Nested Loop küçük dış küme + index'li iç küme için, Hash Join büyük eşitlik birleşimleri için, Merge Join önceden sıralı iki küme için idealdir; yanlış seçim çoğu zaman kötü kardinalite tahmininin sonucudur.","Kardinalite tahmini hatasını avla: EXPLAIN ANALYZE (PG), DBMS_XPLAN ALLSTATS LAST (Oracle) veya SET STATISTICS PROFILE (MSSQL) ile estimated vs actual rows oranına bak; 10x üzeri sapma plan seçiminin kökten yanlış olabileceğini işaret eder.","Planı gerçek maliyete göre oku: en çok zamanı/mantıksal okumayı (logical reads, buffers) tüketen operatörü bul; optimizatör 'cost' birimi tahminidir, gerçek darboğaz değildir.","Spill/geçici alan uyarılarını yakala: Hash/Sort operatörünün belleğe sığmayıp diske taşması (PG 'Sort Method: external merge', MSSQL planda Sort/Hash Warning, SpillToTempDb) work_mem/sort alanı yetersizliğini gösterir.","Operatör ağacını içten dışa ve alttan yukarı oku: iç düğümler önce çalışır, satırlar yukarı akar; loops/actual time çarpımıyla operatör başına toplam maliyeti hesapla."],"level":"expert"},{"id":"parameter-sniffing-deep","title":"Parameter sniffing ve bind peeking","category":"Performans","summary":"Optimizatör ilk çağrıdaki parametre değerine göre plan üretip önbelleğe alır; sonraki farklı dağılımlı değerler bu planı miras alınca performans dramatik biçimde değişebilir.","points":["Belirtiyi tanı: aynı sorgu bazı parametrelerle hızlı, bazılarıyla çok yavaş; önbellekteki planın atipik bir 'ilk' değere göre derlendiğini gösterir.","Çarpık (skewed) dağılımlı sütunlarda risk yüksektir; histogram varlığı optimizatörün değere duyarlı olmasını, tek plan önbelleği ise duyarsız kalmasını sağlar; bu gerilim sorunun kaynağıdır.","MSSQL'de OPTION (RECOMPILE) her çalıştırmada plan üretir, OPTIMIZE FOR UNKNOWN yoğunluk (density) ortalamasıyla dengeli bir plan seçer, OPTIMIZE FOR (@p = deger) tipik değeri sabitler.","Oracle'da adaptive cursor sharing ve bind-aware kürsörler çarpık değerler için farklı planlar üretir; PG'de custom vs generic plan seçimi plan_cache_mode ile yönetilir.","Kalıcı çözüm için değere göre planı ayrıştır: sorgu ayrımı (statement splitting), filtered/partial index veya çok atipik değerlere ayrı erişim yolu tasarla.","OLTP'de aşırı RECOMPILE CPU ve derleme (hard parse) maliyeti getirir; sık çalışan sorgularda ölç ve dengeyi gözet."],"level":"expert"},{"id":"plan-stability","title":"Plan kararlılığı: baseline, hint ve plan guide","category":"Performans","summary":"Kritik sorguların doğrulanmış planlarını dondurarak istatistik/sürüm değişiminde beklenmedik plan regresyonlarını önlemek için motora özgü kalıcılık mekanizmaları kullanılır.","points":["Oracle'da SQL Plan Baselines (SPM) ile onaylı planları sabitle; yeni planlar 'accepted' olana dek yalnızca aday olarak toplanır, evolve ile kontrollü doğrulanır.","MSSQL'de Query Store ile plan regresyonunu tespit et ve 'Force Plan' ile iyi bilinen planı zorla; Automatic Plan Correction bunu otomatikleştirebilir.","PostgreSQL'de yerleşik plan dondurma yoktur; pg_hint_plan uzantısı veya sorgu yeniden yazımı, genişletilmiş istatistik ve index tasarımıyla kararlılık sağlanır.","Hint'i son çare olarak, gerekçelendirerek ve yorumlayarak kullan; hint fiziksel şemayı ve veri dağılımını varsayar, bunlar değişince zararlı hale gelir.","Baseline/forced plan envanterini periyodik denetle; sabitlenmiş planlar veri büyüdükçe zamanla optimalliğini yitirebilir, 'sabit ama yavaş' tuzağına düşme.","Sürüm yükseltmesi öncesi kritik sorgu planlarını yakala; optimizatör davranış değişikliklerine karşı bir güvenlik ağı olarak baseline hazırla."],"level":"expert"},{"id":"latch-mutex-contention","title":"Latch, mutex ve spinlock çekişmesi","category":"Performans","summary":"Latch/mutex bellek içi yapıları koruyan hafif lock'lardır; yüksek eşzamanlılıkta bunlara yönelen çekişme CPU'yu spinlock döngülerinde yakar ve ölçeklenmeyi durdurur.","points":["Lock ile latch farkını ayır: lock'lar mantıksal veriyi (satır/tablo) transaction boyunca korur, latch'ler fiziksel bellek yapılarını (buffer, hash chain) mikrosaniyeler için korur; teşhis yöntemleri farklıdır.","Oracle'da 'cache buffers chains' latch çekişmesi genelde hot block'a işaret eder; sık okunan küçük tablo veya sıralı artan index ucu (right-hand index) yaygın nedendir.","Sıralı artan anahtar (identity/sequence) INSERT'lerinde son sayfa/blok çekişmesi (hot page, PAGELATCH) oluşur; hash partition, reverse-key index veya rasgeleleştirilmiş anahtar ile dağıt.","MSSQL'de spinlock istatistiklerini ve PAGELATCH_* beklemelerini izle; tempdb ayırma çekişmesi için birden çok data file ve uygun tempdb yapılandırması uygula.","Spinlock çekişmesi yüksek CPU ama düşük iş üretimiyle görünür; çözüm kod/mimari düzeyde çekişmeyi azaltmaktır, donanım eklemek çoğu zaman sorunu büyütür.","NUMA farkındalığı ve bağlantı sayısını sınırlama (pool) latch çekişmesini azaltır; aşırı paralellik latch baskısını artırabilir."],"level":"expert"},{"id":"wait-event-methodology","title":"Wait event analizi metodolojisi","category":"Performans","summary":"Performansı tahminle değil, sistemin zamanı nerede beklediğini ölçerek yönet; top-down bekleme analizi darboğazı sistematik olarak daraltan bilimsel yöntemdir.","points":["DB time'ı bileşenlerine ayır: CPU üzerinde harcanan süre ile bekleme (wait) süresini ayrıştır; en büyük bileşenden başla, mikro-optimizasyona sapma.","Oracle'da ASH/AWR ve 'Top Wait Events', PG'de pg_stat_activity + pg_wait_sampling, MSSQL'de sys.dm_os_wait_stats ve Query Store ile en çok beklenen olayı bul.","Bekleme sınıfını yorumla: I/O beklemeleri depolama/plan, lock beklemeleri eşzamanlılık tasarımı, latch beklemeleri hotspot, ağ/commit beklemeleri yapılandırma sorununa işaret eder.","Oturum/sorgu düzeyine in: toplam beklemeden başlayıp en çok katkı yapan SQL'e ve ardından o SQL'in planına inerek nedeni izole et (drill-down).","Ölçümü iş yükü penceresine bağla: kümülatif sayaçların iki nokta arasındaki farkını (delta) al; toplam sayaçlar yanıltır, oran ve zaman aralığı önemlidir.","İdle/benign beklemeleri gürültüden ayıkla; her bekleme sorun değildir, kritik olan kullanıcı yanıt süresine katkı yapan öndeki (foreground) beklemelerdir."],"level":"expert"},{"id":"plan-regression-detection","title":"Yürütme planı regresyonunu tespit","category":"Performans","summary":"Bir sorgunun aniden yavaşlaması çoğu zaman kodun değil planın değişmesindendir; regresyonu proaktif tespit etmek reaktif yangın söndürmeden ucuzdur.","points":["Plan geçmişini sakla ve karşılaştır: MSSQL Query Store, Oracle AWR/SQL Monitor ile aynı sql_id/query_hash için plan değişimini ve süre/kaynak trendini izle.","Regresyonun tetikleyicisini belirle: istatistik güncellemesi, veri hacmi büyümesi, sürüm yükseltmesi, parametre değişimi veya index kaldırma en yaygın nedenlerdir.","Otomatik uyarı kur: plan hash değişip ortalama süre/mantıksal okuma belirli eşiği aşınca alarm üret; kümülatif değil çalıştırma başına metriği izle.","Hızlı geri alma yolu hazırla: bilinen iyi planı Force Plan (MSSQL) veya SQL Plan Baseline (Oracle) ile geçici sabitleyip kök nedeni sonra çöz.","İstatistik kaynaklı regresyonda dondurulmuş/güncel istatistik ve histogram tazeliğini incele; otomatik istatistik toplama zamanlaması kritik saatlere denk gelebilir.","Yükseltme öncesi regresyon testi yap: temsili iş yükünü eski ve yeni optimizatörle çalıştırıp plan farklarını raporla (Oracle SPA benzeri yaklaşım)."],"level":"expert"},{"id":"mvcc-vacuum-internals","title":"MVCC ve vacuum/undo iç yapısı","category":"İç Yapı","summary":"MVCC eski satır sürümlerini saklayarak okuyucu-yazıcı bloklanmasını önler; bu sürümlerin nasıl ve nerede tutulduğu (undo vs tabloya gömülü) bakım stratejisini belirler.","points":["PostgreSQL'de eski sürümler tablonun kendi içinde dead tuple olarak kalır; VACUUM onları temizler, aksi halde bloat ve index büyümesi oluşur.","Oracle ve MySQL/InnoDB eski sürümü undo/rollback segmentinde tutar; uzun okuma işlemi undo'yu tüketirse 'ORA-01555 snapshot too old' benzeri hatalar görülür.","Autovacuum'u iş yüküne göre ayarla: yüksek update/delete tablolarında ölçek faktörünü düşür, maliyet gecikmesini azalt; agresif tablolara tablo-bazlı ayar ver.","Görünürlük haritasını (visibility map) sağlıklı tut; index-only scan ve donmuş (frozen) tuple takibi buna dayanır, bakımsız kalırsa performans düşer.","Transaction ID wraparound riskini izle: PG'de datfrozenxid/age metriğini takip et, aggressive/anti-wraparound vacuum'un iş saatinde patlamasını önle.","HOT (Heap-Only Tuple) güncellemelerini teşvik et: indekslenmiş sütunu değiştirmeyen update'ler index'i büyütmeden yerinde güncellenir; uygun fillfactor bunu destekler."],"level":"expert"},{"id":"wal-redo-log-mechanics","title":"WAL/redo/transaction log mekaniği","category":"İç Yapı","summary":"Kalıcılık, veri sayfaları diske yazılmadan önce değişikliğin log'a yazılmasıyla sağlanır; log akışının hızı ve boyutu hem dayanıklılığı hem yazma performansını belirler.","points":["Write-ahead ilkesini kavra: commit'in dönebilmesi için ilgili log kayıtlarının kalıcı depolamada olması yeterlidir; dirty page'ler daha sonra tembelce (lazy) yazılır.","Grup commit ve log flush davranışını ayarla: PG'de commit_delay/synchronous_commit, Oracle'da log writer davranışı ile fsync sıklığını iş yükü dayanıklılık gereksinimine göre dengele.","Log üretim hızını (WAL/redo generate) izle; ani artış toplu güncelleme, checkpoint sonrası tam sayfa görüntüleri (full_page_writes/FPI) veya index bakımına işaret eder ve DR gecikmesini büyütür.","Log yalnızca kurtarma değil replikasyon ve CDC kaynağıdır; logical replication ve WAL shipping bu akıştan beslenir, arşiv/temizleme politikasını buna göre kur.","Log diskini veri diskinden ayır ve düşük gecikmeli depolamaya koy; log yazımı sıralı (sequential) ve gecikmeye duyarlıdır, commit throughput'u doğrudan buna bağlıdır.","Kontrol edilmemiş log büyümesine karşı önlem al: MSSQL'de doğru recovery model ve düzenli log yedeği, PG'de arşivleme/replikasyon slot'larının geride kalmamasını sağla."],"level":"expert"},{"id":"buffer-pool-management","title":"Buffer/shared pool yönetimi ve eviction","category":"İç Yapı","summary":"Buffer pool sıcak veriyi bellekte tutarak disk I/O'sunu azaltır; hangi sayfanın ne zaman atılacağını (eviction) belirleyen algoritma isabet oranını ve kararlılığı yönetir.","points":["İsabet oranını (buffer cache hit ratio) tek başına hedefleme; yüksek oran bile fiziksel okumaların gecikmesini gizleyebilir, mutlak I/O ve bekleme süresine de bak.","Eviction algoritmasını anla: saf LRU'nun tarama (sequential scan) ile kirlenmesine karşı PG clock-sweep, Oracle touch-count/LRU varyantı, InnoDB midpoint-insertion LRU kullanır.","Büyük tek seferlik taramaların sıcak veriyi pool'dan süpürmesini (cache pollution) önle; ayrı buffer havuzları veya tarama dostu erişim stratejileriyle koru.","Dirty page oranını ve yazma baskısını yönet: çok dirty page checkpoint'te I/O dalgalanması yaratır, çok agresif yazma gereksiz I/O üretir; dengeyi ölç.","Bellek boyutunu çalışma kümesine (working set) göre boyutlandır; toplam veriyi değil aktif erişilen kümeyi karşılamak hedeftir, aşırı büyütme getiriyi azaltır.","Oracle shared pool'da library/dictionary cache çekişmesini ve sık hard parse'ı izle; literal SQL yerine bind değişkeni kullanımı shared pool baskısını düşürür."],"level":"expert"},{"id":"checkpoint-tuning","title":"Checkpoint tuning","category":"İç Yapı","summary":"Checkpoint, dirty page'leri diske yazarak kurtarma süresini kısaltır; çok sık checkpoint I/O tepe noktaları, çok seyrek ise uzun kurtarma yaratır ve bu ödünleşim ayarlanmalıdır.","points":["Kurtarma süresi ile çalışma zamanı I/O'sunu dengele: seyrek checkpoint daha az yazma yükü ama daha uzun crash recovery, sık checkpoint tersi anlamına gelir.","PG'de checkpoint_timeout ve max_wal_size ile checkpoint'i zamana yay; checkpoint_completion_target ile yazmayı aralığa dağıtarak I/O tepe noktasını yumuşat.","MSSQL indirect checkpoint (target recovery time) ile sürekli arka plan yazımı sağlar; ani büyük checkpoint dalgalarını önleyerek gecikmeyi öngörülebilir kılar.","Checkpoint sıklığını log/WAL üretim hızıyla ilişkilendir; ağır yazma dönemlerinde zaman değil boyut tetikleyicisinin devreye girip girmediğini izle.","full_page_writes (PG) checkpoint sonrası ilk değişimde tam sayfa loglar; checkpoint çok sık ise WAL hacmi şişer, bu da DR ve disk maliyetini artırır.","'Checkpoint sink' belirtilerini yakala: checkpoint sırasında yükselen yazma gecikmesi ve fsync beklemesi; depolama kuyruğunu ve dağıtımı gözden geçir."],"level":"expert"},{"id":"statistics-strategy","title":"İstatistik toplama stratejisi","category":"İç Yapı","summary":"Optimizatör kararlarının kalitesi istatistiklerin tazeliği ve çözünürlüğüne bağlıdır; örnekleme oranı, histogram ve genişletilmiş istatistikler kardinalite tahminini belirler.","points":["Örnekleme oranını veri boyutuna ve çarpıklığa göre seç: çok düşük örnek çarpık dağılımda yanlış tahmin, çok yüksek örnek gereksiz toplama maliyeti üretir.","Histogram ile çarpıklığı modelle: PG default_statistics_target, Oracle FREQUENCY/HYBRID histogramları, MSSQL istatistik histogramı sık ve dengesiz değerleri optimizatöre gösterir.","Sütunlar arası korelasyonu genişletilmiş istatistikle yakala: PG CREATE STATISTICS (ndistinct/dependencies), Oracle extended stats birbirine bağımlı sütunlarda tahmin hatasını düzeltir.","Toplama zamanlamasını iş yükünden ayır: otomatik istatistik/gather job'ının kritik saatlere denk gelip I/O ve plan kararsızlığı yaratmasını engelle.","Hızlı büyüyen tablolarda bayat istatistik riskini yönet; eşik tabanlı otomatik güncelleme geç kalabilir, kritik tablolara manuel/planlı toplama ekle.","İstatistik değişiminin plan regresyonu yaratabileceğini bil; kritik ortamlarda istatistikleri sabitleme (locked stats) veya pending publish ile kontrollü yayınla."],"level":"expert"},{"id":"partition-pruning-join","title":"Partition pruning ve partition-wise join","category":"Ölçek/Mimari","summary":"Bölümleme (partitioning) yalnızca tabloyu bölmez; asıl kazanç, sorgunun ilgisiz bölümleri hiç okumaması (pruning) ve birleşimlerin bölüm bazında paralel yapılmasıdır.","points":["Bölümleme anahtarını en sık ve seçici filtreye göre seç; pruning ancak sorgu koşulu bölüm anahtarını içerdiğinde çalışır, aksi halde tüm bölümler taranır.","Statik ve dinamik pruning'i ayırt et: sabit değerli koşullar derleme anında, bind/join değerleri çalışma anında (runtime pruning) bölüm eler; planı buna göre doğrula.","Partition-wise join için iki tabloyu aynı anahtar ve uyumlu şemayla bölümle; optimizatör büyük birleşimi bölüm-bölüm küçük birleşimlere indirger ve paralelleştirir.","Bölüm sayısı ve granülerliğini dengele: çok fazla bölüm meta veri ve plan maliyeti, çok az bölüm zayıf pruning demektir; erişim desenine göre boyutlandır.","Yaşam döngüsü yönetimini bölümlemeyle birleştir: eski bölümleri DETACH/DROP veya arşivle; bu, silme (DELETE) yerine anlık ve loglama-hafif temizlik sağlar.","Fonksiyon/tip dönüşümü veya anahtarı gizleyen ifadelerin pruning'i bozduğunu unutma; EXPLAIN ile taranan bölüm sayısını fiilen doğrula."],"level":"expert"},{"id":"shard-key-selection","title":"Sharding anahtarı seçimi ve hotspot","category":"Ölçek/Mimari","summary":"Shard anahtarı dağıtık sistemin kaderini belirler; kötü seçim yükü tek düğüme yığıp (hot shard) ölçeklenmeyi keser ve çapraz-shard sorguları pahalılaştırır.","points":["Yüksek kardinaliteli ve yükü eşit dağıtan anahtar seç; düşük kardinaliteli veya zamansal/artan anahtar yükü tek shard'a yığarak hotspot yaratır.","En sık sorguları tek shard'da çözecek anahtar tasarla; çapraz-shard (scatter-gather) sorgular gecikme ve koordinasyon maliyetini katlar.","Hash sharding yükü düzler ama aralık sorgularını dağıtır; range sharding aralık sorgusuna iyidir ama hotspot riskini artırır; erişim desenine göre seç.","Consistent hashing ile düğüm ekleme/çıkarmada yeniden dağıtımı en aza indir; sabit modulo hash düğüm sayısı değişince neredeyse tüm veriyi taşıtır.","Yeniden shard'lama (resharding) planını baştan tasarla; anahtarı sonradan değiştirmek pahalı ve risklidir, büyüme senaryosunu önceden modelle.","Tenant/müşteri bazlı bölmede dev tenant'ın (whale) tek shard'ı doldurmasına karşı ayrı shard veya alt-bölümleme (split) stratejisi hazırla."],"level":"expert"},{"id":"read-write-splitting","title":"Okuma-yazma ayrımı ve replika yönlendirme","category":"Ölçek/Mimari","summary":"Okumaları replikalara yönlendirmek yazma primary'sini rahatlatır; fakat replikasyon gecikmesi tutarlılık garantilerini bozacağından yönlendirme bilinçli yapılmalıdır.","points":["Okuma yükünü replikalara dağıtırken replikasyon gecikmesini (lag) sürekli izle; bayat replika kullanıcıya eski veri gösterebilir.","Read-your-writes gerektiren akışları (yazan kullanıcının hemen okuması) primary'e yönlendir veya nedensel (causal) okuma/token ile taze replika garantile.","Yönlendirmeyi uygulama değil altyapı katmanında yap: proxy/router (MySQL'de ProxySQL; PG'de Pgpool-II veya HAProxy ile ayrı okuma/yazma uç noktaları — PgBouncer okuma/yazma ayrımı yapmaz; MSSQL'de uygulama amacıyla read-only routing) ile şeffaf dağıt.","Gecikme eşiği aşılınca replikayı havuzdan çıkar; lag yüksek replikaya okuma göndermek 'ölçekleniyorum' yanılsamasıyla veri tutarsızlığı üretir.","Analitik/raporlama gibi ağır ve gecikmeye toleranslı okumaları özel replikaya izole et; OLTP replikalarını bu yükten koru.","Failover senaryosunda okuma yönlendirmenin otomatik güncellenmesini test et; yeni primary'i bilmeyen router split-brain veya kesinti üretir."],"level":"expert"},{"id":"connection-pool-sizing","title":"Connection pool boyutlandırma matematiği","category":"Ölçek/Mimari","summary":"Havuz boyutu sezgiyle değil, Little yasası ve çekirdek sayısına dayalı hesapla belirlenir; fazla bağlantı çekişme ve bağlam değişimiyle throughput'u düşürür.","points":["Little yasasını uygula: gerekli eşzamanlılık ≈ istek hızı (throughput) × ortalama işlem süresi; hedef eşzamanlılığı ölçülen değerlerden türet, tahminden değil.","Küçük havuz çoğu zaman daha hızlıdır: aktif bağlantı sayısı fiziksel çekirdek/disk paralelliğini aşınca CPU bağlam değişimi ve latch çekişmesi throughput'u düşürür.","Kaba başlangıç noktası olarak çekirdek sayısına yakın bir çekirdek bağlantı kullan (ör. PgBouncer arkasında az sayıda gerçek bağlantı) ve yük altında ölçerek ayarla.","Uygulama tarafı havuzu ile veritabanı max_connections'ı birlikte planla; N uygulama örneği × havuz boyutu, veritabanı sınırını aşmamalıdır.","PG gibi süreç-başına-bağlantı maliyeti yüksek motorlarda PgBouncer/transaction pooling kullan; her bağlantı bellek ve zamanlama maliyetidir.","Havuz doygunluğunu, bekleme kuyruğu süresini ve zaman aşımlarını izle; sürekli kuyruk büyümesi ya darboğaz ya da yetersiz boyut sinyalidir, körlemesine büyütme."],"level":"expert"},{"id":"lock-escalation-deadlock","title":"Lock escalation ve deadlock önleme desenleri","category":"Güvenilirlik","summary":"Çok sayıda row lock table lock'a yükselerek (escalation) eşzamanlılığı öldürebilir; deadlock ise tutarsız lock sıralamasının kaçınılabilir sonucudur.","points":["Lock escalation'ı tetikleyen büyük toplu işlemleri parçala (batch/chunk); tek transaction'da milyonlarca satır kilitlemek escalation ve blocking üretir.","Deadlock'u önlemenin temel deseni tutarlı lock sıralamasıdır: tüm kod yolları kaynakları aynı sırada (ör. primary key sırasıyla) kilitlemeli.","Transaction'ı kısa tut ve tek atomik iş yap; içinde kullanıcı etkileşimi, uzak çağrı veya uzun hesaplama barındıran transaction lock'ları gereksiz uzun tutar.","İzolasyon seviyesini bilinçli seç: gereksiz yüksek izolasyon fazla lock, gereksiz düşük anomali üretir; MVCC motorlarında okuma çoğu lock'u zaten önler.","Deadlock grafiklerini/izlerini topla (MSSQL deadlock graph, PG log_lock_waits, Oracle trace); kurbanı loglayıp tekrarlayan desenleri kök nedene indir.","Yeniden deneme (retry) mantığını uygula: deadlock kurbanı transaction'ı idempotent biçimde yeniden dene; tasarımda kaçınılmaz çekişmeler için güvenlik ağıdır."],"level":"expert"},{"id":"long-transaction-bloat","title":"Uzun transaction ve bloat/undo yönetimi","category":"Güvenilirlik","summary":"Açık kalan uzun bir transaction, MVCC motorlarında eski sürümlerin temizlenmesini engelleyerek bloat, undo baskısı ve performans çöküşü zinciri başlatır.","points":["Uzun süren/açık transaction'ları izle ve alarma bağla: PG'de idle in transaction, Oracle'da aktif undo tutan uzun sorgular temizliği (vacuum/undo geri kazanımı) durdurur.","PG'de tek uzun transaction VACUUM'un dead tuple silmesini engeller; tablo ve index şişer, bir 'zombi' oturum tüm veritabanını yavaşlatabilir.","idle_in_transaction_session_timeout ve statement_timeout ile takılı transaction'ları otomatik sonlandır; uygulama sızıntılarına karşı savunma hattı kur.","Oracle/InnoDB'de uzun okuma undo'yu tüketip 'snapshot too old' üretir; undo alanını/retention'ı iş yükünün en uzun sorgusuna göre boyutlandır.","Toplu işleri kısa commit aralıklarıyla parçala; tek dev transaction hem undo/WAL biriktirir hem geri alma (rollback) süresini tehlikeli biçimde uzatır.","Mevcut bloat'ı ölç ve geri kazan: pgstattuple ile bloat ölç, VACUUM FULL/pg_repack veya online reorg ile alanı ve index verimini iade et."],"level":"expert"},{"id":"dr-game-day","title":"DR tatbikatı (game day) ve RPO/RTO doğrulama","category":"Güvenilirlik","summary":"Test edilmemiş yedek ve failover planı bir varsayımdır; DR yeteneği ancak gerçekçi tatbikatlarla RPO/RTO ölçülerek kanıtlanır.","points":["RPO ve RTO'yu iş gereksiniminden türet ve fiilen ölç: yedek/replikasyon gecikmesi RPO'yu, kurtarma+doğrulama süresi RTO'yu belirler; hedef ile gerçeği kıyasla.","Yedeği düzenli ve otomatik geri yükle: geri yüklenmemiş yedek şrödinger yedeğidir; restore testi olmadan yedeğin var olduğu iddiası doğrulanmamıştır.","Game day tatbikatlarını üretime yakın ortamda ve gerçekçi başarısızlık senaryolarıyla planla (primary kaybı, bölge kesintisi, veri bozulması).","Failover ve failback prosedürünü uçtan uca çalıştır; DNS/bağlantı yönlendirme, uygulama yeniden bağlanma ve replika terfisini dahil et.","Point-in-time recovery (PITR) yeteneğini kanıtla: log arşivi + tam yedekle belirli bir ana dönebildiğini, mantıksal bozulma senaryosunda test et.","Her tatbikattan ölçülen RTO/RPO, sürpriz ve aksiyon maddeleri çıkar; runbook'u güncelle, bir sonraki tatbikatta iyileşmeyi doğrula."],"level":"expert"},{"id":"observability-slo","title":"Gözlemlenebilirlik ve SLO/altın sinyaller","category":"Güvenilirlik","summary":"Veritabanını iş etkisiyle yönetmek için altın sinyalleri (gecikme, trafik, hata, doygunluk) SLO'lara bağla ve hata bütçesiyle önceliklendir.","points":["Dört altın sinyali izle: gecikme (latency), trafik (throughput), hata oranı (errors) ve doygunluk (saturation); bunlar kök nedene inmeden sağlığı özetler.","Gecikmeyi ortalama değil yüzdelik dilimlerle (p95/p99) ölç; ortalama, kuyruk gecikmesini ve en kötü kullanıcı deneyimini gizler.","SLO ve hata bütçesi tanımla; alarmları semptoma (SLO ihlali) göre kur, her düşük seviye metrik dalgalanmasına değil, böylece alarm yorgunluğunu önle.","USE (Utilization, Saturation, Errors) yöntemini kaynaklara uygula: CPU, bellek, disk I/O, bağlantı havuzu doygunluğunu ayrı ayrı gözlemle.","İzlemeyi katmanlar arası ilişkilendir (correlation): sorgu → wait event → kaynak doygunluğu → iş metriği zincirini tek zaman ekseninde gör.","Metrik + log + iz (trace) üçlüsünü birlikte kur; yalnız metrik 'ne', log/iz 'neden' sorusunu yanıtlar, ikisi olmadan MTTR uzar."],"level":"expert"},{"id":"least-privilege-roles","title":"En az yetki ve rol tasarımı","category":"Güvenlik","summary":"Her hesabın yalnızca işini yapacak minimum yetkiye sahip olması ihlalin etki alanını daraltır; roller doğrudan yetki dağıtmak yerine yönetilebilir soyutlama sağlar.","points":["Yetkiyi kullanıcıya değil role ver; rolleri işleve göre tasarla (okuyucu, yazıcı, DDL, operasyon) ve kullanıcıları rollere ata, doğrudan grant'lardan kaçın.","Uygulama hesaplarına yalnızca gereken nesne ve işlem hakkını ver; DDL, SUPERUSER/DBA ve geniş şema hakları üretim uygulama hesabında bulunmamalıdır.","İnsan yönetici erişimini kişiselleştir ve denetle: paylaşılan admin hesabı yerine bireysel kimlik + gerektiğinde yükselen (JIT/break-glass) erişim kullan.","PUBLIC/varsayılan geniş yetkileri kaldır; yeni nesnelerde varsayılan hakların sızmasını önlemek için default privileges ve şema düzeyi kontrolü ayarla.","Ayrıcalıklı hesapları düzenli gözden geçir (access recertification); kullanılmayan, ayrılan çalışana ait veya aşırı yetkili hesapları periyodik temizle.","Görev ayrılığını (separation of duties) uygula; aynı kişi hem üretimi değiştirip hem denetim izini silememelidir, audit yazımını ayrı yetkiyle koru."],"level":"expert"},{"id":"encryption-decision","title":"Şifreleme kararı: at-rest, in-transit, TDE","category":"Güvenlik","summary":"Şifreleme tehdit modeline göre seçilir; her katman farklı bir saldırıya karşı korur ve anahtar yönetimi çoğu zaman şifreleme algoritmasından daha kritiktir.","points":["Tehdidi netleştir: at-rest (disk/yedek çalınması), in-transit (ağ dinlemesi) ve uygulama katmanı (DBA dahil kimseye açılmaması) farklı korumalardır, hangisinin gerektiğine karar ver.","In-transit için istemci-sunucu bağlantılarında TLS'i zorunlu kıl; sertifika doğrulamasını kapatma, ortadaki adam (MITM) saldırısına açık bırakır.","At-rest için TDE veya dosya sistemi/disk şifrelemesi seçenlerini kıyasla; TDE data file ve yedeği korur ama bellek içi ve yetkili DBA erişimini korumaz.","En hassas alanlar için uygulama/kolon düzeyi şifreleme veya Always Encrypted benzeri istemci taraflı yaklaşımla DBA'nın bile düz metni görmesini engelle.","Anahtar yönetimini ciddiye al: anahtarları veriden ayrı bir KMS/HSM'de sakla, rotasyon ve erişim denetimini planla; anahtar sızarsa şifreleme değersizdir.","Performans ve fonksiyon etkisini ölç: şifreli kolonlarda indeksleme/arama kısıtlanır, TDE CPU maliyeti getirir; kararı ölçülü ödünleşimle ver."],"level":"expert"},{"id":"audit-strategy","title":"Denetim (audit) stratejisi","category":"Güvenlik","summary":"Denetim izi güvenlik olaylarını ve uyum gereksinimlerini kanıtlar; ne loglanacağı, izin nereye ve ne kadar tutulacağı gürültü ile kanıt arasındaki dengeyi belirler.","points":["Neyi denetleyeceğini tehdit ve uyumdan türet: ayrıcalıklı işlemler, oturum açma/başarısızlıkları, şema (DDL) değişiklikleri ve hassas veriye erişimi önceliklendir.","Her şeyi loglama tuzağına düşme; aşırı denetim performansı düşürür ve sinyali gürültüde boğar, kritik olayları seçici ve amaçlı hedefle.","Denetim izini üretim DBA'sının değiştiremeyeceği ayrı ve güvenli hedefe yaz (harici log toplayıcı/SIEM); görev ayrılığıyla iz tahrifatını engelle.","Motor yeteneklerini kullan: Oracle Unified/Fine-Grained Audit, MSSQL SQL Audit, PG pgAudit ile ayrıntı düzeyini ihtiyacına göre ayarla.","Saklama süresini uyum gereksinimine (KVKK/GDPR/PCI-DSS vb.) göre belirle ve arşiv/temizleme politikasını otomatikleştir; izlerin bütünlüğünü koru.","İzi yalnızca toplama, düzenli incele ve alarma bağla: denetim ancak anormalliği tetikleyip aksiyona dönüştürdüğünde değer üretir, ölü arşiv değildir."],"level":"expert"}]},"guide/best-practices-4.json":{"topics":[{"id":"oracle-rac-cache-fusion","title":"Oracle RAC: Cache Fusion ve interconnect","category":"Oracle","summary":"RAC'te birden çok instance aynı veritabanını paylaşır; Cache Fusion, blokları disk yerine interconnect üzerinden node'lar arası taşıyarak tutarlılığı sağlar.","points":["Cache Fusion, bir instance'ın ihtiyaç duyduğu bloğun başka bir instance'ın buffer cache'inde olması durumunda bloğu private interconnect üzerinden RAM-to-RAM transfer eder; diske yazıp okuma (disk ping) yapmaz.","Global Cache Service (GCS/LMS process) blok sahipliğini ve modunu (shared/exclusive), Global Enqueue Service (GES) ise lock ve enqueue'ları yönetir.","Her blok için bir master node vardır; blok konumu Global Resource Directory'de tutulur ve DRM (Dynamic Resource Mastering) ile erişim yoğunluğuna göre remaster edilebilir.","Interconnect için düşük gecikmeli özel ağ şart; Jumbo Frame (MTU 9000) ve gerekiyorsa RDMA/RoCE veya InfiniBand kullan, public ağ ile paylaşma.","'gc buffer busy' ve 'gc cr/current block busy' wait event'ler hot block çekişmesine işaret eder; sequence CACHE artırma, ters anahtar (reverse key) index veya partition ile dağıtma çözüm olabilir.","gc blocks lost sayacı sürekli artıyorsa interconnect'te paket kaybı vardır; NIC, switch buffer ve socket buffer boyutlarını (rmem/wmem) incele."],"level":"expert"},{"id":"oracle-rac-node-eviction","title":"Oracle RAC: node eviction ve split-brain","category":"Oracle","summary":"Clusterware, yanıt vermeyen bir node'u split-brain'i önlemek için kümeden atar (eviction); bunu network heartbeat, disk heartbeat ve voting disk çoğunluğu ile karar verir.","points":["CSSD iki ayrı heartbeat izler: interconnect üzerinden network heartbeat (misscount, varsayılan 30 sn) ve voting disk üzerinden disk heartbeat (disktimeout, varsayılan 200 sn).","Split-brain'de sağ kalacak alt küme (cohort) voting disk çoğunluğuna göre belirlenir; bu yüzden voting disk sayısı tek olmalı (3 veya 5) ve ayrı failure group'larda durmalıdır.","Eviction genelde node reboot veya reboot-less fencing (yalnızca stack'in yeniden başlatılması) ile uygulanır; amaç bozulmuş node'un paylaşımlı diske yazmasını engellemektir.","Yaygın eviction nedenleri: interconnect kaybı, aşırı yük altında CSSD'nin CPU alamaması, voting disk I/O gecikmesi ve OCR/voting disk erişim sorunları.","Kök neden analizi için ocssd.log, cssd trace, alert log ve OS mesajları ile CHM/oclumon (Cluster Health Monitor) verisi birlikte incelenmelidir."],"level":"expert"},{"id":"oracle-asm-redundancy-rebalance","title":"Oracle ASM: disk group redundancy ve rebalance","category":"Oracle","summary":"ASM, veriyi disk group içindeki disklere şeritler (stripe) ve failure group bazlı aynalama (mirror) ile korur; disk ekleme/çıkarmada extent'leri otomatik rebalance eder.","points":["Redundancy seviyeleri: EXTERNAL (aynalama yok, koruma storage array'e bırakılır), NORMAL (2 kopya, 1 disk kaybına dayanıklı), HIGH (3 kopya, 2 eşzamanlı kaybına dayanıklı).","ASM diski değil failure group'u aynalar; primary extent bir failure group'ta, mirror kopyaları farklı failure group'larda tutulur, böylece tüm bir failure group çökse veri kaybolmaz.","Disk eklendiğinde/çıkarıldığında rebalance tetiklenir ve extent'leri yeniden dağıtır; ASM_POWER_LIMIT (0-1024) hız ile kaynak kullanımı arasındaki dengeyi belirler.","AU (Allocation Unit) boyutu disk group oluşturulurken belirlenir; büyük veritabanlarında 4 MB AU I/O verimini artırır.","Voting disk ve OCR normal/high redundancy disk group içinde tutulabilir; quorum failure group yalnızca voting disk için kullanılıp veri extent'i barındırmaz."],"level":"expert"},{"id":"oracle-data-guard-modes","title":"Oracle Data Guard: standby türleri ve protection modes","category":"Oracle","summary":"Data Guard, redo'yu bir standby'a taşıyarak felaket kurtarma sağlar; fiziksel/mantıksal standby seçimi ve üç koruma modu, veri kaybı ile kullanılabilirlik arasındaki dengeyi belirler.","points":["Fiziksel standby, primary'nin blok-blok birebir kopyasıdır (redo apply/MRP); Active Data Guard ile açıkken salt-okunur sorgulanabilir. Mantıksal standby ise redo'yu SQL'e çevirip uygular (SQL Apply) ve farklı yapı/index barındırabilir.","Maximum Performance (varsayılan): redo asenkron (ASYNC) gönderilir, primary onaylamayı beklemez; sıfır performans etkisi ama küçük veri kaybı riski.","Maximum Availability: redo senkron (SYNC/AFFIRM) gönderilir; standby ulaşılamazsa primary MAX PERFORMANCE'a düşerek durmaz, standby dönünce yeniden senkronlanır.","Maximum Protection: en az bir standby onaylamadan primary commit etmez; sıfır veri kaybı garanti eder ama tüm standby'lar kaybolursa primary durur.","Fast-Start Failover (FSFO) bir observer süreci ile primary çökünce otomatik failover yapar; FastStartFailoverThreshold ve senkron transport ile RPO=0 hedeflenir.","Standby'da apply gecikmesini v$dataguard_stats ve 'apply lag'/'transport lag' metrikleri ile izle; gerçek zamanlı apply (real-time apply) redo'yu arşive yazılmadan uygular."],"level":"expert"},{"id":"oracle-exadata-offload","title":"Oracle Exadata: smart scan ve storage indexes","category":"Oracle","summary":"Exadata'da storage cell'ler sorgu işlemenin bir kısmını üstlenerek (offload) yalnızca ilgili veriyi DB node'a döndürür; smart scan, storage index ve HCC ile I/O dramatik azalır.","points":["Smart Scan, full scan sorgularında filtreleme (predicate) ve kolon projeksiyonunu storage cell'de yapar; DB node'a blok değil yalnızca gereken satır/sütunlar döner, bu da interconnect trafiğini düşürür.","Smart Scan yalnızca direct path read ile çalışır; buffer cache'ten okunan bloklarda veya belirli işlemlerde devreye girmez; fayda 'cell physical IO bytes eligible for predicate offload' ve 'cell physical IO interconnect bytes returned by smart scan' istatistikleriyle ölçülür ('cell physical IO bytes saved by storage index' yalnız storage index kazancını gösterir).","Storage Index, her 1 MB storage bölgesi için sütun min/max değerlerini bellekte tutar; sorgu predicate'i aralık dışındaysa o bölge hiç okunmadan atlanır (negatif index gibi çalışır).","Storage index kalıcı değildir, bellekte tutulur ve cell yeniden başlayınca yeniden oluşur; verinin fiziksel sıralı olması (clustering) atlama oranını artırır.","HCC (Hybrid Columnar Compression) veriyi Compression Unit içinde kolon-bazlı sıkıştırır; QUERY LOW/HIGH sorgu ağırlıklı, ARCHIVE LOW/HIGH ise nadir erişilen arşiv veri içindir ve yüksek CPU maliyetiyle çok yüksek sıkıştırma sağlar."],"level":"expert"},{"id":"oracle-awr-ash-analysis","title":"Oracle AWR ve ASH ile performans analizi","category":"Oracle","summary":"AWR periyodik olarak performans snapshot'larını toplar, ASH ise aktif oturumları saniyede örnekler; ikisi birlikte 'zaman nereye gitti' sorusunu wait event'ler üzerinden yanıtlar.","points":["AWR varsayılan 60 dakikada bir snapshot alır ve 8 gün saklar; iki snapshot arası AWR raporu, DB Time'ın hangi SQL ve wait event'lerinde harcandığını gösterir (Diagnostics Pack lisansı gerekir).","Analize daima 'Top 10 Foreground Events by Total Wait Time' ve DB Time'dan başla; CPU vs I/O vs concurrency dengesini burada gör, tek tek istatistiklerde kaybolma.","ASH, v$active_session_history'yi saniyede bir örnekleyerek kısa süreli, ani sorunları (spike) yakalar; AWR'nin kaçırdığı anlık lock/latch fırtınalarını SQL_ID ve blocking session bazında ortaya çıkarır.","Average Active Sessions (AAS = DB Time / elapsed time) sistem yükünün tek sayılık özetidir; AAS'in CPU çekirdek sayısını aşması doygunluğa işaret eder.","SQL ayarlaması için AWR'deki 'SQL ordered by Elapsed Time/Gets' bölümünden en pahalı SQL_ID'yi al, ASH ile o SQL'in hangi adımda beklediğini doğrula, ardından SQL Monitor raporu ile plan satır bazında incele."],"level":"expert"},{"id":"oracle-scn-read-consistency","title":"Oracle SCN ve read consistency","category":"Oracle","summary":"System Change Number (SCN) veritabanının mantıksal saatidir; Oracle, sorgunun başladığı andaki SCN'e göre undo'dan tutarlı bir görüntü (read consistency) üreterek okuyucuları yazarlardan izole eder.","points":["SCN her commit'te monoton artar ve redo/undo, control file ve blok başlıklarında tutulur; bir bloğun son değişiklik SCN'i, sorgu SCN'inden büyükse blok 'geri sarılır'.","Read consistency için Oracle, güncel bloğun bir CR (Consistent Read) kopyasını undo'daki bilgiyle sorgu başlangıç SCN'ine geri götürerek üretir; böylece 'okuyucu yazarı, yazar okuyucuyu bloklamaz'.","Undo yetersizse veya undo_retention aşılırsa uzun süren sorgu 'ORA-01555 snapshot too old' alır; çözüm undo tablespace büyütmek, retention ayarlamak veya sorguyu kısaltmaktır.","Statement-level consistency her SQL için ayrı SCN kullanır; SERIALIZABLE veya read-only transaction ise transaction başındaki tek SCN'i tüm ifadeler boyunca korur.","RAC'te SCN tüm instance'lar arası senkron tutulur (Lamport veya broadcast-on-commit); global tutarlılık için SCN ilerlemesi node'lar arası koordine edilir."],"level":"expert"},{"id":"postgres-patroni-failover","title":"PostgreSQL: Patroni ile otomatik failover","category":"PostgreSQL","summary":"Patroni, PostgreSQL kümesinin durumunu bir dağıtık konsensüs deposunda (DCS) tutarak lider seçimi ve otomatik failover sağlar; watchdog ile split-brain'i önler.","points":["Küme durumu ve lider lock'u etcd/Consul/ZooKeeper gibi bir DCS'te tutulur; lider, TTL süreli bir lock'u periyodik yeniler, yenileyemezse lock düşer ve yeni lider seçimi başlar.","Failover'da Patroni en güncel (en büyük LSN'e sahip) replica'yı seçer; yeni lider promote edilir ve diğer replica'lar ona yeniden bağlanır (reinitialize/rewind).","Watchdog (softdog), eski lider DCS ile iletişimi kaybettiğinde makineyi resetleyerek iki node'un aynı anda lider olmasını (split-brain) engelleyen donanımsal güvenlik ağıdır.","maximum_lag_on_failover, çok geride kalmış bir replica'nın lider olup veri kaybına yol açmasını engeller; synchronous_mode ile RPO=0 hedeflenebilir ama yazma gecikmesi artar.","İstemciler doğrudan node'a değil, Patroni'nin REST health-check'ini kullanan HAProxy veya bir VIP üzerinden bağlanmalı; böylece lider değişince trafik otomatik yeni lidere yönlenir.","DCS çoğunluğu (quorum) şarttır; 3 veya 5 üyeli etcd kümesi kullan, DCS erişilemezse Patroni güvenli tarafta kalıp mevcut lideri read-only'ye düşürebilir."],"level":"expert"},{"id":"postgres-logical-replication-upgrade","title":"PostgreSQL: logical replication ile sıfır-kesinti major upgrade","category":"PostgreSQL","summary":"Logical replication, sürümler arası satır değişikliklerini taşıyabildiği için major sürüm yükseltmesini neredeyse kesintisiz yapmayı sağlar; eski ve yeni sürüm bir süre paralel çalışır.","points":["Logical replication değişiklikleri WAL'dan mantıksal olarak (INSERT/UPDATE/DELETE) çözer; fiziksel replikasyonun aksine farklı major sürümler ve farklı platformlar arasında çalışır.","Akış: yeni sürümde boş şema oluştur, eski sürümde PUBLICATION, yeni sürümde SUBSCRIPTION tanımla; başlangıçta tablo kopyalanır (initial sync), ardından canlı değişiklikler akmaya başlar.","Her tablonun bir REPLICA IDENTITY'si olmalı; primary key'i olmayan tablolar için UPDATE/DELETE replikasyonu REPLICA IDENTITY FULL gerektirir, aksi halde hata verir.","DDL değişiklikleri otomatik replike edilmez ve sequence son değerleri taşınmaz; geçişte yeni sürümde sequence'leri manuel ileri al, aksi halde çakışan anahtarlar oluşur.","Geçiş anında uygulamayı kısa süre eski sürüme yazmayı durdur, lag sıfırlanınca (pg_stat_replication ile doğrula) uygulamayı yeni sürüme yönlendir; gerekirse ters yönde subscription ile hızlı geri dönüş (rollback) hazır tut.","Kısıtlar: large object'ler ve bazı DDL'ler replike olmaz; wal_level=logical ve yeterli max_replication_slots/max_wal_senders ayarlanmalıdır."],"level":"expert"},{"id":"postgres-pgvector-similarity","title":"PostgreSQL: pgvector ile benzerlik araması","category":"PostgreSQL","summary":"pgvector, vektör gömme (embedding) saklayıp yaklaşık en yakın komşu (ANN) araması yapar; HNSW ve IVFFlat index'leri doğruluk-hız-bellek dengesini belirler.","points":["Mesafe operatörünü kullanım amacına göre seç: <-> L2 (öklid), <=> kosinüs, <#> iç çarpım; index, sorguda kullanılan operatör sınıfı ile aynı olmalı yoksa devreye girmez.","HNSW çok katmanlı bir graf kurar; yüksek recall ve hızlı sorgu verir ama daha fazla bellek ve yavaş build gerektirir. m (bağlantı sayısı) ve ef_construction build kalitesini, ef_search sorgu anındaki doğruluğu ayarlar.","IVFFlat, vektörleri lists sayıda kümeye böler ve sorguda yalnızca probes kadar kümeyi tarar; daha az bellek kullanır ama index veri yüklendikten SONRA oluşturulmalı (boş tabloda kümeler anlamsız olur).","IVFFlat için lists başlangıçta 1M satıra kadar ≈ satır/1000, 1M üstünde ≈ √satır seçilir; probes artırmak recall'ı yükseltir ama sorguyu yavaşlatır, bu ödünleşim ölçülerek ayarlanmalıdır.","ANN yaklaşık sonuç döndürür; %100 kesinlik gerekiyorsa index'siz tam tarama gerekir. Filtreli (WHERE) aramada index recall'ı düşebilir, gerekirse iterative scan veya partial index düşün.","Vektör boyutu ve satır sayısı bellek gereksinimini belirler; maintenance_work_mem'i build sırasında yeterli tut, aksi halde HNSW build'i diske taşarak çok yavaşlar."],"level":"expert"},{"id":"postgres-citus-distributed","title":"PostgreSQL: Citus ile dağıtık ölçekleme","category":"PostgreSQL","summary":"Citus, tabloları bir dağıtım kolonuna göre shard'lara bölüp worker node'lara dağıtarak PostgreSQL'i yatay ölçekler; dağıtım kolonu seçimi performansın belirleyicisidir.","points":["Coordinator node sorguyu alır, dağıtım kolonuna göre ilgili shard'lara yönlendirir; worker node'lar shard'ları saklar ve paralel işler. Shard'lar standart PostgreSQL tablolarıdır (hash aralığına göre bölünmüş).","Dağıtım kolonu, çoğu sorgunun ve JOIN'in ortak filtresi olmalı (örn. tenant_id); aynı kolon değerine sahip satırlar aynı shard'a düşer, böylece JOIN ve foreign key aynı node içinde (colocation) yerel kalır.","Colocation kritik: birlikte JOIN edilen tablolar aynı dağıtım kolonu ve shard sayısıyla dağıtılırsa cross-node veri karıştırma (repartition) olmadan çalışır.","Sık tekrarlanan ve tüm shard'larla JOIN edilen küçük tabloları reference table yap; her worker'a tam kopyalanır ve dağıtık JOIN'lerde ağ maliyetini ortadan kaldırır.","Dağıtım kolonunu içermeyen sorgular tüm shard'lara yayılır (fan-out) ve pahalıdır; multi-tenant SaaS'te tenant_id ile filtreleme sorguyu tek shard'a indirir (router execution)."],"level":"expert"},{"id":"postgres-timescaledb-hypertable","title":"PostgreSQL: TimescaleDB hypertable ve continuous aggregate","category":"PostgreSQL","summary":"TimescaleDB, zaman serisi verisini otomatik zaman aralıklı parçalara (chunk) bölen hypertable'lar ve önceden hesaplanmış continuous aggregate'ler ile ölçekler.","points":["Hypertable dışarıdan tek tablo görünür ama arka planda zaman (ve isteğe bağlı space) kolonuna göre chunk'lara bölünür; sorgular yalnızca ilgili zaman aralığındaki chunk'lara dokunur (chunk exclusion).","chunk_time_interval, en sık aktif chunk'ların bellekte (shared_buffers) sığacağı şekilde ayarlanmalı; çok küçükse aşırı chunk/planlama maliyeti, çok büyükse zayıf exclusion oluşur.","Continuous aggregate, materialized view'ın artımlı güncellenen halidir; yalnızca değişen zaman dilimlerini yeniden hesaplayan bir refresh politikası (policy) ile arka planda güncel tutulur.","Real-time aggregation ile continuous aggregate, materialize edilmiş eski veriyi ham tablodaki en güncel veriyle birleştirerek sorgu anında güncel sonuç verir.","Eski chunk'lar kolon-bazlı sıkıştırma (compression) ile büyük oranda küçültülebilir; retention policy ise belirlenen yaştan eski chunk'ları drop_chunks ile otomatik siler (satır-satır DELETE'ten çok daha ucuz)."],"level":"expert"},{"id":"postgres-vacuum-xid-wraparound","title":"PostgreSQL: VACUUM ve XID wraparound","category":"PostgreSQL","summary":"MVCC dead tuple'lar bırakır; VACUUM bunları temizler ve satırları 'frozen' işaretleyerek 32-bit transaction ID (XID) wraparound'undan kaynaklı veri kaybını önler.","points":["PostgreSQL 32-bit XID kullanır ve bu daireseldir; her satır sürümü xmin ile damgalanır. Yeterince eski satırlar freeze edilmezse, XID wraparound'unda 'geçmiş' işlemler 'gelecek' gibi görünüp satırlar aniden görünmez olabilir.","autovacuum iki iş yapar: normal temizlik (dead tuple, bloat) ve freeze; autovacuum_freeze_max_age'e yaklaşan tablolarda, autovacuum kapalı olsa bile zorunlu 'anti-wraparound' vacuum tetiklenir.","wraparound'a yaklaşınca uyarı loglanır; sınıra çok yaklaşılırsa veritabanı veri kaybını önlemek için yeni yazmaları reddedip yalnız-okumaya geçer, çözüm agresif VACUUM (FREEZE) çalıştırmaktır.","En eski freeze edilmemiş XID'i pg_database.datfrozenxid ve age() ile izle; sürekli açık uzun transaction'lar (idle in transaction) ve kullanılmayan replication slot'lar VACUUM'un ilerlemesini engelleyerek bloat ve wraparound riskini büyütür.","Yüksek yazma yükünde autovacuum'un yetişememesi bloat'a yol açar; autovacuum_vacuum_cost_limit'i yükselt, naptime'ı düşür ve büyük ve yoğun güncellenen tablolara tablo-özel autovacuum ayarları uygula.","VACUUM alanı işletim sistemine genelde geri vermez, yeniden kullanım için işaretler; fiziksel küçülme için VACUUM FULL (tabloyu kilitler) veya pg_repack (online) gerekir."],"level":"expert"},{"id":"mysql-innodb-cluster","title":"MySQL: Group Replication ve InnoDB Cluster","category":"MySQL","summary":"InnoDB Cluster, Group Replication tabanlı bir çoğunluk (quorum) kümesi olup MySQL Router ile uygulamaya tek bağlantı noktası sunarak yüksek erişilebilirlik sağlar.","points":["Group Replication, Paxos tabanlı bir grup iletişim katmanıyla işlemleri gruba yayar; bir transaction ancak grubun çoğunluğu (quorum) onayladıktan sonra commit edilir, bu da otomatik failover ve tutarlılık sağlar.","Tek-primary mod (varsayılan) yalnızca bir node'a yazmaya izin verir, primary çökünce grup otomatik yeni primary seçer; multi-primary modda tüm node'lara yazılabilir ama çakışma (certification) yönetimi karmaşıklaşır.","MySQL Router, cluster meta verisini okuyup uygulamaya iki port sunar: yazmalar mevcut primary'e (6446), okumalar replica'lara (6447) yönlendirilir; failover'da uygulama bağlantısını değiştirmeden yönlendirme güncellenir.","Çoğunluk kaybı (örn. 3 node'dan 2'sinin gitmesi) grubu bloke eder; split-brain'i önlemek için küme yeni yazma kabul etmez, kurtarma group_replication_force_members ile manuel yapılır.","Group Replication satır-bazlı binlog (ROW format), GTID ve InnoDB gerektirir; her tabloda primary key zorunludur, aksi halde node kümeye katılamaz.","Yeni katılan node önce mevcut bir donör'den durum aktarımı (distributed recovery: klon eklentisi veya binlog) ile senkronlanır, ardından canlı akışa geçer."],"level":"expert"},{"id":"mysql-semisync-replication","title":"MySQL: semi-sync replikasyon","category":"MySQL","summary":"Semi-synchronous replikasyon, primary'nin commit'i onaylamadan önce en az bir replica'nın transaction'ı relay log'a aldığını beklemesini sağlayarak veri kaybını azaltır.","points":["Asenkron replikasyonda primary commit'i replica'yı beklemeden onaylar; primary çökerse henüz gönderilmemiş transaction'lar kaybolur. Semi-sync, en az N replica'nın (rpl_semi_sync_source_wait_for_replica_count) alındı onayını bekler.","AFTER_SYNC (varsayılan, önerilen): primary önce replica onayını alır, sonra istemciye commit'i döndürür; böylece istemci 'başarılı' gördüğü her transaction'ın en az bir replica'da olduğunu garanti eder.","AFTER_COMMIT modunda primary önce yerel commit eder sonra replica'yı bekler; bu, replica gecikirse diğer oturumların henüz replike olmamış veriyi görmesine (phantom read benzeri) yol açabilir.","rpl_semi_sync_source_timeout aşılırsa primary otomatik olarak asenkrona düşer (fallback) ve durmaz; replica geri gelince tekrar semi-sync'e döner, bu yüzden 'garanti' koşulludur.","Semi-sync 'komut alındı' garantisi verir, 'replica'da uygulandı' garantisi değil; sıkı RPO=0 için Group Replication veya harici bir consensus katmanı daha uygundur."],"level":"expert"},{"id":"mysql-undo-purge","title":"MySQL InnoDB: undo tablespace ve purge","category":"MySQL","summary":"InnoDB, MVCC için eski satır sürümlerini undo log'da tutar; purge thread'leri artık hiçbir okuyucunun ihtiyaç duymadığı undo kayıtlarını ve ölü sürümleri temizler.","points":["Her değişiklik, geri alma ve tutarlı okuma için undo log kaydı üretir; uzun süren bir transaction, eski read view'ları hayatta tuttuğu için purge'ün ilerlemesini engeller ve undo'nun şişmesine (history list length artışı) yol açar.","History list length (SHOW ENGINE INNODB STATUS) sürekli büyüyorsa purge yetişemiyordur; başlıca neden uzun açık transaction'lar veya aktif tutulan eski okumalar (örn. mysqldump --single-transaction) olabilir.","innodb_purge_threads ile purge paralelliği, innodb_max_purge_lag ile de purge çok geride kaldığında DML'e yapay gecikme eklenerek yükün purge'ü boğması engellenir.","MySQL 8'de undo, ayrı undo tablespace'lerde tutulur ve otomatik truncate ile büyüyen undo dosyaları küçültülebilir (innodb_undo_log_truncate); eski sürümlerde undo system tablespace içinde kalıp geri küçülmezdi.","Şişmiş undo, tutarlı okumaların daha çok sürüm zincirini gezmesine (I/O ve CPU) neden olur; kısa transaction'lar ve autocommit disiplini undo baskısını en aza indirir."],"level":"expert"},{"id":"mysql-buffer-pool-lru","title":"MySQL InnoDB: buffer pool instances ve LRU","category":"MySQL","summary":"InnoDB buffer pool veri ve index sayfalarını bellekte tutar; midpoint-insertion LRU algoritması tablo taramalarının sıcak veriyi bellekten atmasını engeller.","points":["Buffer pool adanmış bir veritabanı sunucusunda tipik olarak RAM'in ~%70-80'ine ayarlanır (innodb_buffer_pool_size; paylaşımlı sunucuda daha düşük); amaç sık erişilen çalışma kümesini bellekte tutup disk I/O'sunu en aza indirmektir.","LRU listesi 'young' (sıcak) ve 'old' (soğuk) alt listelere bölünür; yeni okunan sayfa listenin tepesine değil old bölgesinin başına (midpoint, ~%37) eklenir, böylece tek seferlik tarama hot page'leri atmaz.","Bir sayfa old bölgede iken innodb_old_blocks_time süresi geçtikten sonra tekrar erişilirse young'a terfi eder; bu, büyük full scan'lerin buffer pool'u kirletmesini (pollution) önler.","innodb_buffer_pool_instances ile pool birden çok bağımsız instance'a bölünür; her instance kendi mutex'ine sahip olduğundan yüksek eşzamanlılıkta buffer pool mutex çekişmesi azalır (büyük pool'larda anlamlı).","Buffer Pool hit oranını ve free/dirty sayfa dengesini izle; çok sayıda dirty sayfa ve agresif flush 'checkpoint fırtınasına' yol açabilir, innodb_io_capacity ile flush hızı depolamaya göre ayarlanır."],"level":"expert"},{"id":"sqlserver-always-on-ag","title":"SQL Server: Always On Availability Groups","category":"SQL Server","summary":"Availability Group, bir veritabanı grubunu senkron/asenkron replica'lara kopyalar; WSFC üzerinde otomatik failover, okunabilir replica ve read-only routing sağlar.","points":["Senkron-commit replica'da primary, transaction'ı commit etmeden önce secondary'nin log kaydını sertleştirdiğini (hardened) bekler; bu RPO=0 sağlar ama replica gecikirse primary'nin commit gecikmesini artırır.","Asenkron-commit replica primary'yi beklemez; uzak felaket kurtarma (DR) siteleri için uygundur ama failover'da bir miktar veri kaybı (RPO>0) olabilir ve yalnızca zorlamalı manuel failover (FORCE_FAILOVER_ALLOW_DATA_LOSS) desteklenir.","Otomatik failover yalnızca senkron-commit ve 'automatic failover' modundaki replica çifti arasında, WSFC quorum'u sağlamken gerçekleşir; sağlık kontrolü sp_server_diagnostics ve database health detection ile yapılır.","Okunabilir secondary replica raporlama yükünü primary'den alır; read-only routing sayesinde ApplicationIntent=ReadOnly ile bağlanan istemciler listener üzerinden otomatik okunabilir replica'ya yönlendirilir.","Okunabilir replica'da sorgular otomatik snapshot isolation kullanır; bunun için primary'de değişen satırlara 14 baytlık sürüm bilgisi eklenir ve secondary'de tempdb version store yüklenir; ayrıca uygulanan redo gecikirse replica'da veri güncelliği (staleness) oluşabilir.","AG listener sanal ağ adı+IP ile istemcilere tek bağlantı noktası sunar; failover'da listener yeni primary'ye taşınır, uygulama bağlantı dizesini değiştirmeden çalışır."],"level":"expert"},{"id":"sqlserver-columnstore","title":"SQL Server: columnstore index ve batch mode","category":"SQL Server","summary":"Columnstore index veriyi kolon-bazlı ve yüksek sıkıştırmalı saklar; batch mode işleme ve segment elimination ile analitik sorgularda büyük hızlanma sağlar.","points":["Veri, satır grupları (rowgroup, ~1 milyon satır) halinde kolon segmentlerine bölünür ve her segment sıkıştırılır; yalnızca sorgunun ihtiyaç duyduğu kolonlar okunur, bu da I/O'yu ciddi azaltır.","Her segment min/max meta verisi tutar; sorgu predicate'i segmentin değer aralığı dışındaysa o segment hiç okunmadan atlanır (segment elimination), bu yüzden verinin sıralı yüklenmesi çok önemlidir.","Batch mode, satır-satır yerine ~900 satırlık gruplar halinde işleyerek CPU başına iş miktarını artırır; aggregate ve join'lerde satır moduna göre kat kat hızlıdır (SQL 2019+ ile rowstore'da da batch mode mümkün).","Clustered columnstore büyük analitik/DW fact tabloları için idealdir; OLTP + analitik karma yükte, satır tablosu üzerine nonclustered columnstore ile gerçek zamanlı operasyonel analitik (HTAP) kurulabilir.","Sıcak (henüz sıkıştırılmamış) satırlar deltastore'da satır-bazlı tutulur, dolunca tuple mover ile sıkıştırılır; çok sayıda küçük yükleme parçalanmaya (fragmentation) yol açar, toplu (bulk) yükleme tercih edilmelidir."],"level":"expert"},{"id":"sqlserver-inmemory-oltp","title":"SQL Server: In-Memory OLTP (Hekaton)","category":"SQL Server","summary":"In-Memory OLTP, memory-optimized tabloları kilitsiz (lock/latch-free) yapılarla ve natively compiled prosedürlerle işleyerek yüksek eşzamanlılıklı OLTP yüklerinde darboğazları kaldırır.","points":["Memory-optimized tablolar tamamen bellekte tutulur ve tüm satır sürümleri bellekte yaşar; eşzamanlılık kilitsiz optimistic MVCC ile yönetilir, böylece klasik latch ve lock çekişmesi ortadan kalkar.","Dayanıklılık (durability) için değişiklikler yine log'a yazılır ve checkpoint dosyalarına (data/delta) aktarılır; SCHEMA_ONLY tablolar log'lanmaz ve yeniden başlatmada boşalır (ör. geçici staging/oturum verisi için idealdir).","Natively compiled stored procedure, T-SQL'i makine koduna (DLL) derleyerek yorumlama maliyetini kaldırır; yalnızca memory-optimized tablolara erişebilir ve desteklediği T-SQL alt kümesi sınırlıdır.","Çakışmalar optimistic olduğundan çalışma anında tespit edilir; yazma-yazma çakışması transaction'ı hata ile geri alır (retry gerektirir), bu yüzden uygulama retry mantığı içermelidir.","En uygun senaryolar: çok yüksek insert hızı (ör. IoT/telemetri ingest), lock/latch darboğazı yaşayan hot tablolar ve tempdb kullanan geçici tablolar; tüm veri belleğe sığmalı ve bellek baskısı dikkatle izlenmelidir."],"level":"expert"},{"id":"sqlserver-query-store","title":"SQL Server: Query Store ile plan yönetimi","category":"SQL Server","summary":"Query Store sorgu metinlerini, çalıştırma planlarını ve çalışma zamanı istatistiklerini kalıcı saklar; plan regresyonlarını tespit edip belirli bir planı zorlamayı (force) sağlar.","points":["Query Store, sorgu bazında zamanla oluşan tüm planları ve her plan için süre/CPU/okuma metriklerini veritabanı içinde saklar; 'sorgu neden dün hızlıyken bugün yavaş' sorusunu tarihsel veriyle yanıtlar.","Plan regresyonu (yeni derlenen planın eskiden daha kötü olması) 'Regressed Queries' ve 'Top Resource Consumers' raporlarıyla bulunur; iyi bilinen planı sys.sp_query_store_force_plan ile zorlayarak istikrar sağlanır.","SQL Server 2022'deki Query Store hints ile plan zorlamadan, sorgu metnini değiştirmeden hint (ör. RECOMPILE, MAXDOP) uygulanabilir; bu, üçüncü parti uygulama sorgularını ayarlamak için güçlüdür.","Otomatik plan düzeltme (automatic tuning, FORCE_LAST_GOOD_PLAN) regresyon tespit edip önceki iyi planı otomatik zorlar ve düzelme olmazsa geri alır; production'da denetimli açılmalıdır.","Capture modu (ALL/AUTO/CUSTOM) ve saklama boyutu doğru ayarlanmalı; AUTO nadir/önemsiz sorguları eleyerek overhead ve alanı düşürür, dolan Query Store salt-okunur moda geçip veri toplamayı durdurur."],"level":"expert"},{"id":"mongodb-sharding-deep","title":"MongoDB: sharding, chunk ve balancer","category":"MongoDB","summary":"MongoDB, veriyi shard key'e göre chunk'lara bölüp shard'lara dağıtır; balancer chunk'ları dengeler, shard key seçimi dağılım ve sorgu yönlendirmesini belirler.","points":["Veri, shard key aralıklarına göre chunk'lara bölünür ve chunk'lar shard'lar arasında dağıtılır; mongos router, sorguyu shard key'e bakarak yalnızca ilgili shard'a yönlendirir (targeted), aksi halde tüm shard'lara yayar (scatter-gather).","İyi bir shard key yüksek kardinaliteli, düşük frekanslı ve monoton artmayan olmalı; monoton artan anahtar (ör. timestamp/ObjectId) tüm yeni yazmaları tek shard'a yığar (hotspot), hashed sharding bunu dağıtır.","Balancer, shard'lar arası chunk sayısı dengesizleştiğinde chunk'ları arka planda taşır; taşıma sırasında kaynak ve hedef tutarlılığı korunur ama I/O maliyeti oluşur, bakım penceresine planlanabilir.","Jumbo chunk, shard key'i düşük kardinaliteli olduğu için bölünemeyen ve max chunk boyutunu aşan chunk'tır; taşınamaz ve dengesizlik yaratır, çözüm daha seçici (bileşik) bir shard key'dir.","Zone sharding (tag-aware) ile belirli shard key aralıkları belirli shard'lara sabitlenir; veri yerleşimini coğrafi/donanımsal olarak yönlendirmek (ör. AB verisi AB bölgesindeki shard'da) için kullanılır.","Modern sürümler chunk yerine boyut-tabanlı dengeleme ve otomatik defragmentasyon getirse de ilke aynıdır: hedefli sorgu için shard key her okuma/yazmada mevcut olmalıdır."],"level":"expert"},{"id":"mongodb-oplog-election","title":"MongoDB: replica set oplog ve election","category":"MongoDB","summary":"Replica set, primary'nin yazma işlemlerini oplog'a kaydeder ve secondary'ler bunu uygular; primary çökünce Raft-benzeri bir seçimle yeni primary belirlenir.","points":["Oplog, primary'deki her değişikliği idempotent (tekrar uygulanabilir) biçimde tutan capped bir koleksiyondur; secondary'ler oplog'u kuyruklayıp uygulayarak senkron kalır.","Oplog boyutu replikasyon penceresini belirler; bir secondary oplog'un tuttuğu süreden daha uzun offline kalırsa 'stale' olur ve yeniden tam senkron (initial sync) gerekir, bu yüzden oplog yükü karşılayacak boyutta olmalıdır.","Primary çökünce secondary'ler Raft-benzeri protokolle oy verir; çoğunluk (majority) oyu alan aday primary olur, bu yüzden çoğunluğu koruyabilmek için tek sayıda oy hakkı (gerekiyorsa arbiter) tutulur.","writeConcern 'majority', bir yazının çoğunluk düğüme ulaştığını garanti ederek failover'da geri alınmama (rollback korumasi) sağlar; w:1 daha hızlıdır ama primary çökerse o yazı kaybolabilir.","readConcern ve read preference ile okuma güncelliği ayarlanır; secondary'den okuma yükü dağıtır ama replikasyon gecikmesi nedeniyle bayat (stale) veri dönebilir, 'majority'/'linearizable' daha güçlü garanti verir.","Eski primary ağ bölünmesinden sonra azınlıkta kalırsa kendini secondary'ye düşürür; commit edilmemiş yazıları yeni primary'e katılırken rollback dosyasına alır (majority write concern bunu önler)."],"level":"expert"},{"id":"mongodb-wiredtiger-checkpoint","title":"MongoDB: WiredTiger checkpoint ve journal","category":"MongoDB","summary":"WiredTiger, dayanıklılığı periyodik checkpoint'ler ve write-ahead journal ile sağlar; belge-seviyesi eşzamanlılık ve sıkıştırma ile yüksek verim sunar.","points":["WiredTiger varsayılan ~60 saniyede bir checkpoint alarak belleğdeki tutarlı bir snapshot'ı diske yazar; checkpoint'ler arasında dayanıklılık, her yazının journal'a (WAL) kaydedilmesiyle korunur.","Journal olmadan bir çökme, son checkpoint'ten sonraki yazıları kaybettirir; journal ile kurtarmada son checkpoint yüklenir ve journal'daki sonraki işlemler yeniden oynatılır (replay).","Belge-seviyesi eşzamanlılık kontrolü (document-level concurrency) ile aynı koleksiyondaki farklı belgeler eşzamanlı güncellenebilir; MVCC snapshot'ları tutarlı okuma sağlar.","WiredTiger cache (varsayılan RAM'in ~%50'si) sık erişilen veri ve index'leri tutar; çalışma kümesi cache'e sığmazsa eviction ve disk I/O artar, cache doygunluğu performansı ciddi düşürür.","Depolama sıkıştırması varsayılan snappy'dir (hız/oran dengesi); zstd/zlib daha yüksek oran ama daha çok CPU ister. Index'ler ayrıca prefix compression ile küçültülür."],"level":"expert"},{"id":"redis-cluster-hashslot","title":"Redis Cluster: hash slot ve resharding","category":"Redis","summary":"Redis Cluster, keyspace'i 16384 hash slot'a bölüp node'lara dağıtarak yatay ölçekler; istemciler MOVED/ASK yönlendirmeleriyle doğru node'u bulur.","points":["Her anahtar CRC16(key) mod 16384 ile bir slot'a eşlenir; her master belirli slot aralıklarından sorumludur, böylece küme merkezi bir router olmadan veriyi dağıtır.","İstemci yanlış node'a giderse node MOVED yanıtı ile slot'un kalıcı sahibini bildirir; istemci slot haritasını günceller. Resharding sürerken taşınmakta olan slot için geçici ASK yönlendirmesi kullanılır.","Resharding, slot'ları (ve içindeki anahtarları) canlı olarak bir node'dan diğerine taşır; taşıma anahtar-anahtar yapılır ve süreç boyunca küme hizmet vermeye devam eder.","Çok anahtarlı işlemler (MSET, transaction, Lua) yalnızca aynı slot'taki anahtarlarda çalışır; ilgili anahtarları aynı slot'a toplamak için hash tag ({...}) kullanılır, örn. user:{123}:name ve user:{123}:email.","Yüksek erişilebilirlik için her master'a en az bir replica verilir; master çökünce replica promote edilir. Küme, master'ların çoğunluğu ile karar verir, çoğunluk kaybında yazmalar durur.","Slot ataması olmayan (unassigned) veya master'ı olmayan slot varsa küme (cluster-require-full-coverage açıkken) tüm yazmaları reddeder; tüm 16384 slot atanmış olmalıdır."],"level":"expert"},{"id":"redis-replication-psync","title":"Redis: replikasyon ve PSYNC","category":"Redis","summary":"Redis asenkron replikasyonda master, veri snapshot'ını replica'ya aktarır ve sonraki komutları akıtır; PSYNC ile kısa kopmalarda kısmi yeniden senkron yapılır.","points":["İlk senkronizasyonda master bir RDB snapshot'ı üretip replica'ya gönderir (full resync); bu sırada gelen yazmaları bir replication backlog buffer'da biriktirir ve RDB sonrası akıtır.","PSYNC, replica'nın replication offset'ini ve master replication ID'sini takip eder; kısa bir kopmadan sonra kaçırılan veri hâlâ backlog buffer'da ise yalnızca eksik kısım gönderilir (partial resync), pahalı full resync'ten kaçınılır.","repl-backlog-size, tolere edilebilecek kesinti süresini belirler; yüksek yazma hızında küçük backlog kopmalarda full resync'e zorlar, bu da master'da RDB üretimi ve ağ maliyeti demektir.","Replikasyon asenkrondur: master yazıyı replica beklemeden onaylar, dolayısıyla master ani çökerse son yazmalar kaybolabilir; WAIT komutu belirli sayıda replica'nın aldığını beklemek için kullanılabilir ama gerçek senkron garanti değildir.","Diskless replikasyon (repl-diskless-sync) ile master RDB'yi diske yazmadan doğrudan sokete akıtabilir; yavaş diskli ama hızlı ağlı ortamlarda ilk senkronu hızlandırır."],"level":"expert"},{"id":"redis-memory-fragmentation","title":"Redis: bellek fragmentasyonu ve jemalloc","category":"Redis","summary":"Redis varsayılan olarak jemalloc kullanır; değişken boyutlu ayırma ve serbest bırakma zamanla bellek fragmentasyonuna yol açar, bu da RSS'in kullanılan veriden büyük görünmesine neden olur.","points":["mem_fragmentation_ratio = used_memory_rss / used_memory; 1'e yakın idealdir, belirgin şekilde 1'in üstü (ör. >1.5) fragmentasyona, 1'in altı ise verinin diske swap edildiğine (kötü) işaret eder.","Fragmentasyon, farklı boyutlarda anahtarların sürekli oluşturulup silinmesiyle jemalloc arenalarında kullanılamayan boşluklar kalmasından doğar; büyük değerlerin sık değişimi bunu artırır.","Aktif defragmentasyon (activedefrag yes) jemalloc yardımıyla, çalışırken bellek bloklarını sıkıştırıp fragmentasyonu düşürür; eşikleri (active-defrag-ignore-bytes, -threshold-lower/upper) yükü sınırlayacak şekilde ayarlanır.","maxmemory ve maxmemory-policy doğru ayarlanmalı; jemalloc'un ayırdığı gerçek RSS maxmemory'yi aşabileceğinden, işletim sistemi OOM'unu önlemek için maxmemory RAM'in altında bırakılmalıdır.","used_memory düşük ama RSS yüksek kalıyorsa, kalıcı düzelme için genelde bir restart (veya failover ile yeniden başlatılan node) fragmentasyonu sıfırlar; aktif defrag çoğu durumda restart ihtiyacını azaltır."],"level":"expert"},{"id":"elasticsearch-shard-sizing","title":"Elasticsearch: shard boyutlandırma ve sizing","category":"Elasticsearch","summary":"Her shard bir Lucene index'idir ve sabit kaynak maliyeti taşır; çok fazla küçük shard (oversharding) veya aşırı büyük shard performansı ve kararlılığı bozar.","points":["Genel pratik: bir shard'ı 10-50 GB aralığında tut; çok büyük shard kurtarma ve rebalance'ı yavaşlatır, çok küçük shard'lar (oversharding) cluster state ve heap üzerinde gereksiz yük yaratır.","Her shard ve özellikle her eşlenen alan (mapped field) heap tüketir. Eski \"GB heap başına ~20 shard\" kuralı 8.3'ten itibaren geçerli değil (shard başına heap ek yükü büyük ölçüde azaldı); güncel kılavuz, data node'larda her index'teki her eşlenen alan için ~1 KB heap ve ek pay ayırmak, düğüm başına shard sayısını da cluster.max_shards_per_node (varsayılan 1000) sınırının altında tutmaktır. Aşırı shard hâlâ cluster state'i büyütür ve koordinasyon yükünü artırır.","Sorgu gecikmesi shard sayısıyla ilişkilidir: sorgu tüm ilgili shard'lara dağılır ve sonuçlar birleştirilir; gereğinden çok shard, koordinasyon maliyetiyle küçük sorguları bile yavaşlatır.","Zaman serisi/log verisinde tek dev index yerine zaman-bazlı index'ler (data stream) kullan; böylece eski veriyi index bazında taşımak/silmek (ILM) ucuzlar ve shard'lar yönetilebilir kalır.","Primary shard sayısı index oluşturulurken sabittir ve sonradan değiştirilemez (yalnızca reindex/split/shrink ile); bu yüzden büyüme tahminine göre baştan doğru planlanmalı, replica sayısı ise dinamik ayarlanabilir."],"level":"expert"},{"id":"elasticsearch-ilm-tiers","title":"Elasticsearch: ILM ve hot-warm-cold-frozen katmanları","category":"Elasticsearch","summary":"Index Lifecycle Management, index'leri yaşam evrelerine göre farklı maliyet/performans katmanları arasında otomatik taşıyarak zaman serisi veriyi ekonomik yönetir.","points":["ILM politikası index'i evreler arası geçirir: hot (aktif yazma+sık sorgu, hızlı SSD), warm (yazma bitti, ara sıra sorgu), cold (nadir sorgu, daha ucuz donanım), frozen (çok nadir, searchable snapshot ile nesne depolamadan).","Rollover, hot index belirli boyut/yaş/doküman sayısına ulaşınca yeni bir index açar; böylece tek index sonsuz büyümez ve her evre index bazında yönetilir.","Frozen katman, searchable snapshot ile veriyi nesne depolamada (S3/blob) tutup yalnızca gerektiğinde kısmen belleğe alır; disk maliyetini büyük oranda düşürür ama sorgu gecikmesi artar.","Warm/cold'a geçerken force merge, shrink ve replica azaltma ile depolama ve heap optimize edilir; bu evrelerde veri değişmediği için segmentler tek segmente indirilebilir.","Data tier'ları node rolleriyle eşle (data_hot/data_warm/data_cold/data_frozen); ILM, shard allocation filtreleriyle index'i doğru donanımdaki node'lara yerleştirir."],"level":"expert"},{"id":"elasticsearch-segment-merge","title":"Elasticsearch: segment merge ve force-merge","category":"Elasticsearch","summary":"Lucene her refresh'te yeni değişmez (immutable) segmentler oluşturur; arka plan merge'i segmentleri birleştirip siler, force-merge ise dikkatli kullanılması gereken manuel bir işlemdir.","points":["Her refresh (varsayılan 1 sn) yeni bir segment üretir ve silmeler segmentte 'tombstone' olarak işaretlenir; okuma sırasında çok sayıda küçük segment sorguyu yavaşlatır, bu yüzden arka plan merge'i onları birleştirir.","Silinen/güncellenen dokümanların gerçek diskten kaldırılması ancak merge sırasında olur; yüksek update yükünde segmentlerde 'deleted docs' birikir ve disk/bellek şişer.","Yazma bitmiş (read-only) index'lerde force-merge ile segment sayısı 1'e indirilerek sorgu hızı ve disk verimi artırılır; bu, ILM'in warm evresinde tipik bir adımdır.","Force-merge aktif yazılan index'te ASLA çalıştırılmamalı; ürettiği çok büyük segment normal merge döngüsüne girmez, sonraki silmeler temizlenemez ve I/O ile heap'i uzun süre boğar.","refresh_interval'i toplu yükleme sırasında geçici artırmak (ör. -1 veya 30s) daha az/daha büyük segment üreterek merge yükünü ve yazma verimini iyileştirir."],"level":"expert"},{"id":"elasticsearch-node-roles","title":"Elasticsearch: node rolleri ve cluster topolojisi","category":"Elasticsearch","summary":"Elasticsearch node'ları master, data, coordinating ve ingest gibi roller üstlenir; büyük kümelerde rolleri ayırmak kararlılık ve ölçeklenebilirlik sağlar.","points":["Master-eligible node'lar cluster state'i (index, shard yerleşimi, mapping) yönetir; kararlı seçim için tek sayıda (genelde 3) özel master node kullan ve split-brain'i önlemek için quorum'a (çoğunluk) dayan.","Data node'lar shard'ları barındırıp indeksleme ve sorgu I/O'sunu üstlenir; en fazla CPU/RAM/disk kaynağını bunlar tüketir ve data tier'lara (hot/warm/cold/frozen) ayrılabilir.","Coordinating-only node, istekleri ilgili shard'lara dağıtıp sonuçları birleştiren (scatter-gather) rol dışı node'dur; ağır arama/aggregation birleştirmesini data node'lardan alarak onları korur ve load balancer görevi görür.","Ingest node, veriyi indekslemeden önce pipeline'larla (dönüştürme, zenginleştirme) işler; ağır ingest pipeline'larını ayrı ingest node'lara vermek data node'ların sorgu performansını korur.","Master node'ları asla ağır sorgu/veri yüküyle paylaştırma; master'ın yük altında yavaşlaması cluster state güncellemelerini geciktirip tüm kümede kararsızlığa (gecikmeli shard atama, seçim) yol açar."],"level":"expert"}]},"guide/glossary.json":{"terms":[{"term":"ACID","full":"Atomicity, Consistency, Isolation, Durability","definition":"Transaction'ların güvenilir olmasını sağlayan dört temel özellik: Atomiklik (ya hep ya hiç), Tutarlılık (kuralların korunması), İzolasyon (eşzamanlı transaction'ların birbirini bozmaması) ve Kalıcılık (commit edilen verinin kaybolmaması). İlişkisel veritabanlarının transaction garantisidir.","tags":["islem","transaction","acid","consistency","tutarlilik"]},{"term":"BASE","full":"Basically Available, Soft state, Eventually consistent","definition":"ACID'e alternatif, dağıtık ve NoSQL sistemlerde tercih edilen gevşek tutarlılık yaklaşımı. Sistem her zaman erişilebilir olmayı önceler ve verinin zamanla tutarlı hale geleceğini (eventual consistency) kabul eder. Ölçeklenebilirlik için katı tutarlılıktan ödün verir.","tags":["base","dagitik","distributed","eventual-consistency","nosql"]},{"term":"MVCC","full":"Multi-Version Concurrency Control","definition":"Aynı satırın birden fazla sürümünü tutarak okuyucular ile yazıcıların birbirini kilitlemeden çalışmasını sağlayan eşzamanlılık yöntemi. Her transaction verinin kendi snapshot'ını görür, böylece okuma yazmayı, yazma da okumayı bloklamaz. PostgreSQL ve Oracle gibi sistemlerde kullanılır.","tags":["eszamanlilik","concurrency","kilit","mvcc","snapshot"]},{"term":"WAL","full":"Write-Ahead Log","definition":"Bir değişiklik veri dosyalarına yazılmadan ÖNCE log kaydının kalıcı olarak diske yazılması ilkesidir. Çökme sonrası kurtarma (recovery) ve kalıcılık (durability) bunun sayesinde garanti edilir. PostgreSQL'de WAL, SQL Server'da transaction log adını alır.","tags":["wal","log","kurtarma","recovery","durability"]},{"term":"Redo Log","full":"","definition":"Veritabanına yapılan değişiklikleri kaydeden, çökme sonrası kaybolan işlemleri yeniden uygulamak (redo) için kullanılan log. Kurtarma sırasında commit edilmiş ama diske yazılmamış değişiklikleri ileri sarar. Oracle'da redo log, genel kavramda WAL'a karşılık gelir.","tags":["redo","log","kurtarma","recovery","oracle"]},{"term":"Undo / Rollback Segment","full":"","definition":"Bir işlemin değiştirdiği verinin eski halini saklayan alan. İki işe yarar: rollback ile değişikliği geri almak ve MVCC'de eski sürümü okuyuculara sunmak. Oracle'da undo/rollback segment, diğer sistemlerde undo/version store olarak geçer.","tags":["undo","rollback","geri-alma","mvcc","segment"]},{"term":"Buffer Pool / Buffer Cache","full":"","definition":"Sık kullanılan veri ve index sayfalarının bellekte tutulduğu ön bellek alanıdır. Diskten okuma pahalı olduğu için veritabanı performansı büyük ölçüde buradaki isabet oranına (cache hit ratio) bağlıdır. MySQL InnoDB'de buffer pool, SQL Server'da buffer cache denir.","tags":["buffer-pool","buffer-cache","onbellek","cache","bellek"]},{"term":"Dirty Page","full":"","definition":"Bellekte değiştirilmiş ama henüz diske yazılmamış veri sayfası. Kalıcılık WAL sayesinde korunur; sayfanın kendisi checkpoint veya background writer tarafından diske indirilene kadar dirty kalır. Fazla dirty page kurtarma süresini uzatır.","tags":["dirty-page","kirli-sayfa","bellek","checkpoint","io"]},{"term":"LSN","full":"Log Sequence Number","definition":"WAL/transaction log içindeki her kayda verilen, sürekli artan benzersiz sıra numarasıdır. Bir sayfanın hangi log kaydına kadar güncel olduğunu ve kurtarmada nereden devam edileceğini belirlemek için kullanılır. Replikasyonda ilerleme takibini de sağlar.","tags":["lsn","log","sira-numarasi","recovery","replikasyon"]},{"term":"SCN","full":"System Change Number","definition":"Oracle'da veritabanındaki her commit anına verilen, monoton artan mantıksal zaman damgasıdır. Okuma tutarlılığı (read consistency), MVCC ve kurtarma sırasında olayların sırasını belirlemek için kullanılır. LSN'in Oracle'daki karşılığı gibi düşünülebilir.","tags":["scn","oracle","zaman-damgasi","read-consistency","commit"]},{"term":"İzolasyon Seviyesi","full":"Isolation Level","definition":"Eşzamanlı işlemlerin birbirinin değişikliklerini ne ölçüde görebileceğini belirleyen ayardır. Read Uncommitted, Read Committed, Repeatable Read ve Serializable olarak sıralanır; seviye yükseldikçe tutarlılık artar, eşzamanlılık azalır. Dirty/non-repeatable/phantom read anomalilerini kontrol eder.","tags":["izolasyon","isolation-level","transaction","eszamanlilik","concurrency"]},{"term":"Dirty Read","full":"","definition":"Bir transaction'ın, başka bir transaction'ın henüz commit etmemiş (belki geri alınacak) değişikliğini okumasıdır. Bu okunan veri geçersiz olabileceğinden bir tutarlılık anomalisidir. Yalnızca Read Uncommitted izolasyon seviyesinde mümkündür.","tags":["dirty-read","anomali","izolasyon","transaction","tutarlilik"]},{"term":"Non-repeatable Read","full":"","definition":"Aynı transaction içinde aynı satırın iki kez okunduğunda, arada başka bir transaction'ın commit'i yüzünden farklı değer görülmesidir. Read Committed seviyesinde ortaya çıkabilir; Repeatable Read ve üstünde engellenir.","tags":["non-repeatable-read","anomali","izolasyon","transaction","tekrarlanamaz"]},{"term":"Phantom Read","full":"","definition":"Aynı transaction içinde bir sorgu aynı koşulla tekrar çalıştırıldığında, araya giren bir ekleme/silme yüzünden satır kümesinin değişmesidir (yeni 'hayalet' satırlar belirir). SQL standardına göre Serializable seviyesinde engellenir; PostgreSQL bunu Repeatable Read'de de engeller.","tags":["phantom-read","hayalet","anomali","serializable","izolasyon"]},{"term":"Deadlock","full":"","definition":"İki veya daha fazla transaction'ın, birbirinin tuttuğu lock'u karşılıklı beklemesi sonucu hiçbirinin ilerleyememesi durumudur. Veritabanı bunu tespit eder ve genellikle en az maliyetli transaction'ı 'kurban' seçip geri alarak (rollback) döngüyü kırar. Lock'ları hep aynı sırada almak riski azaltır.","tags":["deadlock","kilitlenme","kilit","lock","eszamanlilik"]},{"term":"Lock Escalation","full":"","definition":"Bir işlem çok sayıda row/page lock tuttuğunda, veritabanının bunları tek bir daha kaba lock'a (örneğin table lock'a) yükseltmesidir. Lock yönetimi belleğini azaltır ama eşzamanlılığı düşürür ve bloklamayı artırabilir. Özellikle SQL Server'da görülür.","tags":["lock-escalation","kilit","lock","eszamanlilik","sql-server"]},{"term":"Latch","full":"","definition":"Bellek içi yapıları (örneğin buffer pool sayfalarını) çok kısa süre korumak için kullanılan hafif, düşük maliyetli bir eşzamanlılık lock'udur. Transaction lock'larından farklı olarak mantıksal veriyi değil fiziksel bellek yapısını korur ve çok kısa sürelidir.","tags":["latch","kilit","bellek","eszamanlilik","internal"]},{"term":"B-Tree Index","full":"Balanced Tree Index","definition":"Verileri sıralı ve dengeli bir ağaç yapısında tutan, en yaygın index türüdür. Eşitlik ve aralık (range) sorgularında, sıralamada ve ilk-ek (prefix) aramalarında verimlidir. Çoğu veritabanında varsayılan index tipidir.","tags":["btree","index","indeks","arama","range"]},{"term":"Hash Index","full":"","definition":"Anahtarı bir hash fonksiyonundan geçirerek konumlandıran index türüdür. Yalnızca tam eşitlik (=) aramalarında çok hızlıdır; aralık sorguları ve sıralama için kullanılamaz. Mesela PostgreSQL ve MySQL Memory tablolarında bulunur.","tags":["hash-index","index","indeks","esitlik","arama"]},{"term":"Bitmap Index","full":"","definition":"Her farklı değer için bit dizileri tutan, düşük kardinaliteli (az sayıda ayrık değer içeren) sütunlar için uygun index'tir. Birden çok koşulun AND/OR ile hızlı birleştirilmesini sağlar; veri ambarı/OLAP yüklerinde etkilidir ama yoğun yazmada verimsizdir.","tags":["bitmap-index","index","indeks","olap","kardinalite"]},{"term":"Covering Index","full":"","definition":"Bir sorgunun ihtiyaç duyduğu tüm sütunları içeren index'tir; sorgu yalnızca index'ten karşılanır, tabloya (heap/clustered) gitmeye gerek kalmaz. Bu, pahalı satır aramalarını (lookup) ortadan kaldırarak performansı artırır. INCLUDE sütunlarıyla oluşturulabilir.","tags":["covering-index","index","indeks","performans","lookup"]},{"term":"Clustered Index","full":"","definition":"Tablonun satırlarını fiziksel olarak index anahtarına göre sıralı tutan index'tir; tablonun kendisi bu sıraya göre depolanır. Bir tabloda yalnızca bir tane olabilir. Aralık sorgularında hızlıdır; InnoDB'de primary key daima clustered'dır.","tags":["clustered-index","index","indeks","fiziksel","primary-key"]},{"term":"Cardinality","full":"","definition":"Bir sütundaki ayrık (distinct) değer sayısını ifade eder. Yüksek kardinalite (örneğin e-posta) çok farklı değer, düşük kardinalite (örneğin cinsiyet) az değer demektir. Optimizer'ın index seçimini ve plan maliyetini tahmin etmesinde kritik bir ölçüttür.","tags":["cardinality","kardinalite","istatistik","optimizer","distinct"]},{"term":"Selectivity","full":"","definition":"Bir filtre koşulunun toplam satırların ne kadar küçük bir kısmını döndürdüğünü gösterir. Yüksek seçicilik (az satır) index kullanımını cazip kılar; düşük seçicilikte (çok satır) tam tarama daha ucuz olabilir. Optimizer plan seçiminde bunu kullanır.","tags":["selectivity","secicilik","optimizer","index","istatistik"]},{"term":"Execution Plan","full":"","definition":"Optimizer'ın bir sorguyu çalıştırmak için seçtiği adımları (tarama türü, join yöntemi, sıralama vb.) gösteren yol haritasıdır. EXPLAIN/EXPLAIN ANALYZE ile incelenerek performans sorunlarının kök nedeni bulunur. Tahmini ve gerçek maliyetleri karşılaştırmak önemlidir.","tags":["execution-plan","sorgu-plani","explain","optimizer","performans"]},{"term":"Cost-Based Optimizer","full":"CBO","definition":"Olası çalıştırma planlarının maliyetini istatistiklere dayanarak tahmin eden ve en düşük maliyetlisini seçen sorgu iyileştiricidir. Doğru kararlar için istatistiklerin güncel olması şarttır; eski istatistikler kötü plan üretilmesine yol açar. Modern veritabanlarının standart yaklaşımıdır.","tags":["cbo","optimizer","maliyet","istatistik","sorgu-plani"]},{"term":"İstatistik","full":"Statistics","definition":"Optimizer'ın satır sayısı, kardinalite ve değer dağılımını tahmin etmesi için tabloya/index'e ait toplanan meta verilerdir. Güncel istatistikler iyi sorgu planları demektir; eskidiğinde ANALYZE/UPDATE STATISTICS ile yenilenmelidir. Kötü performansın sık nedenlerinden biridir.","tags":["istatistik","statistics","optimizer","analyze","sorgu-plani"]},{"term":"Histogram","full":"","definition":"Bir sütundaki değerlerin dağılımını aralıklara (bucket) bölerek özetleyen istatistik yapısıdır. Özellikle dengesiz (skewed) dağılımlarda optimizer'ın satır sayısını daha isabetli tahmin etmesini sağlar. İstatistiklerin bir bileşenidir.","tags":["histogram","istatistik","statistics","optimizer","dagilim"]},{"term":"Partition","full":"","definition":"Büyük bir tabloyu, mantıksal olarak tek tablo kalarak fiziksel olarak daha küçük parçalara (örneğin tarihe veya aralığa göre) bölme tekniğidir. Sorgular yalnızca ilgili parçayı tarar (partition pruning), bakım ve arşivleme kolaylaşır. Sharding'den farkı: aynı sunucu/instance içindedir.","tags":["partition","bolumleme","olcekleme","pruning","buyuk-veri"]},{"term":"Sharding","full":"","definition":"Veriyi bir shard anahtarına göre birden fazla ayrı sunucuya/veritabanına yatay olarak dağıtma yöntemidir. Tek makinenin sınırlarını aşarak yatay ölçekleme sağlar ama sorgu ve işlem yönetimini karmaşıklaştırır. Partition'dan farkı: veri farklı düğümlere dağılır.","tags":["sharding","olcekleme","dagitik","distributed","yatay-olcekleme"]},{"term":"Replication (Senkron/Asenkron)","full":"","definition":"Verinin bir primary düğümden bir veya daha fazla kopyaya (replica) çoğaltılmasıdır. Senkron replikasyonda commit, kopya onayını bekler (veri kaybı yok, gecikme artar); asenkronda beklemez (hızlı ama replika gerideyse veri kaybı riski var). HA ve okuma ölçeklemesi için kullanılır.","tags":["replikasyon","replication","senkron","asenkron","ha"]},{"term":"Logical vs Physical Replication","full":"","definition":"Fiziksel replikasyon disk bloğu/WAL düzeyinde bire bir kopya oluşturur (aynı sürüm, tüm veritabanı). Mantıksal replikasyon ise değişiklikleri satır/SQL düzeyinde aktarır; seçici tablo çoğaltma, sürümler arası ve farklı şemalar arası aktarıma izin verir. CDC ve upgrade senaryolarında mantıksal tercih edilir.","tags":["logical-replication","physical-replication","replikasyon","cdc","wal"]},{"term":"Failover","full":"","definition":"Primary arızalandığında hizmetin otomatik veya elle bir yedek (standby) düğüme devredilmesidir. Kesintiyi en aza indirir; ne kadar veri kaybedilebileceğini RPO, ne kadar sürede toparlanılacağını RTO belirler. Plansız arıza durumlarında devreye girer.","tags":["failover","ha","yuksek-erisilebilirlik","standby","rpo"]},{"term":"Switchover","full":"","definition":"Primary ve standby düğüm rollerinin planlı ve kontrollü biçimde el değiştirmesidir (örneğin bakım için). Failover'dan farkı: arıza değil, planlı bir işlemdir ve genellikle veri kaybı olmadan yapılır.","tags":["switchover","planli","ha","bakim","standby"]},{"term":"RPO","full":"Recovery Point Objective","definition":"Bir felaket sonrası kabul edilebilir azami veri kaybı miktarıdır (zaman cinsinden). Örneğin RPO 5 dakika ise en fazla 5 dakikalık veri kaybı tolere edilir. Yedekleme sıklığı ve replikasyon türü bu hedefe göre seçilir.","tags":["rpo","veri-kaybi","dr","felaket-kurtarma","yedekleme"]},{"term":"RTO","full":"Recovery Time Objective","definition":"Bir kesinti sonrası sistemin tekrar çalışır hale gelmesi için hedeflenen azami süredir. Örneğin RTO 1 saat ise hizmet en geç 1 saat içinde ayağa kalkmalıdır. HA/DR mimarisi ve otomasyon seviyesi bu hedefe göre tasarlanır.","tags":["rto","kurtarma-suresi","dr","felaket-kurtarma","ha"]},{"term":"HA","full":"High Availability","definition":"Sistemin arızalara rağmen kesintisiz veya çok az kesintiyle hizmet vermesini sağlayan tasarım hedefidir. Yedeklilik (redundancy), otomatik failover ve sağlık denetimi ile sağlanır. Genellikle çalışma süresi yüzdesiyle (örneğin %99,99) ifade edilir.","tags":["ha","yuksek-erisilebilirlik","high-availability","failover","redundancy"]},{"term":"DR","full":"Disaster Recovery","definition":"Yangın, sel, bölge çapında kesinti gibi büyük felaketler sonrası sistem ve veriyi genellikle coğrafi olarak ayrı bir bölgede geri getirme plan ve süreçleridir. RPO ve RTO hedefleriyle ölçülür. HA günlük arızalara, DR ise büyük felaketlere odaklanır.","tags":["dr","felaket-kurtarma","disaster-recovery","rpo","rto"]},{"term":"Quorum","full":"","definition":"Dağıtık bir sistemde bir kararın (örneğin lider seçimi veya yazma onayı) geçerli sayılması için gereken asgari düğüm çoğunluğudur (genellikle N/2 + 1). Split-brain'i önlemek ve tutarlılığı korumak için kullanılır. Bu yüzden küme boyutları çoğunlukla tek sayı seçilir.","tags":["quorum","cogunluk","dagitik","distributed","split-brain"]},{"term":"Split-Brain","full":"","definition":"Ağ kopması sonucu bir kümenin iki parçasının da kendini primary sanıp bağımsız yazmaya devam etmesi durumudur; bu, çelişen veri ve bozulmaya yol açar. Quorum ve fencing mekanizmalarıyla önlenir. HA kümelerinin en tehlikeli hata senaryolarından biridir.","tags":["split-brain","dagitik","quorum","ha","tutarlilik"]},{"term":"TDE","full":"Transparent Data Encryption","definition":"Veritabanı dosyalarının (data ve log) diskte şifreli tutulmasını sağlayan, uygulamaya şeffaf çalışan bir şifreleme yöntemidir. Disk veya yedek dosyaları çalınsa bile veriyi korur (data-at-rest). Ağ üzerindeki veriyi (in-transit) korumaz; onun için TLS gerekir.","tags":["tde","sifreleme","encryption","guvenlik","security"]},{"term":"RBAC","full":"Role-Based Access Control","definition":"Yetkilerin doğrudan kullanıcılara değil rollere atandığı, kullanıcıların da rollere üye yapıldığı erişim denetimi modelidir. Yetki yönetimini sadeleştirir ve en az ayrıcalık (least privilege) ilkesini uygulamayı kolaylaştırır. Kullanıcı sayısı büyüdükçe yönetimi ölçeklenebilir kılar.","tags":["rbac","rol","yetki","guvenlik","security"]},{"term":"Connection Pool","full":"","definition":"Uygulamanın veritabanına açtığı bağlantıları tekrar tekrar kurup kapatmak yerine önceden oluşturup yeniden kullanan havuzdur. Bağlantı kurma maliyetini düşürür, kaynak tüketimini sınırlar ve yükü kontrol eder. Aşırı bağlantı açılmasını önleyerek veritabanını korur.","tags":["connection-pool","baglanti-havuzu","performans","kaynak","uygulama"]},{"term":"Prepared Statement","full":"","definition":"Bir SQL ifadesinin bir kez ayrıştırılıp (parse) planlanıp, sonra farklı parametre değerleriyle tekrar tekrar çalıştırıldığı yapıdır. Plan yeniden kullanımıyla performansı artırır ve SQL enjeksiyonuna karşı güvenlik sağlar. Bind değişkenlerle birlikte kullanılır.","tags":["prepared-statement","bind","guvenlik","sql-injection","performans"]},{"term":"Bind Variable","full":"","definition":"SQL metnine değerin gömülmesi yerine yer tutucu (placeholder) ile geçirilen parametredir. Aynı sorgunun farklı değerlerle tekrar planlanmasını önleyerek plan önbelleğini (plan cache) verimli kullanır ve SQL enjeksiyonunu engeller. Literal değerlerin sık değiştiği sorgularda kritiktir.","tags":["bind-variable","parametre","prepared-statement","plan-cache","guvenlik"]},{"term":"Parameter Sniffing","full":"","definition":"Optimizer'ın bir prepared/parametreli sorgunun planını ilk çalıştırmadaki parametre değerine göre üretip önbelleğe almasıdır. Bu değer atipikse, sonraki farklı değerler için kötü çalışan bir plan kalıcı hale gelebilir. Çözümler arasında plan yeniden derleme (recompile) ve optimize hint'leri bulunur.","tags":["parameter-sniffing","plan-cache","optimizer","performans","sql-server"]},{"term":"VACUUM / Bloat","full":"","definition":"MVCC nedeniyle silinen/güncellenen satırların ölü (dead) sürümleri tabloda birikir; bu şişkinliğe bloat denir. VACUUM bu dead tuple'ların yerini geri kazanır ve istatistikleri günceller (PostgreSQL). Düzenli yapılmazsa disk şişer ve performans düşer.","tags":["vacuum","bloat","sismis","mvcc","postgresql"]},{"term":"Compaction","full":"","definition":"LSM-tree tabanlı depolarda (örneğin Cassandra, RocksDB) birden çok küçük veri dosyasının birleştirilip ölü/eski kayıtların temizlenmesi işlemidir. Okuma performansını iyileştirir ve disk alanını geri kazanır. VACUUM'ın LSM dünyasındaki benzeridir.","tags":["compaction","lsm-tree","birlestirme","cassandra","rocksdb"]},{"term":"Oplog","full":"Operations Log","definition":"MongoDB'de primary'ye uygulanan tüm yazma işlemlerinin sırayla kaydedildiği, sabit boyutlu (capped) özel koleksiyondur. Replika üyeleri buradan okuyarak primary ile senkron olur. CDC ve replikasyonun temelini oluşturur.","tags":["oplog","mongodb","replikasyon","cdc","log"]},{"term":"Binlog","full":"Binary Log","definition":"MySQL'de veriyi değiştiren tüm işlemleri (veya satır değişikliklerini) kaydeden ikili logdur. Replikasyon, point-in-time recovery ve CDC için kullanılır. Row, statement veya mixed formatında tutulabilir.","tags":["binlog","mysql","replikasyon","cdc","recovery"]},{"term":"CDC","full":"Change Data Capture","definition":"Bir veritabanındaki ekleme/güncelleme/silme değişikliklerini yakalayıp başka sistemlere (veri ambarı, arama motoru, mesaj kuyruğu) akıtma tekniğidir. Genellikle transaction log'u (binlog, WAL, oplog) okuyarak düşük yükle çalışır. Gerçek zamanlı veri entegrasyonunun temelidir.","tags":["cdc","change-data-capture","veri-akisi","binlog","entegrasyon"]},{"term":"Materialized View","full":"","definition":"Bir sorgunun sonucunu diskte fiziksel olarak saklayan view'dır; normal view'den farklı olarak her sorguda yeniden hesaplanmaz. Pahalı toplama (aggregation) ve join'leri hızlandırır ama verisi bayatlar; refresh ile güncellenmesi gerekir. OLAP/raporlamada yaygındır.","tags":["materialized-view","gorunum","onbellek","olap","raporlama"]},{"term":"Foreign Key","full":"","definition":"Bir tablodaki sütunun, başka bir tablonun birincil/aday anahtarına başvurmasını sağlayan referans bütünlüğü constraint'idir. Var olmayan bir kayda başvuruyu engeller ve ilişkileri korur. ON DELETE/UPDATE CASCADE gibi kurallarla bağımlı satırların davranışı belirlenebilir.","tags":["foreign-key","yabanci-anahtar","butunluk","iliski","constraint"]},{"term":"Normalizasyon","full":"Normalization","definition":"Veriyi tekrarları (redundancy) azaltacak ve tutarsızlık riskini düşürecek şekilde ilişkili tablolara bölme sürecidir (1NF, 2NF, 3NF gibi normal formlar). Güncelleme anomalilerini önler; OLTP sistemlerinde tercih edilir. Karşılığında sorgular daha çok join gerektirebilir.","tags":["normalizasyon","normalization","tasarim","oltp","redundancy"]},{"term":"Denormalizasyon","full":"Denormalization","definition":"Okuma performansını artırmak için veriyi bilinçli olarak tekrarlayıp join sayısını azaltma tekniğidir. Sorguları hızlandırır ama veri tekrarı ve güncelleme karmaşıklığı getirir. Raporlama/OLAP ve yüksek okuma yüklerinde tercih edilir.","tags":["denormalizasyon","denormalization","performans","olap","okuma"]},{"term":"OLTP","full":"Online Transaction Processing","definition":"Çok sayıda kısa, sık ve eşzamanlı işlemi (ekle/güncelle/sil, tekil kayıt okuma) işleyen sistem türüdür; örneğin bankacılık, e-ticaret. Düşük gecikme ve yüksek eşzamanlılık gerektirir, genellikle normalize tasarlanır. OLAP'ın operasyonel karşılığıdır.","tags":["oltp","islem","transaction","operasyonel","normalizasyon"]},{"term":"OLAP","full":"Online Analytical Processing","definition":"Büyük veri kümeleri üzerinde karmaşık toplama ve analiz sorguları çalıştıran sistem türüdür; örneğin raporlama, iş zekası. Az ama ağır sorgular çalışır, genellikle denormalize ve sütun-tabanlı (columnar) tasarlanır. OLTP'nin analitik karşılığıdır.","tags":["olap","analitik","raporlama","veri-ambari","columnar"]},{"term":"ETL","full":"Extract, Transform, Load","definition":"Veriyi kaynaklardan çıkarma (Extract), iş kurallarına göre dönüştürme (Transform) ve hedef sisteme (genellikle veri ambarı) yükleme (Load) sürecidir. Dönüşümün yükleme sonrası hedefte yapıldığı varyanta ELT denir. Veri entegrasyonunun klasik yaklaşımıdır.","tags":["etl","veri-entegrasyonu","veri-ambari","elt","donusum"]},{"term":"Hot/Cold Data","full":"","definition":"Sık erişilen, güncel veriye 'hot' (sıcak), nadiren erişilen eski/arşiv veriye 'cold' (soğuk) denir. Sıcak veri hızlı/pahalı depolamada, soğuk veri ucuz/yavaş depolamada tutulur (data tiering). Maliyet ile performansı dengelemek için kullanılan bir stratejidir.","tags":["hot-data","cold-data","sicak-soguk","arsiv","tiering"]},{"term":"Index Fragmentation","full":"","definition":"Zamanla yapılan ekleme/silme/güncellemeler sonucu index sayfalarının mantıksal sırasının fiziksel sıradan kopması ve sayfa doluluğunun düşmesidir. Gereksiz I/O ve boşa harcanan alan yaratıp performansı düşürür. REBUILD veya REORGANIZE ile giderilir.","tags":["index-fragmentation","parcalanma","index","bakim","performans"]},{"term":"Two-Phase Commit","full":"2PC","definition":"Birden çok veritabanı/kaynağı kapsayan dağıtık bir transaction'ın atomik commit'ini sağlayan protokoldür. İki aşamalı çalışır: önce koordinatör tüm katılımcılara hazır mısın diye sorar (prepare), hepsi onaylarsa commit, biri reddederse hepsi rollback yapar. Yavaştır ve koordinatör arızasına karşı hassastır.","tags":["two-phase-commit","2pc","dagitik","distributed","atomik"]}]},"guide/glossary-2.json":{"terms":[{"term":"LSM Tree","full":"Log-Structured Merge Tree","definition":"Yazma işlemlerini önce bellekteki bir yapıda (memtable) toplayıp sıralı bloklar hâlinde diske döken depolama yapısıdır. Rastgele yazmaları sıralı yazmalara çevirerek yüksek yazma verimi sağlar; okuma için birden çok seviyeyi tarar. RocksDB, Cassandra ve LevelDB'nin temelidir.","tags":["storage","depolama","lsm","yazma"]},{"term":"B+ Tree","full":"","definition":"Tüm verinin yaprak düğümlerde tutulduğu, iç düğümlerin yalnızca yönlendirme anahtarı içerdiği dengeli ağaç yapısıdır. Yaprakların birbirine bağlı olması aralık (range) taramalarını hızlandırır. İlişkisel veritabanı index'lerinin en yaygın yapısıdır.","tags":["index","indeks","storage","depolama","btree"]},{"term":"Bloom Filter","full":"","definition":"Bir öğenin kümede olup olmadığını az bellekle kontrol eden olasılıksal veri yapısıdır. \"Kesinlikle yok\" ya da \"muhtemelen var\" yanıtı verir; yanlış pozitif olabilir ama yanlış negatif olamaz. LSM tabanlı motorlarda gereksiz disk okumalarını önlemek için kullanılır.","tags":["storage","depolama","olasiliksal","filter","performans"]},{"term":"Consistent Hashing","full":"","definition":"Düğüm eklenip çıkarıldığında anahtarların yalnızca küçük bir kısmının yer değiştirmesini sağlayan dağıtım yöntemidir. Anahtarlar ve düğümler sanal bir halka üzerine yerleştirilir. Dağıtık önbellek ve NoSQL sistemlerinde veri dağıtımı için kullanılır.","tags":["dagitik","distributed","hashing","sharding","olcekleme"]},{"term":"Vector Clock","full":"","definition":"Dağıtık sistemlerde olayların nedensel sırasını izlemek için her düğüme ait sayaçları tutan yapıdır. İki güncellemenin birbirinden mi türediğini yoksa eşzamanlı (çakışan) mı olduğunu belirlemeye yarar. Çakışma tespitinde ve eventual consistency'de kullanılır.","tags":["dagitik","distributed","saat","nedensellik","consistency"]},{"term":"Gossip Protocol","full":"","definition":"Her düğümün durum bilgisini rastgele seçtiği birkaç komşuya periyodik olarak yaydığı, bilginin salgın gibi tüm kümeye ulaştığı iletişim yöntemidir. Merkezi koordinatör gerektirmez, ölçeklenebilir ve arızaya dayanıklıdır. Cassandra ve Consul üyelik yönetiminde kullanılır.","tags":["dagitik","distributed","gossip","cluster","uyelik"]},{"term":"Raft","full":"","definition":"Anlaşılması Paxos'a göre daha kolay olacak biçimde tasarlanmış bir konsensüs (uzlaşma) algoritmasıdır. Bir lider seçer, tüm yazmaları lider üzerinden çoğaltılan bir log'a işler ve çoğunluk onayıyla kalıcı kılar. etcd ve Consul tarafından kullanılır.","tags":["dagitik","distributed","konsensus","raft","replikasyon"]},{"term":"Paxos","full":"","definition":"Güvenilmez bir ağda çoğunluğun tek bir değer üzerinde anlaşmasını garanti eden klasik konsensüs algoritmasıdır. Doğru ancak uygulaması karmaşık kabul edilir; birçok dağıtık sistemin kuramsal temelini oluşturur. Google Chubby gibi sistemlerde kullanılmıştır.","tags":["dagitik","distributed","konsensus","paxos","uzlasma"]},{"term":"Leader Election","full":"","definition":"Dağıtık bir küme içinde belirli bir işi koordine edecek tek bir düğümün (lider) seçilmesi sürecidir. Mevcut lider arızalanırsa otomatik olarak yeni lider seçilir. Split-brain'i önlemek için genellikle çoğunluk (quorum) onayı gerektirir.","tags":["dagitik","distributed","lider","secim","koordinasyon"]},{"term":"Quorum Write/Read","full":"","definition":"Bir okuma ya da yazmanın geçerli sayılması için gereken minimum düğüm sayısıdır. W + R > N koşulu sağlandığında en güncel veriye ulaşmak garanti edilir. Tutarlılık ile erişilebilirlik arasında ayar yapmayı mümkün kılar.","tags":["dagitik","distributed","quorum","consistency","replikasyon"]},{"term":"WAL Shipping","full":"Write-Ahead Log Shipping","definition":"Primary'nin ürettiği WAL kayıtlarının standby sunuculara gönderilerek orada yeniden uygulanmasıdır. Bu sayede yedek, ana veritabanının neredeyse güncel bir kopyasını tutar. PostgreSQL streaming replikasyonunun temelidir.","tags":["replikasyon","replication","wal","yuksek-erisilebilirlik","standby"]},{"term":"Log Shipping","full":"","definition":"İşlem log'u yedeklerinin düzenli aralıklarla bir standby sunucuya kopyalanıp geri yüklenmesiyle çalışan basit replikasyon yöntemidir. Streaming'e göre gecikmesi daha yüksektir ama kurulumu kolaydır. SQL Server'da felaket kurtarma için sık kullanılır.","tags":["replikasyon","replication","log","yedekleme","standby"]},{"term":"Snapshot Isolation","full":"","definition":"Her transaction'ın, başladığı andaki tutarlı veri snapshot'ını gördüğü izolasyon düzeyidir. Okuyucular yazıcıları bloklamaz; ancak write skew gibi bazı anomalilere açıktır. MVCC ile birlikte uygulanır.","tags":["izolasyon","isolation","mvcc","snapshot","eszamanlilik"]},{"term":"Serializable Snapshot Isolation (SSI)","full":"Serializable Snapshot Isolation","definition":"Snapshot isolation'ın üzerine tehlikeli okuma-yazma bağımlılıklarını izleyerek gerçek serileştirilebilirlik (serializability) sağlayan yöntemdir. Çakışma tespit edilince transaction'lardan biri geri alınır. PostgreSQL'in SERIALIZABLE düzeyinde kullanılır.","tags":["izolasyon","isolation","serializable","ssi","eszamanlilik"]},{"term":"Gap Lock","full":"","definition":"Index kayıtları arasındaki boşluğu (henüz var olmayan aralığı) kilitleyerek o aralığa yeni satır eklenmesini engelleyen lock'tur. Phantom (hayalet) okumalarını önlemek için kullanılır. InnoDB'nin REPEATABLE READ düzeyinde devreye girer.","tags":["kilit","lock","innodb","phantom","eszamanlilik"]},{"term":"Next-Key Lock","full":"","definition":"Bir index kaydının lock'u ile ondan önceki boşluğun (gap lock) lock'unun birleşimidir. Hem mevcut satırı hem de aralığı koruyarak phantom eklemeleri engeller. InnoDB'nin varsayılan satır kilitleme davranışıdır.","tags":["kilit","lock","innodb","gap","eszamanlilik"]},{"term":"Optimistic Locking","full":"","definition":"Çakışmaların nadir olduğunu varsayıp lock almadan çalışan, yalnızca commit anında verinin değişip değişmediğini kontrol eden yöntemdir. Genellikle sürüm numarası ya da zaman damgası ile uygulanır. Çakışma bulunursa işlem yeniden denenir.","tags":["kilit","lock","iyimser","eszamanlilik","concurrency"]},{"term":"Pessimistic Locking","full":"","definition":"Çakışma olacağını varsayarak veriyi okurken ya da değiştirirken hemen lock alan yöntemdir. Diğer transaction'lar lock serbest kalana kadar bekler. Yüksek çakışma ortamlarında veri bütünlüğünü korur ama eşzamanlılığı düşürür.","tags":["kilit","lock","kotumser","eszamanlilik","concurrency"]},{"term":"Idempotency","full":"","definition":"Bir işlemin bir kez ya da birçok kez çalıştırılmasının aynı sonucu vermesi özelliğidir. Ağ hataları sonrası güvenli tekrar denemeleri (retry) mümkün kılar. Dağıtık sistemlerde mükerrer isteklerin yan etki yaratmasını önler.","tags":["dagitik","distributed","idempotent","retry","guvenilirlik"]},{"term":"Circuit Breaker","full":"","definition":"Sürekli hata veren bir servise yapılan çağrıları geçici olarak keserek sistemi koruyan tasarım kalıbıdır. Devre \"açık\" durumdayken istekler hızlıca reddedilir, bir süre sonra deneme yapılır. Zincirleme arızaları (cascading failure) önler.","tags":["dagitik","distributed","dayaniklilik","resilience","pattern"]},{"term":"Saga Pattern","full":"","definition":"Birden çok servise yayılmış uzun süreli transaction'ları, her adımı yerel transaction ve hata durumunda telafi (compensating) transaction'larıyla yöneten kalıptır. Dağıtık ortamda ACID yerine nihai tutarlılık sağlar. Mikroservis mimarilerinde yaygındır.","tags":["dagitik","distributed","saga","mikroservis","pattern"]},{"term":"Outbox Pattern","full":"","definition":"Veritabanı güncellemesi ile mesaj yayınlamayı atomik kılmak için mesajı aynı işlemde bir \"outbox\" tablosuna yazma kalıbıdır. Ayrı bir süreç bu tabloyu okuyup mesajı yayınlar. Böylece veri ile olay yayını arasındaki tutarsızlık önlenir.","tags":["dagitik","distributed","outbox","mesajlasma","pattern"]},{"term":"Fan-out","full":"","definition":"Tek bir işlemin çok sayıda alt işlem ya da hedefe dağıtılmasıdır; örneğin bir gönderinin binlerce takipçinin akışına yazılması. Yazma anında (write fan-out) ya da okuma anında (read fan-out) yapılabilir. Ölçeklemede önemli bir tasarım kararıdır.","tags":["dagitik","distributed","olcekleme","fanout","mimari"]},{"term":"Hotspot","full":"","definition":"Yükün belirli bir düğüm, bölüm (partition) ya da anahtar üzerinde aşırı yoğunlaşmasıdır. Bu nokta darboğaza dönüşerek tüm sistemin performansını sınırlar. Kötü seçilmiş sharding anahtarı sık görülen bir nedendir.","tags":["dagitik","distributed","hotspot","performans","sharding"]},{"term":"Skew (veri dengesizliği)","full":"","definition":"Verinin ya da yükün bölümler arasında eşit olmayan biçimde dağılmasıdır. Bazı bölümler dolup taşarken diğerleri boş kalır ve paralellik verimi düşer. Anahtar seçimi ya da salting ile dengelenmeye çalışılır.","tags":["dagitik","distributed","skew","dengesizlik","sharding"]},{"term":"Partial Index","full":"","definition":"Tablonun yalnızca bir WHERE koşulunu sağlayan satırlarını kapsayan index'tir. Index boyutunu küçültüp bakımı ucuzlatır ve sık sorgulanan alt kümeyi hızlandırır. Örneğin yalnızca aktif kayıtları indekslemek için kullanılır.","tags":["index","indeks","postgresql","kismi","performans"]},{"term":"Expression Index","full":"","definition":"Bir sütun yerine bir ifadenin ya da fonksiyonun sonucu üzerine kurulan index'tir. Örneğin LOWER(email) üzerine kurularak büyük-küçük harf duyarsız aramaları hızlandırır. Sorgunun aynı ifadeyi kullanması gerekir.","tags":["index","indeks","ifade","fonksiyon","performans"]},{"term":"GIN Index","full":"Generalized Inverted Index","definition":"Bir değerin içindeki birden çok bileşeni indeksleyen ters (inverted) index türüdür. Dizi, JSONB ve tam metin arama gibi bir alanın çok anahtar içerdiği durumlar için idealdir. PostgreSQL'de kullanılır.","tags":["index","indeks","postgresql","gin","jsonb"]},{"term":"GiST Index","full":"Generalized Search Tree","definition":"Ağaç tabanlı, genişletilebilir bir index çatısıdır; farklı veri türleri için özel arama stratejileri tanımlanabilir. Coğrafi (geometri), aralık ve en yakın komşu sorguları için elverişlidir. PostGIS'in temelini oluşturur.","tags":["index","indeks","postgresql","gist","cografi"]},{"term":"TOAST","full":"The Oversized-Attribute Storage Technique","definition":"PostgreSQL'in sayfa boyutuna sığmayan büyük alan değerlerini sıkıştırıp ayrı bir alanda saklama tekniğidir. Büyük metin ve JSONB değerleri şeffaf biçimde bölünür. Ana tabloyu kompakt tutarak performansı korur.","tags":["storage","depolama","postgresql","toast","buyuk-veri"]},{"term":"Index-Only Scan","full":"","definition":"Gereken tüm verinin index'te bulunması sayesinde tabloyu hiç okumadan yalnızca index'ten yanıt üreten tarama biçimidir. Disk erişimini ciddi biçimde azaltır. PostgreSQL'de visibility map ile birlikte çalışır.","tags":["index","indeks","tarama","performans","postgresql"]},{"term":"HTAP","full":"Hybrid Transactional/Analytical Processing","definition":"Tek bir sistemde hem işlemsel (OLTP) hem analitik (OLAP) yükleri birlikte çalıştırma yaklaşımıdır. Analiz için veriyi ayrı bir depoya taşıma (ETL) gecikmesini ortadan kaldırır. Genellikle satır ve sütun depolarını birleştirir.","tags":["analitik","oltp","olap","htap","mimari"]},{"term":"Sharding Key","full":"","definition":"Bir satırın hangi bölüme (shard) düşeceğini belirleyen sütun ya da sütunlardır. İyi seçilmiş bir anahtar yükü eşit dağıtır ve hotspot'ları önler. Kötü seçim veri dengesizliği ve pahalı çapraz-shard sorgulara yol açar.","tags":["dagitik","distributed","sharding","anahtar","olcekleme"]},{"term":"Rebalancing","full":"","definition":"Düğüm eklenip çıkarıldığında ya da yük dengesizleştiğinde verinin bölümler arasında yeniden dağıtılmasıdır. Amaç yükü eşitlemek ve kaynakları verimli kullanmaktır. İşlem sırasında ağ ve I/O maliyeti oluşturur.","tags":["dagitik","distributed","rebalancing","olcekleme","sharding"]},{"term":"Fencing","full":"","definition":"Eski ya da izole olmuş bir düğümün paylaşılan kaynağa yazmasını engelleyerek veri bozulmasını önleyen mekanizmadır. Genellikle artan bir \"fencing token\" ile eski isteklerin reddedilmesi sağlanır. Split-brain'in etkisini sınırlar.","tags":["dagitik","distributed","fencing","guvenlik","split-brain"]},{"term":"Watermark","full":"","definition":"Akış işleme sistemlerinde belirli bir zamana kadar tüm olayların gelmiş sayıldığını gösteren ilerleme işaretidir. Gecikmeli (geç gelen) olayları ele almak ve pencere (window) hesaplarını ne zaman kapatacağını belirlemek için kullanılır.","tags":["akis","streaming","watermark","zaman","olay"]},{"term":"Tombstone","full":"","definition":"Bir kaydın silindiğini belirtmek için yazılan özel işaretçidir. Verinin hemen fiziksel silinmediği LSM ve dağıtık sistemlerde silmenin tüm kopyalara yayılmasını sağlar. Compaction sırasında gerçek temizlik yapılır.","tags":["storage","depolama","lsm","tombstone","silme"]},{"term":"Compaction (LSM)","full":"","definition":"LSM ağaçlarında diskteki sıralı dosyaların (SSTable) birleştirilip yeniden yazılmasıdır. Eski sürümleri ve tombstone'ları temizleyerek okuma performansını ve disk kullanımını iyileştirir. Arka planda çalışır ve yazma yükü oluşturur.","tags":["storage","depolama","lsm","compaction","bakim"]},{"term":"Read Repair","full":"","definition":"Bir okuma sırasında kopyalar arasında tutarsızlık tespit edilirse en güncel değeri geride kalan düğümlere yazarak onarma tekniğidir. Sistem normal okuma trafiğiyle kendini tutarlı hâle getirir. Cassandra gibi sistemlerde kullanılır.","tags":["dagitik","distributed","onarim","consistency","replikasyon"]},{"term":"Hinted Handoff","full":"","definition":"Hedef düğüm geçici olarak erişilemezken yazmanın başka bir düğümde \"hint\" olarak saklanıp düğüm geri döndüğünde iletilmesidir. Geçici arızalar sırasında yazmaların kaybolmamasını sağlar. Eventual consistency'yi destekler.","tags":["dagitik","distributed","handoff","erisilebilirlik","replikasyon"]},{"term":"Eventual Consistency","full":"","definition":"Yeni güncellemeler durursa tüm kopyaların zamanla aynı değere yakınsayacağını garanti eden gevşek tutarlılık modelidir. Kısa süreli tutarsızlıklara izin verir ama yüksek erişilebilirlik ve düşük gecikme sağlar. Birçok NoSQL sisteminin varsayılanıdır.","tags":["dagitik","distributed","consistency","eventual","nosql"]},{"term":"Strong Consistency","full":"","definition":"Bir yazma tamamlandıktan sonra tüm okuyucuların anında en güncel değeri gördüğü tutarlılık modelidir. Kullanımı sezgiseldir ama koordinasyon gerektirdiğinden gecikme ve erişilebilirlik maliyeti yüksektir. Finansal sistemlerde tercih edilir.","tags":["dagitik","distributed","consistency","guclu","tutarlilik"]},{"term":"Linearizability","full":"","definition":"Her işlemin, başlangıcı ile bitişi arasında bir anda gerçekleşmiş gibi görünmesini ve tüm işlemlerin tek bir gerçek zamanlı sıraya oturmasını garanti eden en güçlü tutarlılık düzeyidir. Sistem sanki tek bir kopyaymış gibi davranır. Uygulaması pahalıdır.","tags":["dagitik","distributed","consistency","linearizability","tutarlilik"]},{"term":"Two-Phase Locking (2PL)","full":"Two-Phase Locking","definition":"Bir transaction'ın önce yalnızca lock aldığı (büyüme) sonra yalnızca lock bıraktığı (küçülme) iki aşamalı kilitleme kuralıdır. Bu düzen serileştirilebilirliği garanti eder. Katı biçiminde (Strict 2PL) lock'lar commit'e kadar tutulur.","tags":["kilit","lock","2pl","serializable","eszamanlilik"]},{"term":"Deadlock Detection","full":"","definition":"İki ya da daha fazla transaction'ın birbirinin tuttuğu lock'u karşılıklı beklediği deadlock durumunu tespit eden mekanizmadır. Genellikle bekleme grafiğinde döngü aranarak bulunur ve transaction'lardan biri kurban seçilip geri alınır. Böylece sistem yeniden akmaya başlar.","tags":["kilit","lock","deadlock","kilitlenme","eszamanlilik"]}]},"guide/glossary-3.json":{"terms":[{"term":"Write Amplification","full":"Yazma çarpanı (WA)","definition":"Bir mantıksal yazmanın, depolama katmanında (LSM compaction, sayfa yeniden yazımı, WAL, SSD blok silme) çok daha fazla fiziksel yazmaya yol açması. Yüksek değerler diski aşındırır ve yazma throughput'unu düşürür.","tags":["storage","lsm","performance","ssd"]},{"term":"Read Amplification","full":"Okuma çarpanı (RA)","definition":"Tek bir mantıksal okumanın gerçekte birden fazla fiziksel/dahili okuma gerektirmesi. LSM-tree'lerde bir anahtarın birçok seviyede aranması tipik örnektir; bloom filter ve compaction bunu azaltır.","tags":["storage","lsm","performance"]},{"term":"LSM-tree","full":"Log-Structured Merge Tree","definition":"Yazmaları önce bellekteki bir yapıya (memtable) alıp sıralı bloklar (SSTable) halinde diske akıtan ve arka planda birleştiren (compaction) veri yapısı. Yazma-yoğun yükler için idealdir; RocksDB, Cassandra kullanır.","tags":["storage","lsm","write-heavy"]},{"term":"B+tree","full":"B+ Tree","definition":"İlişkisel veritabanı index'lerinin klasik yapısı. Tüm veri yaprak düğümlerde tutulur, yapraklar bağlı listeyle zincirlenir; nokta ve aralık sorgularında dengeli okuma performansı sağlar.","tags":["index","btree","storage"]},{"term":"Fill Factor","full":"Sayfa doluluk oranı (fillfactor)","definition":"Bir index/tablo sayfasının başlangıçta ne kadar dolduralacağını belirten oran. Boş alan bırakmak gelecekteki güncelleme/eklemelerde page split'i azaltır; PG'de fillfactor, MSSQL'de fill factor.","tags":["index","storage","tuning"]},{"term":"HOT Update","full":"Heap-Only Tuple Update","definition":"PostgreSQL'de indekslenmiş hiçbir sütunu değiştirmeyen güncellemenin yeni satır sürümünü aynı sayfada oluşturması ve index'leri güncellememesi. Index bloat'ını azaltır ve güncelleme maliyetini düşürür.","tags":["postgres","mvcc","update","performance"]},{"term":"Bloat","full":"Tablo/index içinde ölü alan birikimi","definition":"MVCC motorlarında temizlenmemiş dead tuple'lar veya boş sayfalar nedeniyle tablo/index'in gereğinden fazla yer kaplaması. Tarama maliyetini artırır; VACUUM/reorg ile geri kazanılır.","tags":["mvcc","postgres","maintenance","bloat"]},{"term":"Autovacuum","full":"Otomatik VACUUM","definition":"PostgreSQL'de dead tuple temizliğini, istatistik toplamayı ve transaction ID donmayı arka planda otomatik yürüten süreç. İş yüküne göre eşik ve maliyet parametreleriyle ayarlanır.","tags":["postgres","vacuum","maintenance"]},{"term":"Freeze / Wraparound","full":"Transaction ID Freeze / Wraparound","definition":"PostgreSQL'de 32-bit transaction ID'lerin dönmesini (wraparound) önlemek için eski satırların 'donmuş' (frozen) olarak işaretlenmesi. İhmal edilirse veritabanı veri kaybını önlemek için yazmayı durdurur.","tags":["postgres","mvcc","vacuum","wraparound"]},{"term":"Checkpoint","full":"Dirty page'lerin diske yazıldığı kurtarma başlangıç noktası","definition":"Bellekteki dirty page'lerin diske yazıldığı ve kurtarmanın başlayacağı noktanın işaretlendiği olay. Crash recovery süresini kısaltır; sıklığı I/O tepe noktası ile kurtarma süresi arasında ödünleşimdir.","tags":["recovery","wal","internals","checkpoint"]},{"term":"Fuzzy Checkpoint","full":"Zamana yayılan, arka planda yazan checkpoint","definition":"Sistemi durdurmadan, dirty page'leri zamana yayarak sürekli/arka planda yazan checkpoint türü. Ani I/O dalgalanmasını (checkpoint spike) önleyerek yanıt süresini öngörülebilir kılar.","tags":["recovery","checkpoint","internals"]},{"term":"Redo","full":"Redo Log / Roll Forward","definition":"Bir işlemin yaptığı değişiklikleri kurtarma sırasında yeniden uygulamak (roll forward) için tutulan kayıt. Commit edilmiş ama diske inmemiş değişiklikleri crash sonrası geri getirir.","tags":["recovery","oracle","wal","redo"]},{"term":"Undo","full":"Undo Log / Geri Alma","definition":"Bir transaction'ı geri alabilmek (rollback) ve MVCC için eski satır sürümünü sağlamak amacıyla tutulan kayıt. Oracle/InnoDB'de eski sürümler undo segmentinden okunur.","tags":["mvcc","oracle","innodb","undo","rollback"]},{"term":"MVCC Snapshot","full":"Tutarlı okuma görünümü (read view)","definition":"Bir transaction'ın tutarlı bir okuma görebilmesi için hangi satır sürümlerinin görünür olduğunu belirleyen mantıksal zaman görüntüsü. Transaction başında veya ifade başında alınır (isolation seviyesine göre).","tags":["mvcc","concurrency","isolation","snapshot"]},{"term":"Isolation Anomaly","full":"İzolasyon Anomalileri","definition":"Eşzamanlı transaction'ların yetersiz izolasyonda ürettiği tutarsızlıklar: dirty read (commit edilmemiş veri okuma), non-repeatable read (aynı satırın değişmesi), phantom (yeni satırların belirmesi) ve write-skew (bağımsız görünen yazmaların birlikte kuralı bozması).","tags":["isolation","concurrency","anomaly","acid"]},{"term":"2PL","full":"Two-Phase Locking","definition":"Serileştirilebilirliği lock'larla sağlayan protokol: bir transaction önce yalnızca lock alır (growing), belirli bir noktadan sonra yalnızca serbest bırakır (shrinking). Strict 2PL lock'ları commit'e kadar tutar.","tags":["concurrency","locking","serializable","2pl"]},{"term":"MVTO","full":"Multi-Version Timestamp Ordering","definition":"İşlemlere zaman damgası atayıp çok sürümlü veride okuma/yazmaları bu sıraya göre düzenleyen eşzamanlılık kontrol yöntemi. Lock yerine zaman damgasıyla çakışmaları çözer.","tags":["concurrency","mvcc","timestamp","protocol"]},{"term":"Mutex","full":"Mutual Exclusion","definition":"Bir kaynağa aynı anda tek bir thread'in erişmesini garanti eden karşılıklı dışlama ilkeli. Veritabanlarında paylaşılan bellek yapılarının korunmasında latch'e benzer rol oynar.","tags":["concurrency","internals","mutex"]},{"term":"Spinlock","full":"Spinlock","definition":"Lock serbest kalana kadar thread'i uyutmak yerine döngüde bekleten (busy-wait) çok kısa süreli lock. Çok kısa kritik bölümlerde ucuzdur; çekişme artınca CPU'yu boşa yakar.","tags":["concurrency","internals","spinlock","cpu"]},{"term":"Buffer Pool","full":"Buffer Pool / Buffer Cache","definition":"Sık erişilen veri sayfalarını bellekte tutarak disk I/O'sunu azaltan önbellek. Eviction algoritması (LRU, clock-sweep) hangi sayfanın atılacağını belirler; boyutu çalışma kümesine göre ayarlanır.","tags":["memory","cache","internals","buffer"]},{"term":"Working Set","full":"Çalışma Kümesi","definition":"Bir iş yükünün belirli bir zaman penceresinde aktif olarak eriştiği veri kümesi. Buffer pool bu kümeyi karşılayacak boyutta olduğunda fiziksel I/O en aza iner; toplam veri boyutundan farklıdır.","tags":["memory","cache","sizing","performance"]},{"term":"Skew","full":"Veri Çarpıklığı","definition":"Değerlerin eşit değil, bazılarının çok daha sık dağılması durumu. Kardinalite tahminini, parameter sniffing'i ve sharding hot-spot'unu tetikleyen temel etkendir; histogramla ele alınır.","tags":["statistics","distribution","skew","performance"]},{"term":"Plan Cache","full":"Plan Önbelleği","definition":"Derlenmiş yürütme planlarının yeniden kullanım için saklandığı bellek alanı. Hard parse maliyetini önler ama parameter sniffing ve bayat plan riskleri getirir; MSSQL plan cache, Oracle library cache.","tags":["optimizer","plan-cache","parsing"]},{"term":"Hard/Soft Parse","full":"Hard Parse / Soft Parse","definition":"Hard parse: SQL'in sıfırdan ayrıştırılıp optimize edilip plan üretilmesi (pahalı). Soft parse: önbellekte var olan planın bulunup yeniden kullanılması (ucuz). Bind değişkeni soft parse oranını artırır.","tags":["parsing","oracle","performance","plan-cache"]},{"term":"Connection Storming","full":"Bağlantı Fırtınası","definition":"Kısa sürede çok sayıda yeni veritabanı bağlantısının aynı anda açılmaya çalışılması. Bağlantı kurma maliyeti ve bellek baskısıyla veritabanını boğar; genelde havuz tükenmesi veya yeniden bağlanma dalgasından doğar.","tags":["connections","pooling","overload"]},{"term":"Thundering Herd","full":"Thundering Herd Problemi","definition":"Bir olay (cache süresi bitişi, lock serbest kalması, servis geri gelmesi) sonrası çok sayıda istemcinin aynı anda aynı kaynağa yüklenmesi. Backpressure, jitter ve tek-uçuş (single-flight) desenleriyle hafifletilir.","tags":["concurrency","cache","overload","resilience"]},{"term":"Backpressure","full":"Üreticiyi yavaşlatan akış kontrolü","definition":"Bir sistemin, kaldıramayacağı yükü kabul etmek yerine üreticiyi yavaşlatması veya reddetmesi (kuyruk sınırı, hız limiti). Aşırı yük altında çökmek yerine kontrollü zarafetle bozulmayı (graceful degradation) sağlar.","tags":["resilience","flow-control","overload"]},{"term":"Lease","full":"Süreli liderlik/kaynak hakkı","definition":"Bir düğüme belirli bir süre için verilen ve süresi dolunca otomatik geçersizleşen liderlik/kaynak hakkı. Zaman sınırlı olduğundan takılı kalan düğümün sonsuza dek lider kalmasını önler.","tags":["distributed","leader-election","lease"]},{"term":"Read-Your-Writes","full":"Read-Your-Writes Consistency","definition":"Bir kullanıcının kendi yazdığı değişikliği hemen sonraki okumasında mutlaka görmesini garantileyen oturum tutarlılığı. Replikaya yönlendirmede lag varsa özel yönlendirme/token ile sağlanır.","tags":["distributed","consistency","session","replication"]},{"term":"Causal Consistency","full":"Nedensel Tutarlılık","definition":"Nedensel olarak ilişkili işlemlerin tüm düğümlerde aynı sırada görülmesini garantileyen, eventual'dan güçlü tutarlılık modeli. İlişkisiz (concurrent) işlemler farklı sırada görülebilir.","tags":["distributed","consistency","causal"]},{"term":"CAP","full":"Consistency, Availability, Partition tolerance","definition":"Ağ bölünmesi (partition) yaşandığında bir dağıtık sistemin tutarlılık ile erişilebilirlikten yalnızca birini seçebileceğini söyleyen teorem. Bölünme yokken bu ödünleşim zorunlu değildir.","tags":["distributed","cap","consistency","theory"]},{"term":"PACELC","full":"PACELC Theorem","definition":"CAP'i genişleten model: bölünme (P) halinde Availability/Consistency, aksi halde (E, else) Latency/Consistency arasında seçim yapılır. Normal çalışmadaki gecikme-tutarlılık ödünleşimini de kapsar.","tags":["distributed","cap","pacelc","latency","theory"]},{"term":"Hot Partition","full":"Hotspot / aşırı yüklenen partition","definition":"Yükün orantısız biçimde tek bir bölüme/shard'a yığılması. Düşük kardinaliteli, zamansal veya artan shard anahtarından doğar; o düğümü darboğaza sokarak ölçeklenmeyi durdurur.","tags":["distributed","sharding","hot-spot","skew"]},{"term":"Columnstore","full":"Sütun Tabanlı Depolama","definition":"Verinin satır değil sütun bazında saklandığı format. Analitik sorgularda yalnızca gereken sütunları okuyup yüksek sıkıştırma ve vektörize yürütme sağlar; OLAP için idealdir.","tags":["olap","columnar","analytics","compression"]},{"term":"Vectorized Execution","full":"Vektörize Yürütme","definition":"Sorgu operatörlerinin satır-satır yerine bir seferde bir sütun bloğu (batch) üzerinde çalışması. CPU önbelleği ve SIMD kullanımını artırarak analitik sorgu throughput'unu büyük ölçüde yükseltir.","tags":["olap","execution","performance","columnar"]},{"term":"Zone Map / Min-Max","full":"Zone Map / Min-Max Index","definition":"Her veri bloğu için sütunun minimum ve maksimum değerini saklayan hafif meta veri. Sorgu koşuluyla eşleşmeyen blokları hiç okumadan atlayarak (block skipping) tarama maliyetini düşürür.","tags":["olap","index","pruning","columnar"]},{"term":"Logical Replication","full":"Mantıksal Replikasyon","definition":"Fiziksel bloklar yerine satır düzeyi değişiklikleri (mantıksal olay) yayınlayıp abone eden replikasyon. Seçmeli tablo, sürümler arası ve çift yönlü senaryolara izin verir; PG publication/subscription bunu sağlar.","tags":["replication","postgres","logical","cdc"]},{"term":"GTID","full":"Global Transaction Identifier","definition":"MySQL replikasyonunda her transaction'a atanan küresel benzersiz kimlik. Replika konumunu dosya/ofset yerine transaction kimliğiyle izleyerek failover ve yeniden yapılandırmayı güvenli/basit kılar.","tags":["mysql","replication","gtid","failover"]},{"term":"High Water Mark","full":"HWM — segmentin kullanılmış en üst blok sınırı","definition":"Bir segmentte/tabloda şimdiye dek kullanılmış en yüksek blok sınırı. Oracle'da full table scan bu sınıra kadar tarar; kitlesel silme sonrası düşmediği için boş blokların taranmasına ve şişmeye yol açabilir.","tags":["oracle","storage","internals","scan"]}]},"playbooks/playbooks.json":{"schemaVersion":1,"playbooks":[{"id":"db-slow","title":"Veritabanı yavaş","icon":"🐢","symptom":"Uygulama genelinde yavaşlık; sorgular normalden çok uzun sürüyor, kullanıcılar şikayetçi.","steps":[{"title":"Önce 'yavaş olan ne' sorusunu netleştir","detail":"Her şey mi yavaş yoksa belirli bir sorgu/ekran mı? Ne zaman başladı, bir deploy/patch/veri artışı ile örtüşüyor mu? Sistem genelinde mi yoksa tek DB'de mi? Bu, aramayı CPU/IO/lock/plan değişimi eksenlerinden birine daraltır."},{"title":"Aktif oturumları ve wait event'leri gör","detail":"O an ne çalışıyor ve ne bekliyor? Yoğun bir wait event (IO, lock, log) darboğazı işaret eder.","engines":{"oracle":"SELECT sid, username, status, event, sql_id FROM v$session WHERE status='ACTIVE' AND type='USER';","postgres":"SELECT pid, state, wait_event_type, wait_event, query FROM pg_stat_activity WHERE state='active';","mysql":"SELECT id, user, command, time, state, info FROM information_schema.processlist WHERE command<>'Sleep' ORDER BY time DESC;","mssql":"SELECT session_id, status, wait_type, wait_time, blocking_session_id FROM sys.dm_exec_requests WHERE session_id IN (SELECT session_id FROM sys.dm_exec_sessions WHERE is_user_process = 1);","mongodb":"db.currentOp({ active: true, secs_running: { $gt: 1 } })","redis":"SLOWLOG GET 10"}},{"title":"Bloklama var mı bak","detail":"Yavaşlığın en sık nedeni birinin diğerlerini bloklamasıdır. Bloklayan oturumu bulup zincirin başını tespit et.","engines":{"oracle":"SELECT blocking_session, sid, seconds_in_wait, event FROM v$session WHERE blocking_session IS NOT NULL;","postgres":"SELECT pid, pg_blocking_pids(pid) AS blocked_by, query FROM pg_stat_activity WHERE cardinality(pg_blocking_pids(pid))>0;","mysql":"SELECT * FROM sys.innodb_lock_waits\\G","mssql":"SELECT session_id, blocking_session_id, wait_type FROM sys.dm_exec_requests WHERE blocking_session_id<>0;"}},{"title":"En maliyetli sorguları çıkar","detail":"Kaynağı en çok yiyen ilk 10 sorguyu bul. Genellikle sorunun %90'ı birkaç sorgudan gelir.","engines":{"oracle":"SELECT sql_id, elapsed_time/1e6 sec, executions, sql_text FROM v$sql ORDER BY elapsed_time DESC FETCH FIRST 10 ROWS ONLY;","postgres":"SELECT calls, total_exec_time, mean_exec_time, query FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 10;","mysql":"SELECT digest_text, count_star, sum_timer_wait/1e12 sec FROM performance_schema.events_statements_summary_by_digest ORDER BY sum_timer_wait DESC LIMIT 10;","mssql":"SELECT TOP 10 total_elapsed_time/execution_count avg_us, execution_count, SUBSTRING(t.text,1,200) FROM sys.dm_exec_query_stats qs CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) t ORDER BY total_elapsed_time DESC;"}},{"title":"Şüpheli sorgunun planını incele","detail":"Yavaş sorgu için EXPLAIN al. Tam tablo taraması (full scan), eksik index, kötü join sırası veya bayat istatistik ara. Plan aniden değiştiyse istatistik toplamayı düşün.","engines":{"oracle":"SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('&sql_id', NULL, 'ALLSTATS LAST'));","postgres":"EXPLAIN (ANALYZE, BUFFERS) <sorgu>;","mysql":"EXPLAIN ANALYZE <sorgu>;","mssql":"SET STATISTICS PROFILE ON; <sorgu>; SET STATISTICS PROFILE OFF;","mongodb":"db.koleksiyon.find({...}).explain('executionStats')  // COLLSCAN mı IXSCAN mı?"}},{"title":"Sistem kaynaklarını doğrula","detail":"OS düzeyinde CPU, IO bekleme (iowait), bellek ve disk doluluğuna bak. Cache hit oranını kontrol et; düşükse bellek darboğazı olabilir. Sorun DB dışında (disk dolu, komşu VM) olabilir."},{"title":"Hızlı çözüm mü kalıcı çözüm mü karar ver","detail":"Acil rahatlama için: kaçak sorguyu kill et, eksik index'i ekle, istatistik topla. Kalıcı için: sorguyu/index'i yeniden tasarla, bellek ayarlarını düzelt, plan kararlılığını sağla (baseline/hint)."}],"related":["active-sessions","blocking-sessions","top-slow-queries","explain-plan","cache-hit-ratio"]},{"id":"disk-full","title":"Disk / tablespace doldu","icon":"💽","symptom":"'unable to extend', 'disk full', 'log file full' hataları; yazma işlemleri duruyor.","steps":[{"title":"Panik yapma, önce neyin dolduğunu bul","detail":"Data file mı, transaction log mu, arşiv/redo alanı mı, temp mi, yoksa OS diski mi? Yanlış yeri temizlemek işe yaramaz. OS'te df -h ile diski, DB içinde alan view'larını kontrol et."},{"title":"Doluluğu ölç","detail":"Hangi tablespace/dosya/dizin dolu, yüzde kaç?","engines":{"oracle":"SELECT d.tablespace_name, ROUND((1-(d.alloc-NVL(f.free,0))/d.maxb)*100,1) pct_free FROM (SELECT tablespace_name, SUM(bytes) alloc, SUM(GREATEST(bytes,maxbytes)) maxb FROM dba_data_files GROUP BY tablespace_name) d LEFT JOIN (SELECT tablespace_name, SUM(bytes) free FROM dba_free_space GROUP BY tablespace_name) f ON f.tablespace_name = d.tablespace_name;","postgres":"SELECT datname, pg_size_pretty(pg_database_size(datname)) FROM pg_database ORDER BY 2 DESC; -- disk için OS df","mysql":"SELECT table_schema, ROUND(SUM(data_length+index_length)/1048576,1) mb FROM information_schema.tables GROUP BY table_schema ORDER BY mb DESC;","mssql":"SELECT name, size/128.0 size_mb, size/128.0 - CAST(FILEPROPERTY(name,'SpaceUsed') AS int)/128.0 free_mb FROM sys.database_files;","redis":"INFO memory  # used_memory vs maxmemory"}},{"title":"En büyük tüketicileri bul","detail":"En büyük tabloları/segmentleri, en büyük log/arşiv dosyalarını, gereksiz eski yedekleri tespit et. Çoğu zaman tek bir kaçak tablo veya birikmiş arşiv log suçludur.","engines":{"oracle":"SELECT segment_name, bytes/1048576 mb FROM dba_segments ORDER BY bytes DESC FETCH FIRST 10 ROWS ONLY;","postgres":"SELECT relname, pg_size_pretty(pg_total_relation_size(relid)) FROM pg_statio_user_tables ORDER BY pg_total_relation_size(relid) DESC LIMIT 10;","mssql":"SELECT TOP 10 OBJECT_NAME(object_id), SUM(reserved_page_count)*8/1024 mb FROM sys.dm_db_partition_stats GROUP BY object_id ORDER BY mb DESC;"}},{"title":"Güvenli alan kazan (hızlı)","detail":"Log/arşiv için: yedeğini alıp eski arşiv logları/backup'ları temizle (Oracle: RMAN delete archivelog; MSSQL: log yedeği alıp log'u küçült). Redis'te maxmemory-policy ve eviction. ASLA canlı data file'ı elle silme; ASLA yedeksiz arşiv log silme."},{"title":"Kapasiteyi kalıcı büyüt","detail":"Data file'a alan ekle veya autoextend aç (Oracle: ALTER DATABASE DATAFILE ... AUTOEXTEND ON MAXSIZE), diski büyüt, tablespace ekle. Kök nedeni çöz: log döngüsü, arşiv temizleme job'u, retention politikası."},{"title":"Tekrarı önle","detail":"Disk doluluk alarmı kur (%80/%90 eşik), arşiv/log temizleme otomasyonu, retention politikasını netleştir. Bu playbook'u bir daha açmak zorunda kalma."}],"related":["free-space","largest-tables","database-size","reclaim-space","last-backup-status"]},{"id":"blocking","title":"Bloklama & lock krizi","icon":"🔒","symptom":"Sorgular takılı kalıyor, 'lock wait timeout', birçok oturum bekliyor ama CPU düşük.","steps":[{"title":"Bloklama zincirinin başını (root blocker) bul","detail":"Kimin kimi bloklağını çıkar; asıl suçlu, kendisi hiçbir şey beklemeyen ama başkalarını bekleten oturumdur. Zincirin en tepesindeki oturuma odaklan.","engines":{"oracle":"SELECT blocking_session, sid, serial#, username, seconds_in_wait, sql_id FROM v$session WHERE blocking_session IS NOT NULL ORDER BY seconds_in_wait DESC;","postgres":"SELECT pid, usename, pg_blocking_pids(pid) blocked_by, state, query FROM pg_stat_activity WHERE cardinality(pg_blocking_pids(pid))>0;","mysql":"SELECT waiting_pid, waiting_query, blocking_pid, blocking_query FROM sys.innodb_lock_waits;","mssql":"SELECT session_id, blocking_session_id, wait_type, wait_resource FROM sys.dm_exec_requests WHERE blocking_session_id<>0;","mongodb":"db.currentOp({ waitingForLock: true })"}},{"title":"Root blocker ne yapıyor anla","detail":"Açık ama commit edilmemiş bir transaction mı? Uygulama 'idle in transaction' durumunda mı bıraktı? Uzun bir batch mi? Kör kill etmeden önce ne olduğunu anla — belki bitmek üzeredir.","engines":{"oracle":"SELECT s.sid, s.prev_sql_id, t.start_time, t.used_ublk FROM v$transaction t JOIN v$session s ON t.ses_addr=s.saddr;","postgres":"SELECT pid, state, xact_start, now()-xact_start age, query FROM pg_stat_activity WHERE pid=<root_pid>;"}},{"title":"Karar: bekle, uygulamadan çöz, ya da kill","detail":"Bitmek üzereyse bekle. Uygulama commit/rollback yapabilecekse onu tetikle. Aksi halde ve iş duruyorsa root blocker'ı sonlandır. Kill etmeden önce etkisini (rollback süresi, veri) düşün."},{"title":"Gerekirse root blocker'ı sonlandır","detail":"Yalnızca zincirin başındaki oturumu kill et; alttakiler otomatik serbest kalır.","engines":{"oracle":"ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE;","postgres":"SELECT pg_terminate_backend(<root_pid>);","mysql":"KILL <root_id>;","mssql":"KILL <root_session_id>;","mongodb":"db.killOp(<opid>)"}},{"title":"Kök nedeni çöz","detail":"Eksik index geniş lock'lara yol açıyor olabilir; uygulama transaction'ları çok uzun tutuyor olabilir; yanlış izolasyon seviyesi. Index ekle, transaction'ları kısalt, 'idle in transaction timeout' ayarla, uygun izolasyon seç."}],"related":["blocking-sessions","kill-session","open-transactions"]},{"id":"connection-storm","title":"Bağlantı fırtınası (too many connections)","icon":"🌊","symptom":"'too many connections', 'ORA-00018', 'remaining connection slots reserved' — yeni bağlantılar reddediliyor.","steps":[{"title":"Mevcut durumu ölç","detail":"Kaç bağlantı var, limit ne, ne kadarı aktif ne kadarı idle?","engines":{"oracle":"SELECT COUNT(*) total, SUM(CASE WHEN status='ACTIVE' THEN 1 ELSE 0 END) active FROM v$session WHERE type='USER';","postgres":"SELECT count(*), state FROM pg_stat_activity WHERE backend_type = 'client backend' GROUP BY state;","mysql":"SHOW STATUS LIKE 'Threads_connected'; SHOW VARIABLES LIKE 'max_connections';","mssql":"SELECT COUNT(*), status FROM sys.dm_exec_sessions WHERE is_user_process=1 GROUP BY status;","redis":"INFO clients"}},{"title":"Kaynağı tespit et: kim/nereden","detail":"Hangi uygulama/host/kullanıcı bağlantıları açıyor? Genelde tek bir uygulama sunucusunun pool'u patlamış ya da bağlantı sızıntısı vardır (idle in transaction yığını).","engines":{"postgres":"SELECT client_addr, usename, state, count(*) FROM pg_stat_activity WHERE backend_type = 'client backend' GROUP BY 1,2,3 ORDER BY 4 DESC;","mysql":"SELECT host, user, count(*) FROM information_schema.processlist GROUP BY host, user ORDER BY 3 DESC;","mssql":"SELECT host_name, program_name, login_name, COUNT(*) FROM sys.dm_exec_sessions WHERE is_user_process=1 GROUP BY host_name, program_name, login_name ORDER BY 4 DESC;"}},{"title":"Acil nefes aldır","detail":"Uzun süren idle/idle-in-transaction bağlantıları temizle. Gerekirse suçlu uygulamanın bağlantılarını topluca kes. Admin girişi için ayrılmış slot'u kullan (PG superuser_reserved_connections)."},{"title":"Doğru çözüm: connection pooling","detail":"max_connections'ı sınırsızca artırmak bellek tüketir ve sorunu erteler. Doğru çözüm uygulama tarafında bir connection pool (HikariCP, PgBouncer, ProxySQL) ve makul pool boyutudur. Pool boyutu genelde (çekirdek*2 + disk sayısı) civarıdır — Araçlar > Connection Pool hesaplayıcısına bak."},{"title":"Sızıntıyı ve tekrarını önle","detail":"Uygulamada bağlantıların kapatıldığından emin ol (finally/using). idle_in_transaction_session_timeout, wait_timeout ayarla. Bağlantı sayısı için alarm kur."}],"related":["connection-count","kill-session","open-transactions"]},{"id":"replication-lag","title":"Replikasyon gecikmesi / durdu","icon":"🔁","symptom":"Standby/replika geride kalıyor ya da tamamen durdu; okuma replikaları bayat veri gösteriyor.","steps":[{"title":"Gecikme ne kadar, artıyor mu sabit mi","detail":"Lag saniye/byte cinsinden ne? Sabit bir offset mi yoksa sürekli büyüyor mu? Büyüyorsa replika uygulamaya yetişemiyordur; sabitse anlık bir tıkanma olmuştur.","engines":{"oracle":"SELECT name, value, unit FROM v$dataguard_stats WHERE name LIKE '%lag%';","postgres":"SELECT client_addr, state, write_lag, flush_lag, replay_lag FROM pg_stat_replication;","mysql":"SHOW REPLICA STATUS\\G  -- Seconds_Behind_Source","mssql":"SELECT ar.replica_server_name, drs.redo_queue_size, drs.log_send_queue_size FROM sys.dm_hadr_database_replica_states drs JOIN sys.availability_replicas ar ON drs.replica_id=ar.replica_id;","redis":"INFO replication  # master_repl_offset vs slave offset"}},{"title":"Replikasyon çalışıyor mu, hata var mı","detail":"IO/SQL thread durumu, apply süreci, bağlantı kopmuş mu? Bir hata varsa (ör. çakışan satır, eksik tablo) apply durmuştur; hata mesajını oku.","engines":{"mysql":"SHOW REPLICA STATUS\\G  -- Replica_IO_Running / Replica_SQL_Running / Last_Error","postgres":"SELECT status, last_msg_receipt_time, latest_end_lsn FROM pg_stat_wal_receiver;  -- standby üzerinde","oracle":"SELECT process, status, sequence#, thread# FROM v$managed_standby WHERE process LIKE 'MRP%' OR process LIKE 'RFS%';"}},{"title":"Darboğazı bul","detail":"Neden yetişemiyor? Tek thread apply + ağır yazma yükü mü (PG/MySQL çoğunlukla seri apply), standby'da IO darboğazı mı, ağ mı, uzun bir sorgu apply'ı bloklamış mı (PG hot_standby_feedback / recovery conflict)?"},{"title":"Gecikmeyi kapat","detail":"Apply'ı hızlandır: paralel apply aç (MySQL replica_parallel_workers — 8.0.26 öncesinde slave_parallel_workers, PG yoktur ama recovery ayarları), standby IO'sunu iyileştir, apply'ı bloklayan sorguyu çöz. Hata ile durduysa: hatayı düzelt (çakışan satırı elle çöz) ve replikasyonu devam ettir."},{"title":"Kopmuşsa yeniden kur","detail":"Replika çok geride/bozuksa yeniden senkronize etmek en temizidir: taze yedekten (PG pg_basebackup, MySQL clone/xtrabackup, Oracle RMAN duplicate) standby'ı yeniden kur. Kritik: yeniden kurmadan önce nedeni bul, yoksa tekrar eder."}],"related":["replication-status","list-replicas","promote-failover"]},{"id":"high-cpu","title":"Yüksek CPU","icon":"🔥","symptom":"Sunucu CPU'su %90+; sistem geneli yavaş, load average yüksek.","steps":[{"title":"CPU'yu DB mi yiyor doğrula","detail":"OS'te top/mpstat ile CPU'yu tüketen sürecin gerçekten DB olduğunu doğrula. Bazen komşu bir süreç veya yedek/antivirüs yiyor. iowait yüksekse sorun CPU değil disk'tir."},{"title":"En çok CPU harcayan sorguları bul","detail":"CPU zamanına göre sıralı ilk sorguları çıkar. Genelde birkaç sorgu (kötü plan, full scan, eksik index) CPU'yu yakar.","engines":{"oracle":"SELECT sql_id, cpu_time/1e6 cpu_sec, executions, sql_text FROM v$sql ORDER BY cpu_time DESC FETCH FIRST 10 ROWS ONLY;","postgres":"SELECT query, calls, total_exec_time, mean_exec_time FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 10;","mysql":"SELECT digest_text, count_star, sum_timer_wait/1e12 sec FROM performance_schema.events_statements_summary_by_digest ORDER BY sum_timer_wait DESC LIMIT 10;","mssql":"SELECT TOP 10 total_worker_time/execution_count avg_cpu, execution_count, SUBSTRING(t.text,1,200) FROM sys.dm_exec_query_stats q CROSS APPLY sys.dm_exec_sql_text(q.sql_handle) t ORDER BY total_worker_time DESC;"}},{"title":"Plan / index sorunu mu bak","detail":"Suçlu sorgunun planını al. Full table scan, nested loop patlaması, hash join spill, ya da parametre sniffing/bayat istatistik kaynaklı kötü plan CPU yakar. Index ekle veya istatistik topla."},{"title":"Acil rahatlat","detail":"Kaçak sorguyu kill et, gerekiyorsa Resource Manager/Resource Governor ile sınırla. Ani başlayan yükte son deploy'u/parametre değişimini gözden geçir."},{"title":"Kalıcı çöz","detail":"Sorguyu/index'i düzelt, plan kararlılığı sağla, istatistik toplama işini planla. Sürekli %100 ise ölçeklendirme (CPU ekleme, read replica'ya okuma dağıtma) gerekebilir."}],"related":["top-slow-queries","explain-plan","active-sessions","update-statistics"]},{"id":"memory-pressure","title":"Bellek baskısı / OOM","icon":"🧠","symptom":"OOM killer süreci öldürüyor, 'out of memory', düşük cache hit, aşırı swap, Redis 'OOM command not allowed'.","steps":[{"title":"Belleği kim tüketiyor","detail":"DB'nin ayrılmış belleği (buffer pool/SGA) mı, oturum başı bellek (PGA/sort/work_mem) mi, yoksa OS geneli mi? OS'te free/vmstat, DB içinde bellek view'larına bak.","engines":{"oracle":"SELECT component, current_size/1048576 mb FROM v$memory_dynamic_components WHERE current_size>0;","postgres":"SHOW shared_buffers; SHOW work_mem; -- work_mem * bağlantı * sort sayısı toplamı patlayabilir","mysql":"SHOW VARIABLES LIKE 'innodb_buffer_pool_size'; SHOW STATUS LIKE 'Innodb_buffer_pool%';","redis":"INFO memory  # used_memory, maxmemory, mem_fragmentation_ratio"}},{"title":"Ayar mı yük mü ayır et","detail":"Bellek ayarları toplamı fiziksel RAM'i aşıyor mu (over-commit)? shared_buffers + (work_mem * eşzamanlılık) hesabını yap. Yoksa anlık bir yük mü (dev bir sort/hash, çok bağlantı)?"},{"title":"Redis'e özel: eviction ve fragmentation","detail":"used_memory maxmemory'ye dayandıysa maxmemory-policy'yi kontrol et (noeviction ise yazma reddedilir). mem_fragmentation_ratio yüksekse MEMORY PURGE / activedefrag. Büyük anahtarları --bigkeys ile bul.","engines":{"redis":"CONFIG GET maxmemory-policy\nMEMORY DOCTOR\nredis-cli --bigkeys"}},{"title":"Acil rahatlat","detail":"Bellek yiyen kaçak sorguyu/oturumu kill et, work_mem gibi oturum belleğini geçici düşür, gereksiz bağlantıları kes. Swap'a düşmüşse öncelik swap'tan çıkmak."},{"title":"Doğru boyutlandır","detail":"Araçlar > Bellek/Buffer Pool hesaplayıcısı ile RAM'i doğru dağıt. Genel kural: adanmış sunucuda buffer pool/SGA ~%70-80 RAM; oturum belleğini eşzamanlılıkla çarparak topla ve RAM'i aşma. Gerekirse RAM ekle."}],"related":["cache-hit-ratio","show-config-param","reclaim-space"]},{"id":"log-growth","title":"Transaction log / undo şişmesi","icon":"📈","symptom":"Transaction log dosyası ya da undo/redo alanı hızla büyüyor; 'log full', 'ORA-01555 snapshot too old', 'unable to extend undo'.","steps":[{"title":"Log'u büyüten açık transaction'ı bul","detail":"Log/undo, en eski aktif transaction bitene kadar temizlenemez. Tek bir uzun açık transaction tüm log'u tutuyor olabilir.","engines":{"oracle":"SELECT s.sid, s.username, t.start_time, t.used_ublk FROM v$transaction t JOIN v$session s ON t.ses_addr=s.saddr ORDER BY t.start_time;","postgres":"SELECT pid, state, xact_start, now()-xact_start age, query FROM pg_stat_activity WHERE xact_start IS NOT NULL ORDER BY xact_start;","mysql":"SELECT trx_id, trx_started, trx_mysql_thread_id FROM information_schema.innodb_trx ORDER BY trx_started;","mssql":"DBCC OPENTRAN;"}},{"title":"Motora özel kök nedeni anla","detail":"MSSQL: FULL recovery modelinde log yedeği alınmıyorsa log sonsuz büyür. Oracle: ORA-01555 undo retention/boyutu yetersiz + uzun sorgu. PG: replication slot ilerlemiyorsa WAL birikir; long transaction VACUUM'u engeller."},{"title":"MSSQL log'u için doğru aksiyon","detail":"Log yedeği al (BACKUP LOG) — bu log'u yeniden kullanılabilir yapar. Recovery model gerçekten SIMPLE olmalıysa değiştir. Sonra gerekiyorsa (ve sadece gerekiyorsa) log'u küçült.","engines":{"mssql":"BACKUP LOG [DB] TO DISK='C:\\yedek\\DB_log.trn';\n-- Sonra gerekiyorsa: DBCC SHRINKFILE (N'DB_log', 512);"}},{"title":"PG WAL / replication slot kontrolü","detail":"İlerlemeyen (inactive) bir replication slot WAL birikimine yol açar. Silmeden önce slot'un sahibini doğrula (slot_type, database, plugin): geçici olarak kopmuş bir standby ya da logical abone/CDC (ör. Debezium) olabilir. Slot düşürülürse bağlı standby yeniden kurulmalı, abone/CDC tarafı yeniden senkronize edilmelidir. Gerçekten kullanılmıyorsa düşür; kalıcı koruma için max_slot_wal_keep_size (PG13+) ile üst sınır koy.","engines":{"postgres":"SELECT slot_name, active, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) retained FROM pg_replication_slots ORDER BY 3 DESC;\n-- Gereksizse: SELECT pg_drop_replication_slot('slot_adi');"}},{"title":"Undo/retention'ı ayarla ve tekrarı önle","detail":"Oracle: UNDO tablespace'i büyüt, undo_retention'ı uzun sorgulara göre ayarla (veya RETENTION GUARANTEE). Uygulamada uzun açık transaction'ları engelle. Log yedek job'unun çalıştığını izle."}],"related":["open-transactions","reclaim-space","last-backup-status"]},{"id":"deadlocks","title":"Deadlock analizi","icon":"♻️","symptom":"'deadlock detected', 'ORA-00060', 'chosen as deadlock victim' — transaction'lar birbirini kilitleyip biri iptal ediliyor.","steps":[{"title":"Deadlock normaldir ama sık olmamalı","detail":"DB deadlock'u tespit edip birini kurban seçerek çözer — bu tasarım gereğidir. Amaç sıklığı azaltmak. Uygulama kurban seçilen transaction'ı yeniden denemeli (retry). Önce deadlock grafiğini yakala."},{"title":"Deadlock grafiğini/detayını al","detail":"Hangi iki (veya daha çok) oturum, hangi kaynaklar, hangi lock modları çakıştı?","engines":{"oracle":"-- Alert log'daki trace dosyasına bak (deadlock graph). Ayrıca:\nSELECT * FROM dba_hist_active_sess_history WHERE event LIKE 'enq: TX%' ORDER BY sample_time DESC;","postgres":"-- log_lock_waits=on ve deadlock detayı postgresql.log içinde. deadlock_timeout ayarını kontrol et.","mysql":"SHOW ENGINE INNODB STATUS\\G  -- LATEST DETECTED DEADLOCK bölümü","mssql":"-- system_health Extended Event oturumunda deadlock XML'i (ring_buffer, son olaylar):\nSELECT x.ev.value('@timestamp','datetime2') AS zaman, x.ev.query('.') AS deadlock_xml\nFROM (SELECT CAST(t.target_data AS XML) td FROM sys.dm_xe_session_targets t\n      JOIN sys.dm_xe_sessions s ON s.address = t.event_session_address\n      WHERE s.name = N'system_health' AND t.target_name = N'ring_buffer') r\nCROSS APPLY r.td.nodes('//RingBufferTarget/event[@name=\"xml_deadlock_report\"]') AS x(ev);\n-- Daha uzun geçmiş için event_file hedefi:\n-- SELECT CAST(event_data AS XML) FROM sys.fn_xe_file_target_read_file(N'system_health*.xel', NULL, NULL, NULL) WHERE object_name = N'xml_deadlock_report';"}},{"title":"Çakışma desenini çöz","detail":"En yaygın neden: iki transaction'ın kaynaklara TERS sırada erişmesi. Tüm kod yollarında kaynaklara AYNI sırada eriş. İkinci yaygın neden: eksik index yüzünden geniş range lock'ları — gereken index'i ekle."},{"title":"Lock süresini ve kapsamını azalt","detail":"Transaction'ları kısa tut (kullanıcı etkileşimini transaction içine alma). Uygun izolasyon seviyesi seç. Gerektiğinde row lock'u erken al (SELECT ... FOR UPDATE ile deterministik sıralama)."},{"title":"Uygulamada retry şart","detail":"Deadlock tamamen elimine edilemez; kurban seçilen transaction için otomatik yeniden deneme (exponential backoff) uygula. Bu, kullanıcının hata görmesini engeller."}],"related":["blocking-sessions","open-transactions","list-indexes"]},{"id":"db-down","title":"Veritabanı açılmıyor / erişilemiyor","icon":"🚨","symptom":"Servise bağlanılamıyor, 'connection refused', örnek başlamıyor, listener yanıt vermiyor.","steps":[{"title":"Nerede kopuyor: ağ mı, servis mi, örnek mi","detail":"Sunucuya erişilebiliyor mu (ping/ssh)? DB süreci/servisi çalışıyor mu (ps/systemctl/services.msc)? Port dinleniyor mu (ss -ltnp / telnet host port)? Bu, sorunu ağ / servis / veritabanı örneği katmanlarından birine yerleştirir."},{"title":"Servisi ve listener'ı kontrol et","detail":"DB süreci ayakta değilse başlatmayı dene; ayaktaysa ama bağlanılmıyorsa listener/port ve auth katmanına bak.","engines":{"oracle":"-- OS: lsnrctl status  (listener)\n-- SQL*Plus: STARTUP;  (örnek kapalıysa)\nSELECT status FROM v$instance;","postgres":"-- OS: systemctl status postgresql ; pg_isready -h host\n-- Loglar: son satırlar neden başlamadığını söyler","mysql":"-- OS: systemctl status mysqld ; mysqladmin ping","mssql":"-- Services / SQL Server Configuration Manager; SQL Server Error Log","redis":"redis-cli ping  # PONG beklenir"}},{"title":"Logları oku — cevap oradadır","detail":"DB açılmıyorsa neden log'a yazılır: alert log (Oracle), postgresql.log / startup, mysqld error log, SQL Server ERRORLOG, redis log. Disk dolu, dosya bozuk, izin, port çakışması, eksik dosya — hepsi burada görünür."},{"title":"Sık nedenleri ele: disk, izin, port, bozulma","detail":"Disk %100 dolu mu (en sık neden)? Veri dizini izinleri bozulmuş mu? Port başka süreçte mi? Recovery gerekiyor mu (crash sonrası)? Bozuk control file/redo mu? Her birini logdaki mesaja göre hedefle."},{"title":"Kurtar ve olay kaydı tut","detail":"Crash recovery genelde otomatik tamamlanır; sabırlı ol. Bozulma varsa yedekten/PITR ile kurtar (Corruption playbook'una bak). Sonrasında kök neden analizi (RCA) yaz: ne oldu, neden, tekrarı nasıl önlenir."}],"related":["version-uptime","connect-cli","last-backup-status"]},{"id":"corruption","title":"Veri bozulması (corruption)","icon":"🧯","symptom":"'ORA-01578', 'page corruption', 'checksum mismatch', 'MISCONF', okuma sırasında I/O tutarlılık hataları.","steps":[{"title":"Sakin ol ve yayılmayı durdur","detail":"Panikle yapılan müdahale durumu kötüleştirir. Önce kapsamı belirle, mümkünse etkilenen nesneye yazmayı durdur. Donanım (disk/denetleyici) kaynaklıysa OS/donanım loglarına da bak — DB'yi düzeltmek diski düzeltmez."},{"title":"Kapsamı tespit et: ne kadar bozuk","detail":"Tek bir blok/sayfa/nesne mi, yoksa yaygın mı? Bütünlük kontrolü çalıştır.","engines":{"oracle":"RMAN> VALIDATE DATABASE;  -- ya da: SELECT * FROM v$database_block_corruption;","postgres":"-- data_checksums açıksa loglarda görünür; pg_amcheck ile indeks/heap kontrolü:\n-- pg_amcheck --heapallindexed -d veritabani","mysql":"CHECK TABLE musteri;  -- InnoDB için innodb_force_recovery son çare","mssql":"DBCC CHECKDB ('MyDB') WITH NO_INFOMSGS, ALL_ERRORMSGS;","redis":"redis-check-rdb dump.rdb\n# AOF (Redis 7+ multi-part: appendonlydir/ altında, manifest dosyası verilir):\nredis-check-aof appendonlydir/appendonly.aof.manifest\n# --fix bozuk noktadan sonrasını KESER (o kısımdaki yazmalar kaybolur); önce dizinin yedeğini alın:\n# redis-check-aof --fix appendonlydir/appendonly.aof.manifest"}},{"title":"Öncelik: yedekten kurtarma","detail":"Bozulmada en güvenli yol sağlam yedekten geri dönüştür. Blok/sayfa düzeyi kurtarma destekleniyorsa sadece bozuk kısmı kurtar (Oracle RMAN BLOCKRECOVER, MSSQL page restore). Repair araçları (DBCC REPAIR_ALLOW_DATA_LOSS, innodb_force_recovery) VERİ KAYBETTİRİR — son çaredir."},{"title":"Bütünlüğü doğrula","detail":"Kurtarma sonrası kontrolü tekrar çalıştır (DBCC CHECKDB / RMAN VALIDATE / CHECK TABLE) ve temiz çıktığını gör. Uygulama tarafında da veri tutarlılığını (satır sayıları, kritik toplamlar) doğrula."},{"title":"Kök neden: genelde donanım","detail":"Corruption çoğu zaman disk/bellek/denetleyici arızasından gelir. Donanımı test et/değiştir, checksum'ları aç (data_checksums, PAGE_VERIFY CHECKSUM), yedek + doğrulama rutinini sıkılaştır. Düzenli DBCC CHECKDB / RMAN VALIDATE planla."}],"related":["last-backup-status","restore-dump","db-down"]},{"id":"long-running-query","title":"Uzun süren sorgu / iş","icon":"⏱️","symptom":"Tek bir sorgu/iş saatlerdir çalışıyor, bitmiyor; kaynak tüketiyor ya da başkalarını etkiliyor.","steps":[{"title":"Sorguyu ve süresini yakala","detail":"Hangi sorgu, ne zamandır çalışıyor, hangi kullanıcı/uygulama?","engines":{"oracle":"SELECT sid, serial#, sql_id, last_call_et/60 running_min, username FROM v$session WHERE status='ACTIVE' AND type='USER' ORDER BY last_call_et DESC;","postgres":"SELECT pid, now()-query_start dur, usename, query FROM pg_stat_activity WHERE state='active' ORDER BY query_start;","mysql":"SELECT id, user, time, state, info FROM information_schema.processlist WHERE command='Query' ORDER BY time DESC;","mssql":"SELECT session_id, total_elapsed_time/1000 sec, status, command FROM sys.dm_exec_requests WHERE session_id IN (SELECT session_id FROM sys.dm_exec_sessions WHERE is_user_process = 1) ORDER BY total_elapsed_time DESC;","mongodb":"db.currentOp({ active: true, secs_running: { $gt: 60 } })"}},{"title":"İlerliyor mu, takıldı mı","detail":"Gerçekten çalışıyor mu yoksa bir lock'ta mi bekliyor? İlerleme göstergesine bak (Oracle v$session_longops, PG pg_stat_progress_* view'ları). Bekliyorsa Bloklama playbook'una geç.","engines":{"oracle":"SELECT sid, opname, sofar, totalwork, ROUND(sofar/NULLIF(totalwork,0)*100,1) pct, time_remaining FROM v$session_longops WHERE sofar<totalwork;","postgres":"SELECT * FROM pg_stat_progress_create_index;  -- veya pg_stat_progress_vacuum / _cluster / _analyze"}},{"title":"Karar: bekle mi, kes mi","detail":"İlerliyor ve yakında bitecekse bekle (kesmenin rollback maliyeti işi daha da uzatabilir). Takılıysa, yanlış çalışıyorsa veya üretimi etkiliyorsa sonlandır. Kesmeden önce rollback süresini düşün."},{"title":"Gerekirse sonlandır","detail":"Sadece sorguyu iptal etmeyi (oturumu koruyarak) tercih et; olmuyorsa oturumu kes.","engines":{"oracle":"ALTER SYSTEM CANCEL SQL 'sid,serial#';  -- 18c+; olmazsa KILL SESSION","postgres":"SELECT pg_cancel_backend(pid);  -- olmazsa pg_terminate_backend(pid)","mysql":"KILL QUERY <id>;","mssql":"KILL <session_id>;","mongodb":"db.killOp(<opid>)"}},{"title":"Kalıcı çöz","detail":"Sorguyu optimize et (index, plan, sayfalama/batch'leme), ağır işleri düşük yoğunluklu saatlere al, gerekiyorsa aşamalı (chunk) çalıştır. Tekrarlayan raporlar için materialized view / read replica düşün."}],"related":["active-sessions","kill-session","explain-plan","top-slow-queries"]},{"id":"xid-wraparound","title":"Postgres XID wraparound / autovacuum krizi","icon":"🧬","symptom":"'database is not accepting commands to avoid wraparound data loss'; autovacuum yetişemiyor, datfrozenxid yaşlanıyor.","steps":[{"title":"Aciliyeti anla","detail":"PostgreSQL transaction ID'si 32 bittir; tükenmeye yaklaşınca veri kaybını önlemek için sunucu YAZMAYI durdurur. Bu kritik ve zamana karşı bir durumdur. İyi haber: çözülebilir, panik değil disiplin gerekir."},{"title":"Ne kadar yakınsın ölç","detail":"Her veritabanının en eski donmamış XID yaşını çıkar; autovacuum_freeze_max_age'e (varsayılan 200M) yakınlık tehlikeyi gösterir.","engines":{"postgres":"SELECT datname, age(datfrozenxid) AS xid_age\nFROM pg_database ORDER BY xid_age DESC;"}},{"title":"En yaşlı tabloları bul","detail":"Sorun genelde birkaç büyük/sık yazılan tablodan gelir; en yaşlı relfrozenxid'lere odaklan.","engines":{"postgres":"SELECT relname, age(relfrozenxid) AS xid_age\nFROM pg_class WHERE relkind IN ('r','m','t')\nORDER BY xid_age DESC LIMIT 20;"}},{"title":"VACUUM'u engelleyenleri kaldır","detail":"Uzun açık transaction'lar, terk edilmiş replication slot'ları ve prepared transaction'lar temizlemeyi (freeze) engeller. Bunları bul ve çöz — yoksa VACUUM ne kadar çalışsa da ilerlemez.","engines":{"postgres":"SELECT pid, now()-xact_start AS age, state FROM pg_stat_activity WHERE xact_start IS NOT NULL ORDER BY age DESC;\nSELECT slot_name, active FROM pg_replication_slots WHERE NOT active;\nSELECT * FROM pg_prepared_xacts;"}},{"title":"Agresif FREEZE çalıştır","detail":"Engeller kalktıktan sonra en yaşlı tablolardan başlayarak donmayı zorla. Sunucu yeni transaction ID atamayı durdurmuş olsa bile tek-kullanıcı moduna (postgres --single) geçme: güncel PostgreSQL belgeleri bunun artık gerekmediğini ve kaçınılması gerektiğini belirtir. Normal modda superuser olarak bağlanıp VACUUM çalıştırmak yeterlidir; PG14+ sürümlerde wraparound yaklaşınca VACUUM'un failsafe mekanizması devreye girer.","engines":{"postgres":"VACUUM (FREEZE, VERBOSE) yasli_tablo;\n-- Tüm veritabanı: vacuumdb --all --freeze --jobs=4"}},{"title":"Kalıcı: autovacuum'u güçlendir ve izle","detail":"autovacuum_vacuum_cost_limit'i artır, autovacuum_naptime'ı düşür, çok yazılan tablolara özel storage parametreleri ver. age(datfrozenxid) için alarm kur; bu krizi bir daha yaşama."}],"related":["open-transactions","reclaim-space"]},{"id":"tempdb-contention","title":"tempdb çekişmesi (SQL Server)","icon":"🌀","symptom":"PAGELATCH_UP/EX beklemeleri, tempdb allocation (PFS/GAM/SGAM) sayfalarında çekişme, genel yavaşlık.","steps":[{"title":"Çekişmeyi doğrula","detail":"tempdb'nin sistem sayfalarındaki (2:1:1 gibi) PAGELATCH beklemeleri allocation çekişmesini işaret eder.","engines":{"mssql":"SELECT session_id, wait_type, wait_duration_ms, resource_description\nFROM sys.dm_os_waiting_tasks\nWHERE wait_type LIKE 'PAGELATCH%' AND resource_description LIKE '2:%'\nORDER BY wait_duration_ms DESC;"}},{"title":"tempdb kullanımını çıkar","detail":"Kim ne kadar tempdb kullanıyor? İç nesneler (sort/hash spill) mi, sürüm deposu mu, kullanıcı nesneleri mi?","engines":{"mssql":"SELECT * FROM sys.dm_db_file_space_usage;\nSELECT TOP 10 session_id, user_objects_alloc_page_count, internal_objects_alloc_page_count\nFROM sys.dm_db_task_space_usage ORDER BY internal_objects_alloc_page_count DESC;"}},{"title":"Dosya yapılandırmasını düzelt","detail":"tempdb için CPU çekirdek sayısına eşit (8'e kadar), EŞİT boyutlu birden çok data file kullan. SQL 2016+ bunu kurulumda önerir; eski sürümlerde trace flag 1117/1118. Dosyaları hızlı diske (yerel NVMe) al."},{"title":"Kaçak sorguyu bul","detail":"Büyük sort/hash spill yapan sorgular tempdb'yi patlatır. Bellek grant'i yetersiz veya kötü plan olanları hedefle; index/plan ile spill'i azalt.","engines":{"mssql":"SELECT TOP 10 t.text, mg.requested_memory_kb, mg.granted_memory_kb\nFROM sys.dm_exec_query_memory_grants mg CROSS APPLY sys.dm_exec_sql_text(mg.sql_handle) t\nORDER BY mg.requested_memory_kb DESC;"}},{"title":"Analog: diğer veritabanları","detail":"Aynı 'geçici alan çekişmesi' Oracle'da TEMP tablespace (v$tempseg_usage / v$sort_usage), PostgreSQL'de temp_files ve work_mem taşmasıdır. Kök çözüm hep aynı: spill yapan sorguyu düzelt, geçici alanı hızlandır."}],"related":["free-space","top-slow-queries","reclaim-space"]},{"id":"cert-expiry","title":"TLS / sertifika süresi doldu","icon":"🔐","symptom":"'certificate has expired', 'SSL handshake failed', istemciler aniden bağlanamıyor (kod değişmeden).","steps":[{"title":"Nerede kopuyor: sunucu, istemci, yoksa CA?","detail":"Süresi dolan sunucu sertifikası mı, istemci sertifikası mı, yoksa zincirdeki CA mı? Belirti çoğu zaman 'dün çalışıyordu bugün çalışmıyor, kod değişmedi' şeklindedir."},{"title":"Süreyi ölç","detail":"Sertifikanın bitiş tarihini doğrudan sunucudan oku (veritabanı bağımsız hızlı yöntem).","engines":{"postgres":"openssl s_client -connect host:5432 -starttls postgres </dev/null 2>/dev/null | openssl x509 -noout -dates","mongodb":"openssl s_client -connect host:27017 </dev/null 2>/dev/null | openssl x509 -noout -enddate","redis":"openssl s_client -connect host:6379 </dev/null 2>/dev/null | openssl x509 -noout -enddate"}},{"title":"Yeni sertifikayı kur ve yükle","detail":"Sertifikayı değiştirip servisi çoğunlukla yeniden başlatmadan yeniden yükle (reload).","engines":{"postgres":"-- ssl_cert_file/ssl_key_file yenile, sonra:\nSELECT pg_reload_conf();","mysql":"ALTER INSTANCE RELOAD TLS;","mssql":"-- SQL Server Configuration Manager > Certificate; servis restart gerekir","mongodb":"// net.tls.certificateKeyFile dosyasını (aynı yolda) yenile, sonra yeniden başlatmadan yükle (5.0+):\ndb.adminCommand({rotateCertificates: 1})","redis":"CONFIG SET tls-cert-file /path/yeni.crt\nCONFIG SET tls-key-file /path/yeni.key","elasticsearch":"# ES, xpack.security.*.ssl altında tanımlı sertifika/anahtar dosyalarını (PEM, PKCS#12) izler ve\n# AYNI yoldaki dosya değişince otomatik yeniden yükler (yeniden başlatma gerekmez).\n# Yol, dosya adı veya keystore parolası değişiyorsa rolling restart gerekir.\n# Not: POST _nodes/reload_secure_settings yalnızca yeniden yüklenebilir keystore ayarları içindir, TLS sertifikası için değildir.\n# Doğrula: openssl s_client ile yeni bitiş tarihini kontrol edin ve ES loglarında\n# sertifikanın yeniden yüklendiğine dair kaydı arayın."}},{"title":"Doğrula","detail":"Yeni sertifikayla TLS el sıkışmasının başarılı olduğunu ve süresinin uzadığını yukarıdaki openssl komutuyla teyit et; bir istemciyle uçtan uca bağlan."},{"title":"Kalıcı: bir daha yaşama","detail":"Sertifika bitişine 30 gün kala alarm kur; otomatik yenileme (ACME/Let's Encrypt, HashiCorp Vault, cert-manager) kullan. Yenileme sonrası reload'ı otomasyona bağla."}],"related":["connect-cli"]},{"id":"upgrade-rollback","title":"Sürüm yükseltme / patch geri alma","icon":"⏪","symptom":"Upgrade/patch sonrası sorun: performans regresyonu, uygulama uyumsuzluğu ya da açılmama.","steps":[{"title":"Önce dur: geri dönüş planın var mı?","detail":"Prod yükseltmesi ÖNCESİNDE tam yedek + (mümkünse) depolama snapshot'ı almadıysan, en güvenli yol ileri düzeltmektir. Geri alma çoğu veritabanında yedekten dönmek demektir. Bu adım aslında upgrade'den ÖNCE planlanmalıydı."},{"title":"Sorunu sınıflandır","detail":"Optimizer plan regresyonu mu (sorgular yavaşladı), uygulama/sürücü uyumsuzluğu mu, yoksa açılmama/bozulma mı? Çözüm yolu buna göre çok değişir."},{"title":"Veritabanına göre geri alma yolu","detail":"Oracle: datapatch ile patch rollback ya da Flashback Database (guaranteed restore point aldıysan). PostgreSQL: pg_upgrade sonrası geri dönüş = eski binary + eski data dizininin yedeği. MySQL: in-place DOWNGRADE genelde DESTEKLENMEZ — yedekten dön. SQL Server: sürüm düşürme yoktur — upgrade öncesi yedekten restore. Her durumda: snapshot/yedek senin sigortandır."},{"title":"Plan regresyonu ise: geri almadan çöz","detail":"Genelde tüm sürümü geri almak gerekmez; sadece planlar değişmiştir.","engines":{"oracle":"ALTER SYSTEM SET optimizer_features_enable='19.1.0';  -- eski davranışa sabitle\n-- veya SQL Plan Baseline ile iyi planı kilitle","postgres":"ANALYZE;  -- önce taze istatistik\n-- gerekirse geçici: SET enable_nestloop=off; gibi ayarlarla planı yönlendir"}},{"title":"Kalıcı: bir dahakine","detail":"Yükseltmeyi önce staging'de gerçek iş yüküyle test et, canary/rolling uygula, guaranteed restore point / snapshot al ve geri dönüş prosedürünü yazılı hale getir."}],"related":["last-backup-status","restore-dump","version-uptime"]},{"id":"es-red-cluster","title":"Elasticsearch kırmızı/sarı küme & atanmamış shard","icon":"🟥","symptom":"_cluster/health 'red' veya 'yellow'; unassigned shard'lar; okuma/yazma kısıtlı ya da veri erişilemez.","steps":[{"title":"Renk ve neden","detail":"yellow = replica shard'lar atanmadı (veri var, dayanıklılık düşük). red = en az bir PRIMARY shard yok (o veriye erişilemez). Önce hangisi ve neden olduğunu çıkar.","engines":{"elasticsearch":"GET _cluster/health?level=indices\nGET _cluster/allocation/explain"}},{"title":"Atanmamış shard'ları ve sebebini listele","detail":"unassigned.reason sütunu kök nedeni söyler (NODE_LEFT, ALLOCATION_FAILED, DISK vb.).","engines":{"elasticsearch":"GET _cat/shards?v&h=index,shard,prirep,state,unassigned.reason&s=state"}},{"title":"Sık nedenleri ele","detail":"1) Disk watermark → low aşılınca düğüm yeni shard almaz, flood_stage'de index'ler salt okunur olur. 2) Düğüm düştü / ayrıldı. 3) allocation kapalı bırakılmış. 4) replica sayısı > uygun düğüm sayısı."},{"title":"Çöz","detail":"Neden hangisiyse ona göre aç.","engines":{"elasticsearch":"# Disk açıldıysa read-only kilidini kaldır (7.4+ high watermark altına inince kendiliğinden de kalkar):\nPUT _all/_settings {\"index.blocks.read_only_allow_delete\": null}\n# Allocation kısıtlı bırakıldıysa varsayılana (all) döndür:\nPUT _cluster/settings {\"persistent\":{\"cluster.routing.allocation.enable\":null}}\n# Başarısız atamaları yeniden dene:\nPOST _cluster/reroute?retry_failed=true"}},{"title":"red kaldıysa ve primary gerçekten kayıpsa","detail":"Snapshot'tan ilgili index'i geri yükle ya da kaynak veriden yeniden indeksle (_reindex). Kalıcı: disk watermark alarmı, uygun replica sayısı (≥1) ve düğüm sağlığı izleme."}],"related":["replication-status","list-replicas","free-space"]},{"id":"time-skew","title":"Zaman kayması / NTP sorunu","icon":"⏱️","symptom":"Küme düğümleri arasında saat farkı; replikasyon/election tutarsızlıkları, 'certificate not yet valid', log zaman sıçramaları.","steps":[{"title":"Belirtiyi tanı","detail":"Saat kayması sinsidir: Mongo/Redis Sentinel election flapping, TLS 'not yet valid/expired' hataları, Kerberos hataları, loglarda geriye giden zaman damgaları. Dağıtık sistemlerde çoğu 'açıklanamayan' tuhaflığın kökü budur."},{"title":"Farkı ölç","detail":"Her düğümde saat kaynağını ve offset'i karşılaştır: `timedatectl`, `chronyc tracking` (veya `ntpq -p`), ve düğümler arası `date -u`. Birbirine göre kaç ms/sn fark var?"},{"title":"NTP/chrony'yi düzelt","detail":"chronyd/ntpd çalışıyor mu, zaman kaynaklarına ulaşıyor mu, senkron mu? Servisi başlat, kaynağı düzelt; büyük sapmada dikkatli step (ani sıçrama bazı DB'leri tetikleyebilir)."},{"title":"Etkilenen bileşeni doğrula","detail":"Saat düzeldikten sonra: MongoDB replica set election'ı stabil mi, Redis Sentinel/Cluster sağlıklı mı, TLS el sıkışmaları geçiyor mu, replikasyon lag metrikleri düzeldi mi kontrol et."},{"title":"Kalıcı","detail":"Tüm düğümlerde NTP'yi zorunlu kıl ve offset'i izle (alarm: >100ms). Sanal makinelerde host-guest time sync ayarını netleştir; tercihen tek, güvenilir bir zaman kaynağı hiyerarşisi kullan."}],"related":["replication-status"]}]},"playbooks/hadr.json":{"schemaVersion":1,"playbooks":[{"id":"hadr-oracle-dataguard","title":"Oracle Data Guard (fiziksel standby) kurulumu","icon":"🛡️","symptom":"Amaç: Oracle için fiziksel standby (Data Guard) ile felaket kurtarma ve yüksek erişilebilirlik kur; primary çökerse standby'a geçebil.","steps":[{"title":"Primary'yi FORCE LOGGING ve ARCHIVELOG moda al","detail":"Standby'ın primary ile tutarlı kalması için tüm değişikliklerin redo'ya yazılması şarttır. FORCE LOGGING NOLOGGING işlemlerini bile loglar. ARCHIVELOG modu için veritabanı MOUNT durumunda açılır.","engines":{"oracle":"ALTER DATABASE FORCE LOGGING;\n-- ARCHIVELOG için:\nSHUTDOWN IMMEDIATE;\nSTARTUP MOUNT;\nALTER DATABASE ARCHIVELOG;\nALTER DATABASE OPEN;"}},{"title":"Standby redo log dosyalarını ekle","detail":"Standby redo log (SRL), online redo'dan bir grup fazla ve aynı boyutta olmalıdır. Hem primary hem standby üzerinde oluşturulur; real-time apply için gereklidir. Örnekte online redo 200M ise SRL de 200M olur.","engines":{"oracle":"ALTER DATABASE ADD STANDBY LOGFILE ('/u01/oradata/srl01.log') SIZE 200M;\nALTER DATABASE ADD STANDBY LOGFILE ('/u01/oradata/srl02.log') SIZE 200M;\nALTER DATABASE ADD STANDBY LOGFILE ('/u01/oradata/srl03.log') SIZE 200M;\nALTER DATABASE ADD STANDBY LOGFILE ('/u01/oradata/srl04.log') SIZE 200M;"}},{"title":"log_archive_dest ve ilgili parametreleri ayarla","detail":"Primary üzerinde redo'yu standby'a taşıyacak dest_2 tanımlanır. DB_UNIQUE_NAME, LOG_ARCHIVE_CONFIG (her iki tarafın db_unique_name'i), FAL_SERVER ve STANDBY_FILE_MANAGEMENT=AUTO ayarlanır. Böylece standby'da dosyalar otomatik oluşur.","engines":{"oracle":"ALTER SYSTEM SET LOG_ARCHIVE_CONFIG='DG_CONFIG=(orcl_prim,orcl_stby)';\nALTER SYSTEM SET LOG_ARCHIVE_DEST_2='SERVICE=orcl_stby ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=orcl_stby';\nALTER SYSTEM SET FAL_SERVER='orcl_stby';  -- rol değişimi için; standby'da FAL_SERVER='orcl_prim'\nALTER SYSTEM SET STANDBY_FILE_MANAGEMENT=AUTO;"}},{"title":"Standby'ı RMAN DUPLICATE FOR STANDBY ile oluştur","detail":"Standby sunucuda parola dosyası ve statik listener/tnsnames kurulduktan sonra, RMAN primary'ye ve standby'a (AUXILIARY) bağlanır. FROM ACTIVE DATABASE ağ üzerinden yedeksiz kopyalar; DORECOVER redo'yu uygular.","engines":{"oracle":"rman TARGET sys/parola@orcl_prim AUXILIARY sys/parola@orcl_stby\nRUN {\n  DUPLICATE TARGET DATABASE FOR STANDBY FROM ACTIVE DATABASE\n  DORECOVER\n  NOFILENAMECHECK;\n}"}},{"title":"Redo apply (MRP) başlat ve doğrula","detail":"Standby MOUNT durumunda iken managed recovery başlatılır; real-time apply için USING CURRENT LOGFILE kullanılır. Apply sürecinin (MRP0) çalıştığını v$managed_standby ile doğrula.","engines":{"oracle":"ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION;\nSELECT process, status, sequence# FROM v$managed_standby WHERE process LIKE 'MRP%';"}},{"title":"Data Guard Broker'ı etkinleştir","detail":"Broker, konfigürasyonu merkezîleştirir ve failover/switchover'ı tek komuta indirir. Her iki instance'ta DG_BROKER_START=TRUE yapılır, sonra dgmgrl ile konfigürasyon oluşturulur ve etkinleştirilir. 12c+'da redo taşımayı broker yönetir: elle ayarlanmış LOG_ARCHIVE_DEST_2 varsa ADD DATABASE ORA-16698 verir; önce ALTER SYSTEM SET LOG_ARCHIVE_DEST_2='' ile temizleyin.","engines":{"oracle":"ALTER SYSTEM SET DG_BROKER_START=TRUE;\n-- dgmgrl içinde:\nCREATE CONFIGURATION dgconf AS PRIMARY DATABASE IS orcl_prim CONNECT IDENTIFIER IS orcl_prim;\nADD DATABASE orcl_stby AS CONNECT IDENTIFIER IS orcl_stby;\nENABLE CONFIGURATION;"}},{"title":"Senkronizasyon boşluğunu (gap) izle ve testi tamamla","detail":"Primary ile standby arasındaki sequence farkı sürekli izlenmelidir; fark büyüyorsa ağ/apply darboğazı vardır. dgmgrl SHOW CONFIGURATION 'SUCCESS' göstermeli. İsteğe bağlı bir switchover ile rol değişimini test et.","engines":{"oracle":"-- dgmgrl (SHOW DATABASE, Transport Lag / Apply Lag değerlerini gösterir):\nSHOW CONFIGURATION;\nSHOW DATABASE orcl_stby;\n-- SQL (standby): SELECT name, value FROM v$dataguard_stats WHERE name LIKE '%lag';"}}],"related":["replication-status","promote-failover","last-backup-status"]},{"id":"hadr-mssql-alwayson","title":"SQL Server Always On Availability Group kurulumu","icon":"🔁","symptom":"Amaç: SQL Server için Always On Availability Group (AG) ile otomatik failover ve okunabilir secondary replika kur.","steps":[{"title":"Windows Server Failover Cluster (WSFC) kur","detail":"Always On, altta bir WSFC'ye dayanır. Tüm düğümlerde Failover Clustering rolü kurulur, ağ ve tanık (witness) yapılandırılır. PowerShell ile cluster oluşturulur.","engines":{"mssql":"-- PowerShell (her düğümde Failover-Clustering özelliği kurulu olmalı):\nNew-Cluster -Name sqlclu -Node node1,node2 -StaticAddress 10.0.0.50\n-- Tanık:\nSet-ClusterQuorum -NodeAndFileShareMajority \\\\fs01\\quorum"}},{"title":"Her instance'ta Always On'u etkinleştir","detail":"SQL Server Configuration Manager veya PowerShell ile Always On Availability Groups özelliği açılır. Ardından SQL Server servisi yeniden başlatılır. Bu, cluster üyeliğini instance'a bağlar.","engines":{"mssql":"-- PowerShell:\nEnable-SqlAlwaysOn -ServerInstance node1\\SQL01 -Force\nEnable-SqlAlwaysOn -ServerInstance node2\\SQL01 -Force"}},{"title":"Veritabanını yedekle ve secondary düğüme NORECOVERY ile geri yükle","detail":"AG'ye alınacak veritabanı FULL recovery modunda olmalı. Primary'de tam ve log yedeği alınır; secondary düğümde NORECOVERY ile geri yüklenir (böylece redo almaya devam eder). Bu manuel seeding yöntemidir; alternatif otomatik seeding'dir.","engines":{"mssql":"-- Primary'de:\nBACKUP DATABASE app TO DISK='\\\\fs01\\bak\\app.bak';\nBACKUP LOG app TO DISK='\\\\fs01\\bak\\app.trn';\n-- Secondary'de:\nRESTORE DATABASE app FROM DISK='\\\\fs01\\bak\\app.bak' WITH NORECOVERY;\nRESTORE LOG app FROM DISK='\\\\fs01\\bak\\app.trn' WITH NORECOVERY;"}},{"title":"Uç noktaları oluştur ve Availability Group'u tanımla","detail":"Düğümler arası redo trafiği için 5022 portunda HADR endpoint kurulur. Senkron mod (SYNCHRONOUS_COMMIT) veri kaybı sıfır otomatik failover sağlar; asenkron (ASYNCHRONOUS_COMMIT) uzak DR için gecikmeli ama performanslıdır.","engines":{"mssql":"CREATE ENDPOINT hadr_endpoint STATE=STARTED\n  AS TCP (LISTENER_PORT=5022)\n  FOR DATA_MIRRORING (ROLE=ALL, ENCRYPTION=REQUIRED ALGORITHM AES);\n\nCREATE AVAILABILITY GROUP appag\n  FOR DATABASE app\n  REPLICA ON\n    'NODE1\\SQL01' WITH (ENDPOINT_URL='TCP://node1:5022', AVAILABILITY_MODE=SYNCHRONOUS_COMMIT, FAILOVER_MODE=AUTOMATIC, SECONDARY_ROLE(ALLOW_CONNECTIONS=ALL)),\n    'NODE2\\SQL01' WITH (ENDPOINT_URL='TCP://node2:5022', AVAILABILITY_MODE=SYNCHRONOUS_COMMIT, FAILOVER_MODE=AUTOMATIC, SECONDARY_ROLE(ALLOW_CONNECTIONS=ALL));"}},{"title":"Secondary düğümü AG'ye katıp veritabanını birleştir","detail":"Secondary instance'ta AG'ye JOIN yapılır, sonra geri yüklenen veritabanı AG'ye eklenir. Manuel seeding kullanıldıysa bu adım gerekir; otomatik seeding'de primary tarafında SET(SEEDING_MODE) ile hallolur.","engines":{"mssql":"-- Secondary'de:\nALTER AVAILABILITY GROUP appag JOIN;\nALTER DATABASE app SET HADR AVAILABILITY GROUP = appag;"}},{"title":"Availability Group Listener oluştur","detail":"Listener, uygulamaların bağlandığı sanal ad ve IP'dir; failover sonrası bağlantı otomatik olarak yeni primary'ye yönlenir. Uygulama connection string'inde bu ad ve MultiSubnetFailover=True kullanılır.","engines":{"mssql":"ALTER AVAILABILITY GROUP appag\n  ADD LISTENER 'appag-listener' (WITH IP ((N'10.0.0.60', N'255.255.255.0')), PORT=1433);"}},{"title":"Failover testi yap ve senkronizasyon durumunu doğrula","detail":"Senkronizasyon 'HEALTHY' olduğunda planlı bir failover ile rol değişimi test edilir. Otomatik failover için mod senkron ve FAILOVER_MODE=AUTOMATIC olmalı. Durumu sys.dm_hadr_availability_replica_states ile izle.","engines":{"mssql":"SELECT ag.name, ars.role_desc, ars.synchronization_health_desc\nFROM sys.dm_hadr_availability_replica_states ars\nJOIN sys.availability_groups ag ON ag.group_id=ars.group_id;\n-- Planlı failover (yeni primary olacak düğümde):\nALTER AVAILABILITY GROUP appag FAILOVER;"}}],"related":["replication-status","promote-failover","list-replicas"]},{"id":"hadr-postgres-streaming","title":"PostgreSQL streaming replication + otomatik failover","icon":"🐘","symptom":"Amaç: PostgreSQL için streaming (akış) replikasyonu ile hot standby kur ve otomatik failover için Patroni/repmgr ekle.","steps":[{"title":"Primary'de WAL ve bağlantı parametrelerini ayarla","detail":"Streaming replikasyon için wal_level en az 'replica' olmalı. max_wal_senders yeterli replika + yedek sayısını karşılamalı, wal_keep_size veya replication slot ile WAL'ın erken silinmesi engellenmeli. Değişiklikler yeniden başlatma gerektirir.","engines":{"postgres":"ALTER SYSTEM SET wal_level = 'replica';\nALTER SYSTEM SET max_wal_senders = 10;\nALTER SYSTEM SET max_replication_slots = 10;\nALTER SYSTEM SET hot_standby = on;\n-- postgresql.conf değişimi için:\n-- systemctl restart postgresql"}},{"title":"Replikasyon rolü ve pg_hba erişimi tanımla","detail":"Standby'ın bağlanacağı REPLICATION yetkili bir rol oluşturulur. pg_hba.conf'a standby IP'sinden 'replication' veritabanına erişim satırı eklenir ve pg_reload_conf() ile yeniden yüklenir.","engines":{"postgres":"CREATE ROLE replikator WITH REPLICATION LOGIN PASSWORD 'gizli';\n-- pg_hba.conf'a ekle:\n-- host replication replikator 10.0.0.20/32 scram-sha-256\nSELECT pg_reload_conf();"}},{"title":"Primary'de kalıcı replication slot oluştur","detail":"Fiziksel replication slot, standby geride kaldığında bile primary'nin ihtiyaç duyulan WAL'ı silmesini engeller; slot yönetimi wal_keep_size'a göre daha güvenlidir. Slot ismini standby yapılandırmasında kullanacağız.","engines":{"postgres":"SELECT pg_create_physical_replication_slot('standby1_slot');\nSELECT slot_name, active, restart_lsn FROM pg_replication_slots;"}},{"title":"Standby sunucuda pg_basebackup ile taban yedeği al","detail":"Standby'ın veri dizini boşken primary'den tam bir kopya alınır. -R bayrağı standby.signal dosyasını ve primary_conninfo'yu otomatik yazar; -C ile slot da oluşturulabilir. Slot ismi -S ile verilir.","engines":{"postgres":"pg_basebackup -h 10.0.0.10 -U replikator -D /var/lib/pgsql/data \\\n  -R -X stream -S standby1_slot -P -v"}},{"title":"primary_conninfo ve hot_standby'ı doğrula, standby'ı başlat","detail":"-R yazdığı postgresql.auto.conf içindeki primary_conninfo (host, user, slot) kontrol edilir; standby.signal dosyasının varlığı standby modunu belirler. hot_standby=on ise standby salt-okunur sorgulara açılır. Servis başlatılır.","engines":{"postgres":"-- postgresql.auto.conf içinde beklenen:\n-- primary_conninfo = 'host=10.0.0.10 user=replikator password=gizli'\n-- primary_slot_name = 'standby1_slot'\n-- systemctl start postgresql\nSELECT pg_is_in_recovery();  -- standby'da true dönmeli"}},{"title":"Replikasyon gecikmesini primary'den izle","detail":"Primary üzerinde pg_stat_replication her standby için gönderilen/uygulanan LSN ve gecikmeyi gösterir. write/flush/replay lag'ler küçük kalmalı; sync_state senkron replika kullanılıyorsa 'sync' olur.","engines":{"postgres":"SELECT client_addr, state, sync_state,\n       pg_wal_lsn_diff(sent_lsn, replay_lsn) AS replay_lag_bytes,\n       write_lag, flush_lag, replay_lag\nFROM pg_stat_replication;"}},{"title":"Otomatik failover için Patroni veya repmgr ekle","detail":"Çıplak streaming replikasyon manuel promote gerektirir. Otomatik failover için bir küme yöneticisi şarttır: Patroni (etcd/Consul üzerinde lider seçimi + otomatik promote) veya repmgr (repmgrd ile izleme/failover). Uygulama tarafında HAProxy/pgBouncer ile tek endpoint sağlanır. Manuel promote gerekirse: pg_ctl promote. Promote öncesinde eski primary'nin gerçekten durduğundan ve uygulamaların ona yazamadığından emin olun (split-brain riski). Eski primary'yi yeni primary'ye standby olarak geri katmak için pg_rewind gerekir; bunun için wal_log_hints = on ya da data checksums açık olmalıdır.","engines":{"postgres":"-- Manuel promote (küme yöneticisi yoksa):\npg_ctl promote -D /var/lib/pgsql/data\n-- veya SQL:\nSELECT pg_promote();\n-- Patroni ile: patronictl -c /etc/patroni.yml switchover mycluster"}}],"related":["replication-status","list-replicas","promote-failover"]},{"id":"hadr-mysql-innodb-cluster","title":"MySQL InnoDB Cluster (Group Replication) kurulumu","icon":"🐬","symptom":"Amaç: MySQL için InnoDB Cluster (Group Replication + MySQL Shell + MySQL Router) ile otomatik failover'lı yüksek erişilebilirlik kur.","steps":[{"title":"Ön koşulları sağla","detail":"InnoDB Cluster için her düğümde MySQL 8.0+, benzersiz server_id, GTID modu ve InnoDB depolama motoru gerekir. Tüm instance'lar birbirine ağ üzerinden erişebilmeli ve tablolarda primary key bulunmalıdır. Yönetim için bir clusterAdmin kullanıcısı hazırlanır.","engines":{"mysql":"-- her instance'ta my.cnf:\n-- server_id benzersiz, gtid_mode=ON, enforce_gtid_consistency=ON\nCREATE USER 'icadmin'@'%' IDENTIFIED BY 'gizli';\nGRANT ALL PRIVILEGES ON *.* TO 'icadmin'@'%' WITH GRANT OPTION;"}},{"title":"Her instance'ı MySQL Shell ile yapılandır","detail":"mysqlsh içinde dba.configureInstance() her düğümü Group Replication'a uygun hâle getirir; eksik parametreleri düzeltir ve gerekirse yeniden başlatma ister. Tüm düğümlerde tekrarlanır.","engines":{"mysql":"-- mysqlsh:\ndba.configureInstance('icadmin@node1:3306')\ndba.configureInstance('icadmin@node2:3306')\ndba.configureInstance('icadmin@node3:3306')"}},{"title":"Cluster'ı oluştur (seed düğüm)","detail":"Bir düğüme bağlanılıp dba.createCluster() ile küme başlatılır; bu düğüm ilk primary olur. Küme nesnesi döner ve sonraki eklemeler için kullanılır.","engines":{"mysql":"-- mysqlsh, node1'e bağlıyken:\nvar cluster = dba.createCluster('appCluster')"}},{"title":"Diğer instance'ları cluster'a ekle","detail":"cluster.addInstance() ile secondary düğümler eklenir. recoveryMethod olarak clone (fiziksel klon, yeni düğüm için hızlı) veya incremental (GTID ile) seçilir. En az 3 düğüm tek çoğunluk ve otomatik failover sağlar.","engines":{"mysql":"-- mysqlsh:\ncluster.addInstance('icadmin@node2:3306', {recoveryMethod: 'clone'})\ncluster.addInstance('icadmin@node3:3306', {recoveryMethod: 'clone'})"}},{"title":"MySQL Router'ı bootstrap et","detail":"MySQL Router uygulama ile küme arasında yönlendirme yapar; okuma/yazma (6446) ve salt-okuma (6447) portları sunar ve primary değişince trafiği otomatik yönlendirir. Bootstrap küme metadatasından yapılandırmayı üretir.","engines":{"mysql":"mysqlrouter --bootstrap icadmin@node1:3306 --user=mysqlrouter --directory /etc/mysqlrouter\n# Ardından: mysqlrouter -c /etc/mysqlrouter/mysqlrouter.conf &"}},{"title":"Küme durumunu kontrol et ve failover'ı doğrula","detail":"cluster.status() her düğümün rolünü (R/W primary, R/O secondary) ve durumunu (ONLINE) gösterir. clusterName ve topology sağlıklı olmalı. Primary'yi kapatıp otomatik yeni primary seçimini gözlemleyerek failover test edilir.","engines":{"mysql":"-- mysqlsh:\nvar cluster = dba.getCluster('appCluster')\ncluster.status()\n-- SQL ile üyeler:\nSELECT member_host, member_role, member_state FROM performance_schema.replication_group_members;"}}],"related":["replication-status","list-replicas","promote-failover"]},{"id":"hadr-mongodb-replicaset","title":"MongoDB replica set + sharding kurulumu","icon":"🍃","symptom":"Amaç: MongoDB için otomatik failover'lı replica set kur ve yatay ölçek için sharded cluster'a genişlet.","steps":[{"title":"mongod'ları aynı replSet adıyla başlat","detail":"Replica set üyelerinin her biri aynı --replSet adıyla ve erişilebilir --bind_ip ile başlatılır. Üretimde anahtar dosyası (keyFile) veya TLS ile iç kimlik doğrulama önerilir. Tek çoğunluk için tek sayıda oy veren üye hedeflenir.","engines":{"mongodb":"mongod --replSet rs0 --port 27017 --dbpath /data/n1 --bind_ip localhost,10.0.0.11\nmongod --replSet rs0 --port 27017 --dbpath /data/n2 --bind_ip localhost,10.0.0.12\nmongod --replSet rs0 --port 27017 --dbpath /data/n3 --bind_ip localhost,10.0.0.13"}},{"title":"Replica set'i initiate et","detail":"Bir üyeye mongosh ile bağlanıp rs.initiate() çağrılır ve tüm üyeler tanımlanır. Bu, ilk seçimi tetikler ve bir primary belirlenir. rs.status() ile PRIMARY/SECONDARY rolleri doğrulanır.","engines":{"mongodb":"rs.initiate({\n  _id: 'rs0',\n  members: [\n    { _id: 0, host: '10.0.0.11:27017' },\n    { _id: 1, host: '10.0.0.12:27017' },\n    { _id: 2, host: '10.0.0.13:27017' }\n  ]\n})\nrs.status()"}},{"title":"Üye ekle, öncelik ve gerekiyorsa arbiter ayarla","detail":"Sonradan rs.add() ile üye eklenir. priority ile hangi üyenin primary olmaya eğilimli olduğu belirlenir (0 = asla primary olmaz). Arbiter yalnızca oy verir, veri tutmaz; çift sayıda veri düğümünde tie-breaker olarak kullanılır ancak veri güvenliği için gerçek üye tercih edilir. Arbiter'lı (özellikle PSA) yapılarda bir veri düğümü düşünce majority write concern sağlanamaz ve yazmalar bekler; 5.0+ sürümlerde arbiter eklemeden önce küme geneli varsayılan write concern'ün setDefaultRWConcern ile açıkça ayarlanması gerekebilir.","engines":{"mongodb":"rs.add({ host: '10.0.0.14:27017', priority: 0.5 })\n// Arbiter yalnızca gerçekten gerekiyorsa (veri taşıyan üye tercih edilir):\nrs.addArb('10.0.0.15:27017')\n// öncelik değiştirme:\ncfg = rs.conf(); cfg.members[0].priority = 2; rs.reconfig(cfg)"}},{"title":"Sharding için config server replica set'i kur","detail":"Sharded cluster'ın metadatası bir config server replica set'inde (--configsvr) tutulur. Kendisi de bir replica set olarak initiate edilir; yüksek erişilebilirlik için 3 üye önerilir.","engines":{"mongodb":"mongod --configsvr --replSet cfgrs --port 27019 --dbpath /data/cfg1 --bind_ip localhost,10.0.0.21\n-- mongosh (config sunucusunda):\nrs.initiate({ _id: 'cfgrs', configsvr: true, members: [\n  { _id: 0, host: '10.0.0.21:27019' },\n  { _id: 1, host: '10.0.0.22:27019' },\n  { _id: 2, host: '10.0.0.23:27019' } ] })"}},{"title":"Shard replica set'lerini ve mongos router'ı başlat","detail":"Her shard, --shardsvr ile başlatılan kendi replica set'idir (veri dayanıklılığı shard içi replikasyondan gelir). mongos yönlendirici config server'lara işaret ederek başlatılır; uygulamalar mongos'a bağlanır.","engines":{"mongodb":"mongod --shardsvr --replSet shard1rs --port 27018 --dbpath /data/s1 --bind_ip localhost,10.0.0.31\n# shard1rs'i rs.initiate ile başlat, sonra mongos:\nmongos --configdb cfgrs/10.0.0.21:27019,10.0.0.22:27019,10.0.0.23:27019 --port 27017 --bind_ip localhost,10.0.0.40"}},{"title":"Shard'ları ekle ve koleksiyonu shard'la","detail":"mongos'a bağlanılıp sh.addShard() ile her shard replica set'i eklenir. Veritabanında sharding etkinleştirilir ve sh.shardCollection() ile bir shard anahtarına göre koleksiyon dağıtılır. Anahtar seçimi kritiktir: kardinalitesi yüksek ve dağılımı düzgün olmalı. sh.status() ile chunk dağılımı izlenir.","engines":{"mongodb":"sh.addShard('shard1rs/10.0.0.31:27018')\nsh.addShard('shard2rs/10.0.0.32:27018')\nsh.enableSharding('appdb')\nsh.shardCollection('appdb.olaylar', { musteri_id: 'hashed' })\nsh.status()"}}],"related":["replication-status","list-replicas","promote-failover"]},{"id":"hadr-redis-sentinel","title":"Redis Sentinel + Cluster ile yüksek erişilebilirlik","icon":"⚡","symptom":"Amaç: Redis için Sentinel ile otomatik failover'lı master-replica kur; yatay ölçek gerekiyorsa Redis Cluster moduna geç.","steps":[{"title":"Master ve replica'ları yapılandır","detail":"Bir master ve en az iki replica çalıştırılır. Replica'lar REPLICAOF ile master'ı takip eder (redis.conf içinde 'replicaof <host> <port>' de yazılabilir). Kalıcılık için AOF veya RDB açılmalı ve requirepass/masterauth ile kimlik doğrulama önerilir.","engines":{"redis":"# replica düğümlerinde çalışma anında:\nREPLICAOF 10.0.0.10 6379\n# kalıcı yapmak için redis.conf:\n# replicaof 10.0.0.10 6379\n# masterauth gizli\nINFO replication"}},{"title":"Sentinel'i monitor ve quorum ile yapılandır","detail":"Her Sentinel düğümünün sentinel.conf'unda izlenecek master ve quorum tanımlanır. quorum, master'ı 'down' saymak için gereken minimum Sentinel sayısıdır. Üretimde 3 ayrı sunucuda 3 Sentinel önerilir (split-brain'e karşı).","engines":{"redis":"# sentinel.conf:\nsentinel monitor mymaster 10.0.0.10 6379 2\nsentinel down-after-milliseconds mymaster 5000\nsentinel failover-timeout mymaster 60000\nsentinel parallel-syncs mymaster 1"}},{"title":"Sentinel süreçlerini başlat","detail":"Her düğümde Sentinel başlatılır. Sentinel'ler birbirini ve replica'ları otomatik keşfeder; yapılandırmayı çalışırken dosyaya yazar. Bu yüzden sentinel.conf yazılabilir olmalıdır.","engines":{"redis":"redis-sentinel /etc/redis/sentinel.conf\n# veya:\nredis-server /etc/redis/sentinel.conf --sentinel"}},{"title":"Sentinel üzerinden durum sorgula ve failover test et","detail":"SENTINEL komutlarıyla mevcut master ve replica'lar sorgulanır. Uygulamalar Sentinel'e 'get-master-addr-by-name' sorarak güncel master'ı öğrenmelidir. Planlı bir failover ile otomatik geçiş doğrulanır.","engines":{"redis":"SENTINEL master mymaster\nSENTINEL get-master-addr-by-name mymaster\nSENTINEL replicas mymaster\n# planlı geçiş:\nSENTINEL failover mymaster"}},{"title":"Alternatif: Redis Cluster ile veriyi bölümlere ayır","detail":"Tek master'ın belleği/verimi yetmiyorsa Redis Cluster kullanılır: veri 16384 hash slotuna bölünür ve birden çok master'a dağıtılır; her master'ın kendi replica'sı olur. Uygulama cluster-aware istemci kullanmalıdır. redis-cli --cluster create ile kurulur.","engines":{"redis":"redis-cli --cluster create \\\n  10.0.0.11:6379 10.0.0.12:6379 10.0.0.13:6379 \\\n  10.0.0.21:6379 10.0.0.22:6379 10.0.0.23:6379 \\\n  --cluster-replicas 1"}},{"title":"Cluster durumunu doğrula","detail":"Cluster kurulduktan sonra tüm slotların atandığı ve düğümlerin bağlı olduğu doğrulanır. cluster_state 'ok' olmalı ve 16384 slotun tamamı atanmış görünmelidir. Düğüm ve slot dağılımı CLUSTER komutlarıyla izlenir.","engines":{"redis":"redis-cli --cluster check 10.0.0.11:6379\nredis-cli -c -h 10.0.0.11 CLUSTER INFO\nredis-cli -c -h 10.0.0.11 CLUSTER NODES"}}],"related":["replication-status","list-replicas","promote-failover"]},{"id":"hadr-elasticsearch-ha","title":"Elasticsearch dayanıklılık: replica + snapshot + CCR","icon":"🔎","symptom":"Amaç: Elasticsearch için replica shard'lar, ayrılmış master/data düğümleri, snapshot yedekleri (SLM) ve cross-cluster replication (CCR) ile dayanıklılık kur.","steps":[{"title":"Rolleri ayır: ayrılmış master ve data düğümleri","detail":"Küme kararlılığı için oy veren master-eligible düğümler (tercihen 3, tek çoğunluk) data yükünden ayrılır. elasticsearch.yml'de node.roles ile roller atanır ve discovery için seed host'lar tanımlanır. 3 master split-brain'i önler.","engines":{"elasticsearch":"# master düğümlerde elasticsearch.yml:\n# node.roles: [ master ]\n# data düğümlerde:\n# node.roles: [ data, ingest ]\n# discovery.seed_hosts: [ m1, m2, m3 ]\n# cluster.initial_master_nodes: [ m1, m2, m3 ]"}},{"title":"Index replica sayısını ayarla","detail":"number_of_replicas her primary shard için tutulacak kopya sayısıdır; en az 1 olmalı ki bir data düğümü kaybında veri erişilebilir kalsın. Çalışan index'te dinamik olarak değiştirilebilir; replica sayısı data düğüm sayısından az olmalıdır.","engines":{"elasticsearch":"PUT /siparisler/_settings\n{\n  \"index\": { \"number_of_replicas\": 1 }\n}\n# şablonla varsayılan (composable template; eski _template API'si legacy'dir):\n# PUT _index_template/siparis-tpl { \"index_patterns\": [\"siparis*\"], \"template\": { \"settings\": { \"number_of_replicas\": 1 } } }"}},{"title":"Snapshot repository tanımla","detail":"Yedekler bir repository'ye alınır: paylaşımlı dosya sistemi (fs) veya S3/GCS/Azure eklentileri. Küme silinse bile veriyi geri getirebilmek için repository küme dışında kalıcı depolamada olmalıdır.","engines":{"elasticsearch":"PUT /_snapshot/yedek_deposu\n{\n  \"type\": \"fs\",\n  \"settings\": { \"location\": \"/mnt/es_backups\", \"compress\": true }\n}"}},{"title":"SLM ile otomatik snapshot zamanla","detail":"Snapshot Lifecycle Management (SLM) düzenli snapshot alır ve saklama (retention) politikası uygular. Bir cron ifadesiyle sıklık, hangi index'lerin alınacağı ve kaç snapshot tutulacağı tanımlanır.","engines":{"elasticsearch":"PUT /_slm/policy/gunluk_yedek\n{\n  \"schedule\": \"0 30 1 * * ?\",\n  \"name\": \"<gunluk-{now/d}>\",\n  \"repository\": \"yedek_deposu\",\n  \"config\": { \"indices\": [\"*\"] },\n  \"retention\": { \"expire_after\": \"30d\", \"min_count\": 5, \"max_count\": 50 }\n}"}},{"title":"Snapshot'ı ve geri yüklemeyi doğrula","detail":"SLM politikası elle tetiklenerek çalıştığı doğrulanır; snapshot durumu SUCCESS olmalı. Düzenli olarak bir geri yükleme testi yapılmalıdır çünkü test edilmemiş yedek yedek sayılmaz.","engines":{"elasticsearch":"POST /_slm/policy/gunluk_yedek/_execute\nGET /_snapshot/yedek_deposu/_all\n# geri yükleme:\nPOST /_snapshot/yedek_deposu/<snapshot_adi>/_restore"}},{"title":"Cross-Cluster Replication (CCR) ile uzak DR kur","detail":"Bölgeler arası felaket kurtarma için ikinci bir küme (follower) uzak primary cluster'daki (leader) index'leri takip eder. Önce remote cluster tanımlanır, sonra follower index leader'a bağlanır; leader'daki değişiklikler otomatik akar. CCR bir platin (ticari) özelliktir.","engines":{"elasticsearch":"# follower kümede uzak kümeyi tanımla:\nPUT /_cluster/settings\n{ \"persistent\": { \"cluster\": { \"remote\": { \"birincil\": { \"seeds\": [\"leader1:9300\"] } } } } }\n# follower indeksi oluştur:\nPUT /siparisler-follower/_ccr/follow\n{ \"remote_cluster\": \"birincil\", \"leader_index\": \"siparisler\" }"}}],"related":["replication-status","list-replicas","last-backup-status"]}]},"playbooks/security.json":{"schemaVersion":1,"playbooks":[{"id":"harden-sql","title":"Güvenlik sıkılaştırma: SQL veritabanları (Oracle, PostgreSQL, MySQL, SQL Server)","icon":"🔒","symptom":"Amaç: İlişkisel veritabanlarını CIS-tarzı sıkılaştır — varsayılan hesaplar, güçlü parola politikası, en az yetki, ağ kısıtlama, TLS, denetim (audit) ve şifreleme (TDE).","steps":[{"title":"Varsayılan/gereksiz hesapları kaldır veya kilitle, örnek şemaları sil","detail":"Kurulumla gelen varsayılan hesaplar ve örnek şemalar bilinen saldırı yüzeyidir. Kullanılmayanları kilitle veya kaldır; üst düzey/servis hesaplarını yeniden adlandır.","engines":{"oracle":"-- Kullanılmayan varsayılan hesapları kilitle ve süresini doldur:\nALTER USER SCOTT ACCOUNT LOCK PASSWORD EXPIRE;\nALTER USER HR ACCOUNT LOCK PASSWORD EXPIRE;\n-- Kilitli/açık hesapları denetle:\nSELECT username, account_status FROM dba_users ORDER BY account_status;\n-- Örnek şemaları kaldır: $ORACLE_HOME/demo/schema/drop_sch.sql","postgres":"-- Varsayılan superuser 'postgres' rolünü koru; yerine kaldır/rename ETME.\n-- Rolleri denetle:\nSELECT rolname, rolsuper, rolcanlogin FROM pg_roles ORDER BY rolsuper DESC;\n-- Gereksiz login rollerini kaldır:\nDROP ROLE IF EXISTS test_user;\n-- Örnek/test veritabanlarını sil: DROP DATABASE IF EXISTS test;","mysql":"# İnteraktif sıkılaştırma sihirbazı (anonim kullanıcı, test DB, uzak root'u kaldırır):\nmysql_secure_installation\n-- Manuel: anonim ve test hesaplarını kaldır:\nDROP USER IF EXISTS ''@'localhost';\nDROP USER IF EXISTS ''@'%';\nDROP DATABASE IF EXISTS test;\nDELETE FROM mysql.db WHERE Db LIKE 'test%'; FLUSH PRIVILEGES;","mssql":"-- 'sa' hesabını devre dışı bırak ve yeniden adlandır:\nALTER LOGIN sa DISABLE;\nALTER LOGIN sa WITH NAME = [sa_disabled_acct];\n-- Guest kullanıcısını kısıtla — yalnızca KULLANICI veritabanlarında\n-- (master, tempdb ve msdb'de guest açık kalmalıdır; tempdb/msdb'de kapatmak sorun çıkarır):\nUSE appdb;\nREVOKE CONNECT FROM guest;\n-- Örnek DB'leri kaldır: DROP DATABASE AdventureWorks;"}},{"title":"Güçlü parola politikası ve süre sınırı uygula","detail":"Zayıf/asla değişmeyen parolalar en yaygın giriş noktasıdır. Deneme sınırı, karmaşıklık ve parola ömrü uygula; parolaları güçlü hash ile sakla.","engines":{"oracle":"-- Profil ile deneme sınırı, ömür ve karmaşıklık:\nCREATE PROFILE app_profile LIMIT\n  FAILED_LOGIN_ATTEMPTS 5\n  PASSWORD_LIFE_TIME 90\n  PASSWORD_REUSE_MAX 10\n  PASSWORD_VERIFY_FUNCTION ora12c_verify_function;\nALTER USER app_user PROFILE app_profile;","postgres":"-- Güçlü hash algoritması (SCRAM):\nSHOW password_encryption;              -- 'scram-sha-256' olmalı\nALTER SYSTEM SET password_encryption = 'scram-sha-256';\n-- Karmaşıklık için passwordcheck uzantısını yükle:\n-- shared_preload_libraries = 'passwordcheck'\n-- Ömür: ALTER ROLE app_user VALID UNTIL '2026-12-31';","mysql":"-- validate_password bileşenini kur ve politika ayarla:\nINSTALL COMPONENT 'file://component_validate_password';\nSET PERSIST validate_password.policy = 'STRONG';\nSET PERSIST validate_password.length = 14;\n-- Deneme sınırı ve ömür:\nALTER USER app_user PASSWORD EXPIRE INTERVAL 90 DAY\n  FAILED_LOGIN_ATTEMPTS 5 PASSWORD_LOCK_TIME 1;","mssql":"-- Login'de Windows parola politikası ve süre dolumunu zorunlu kıl:\nALTER LOGIN app_user WITH CHECK_POLICY = ON, CHECK_EXPIRATION = ON;\n-- Politika/expiration durumunu denetle:\nSELECT name, is_policy_checked, is_expiration_checked\nFROM sys.sql_logins;"}},{"title":"En az yetki: PUBLIC/geniş yetkileri geri al, rol tabanlı yetki ver","detail":"Herkese (PUBLIC) verilmiş geniş yetkiler yatay hareketi kolaylaştırır. Yetkileri geri al, roller oluştur ve yalnızca gerekeni ver.","engines":{"oracle":"-- Tehlikeli PUBLIC yetkilerini geri al:\nREVOKE EXECUTE ON UTL_HTTP FROM PUBLIC;\nREVOKE EXECUTE ON UTL_FILE FROM PUBLIC;\nREVOKE EXECUTE ON DBMS_SCHEDULER FROM PUBLIC;\n-- Rol tabanlı yetki:\nCREATE ROLE app_read;\nGRANT SELECT ON app.orders TO app_read;\nGRANT app_read TO app_user;","postgres":"-- Şemadaki varsayılan PUBLIC yetkilerini geri al:\nREVOKE ALL ON DATABASE appdb FROM PUBLIC;\nREVOKE CREATE ON SCHEMA public FROM PUBLIC;\n-- Rol tabanlı, salt-okunur erişim:\nCREATE ROLE app_read NOLOGIN;\nGRANT USAGE ON SCHEMA app TO app_read;\nGRANT SELECT ON ALL TABLES IN SCHEMA app TO app_read;\nGRANT app_read TO app_user;","mysql":"-- Global geniş yetkileri denetle ve geri al:\nSHOW GRANTS FOR app_user;\nREVOKE ALL PRIVILEGES, GRANT OPTION FROM app_user;\n-- Rol tabanlı, nesne düzeyinde yetki (MySQL 8+):\nCREATE ROLE app_read;\nGRANT SELECT ON appdb.* TO app_read;\nGRANT app_read TO app_user;\nSET DEFAULT ROLE app_read TO app_user;","mssql":"-- public rolüne verilmiş fazla yetkiyi geri al:\nREVOKE SELECT ON SCHEMA::dbo FROM public;\n-- Rol tabanlı yetki:\nCREATE ROLE app_read;\nGRANT SELECT ON SCHEMA::app TO app_read;\nALTER ROLE app_read ADD MEMBER app_user;\n-- Sunucu düzeyinde: sabit sunucu rollerini (sysadmin) sınırla."}},{"title":"Ağ/erişim kısıtla — yalnızca bilinen istemciler bağlansın","detail":"Veritabanını dünyaya açık dinlemekten kaçın. Dinleme adresini kısıtla, host/IP bazlı erişim kuralları uygula ve güvenlik duvarıyla portu sınırla.","engines":{"oracle":"# listener.ora / sqlnet.ora — geçerli düğüm kontrolü:\nTCP.VALIDNODE_CHECKING = YES\nTCP.INVITED_NODES = (10.0.0.5, 10.0.0.6)\nTCP.EXCLUDED_NODES = (0.0.0.0/0)\n# Değişiklikten sonra: lsnrctl reload","postgres":"# postgresql.conf — sadece belirli arayüzü dinle:\nlisten_addresses = '10.0.0.10,localhost'\n# pg_hba.conf — host/IP + güçlü kimlik doğrulama:\nhostssl appdb app_user 10.0.0.0/24 scram-sha-256\nhost    all      all       0.0.0.0/0      reject\n# Yeniden yükle: SELECT pg_reload_conf();","mysql":"# my.cnf — yalnızca belirli arayüze bağlan:\n[mysqld]\nbind-address = 10.0.0.10\n-- Host bazlı kullanıcı (yalnız uygulama sunucusundan):\nCREATE USER 'app_user'@'10.0.0.5'\n  IDENTIFIED BY '****' REQUIRE SSL;\n-- Uzak root'a asla '%' host verme.","mssql":"# TCP portunu güvenlik duvarıyla sınırla (yalnız uygulama subnet'i):\nNew-NetFirewallRule -DisplayName 'SQL-1433' -Direction Inbound `\n  -Protocol TCP -LocalPort 1433 -RemoteAddress 10.0.0.0/24 -Action Allow\n-- Dinlenen adresleri denetle:\nSELECT * FROM sys.dm_tcp_listener_states;\n-- Kullanılmıyorsa SQL Browser servisini kapat."}},{"title":"TLS/şifreli bağlantı zorunlu kıl","detail":"Ağdaki trafik pasif dinlemeye açıktır. Sunucu sertifikası tanımla ve istemcilerin şifreli bağlanmasını zorunlu kıl.","engines":{"oracle":"# sqlnet.ora — TCPS/TLS (sunucu sertifikası wallet'ta):\nWALLET_LOCATION = (SOURCE=(METHOD=FILE)(METHOD_DATA=(DIRECTORY=/etc/oracle/wallet)))\nSSL_CLIENT_AUTHENTICATION = FALSE\nSSL_VERSION = 1.2\n# listener.ora'da yalnız TCPS (port 2484) dinle. Not: SQLNET.ENCRYPTION_SERVER TLS değil, Native Network Encryption'dır.","postgres":"# postgresql.conf:\nssl = on\nssl_cert_file = 'server.crt'\nssl_key_file  = 'server.key'\nssl_min_protocol_version = 'TLSv1.2'\n# pg_hba.conf'te 'hostssl' satırı kullan; düz 'host' ile şifresiz bağlantıyı reddet.","mysql":"# my.cnf:\n[mysqld]\nrequire_secure_transport = ON\nssl_cert = /etc/mysql/server-cert.pem\nssl_key  = /etc/mysql/server-key.pem\nssl_ca   = /etc/mysql/ca.pem\n-- Kullanıcı düzeyinde: ALTER USER app_user REQUIRE SSL;","mssql":"-- Bağlantı şifrelemesini zorunlu kıl (SQL Server Configuration Manager):\n-- Protocols for MSSQLSERVER > Properties > Force Encryption = Yes\n-- Sertifika ata; sonra servisi yeniden başlat.\n-- Durumu denetle:\nSELECT session_id, encrypt_option FROM sys.dm_exec_connections;"}},{"title":"Denetim (audit) aç — kim ne yaptı görülebilsin","detail":"Yetkili erişim ve şüpheli işlemleri izlemek için denetim kaydı şart. Oturum açma, yetki değişikliği ve hassas nesne erişimini logla.","engines":{"oracle":"-- Unified Auditing ile politika oluştur ve etkinleştir:\nCREATE AUDIT POLICY sec_pol\n  ACTIONS LOGON, LOGOFF, ALTER USER, GRANT, CREATE USER, DROP USER;\nAUDIT POLICY sec_pol;\n-- Kayıtları gör:\nSELECT * FROM unified_audit_trail ORDER BY event_timestamp DESC;","postgres":"# pgaudit uzantısı ile:\n# postgresql.conf:\nshared_preload_libraries = 'pgaudit'\npgaudit.log = 'ddl, role, write'\n-- Uzantıyı oluştur:\nCREATE EXTENSION pgaudit;\n-- log_connections = on, log_disconnections = on da açılmalı.","mysql":"-- Enterprise/Percona audit_log eklentisini yükle:\nINSTALL PLUGIN audit_log SONAME 'audit_log.so';\nSET PERSIST audit_log_policy = 'ALL';\n-- MariaDB: server_audit eklentisi\n-- INSTALL SONAME 'server_audit'; SET GLOBAL server_audit_logging=ON;","mssql":"-- Server Audit oluştur ve başlat:\nCREATE SERVER AUDIT sec_audit\n  TO FILE (FILEPATH = 'C:\\SQLAudit\\');\nALTER SERVER AUDIT sec_audit WITH (STATE = ON);\nCREATE SERVER AUDIT SPECIFICATION sec_spec\n  FOR SERVER AUDIT sec_audit\n  ADD (FAILED_LOGIN_GROUP), ADD (DATABASE_ROLE_MEMBER_CHANGE_GROUP)\n  WITH (STATE = ON);"}},{"title":"Veri şifreleme (at-rest / TDE) uygula","detail":"Disk, yedek veya dosya çalınırsa veri okunamamalı. Sütun/tablespace/veritabanı düzeyinde durağan veri şifrelemesi (TDE) etkinleştir.","engines":{"oracle":"-- Transparent Data Encryption (keystore + tablespace):\nADMINISTER KEY MANAGEMENT CREATE KEYSTORE '/etc/oracle/wallet'\n  IDENTIFIED BY \"WalletPwd1\";\nADMINISTER KEY MANAGEMENT SET KEY IDENTIFIED BY \"WalletPwd1\" WITH BACKUP;\nCREATE TABLESPACE sec_ts DATAFILE '/u01/sec01.dbf' SIZE 100M\n  ENCRYPTION USING 'AES256' DEFAULT STORAGE(ENCRYPT);","postgres":"-- Yerleşik blok TDE yoktur; iki yaygın yaklaşım:\n-- 1) Sütun düzeyinde pgcrypto:\nCREATE EXTENSION pgcrypto;\nINSERT INTO t(ssn) VALUES (pgp_sym_encrypt('123-45', 'anahtar'));\nSELECT pgp_sym_decrypt(ssn, 'anahtar') FROM t;\n-- 2) Dosya sistemi/blok şifreleme (LUKS) veya EDB/Cybertec TDE derlemesi.","mysql":"# InnoDB tablespace şifreleme — keyring BİLEŞENİ (8.0.24+; 8.4'te keyring_file eklentisi kaldırıldı)\n# 1) mysqld ikilisinin dizininde global manifest: mysqld.my\n{ \"components\": \"file://component_keyring_file\" }\n# 2) plugin_dir içinde: component_keyring_file.cnf\n{ \"path\": \"/var/lib/mysql-keyring/component_keyring_file\", \"read_only\": false }\n# 3) Sunucuyu yeniden başlat; doğrula:\n-- SELECT * FROM performance_schema.keyring_component_status;\n-- Tabloyu şifrele:\nALTER TABLE app.orders ENCRYPTION = 'Y';\n-- Yeni tablolar için: SET PERSIST default_table_encryption = ON;\n# 8.0.24 öncesi (yalnızca 8.0): early-plugin-load = keyring_file.so + keyring_file_data\n# UYARI: keyring dosyasını veri dizininden AYRI ve güvenli biçimde yedekleyin;\n# keyring kaybolursa şifreli tablolar ve yedekleri kalıcı olarak okunamaz.","mssql":"-- Transparent Data Encryption (DEK + sertifika) — anahtar ve sertifika master'da olmalı:\nUSE master;\nCREATE MASTER KEY ENCRYPTION BY PASSWORD = '<GucluParola1>';\nCREATE CERTIFICATE tde_cert WITH SUBJECT = 'TDE Cert';\n-- ZORUNLU: sertifikayı özel anahtarıyla hemen yedekle ve sunucu dışında sakla.\n-- Bu yedek olmadan sunucu kaybında şifreli DB ve yedekleri geri YÜKLENEMEZ.\nBACKUP CERTIFICATE tde_cert TO FILE = 'D:\\guvenli\\tde_cert.cer'\n  WITH PRIVATE KEY (FILE = 'D:\\guvenli\\tde_cert.pvk',\n    ENCRYPTION BY PASSWORD = '<CertYedekParola1>');\nUSE appdb;\nCREATE DATABASE ENCRYPTION KEY\n  WITH ALGORITHM = AES_256 ENCRYPTION BY SERVER CERTIFICATE tde_cert;\nALTER DATABASE appdb SET ENCRYPTION ON;\n-- İlerleme: SELECT DB_NAME(database_id), encryption_state, percent_complete FROM sys.dm_database_encryption_keys;"}},{"title":"Yamaları güncel tut ve gereksiz özellikleri kapat","detail":"Bilinen açıklar en çok sömürülen risktir. Düzenli güvenlik yaması uygula; kullanılmayan protokol, eklenti ve özellikleri devre dışı bırak (saldırı yüzeyini küçült).","engines":{"oracle":"-- Yüklü sürüm ve yamaları denetle:\nSELECT version_full FROM v$instance;\n-- Quarterly Critical Patch Update (CPU) uygula: OPatch/opatchauto\n-- Kullanılmayan bileşenleri kaldır (ör. XML DB, APEX) ve\n-- external procedure (extproc) listener'ını kapat.","postgres":"# Sürümü ve minor yamayı denetle:\nSELECT version();\n# Paket yöneticisiyle güncel minor sürüme yükselt (ör. 16.x en son).\n# Kullanılmayan uzantıları kaldır: DROP EXTENSION IF EXISTS ...;\n# postgresql.conf: kullanılmayan dil/PL uzantılarını yükleme.","mysql":"-- Sürümü denetle: SELECT VERSION();\n-- LTS/güvenlik güncellemesine yükselt (8.0.x/8.4 LTS).\n-- Yerel dosya okumayı kapat:\nSET PERSIST local_infile = OFF;\n-- Kullanılmayan eklentileri kaldır: UNINSTALL PLUGIN ...;","mssql":"-- Ürün sürümü/patch seviyesini denetle:\nSELECT SERVERPROPERTY('ProductVersion'), SERVERPROPERTY('ProductLevel');\n-- En güncel Cumulative Update (CU) uygula.\n-- Kullanılmayan özellikleri kapat (sp_configure ile):\nEXEC sp_configure 'xp_cmdshell', 0; RECONFIGURE;\nEXEC sp_configure 'Ole Automation Procedures', 0; RECONFIGURE;"}}],"related":["list-users","create-user-grant","enable-audit","change-password"]},{"id":"harden-nosql","title":"Güvenlik sıkılaştırma: MongoDB / Redis / Elasticsearch","icon":"🛡️","symptom":"Amaç: NoSQL/veri depolarını CIS-tarzı sıkılaştır — kimlik doğrulama, ağ kısıtlama, tehlikeli komut engelleme, TLS, en az yetki rolleri ve denetim.","steps":[{"title":"Kimlik doğrulamayı AÇ — kimliksiz erişimi kes","detail":"Bu ürünler varsayılan olarak sık sık kimlik doğrulaması KAPALI gelir ve internete açık bırakılınca ele geçirilir. Kimlik doğrulamayı etkinleştir ve yönetici kullanıcı oluştur.","engines":{"mongodb":"// mongod.conf:\nsecurity:\n  authorization: enabled\n// Yönetici kullanıcı oluştur (localhost exception ile ilk kez):\nuse admin\ndb.createUser({ user: \"admin\", pwd: passwordPrompt(),\n  roles: [ { role: \"userAdminAnyDatabase\", db: \"admin\" } ] })\n// Sonra bağlanırken: mongosh -u admin --authenticationDatabase admin","redis":"# redis.conf — ACL (Redis 6+): varsayılan kullanıcıyı kapat, adlı kullanıcılar tanımla:\nuser default off\nuser admin on >YoneticiParola789! ~* &* +@all\nuser app on >AppParola456! ~app:* +@read +@write\n# Not: requirepass yalnızca 'default' kullanıcısının parolasını ayarlayan eski uyumluluk ayarıdır;\n# ACL kullanıcılarıyla karıştırmayın. Kullanıcıları aclfile içinde de tutabilirsiniz (ACL SAVE ile kalıcı).","elasticsearch":"# 8.x: güvenlik (kimlik doğrulama + TLS) ilk açılışta otomatik yapılandırılır; elasticsearch.yml:\nxpack.security.enabled: true\n# 'elastic' kullanıcısının parolasını belirle/sıfırla:\nbin/elasticsearch-reset-password -u elastic\n# (elasticsearch-setup-passwords 8.0'dan beri deprecated)\n# Kibana/istemciler için 'elastic' yerine ayrı rol'lü kullanıcı üret."}},{"title":"Ağı kısıtla — yalnızca gerekli arayüz ve portları aç","detail":"Servisi 0.0.0.0 üzerinde tüm dünyaya dinletmekten kaçın. Bağlanma adresini iç arayüze/loopback'e sabitle ve koruma modunu aç.","engines":{"mongodb":"# mongod.conf — yalnız iç arayüz + loopback:\nnet:\n  bindIp: 127.0.0.1,10.0.0.10\n  port: 27017\n# Asla bindIpAll: true kullanma; güvenlik duvarıyla portu sınırla.","redis":"# redis.conf:\nbind 127.0.0.1 10.0.0.10\nprotected-mode yes\nport 6379\n# protected-mode, parola yoksa dıştan erişimi engeller;\n# yine de güvenlik duvarıyla 6379'u sınırla.","elasticsearch":"# elasticsearch.yml — dinlenen arayüzü sabitle:\nnetwork.host: 10.0.0.10\nhttp.port: 9200\ntransport.port: 9300\n# Yalnız gerekli portları güvenlik duvarında aç;\n# 9300 (transport) dışarıya asla açılmamalı."}},{"title":"Tehlikeli komutları kısıtla","detail":"Tek bir komut tüm veriyi silebilir. Yıkıcı/idari komutları yeniden adlandır, kaldır veya joker (wildcard) hedeflemeyi engelle.","engines":{"mongodb":"// Ayrı komut engeli yerine rol bazlı kontrol kullan:\n// Yıkıcı ayrıcalıkları (dropDatabase, dropCollection) yalnız\n// dbAdmin/clusterAdmin rollerine ver; uygulama kullanıcısına verme.\ndb.grantRolesToUser(\"app\", [ { role: \"readWrite\", db: \"appdb\" } ])\n// Uygulama kullanıcısına dbAdmin/root VERME.","redis":"# Redis 6+ için tercih edilen yol ACL'dir (uygulama kullanıcısına tehlikeli komut verme):\n# ACL SETUSER app ... -@dangerous\n# Eski yöntem — redis.conf'ta komutları devre dışı bırak/yeniden adlandır:\nrename-command FLUSHALL \"\"\nrename-command FLUSHDB \"\"\nrename-command KEYS \"\"\nrename-command DEBUG \"\"\n# Dikkat: CONFIG'i yeniden adlandırmak Sentinel'i, CONFIG REWRITE'ı ve yönetim araçlarını bozabilir.","elasticsearch":"# elasticsearch.yml — joker/tüm indeks silmeyi engelle:\naction.destructive_requires_name: true\n# Böylece DELETE /* veya DELETE /_all reddedilir;\n# indeks adı açıkça belirtilmeden toplu silme yapılamaz."}},{"title":"TLS/şifreli bağlantı aç","detail":"Kimlik bilgileri ve veri açık ağda şifresiz gitmemeli. İstemci ve düğümler arası trafik için TLS etkinleştir.","engines":{"mongodb":"# mongod.conf — istemci TLS:\nnet:\n  tls:\n    mode: requireTLS\n    certificateKeyFile: /etc/ssl/mongodb.pem\n    CAFile: /etc/ssl/ca.pem\n# İstemci: mongosh --tls --tlsCAFile ca.pem","redis":"# redis.conf — TLS'i aç, düz portu kapat:\nport 0\ntls-port 6379\ntls-cert-file /etc/redis/redis.crt\ntls-key-file  /etc/redis/redis.key\ntls-ca-cert-file /etc/redis/ca.crt","elasticsearch":"# elasticsearch.yml — HTTP ve transport TLS:\nxpack.security.http.ssl.enabled: true\nxpack.security.http.ssl.keystore.path: http.p12\nxpack.security.transport.ssl.enabled: true\nxpack.security.transport.ssl.verification_mode: certificate\nxpack.security.transport.ssl.keystore.path: transport.p12"}},{"title":"En az yetki rolleri ver — geniş rollerden kaçın","detail":"Her kullanıcıya yalnız işi için gereken erişimi ver. Geniş/yönetici rolleri yerine belirli veritabanı, anahtar deseni veya index'e sınırlı ince roller kullan.","engines":{"mongodb":"// Geniş readWrite yerine yalnız gereken DB'ye ver;\n// gerekiyorsa özel rol tanımla:\ndb.createRole({ role: \"ordersRW\",\n  privileges: [ { resource: { db: \"appdb\", collection: \"orders\" },\n    actions: [ \"find\", \"insert\", \"update\" ] } ], roles: [] })\ndb.grantRolesToUser(\"app\", [ { role: \"ordersRW\", db: \"appdb\" } ])","redis":"# ACL ile anahtar deseni ve komut kategorisine sınırla:\nACL SETUSER app on >AppParola456! ~app:* +@read +@write -@dangerous\n# Yalnız 'app:' önekli anahtarlar, okuma/yazma; tehlikeli komutlar yasak.\nACL LIST\nACL WHOAMI","elasticsearch":"# İnce rol tanımla (yalnız belirli indekse okuma):\nPOST /_security/role/orders_read\n{ \"indices\": [ { \"names\": [ \"orders-*\" ],\n    \"privileges\": [ \"read\" ] } ] }\n# Kullanıcıya ata:\nPOST /_security/user/app\n{ \"password\": \"...\", \"roles\": [ \"orders_read\" ] }"}},{"title":"Denetim/loglama aç — erişim ve değişiklikleri izle","detail":"Yetkisiz erişim denemeleri ve idari işlemler kayıt altına alınmalı. Audit log etkinleştir ve merkezi bir yere gönder.","engines":{"mongodb":"# Denetim (MongoDB Enterprise gerektirir) — mongod.conf:\nauditLog:\n  destination: file\n  format: JSON\n  path: /var/log/mongodb/audit.json\n# Filtre: authenticate, createUser, dropDatabase gibi olayları yakala.","redis":"# Redis'te tam audit yoktur; ACL LOG ile reddedilen\n# kimlik doğrulama/komut denemelerini gör:\nACL LOG\nACL LOG RESET\n# Ayrıca: loglevel notice ve logfile ayarlarını merkezi toplayıcıya yönlendir.","elasticsearch":"# elasticsearch.yml — güvenlik denetimini aç:\nxpack.security.audit.enabled: true\nxpack.security.audit.logfile.events.include:\n  [ authentication_failed, access_denied, connection_denied ]\n# Kayıtlar <cluster>_audit.json dosyasına yazılır."}}],"related":["list-users","create-user-grant","enable-audit","change-password"]}]},"playbooks/cloud.json":{"schemaVersion":1,"playbooks":[{"id":"cloud-managed-db","title":"Bulut-yönetilen veritabanları (RDS/Aurora/Cloud SQL/Atlas/Azure SQL)","icon":"☁️","symptom":"Amaç: Bulut-yönetilen (managed) veritabanlarını kendi kendine yönetilen (self-managed) kurulumlardan ayıran temel farkları öğren; yedek, parametre, failover, izleme, yükseltme ve bağlantının bulutta nasıl çalıştığını kavra.","steps":[{"title":"Zihniyet farkı: sunucuya değil servise erişirsin","detail":"Managed veritabanlarında OS'e, dosya sistemine veya veritabanı sürecine kabuk (shell) erişimin YOKTUR; SSH yapamaz, konfig dosyalarını elle düzenleyemez, süper kullanıcı olamazsın. Yalnızca sağlayıcının verdiği yönetim API/konsolu ve normal SQL bağlantısı vardır. AWS RDS/Aurora: yönetim tüm kaynak (instance/cluster) düzeyinde, sunucu gizli. GCP Cloud SQL: yalnızca instance API'si, OS yok. MongoDB Atlas: tam yönetilen küme, mongod'a erişim yok. Azure SQL Database: PaaS, altta ne sunucu ne OS görünür (Managed Instance biraz daha fazla kontrol verir). Bu yüzden 'dosyaya bak', 'süreç öldür', 'OS aracını çalıştır' gibi self-managed reflekslerinin çoğu geçersizdir."},{"title":"Yedekleme: otomatik snapshot + point-in-time recovery (PITR)","detail":"Yedeği sen zamanlamaz, sağlayıcı otomatik alır; geri dönüş genelde 'belirli bir ana geri yükle' (PITR) veya snapshot'tan yeni instance oluşturma şeklindedir; mevcut instance'ın üzerine yazılmaz. AWS RDS/Aurora: otomatik yedekler + saklama penceresi; PITR ile saniye hassasiyetinde geri yükleme yeni bir instance/cluster olarak açılır; manuel snapshot da alınabilir. GCP Cloud SQL: otomatik yedekler + binary log ile PITR; geri yükleme yeni instance'a. MongoDB Atlas: sürekli cloud backup + PITR (M10+); snapshot'tan restore. Azure SQL: otomatik yedekler yerleşik, 1-35 gün saklama, herhangi bir ana PITR ve silinen DB için restore. Ortak kural: yedek yapılandırmasını (pencere, saklama süresi) doğrula ve düzenli restore testi yap."},{"title":"Parametreler: konfig dosyası değil, parameter group / flags","detail":"postgresql.conf veya my.cnf'i elle düzenlemek yerine sağlayıcının parametre soyutlamasını kullanırsın; bazı parametreler kilitlidir ve bir kısmı yeniden başlatma (static) ister. AWS RDS/Aurora: DB parameter group (ve cluster parameter group) ile ayar; dynamic parametreler anında, static olanlar reboot ile uygulanır. GCP Cloud SQL: 'database flags' konsoldan/gcloud ile ayarlanır. MongoDB Atlas: sınırlı 'Additional Settings' + oplog boyutu vb.; çoğu iç parametre yönetilir. Azure SQL: sunucu düzeyi ayarların çoğu yönetilir; davranış SCOPED CONFIGURATION ve service tier seçimiyle değişir. Uygulamadan önce parametrenin dynamic mi static mi olduğunu kontrol et."},{"title":"Yüksek erişilebilirlik / failover: yönetilen Multi-AZ ve replikalar","detail":"Failover'ı sen kurmaz, bir kutu işaretleyip sağlayıcıya bırakırsın; standby ve otomatik geçiş yönetilir, bağlantı sabit bir endpoint üzerinden yeni primary'ye yönlenir. AWS RDS: Multi-AZ (senkron standby, otomatik failover); Aurora: çok replikalı depolama + otomatik failover, cluster endpoint yazar'a yönlenir. GCP Cloud SQL: HA yapılandırması (regional, yedek bölgede standby) tek tıkla; okuma replikaları ayrıca eklenir. MongoDB Atlas: replica set zaten yerleşik, çok bölgeli/çok bulutlu yayılım seçilebilir, failover otomatik. Azure SQL: yerleşik HA (Business Critical'de yerel replikalar), zone-redundant seçeneği ve bölgeler arası active geo-replication / failover group. Uygulama daima endpoint'e bağlanmalı, sabit IP'ye değil."},{"title":"İzleme: sağlayıcının metrik ve log servisi","detail":"OS araçlarını (top, iostat) çalıştıramadığın için izlemeyi sağlayıcının metrik platformundan yaparsın; CPU, bağlantı sayısı, IOPS, replikasyon gecikmesi ve depolama metrikleri buradadır. AWS: CloudWatch metrikleri + Enhanced Monitoring + Performance Insights (sorgu düzeyi analiz). GCP Cloud SQL: Cloud Monitoring (eski Stackdriver) + Query Insights. MongoDB Atlas: yerleşik Atlas metrics/charts + Performance Advisor + gerçek zamanlı panel. Azure SQL: Azure Monitor + SQL Analytics + Query Performance Insight. Eşik alarmlarını (storage doluluğu, CPU, bağlantı limiti, replica lag) mutlaka kur."},{"title":"Sürüm yükseltme ve bakım: konsoldan, bakım penceresinde","detail":"Binary'yi elle güncellemek yerine bir hedef sürüm seçersin; küçük sürüm yamaları çoğunlukla otomatik, büyük sürüm yükseltmeleri planlı ve genelde kesinti/HA failover ile olur. AWS RDS/Aurora: engine version seçimi + otomatik minor upgrade seçeneği + Blue/Green Deployments ile düşük riskli major upgrade. GCP Cloud SQL: maintenance window + self-service major version upgrade. MongoDB Atlas: sürüm yükseltme tek tıkla, yuvarlanan (rolling) biçimde kesintisize yakın. Azure SQL: platform tarafından otomatik yamalanır (sürüm kavramı büyük ölçüde soyutlanmıştır); compatibility level ile davranış ayarlanır. Her zaman önce test/staging kopyada dene ve bakım penceresini iş dışı saate al."},{"title":"Bağlantı ve güvenlik: endpoint + IAM/TLS","detail":"Bağlantı her zaman sağlayıcının verdiği DNS endpoint'i üzerinden ve şifreli (TLS) yapılır; ağ erişimi ve kimlik bulut kimlik sistemine bağlanabilir. AWS RDS/Aurora: instance/cluster endpoint + Security Group ile ağ + isteğe bağlı IAM database authentication + TLS (rds-ca sertifikası). GCP Cloud SQL: public IP + Authorized Networks veya private IP/VPC, Cloud SQL Auth Proxy, IAM database authentication, TLS. MongoDB Atlas: SRV connection string (mongodb+srv://), IP access list + private endpoint/peering, SCRAM veya IAM/X.509, TLS zorunlu. Azure SQL: sunucu FQDN endpoint + firewall/Private Link + Microsoft Entra ID (eski Azure AD) kimlik doğrulama + TLS zorunlu. Kural: bağlantı dizesinde sabit IP değil endpoint kullan, TLS'i zorla ve mümkünse bulut IAM kimliğiyle bağlan."}],"related":["last-backup-status","promote-failover","connect-cli"]}]},"playbooks/automation.json":{"schemaVersion":1,"playbooks":[{"id":"auto-ansible","title":"Ansible ile veritabanı otomasyonu","icon":"🤖","symptom":"Amaç: Veritabanı kurulum, yapılandırma, kullanıcı ve yedek işlerini Ansible ile tekrarlanabilir ve idempotent (aynı playbook'u tekrar çalıştırınca sistemi bozmayan) hale getir.","steps":[{"title":"Envanteri ve grupları tanımla","detail":"Hangi sunucuların hangi veritabanı rolünde olduğunu envanterde grupla; primary, replika ve yedek sunucularını ayrı gruplara koy. Statik INI/YAML envanteri veya bulut için dinamik envanter (aws_ec2, gcp_compute) kullan. Grup değişkenlerini group_vars/ altına, sunucuya özel olanları host_vars/ altına yaz.","engines":{"postgres":"[pg_primary]\ndb1.ornek.local\n\n[pg_replica]\ndb2.ornek.local\n\n[postgres:children]\npg_primary\npg_replica"}},{"title":"Doğru koleksiyonu kur (community.postgresql / community.mysql / community.mongodb)","detail":"Ansible çekirdeği veritabanı modüllerini artık ayrı koleksiyonlarda tutar; kullandığın motora göre koleksiyonu requirements.yml ile kur. PostgreSQL için community.postgresql (postgresql_db, postgresql_user, postgresql_privs), MySQL/MariaDB için community.mysql (mysql_db, mysql_user), MongoDB için community.mongodb koleksiyonunu kullan. Hedef sunucuda ilgili Python istemcisi (psycopg2, PyMySQL, pymongo) kurulu olmalı.","engines":{"postgres":"# requirements.yml\ncollections:\n  - name: community.postgresql\n\n# kur:\nansible-galaxy collection install -r requirements.yml","mysql":"collections:\n  - name: community.mysql","mongodb":"collections:\n  - name: community.mongodb"}},{"title":"Sırları Ansible Vault ile şifrele","detail":"Veritabanı parolalarını, replikasyon sırlarını ve süper kullanıcı bilgilerini düz metin bırakma; ansible-vault ile şifreli bir değişken dosyasında tut. Çalıştırırken --ask-vault-pass veya --vault-password-file ile aç. Böylece sırlar Git'te güvenle saklanır ve playbook idempotent kalır.","engines":{"postgres":"ansible-vault create group_vars/postgres/vault.yml\n# içine:\nvault_pg_admin_password: \"S3cret!\"\n\n# çalıştır:\nansible-playbook site.yml --ask-vault-pass"}},{"title":"Rol yapısını kur (roles/postgres, roles/mysql)","detail":"Her motor için bir rol oluştur ve mantığı tasks/, defaults/, templates/, handlers/ alt klasörlerine böl. Bu yapı yeniden kullanılabilirliği artırır: defaults/main.yml varsayılan değerler, templates/ ile jinja2 yapılandırma şablonları, handlers/ ile 'yalnızca değişiklik olursa yeniden başlat' mantığı. Rolü ansible-galaxy init roles/postgres ile iskeletleyebilirsin.","engines":{"postgres":"ansible-galaxy init roles/postgres\n# roles/postgres/\n#   defaults/main.yml\n#   tasks/main.yml\n#   templates/postgresql.conf.j2\n#   handlers/main.yml"}},{"title":"Kurulum ve yapılandırma görevlerini idempotent yaz","detail":"Paketi kur, veri dizinini başlat ve postgresql.conf/my.cnf'i şablondan üret; yapılandırma değişince handler ile servisi yeniden başlat. Modüller idempotenttir: paket zaten kuruluysa tekrar kurmaz, dosya değişmediyse handler tetiklenmez. Yapılandırma şablonunu template modülüyle bas ve 'notify' ile handler'a bağla.","engines":{"postgres":"- name: postgresql.conf şablonu\n  ansible.builtin.template:\n    src: postgresql.conf.j2\n    dest: /etc/postgresql/16/main/postgresql.conf\n  notify: restart postgresql\n\n# handlers/main.yml\n- name: restart postgresql\n  ansible.builtin.service:\n    name: postgresql\n    state: restarted","mysql":"- name: my.cnf şablonu\n  ansible.builtin.template:\n    src: my.cnf.j2\n    dest: /etc/mysql/my.cnf\n  notify: restart mysql"}},{"title":"Veritabanı ve kullanıcı görevlerini tanımla","detail":"Veritabanını, kullanıcıları ve yetkileri modüllerle oluştur; parolayı Vault değişkeninden al. community.postgresql modülleri idempotenttir: kullanıcı/DB varsa yeniden oluşturmaz, yalnızca farkı uygular. Yetkileri postgresql_privs ile ayrı ver; MySQL'de mysql_user içindeki priv alanı kullanılır.","engines":{"postgres":"- name: uygulama veritabanı\n  community.postgresql.postgresql_db:\n    name: uygulama\n    state: present\n\n- name: uygulama kullanıcısı\n  community.postgresql.postgresql_user:\n    name: uygulama_user\n    password: \"{{ vault_app_password }}\"\n    db: uygulama\n    state: present","mysql":"- name: uygulama kullanıcısı\n  community.mysql.mysql_user:\n    name: uygulama_user\n    password: \"{{ vault_app_password }}\"\n    priv: 'uygulama.*:ALL'\n    state: present"}},{"title":"Yedek görevini ve zamanlamayı ekle","detail":"Yedek betiğini şablonla yerleştir ve ansible.builtin.cron ile zamanla; böylece yedek işi de kod olarak (as code) yönetilir. Yedek dosyalarının hedef dizinini, saklama süresini ve zamanlamayı değişken yap. Cron modülü idempotenttir ve girdiyi 'name' ile tanır, tekrar çalıştırınca kopyalamaz.","engines":{"postgres":"- name: gece yedeği (cron)\n  ansible.builtin.cron:\n    name: \"pg dump gece\"\n    minute: \"0\"\n    hour: \"2\"\n    job: \"pg_dump -Fc uygulama > /yedek/uygulama_$(date +\\\\%F).dump\""}}],"related":["schedule-job","check-version","logical-dump"]},{"id":"auto-terraform","title":"Terraform ile veritabanı provisioning (IaC)","icon":"🏗️","symptom":"Amaç: Veritabanı altyapısını (instance, parametre grubu, ağ) Terraform ile kod olarak (Infrastructure as Code) tanımla; plan/apply akışı, uzak state ve drift yönetimini kur.","steps":[{"title":"Provider'ı seç ve yapılandır (aws / google / azurerm)","detail":"Hangi bulutta çalıştığına göre provider'ı tanımla ve sürümünü sabitle. AWS için hashicorp/aws, GCP için hashicorp/google, Azure için hashicorp/azurerm provider'ını required_providers bloğunda kilitle. Sürüm kilidi, ekip arasında tutarlı davranış sağlar.","engines":{"postgres":"terraform {\n  required_providers {\n    aws = {\n      source  = \"hashicorp/aws\"\n      version = \"~> 5.0\"\n    }\n  }\n}\n\nprovider \"aws\" {\n  region = \"eu-central-1\"\n}"}},{"title":"Uzak state ve kilidi (remote state) kur","detail":"State dosyasını yerelde bırakma; ekip çalışması ve güvenlik için uzak backend kullan. AWS'de S3 backend + DynamoDB kilit tablosu, GCP'de gcs backend, Azure'da azurerm backend (Storage Account) yaygındır. Uzak state eşzamanlı apply'ları kilitle önler ve state'i tek doğru kaynak yapar. State içinde parolalar düz metin durabileceği için backend'i şifreli ve erişimi kısıtlı tut.","engines":{"postgres":"terraform {\n  backend \"s3\" {\n    bucket         = \"sirket-tfstate\"\n    key            = \"db/terraform.tfstate\"\n    region         = \"eu-central-1\"\n    dynamodb_table = \"tf-lock\"\n    encrypt        = true\n  }\n}"}},{"title":"Veritabanı kaynağını tanımla","detail":"Motor ve buluta göre ana kaynağı yaz: AWS'de aws_db_instance (veya Aurora için aws_rds_cluster), GCP'de google_sql_database_instance, Azure'da azurerm_mssql_database (SQL Server için, altında azurerm_mssql_server ile). Engine, sürüm, sınıf, depolama ve yedek penceresini burada belirt.","engines":{"postgres":"resource \"aws_db_instance\" \"pg\" {\n  identifier        = \"uygulama-db\"\n  engine            = \"postgres\"\n  engine_version    = \"16\"\n  instance_class    = \"db.t3.medium\"\n  allocated_storage = 50\n  db_name           = \"uygulama\"\n  username          = \"pgadmin\"\n  password          = var.db_password\n  backup_retention_period = 7\n}","mssql":"resource \"azurerm_mssql_database\" \"db\" {\n  name      = \"uygulama\"\n  server_id = azurerm_mssql_server.srv.id\n  sku_name  = \"S1\"\n}"}},{"title":"Parametre grubunu kod olarak yaz","detail":"Veritabanı ayarlarını (max_connections, work_mem, karakter seti) konsoldan elle değil, parametre kaynağıyla tanımla. AWS'de aws_db_parameter_group, GCP'de google_sql_database_instance içindeki settings.database_flags, Azure'da server yapılandırma kaynağı kullanılır. Böylece ayarlar sürümlenir ve tekrar üretilebilir.","engines":{"postgres":"resource \"aws_db_parameter_group\" \"pg\" {\n  name   = \"uygulama-pg16\"\n  family = \"postgres16\"\n\n  parameter {\n    name  = \"max_connections\"\n    value = \"200\"\n  }\n}\n# aws_db_instance içinde:\n# parameter_group_name = aws_db_parameter_group.pg.name"}},{"title":"Sırları değişken ve secret yöneticisiyle ver","detail":"Parolayı .tf dosyasına düz yazma; hassas değişken (variable ... sensitive = true) olarak tanımla ve değeri TF_VAR_ ortam değişkeni, secret yöneticisi (AWS Secrets Manager, Vault) veya CI secret'ından ver. Unutma: değer state dosyasına yazılır, bu yüzden uzak state şifreli olmalı. En temizi parolayı Terraform'a hiç girmeyip secret manager kaynağından okumaktır.","engines":{"postgres":"variable \"db_password\" {\n  type      = string\n  sensitive = true\n}\n\n# CI/kabuk:\nexport TF_VAR_db_password=\"$(vault kv get -field=pw secret/db)\""}},{"title":"plan ve apply akışını çalıştır","detail":"Önce terraform init ile provider/backend'i hazırla, terraform plan ile ne değişeceğini gör, onayla ve terraform apply ile uygula. Plan çıktısını gözden geçirmeden apply etme; CI'da 'plan'ı PR'a yorum olarak koyup insan onayından sonra apply etmek güvenli akıştır. Yıkıcı değişiklikleri (örneğin instance yeniden oluşturma) plan çıktısında -/+ işaretinden yakala.","engines":{"postgres":"terraform init\nterraform plan -out=plan.tfplan\nterraform apply plan.tfplan"}},{"title":"Drift'i tespit et ve düzelt","detail":"Biri konsoldan elle değişiklik yaparsa gerçek altyapı ile state uyuşmaz (drift). terraform plan çalıştırıp 'değişiklik yokken' çıkan farklar drift'i gösterir; terraform refresh/plan ile fark okunur. Ya değişikliği koda geri yansıt ya da apply ile altyapıyı koda geri çek. Elle değişikliği kural olarak yasakla, tek doğru kaynak kod olsun.","engines":{"postgres":"# drift kontrolü (değişiklik beklemiyorken):\nterraform plan\n# 'No changes' bekle; fark çıkarsa drift var\n# import ile mevcut kaynağı state'e al:\nterraform import aws_db_instance.pg uygulama-db"}}],"related":["check-version","apply-patch","schedule-job"]},{"id":"auto-k8s-operator","title":"Kubernetes'te veritabanı (operator)","icon":"☸️","symptom":"Amaç: Kubernetes üzerinde veritabanını bir operator ile çalıştır; StatefulSet yerine operator'ün sağladığı otomatik failover, kalıcı depolama ve yedek özelliklerini kullan.","steps":[{"title":"Neden operator: StatefulSet tek başına yetmez","detail":"Düz StatefulSet sana kalıcı kimlikli pod'lar ve PVC verir ama failover, replikasyon kurulumu, yedek ve yükseltme mantığını vermez. Operator, veritabanına özel bu operasyonel bilgiyi bir denetleyici (controller) + özel kaynak (CRD) olarak paketler. Yani 'Cluster' adında bir CR yazarsın, operator arkada StatefulSet, Service, Secret ve yedek işlerini yönetir. Üretimde veritabanını genelde operator ile çalıştırmak tercih edilir.","engines":{"postgres":"# operator'ler PostgreSQL için:\n#  - CloudNativePG (CNPG)\n#  - Zalando postgres-operator\n#  - Crunchy PGO"}},{"title":"Operator'ü seç ve kur","detail":"Motora göre operator seç: PostgreSQL için CloudNativePG veya Zalando postgres-operator; MySQL ve MongoDB için Percona operatörleri (Percona Operator for MySQL / for MongoDB) yaygındır. Operator'ü Helm veya bundle manifest ile kur; bu adımda CRD'ler ve denetleyici pod'u kümeye eklenir.","engines":{"postgres":"# CloudNativePG kurulumu\nkubectl apply --server-side -f \\\n  https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/main/releases/cnpg-1.24.0.yaml","mysql":"# Percona Operator for MySQL (Helm)\nhelm install my-op percona/pxc-operator","mongodb":"# Percona Operator for MongoDB (Helm)\nhelm install psmdb-op percona/psmdb-operator"}},{"title":"Depolamayı (StorageClass / PVC) planla","detail":"Veritabanı durumu (state) PVC'lerde tutulur; hangi StorageClass'ın kullanılacağını CR'da belirt. Düşük gecikmeli, bloklu (block) ve mümkünse yerel-benzeri SSD sağlayan bir StorageClass seç; ağ dosya sistemi (NFS) çoğu veritabanı için önerilmez. PVC boyutunu ve genişletilebilirliği (allowVolumeExpansion) baştan doğru ayarla, çünkü küçültmek zordur.","engines":{"postgres":"spec:\n  storage:\n    storageClass: fast-ssd\n    size: 50Gi"}},{"title":"Cluster CR'ını uygula (replika ve otomatik failover)","detail":"İnstance/replika sayısını CR'da ver; operator senkron/asenkron replikasyonu kurar ve primary düşerse otomatik failover yaparak bir replikayı terfi ettirir. Uygulama, operator'ün oluşturduğu '-rw' (okuma-yazma) Service'ine bağlanmalı; bu servis her zaman güncel primary'ye yönlenir. Böylece failover sırasında bağlantı hedefi değişmez.","engines":{"postgres":"apiVersion: postgresql.cnpg.io/v1\nkind: Cluster\nmetadata:\n  name: uygulama-db\nspec:\n  instances: 3\n  storage:\n    storageClass: fast-ssd\n    size: 50Gi\n# uygulama şuna bağlanır: uygulama-db-rw"}},{"title":"Yedeklemeyi CR ile S3'e yaz","detail":"Operator'ler yedeği de bildirimsel (declarative) yönetir: birincil yedek hedefini (object storage/S3) ve WAL arşivlemeyi CR'da tanımlarsın. CloudNativePG'de spec.backup.barmanObjectStore ile S3 bilgisi verilir (1.26'dan beri deprecated; yeni kurulumlarda Barman Cloud Plugin ve ObjectStore kaynağını kullan); sürekli WAL arşivi + baz yedek ile point-in-time recovery mümkün olur. Kimlik bilgilerini Kubernetes Secret'tan referansla.","engines":{"postgres":"spec:\n  backup:\n    barmanObjectStore:\n      destinationPath: s3://sirket-yedek/uygulama-db\n      s3Credentials:\n        accessKeyId:\n          name: s3-creds\n          key: ACCESS_KEY_ID\n        secretAccessKey:\n          name: s3-creds\n          key: SECRET_ACCESS_KEY"}},{"title":"Zamanlanmış yedek ve geri yükleme CR'ı","detail":"Tek seferlik yedek için Backup, zamanlanmış için ScheduledBackup CR'ı oluştur; cron ifadesiyle düzenli baz yedek al. Geri yüklemeyi de bildirimsel yaparsın: yeni bir Cluster'ı 'bootstrap.recovery' ile mevcut object store yedeğinden başlatırsın. Restore tatbikatını düzenli yap; yalnızca yedek almak yetmez, geri dönüşü test et.","engines":{"postgres":"apiVersion: postgresql.cnpg.io/v1\nkind: ScheduledBackup\nmetadata:\n  name: gece-yedek\nspec:\n  schedule: \"0 0 2 * * *\"\n  cluster:\n    name: uygulama-db"}}],"related":["setup-cdc-replication","logical-dump","restore-dump"]},{"id":"auto-schema-migration","title":"Şema migration CI/CD (Flyway/Liquibase)","icon":"🧬","symptom":"Amaç: Veritabanı şema değişikliklerini versiyonlu migration dosyalarıyla yönet; Flyway veya Liquibase ile CI/CD içinde otomatik ama kontrollü uygula.","steps":[{"title":"Versiyonlu migration dosyaları oluştur (Vxxx__ad.sql)","detail":"Her şema değişikliğini artan sürüm numaralı, adlandırılmış bir dosyaya yaz; Flyway kuralı V<versiyon>__<açıklama>.sql biçimindedir (örn. V1__ilk_semalar.sql, V2__siparis_tablosu.sql). Bu dosyalar Git'te tutulur ve sıra numarasına göre uygulanır. Uygulanmış migration'lar bir izleme tablosunda (Flyway'de flyway_schema_history) kaydedilir, böylece her migration tam bir kez çalışır.","engines":{"postgres":"-- V2__siparis_tablosu.sql\nCREATE TABLE siparis (\n  id       bigserial PRIMARY KEY,\n  tutar    numeric(12,2) NOT NULL,\n  olusma   timestamptz DEFAULT now()\n);"}},{"title":"Checksum ile değişmezliği koru","detail":"Flyway/Liquibase her uygulanmış migration'ın checksum'ını (özet) saklar. Zaten uygulanmış bir dosyayı sonradan düzenlersen checksum tutmaz ve araç hata verir. Kural: uygulanmış bir migration'ı ASLA düzenleme; düzeltmeyi yeni bir sürüm dosyasıyla yap. Bu, tüm ortamların (dev/staging/prod) aynı geçmişi paylaşmasını garanti eder.","engines":{"postgres":"# checksum uyuşmazlığında onarım (dikkatli kullan):\nflyway repair\n# doğru yol: değişikliği yeni Vx dosyasıyla ekle"}},{"title":"Mevcut veritabanına baseline uygula","detail":"Migration aracını zaten dolu, geçmişsiz bir veritabanına bağlarken baseline kullan; bu mevcut durumu 'başlangıç sürümü' kabul eder ve eski nesneleri yeniden oluşturmaya çalışmaz. baselineVersion'dan sonraki migration'lar uygulanır. Sıfırdan kurulan ortamda baseline gerekmez, migration'lar V1'den itibaren çalışır.","engines":{"postgres":"flyway baseline -baselineVersion=1 -baselineDescription=\"mevcut sema\""}},{"title":"CI pipeline'da otomatik migrate et","detail":"CI adımında migration aracını çalıştırıp değişiklikleri test ve staging veritabanına otomatik uygula; migrate komutu yalnızca yeni (uygulanmamış) dosyaları çalıştırır, idempotenttir. Önce migration'ı geçici/ephemeral bir veritabanına uygulayıp doğrulamak, bozuk SQL'i prod'a gitmeden yakalar. Uygulama kodu deploy'undan ÖNCE şema migrate edilmeli (geriye uyumlu değişimlerle).","engines":{"postgres":"# CI adımı (Flyway)\nflyway -url=jdbc:postgresql://staging/uygulama \\\n  -user=ci -password=$PW migrate","mysql":"flyway -url=jdbc:mysql://staging/uygulama \\\n  -user=ci -password=$PW migrate"}},{"title":"Prod'da manuel onay kapısı koy","detail":"Test/staging otomatik, ama prod migrate'ini elle onaya bağla; CI/CD içinde bir 'approval gate' (manuel onay) adımı ekle. Onaydan önce 'flyway info' veya 'liquibase status' ile hangi migration'ların çalışacağını göster. Prod'a uygulamadan önce mutlaka güncel bir yedek al; böylece sorun olursa geri dönebilirsin.","engines":{"postgres":"# onaydan önce ne çalışacak?\nflyway info\n# liquibase karşılığı:\nliquibase status --verbose"}},{"title":"Geri alınabilirlik ve rollback stratejisi belirle","detail":"Flyway Community'de otomatik geri alma yoktur; düz ileri (forward-only) migration ilkesini benimse: bir hatayı geri almak yerine düzelten yeni bir migration yaz. Liquibase changeset'lerinde rollback bloğu tanımlanabilir ve 'liquibase rollback' ile geri alınabilir. En sağlam strateji: değişimleri küçük ve geriye uyumlu tut, riskli işlemlerden (kolon silme) önce yedek al, geri dönüş planını yazılı hazırla.","engines":{"postgres":"-- Liquibase rollback örneği (changeset içinde)\n--changeset dev:2\nCREATE TABLE siparis (...);\n--rollback DROP TABLE siparis;"}}],"related":["apply-patch","logical-dump","check-version"]},{"id":"auto-backup","title":"Otomatik yedekleme (pgBackRest/Barman/Xtrabackup/cron)","icon":"💾","symptom":"Amaç: Veritabanı yedeklerini otomatikleştir; zamanlanmış full+incremental+WAL/binlog arşivi, saklama (retention), doğrulama ve offsite kopya ile güvenilir bir kurtarma zinciri kur.","steps":[{"title":"Doğru yedek aracını seç","detail":"Motora göre araç seç: PostgreSQL için pgBackRest veya Barman (fiziksel yedek + WAL arşivi + PITR); MySQL/MariaDB için Percona XtraBackup (online fiziksel yedek) veya küçük veriler için mysqldump/mydumper (mantıksal). Fiziksel araçlar büyük veritabanlarında hızlı ve tutarlı yedek + point-in-time recovery sağlar; mantıksal dökümler taşınabilir ama büyük veride yavaştır.","engines":{"postgres":"# pgBackRest veya Barman","mysql":"# fiziksel: xtrabackup\n# mantıksal: mysqldump / mydumper"}},{"title":"Full + incremental + sürekli arşiv zincirini kur","detail":"Haftalık/günlük tam (full) yedek, aralarda artımlı (incremental/differential) yedek ve sürekli WAL (PostgreSQL) veya binlog (MySQL) arşivi ile point-in-time recovery kur. pgBackRest tam/diff/artımlı yedek tiplerini ve WAL arşivini yönetir; PostgreSQL'de archive_command'ı pgBackRest'e yönlendirirsin. Artımlı yedek + arşiv, herhangi bir ana dönebilmeni sağlar.","engines":{"postgres":"# postgresql.conf\narchive_mode = on\narchive_command = 'pgbackrest --stanza=uygulama archive-push %p'\n\n# tam yedek\npgbackrest --stanza=uygulama --type=full backup\n# artımlı\npgbackrest --stanza=uygulama --type=incr backup","mysql":"# tam\nxtrabackup --backup --target-dir=/yedek/full\n# artımlı\nxtrabackup --backup --target-dir=/yedek/incr1 \\\n  --incremental-basedir=/yedek/full"}},{"title":"Yedeği cron/timer ile zamanla","detail":"Yedek komutlarını cron veya systemd timer ile düzenli çalıştır: örneğin Pazar gece tam, diğer geceler artımlı. Zamanlamayı iş dışı saate al ve çakışmayı önlemek için full ve incr işlerinin üst üste binmediğinden emin ol. Çıktı loglarını bir yere yaz ve başarısızlıkta uyarı üret.","engines":{"postgres":"# crontab\n0 1 * * 0 pgbackrest --stanza=uygulama --type=full backup\n0 1 * * 1-6 pgbackrest --stanza=uygulama --type=incr backup"}},{"title":"Saklama (retention) politikası tanımla","detail":"Sonsuza dek yedek biriktirme; kaç tam yedek ve kaç günlük arşiv tutulacağını ayarla, araç eskiyeni otomatik temizlesin. pgBackRest'te repo1-retention-full ve arşiv saklama ayarlarıyla; Barman'da retention_policy ile yönetilir. Saklama süresi, kurtarma hedeflerinle (kaç gün geriye dönebilmen gerekiyor) uyumlu olmalı.","engines":{"postgres":"# pgbackrest.conf\n[global]\nrepo1-retention-full=4\nrepo1-retention-archive=8","mysql":"# eski yedekleri cron ile temizle (örnek)\nfind /yedek -type d -mtime +14 -exec rm -rf {} +"}},{"title":"Yedeği offsite / S3'e kopyala","detail":"Yedek, veritabanıyla aynı makinede/aynı bölgede kalmamalı; başka bir konuma veya nesne depolamaya (S3, GCS) kopyala. pgBackRest doğrudan S3 uyumlu depolamaya yazabilir; aksi halde rsync/rclone ile offsite bir hedefe senkronla. Felaket senaryosunda (yerel disk/bölge kaybı) yalnızca offsite kopya seni kurtarır.","engines":{"postgres":"# pgbackrest.conf S3 deposu\n[global]\nrepo1-type=s3\nrepo1-s3-bucket=sirket-yedek\nrepo1-s3-region=eu-central-1\nrepo1-s3-endpoint=s3.eu-central-1.amazonaws.com"}},{"title":"Yedeği doğrula","detail":"Yedeğin var olması geri yüklenebildiği anlamına gelmez; bütünlüğü düzenli doğrula. pgBackRest'te 'verify' ve arşiv tutarlılığı kontrolleri, XtraBackup'ta hazırlama (--prepare) adımının başarısı yedeğin sağlamlığını gösterir. Otomatik bir işle her yedekten sonra doğrulama çalıştır ve başarısızlıkta alarm üret.","engines":{"postgres":"pgbackrest --stanza=uygulama verify","mysql":"# yedeği tutarlı hale getir (doğrulama)\nxtrabackup --prepare --target-dir=/yedek/full"}},{"title":"Düzenli restore tatbikatı yap","detail":"En kritik adım: yedeği ayrı bir sunucuya periyodik olarak GERÇEKTEN geri yükle ve veritabanının açıldığını, verinin tutarlı olduğunu doğrula. Bu tatbikat kurtarma süreni (RTO) ölçmeni ve prosedürdeki boşlukları test dışında yakalamanı sağlar. Test edilmemiş yedek, yedek sayılmaz.","engines":{"postgres":"# ayrı sunucuda geri yükleme + PITR\npgbackrest --stanza=uygulama \\\n  --type=time --target=\"2026-07-01 03:00:00\" restore","mysql":"# hazırlanmış yedeği veri dizinine geri koy\nxtrabackup --copy-back --target-dir=/yedek/full"}}],"related":["logical-dump","restore-dump","schedule-job"]},{"id":"auto-gitops-bluegreen","title":"GitOps & mavi-yeşil / sıfır kesinti dağıtım","icon":"🟦","symptom":"Amaç: Şema ve uygulama değişikliklerini kesintisiz dağıt; expand-contract (genişlet-daralt) migration, mavi-yeşil ortam, feature flag ve otomatik rollback ile sıfır kesintiye yaklaş.","steps":[{"title":"GitOps: Git tek doğru kaynak olsun","detail":"Hem altyapı hem şema migration'ları hem uygulama sürümü Git'te tanımlı olsun; dağıtım, depoya yapılan merge ile tetiklensin (GitOps). Bir uzlaştırıcı (Argo CD/Flux veya CI/CD) istenen durumu gerçek ortama uygular. Böylece her değişiklik denetlenebilir, tekrarlanabilir ve gerektiğinde bir önceki commit'e geri alınabilir.","engines":{"postgres":"# repo/\n#   migrations/  (Vxxx__*.sql)\n#   k8s/         (Deployment, Service)\n#   flags/       (feature flag config)"}},{"title":"Şemayı geriye uyumlu değiştir (expand-contract)","detail":"Sıfır kesinti için şemayı tek adımda kırıcı biçimde değiştirme; iki aşamaya böl. EXPAND: yeni yapıyı (yeni kolon/tablo) ekle, eski ve yeni kod aynı anda çalışabilsin (kolon nullable, varsayılanlı, çift yazma). Uygulama yeni yapıya geçtikten SONRA CONTRACT: artık kullanılmayan eski kolonu/tabloyu ayrı bir migration'da kaldır. Böylece dağıtım sırasında eski ve yeni uygulama sürümü yan yana sorunsuz çalışır.","engines":{"postgres":"-- EXPAND (V5): geriye uyumlu ekleme\nALTER TABLE musteri ADD COLUMN eposta text;\n\n-- kod her iki kolona da yazar/okur bir süre\n\n-- CONTRACT (V9): eski kolonu kaldır\nALTER TABLE musteri DROP COLUMN mail_eski;"}},{"title":"Riskli davranışı feature flag arkasına al","detail":"Yeni kod yolunu (yeni kolonu okuma gibi) bir feature flag ile koşullu çalıştır; şema hazır olunca flag'i aç, sorun olursa deploy'a dokunmadan kapat. Flag, kod dağıtımını (deploy) ile özelliğin devreye girmesini (release) ayırır. Böylece expand aşaması yayınlanır ama davranış değişikliği kontrollü açılır ve hızlı geri alınabilir.","engines":{"postgres":"-- uygulama katmanı (sözde kod)\n-- if flag('yeni_eposta_alani'):\n--     SELECT eposta FROM musteri ...\n-- else:\n--     SELECT mail_eski FROM musteri ..."}},{"title":"Mavi-yeşil ortamı kur","detail":"İki eş ortam tut: 'mavi' (canlı) ve 'yeşil' (yeni sürüm). Yeni uygulama sürümünü yeşile dağıt ve gerçek trafik almadan doğrula; hazır olunca yönlendiriciyi/trafiği yeşile çevir. Kritik nokta: veritabanı genelde PAYLAŞILIR, bu yüzden şema her iki sürümle de uyumlu olmalı (expand-contract bunu sağlar). Geçiş anında bağlantı hedefi değişse de şema uyumu sayesinde kesinti olmaz.","engines":{"postgres":"# trafik yeşile (yeni sürüm) çevrilir\n# DB paylaşımlı: şema hem mavi hem yeşil ile uyumlu olmalı"}},{"title":"İzleme ile dağıtımı doğrula (canary/gözlem)","detail":"Trafiği tam çevirmeden önce hata oranı, gecikme, veritabanı hata/lock sayısı ve replikasyon gecikmesi gibi metrikleri izle; istersen trafiğin küçük bir yüzdesini (canary) yeşile verip gözlemle. Sağlık göstergeleri iyiyse trafiği kademeli artır, kötüyse ilerleme. İzleme, otomatik rollback kararının girdisidir.","engines":{"postgres":"-- canlı sağlık sorguları\nSELECT count(*) FROM pg_stat_activity WHERE wait_event_type='Lock';\nSELECT * FROM pg_stat_replication;"}},{"title":"Otomatik rollback'i hazırla","detail":"Metrikler eşiği aşarsa dağıtım otomatik geri alınmalı: mavi-yeşilde trafiği hızla maviye (eski sürüm) döndür. Uygulama rollback'i anlıktır çünkü mavi hâlâ ayakta. Şema tarafında ise geri alma çoğu zaman GEREKMEZ: expand-contract sayesinde yeni şema eski kodla da uyumludur, dolayısıyla yalnızca uygulamayı geri almak yeter. Bu yüzden şema değişimini uygulama dağıtımından bağımsız ve daima geriye uyumlu tut.","engines":{"postgres":"# trafik anında maviye döner (uygulama rollback)\n# şema geri alınmaz: expand-contract eski kodla uyumlu\n# gerçekten gerekirse: düzeltici yeni migration yaz"}}],"related":["setup-cdc-replication","apply-patch","check-version"]}]},"install/index.json":{"schemaVersion":1,"categories":[{"id":"install","title":"Kurulum"},{"id":"ha","title":"Yüksek erişilebilirlik & replikasyon"},{"id":"backup","title":"Yedekleme & geri dönüş"},{"id":"ops","title":"Günlük işletim & arıza"},{"id":"pooling","title":"Bağlantı & yük dengeleme"},{"id":"patch","title":"Patch & minor güncelleme"},{"id":"upgrade","title":"Major upgrade & taşıma"},{"id":"monitoring","title":"İzleme & yönetim"},{"id":"security","title":"Güvenlik & sıkılaştırma"}],"guides":[{"id":"pg-install","file":"install/guides/pg-install.json","group":"PostgreSQL","engineId":"postgres","category":"install","title":"PostgreSQL tek sunucu kurulumu (üretime hazır)","summary":"Tek sunucuya PGDG repo'sundan üretime hazır PostgreSQL kurulumu: ayrı veri dizini, data checksums, RAM/CPU'ya göre hesaplanmış ayarlar, güvenli erişim (peer + scram-sha-256), loglama, pg_stat_statements, firewall ve SELi","level":"Başlangıç","duration":"30–45 dk","topology":"1 sunucu","tags":["postgresql","postgres","kurulum","install","pgdg","initdb","tuning","rhel","ubuntu"],"order":1,"steps":23,"scenarios":[]},{"id":"pg-streaming","file":"install/guides/pg-streaming.json","group":"PostgreSQL","engineId":"postgres","category":"ha","title":"PostgreSQL streaming replication (primary + standby)","summary":"Kurulu bir primary'ye pg_basebackup ile bir ya da daha fazla hot standby ekler (replikasyon kullanıcısı, pg_hba, replication slot, asenkron ya da senkron ANY/FIRST mod, gecikme izleme) ve bu Patroni'siz cluster'ın işleti","level":"Orta","duration":"45–90 dk","topology":"1 primary + 1..N standby","tags":["postgresql","streaming replication","replikasyon","standby","hot standby","pg_basebackup","replication slot","synchronous","senkron","failover","switchover","pg_promote","pg_rewind","ha","cascading","delayed standby","recovery_min_apply_delay","slot temizliği","pg_wal dolu","synchronous_standby_names","standby yeniden kur"],"order":2,"steps":24,"scenarios":[{"k":"mode","v":"install","l":"Kurulum: primary'ye standby ekle","m":"Standby ekle / yeniden kur streaming replication kur standby ekle hot standby pg_basebackup read replica okuma replikası physical replication fiziksel replikasyon standby.signal primary_conninfo Kurulu primary'ye pg_basebackup ile bir ya da daha fazla hot standby eklenir (slot, senkron/asenkron, izleme). Primary açık kalır; ilk kopya primary'ye disk ve ağ yükü bindirir."},{"k":"mode","v":"switchover","l":"Planlı switchover (rol değişimi, veri kaybı yok)","m":"Rol değişimi switchover planned switchover rol değişimi planlı geçiş primary bakımı standby'ı primary yap pg_promote pg_ctl promote Planlı bakım: primary temiz kapatılır, ilk standby promote edilir, eski primary standby olarak döner. Veri kaybı yok; yazma kesintisi genelde 1 dakikadan kısa."},{"k":"mode","v":"failover","l":"Manuel failover (primary çöktü, standby'ı promote et)","m":"Rol değişimi could not connect to the primary server Connection refused primary down primary çöktü primary erişilemiyor failover manual failover promote standby pg_promote split-brain could not receive data from WAL stream primary sunucu kayıp Primary çöktü ya da erişilemiyor: eski primary yalıtılır (fencing), en güncel standby elle promote edilir. Asenkron modda son işlemler kaybolabilir."},{"k":"mode","v":"rejoin","l":"Eski primary'yi pg_rewind ile standby olarak geri kat","m":"Rol değişimi requested timeline is not a child of this server's history target server must be shut down cleanly could not find previous WAL record pg_rewind diverged timeline eski primary geri kat rejoin old primary Failover sonrası eski primary pg_rewind ile yeni primary'ye eşitlenip standby olarak geri katılır; tam kopyadan çok daha hızlıdır."},{"k":"mode","v":"cascade","l":"Bir standby'dan beslenen yeni standby ekle (cascading)","m":"Standby ekle / yeniden kur cascading replication cascade standby zincirleme replikasyon standby'dan standby uzak veri merkezi DR standby Yeni standby WAL'ı primary yerine ilk standby'dan alır: uzak veri merkezi ya da çok standby'lı düzende primary'nin ağ/WAL gönderim yükü azalır. Primary etkilenmez."},{"k":"mode","v":"delayed","l":"Gecikmeli (delayed) standby kur","m":"Standby ekle / yeniden kur recovery_min_apply_delay delayed standby gecikmeli standby yanlışlıkla silindi DROP TABLE geri al accidental delete pg_wal_replay_pause WAL'ı saatler sonra uygulayan standby (`recovery_min_apply_delay`): yanlışlıkla silinen veriyi yedekten dönmeden kurtarmak için. Failover adayı değildir."},{"k":"mode","v":"rebuild","l":"Bir standby'ı sıfırdan yeniden kur","m":"Standby ekle / yeniden kur requested WAL segment has already been removed could not receive data from WAL stream database system identifier differs wal_status lost exceeds max_slot_wal_keep_size standby yeniden kur standby bozuk re-clone standby could not start WAL streaming wal_removed standby geride kaldı Standby geride kaldı, WAL'ı silinmiş ya da bozuk: veri dizini kenara alınır, primary'den ye"},{"k":"mode","v":"slotclean","l":"pg_wal büyüyor, disk doluyor (kullanılmayan slot temizliği)","m":"Bakım ve sorun giderme No space left on device could not write to file \"pg_wal pg_wal dolu pg_wal büyüyor WAL şişmesi disk doldu replication slot inactive max_slot_wal_keep_size pg_wal klasörü büyük WAL disk full WAL birikmesinin nedeni bulunur (pasif slot, arşiv hatası, wal_keep_size); kullanılmayan replication slot silinir, WAL alanı geri kazanılır. Primary açık kalır."},{"k":"mode","v":"syncchg","l":"Senkron standby ekle / çıkar (synchronous_standby_names)","m":"Bakım ve sorun giderme canceling wait for synchronous replication synchronous_standby_names COMMIT askıda commit hangs sync standby senkron standby sync_state potential synchronous_commit Senkron listesini formdaki moda (ANY/FIRST, k) göre yeniden yazar ya da asenkrona döner; reload ile uygulanır, restart gerekmez. Yanlış ayar commit'leri askıda bırakabilir; önce kontrol edilir."}]},{"id":"pg-patroni","file":"install/guides/pg-patroni.json","group":"PostgreSQL","engineId":"postgres","category":"ha","title":"Patroni + etcd + HAProxy ile otomatik failover cluster'ı","summary":"Otomatik failover'lı PostgreSQL cluster'ını kurar ve işletir: her node'da PostgreSQL'i Patroni yönetir, leader seçimi 3 (ya da 5) üyeli etcd'de yapılır, uygulamalar HAProxy'nin yazma (5000) ve okuma (5001) portlarına, is","level":"İleri","duration":"2–3 saat","topology":"3 PostgreSQL + etcd node'u (ortak ya da ayrı) + HAProxy (+ VIP)","tags":["postgresql","patroni","etcd","haproxy","keepalived","vip","otomatik failover","auto failover","switchover","ha","high availability","cluster","küme","patronictl","dcs","reinit","pg_rewind","edit-config","pause","resume","etcdctl member","quorum","failsafe","node ekle","node çıkar","patroni upgrade","cluster kapatma"],"order":3,"steps":40,"scenarios":[{"k":"mode","v":"install","l":"Kurulum: yeni Patroni cluster'ı","m":"Kurulum patroni kurulumu patroni install etcd kurulumu haproxy otomatik failover automatic failover high availability yüksek erişilebilirlik HA cluster Sıfırdan etcd + Patroni + HAProxy (+ VIP) cluster'ı kurulur. Sunucularda PostgreSQL cluster'ı olmamalı: initdb'yi Patroni yapar (pg-install uygulanmaz)."},{"k":"mode","v":"ops","l":"İşletim runbook'u: switchover, failover testi, bakım modu, parametre değişikliği","m":"Kontrol ve tatbikat failover testi failover test tatbikat DR drill runbook Yeni kurulmuş cluster'da temel işlemleri sırayla dener: durum, switchover, failover testi (lider durdurulur, kısa yazma kesintisi), bakım modu, parametre değişikliği. Bakım penceresinde uygulayın."},{"k":"mode","v":"health","l":"Cluster sağlıklı mı? (sağlık kontrolü)","m":"Kontrol ve tatbikat patronictl list Pending restart Maintenance mode: on start failed patroni health cluster durumu replica lag gecikme timeline farklı Salt okunur: roller, gecikme, timeline, REST API, etcd sağlığı, slotlar, bekleyen restart ve bakım modu."},{"k":"mode","v":"switchover","l":"Planlı switchover (leader'ı başka node'a al)","m":"Rol değişimi candidate name does not match with sync_standby Switchover failed does not exist in cluster or is tagged as nofailover switchover leader değiştir rol değişimi planlı bakım Bakım öncesi leader rolü kontrollü olarak bir replica'ya geçer; birkaç saniyelik yazma kesintisi, veri kaybı yok."},{"k":"mode","v":"rejoin","l":"Failover oldu, eski leader geri katılmıyor (pg_rewind / reinit)","m":"Rol değişimi requested timeline is not a child of this server's history could not find previous WAL record pg_rewind: error target server needs to use either data checksums or wal_log_hints start failed diverged eski leader failover sonrası pg_rewind: fatal could not find common ancestor timeline history mismatch Çöken eski leader açılınca replica olarak katılmalı; pg_rewind başarısızsa veri dizin"},{"k":"mode","v":"reinit","l":"Bir replica'yı sıfırdan yeniden kur (reinit)","m":"Üye bakımı requested WAL segment has already been removed could not receive data from WAL stream invalid record length invalid page patronictl reinit replica bozuk replica geride rebuild replica replica start failed creating replica Replica bozuk, çok geride ya da WAL'ı kaybetti: veri dizini silinir ve leader'dan (ya da yedekten) yeniden kurulur. Leader etkilenmez."},{"k":"mode","v":"addmember","l":"Cluster'a yeni node ekle","m":"Üye bakımı node ekle add member yeni replica scale out cluster büyüt Yeni node'u formdaki listenin sonuna ekleyin: yazılım kurulur, mevcut node'larda pg_hba ve HAProxy güncellenir, replica olarak katılır."},{"k":"mode","v":"rmmember","l":"Cluster'dan node çıkar","m":"Üye bakımı node çıkar remove member decommission sunucu iptal replica kaldır Replica olan bir node kalıcı olarak çıkarılır: Patroni durdurulur, DCS kaydı ve slot temizlenir, HAProxy'den kaldırılır."},{"k":"mode","v":"editcfg","l":"PostgreSQL ya da Patroni ayarını değiştir (edit-config)","m":"Ayar ve bakım edit-config Pending restart postgresql.conf ayarı kayboldu ALTER SYSTEM parametre değiştir max_connections shared_buffers change parameter work_mem parametre kaybolmuş ayar uygulanmıyor Ayar DCS'ye yazılır, tüm node'lara uygulanır; restart gerektiren ayarlarda `restart --pending` (önce replica'lar)."},{"k":"mode","v":"pause","l":"Bakım için otomatik failover'ı durdur (pause / resume)","m":"Ayar ve bakım Maintenance mode: on patronictl pause patronictl resume maintenance mode bakım modu otomatik failover kapat Pause'da Patroni PostgreSQL'e dokunmaz ve failover yapmaz; ağ/etcd bakımı ya da elle müdahale için. İş bitince resume."},{"k":"mode","v":"upgrade","l":"Patroni yazılımını yükselt (rolling)","m":"Ayar ve bakım patroni upgrade patroni güncelleme patroni sürüm dnf update patroni apt upgrade patroni patroni 3 to 4 Cluster pause'a alınır, node node Patroni güncellenip yeniden başlatılır; PostgreSQL kapanmaz, failover olmaz."},{"k":"mode","v":"stopstart","l":"Tüm cluster'ı durdur / başlat (doğru sıra)","m":"Ayar ve bakım cluster kapat cluster başlat shutdown order tam kapatma planlı kapatma veri merkezi bakımı elektrik kesintisi Planlı tam kapatma (depolama, veri merkezi bakımı): önce replica'lar, sonra leader, en son etcd; açılış tersi sırada."},{"k":"mode","v":"etcdmember","l":"etcd üyesini değiştir ya da ekle (etcdctl member)","m":"etcd (DCS) etcdserver: unhealthy cluster member has already been bootstrapped Peer URLs already exists member count is unequal etcdctl member etcd member add etcd member remove etcd üye unhealthy Bozulan etcd üyesi çıkarılıp yeni sunucu eklenir (ya da üye sayısı artırılır); Patroni'nin etcd listesi güncellenir."},{"k":"mode","v":"dcsloss","l":"etcd çoğunluğu kayboldu: leader salt okunur oldu","m":"etcd (DCS) Failed to get list of machines DCS is not accessible demoting self etcdserver: request timed out etcdserver: no leader cannot execute INSERT in a read-only transaction quorum failsafe etcd quorum lost leader yok no leader etcd quorum'u yoksa Patroni leader'ı salt okunur yapar, failover da olmaz. etcd geri getirilir ya da tek üyeden yeniden kurulur."}]},{"id":"pg-pgbouncer","file":"install/guides/pg-pgbouncer.json","group":"PostgreSQL","engineId":"postgres","category":"pooling","title":"PgBouncer bağlantı havuzu","summary":"PGDG repo'sundan PgBouncer kurulumu: transaction ya da session havuz modu, auth_query (SECURITY DEFINER fonksiyon) ya da userlist.txt ile scram-sha-256 kimlik doğrulama, veritabanının max_connections ve CPU değerine göre","level":"Orta","duration":"30–45 dk","topology":"PgBouncer veritabanı sunucusunda ya da ayrı sunucuda; Patroni'de HAProxy/VIP önünde","tags":["postgresql","pgbouncer","connection pool","bağlantı havuzu","pooling","transaction pooling","auth_query","userlist","scram-sha-256","so_reuseport","max_client_conn","default_pool_size","patroni","haproxy","vip","failover"],"order":4,"steps":15,"scenarios":[]},{"id":"pg-pgbackrest","file":"install/guides/pg-pgbackrest.json","group":"PostgreSQL","engineId":"postgres","category":"backup","title":"pgBackRest ile yedekleme ve PITR","summary":"pgBackRest ile tam / diferansiyel / artımlı yedek, sürekli WAL arşivi ve zamana göre geri dönüş (PITR). Tek sunucu, streaming replication (primary + standby'lar) ya da Patroni cluster'ı için; repo aynı sunucuda, ayrı bir","level":"Orta","duration":"45–90 dk","topology":"1 sunucu, primary + standby'lar ya da Patroni cluster'ı; isteğe bağlı yedek sunucusu","tags":["postgresql","pgbackrest","yedek","backup","restore","pitr","wal","archive","s3","minio","şifreleme","retention","geri dönüş","patroni","streaming","standby","cron","backup-standby","systemd timer","delta restore","db-include","target-action","restore point","xid","lsn","clone","klon","felaket","disaster recovery","verify","expire","type=standby","tatbikat"],"order":10,"steps":28,"scenarios":[{"k":"purpose","v":"kur","l":"pgBackRest kurulumu + ilk yedek + test restore","m":"Kurulum stanza-create archive_command archive-push pgbackrest kurulumu pgbackrest install yedekleme kur backup setup yedek planı full diff incr zamanlanmış yedek ERROR: [087] archive_mode must be enabled WAL arşivi kur ilk yedek pgBackRest henüz yok: yazılım, repo, WAL arşivi, ilk yedek, zamanlama ve bir test restore."},{"k":"purpose","v":"geri","l":"Felaket anı: yerinde restore (son duruma ya da zamana göre)","m":"Geri yükleme (aynı sunucu) recovery_target_time recovery_target_xid recovery_target_lsn pg_create_restore_point PITR point in time recovery zamana dönüş yanlışlıkla silindi DROP TABLE DELETE without WHERE UPDATE without WHERE TRUNCATE restore point restore to time veriyi geri al Veritabanını yerinde, yedekteki ve arşivdeki bir ana döndürün: son an, zaman, xid, LSN ya da restore point. Cluster kapa"},{"k":"purpose","v":"delta","l":"Veri dizininde bozuk ya da silinmiş dosya var (delta restore ile onar)","m":"Geri yükleme (aynı sunucu) invalid page in block could not read block page verification failed checksum verification failed could not open file \"base/ could not access status of transaction missing chunk number No such file or directory could not read file bozuk blok data corruption block corruption silinen veri dosyası ERROR:  could not read block PANIC:  could not open file PANIC:  could not rea"},{"k":"purpose","v":"dbinc","l":"Yalnız bir veritabanını geri getir (--db-include)","m":"Geri yükleme (aynı sunucu) db-include DROP DATABASE tek veritabanı single database restore veritabanı silindi tablo geri getir table restore tek tablo restore Cluster açık kalır: tek veritabanı geçici bir instance'a (ayrı dizin ve port) restore edilir, pg_dump ile alınıp canlı sunucuya yeni adla yüklenir. Silinen tek tablo için de bu kart (oradan `pg_dump -t`)."},{"k":"purpose","v":"clone","l":"Yedeği başka bir sunucuya geri yükle (klon / test / raporlama)","m":"Yeni sunucu: klon, felaket, standby repo1-cipher-pass clone klon test ortamı test ortamını yenile refresh test staging yeni sunucuya restore raporlama sunucusu şifreli repo Canlı sunucuya dokunulmaz. Yedek yeni bir sunucuya açılır; WAL arşivi kapatılır, böylece klon canlı repo'ya yazmaz. Şifreli repo'da anahtar istenir."},{"k":"purpose","v":"dr","l":"Sunucu tamamen kayboldu: yedeği yeni sunucuya aç ve yerine geçir","m":"Yeni sunucu: klon, felaket, standby PANIC: could not locate a valid checkpoint record felaket disaster recovery DR sunucu kaybı disk arızası server lost veri dizini kayboldu yeni primary şifreli repo could not open file \"global/pg_control\" sunucu açılmıyor PostgreSQL başlamıyor Disk ya da sunucu kaybı: yeni sunucu yedekten açılır ve yeni primary olur; WAL arşivi ve yedekler aynı stanza'da sürer. E"},{"k":"purpose","v":"standby","l":"Yedekten yeni bir standby kur (--type=standby)","m":"Yeni sunucu: klon, felaket, standby type=standby standby kur replica ekle yedekten standby standby rebuild pg_basebackup yerine add standby Primary'ye kopya yükü bindirmeden yeni standby: dosyalar yedekten gelir, eksik WAL arşivden ve streaming ile tamamlanır. Primary açık kalır."},{"k":"purpose","v":"verify","l":"Yedekler gerçekten sağlam mı? (info / check / verify ve restore tatbikatı)","m":"Kontrol ve bakım ERROR: [082] ERROR: [028] ERROR: [056] pgbackrest verify pgbackrest check pgbackrest info yedek doğrulama backup verification restore test tatbikat son yedek ne zaman verify command yedek sağlam mı restore drill aylık doğrulama Salt okunur kontroller ve canlı sunucuya dokunmayan, ayrı dizinde restore tatbikatı. Aylık doğrulama işi (cron) da kurulur."},{"k":"purpose","v":"retention","l":"Saklama süresini değiştir ve eski yedekleri temizle (expire)","m":"Kontrol ve bakım No space left on device WARN: option 'repo1-retention-full' is not set repo1-retention-full expire retention saklama repo doldu yedek diski dolu eski yedekleri sil repo dolu bucket dolu yedek diski doldu repo1-retention-full/diff ayarlarını değiştirir, önce --dry-run ile neyin silineceğini gösterir, sonra expire çalıştırır. Silinen yedek geri gelmez."}]},{"id":"pg-pitr-basebackup","file":"install/guides/pg-pitr-basebackup.json","group":"PostgreSQL","engineId":"postgres","category":"backup","title":"pg_basebackup + WAL arşivi ile yedek ve PITR (pgBackRest olmadan)","summary":"Ek araç kurmadan, PostgreSQL'in kendi araçlarıyla fiziksel yedek: archive_command ile sürekli WAL arşivi, pg_basebackup ile gecelik base backup, pg_archivecleanup ile saklama. Belirli bir zamana / transaction'a / restore","level":"Orta","duration":"45–90 dk","topology":"1 sunucu; streaming ya da Patroni'de arşiv dizini tüm node'larda ortak (NFS)","tags":["postgresql","pg_basebackup","archive_command","restore_command","pitr","point in time recovery","recovery.signal","recovery_target_time","pg_archivecleanup","wal arşivi","timeline","base backup","yedek","geri dönüş","pg_verifybackup","cron","tatbikat"],"order":12,"steps":14,"scenarios":[{"k":"op","v":"kur","l":"WAL arşivini ve gecelik base backup'ı kur","m":"Kurulum archive_mode archive_command archive_timeout pg_stat_archiver wal_level WAL arşivi WAL archiving continuous archiving sürekli arşivleme pg_basebackup cron base backup gecelik yedek nightly backup wal arşivi kur İlk kurulum: archive_command ile sürekli WAL arşivi, pg_basebackup betiği, /etc/cron.d zamanlaması, saklama ve WAL temizliği. archive_mode için bir kez kısa yeniden başlatma gerekir"},{"k":"op","v":"pitr","l":"Belirli bir ana geri dön (PITR: zaman, xid, LSN, restore point)","m":"Geri dönüş recovery ended before configured recovery target was reached requested recovery stop point is before consistent recovery point PITR point in time recovery point in time recovery.signal restore_command recovery_target_time recovery_target_xid recovery_target_lsn recovery_target_name pg_create_restore_point DROP TABLE TRUNCATE yanlışlıkla silindi accidental delete zamana dönüş sunucu kayb"},{"k":"op","v":"drill","l":"Restore tatbikatı (ayrı dizinde, canlıya dokunmadan)","m":"Kontrol ve bakım backup successfully verified pg_verifybackup pg_amcheck restore test restore drill tatbikat yedek doğrulama backup verify RTO yedek açılıyor mu Yedeğin gerçekten açıldığını kanıtlamak için (ayda bir önerilir): son base backup doğrulanır (pg_verifybackup), ayrı dizine açılıp arşivle ayrı portta başlatılır; süre (RTO) ölçülür. Canlıya dokunulmaz."},{"k":"op","v":"cleanup","l":"Eski base backup'ları ve WAL arşivini temizle","m":"Kontrol ve bakım No space left on device could not write to file archive command failed pg_archivecleanup arşiv diski dolu archive dolu disk full eski yedekleri sil saklama retention pg_wal büyüyor archive_status .ready Arşiv ya da yedek diski doluyor veya saklama değişti: eski base backup'lar silinir, pg_archivecleanup ile en eski yedekten önceki WAL kaldırılır (önce dry-run). Veritabanı açık kal"}]},{"id":"pg-logical-repl","file":"install/guides/pg-logical-repl.json","group":"PostgreSQL","engineId":"postgres","category":"ha","title":"PostgreSQL logical replication (publication / subscription)","summary":"İki PostgreSQL cluster'ı arasında tablo düzeyinde logical replication: wal_level=logical, replica identity kontrolü, publication ve subscription, ilk senkron, izleme, çakışma (conflict) yönetimi, sequence'lerin elle eşit","level":"İleri","duration":"45–90 dk (+ ilk kopya süresi)","topology":"2 sunucu: yayıncı (publisher) + abone (subscriber); yayıncı tek sunucu, streaming replication ya da Patroni cluster'ı olabilir","tags":["postgresql","logical replication","mantıksal replikasyon","publication","subscription","cdc","taşıma","migration","upgrade","conflict","replica identity","sequence","patroni","failover slot","permanent slots","sync_replication_slots"],"order":15,"steps":25,"scenarios":[{"k":"purpose","v":"sync","l":"Sürekli replikasyon (raporlama, entegrasyon, kısmi kopya)","m":"logical replication publication subscription CREATE SUBSCRIPTION tablo replikasyonu kısmi replikasyon Seçilen tablolar sürekli olarak başka bir cluster'a akar (raporlama sunucusu, veri ambarı beslemesi, servisler arası entegrasyon). Abone yazılabilir kalır."},{"k":"purpose","v":"migrate","l":"Taşıma: yeni sunucu / yeni ana sürüm + son geçiş (cutover)","m":"sıfır kesinti upgrade near zero downtime cutover sunucu taşıma logical upgrade Yeni sunucuya ya da yeni ana sürüme saniyelik kesintiyle geçiş: ilk kopya ve sürekli eşitleme, sonra kısa yazma durdurma ve son geçiş (cutover)."}]},{"id":"pg-dump-restore","file":"install/guides/pg-dump-restore.json","group":"PostgreSQL","engineId":"postgres","category":"backup","title":"PostgreSQL mantıksal yedek ve geri yükleme (pg_dump / pg_restore)","summary":"pg_dump, pg_dumpall ve pg_restore ile tablo, şema, veritabanı ya da tüm cluster düzeyinde mantıksal yedek ve geri yükleme; yalnız yapı (DDL) ya da yalnız veri, başka sunucuya/sürüme taşıma, dump içinden tek tablo geri yü","level":"Orta","duration":"20–90 dk (veri boyutuna göre)","topology":"1 sunucu, streaming replication (primary + standby) ya da Patroni cluster'ı; taşımada kaynak + hedef, uzaktan zamanlanmış yedekte + yedek sunucusu","tags":["postgresql","postgres","pg_dump","pg_restore","pg_dumpall","mantıksal yedek","logical backup","export","import","dump","restore","geri yükleme","taşıma","migration","upgrade","globals","systemd timer","cron","pgpass","yedekleme","patroni","streaming replication","replica","standby","haproxy","hot standby","pg_wrapper","cron.d","flock"],"order":15,"steps":9,"scenarios":[{"k":"mode","v":"tables","l":"Tek tablo(lar) export / import","m":"Export / import pg_dump -t tablo export tablo import table export tek tablo yedek no matching tables were found Seçilen tabloların yapısı ve verisi (index, constraint, trigger dahil) alınır ve başka bir veritabanına yüklenir."},{"k":"mode","v":"schema","l":"Bir şemayı export / import","m":"Export / import pg_dump -n şema export schema export no matching schemas were found Şemadaki tüm nesneler (tablo, view, fonksiyon, sequence) alınır."},{"k":"mode","v":"db","l":"Tek veritabanı yedek / geri yükleme","m":"Export / import pg_dump pg_restore veritabanı yedeği database backup database restore errors ignored on restore Bir veritabanının tamamı (yapı + veri) tek dump'a alınır ve aynı ya da başka bir veritabanına geri yüklenir. Roller (globals) dahil değildir."},{"k":"mode","v":"cluster","l":"Tüm cluster (roller + tablespace'ler + her veritabanı)","m":"Export / import pg_dumpall pg_dumpall -g globals tüm cluster yedeği roller yedeği pg_dumpall -g ile globals, her veritabanı için ayrı pg_dump; geri yükleme geçici bir test cluster'ında prova edilir."},{"k":"mode","v":"ddl","l":"Yalnız şema yapısı (DDL)","m":"Yapı ve veri ayrı pg_dump -s --schema-only DDL export yalnız yapı Veri olmadan tablo, index, view, fonksiyon tanımları; inceleme, sürüm kontrolü ya da boş ortam kurmak için."},{"k":"mode","v":"data","l":"Yalnız veri","m":"Yapı ve veri ayrı pg_dump -a --data-only yalnız veri --disable-triggers circular foreign-key constraints Yapı hedefte hazırken yalnız satırlar (COPY) aktarılır."},{"k":"mode","v":"migrate","l":"Başka sunucuya / sürüme taşıma","m":"Taşıma ve kurtarma sunucu taşıma migration dump restore upgrade aborting because of server version mismatch yeni sürüme taşı Hedef sunucuda yeni sürümün pg_dump'ı kaynağa ağ üzerinden bağlanır; pipe ya da dosya ile aktarılır."},{"k":"mode","v":"partial","l":"Dump içinden tek tablo / nesne geri yükleme","m":"Taşıma ve kurtarma tek tablo geri yükle pg_restore -L pg_restore --list DROP TABLE silinen tablo silinen satır yanlışlıkla silindi table restore Mevcut bir custom/directory dump'tan liste dosyası (-L) ile yalnız bir tablo ve ona ait index, constraint ve verisi geri yüklenir."},{"k":"mode","v":"sched","l":"Zamanlanmış yedek (systemd timer / cron)","m":"Zamanlanmış yedek pg_dump cron systemd timer zamanlanmış yedek scheduled backup günlük yedek yedek saklama Her gün globals + veritabanı yedeği, okunabilirlik doğrulaması, saklama süresi, log ve hata bildirimi."}]},{"id":"pg-minor-update","file":"install/guides/pg-minor-update.json","group":"PostgreSQL","engineId":"postgres","category":"patch","title":"PostgreSQL minor sürüm güncellemesi (patch)","summary":"Aynı ana sürüm içinde minor güncelleme (ör. 17.4 → 17.x): release notes kontrolü, yedek ve geri dönüş için mevcut RPM/deb'lerin saklanması. Tek sunucuda kısa kesintiyle; streaming replication'lı cluster'da önce standby'l","level":"Orta","duration":"20–60 dk","topology":"1 sunucu, primary + standby'lar ya da Patroni cluster'ı","tags":["postgresql","minor","patch","güncelleme","update","upgrade","rolling","switchover","dnf","apt","downgrade","rollback","extension","patroni","patronictl","failover"],"order":20,"steps":17,"scenarios":[{"k":"purpose","v":"upd","l":"Minor güncelleme","m":"minor update minor güncelleme patch CVE güvenlik güncellemesi dnf upgrade postgresql apt upgrade postgresql Aynı ana sürüm içinde yeni minor sürüme geçiş (ör. 17.4 → 17.6): güvenlik/hata düzeltmeleri. Tek sunucuda kısa kesinti, cluster'da rolling."},{"k":"purpose","v":"rb","l":"Geri alma: önceki minor sürüme dön (downgrade)","m":"downgrade geri alma rollback önceki sürüme dön undefined symbol Yeni minor sürümde hata/regresyon görüldü: kaydedilen önceki sürümün RPM/deb'leri ile geri dönülür. Veri dizini değişmez."}]},{"id":"pg-major-upgrade","file":"install/guides/pg-major-upgrade.json","group":"PostgreSQL","engineId":"postgres","category":"upgrade","title":"PostgreSQL major upgrade (pg_upgrade / logical replication)","summary":"Ana sürüm yükseltmesi (ör. 16 → 17): yöntem seçimi (pg_upgrade --link / --copy / --clone ya da logical replication ile neredeyse kesintisiz taşıma), pg_upgrade --check, eklenti uyumluluğu, yapılandırmanın taşınması, ista","level":"İleri","duration":"1–3 saat (+ veri boyutuna bağlı)","topology":"Aynı sunucuda yerinde (pg_upgrade; tek sunucu, primary + standby'lar ya da Patroni cluster'ı) veya yeni sunucuya (logical)","tags":["postgresql","major","upgrade","yükseltme","pg_upgrade","pg_upgradecluster","link","clone","logical replication","taşıma","migration","rsync","rollback","patroni","patronictl remove","replica","streaming replication"],"order":30,"steps":24,"scenarios":[{"k":"purpose","v":"upg","l":"Major upgrade","m":"major upgrade pg_upgrade pg_upgradecluster sürüm yükseltme ana sürüm upgrade postgresql 17 upgrade postgresql 18 Ana sürüm yükseltmesi (ör. 16 → 17): ön kontrol, yedek, pg_upgrade ya da logical replication, doğrulama ve temizlik."},{"k":"purpose","v":"rb","l":"Geri dönüş (upgrade başarısız / vazgeçildi)","m":"upgrade geri al rollback pg_control.old database files are incompatible with server upgrade başarısız Upgrade yarıda kaldı ya da yeni sürümde sorun çıktı: eski sürüme dönüş. --link'te yeni cluster başlatıldıysa yalnız yedekten dönülür."}]},{"id":"pg-security","file":"install/guides/pg-security.json","group":"PostgreSQL","engineId":"postgres","category":"security","title":"PostgreSQL güvenlik sıkılaştırma (durum denetimi, ağ, TLS, kimlik, yetki, audit, şifreleme)","summary":"Kurulum rehberi değildir: çalışan bir PostgreSQL sunucusunun açıklarını bulur ve kapatır. Önce salt-okur Durum denetimi açıkları önem sırasıyla listeler ve her bulgunun hangi karta götürdüğünü söyler; sonra alanları tek ","level":"Orta","duration":"5 dk (denetim) – 3 saat (tam sıkılaştırma)","topology":"Tek PostgreSQL sunucusu + uygulama sunucusu (istemci doğrulaması); replica'lı/Patroni ortam notlarda","tags":["postgresql","postgres","güvenlik","security","hardening","sıkılaştırma","cis benchmark","pg_hba","tls","ssl","sslmode","verify-full","scram-sha-256","md5","pgaudit","audit","denetim","public schema","yetki","rol","luks","pgcrypto","şifreleme","encryption","firewall"],"order":40,"steps":3,"scenarios":[{"k":"scenario","v":"scan","l":"Durum denetimi: açıklarım neler? (salt-okur)","m":"Başlangıç güvenlik denetimi security audit hardening check CIS açık zafiyet vulnerability pentest bulgusu denetim raporu denetim sorgusu CIS kontrolü güvenlik taraması security scan İlk çalıştırılacak tarama: pg_hba, dinleme adresi, TLS, md5 parolalar, süper kullanıcılar, PUBLIC yetkileri, audit, dosya izinleri ve firewall; hiçbir şeyi değiştirmez."},{"k":"scenario","v":"all","l":"Tam sıkılaştırma (hepsi sırayla)","m":"Başlangıç hardening sıkılaştırma tam güvenlik full hardening CIS benchmark uygula STIG Yeni kurulmuş ya da hiç sıkılaştırılmamış sunucu: tüm alanlar güvenli sırayla uygulanır; PostgreSQL bir-iki kez yeniden başlatılır (bakım penceresi gerekir)."},{"k":"scenario","v":"net","l":"Ağ ve bağlantı: kim nereden bağlanabilir? (listen, firewall, pg_hba)","m":"Ağ ve kimlik pg_hba.conf 0.0.0.0/0 trust listen_addresses firewall no pg_hba.conf entry pg_hba.conf rejects connection port 5432 açık FATAL: no pg_hba.conf entry for host 28000 Connection refused listen_addresses = * host all all 0.0.0.0/0 dışarıdan erişim erişim kısıtlama PostgreSQL tüm arayüzlerde dinliyor, pg_hba'da 0.0.0.0/0 ya da trust var, port herkese açık. listen_addresses değişirse yenide"},{"k":"scenario","v":"tls","l":"Bağlantıyı şifrele (TLS, sslmode=verify-full)","m":"Ağ ve kimlik ssl tls sslmode verify-full hostssl certificate verify failed SSL off no encryption server.crt sertifika süresi doldu certificate expired SSL error: certificate verify failed does not match host name root certificate file does not exist server does not support SSL, but SSL was required self-signed certificate sertifika zinciri certificate chain hostnossl ssl = off ya da istemciler ser"},{"k":"scenario","v":"auth","l":"Kimlik doğrulama ve parola (scram-sha-256, postgres uzaktan girişi)","m":"Ağ ve kimlik md5 scram-sha-256 password_encryption password authentication failed authentication method 10 not supported postgres uzaktan parola politikası password policy 28P01 FATAL: password authentication failed for user SCRAM authentication requires libpq version 10 or above pass-the-hash VALID UNTIL parola süresi md5/password yöntemi, md5 özetli parolalar, postgres kullanıcısının ağdan gireb"},{"k":"scenario","v":"priv","l":"En az yetki: roller, PUBLIC ve uygulama hesabı","m":"Yetki ve iz public schema PUBLIC GRANT REVOKE superuser least privilege en az yetki permission denied for schema rol tasarımı DEFAULT PRIVILEGES 42501 permission denied for table must be owner of table pg_read_server_files pg_execute_server_program SECURITY DEFINER REASSIGN OWNED yetki raporu Uygulama hesabı tabloların sahibi ya da süper kullanıcı, public şemaya herkes yazabiliyor; okuma/yazma/sah"},{"k":"scenario","v":"audit","l":"Audit: kim ne yaptı? (pgaudit, merkezi log)","m":"Yetki ve iz pgaudit audit denetim izi audit log AUDIT: SESSION log_connections syslog SIEM KVKK PCI shared_preload_libraries could not access file \"pgaudit\" pgaudit must be loaded via shared_preload_libraries log_statement kim ne yaptı who changed Denetçi ya da güvenlik ekibi DDL/rol değişikliklerinin kaydını istiyor; pgaudit kurulumu ve log'un merkezi sunucuya gönderilmesi. Bir kez yeniden başlat"},{"k":"scenario","v":"tde","l":"Veriyi diskte şifrele (LUKS / pgcrypto)","m":"Veri ve yedek TDE transparent data encryption disk şifreleme encryption at rest LUKS dm-crypt pgcrypto pg_tde cryptsetup luksFormat pgp_sym_encrypt at-rest encryption Diskin ya da yedeğin çalınmasına karşı koruma isteniyor. PostgreSQL'de yerleşik TDE yoktur: disk düzeyinde LUKS (taşıma için kesinti) ya da sütun düzeyinde pgcrypto."},{"k":"scenario","v":"backup","l":"Yedeklerin güvenliği (şifreli yedek, izinler)","m":"Veri ve yedek yedek şifreleme backup encryption repo-cipher-type pgbackrest cipher gpg .pgpass yedek izinleri cipher: none repo-cipher-pass şifresiz yedek unencrypted backup Yedek dosyaları şifresiz ya da herkesin okuyabileceği dizinde; pgBackRest repo şifrelemesi ya da pg_dump + GPG, .pgpass ve dizin izinleri. Kesinti yok."},{"k":"scenario","v":"os","l":"İşletim sistemi tarafı (servis hesabı, izinler, core dump, SELinux)","m":"Sunucu ve sürüm SELinux permissive chmod 700 data directory has invalid permissions core dump postgres hesabı sudo avc: denied LimitCORE core dumped passwd -l postgres hesabının parolası açık, veri dizini izinleri gevşek, SELinux Permissive/Disabled. Core dump ayarı bir sonraki yeniden başlatmada geçerli olur."},{"k":"scenario","v":"patch","l":"Yama ve sürüm: desteklenen sürümde miyim?","m":"Sunucu ve sürüm EOL end of life destek bitti minor sürüm CVE güvenlik yaması security release out of support server_version yama takvimi minor update pgsql-announce Sürüm, destek bitiş tarihi ve bekleyen minor güncelleme kontrolü; uygulama için patch rehberine bağlanır. Salt-okur."}]},{"id":"mysql-install","file":"install/guides/mysql-install.json","group":"MySQL","engineId":"mysql","category":"install","title":"MySQL tek sunucu kurulumu (üretime hazır)","summary":"Tek bir MySQL 8.4 LTS (ya da 8.0) sunucusunu resmi repo'dan sıfırdan, üretime hazır kurar: veri, binlog ve log için ayrı dizinler, RAM/CPU/disk tipine göre hesaplanmış my.cnf, GTID ve binlog saklama süresi, slow query lo","level":"Başlangıç","duration":"30–45 dk","topology":"1 sunucu","tags":["mysql","kurulum","install","8.4","lts","innodb","my.cnf","tuning","gtid","binlog","rhel","ubuntu"],"order":1,"steps":24,"scenarios":[]},{"id":"mysql-replication","file":"install/guides/mysql-replication.json","group":"MySQL","engineId":"mysql","category":"ha","title":"MySQL GTID replikasyonu (async / semi-sync)","summary":"Kurulu MySQL sunucularından 1 source + N replica GTID tabanlı replikasyon kurar: replikasyon kullanıcısı, mevcut verinin clone plugin ya da mysqldump ile aktarılması, SOURCE_AUTO_POSITION, TLS, isteğe bağlı semi-sync, su","level":"Orta","duration":"45–90 dk","topology":"1 source + 1..5 replica","tags":["mysql","replikasyon","replication","gtid","semi-sync","semisync","replica","source","clone","failover","read_only"],"order":2,"steps":21,"scenarios":[]},{"id":"mysql-innodb-cluster","file":"install/guides/mysql-innodb-cluster.json","group":"MySQL","engineId":"mysql","category":"ha","title":"MySQL InnoDB Cluster (Group Replication + MySQL Router)","summary":"Aynı veri merkezindeki 3 (ya da 5–9) kurulu MySQL sunucusundan single-primary InnoDB Cluster kurar: MySQL Shell AdminAPI ile dba.configureInstance, createCluster ve clone ile addInstance; MySQL Router bootstrap (6446 RW ","level":"İleri","duration":"90–120 dk","topology":"3–9 MySQL node'u + 1 Router sunucusu","tags":["mysql","innodb cluster","group replication","mysql shell","mysqlsh","adminapi","mysql router","ha","failover","quorum","clone","single-primary"],"order":3,"steps":39,"scenarios":[]},{"id":"mysql-xtrabackup","file":"install/guides/mysql-xtrabackup.json","group":"MySQL","engineId":"mysql","category":"backup","title":"Percona XtraBackup ile yedekleme, geri yükleme ve PITR","summary":"Percona XtraBackup ile fiziksel yedekleme: uyumlu XtraBackup sürümünün kurulumu, auth_socket'li yedek kullanıcısı, sıkıştırmalı/şifreli full + incremental yedek betiği, systemd timer ya da cron ile zamanlama, binlog kopy","level":"Orta","duration":"45–90 dk","topology":"1 sunucu (tek sunucu, source, replica ya da InnoDB Cluster secondary'si); yedek alanı yerel disk ya da NFS","tags":["mysql","xtrabackup","percona","yedek","backup","restore","incremental","pitr","binlog","geri dönüş","zstd","şifreleme","replica","slave-info","safe-slave-backup","innodb cluster","cron","systemd timer","flock"],"order":4,"steps":26,"scenarios":[{"k":"scenario","v":"setup","l":"Yedeklemeyi kur, zamanla ve geri yüklemeyi dene (tam akış)","m":"Kurulum ve prova xtrabackup kurulum yedek betiği backup script systemd timer cron restore provası xtrabackup yedek fiziksel yedek physical backup hot backup incremental backup full backup percona-xtrabackup XtraBackup kurulumu, yedek kullanıcısı, full + incremental yedek betiği, zamanlama ve bir geri yükleme provası (PITR dahil). İlk kez kuruyorsanız bunu seçin. Yedek sunucu açıkken alınır; kesint"},{"k":"scenario","v":"r_full","l":"Tam restore: son full yedekten geri dön","m":"Geri yükleme restore geri yükle copy-back datadir kayıp InnoDB: corruption MY-011971 MY-012592 Database page corruption mysqld açılmıyor full restore ERROR 2002 Can't connect to local MySQL server through socket MY-012574 Unable to lock ./ibdata1 datadir silindi disk arızası disk failure veri kaybı Veri dizini kayıp/bozuk ya da sunucu açılmıyor; yalnız zincirin full yedeğine dönmek yeterli. MySQL "},{"k":"scenario","v":"r_inc","l":"Full + incremental zinciriyle restore (en son incremental'a kadar)","m":"Geri yükleme incremental restore apply-log-only incremental-dir to_lsn from_lsn This incremental backup seems not to be proper for the target incremental zincir incremental chain xtrabackup_checkpoints applying incremental Son incremental yedeğin anına (ya da seçtiğiniz bir incremental'a) dönmek istiyorsunuz; full'ün üzerine incremental'lar `--apply-log-only` ile sırayla uygulanır. MySQL geri yükl"},{"k":"scenario","v":"r_pitr","l":"Belirli bir ana dönüş (PITR): yanlış DELETE / DROP öncesi","m":"Zamana dönüş PITR point in time yanlışlıkla silindi DROP TABLE DELETE yanlış TRUNCATE mysqlbinlog stop-datetime stop-position exclude-gtids binlog replay yanlış UPDATE WHERE'siz DELETE accidental delete accidental drop DROP DATABASE geri al undo delete binlog ile geri dönüş Yanlışlıkla silinen ya da bozulan veri: son yedek geri yüklenir ve binlog'lar hatalı transaction'dan hemen öncesine kadar (za"},{"k":"scenario","v":"r_table","l":"Tek tabloyu geri yükle (--export + IMPORT TABLESPACE)","m":"Zamana dönüş tek tablo single table restore IMPORT TABLESPACE DISCARD TABLESPACE transportable tablespace --export .cfg ERROR 1808 ERROR 1812 Schema mismatch ERROR 1813 Tablespace exists ERROR 1146 Table doesn't exist tablespace is missing tek tablo geri al table restore ibd dosyası Yalnız bir tablonun yedekteki hâli gerekiyor; tüm sunucuyu geri yüklemeden tablo yedekten `t_restore` adıyla içeri a"},{"k":"scenario","v":"r_replica","l":"Yedekten yeni replica kur","m":"Taşıma ve klon yeni replica replica kur xtrabackup_binlog_info xtrabackup_slave_info gtid_purged slave-info replication from backup 1236 replica'yı yedekten kur seed replica Could not find first log file name in binary log index file purged required binary logs 1236 replica yeniden kur Yeni (ya da yeniden kurulacak) bir replica'yı ağdan clone yerine mevcut XtraBackup yedeğinden hazırlayıp source'a"},{"k":"scenario","v":"r_other","l":"Yedeği başka bir sunucuya geri yükle (taşıma, test, klon)","m":"Taşıma ve klon başka sunucu test sunucusu restore test taşıma migration klon clone to test rsync server_uuid test ortamına yükle yedek doğrulama restore drill yedeği aç sunucu taşıma Üretim yedeğini test/geliştirme sunucusuna açmak, sunucu taşımak ya da yedeğin gerçekten açıldığını ayrı sunucuda doğrulamak istiyorsunuz. Kaynak sunucu etkilenmez."}]},{"id":"mysql-upgrade","file":"install/guides/mysql-upgrade.json","group":"MySQL","engineId":"mysql","category":"upgrade","title":"MySQL 8.0 → 8.4 LTS upgrade (in-place)","summary":"Kurulu bir MySQL 8.0'ı aynı sunucuda (in-place) 8.4 LTS'e yükseltir: tek sunucu, source + replica'lar (önce replica'lar, en son source) ya da InnoDB Cluster (Router → Shell → metadata → secondary'ler tek tek → en son pri","level":"Orta","duration":"60–120 dk (veri boyutuna göre)","topology":"1 sunucu, source + replica'lar ya da InnoDB Cluster (3+ üye + MySQL Router sunucuları)","tags":["mysql","upgrade","8.0","8.4","lts","yükseltme","checkForServerUpgrade","mysql_native_password","authentication_policy","rollback","geri dönüş","innodb cluster","group replication","mysql router","upgradeMetadata","setPrimaryInstance","rolling upgrade"],"order":5,"steps":18,"scenarios":[]},{"id":"mysql-repl-ops","file":"install/guides/mysql-repl-ops.json","group":"MySQL","engineId":"mysql","category":"ops","title":"MySQL replikasyonu günlük işletim ve arıza senaryoları (8.0 / 8.4)","summary":"Kurulu bir source + replica topolojisinin (async / semi-sync, GTID ya da binlog konumu) günlük işletimi ve arıza kurtarma runbook'u: sağlık ve gecikme kontrolü, planlı switchover, failover, eski source'u geri katma, repl","level":"İleri","duration":"5 dk (kontrol) – 2 saat (yeniden kurma)","topology":"1 source + 1..5 replica (async / semi-sync)","tags":["mysql","replikasyon","replication","gtid","errant gtid","errant transaction","switchover","failover","replica","source","super_read_only","semi-sync","show replica status","seconds_behind_source","gecikme","lag","1062","1032","1236","duplicate entry","can't find record","gtid_next","sql_replica_skip_counter","source_delay","gecikmeli replica","delayed replica","clone","xtrabackup","mysqldump","purge binary logs","binlog_expire_logs_seconds","wait_for_executed_gtid_set","change replication source to","runbook","8.0","8.4"],"order":12,"steps":5,"scenarios":[{"k":"scenario","v":"health","l":"Durum ve gecikme kontrolü (replikasyon sağlıklı mı?)","m":"İzleme ve kontrol SHOW REPLICA STATUS SHOW SLAVE STATUS Seconds_Behind_Source Seconds_Behind_Master Replica_IO_Running Slave_IO_Running Replica_SQL_Running: No gecikme replication lag replica lag Rpl_semi_sync_source_status 1045 2003 2026 Error connecting to source replikasyon durumu Replica_IO_Running: No Replica_IO_Running: Connecting Slave_IO_Running: No Slave_SQL_Running: No Seconds_Behind_Sou"},{"k":"scenario","v":"switchover","l":"Planlı switchover (source rolünü bir replica'ya devret)","m":"Rol değişimi switchover planlı geçiş rol değişimi role change promote replica source değiştir bakım planlı bakım graceful takeover graceful-master-takeover source'u değiştir primary değiştir change primary yeni source Source ve replica'lar sağlıklı; bakım, donanım değişimi ya da upgrade için source rolünü planlı olarak bir replica'ya devrediyorsunuz. Yazmalar birkaç dakika durur, veri kaybı olmaz;"},{"k":"scenario","v":"failover","l":"Source kayıp: en ileri replica'ya failover","m":"Rol değişimi failover source çöktü source down master down primary down Error connecting to source Can't connect to MySQL server 2003 2013 Lost connection en ileri replica most advanced replica Replica_IO_Running: Connecting Slave_IO_Running: Connecting 2005 Unknown MySQL server host error reconnecting to source source erişilemiyor source kapandı primary çöktü sunucu çöktü server crashed Source çö"},{"k":"scenario","v":"rejoin","l":"Failover sonrası eski source'u replica olarak geri kat","m":"Rol değişimi eski source old source old master rejoin geri kat errant split brain 1236 eski primary old primary eski master geri geldi split-brain Replica has more GTIDs than the source has Slave has more GTIDs than the master has geri katma reintegrate Failover yapıldı, eski source sunucusu geri geldi. Önce yazmaya kapatılır ve binlog'ları kopyalanır, errant transaction kontrol edilir; temizse do"},{"k":"scenario","v":"rebuild","l":"Replica'yı sıfırdan yeniden kur (clone / XtraBackup / mysqldump)","m":"Kurtarma 1236 Cannot replicate because the source purged required binary logs purged required binary logs yeniden kur rebuild replica reseed clone instance yeni replica veri ayrışması data drift Could not find first log file name in binary log index file the source has purged binary logs containing GTIDs that the replica requires the master has purged binary logs containing GTIDs that the slave re"},{"k":"scenario","v":"errant","l":"Errant GTID: replica'da source'ta olmayan transaction var","m":"Kurtarma errant gtid errant transaction gtid_subtract extra gtid fazla gtid Having extra GTID events incompatible GTID set 1236 GTID_SUBTRACT gtid_executed farkı replica'ya yazıldı write on replica super_read_only kapalı Replica has more GTIDs than the source has Replica'ya doğrudan yazılmış (super_read_only kapalıyken) ya da eski bir source'tan kalmış transaction'lar var; failover'da bu transacti"},{"k":"scenario","v":"sqlerr","l":"Replikasyon durdu: 1062 Duplicate entry / 1032 Can't find record","m":"Kurtarma 1062 1032 1452 1146 1007 1008 Duplicate entry Can't find record HA_ERR_KEY_NOT_FOUND HA_ERR_FOUND_DUPP_KEY Could not execute Write_rows event Could not execute Update_rows event Could not execute Delete_rows event Replica_SQL_Running: No Slave_SQL_Running: No Coordinator stopped because there were error(s) in the worker(s) sql_slave_skip_counter sql_replica_skip_counter gtid_next MY-01058"},{"k":"scenario","v":"delayed","l":"Gecikmeli replica (SOURCE_DELAY): kur ya da silinen veriyi kurtar","m":"Günlük işletim SOURCE_DELAY MASTER_DELAY delayed replica gecikmeli replica yanlışlıkla silindi DROP TABLE DELETE yanlış SQL_Delay SQL_BEFORE_GTIDS SQL_Remaining_Delay yanlışlıkla DELETE WHERE'siz DELETE accidental delete accidental drop dropped table tablo silindi veri kurtarma UNTIL SQL_BEFORE_GTIDS Bir replica'yı bilinçli olarak N saniye geride tutmak (gecikme ayarla / kaldır) ya da yanlışlıkla "},{"k":"scenario","v":"repoint","l":"Replica'yı farklı bir source'a taşı (zincir / yeniden bağlama)","m":"Günlük işletim repoint change source zincir replikasyon chained replication intermediate ara replica relay replica CHANGE MASTER TO CHANGE REPLICATION SOURCE TO cascading replication kademeli replikasyon replica'yı başka source'a bağla SOURCE_HOST değiştir MASTER_HOST değiştir log_replica_updates Bir replica'yı başka bir replica'nın altına (zincir / ara replica) ya da source'a geri bağlamak istiyo"},{"k":"scenario","v":"binlog","l":"Binlog temizliği ve saklama süresi (disk doluyor)","m":"Günlük işletim PURGE BINARY LOGS PURGE MASTER LOGS binlog_expire_logs_seconds expire_logs_days binlog disk dolu No space left on device errno 28 binlog temizliği binlog retention Disk is full writing OS errno 28 1867 was not purged because it was being read 1373 Target log not found in binlog index binlog büyüyor binlog_expire_logs_auto_purge binlog_transaction_compression Binlog'lar diski dolduru"}]},{"id":"mysql-ic-ops","file":"install/guides/mysql-ic-ops.json","group":"MySQL","engineId":"mysql","category":"ops","title":"MySQL InnoDB Cluster günlük işletim ve arıza senaryoları (MySQL Shell 8.4)","summary":"Kurulum değil: zaten çalışan bir InnoDB Cluster'ın (Group Replication + MySQL Router, MySQL Shell AdminAPI ile kurulmuş) günlük işletimi ve arıza kurtarması için senaryo bazlı runbook. Bir senaryo kartı seçin: sağlık kon","level":"İleri","duration":"5 dk (kontrol) – 1 saat (üye ekleme)","topology":"3–9 MySQL node'u (single-primary) + MySQL Router","tags":["mysql","innodb cluster","group replication","mysql shell","mysqlsh","adminapi","cluster.status","addinstance","removeinstance","rejoininstance","rebootclusterfromcompleteoutage","forcequorumusingpartitionof","setprimaryinstance","setoption","setinstanceoption","rescan","mysql router","bootstrap","quorum","no_quorum","split brain","expelTimeout","memberWeight","autoRejoinTries","exitStateAction","consistency","clone","MISSING","UNREACHABLE","RECOVERING","ERROR","runbook","8.4"],"order":13,"steps":5,"scenarios":[{"k":"scenario","v":"health","l":"Cluster durumu ve sağlık kontrolü (her şey yolunda mı?)","m":"İzleme ve kontrol cluster.status status() OK_PARTIAL OK_NO_TOLERANCE OK_NO_TOLERANCE_PARTIAL instanceErrors replicationLag flow control RECOVERING applier queue cluster durumu Cluster is ONLINE and can tolerate can tolerate up to ONE failure sağlık kontrolü health check kuyruk büyüyor replication_group_members group_replication_member_stats cluster ne durumda Salt-okur: `cluster.status({extended: "},{"k":"scenario","v":"add","l":"Yeni üye ekle (addInstance: clone / incremental)","m":"Üyeler addInstance üye ekle node ekle add instance recoveryMethod clone incremental 3092 Having extra GTID events MYSQLSH 51166 The target instance must be either cloned or fully provisioned Clone Donor Error kapasite artır tolerans artır OK_NO_TOLERANCE Cluster'a yeni bir MySQL node'u eklemek, tolerans artırmak (3 → 5) ya da çıkarılmış bir node'u geri almak istiyorsunuz. Cluster yazmaya açık kalı"},{"k":"scenario","v":"remove","l":"Üyeyi çıkar (removeInstance, gerekirse force)","m":"Üyeler removeInstance üye çıkar node çıkar remove instance force MISSING decommission Cluster.removeInstance is not reachable and cannot be safely removed node kaldır küçült sunucu iadesi Bir node'u kalıcı olarak cluster'dan çıkarmak istiyorsunuz (donanım iadesi, küçültme) ya da node kayıp ve metadata'dan silinmesi gerekiyor (`force`). Secondary çıkarılırken kesinti olmaz; primary çıkarılırsa birk"},{"k":"scenario","v":"rejoin","l":"Düşen üyeyi geri kat (MISSING / ERROR / OFFLINE)","m":"Arıza ve kurtarma rejoinInstance MISSING ERROR OFFLINE UNREACHABLE expelled gruptan atıldı member was expelled MY-011735 MY-011526 incompatible GTID set (MISSING) This member has more executed transactions than those present in the group has an incompatible GTID set with the seed instance Error connecting to all peers Member join failed group_replication is stopped üye düştü üye OFFLINE member exp"},{"k":"scenario","v":"reboot","l":"Tüm cluster kapandı: yeniden başlat (rebootClusterFromCompleteOutage)","m":"Arıza ve kurtarma rebootClusterFromCompleteOutage complete outage tam kesinti tüm node'lar kapandı elektrik kesintisi Group Replication is not active OFFLINE Unable to find a cluster PRIMARY member The cluster is offline Dba.rebootClusterFromCompleteOutage Dba.getCluster: This function is not available through a session to a standalone instance metadata exists, instance belongs to that metadata, b"},{"k":"scenario","v":"quorum","l":"Çoğunluk kaybı (NO_QUORUM): kalan üyelerle zorla quorum kur","m":"Arıza ve kurtarma NO_QUORUM forceQuorumUsingPartitionOf quorum çoğunluk kaybı split-brain split brain UNREACHABLE majority partition 3100 Cluster has no quorum cannot process write transactions split-brain! Instance is not part of the majority group yazmalar askıda writes hang forceQuorum Üyelerin çoğu aynı anda kayboldu (ör. 3'te 2), kalanlar `NO_QUORUM` ile yazmayı durdurdu (yazmalar askıda kalı"},{"k":"scenario","v":"switch","l":"Planlı primary değişimi (setPrimaryInstance)","m":"Rol ve yönlendirme setPrimaryInstance primary değiştir switchover primary devret The appointed primary member has a version that is greater group_replication_set_as_primary Cluster.setPrimaryInstance runningTransactionsTimeout planlı primary değişimi primary taşı planned switchover Bakım (OS patch, donanım), yük dengesi ya da DR provası için primary rolünü belirli bir secondary'ye planlı olarak de"},{"k":"scenario","v":"router","l":"Router ekle ya da yeniden bootstrap et","m":"Rol ve yönlendirme mysqlrouter MySQL Router bootstrap --force routerErrors re-bootstrap Router listRouters removeRouterMetadata 6446 6447 previously configured in this host Unable to connect to the metadata server Unable to fetch all configuration options The provided server is currently not in a InnoDB cluster group with quorum mysqlrouter.service failed Router bağlanmıyor Router kurulumu Yeni bi"},{"k":"scenario","v":"options","l":"Cluster seçeneklerini değiştir (consistency, expelTimeout, memberWeight…)","m":"Yapılandırma setOption setInstanceOption consistency BEFORE_ON_PRIMARY_FAILOVER expelTimeout group_replication_member_expel_timeout memberWeight autoRejoinTries exitStateAction OFFLINE_MODE READ_ONLY options() group_replication_consistency group_replication_member_weight group_replication_autorejoin_tries group_replication_exit_state_action üye sık atılıyor failover önceliği Failover tutarlılığı, "},{"k":"scenario","v":"rescan","l":"Metadata'yı gerçek grupla eşitle (rescan)","m":"Yapılandırma rescan metadata is not managed not registered in the metadata newlyDiscoveredInstances unavailableInstances instanceErrors obsolete Use cluster.rescan() Instance is not managed by InnoDB cluster Use cluster.rescan() to repair metadata uyumsuz metadata ayrıştı `cluster.status()` metadata'da olmayan bir üyeden ya da artık grupta olmayan eski bir kayıttan söz ediyor (elle `START GROUP_RE"}]},{"id":"mysql-logical-backup","file":"install/guides/mysql-logical-backup.json","group":"MySQL","engineId":"mysql","category":"backup","title":"MySQL mantıksal yedek ve geri yükleme (mysqldump, MySQL Shell)","summary":"mysqldump ya da MySQL Shell (util.dumpInstance / dumpSchemas / dumpTables + util.loadDump) ile mantıksal yedek ve geri yükleme: tablo, şema ya da tüm instance; yalnız yapı ya da yalnız veri; başka sunucuya taşıma; tam du","level":"Orta","duration":"20–90 dk (veri boyutuna göre)","topology":"1 sunucu (taşımada ve instance geri yüklemesinde + hedef sunucu)","tags":["mysql","mysqldump","mysql shell","mysqlsh","dumpInstance","dumpSchemas","dumpTables","loadDump","mantıksal yedek","logical backup","export","import","geri yükleme","restore","taşıma","migration","login-path","mysql_config_editor","systemd timer","cron","yedekleme","replica","dump-replica","source-data","innodb cluster","cron","systemd timer","flock","login-path"],"order":15,"steps":8,"scenarios":[{"k":"mode","v":"table","l":"Tablo(lar) export / import","m":"Yedek ve geri yükleme tablo yedeği table export tablo kopyala copy table mysqldump tablo Bir ya da birkaç tablonun yedeğini almak, başka şemaya/sunucuya kopyalamak ya da geri yüklemek. Kaynak açık kalır; InnoDB tablolarında lock alınmaz."},{"k":"mode","v":"schema","l":"Bir şemayı (veritabanını) yedekle / geri yükle","m":"Yedek ve geri yükleme şema yedeği veritabanı yedeği database backup dumpSchemas mysqldump database Bir veritabanının (şemanın) tamamını yedeklemek ya da başka bir şemaya/sunucuya yüklemek. Kaynak açık kalır; hedefte aynı adlı tablolar silinip yeniden oluşturulur."},{"k":"mode","v":"instance","l":"Tüm instance (kullanıcılar + tüm şemalar)","m":"Yedek ve geri yükleme tüm veritabanları all databases dumpInstance kullanıcıları taşı full logical backup Yedek bu sunucuda alınır, geri yükleme boş bir sunucuda yapılır: kullanıcılar, yetkiler ve tüm şemalar. Sunucuyu yeniden kurmak ya da sürüm/platform değiştirmek için."},{"k":"mode","v":"ddl","l":"Yalnız yapı (DDL)","m":"Yapı ve veri ayrı yalnız yapı schema only no-data ddlOnly CREATE TABLE export Tablo, view, trigger, procedure ve event tanımları; veri yok. Şema karşılaştırma, boş ortam kurma ya da yapıyı sürüm kontrolüne almak için."},{"k":"mode","v":"data","l":"Yalnız veri","m":"Yapı ve veri ayrı yalnız veri data only no-create-info dataOnly veri aktarımı Yapı hedefte hazırken yalnız satırlar aktarılır (ör. test verisini yenilemek). Hedefteki trigger'lar yükleme sırasında çalışabilir; rehber bunu kontrol eder."},{"k":"mode","v":"migrate","l":"Başka sunucuya taşıma","m":"Taşıma taşıma migration sunucu değişimi yeni sunucuya taşı 8.0 to 8.4 migration dump and load HeatWave'e taşı Hedef sunucuda çalışılır; kaynağa ağ üzerinden, login-path ile bağlanılır. Kesme anında uygulama yazmayı durdurur; kesinti dump + yükleme süresi kadardır. Sunucu, işletim sistemi ya da sürüm değişimi için."},{"k":"mode","v":"extract","l":"Tam dump içinden tek tablo çıkarma","m":"Kurtarma tek tablo geri yükle dump'tan tablo çıkar extract table from dump DROP TABLE geri al silinen satırlar ERROR 1146 Table doesn't exist Elinizde tam bir dump var ve yalnız bir tablo gerekiyor (silinen satırlar, DROP edilen tablo). Asıl şemaya dokunmadan ayrı şemaya çıkarılır ya da silinmiş tablo geri konur."},{"k":"mode","v":"sched","l":"Zamanlanmış yedek (systemd timer / cron)","m":"Zamanlanmış yedek zamanlanmış yedek scheduled backup cron mysqldump systemd timer otomatik yedek gece yedeği Her gün belirli saatte otomatik mantıksal yedek: ayrı yedek kullanıcısı, login-path, betik, systemd timer ya da cron, saklama süresi ve hata bildirimi. Kaynak açık kalır."}]},{"id":"mysql-security","file":"install/guides/mysql-security.json","group":"MySQL","engineId":"mysql","category":"security","title":"MySQL güvenlik sıkılaştırma (durum denetimi, ağ, TLS, kimlik, yetki, audit, şifreleme)","summary":"Kurulum rehberi değildir: çalışan bir MySQL 8.4 / 8.0 sunucusunun açıklarını bulur ve kapatır. Önce salt-okur Durum denetimi açıkları önem sırasıyla listeler ve her bulgunun hangi karta götürdüğünü söyler; sonra alanları","level":"Orta","duration":"5 dk (denetim) – 3 saat (tam sıkılaştırma)","topology":"Tek MySQL sunucusu + uygulama sunucusu (istemci doğrulaması); replica/InnoDB Cluster notlarda","tags":["mysql","güvenlik","security","hardening","sıkılaştırma","cis benchmark","tls","ssl","require_secure_transport","verify_identity","caching_sha2_password","mysql_native_password","validate_password","audit_log","audit","percona","tde","keyring","innodb encryption","root","anonim kullanıcı","yetki","rol","login-path"],"order":40,"steps":2,"scenarios":[{"k":"scenario","v":"scan","l":"Durum denetimi: açıklarım neler? (salt-okur)","m":"Başlangıç güvenlik denetimi security audit hardening check CIS açık zafiyet vulnerability pentest bulgusu mysql_secure_installation denetim sorgusu güvenlik taraması security scan KRİTİK İlk çalıştırılacak tarama: anonim/parolasız/uzaktan root hesaplar, her yerden (%) erişim, zayıf kimlik eklentisi, global yetkiler, TLS, audit, şifreleme, dosya izinleri ve firewall; hiçbir şeyi değiştirmez."},{"k":"scenario","v":"all","l":"Tam sıkılaştırma (hepsi sırayla)","m":"Başlangıç hardening sıkılaştırma tam güvenlik full hardening CIS benchmark uygula STIG Yeni kurulmuş ya da hiç sıkılaştırılmamış sunucu: tüm alanlar güvenli sırayla uygulanır; MySQL birkaç kez yeniden başlatılır (bakım penceresi gerekir)."},{"k":"scenario","v":"net","l":"Ağ ve bağlantı: kim nereden bağlanabilir? (bind_address, firewall, host kısıtı)","m":"Ağ ve kimlik bind_address 0.0.0.0 '%' host '%' firewall 3306 33060 Host is not allowed to connect ERROR 1130 ERROR 2003 Can't connect to MySQL server skip_name_resolve dışarıdan erişim erişim kısıtlama MySQL tüm arayüzlerde dinliyor, hesaplar '%' host'lu, port herkese açık. bind_address değişirse yeniden başlatma gerekir."},{"k":"scenario","v":"tls","l":"Bağlantıyı şifrele (TLS, require_secure_transport, VERIFY_IDENTITY)","m":"Ağ ve kimlik ssl tls require_secure_transport ssl-mode VERIFY_IDENTITY VERIFY_CA ERROR 3159 Connections using insecure transport are prohibited server-cert.pem sertifika süresi ERROR 2026 SSL connection error certificate verify failed ERROR 3888 sertifika zinciri certificate chain Otomatik üretilen kendinden imzalı sertifika kullanılıyor, şifresiz bağlantı kabul ediliyor ya da istemciler sertifika"},{"k":"scenario","v":"auth","l":"Kimlik doğrulama ve parola (caching_sha2, parola politikası, root)","m":"Ağ ve kimlik mysql_native_password caching_sha2_password validate_password password_history FAILED_LOGIN_ATTEMPTS root uzaktan anonymous user anonim kullanıcı ERROR 1045 Access denied Plugin 'mysql_native_password' is not loaded ERROR 1524 ERROR 1819 ERROR 3955 ERROR 3118 Account is locked ERROR 2061 Authentication requires secure connection auth_socket mysql_native_password hesapları, parola poli"},{"k":"scenario","v":"priv","l":"En az yetki: roller ve DDL'siz uygulama hesabı","m":"Yetki ve iz GRANT REVOKE ALL PRIVILEGES SUPER FILE least privilege en az yetki CREATE ROLE ERROR 1142 command denied ERROR 3530 ERROR 1227 you need (at least one of) the SUPER privilege DEFAULT ROLE yetki raporu Uygulama hesabında CREATE/ALTER/DROP ya da *.* yetkisi, FILE/SUPER yetkili hesaplar; okuma/yazma/DDL rolleri ve yetki raporu. Kesinti yok."},{"k":"scenario","v":"audit","l":"Audit: kim ne yaptı?","m":"Yetki ve iz audit audit_log audit_log_filter denetim izi general_log Enterprise Audit Percona audit SIEM KVKK PCI audit_log_filter_set_filter ERROR 1126 MySQL Enterprise lisansı kim ne yaptı Denetçi oturum ve sorgu kaydı istiyor. MySQL Community'de yerleşik audit yoktur: Enterprise Audit, Percona Server Audit Log Filter ya da Community için sınırlı seçenekler. **Lisans:** Enterprise Audit yalnız M"},{"k":"scenario","v":"tde","l":"Veriyi diskte şifrele (InnoDB tablespace encryption, keyring)","m":"Veri ve yedek TDE encryption at rest ENCRYPTION='Y' keyring component_keyring_file ERROR 3185 Can't find master key from keyring binlog_encryption innodb_redo_log_encrypt ALTER INSTANCE ROTATE INNODB MASTER KEY mysqld.my keyring_component_status master key Disk ya da yedek kopyasının çalınmasına karşı tablo, redo, undo ve binlog şifrelemesi; keyring component kurulumu için bir yeniden başlatma, bü"},{"k":"scenario","v":"backup","l":"Yedeklerin güvenliği (şifreli yedek, login-path, izinler)","m":"Veri ve yedek yedek şifreleme backup encryption mysqldump gpg xtrabackup --encrypt login-path mysql_config_editor .my.cnf parola xbcrypt --encrypt-key-file şifresiz yedek unencrypted backup Yedekler şifresiz ya da herkesin okuyabildiği dizinde, betikte düz metin parola; mysqldump + GPG ya da XtraBackup --encrypt, yedek hesabı ve login-path."},{"k":"scenario","v":"os","l":"İşletim sistemi tarafı (servis hesabı, izinler, core dump, SELinux)","m":"Sunucu ve sürüm SELinux permissive secure_file_priv local_infile core dump mysql hesabı .mysql_history ERROR 1290 secure-file-priv option ERROR 3948 Loading local data is disabled avc: denied Veri dizini ya da sertifika dosyaları başkalarına açık, secure_file_priv boş, local_infile açık, SELinux kapalı. Bazı ayarlar yeniden başlatmada geçerli olur."},{"k":"scenario","v":"patch","l":"Yama ve sürüm: desteklenen sürümde miyim?","m":"Sunucu ve sürüm EOL end of life destek bitti MySQL 8.0 EOL CPU Critical Patch Update CVE güvenlik yaması yama takvimi MySQL 8.0 end of life 8.4 LTS Sürüm, destek bitişi (8.0 Nisan 2026'da bitti) ve bekleyen güncellemeler; uygulama için upgrade rehberine bağlanır. Salt-okur."}]},{"id":"mssql-linux-install","file":"install/guides/mssql-linux-install.json","group":"SQL Server","engineId":"mssql","category":"install","title":"SQL Server Linux kurulumu (RHEL / Ubuntu, üretime hazır)","summary":"Tek bir Linux sunucuya (RHEL ailesi ya da Ubuntu) Microsoft repo'sundan SQL Server 2022 veya 2025 kurar: edition seçimi, sa parolasının güvenli verilmesi, mssql-tools18 (sqlcmd/bcp), ayrı veri/log/tempdb/yedek dizinleri,","level":"Başlangıç","duration":"40–60 dk","topology":"1 sunucu","tags":["sql server","mssql","linux","kurulum","install","mssql-conf","sqlcmd","tempdb","maxdop","rhel","ubuntu","2022","2025"],"order":1,"steps":22,"scenarios":[]},{"id":"mssql-windows-install","file":"install/guides/mssql-windows-install.json","group":"SQL Server","engineId":"mssql","category":"install","title":"SQL Server 2022 Windows kurulumu (unattended, üretime hazır)","summary":"Tek bir Windows Server'a SQL Server 2022'yi ConfigurationFile.ini ile sessiz (unattended) kurar: seçimlerinize göre üretilen INI (özellikler, instance, servis hesapları/gMSA, collation, veri/log/tempdb/yedek dizinleri, t","level":"Orta","duration":"45–75 dk","topology":"1 Windows Server","tags":["sql server","mssql","windows","kurulum","install","unattended","configurationfile.ini","setup.exe","gmsa","tempdb","maxdop","ifi","lock pages in memory","2022"],"order":2,"steps":18,"scenarios":[]},{"id":"mssql-ag-windows","file":"install/guides/mssql-ag-windows.json","group":"SQL Server","engineId":"mssql","category":"ha","title":"SQL Server Always On Availability Group (Windows, WSFC)","summary":"SQL Server 2022 kurulu Windows sunucularından Always On Availability Group kurar: Windows Server Failover Cluster (WSFC) ve quorum tanığı (file share / cloud witness), Always On'un etkinleştirilmesi, mirroring endpoint'l","level":"İleri","duration":"90–150 dk","topology":"2–9 Windows node (WSFC) + tanık (witness)","tags":["sql server","mssql","always on","availability group","ag","wsfc","failover cluster","listener","witness","automatic seeding","hadr","windows","high availability"],"order":3,"steps":25,"scenarios":[]},{"id":"mssql-ag-linux","file":"install/guides/mssql-ag-linux.json","group":"SQL Server","engineId":"mssql","category":"ha","title":"SQL Server Always On Availability Group (Linux, Pacemaker)","summary":"SQL Server 2022 kurulu üç Linux sunucusundan (RHEL 9 ya da Ubuntu 22.04) Pacemaker yönetimli Always On AG kurar: mssql-server-ha, hadr.hadrenabled, sertifikayla kimlik doğrulayan mirroring endpoint'leri, CLUSTER_TYPE = E","level":"İleri","duration":"120–180 dk","topology":"3 Linux node: 3 senkron replica ya da 2 senkron + configuration-only replica","tags":["sql server","mssql","always on","availability group","ag","linux","pacemaker","corosync","pcs","stonith","fencing","mssql-server-ha","ocf:mssql:ag","cluster_type external","configuration only","listener","virtual ip","rhel","ubuntu","high availability"],"order":4,"steps":30,"scenarios":[]},{"id":"mssql-cu-patch","file":"install/guides/mssql-cu-patch.json","group":"SQL Server","engineId":"mssql","category":"patch","title":"SQL Server Cumulative Update (CU) uygulama","summary":"Kurulu SQL Server 2022/2025 instance'ına aynı ana sürüm içinde Cumulative Update (CU) uygular: Linux'ta dnf/apt ile, Windows'ta CU kurulum dosyasıyla sessiz (/quiet) kurulum. Tek sunucu ya da Always On AG'de rolling (önc","level":"Orta","duration":"30–90 dk","topology":"1 sunucu ya da AG (2+ replica)","tags":["sql server","mssql","cu","cumulative update","patch","güncelleme","rolling","availability group","always on","yum","apt","kb"],"order":4,"steps":12,"scenarios":[]},{"id":"mssql-ag-ops","file":"install/guides/mssql-ag-ops.json","group":"SQL Server","engineId":"mssql","category":"ops","title":"SQL Server Always On AG işletimi (Windows ve Linux)","summary":"Kurulum değil, kurulu bir Always On Availability Group'un günlük işletimi ve arıza senaryoları: sağlık kontrolü, gecikme ve log büyümesi teşhisi, planlı failover, zorunlu failover (FORCE_FAILOVER_ALLOW_DATA_LOSS) ve sonr","level":"İleri","duration":"15–90 dk (senaryoya göre)","topology":"2–9 replica'lı AG (Windows WSFC ya da Linux Pacemaker)","tags":["sql server","mssql","always on","availability group","ag","failover","forced failover","force_failover_allow_data_loss","suspend","resume","automatic seeding","read-only routing","listener","pacemaker","pcs","wsfc","secondary lag","log_send_queue","redo_queue","required_synchronized_secondaries_to_commit"],"order":5,"steps":3,"scenarios":[{"k":"op","v":"health","l":"AG sağlık kontrolü (dashboard sorguları)","m":"İzleme ve teşhis NOT SYNCHRONIZING NOT_HEALTHY DISCONNECTED RESOLVING PARTIALLY_HEALTHY AG sağlığı availability group health sys.dm_hadr dashboard replica durumu Msg 35206 connection timeout AG dashboard Show Dashboard Her şey yolunda mı? Replica / veritabanı durumu, failover'a hazırlık, cluster ve son rol değişimleri. Hiçbir şeyi değiştirmez."},{"k":"op","v":"lag","l":"Secondary geride kalıyor / log dosyası büyüyor (gecikme teşhisi)","m":"İzleme ve teşhis AVAILABILITY_REPLICA log_reuse_wait log_send_queue redo_queue HADR_SYNC_COMMIT secondary lag secondary_lag_seconds Msg 9002 9002 transaction log is full gecikme redo blocked log büyüyor send/redo kuyruğu büyüyor, secondary'de veri eski, primary'de log dolmak üzere (log_reuse_wait = AVAILABILITY_REPLICA) ya da commit'ler yavaş (HADR_SYNC_COMMIT)."},{"k":"op","v":"failover","l":"Planlı failover (switchover, veri kaybı yok)","m":"Rol değişimi planned failover manual failover switchover ALTER AVAILABILITY GROUP FAILOVER pcs resource move Msg 41142 41142 Msg 19407 rol değiştir primary taşı Failover Cluster Manager Move bakım failover Bakım, patch ya da test için primary'yi senkron ve SYNCHRONIZED bir secondary'ye taşır; birkaç saniye kesinti, veri kaybı yok."},{"k":"op","v":"forced","l":"Primary kayıp: zorunlu failover (FORCE_FAILOVER_ALLOW_DATA_LOSS)","m":"Rol değişimi FORCE_FAILOVER_ALLOW_DATA_LOSS forced failover zorunlu failover quorum lost quorum kaybı FixQuorum forcequorum disaster recovery DR Msg 41131 Msg 35250 site kaybı primary down Msg 47104 ForceQuorum Cluster is running in ForceQuorum state RESOLVING_NORMAL primary çöktü veri kaybı Primary (ya da tüm site / cluster quorum) kayıp ve beklenemez: veri kaybı göze alınarak bir secondary prima"},{"k":"op","v":"suspend","l":"Veri akışını durdur / sürdür (SUSPEND / RESUME)","m":"Bakım SUSPENDED SET HADR SUSPEND SET HADR RESUME is_suspended suspend_reason data movement veri akışı durdu Msg 35264 35264 Msg 35265 SUSPEND_FROM_REDO SUSPEND_FROM_USER SUSPEND_FROM_PARTNER askıda askıya al Secondary'ye veri gönderimini geçici durdurmak (ağ bakımı, toplu işlem) ya da askıda kalmış (SUSPENDED) veritabanını sürdürmek."},{"k":"op","v":"mode","l":"Senkron / asenkron modu değiştir","m":"Bakım SYNCHRONOUS_COMMIT ASYNCHRONOUS_COMMIT availability mode REQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMIT required_synchronized_secondaries_to_commit senkron asenkron Msg 35211 35211 Msg 35212 35212 FAILOVER_MODE Bir replica'yı SYNCHRONOUS_COMMIT ↔ ASYNCHRONOUS_COMMIT yapmak (uzak site, yavaş ağ, DR tatbikatı) ve commit korumasını (REQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMIT) ayarlamak."},{"k":"op","v":"adddb","l":"AG'ye veritabanı ekle (automatic seeding ya da backup/restore)","m":"Değişiklik ADD DATABASE automatic seeding SET HADR AVAILABILITY GROUP Msg 35250 Msg 1478 1478 seeding failed veritabanı ekle Msg 1475 1475 might contain bulk logged changes manual seeding Yeni ya da mevcut bir veritabanını AG'ye almak: küçük/orta veritabanlarında automatic seeding, büyük veritabanlarında ya da yavaş ağda yedekten."},{"k":"op","v":"addrep","l":"Replica (node) ekle","m":"Değişiklik ADD REPLICA Add-ClusterNode pcs cluster node add yeni replica replica ekle Msg 41158 41158 Failed to join local availability replica JOIN AG'ye yeni bir secondary eklemek: node cluster'a katılır, endpoint hazırlanır, ADD REPLICA + JOIN, veritabanları seeding ile gelir."},{"k":"op","v":"removerep","l":"Replica (node) çıkar","m":"Değişiklik REMOVE REPLICA Remove-ClusterNode pcs cluster node remove replica çıkar decommission Msg 35223 35223 node çıkar Kalıcı olarak kapatılacak ya da yeniden kurulacak bir secondary'yi AG'den ve cluster'dan çıkarmak."},{"k":"op","v":"routing","l":"Okuma yönlendirmesi (read-only routing)","m":"Bağlantı read-only routing READ_ONLY_ROUTING_URL READ_ONLY_ROUTING_LIST ApplicationIntent=ReadOnly readable secondary okunabilir secondary Msg 978 978 Msg 976 976 not accessible for queries Msg 10786 ApplicationIntent ApplicationIntent=ReadOnly bağlantıları listener üzerinden okunabilir secondary'lere yönlendirmek (raporlama yükünü primary'den almak)."},{"k":"op","v":"listener","l":"Listener oluştur ya da değiştir (IP, port)","m":"Bağlantı listener ADD LISTENER MODIFY LISTENER MultiSubnetFailover RegisterAllProvidersIP Msg 19471 19471 Msg 41009 virtualip Msg 19456 19456 HostRecordTTL listener portu DNS kaydı Listener yoksa oluşturmak, portunu değiştirmek ya da (Windows) ikinci alt ağ için IP eklemek."}]},{"id":"mssql-backup","file":"install/guides/mssql-backup.json","group":"SQL Server","engineId":"mssql","category":"backup","title":"SQL Server yedekleme stratejisi, otomasyon ve restore","summary":"Kurulu bir SQL Server instance'ının (Linux ya da Windows; tek instance, FCI ya da AG replica'ları) yedeklerini kurar ve yedekten kurtarır. Yedekleme: recovery model seçimi, haftalık full + günlük differential + n dakikad","level":"Orta","duration":"30–90 dk","topology":"1 sunucu, Failover Cluster Instance ya da Always On AG replica'ları (restore başka sunucuya: kaynak + hedef)","tags":["sql server","mssql","backup","yedek","yedekleme","restore","geri yükleme","pitr","stopat","point in time","differential","transaction log","copy_only","compression","checksum","encryption","şifreleme","sql server agent","job","ola hallengren","maintenance solution","retention","verifyonly","headeronly","filelistonly","norecovery","standby","with move","task scheduler","cron","availability group","always on","backup preference","automated_backup_preference","fn_hadr_backup_is_preferred_replica","copy_only","sql agent","sysjobhistory","cron","task scheduler","page restore","suspect_pages","824","823","33111","18456","orphaned user","sp_help_revlogin","master restore","single user","msdb restore","model restore","stopatmark","tail-log","no_truncate","recovery_pending","suspect","log chain","lsn"],"order":15,"steps":11,"scenarios":[{"k":"mode","v":"strategy","l":"Yedekleme stratejisi kur (zamanlanmış yedekler + retention)","m":"Yedekleme yedek planı backup strategy log dosyası büyüyor LOG_BACKUP Msg 9002 transaction log is full sql agent job Msg 3013 3013 BACKUP DATABASE is terminating abnormally yedek alınmıyor yedek job'u Yeni sunucu ya da düzenli yedeği olmayan veritabanı: full / differential / log job'ları, retention ve izleme kurulur."},{"k":"mode","v":"oneoff","l":"Tek seferlik yedek al (ör. değişiklik öncesi COPY_ONLY)","m":"Yedekleme copy_only tek seferlik yedek değişiklik öncesi yedek manuel yedek Msg 4214 4214 Msg 4208 4208 BACKUP LOG is not allowed while the recovery model is SIMPLE Değişiklik, patch ya da upgrade öncesi ya da test ortamına kopya için tek bir yedek; COPY_ONLY zinciri bozmaz."},{"k":"mode","v":"verify","l":"Yedekleri doğrula (geçmiş, VERIFYONLY, test restore)","m":"Prova ve kontrol VERIFYONLY HEADERONLY FILELISTONLY test restore yedek bozuk mu Msg 3241 Msg 3183 Msg 3203 Yedeklerin gerçekten açılabildiğini kanıtlamak için: yedek geçmişi, VERIFYONLY, HEADERONLY / FILELISTONLY ve geçici veritabanına test restore + CHECKDB."},{"k":"mode","v":"chain","l":"Yedek zinciri sağlam mı? (LSN boşluğu, eksik dosya)","m":"Prova ve kontrol Msg 4305 4305 too recent to apply LSN log chain zincir kırık broken log chain Msg 3136 last_log_backup_lsn yedek zinciri Restore'dan önce ya da düzenli denetimde: msdb geçmişinden zinciri çıkarır; LSN boşluklarını, diskte olmayan dosyaları ve araya giren yedekleri bulur. Hiçbir şeyi değiştirmez."},{"k":"mode","v":"restore","l":"Veritabanını yedekten geri yükle (zincir, STOPAT / STOPATMARK, MOVE / REPLACE, başka sunucu)","m":"Geri yükleme ve zamana dönüş STOPAT STOPATMARK STOPBEFOREMARK point in time PITR yanlışlıkla silindi DELETE geri al WITH MOVE REPLACE tail-log Msg 3154 Msg 3159 Msg 5133 Msg 1834 Msg 3156 The tail of the log for the database Msg 3101 3101 Exclusive access could not be obtained Msg 4335 4335 RESTORE DATABASE Veri silindi ya da yanlış güncellendi, veritabanının kopyası gerekiyor ya da başka sunucuya"},{"k":"mode","v":"damaged","l":"Veritabanı açılmıyor: veri dosyası kayıp ya da bozuk (tail-log + restore)","m":"Kayıp / bozulma Msg 945 945 RECOVERY_PENDING recovery pending SUSPECT Msg 5120 5120 Msg 17204 Msg 17207 Msg 5181 FCB::Open failed Operating system error 2 mdf silindi veri dosyası kayıp database cannot be opened Msg 823 NO_TRUNCATE CONTINUE_AFTER_ERROR EMERGENCY Veritabanı RECOVERY_PENDING ya da SUSPECT, .mdf/.ndf okunamıyor ama instance çalışıyor: önce NO_TRUNCATE ile tail-log alınır, sonra son a"},{"k":"mode","v":"page","l":"Birkaç sayfa bozuk (Msg 823 / 824): page restore","m":"Kayıp / bozulma Msg 824 824 Msg 823 823 Msg 829 829 suspect_pages torn page incorrect checksum bozuk sayfa page corruption page restore CHECKDB found Msg 8928 Msg 8939 Msg 8976 repair_allow_data_loss Sorgular ya da CHECKDB belirli sayfalarda hata veriyor (msdb.dbo.suspect_pages): yalnız bozuk sayfalar yedekten geri yüklenir. Enterprise/Developer'da veritabanı açık kalır, Standard/Express'te kısa s"},{"k":"mode","v":"master","l":"master veritabanını geri yükle (tek kullanıcı modu)","m":"Sistem veritabanları master Msg 3108 3108 single user mode single-user tek kullanıcı modu -m Msg 3417 3417 Msg 17113 Msg 18461 master bozuk force-setup REBUILDDATABASE master bozuk ya da login / linked server / sunucu ayarı kaybı: instance tek kullanıcı modunda (-m) başlatılır, master restore edilir, SQL Server kendini kapatır. Kesinti gerekir; instance hiç açılmıyorsa önce sistem veritabanları ye"},{"k":"mode","v":"sysdb","l":"msdb ya da model veritabanını geri yükle","m":"Sistem veritabanları msdb model Msg 3168 3168 job'lar kayboldu msdb suspect Msg 1807 msdb bozuk model bozuk Job'lar, yedek geçmişi, Database Mail (msdb) ya da yeni veritabanı şablonu (model) bozuk / kayıp: aynı build'de alınmış yedekten REPLACE ile geri yüklenir; Agent kısa süre durur."},{"k":"mode","v":"orphan","l":"Restore sonrası kullanıcılar bağlanamıyor (orphaned user, login eşleme)","m":"Taşıma ve erişim Msg 18456 18456 Login failed for user orphaned user orphan yetim kullanıcı sp_help_revlogin sp_change_users_login Msg 15023 15023 Msg 916 Msg 4060 login eşleme SID Veritabanı başka sunucuya taşındı ya da restore edildi, uygulama 'Login failed' alıyor: login'ler SID ve parola hash'iyle kaynaktan taşınır, kalan kullanıcılar login'e bağlanır. Veritabanı açık kalır."},{"k":"mode","v":"enc","l":"Şifreli yedek açılmıyor (sertifika yok, Msg 33111)","m":"Taşıma ve erişim Msg 33111 33111 Cannot find server certificate with thumbprint şifreli yedek encrypted backup sertifika certificate TDE Msg 15581 15581 master key Yedek (ya da TDE'li veritabanının yedeği) sertifikayla şifreli ve bu sunucuda sertifika yok: thumbprint bulunur, sertifika private key ile yüklenir, yedek doğrulanır. Mevcut veritabanlarına dokunulmaz."}]},{"id":"mssql-bcp-export","file":"install/guides/mssql-bcp-export.json","group":"SQL Server","engineId":"mssql","category":"backup","title":"SQL Server tablo bazlı export/import (bcp, sqlpackage)","summary":"Yedek değil, mantıksal veri taşıma: tabloları bcp ile dışa aktarıp başka bir veritabanına yükleme (native ya da karakter biçimi, format dosyası, batch, TABLOCK, kimlik sütunu, UTF-8), sorgu sonucunu CSV/metin dosyasına a","level":"Orta","duration":"20–60 dk","topology":"1 sunucu (komutlar SQL Server'da ya da bir yönetim sunucusunda çalışır)","tags":["sql server","mssql","bcp","bulk copy","export","import","queryout","format file","native","csv","utf-8","sqlpackage","bacpac","dacpac","extract","publish","azure sql","taşıma","migration","tablo kopyalama"],"order":16,"steps":8,"scenarios":[{"k":"op","v":"table","l":"Tabloları taşı: bcp out → bcp in","m":"Veri taşıma bcp bcp out bcp in bulk copy tablo kopyala tablo taşı Unexpected EOF encountered in BCP data-file Unable to open BCP host data-file Bir ya da birkaç tabloyu başka bir SQL Server veritabanına kopyalamak; hedefte tablolar önceden var olmalı."},{"k":"op","v":"query","l":"Sorgu sonucunu dosyaya al: bcp queryout (CSV/metin)","m":"Dışa aktarma queryout csv csv export sorgu sonucu dosyaya export to file Bir sorgunun sonucunu başka sisteme (Excel, ETL, rapor) verilecek CSV/metin dosyasına yazmak."},{"k":"op","v":"bacpac","l":"Şema + veri: sqlpackage Export / Import (.bacpac)","m":"Veri taşıma bacpac sqlpackage SqlPackage Export SqlPackage Import Azure SQL Database taşıma SQL71564 SQL71501 Şema ve veriyi tek dosyada taşımak; özellikle Azure SQL Database'e geçiş ya da küçük/orta veritabanları."},{"k":"op","v":"dacpac","l":"Yalnız şema: sqlpackage Extract / Script / Publish (.dacpac)","m":"Şema dacpac Extract Publish şema karşılaştırma schema compare BlockOnPossibleDataLoss The schema update is terminating because data loss might occur Yalnız şemayı çıkarmak, hedefle karşılaştırıp değişiklik betiği üretmek ya da boş şemayı yeni ortama kurmak."}]},{"id":"mssql-security","file":"install/guides/mssql-security.json","group":"SQL Server","engineId":"mssql","category":"security","title":"SQL Server güvenlik sıkılaştırma (Linux ve Windows: denetim, ağ, TLS, kimlik, yetki, audit, TDE)","summary":"Kurulum rehberi değildir: çalışan bir SQL Server 2019 / 2022 / 2025 instance'ının (Linux ya da Windows) açıklarını bulur ve kapatır. Önce salt-okur Durum denetimi açıkları önem sırasıyla listeler ve her bulgunun hangi ka","level":"Orta","duration":"5 dk (denetim) – 3 saat (tam sıkılaştırma)","topology":"Tek SQL Server instance (Linux ya da Windows) + uygulama sunucusu; Always On AG notlarda","tags":["sql server","mssql","güvenlik","security","hardening","sıkılaştırma","cis benchmark","stig","force encryption","tls","sertifika","sa","check_policy","xp_cmdshell","trustworthy","server audit","audit","tde","transparent data encryption","backup encryption","mssql-conf","windows","linux"],"order":40,"steps":2,"scenarios":[{"k":"scenario","v":"scan","l":"Durum denetimi: açıklarım neler? (salt-okur)","m":"Başlangıç güvenlik denetimi security audit hardening check CIS STIG açık zafiyet vulnerability pentest bulgusu SQL Vulnerability Assessment denetim sorgusu güvenlik taraması security scan KRİTİK İlk çalıştırılacak tarama: sa, parola politikası, boş parolalar, sysadmin üyeleri, public/guest yetkileri, xp_cmdshell, şifresiz bağlantılar, audit, TDE ve sertifika yedekleri, portlar ve firewall; hiçbir "},{"k":"scenario","v":"all","l":"Tam sıkılaştırma (hepsi sırayla)","m":"Başlangıç hardening sıkılaştırma tam güvenlik full hardening CIS benchmark uygula STIG Yeni kurulmuş ya da hiç sıkılaştırılmamış instance: tüm alanlar güvenli sırayla uygulanır; SQL Server bir-iki kez yeniden başlatılır (bakım penceresi gerekir)."},{"k":"scenario","v":"net","l":"Ağ ve bağlantı: kim nereden bağlanabilir? (dinleme, firewall, Browser)","m":"Ağ ve kimlik 1433 1434 SQL Browser firewall ListenOnAllIPs network.ipaddress Error 53 Error 40 TCP/IP Error 26 Error locating Server/Instance Specified Login timeout expired A network-related or instance-specific error dışarıdan erişim erişim kısıtlama SQL Server tüm arayüzlerde dinliyor, 1433 herkese açık, SQL Browser gereksiz yere çalışıyor. Dinleme adresi değişirse yeniden başlatma gerekir."},{"k":"scenario","v":"tls","l":"Bağlantıyı şifrele (Force Encryption, sertifika, istemci doğrulaması)","m":"Ağ ve kimlik Force Encryption TrustServerCertificate Encrypt=Mandatory certificate chain was issued by an authority that is not trusted SSL Provider error 0x80090325 tlscert sertifika süresi TDS 8.0 strict The target principal name is incorrect certificate verify failed Encrypt=Strict Force Strict Encryption Unable to load user-specified certificate sertifika zinciri certificate chain Bağlantılar "},{"k":"scenario","v":"auth","l":"Kimlik doğrulama ve parola (sa, CHECK_POLICY, Windows kimliği)","m":"Ağ ve kimlik sa CHECK_POLICY CHECK_EXPIRATION mixed mode Login failed for user Error 18456 Error 18486 account is locked out parola politikası password policy PWDCOMPARE Error 18452 Login is from an untrusted domain Error 18470 The account is disabled Msg 15118 Msg 33062 sa_disabled Windows Authentication sa açık, SQL login'lerde parola politikası yok, boş/zayıf parolalar; kişisel DBA hesabı ve sa"},{"k":"scenario","v":"priv","l":"En az yetki ve saldırı yüzeyi (roller, public, guest, xp_cmdshell)","m":"Yetki ve iz db_owner sysadmin public guest xp_cmdshell TRUSTWORTHY CONTROL SERVER least privilege en az yetki Msg 262 Msg 229 permission was denied Msg 15247 Msg 916 db_ddladmin EXECUTE AS yetki raporu Uygulama kullanıcısı db_owner ya da sysadmin, public/guest'e fazladan yetki, xp_cmdshell/TRUSTWORTHY açık; rol tasarımı ve yetki raporu. Kesinti yok."},{"k":"scenario","v":"audit","l":"Audit: kim ne yaptı? (Server Audit, Database Audit Specification)","m":"Yetki ve iz SQL Server Audit server audit audit specification fn_get_audit_file C2 audit login auditing denetim izi SIEM KVKK PCI sqlaudit Server Audit Specification Database Audit Specification Msg 33072 kim ne yaptı Denetçi giriş, yetki ve şema değişikliklerinin kaydını istiyor; Server Audit dosyaya (ya da Windows olay günlüğüne), merkezi sisteme aktarım ve saklama. Kesinti yok. Tüm sürümlerde l"},{"k":"scenario","v":"tde","l":"Veriyi diskte şifrele (TDE)","m":"Veri ve yedek TDE transparent data encryption database encryption key DEK service master key Msg 33111 Cannot find server certificate with thumbprint encryption at rest Msg 15208 ENCRYPTION_IN_PROGRESS percent_complete Msg 15581 sertifika yedeği Disk, veri dosyası ya da yedeğin başka sunucuda açılmasına karşı TDE: DMK, sertifika, DEK. Çevrimiçi yapılır; sertifika yedeği ZORUNLU (kaybolursa veritab"},{"k":"scenario","v":"backup","l":"Yedeklerin güvenliği (şifreli yedek, sertifika, izinler)","m":"Veri ve yedek backup encryption yedek şifreleme WITH ENCRYPTION BACKUP CERTIFICATE yedek izinleri Msg 33111 Msg 15151 RESTORE VERIFYONLY key_algorithm Msg 15240 Yedekler şifresiz, yedek dizini herkese açık, parola betikte düz metin; BACKUP … WITH ENCRYPTION, sertifika yedeği ve dizin izinleri. Kesinti yok. Yedek şifrelemesi Standard ve Enterprise'da var, Express'te yok."},{"k":"scenario","v":"os","l":"İşletim sistemi tarafı (servis hesabı, dosya izinleri, SELinux)","m":"Sunucu ve sürüm service account servis hesabı LocalSystem gMSA virtual account icacls SELinux mssql kullanıcısı NT Service\\MSSQLSERVER mssql-server-selinux unconfined_service_t Configuration Manager Log On Servis LocalSystem ya da yönetici hesabıyla çalışıyor, veri/yedek dizinleri herkese açık, SELinux kapalı; servis hesabı değişikliği yeniden başlatma ister."},{"k":"scenario","v":"patch","l":"Yama ve sürüm: desteklenen sürümde ve son CU'da mıyım?","m":"Sunucu ve sürüm CU cumulative update GDR EOL end of support destek bitti CVE güvenlik yaması ProductUpdateLevel ProductUpdateReference Latest updates yama takvimi Sürüm, CU seviyesi ve destek bitişi (2016 Temmuz 2026'da bitti); uygulama için CU patch rehberine bağlanır. Salt-okur."}]},{"id":"mongo-replset","file":"install/guides/mongo-replset.json","group":"MongoDB","engineId":"mongodb","category":"ha","title":"MongoDB replica set kurulumu (3 üye, keyfile ve yetkilendirme)","summary":"Sıfırdan üç üyeli bir MongoDB 8.0 (ya da 7.0) replica set'i kurar: resmi repo, XFS veri dizini, RAM'e göre WiredTiger cache, keyfile ile üyeler arası doğrulama, yetkilendirme, yönetici ve uygulama kullanıcıları, read/wri","level":"Orta","duration":"60–90 dk","topology":"3 sunucu (1 primary + 2 secondary), tek sayıda veri taşıyan üye","tags":["mongodb","mongo","replica set","replset","rs.initiate","keyfile","failover","stepdown","write concern","wiredtiger","yüksek erişilebilirlik","ha","rhel","ubuntu"],"order":1,"steps":36,"scenarios":[]},{"id":"mongo-sharded","file":"install/guides/mongo-sharded.json","group":"MongoDB","engineId":"mongodb","category":"ha","title":"MongoDB sharded cluster kurulumu (config server + shard'lar + mongos)","summary":"Veri ya da yazma yükü tek bir replica set'i aştığında kurulan sharded cluster: üç üyeli config server replica set, iki ya da üç shard replica set ve iki mongos router; keyfile ile iç doğrulama, yetkilendirme, sh.addShard","level":"İleri","duration":"2–3 saat","topology":"3 config server + 2×3 shard üyesi + 2 mongos (en az 11 sunucu; test için daha küçük)","tags":["mongodb","sharding","sharded cluster","mongos","config server","shard key","addShard","balancer","hashed","ölçekleme","rhel","ubuntu"],"order":2,"steps":60,"scenarios":[]},{"id":"mongo-upgrade","file":"install/guides/mongo-upgrade.json","group":"MongoDB","engineId":"mongodb","category":"upgrade","title":"MongoDB rolling upgrade (7.0 → 8.0): replica set ve sharded cluster","summary":"Çalışan bir MongoDB 7.0 replica set'ini ya da sharded cluster'ını kesintisiz (rolling) 8.0'a yükseltir: ön kontroller (sürüm, FCV, üye durumu, sürücü uyumu), yedek, önce secondary'ler, ardından stepDown ve eski primary; ","level":"İleri","duration":"60–120 dk (veri boyutundan bağımsız; üye başına birkaç dakika)","topology":"Replica set (3+ üye) ya da sharded cluster (config server + shard'lar + mongos)","tags":["mongodb","upgrade","yükseltme","rolling upgrade","8.0","7.0","featureCompatibilityVersion","fcv","stepdown","replica set","sharded","balancer","config server","mongos","fcv","featureCompatibilityVersion","rolling upgrade"],"order":3,"steps":30,"scenarios":[]},{"id":"mongo-backup","file":"install/guides/mongo-backup.json","group":"MongoDB","engineId":"mongodb","category":"backup","title":"MongoDB yedek ve geri yükleme (mongodump, mongorestore, snapshot)","summary":"Kurulu bir MongoDB için yedekleme düzenini kurar ve yedekten geri dönüşü senaryo senaryo anlatır. Yedekleme: mongodump ile tek collection, veritabanı ya da tüm deployment (--archive --gzip; replica set'te --oplog ile tut","level":"Orta","duration":"45–90 dk","topology":"Yedek sunucusu ya da bir üye + replica set / tek instance / sharded cluster (mongos)","tags":["mongodb","mongo","yedek","backup","restore","geri yükleme","mongodump","mongorestore","oplog","oplogReplay","nsFrom","nsTo","mongoexport","mongoimport","fsyncLock","lvm snapshot","systemd timer","cron","retention","balancer","activeWindow","config server","cron","systemd timer","flock","oplog","restore senaryoları","point in time recovery","pitr","oplogLimit","nsInclude","dryRun","sharded restore","klon","silinen collection","yanlışlıkla silindi"],"order":15,"steps":20,"scenarios":[{"k":"scenario","v":"setup","l":"Yedeklemeyi kur: mongodump, zamanlama ve test restore","m":"Yedekleme mongodump yedek kur backup setup systemd timer cron retention mongorestore backup user backup.yaml Failed: can't create session oplog overflow mongodump was unable to capture all new oplog entries yedekleme Yedek kullanıcısı, kimlik dosyası, elle ve zamanlanmış mongodump, yeniden adlandırarak test restore; isteğe bağlı snapshot ve mongoexport. İlk kez kuruyorsanız buradan başlayın."},{"k":"scenario","v":"r_dry","l":"Yedek gerçekten geri yüklenebilir mi? (--dryRun ve geçici instance'ta prova)","m":"Prova ve kontrol dryRun --dryRun restore test restore provası yedek doğrulama backup verify gzip: invalid compressed data unexpected EOF archive is corrupt bozuk arşiv gzip -t yedek açılıyor mu Canlı veriye dokunmadan: arşivin bütünlüğü, içindeki namespace'ler ve oplog, isteğe bağlı olarak geçici bir mongod'a tam geri yükleme ve belge sayımı."},{"k":"scenario","v":"r_full","l":"Tüm veriyi yedekten geri yükle (tam restore, --drop)","m":"Geri yükleme full restore tam restore tam geri yükleme --drop mongorestore --drop veri kaybı data loss ransomware fidye tüm veri silindi dropDatabase no oplog file to replay oplogReplay applyOps not authorized … applyOps admin.tempusers Veri büyük ölçüde kayboldu ya da bozuldu ve deployment yedeğin alındığı ana dönecek. Yedekten sonraki yazmalar kaybolur; uygulama restore süresince durur."},{"k":"scenario","v":"r_ns","l":"Tek veritabanını ya da collection'ı geri getir (--nsInclude, yeni adla ya da yerinde)","m":"Geri yükleme --nsInclude --nsFrom --nsTo tek collection single collection restore collection silindi collection dropped drop collection silinen belgeler deleted documents deleteMany namespace restore E11000 duplicate key error $merge orders_restored tek veritabanı geri yükle Bir collection/veritabanı silindi ya da bozuldu, geri kalanı sağlam: yalnız o namespace yedekten gelir; diğer verilere dokun"},{"k":"scenario","v":"r_pitr","l":"Belirli bir ana dön: yedek + oplog (yanlışlıkla drop, hatalı update/delete)","m":"Zamana dönüş point in time PITR zamana dönüş --oplogReplay --oplogLimit oplog replay oplog.rs yanlışlıkla silindi accidental drop hatalı update wrong update drop öncesi Timestamp oplog dönmüş rollback to time belirli saate dön Hatalı işlem yedekten sonra oldu ve o ana kadar olan yazmalar da gerekli: son tam yedek geri yüklenir, canlı oplog hatalı işlemden hemen öncesine kadar uygulanır (--oplogRep"},{"k":"scenario","v":"r_other","l":"Yedeği başka bir cluster'a / sunucuya geri yükle (klon, test ortamı, taşıma)","m":"Taşıma ve klon clone klon başka sunucuya restore restore to another cluster migration taşıma test ortamı refresh nsExclude admin.system.users Invalid feature compatibility version cannot use --oplogReplay with excludes specified test ortamına kopya Kaynak deployment'a dokunulmaz: yedek başka bir replica set ya da instance'a açılır (test/raporlama kopyası, sunucu taşıma, sürüm geçişi); kullanıcılar"},{"k":"scenario","v":"r_shard","l":"Sharded cluster'ı geri yükle: mongodump'ın sınırları ve doğru yöntem","m":"Taşıma ve klon sharded restore sharded cluster restore mongos restore shard key shardCollection config server restore balancer inconsistent tutarsız yedek PBM Percona Backup Ops Manager --oplog mode only supported on full dumps mongos üzerinden yedek Yedeklenen yapı sharded cluster: mongos üzerinden mantıksal geri yükleme (shard key'lerin yeniden kurulması, balancer) ya da koordineli snapshot'larl"}]},{"id":"mongo-ops","file":"install/guides/mongo-ops.json","group":"MongoDB","engineId":"mongodb","category":"ops","title":"MongoDB günlük işletim ve arıza senaryoları (replica set ve sharded cluster)","summary":"Kurulum değil: kurulu bir MongoDB replica set'ini ve sharded cluster'ını günlük olarak yönetmek ve bozulduğunda kurtarmak için senaryo bazlı runbook. Sağlık kontrolü, üye ekleme/çıkarma, priority/hidden/delayed üye, arbi","level":"İleri","duration":"5 dk (kontrol) – birkaç saat (initial sync, drain, reshard)","topology":"Replica set (3+ üye) ya da sharded cluster (config server + shard replica set'leri + mongos)","tags":["mongodb","mongo","replica set","sharded cluster","rs.status","rs.add","rs.remove","rs.reconfig","force reconfig","stepDown","priority","hidden","delayed","secondaryDelaySecs","arbiter","resync","initial sync","too stale","oplog","replSetResizeOplog","FCV","setFeatureCompatibilityVersion","addShard","removeShard","movePrimary","balancer","activeWindow","jumbo","chunk","reshardCollection","shard key","işletim","arıza"],"order":20,"steps":3,"scenarios":[{"k":"scenario","v":"health","l":"Sağlık kontrolü: üyeler, gecikme, oplog penceresi (sharded'da shard'lar ve balancer)","m":"İzleme ve kontrol rs.status rs.status() replication lag gecikme replLag printSecondaryReplicationInfo sh.status health sağlık NotYetInitialized RECOVERING STARTUP2 UNKNOWN (not reachable/healthy) DOWN ReplicaSetNoPrimary Server selection timed out lastHeartbeatMessage Salt-okur: üye durumları, replikasyon gecikmesi, oplog penceresi, yapılandırma; sharded cluster'da shard listesi, balancer ve chunk"},{"k":"scenario","v":"add","l":"Replica set'e yeni üye ekle (initial sync)","m":"Üye yönetimi rs.add üye ekle add member initial sync yeni secondary newlyAdded STARTUP2 scale out rs.add() Quorum check failed Found two member configurations with same host field votes: 0 Yeni sunucu kuruldu (aynı sürüm, keyfile, replSetName); priority 0 / votes 0 ile eklenir, initial sync bitip SECONDARY olunca oy ve priority verilir. Kesinti yok."},{"k":"scenario","v":"remove","l":"Üyeyi replica set'ten çıkar","m":"Üye yönetimi rs.remove üye çıkar remove member decommission sunucu kaldır REMOVED Our replica set config is invalid or we are not a member of it rs.remove() Sunucu emekliye ayrılıyor ya da kalıcı olarak kayıp: üye yapılandırmadan çıkarılır, kalan oy sayısının çoğunluğu koruduğu doğrulanır. Primary ise önce stepDown."},{"k":"scenario","v":"member_cfg","l":"Üye rolünü değiştir: priority, hidden, delayed (gecikmeli) üye","m":"Üye yönetimi priority hidden delayed secondaryDelaySecs slaveDelay gizli üye gecikmeli üye votes rs.reconfig priority must be 0 when hidden=true only one voting member can be added or removed at a time rs.reconfig() Bir üyenin primary olma önceliğini değiştirmek, raporlama/yedek için gizli (hidden) ya da yanlış silmelere karşı gecikmeli (delayed) üye yapmak veya normale döndürmek."},{"k":"scenario","v":"arbiter","l":"Arbiter'ı veri taşıyan üyeyle değiştir (PSA → PSS)","m":"Üye yönetimi arbiter arbiterOnly PSA rs.addArb majority write concern cache pressure w: majority bekliyor Rejecting reconfig where the new config has a PSA topology implicit default write concern majority commit point Replica set primary + secondary + arbiter: bir veri üyesi düşünce majority yazmalar ve cache baskısı sorun olur. Yeni veri üyesi eklenir, arbiter çıkarılır."},{"k":"scenario","v":"resync","l":"Geride kalmış ya da bozuk üyeyi yeniden eşitle (resync)","m":"Arıza ve kurtarma too stale too stale to catch up RS102 resync yeniden eşitle initial sync RECOVERING WiredTiger error WT_PANIC bozuk veri dosyası data corruption OplogStartMissing maintenance mode InitialSyncFailure fassert checksum mismatch Üye RECOVERING'de takılı ve 'too stale to catch up' diyor, ya da veri dosyaları bozuk: üyenin veri dizini boşaltılır, initial sync ile sıfırdan eşitlenir. Di"},{"k":"scenario","v":"force","l":"Çoğunluk kaybı: kalan üyelerle zorla yeniden yapılandır (force reconfig)","m":"Arıza ve kurtarma force reconfig force: true no primary primary yok çoğunluk kaybı majority lost NotWritablePrimary not master no replset config split brain DR site site kaybı ReplicaSetNoPrimary Server selection timed out rs.reconfig force Üyelerin çoğu kalıcı olarak kayıp (site/sunucu kaybı), kalanlar primary seçemiyor: kalan üyelerle rs.reconfig(cfg, {force: true}). Son çare; yanlış kullanımda "},{"k":"scenario","v":"stepdown","l":"Planlı primary değişimi (rs.stepDown, belirli üyeyi primary yapma)","m":"Bakım stepDown rs.stepDown replSetStepDown primary değiştir switchover bakım maintenance rs.freeze No electable secondaries caught up InterruptedDueToReplStateChange PrimarySteppedDown primary değişimi Primary sunucuda bakım/patch yapılacak: primary geri çekilir, yetişmiş bir secondary primary olur. Uygulama birkaç saniye yazma hatası alabilir."},{"k":"scenario","v":"oplog","l":"Oplog boyutunu değiştir (replSetResizeOplog)","m":"Bakım oplog oplog window oplog penceresi replSetResizeOplog oplogSizeMB oplogMinRetentionHours too stale oplog overflow rs.printReplicationInfo getReplicationInfo log length start to end Oplog penceresi kısa: secondary'ler bakım sonrası 'too stale' oluyor, yedek oplog'u yakalayamıyor ya da zamana dönüş için yetmiyor. Her üyede kesintisiz büyütülür."},{"k":"scenario","v":"fcv","l":"Feature Compatibility Version (FCV) kontrol et ve tamamla","m":"Bakım FCV featureCompatibilityVersion setFeatureCompatibilityVersion Invalid feature compatibility version IncompatibleServerVersion upgrade sonrası UPGRADE PROBLEM requires confirm: true getParameter featureCompatibilityVersion Upgrade sonrası FCV eski sürümde kaldı ya da üyeler arasında sürüm farkı var: tüm üyelerin binary sürümü ve FCV kontrol edilir, FCV yeni sürüme çekilir."},{"k":"scenario","v":"addshard","l":"Cluster'a shard ekle (sh.addShard)","m":"Sharded cluster addShard sh.addShard shard ekle add shard scale out yeni shard shardAdded is not running with --shardsvr in use by another shard Kapasite yetmiyor: yeni bir shard replica set'i (shardsvr) kuruldu, cluster'a eklenir; balancer chunk'ları kademeli olarak taşır."},{"k":"scenario","v":"rmshard","l":"Shard çıkar (removeShard: drain ve movePrimary)","m":"Sharded cluster removeShard remove shard shard çıkar drain draining movePrimary dbsToMove jumboChunks moveCollection collectionsToMove ShardNotFound draining started successfully Bir shard emekliye ayrılıyor: chunk'ları diğer shard'lara boşaltılır (drain), primary shard olduğu veritabanları taşınır (movePrimary), sonra cluster'dan çıkarılır."},{"k":"scenario","v":"balancer","l":"Balancer: zaman penceresi, durdur / başlat, collection bazında kapat","m":"Sharded cluster balancer activeWindow stopBalancer startBalancer sh.stopBalancer disableBalancing balancer penceresi chunk migration moveChunk isBalancerRunning getBalancerState Balancer timed out Chunk taşımaları yoğun saatte yük yaratıyor, bakım/yedek için taşımaların durması gerekiyor ya da tek bir collection'ın dengelenmesi istenmiyor."},{"k":"scenario","v":"chunks","l":"Dağılım dengesiz ya da jumbo chunk var (teşhis ve çözüm)","m":"Sharded cluster jumbo jumbo chunk chunk too big ChunkTooBig dengesiz imbalance hot shard balancerCollectionStatus clearJumboFlag moveChunk failed getShardDistribution low cardinality splitFind Cannot split on the boundary jumboChunks Bir shard diğerlerinden çok dolu, balancer taşımıyor, 'jumbo' işaretli chunk'lar var ya da moveChunk hata veriyor: dağılım, jumbo chunk'lar ve balancer hataları incel"},{"k":"scenario","v":"reshard","l":"Shard key'i değiştir (reshardCollection)","m":"Sharded cluster reshardCollection reshard shard key değiştir change shard key refineCollectionShardKey abortReshardCollection commitReshardCollection forceRedistribution ReshardCollectionInProgress ReshardCollectionAborted unshardCollection Mevcut shard key sıcak shard, jumbo chunk ya da scatter-gather sorgular üretiyor: collection çevrimiçi olarak yeni shard key ile yeniden dağıtılır (5.0+). Sond"},{"k":"mcfg","v":"priority","l":"Priority değiştir (primary olma önceliği)","m":"Üyenin primary olma önceliğini değiştirir (ör. ana veri merkezindeki üyeyi tercih etmek, DR üyesini 0 yapmak). Seçim yapılabilir; kısa yazma kesintisi olabilir."},{"k":"mcfg","v":"hidden","l":"Gizli (hidden) üye: uygulama görmez, yedek/raporlama için","m":"Üye uygulamalara görünmez (okuma yönlendirilmez); raporlama, analitik ya da yedek için ayrılır. Priority 0 olur, primary olamaz."},{"k":"mcfg","v":"delayed","l":"Gecikmeli (delayed) üye: yanlış silmelere karşı","m":"Üye oplog'u belirtilen süre geriden uygular; yanlışlıkla silinen veri bu süre boyunca onda durur. Hidden, priority 0 ve votes 0 olur."},{"k":"mcfg","v":"normal","l":"Normale döndür (priority 1, görünür, gecikmesiz, oy verir)","m":"Önceki rolü geri alır: priority 1, görünür, gecikmesiz, oy verir."},{"k":"bal_op","v":"window","l":"Zaman penceresi tanımla (activeWindow)","m":"Taşımalar yalnız belirli saatlerde (ör. gece) yapılsın; gündüz yük oluşmaz."},{"k":"bal_op","v":"unwindow","l":"Zaman penceresini kaldır (her zaman çalışsın)","m":"Zaman penceresi kaldırılır; balancer gerektiğinde her saatte taşır (ör. yeni shard eklendikten sonra hızlı denge için)."},{"k":"bal_op","v":"stop","l":"Balancer'ı durdur (bakım/yedek)","m":"Yedek, upgrade ya da bakım öncesi: devam eden taşıma biter, yenisi başlamaz. İş bitince mutlaka yeniden başlatın."},{"k":"bal_op","v":"start","l":"Balancer'ı başlat","m":"Durdurulmuş balancer'ı açar; dengeleme kaldığı yerden devam eder."},{"k":"bal_op","v":"coll_off","l":"Tek collection'da dengelemeyi kapat","m":"Yalnız bir collection'ın chunk'ları taşınmaz (bilinçli yerleşim, sorunlu collection). Diğerleri dengelenmeye devam eder."},{"k":"bal_op","v":"coll_on","l":"Tek collection'da dengelemeyi aç","m":"Collection için kapatılmış dengelemeyi yeniden açar."}]},{"id":"mongo-security","file":"install/guides/mongo-security.json","group":"MongoDB","engineId":"mongodb","category":"security","title":"MongoDB güvenlik sıkılaştırma (yetkilendirme, TLS, roller, audit)","summary":"Çalışan bir MongoDB'yi (tek sunucu, replica set ya da sharded cluster) kesinti olmadan sıkılaştırmak için senaryo bazlı runbook: salt-okur güvenlik denetimi, keyFile + transitionToAuth ile rolling yetkilendirme, en az ye","level":"İleri","duration":"10 dk (denetim) – 2 saat (tam sıkılaştırma)","topology":"Tek sunucu, 3+ üyeli replica set ya da sharded cluster","tags":["mongodb güvenlik","mongodb security","hardening","sıkılaştırma","CIS","authorization","keyFile","transitionToAuth","TLS","requireTLS","x.509","SCRAM-SHA-256","custom role","least privilege","bindIp","audit log","auditLog","encryption at rest","LUKS","Percona"],"order":20,"steps":8,"scenarios":[{"k":"op","v":"audit","l":"Güvenlik durumu denetimi (salt-okur)","m":"Denetim güvenlik denetimi security audit security checklist CIS MongoDB hardening sıkılaştırma Access control is not enabled for the database auth kapalı mı bindIp 0.0.0.0 exposed mongodb internete açık mongodb ransom fidye getCmdLineOpts security checklist MongoDB denetim raporu Hiçbir şey değiştirmez. Kimliksiz erişim, dinlenen adresler, TLS, kimlik doğrulama mekanizmaları, yüksek yetkili kullan"},{"k":"op","v":"all","l":"Tam sıkılaştırma (hepsi sırayla)","m":"Denetim tam sıkılaştırma full hardening CIS benchmark güvenlik projesi pentest bulgusu denetim bulguları Denetim → internal auth + authorization (transitionToAuth ile kesintisiz) → en az yetkili kullanıcılar → SCRAM-SHA-256 → bindIp/firewall → TLS (allowTLS → preferTLS → requireTLS) → audit (Enterprise/Percona) → son denetim. Replica set'te rolling yapılır; her riskli adım onay ister."},{"k":"op","v":"auth","l":"Yetkilendirme kapalı: authorization'ı aç (keyFile, kesintisiz)","m":"Kimlik ve yetki Access control is not enabled for the database Read and write access to data and configuration is unrestricted authorization disabled authorization: enabled auth kapalı no authentication transitionToAuth keyFile internal authentication üyeler arası doğrulama kimliksiz erişim permissions on /etc/mongod.keyfile are too open Authentication failed __system localhost exception Herkes ku"},{"k":"op","v":"users","l":"En az yetkili kullanıcılar ve custom role (uygulama, yedek, izleme)","m":"Kimlik ve yetki least privilege en az yetki custom role createRole root kullanıcı uygulama root ile bağlanıyor not authorized on Unauthorized command find requires authentication requires authentication readWrite clusterMonitor backup rolü createUser grantRolesToUser monitor_user backup_user Uygulamalar root ya da ortak bir yönetici hesabıyla bağlanıyor. Uygulamaya yalnız kendi veritabanında gerek"},{"k":"op","v":"scram","l":"SCRAM-SHA-1'i kapat, yalnız SCRAM-SHA-256","m":"Kimlik ve yetki SCRAM-SHA-1 SCRAM-SHA-256 authenticationMechanisms Received authentication for mechanism SCRAM-SHA-1 which is not enabled Unable to use SCRAM-SHA-256 based authentication for user without any SCRAM-SHA-256 credentials registered MD5 mechanism Eski kullanıcıların kimlik bilgisi SHA-1 ile saklanıyor ya da denetim SCRAM-SHA-1'i açık buldu. Kullanıcılar SHA-256'ya taşınır, ardından `au"},{"k":"op","v":"bind","l":"Ağ erişimini daralt (bindIp 0.0.0.0, firewall)","m":"Ağ ve şifreleme bindIp 0.0.0.0 bindIpAll bind_ip_all 0.0.0.0:27017 port 27017 açık shodan internete açık firewall javascriptEnabled noscripting net.bindIp ufw allow 27017 firewall-cmd 27017 mongod tüm arayüzlerde (0.0.0.0, `bindIpAll`) dinliyor ya da port herkese açık. bindIp yalnız localhost + sunucunun iç IP'sine indirilir, firewall yalnız üyelere ve uygulama ağına izin verir. Rolling, kesintisi"},{"k":"op","v":"tls","l":"Bağlantıları şifrele: TLS (allowTLS → preferTLS → requireTLS)","m":"Ağ ve şifreleme TLS SSL net.tls.mode requireTLS preferTLS allowTLS şifresiz bağlantı cleartext no SSL certificate provided by peer SSL peer certificate validation failed certificate verify failed x.509 x509 clusterAuthMode Hostname/IP does not match certificate's altnames self-signed certificate in certificate chain rotateCertificates allowConnectionsWithoutCertificates Uygulama ve üyeler arası tr"},{"k":"op","v":"auditlog","l":"Audit log'u aç (Enterprise / Percona)","m":"İz ve veri koruma audit log auditLog denetim kaydı kim sildi who dropped Unrecognized option: auditLog unrecognised option '--auditDestination' KVKK PCI DSS log kaydı Kimin ne zaman oturum açtığı, kullanıcı/rol değişiklikleri ve drop işlemleri kayıt altına alınmalı. MongoDB Enterprise ve Percona Server for MongoDB'de `auditLog` ile açılır; Community'de bu özellik yoktur (alternatif gösterilir)."},{"k":"op","v":"ear","l":"Encryption at rest (diskteki veriyi şifrele)","m":"İz ve veri koruma encryption at rest disk şifreleme enableEncryption encryptionKeyFile KMIP Vault LUKS dm-crypt veri şifreleme Unrecognized option: security.enableEncryption Unable to retrieve key Unable to use encryption at rest cryptsetup luksFormat Disk ya da yedek çalınırsa veri okunamasın. Enterprise/Percona'da WiredTiger şifrelemesi üyeler tek tek initial sync ile yeniden kurularak açılır; C"}]},{"id":"redis-sentinel","file":"install/guides/redis-sentinel.json","group":"Redis","engineId":"redis","category":"ha","title":"Redis Sentinel ile yüksek erişilebilirlik (master + replica + 3 Sentinel)","summary":"Sıfırdan üç sunuculu bir Redis 7.2 / 8.2 ya da Valkey yüksek erişilebilirlik kurulumu yapar: bir master, iki replica ve her sunucuda bir Sentinel. RAM'e göre maxmemory, kalıcılık (RDB/AOF), parola, çekirdek ayarları, quo","level":"Orta","duration":"45–60 dk","topology":"3 sunucu: her birinde Redis (1 master + 2 replica) ve Sentinel","tags":["redis","valkey","sentinel","replica","replication","failover","quorum","yüksek erişilebilirlik","ha","cache","rhel","ubuntu"],"order":1,"steps":27,"scenarios":[]},{"id":"redis-cluster","file":"install/guides/redis-cluster.json","group":"Redis","engineId":"redis","category":"ha","title":"Redis Cluster kurulumu (3 master + 3 replica)","summary":"Sıfırdan bir Redis Cluster kurar (Redis 7.2 / 8.2 ya da Valkey): 16384 hash slot üç (ya da daha çok) master'a paylaştırılır, her master'ın farklı sunucuda bir replica'sı olur. Sunucu başına bir instance (6 sunucu) ya da ","level":"Orta","duration":"45–60 dk","topology":"6 instance: 6 sunucu × 1 ya da 3 sunucu × 2","tags":["redis","valkey","cluster","redis cluster","sharding","hash slot","reshard","failover","replica","ölçekleme","rhel","ubuntu"],"order":2,"steps":33,"scenarios":[]},{"id":"redis-backup","file":"install/guides/redis-backup.json","group":"Redis","engineId":"redis","category":"backup","title":"Redis yedek ve geri yükleme (RDB, AOF, replica ve cluster)","summary":"Kurulu bir Redis ya da Valkey (tek instance, Sentinel'li master/replica ya da Redis Cluster) için yedekleme düzenini kurar ve yedekten geri dönüşü anlatır. RDB (save kuralı, BGSAVE, LASTSAVE, dump.rdb kopyası) ve AOF (BG","level":"Orta","duration":"30–60 dk","topology":"Tek instance, replica ya da Redis Cluster sunucusu (Redis 7.2 / 8.x, Valkey)","tags":["redis","valkey","yedek","backup","restore","geri yükleme","rdb","dump.rdb","bgsave","lastsave","aof","appendonly","bgrewriteaof","appendonlydir","redis cluster","systemd timer","cron","retention","cron","systemd timer","flock","REDISCLI_AUTH","sentinel"],"order":15,"steps":19,"scenarios":[]},{"id":"redis-ops","file":"install/guides/redis-ops.json","group":"Redis","engineId":"redis","category":"ops","title":"Redis / Valkey günlük işletim ve arıza senaryoları (Cluster ve Sentinel)","summary":"Kurulum değil: kurulu bir Redis Cluster'ı ya da Sentinel'li master/replica yapısını günlük olarak yönetmek ve bozulduğunda kurtarmak için senaryo bazlı runbook (Redis 7.2, Redis 8 ve Valkey). Cluster: sağlık kontrolü, no","level":"İleri","duration":"5 dk (kontrol) – 1 saat (reshard)","topology":"Redis Cluster (3+ master + replica'lar) ya da Sentinel (1 master + replica'lar + 3 Sentinel)","tags":["redis","valkey","redis cluster","sentinel","redis-cli --cluster","cluster check","add-node","del-node","reshard","rebalance","CLUSTER FAILOVER","FORCE","TAKEOVER","CLUSTER FORGET","cluster fix","SENTINEL FAILOVER","SENTINEL RESET","quorum","CKQUORUM","INFO memory","MEMORY DOCTOR","eviction","maxmemory","bigkeys","memkeys","hotkeys","işletim","arıza"],"order":20,"steps":3,"scenarios":[{"k":"scenario","v":"c_health","l":"Cluster sağlık kontrolü (--cluster check, CLUSTER INFO / NODES)","m":"Redis Cluster: izleme cluster_state:fail CLUSTERDOWN CLUSTERDOWN Hash slot not served --cluster check CLUSTER INFO CLUSTER NODES fail? pfail slots not covered Not all 16384 slots are covered [ERR] Nodes don't agree about configuration MOVED ASK CLUSTERDOWN The cluster is down cluster_slots_fail cluster sağlık cluster health cluster_state Salt-okur: tüm slot'lar kapsanmış mı, node'lar aynı yapıland"},{"k":"scenario","v":"c_add","l":"Cluster'a node ekle (master ya da replica)","m":"Redis Cluster: node yönetimi add-node --cluster add-node node ekle add node scale out --cluster-slave --cluster-replica cluster-master-id yeni master yeni replica Node is not empty. Either the node already knows other nodes New node added correctly kapasite artır Yeni instance (cluster-enabled yes, boş) hazır: cluster'a master olarak eklenip slot alır ya da bir master'ın replica'sı olur. Kesinti y"},{"k":"scenario","v":"c_remove","l":"Cluster'dan node çıkar (slot'ları boşalt + del-node)","m":"Redis Cluster: node yönetimi del-node --cluster del-node node çıkar remove node scale in slot boşalt cluster-weight Node … is not empty is not empty! Reshard data away and try again CLUSTER RESET SOFT node emekli Bir master ya da replica emekliye ayrılıyor: master'ın slot'ları diğer master'lara taşınır, sonra node cluster'dan çıkarılır. Kesinti yok; taşıma sırasında ASK yönlendirmesi olur."},{"k":"scenario","v":"c_reshard","l":"Slot'ları yeniden dağıt (rebalance / reshard)","m":"Redis Cluster: node yönetimi rebalance reshard --cluster rebalance --cluster reshard slot dağılımı dengesiz imbalance use-empty-masters MIGRATE importing migrating BUSYKEY IOERR error or timeout reading to target instance has slots in importing state has slots in migrating state Calling MIGRATE No rebalancing needed slot taşı Master'lar arasında slot ya da bellek dengesiz, yeni master slot almadı "},{"k":"scenario","v":"c_failover","l":"Elle failover: replica'yı master yap (CLUSTER FAILOVER, FORCE, TAKEOVER)","m":"Redis Cluster: arıza ve bakım CLUSTER FAILOVER failover FORCE TAKEOVER manual failover master bakım replica master yap Manual failover timed out ERR Master is down or failed, please use CLUSTER FAILOVER FORCE ERR You should send CLUSTER FAILOVER to a replica master değiştir Master'ın sunucusunda bakım yapılacak (planlı, veri kaybı yok) ya da master erişilemez ve otomatik failover olmadı (FORCE / T"},{"k":"scenario","v":"c_replace","l":"Arızalı master'ı / node'u değiştir (FORGET, yeni replica, --cluster fix)","m":"Redis Cluster: arıza ve bakım CLUSTER FORGET --cluster fix node kayıp failed node fail noaddr slots not covered CLUSTERDOWN replace node arızalı master handshake ERR Can't forget my master! CLUSTERDOWN Hash slot not served sunucu kayıp disk arızası Bir node'un sunucusu kalıcı olarak kayıp: replica'sı master olduysa eski node unutturulur ve yerine yeni replica eklenir; replica'sı yoksa slot'lar sah"},{"k":"scenario","v":"s_health","l":"Sentinel durumu: master, replica'lar, Sentinel'ler, quorum","m":"Sentinel SENTINEL MASTERS SENTINEL master get-master-addr-by-name CKQUORUM +sdown +odown -odown +switch-master NOQUORUM NOGOODSLAVE sentinel durumu +tilt -failover-abort-not-elected s_down o_down master_link_status:down sentinel health Salt-okur: Sentinel'lerin gördüğü master adresi, replica'lar, diğer Sentinel'ler, CKQUORUM ve son failover olayları. Sentinel'li yapıda ne yapacağınızdan emin değil"},{"k":"scenario","v":"s_failover","l":"Sentinel ile elle failover (SENTINEL FAILOVER)","m":"Sentinel SENTINEL FAILOVER sentinel failover switch-master planlı failover INPROG NOGOODSLAVE -failover-abort-no-good-slave NOGOODSLAVE No suitable replica to promote sentinel bakım Master sunucusunda bakım yapılacak: Sentinel en uygun replica'yı master yapar, diğer replica'ları ve istemcileri yeni master'a yönlendirir. Kesinti 1–2 sn; master çalışırken veri kaybı yok."},{"k":"scenario","v":"s_replace","l":"Sentinel ortamında node ekle / çıkar / değiştir (SENTINEL RESET)","m":"Sentinel SENTINEL RESET sentinel reset replicaof yeni replica yeni sentinel sentinel ekle sentinel çıkar eski replica görünüyor num-other-sentinels known-replica known-sentinel eski sentinel görünüyor Bir replica ya da Sentinel kalıcı olarak kaldırıldı ya da yeni eklendi: yeni replica REPLICAOF ile bağlanır, Sentinel'lerin eski kayıtları SENTINEL RESET ile temizlenir."},{"k":"scenario","v":"s_quorum","l":"Quorum ve Sentinel ayarlarını değiştir (SENTINEL SET)","m":"Sentinel SENTINEL SET quorum down-after-milliseconds failover-timeout parallel-syncs CKQUORUM NOQUORUM failover çok geç gereksiz failover Sentinel sayısı değişti ya da failover çok geç/çok erken tetikleniyor: quorum, down-after-milliseconds, failover-timeout, parallel-syncs tüm Sentinel'lerde değiştirilir."},{"k":"scenario","v":"memory","l":"Bellek baskısı: kullanım, fragmentation, eviction teşhisi","m":"Bellek ve anahtarlar OOM command not allowed when used memory > 'maxmemory' OOM maxmemory used_memory evicted_keys eviction maxmemory-policy MEMORY DOCTOR mem_fragmentation_ratio fragmentation activedefrag client-output-buffer-limit bellek doldu Out of memory: Killed process oom-killer used_memory_rss mem_clients_normal omem used_memory maxmemory'ye yaklaştı, 'OOM command not allowed' hatası, evic"},{"k":"scenario","v":"bigkeys","l":"Büyük ve sıcak anahtarları bul (--bigkeys, --memkeys, --hotkeys)","m":"Bellek ve anahtarlar --bigkeys --memkeys --hotkeys big key büyük anahtar hot key sıcak anahtar MEMORY USAGE UNLINK slowlog latency SCAN HGETALL KEYS * --keystats gecikme sıçraması latency spike Tek bir node'un belleği ya da CPU'su diğerlerinden yüksek, gecikme sıçramaları var, DEL uzun sürüyor: en büyük ve en çok erişilen anahtarlar bulunur ve güvenli şekilde temizlenir (UNLINK)."},{"k":"add_role","v":"master","l":"Master (slot alır: ekledikten sonra rebalance)","m":"Boş master olarak katılır, sonra rebalance ile slot alır. Kapasite artırır; yeni master için ayrıca bir replica eklenmelidir."},{"k":"add_role","v":"replica","l":"Replica (bir master'ın kopyası)","m":"Bir master'ın kopyası olur: master düşerse devralır. Master'ın belleği kadar veri ağdan geçer (tam eşitleme)."},{"k":"rs_mode","v":"rebalance","l":"Rebalance: slot'ları master'lar arasında eşit dağıt (boş master'lar dahil)","m":"Tüm master'lar eşit pay alır (slot'suz yeni master dahil). Önce simülasyon gösterilir. Yeni master eklendikten sonra en yaygın işlem."},{"k":"rs_mode","v":"move","l":"Reshard: belirli sayıda slot'u bir master'dan diğerine taşı","m":"Belirli sayıda slot bir master'dan diğerine taşınır: sıcak/büyük bir master'ı rahatlatmak ya da bir master'ı kademeli boşaltmak için."},{"k":"fo_mode","v":"default","l":"Planlı (varsayılan): master ile eşitlenip devralır, veri kaybı yok","m":"Master çalışıyor olmalı."},{"k":"fo_mode","v":"force","l":"FORCE: master'a ulaşılamıyor, eşitlemeyi beklemeden devral","m":"Master'ın son yazmaları kaybolabilir; master'ların çoğunluğu yine oy verir."},{"k":"fo_mode","v":"takeover","l":"TAKEOVER: master'ların çoğunluğu da yok, oylama olmadan devral","m":"Son çare: split brain ve epoch çakışması riski."},{"k":"srep_op","v":"add_replica","l":"Yeni replica ekle","m":"Yeni sunucudaki Redis mevcut master'a bağlanır; Sentinel'ler onu kendiliğinden keşfeder."},{"k":"srep_op","v":"rm_replica","l":"Replica'yı kalıcı olarak çıkar","m":"Replica kapatılır ve tüm Sentinel'lerde kaydı temizlenir."},{"k":"srep_op","v":"add_sentinel","l":"Yeni Sentinel ekle","m":"Yeni sunucuya Sentinel eklenir (toplam Sentinel sayısı tek kalmalı: 3 → 5)."},{"k":"srep_op","v":"rm_sentinel","l":"Sentinel'i kalıcı olarak çıkar","m":"Sentinel kapatılır ve diğerlerinde kaydı temizlenir; sonra quorum gözden geçirilir."}]},{"id":"redis-security","file":"install/guides/redis-security.json","group":"Redis","engineId":"redis","category":"security","title":"Redis / Valkey güvenlik sıkılaştırma (ACL, TLS, tehlikeli komutlar)","summary":"Kurulum ya da günlük işletim değil: çalışan bir Redis ya da Valkey'i (tek sunucu, replica + Sentinel ya da Cluster) kesinti olmadan sıkılaştırmak için senaryo bazlı runbook. Salt-okur güvenlik denetimi, ACL kullanıcıları","level":"İleri","duration":"5 dk (denetim) – 90 dk (tam sıkılaştırma)","topology":"Tek sunucu, master + replica + Sentinel ya da Redis Cluster","tags":["redis güvenlik","redis security","valkey","hardening","sıkılaştırma","ACL","ACL SETUSER","aclfile","requirepass","masterauth","protected-mode","bind","rename-command","enable-protected-configs","TLS","tls-replication","sentinel parola","CIS"],"order":20,"steps":7,"scenarios":[{"k":"op","v":"audit","l":"Güvenlik durumu denetimi (salt-okur)","m":"Denetim redis güvenlik denetimi redis security audit CIS Redis hardening sıkılaştırma redis açık exposed redis unauthorized redis redis parolasız -NOAUTH crackit redis cryptominer kinsing NOAUTH Authentication required redis güvenlik kontrolü redis pentest Hiçbir şey değiştirmez. Parolasız erişim, default kullanıcı, dinlenen adresler, protected-mode, tehlikeli komutlar, TLS, Sentinel parolası ve d"},{"k":"op","v":"all","l":"Tam sıkılaştırma (hepsi sırayla)","m":"Denetim tam sıkılaştırma full hardening redis güvenlik projesi pentest bulgusu Denetim → ACL kullanıcıları (yönetici, uygulama, replikasyon, Sentinel) ve default kullanıcıyı kapatma → bind/protected-mode/firewall → tehlikeli komutlar ve protected config'ler → TLS → dosya izinleri → son denetim. Replica/Sentinel'de rolling; riskli adımlar onay ister."},{"k":"op","v":"acl","l":"ACL kullanıcıları ve default kullanıcıyı kapat (Redis 6+)","m":"Kimlik ve yetki ACL ACL SETUSER aclfile default user default kullanıcı NOPERM WRONGPASS invalid username-password pair -NOAUTH Authentication required user default on nopass masteruser least privilege en az yetki NOPERM this user has no permissions to run the NOPERM this user has no permissions to access one of the keys used as arguments ACL LOG kullanıcı başına parola ACL SAVE Herkes tek parolayl"},{"k":"op","v":"auth","l":"Parolasız Redis: requirepass / masterauth (hızlı önlem)","m":"Kimlik ve yetki requirepass masterauth auth-pass parolasız redis no password MASTER aborted replication with an error: NOAUTH Unable to AUTH to MASTER -NOAUTH ERR AUTH <password> called without any password configured for the default user Client sent AUTH, but no password is set parola koy Hiç parola yok ve ACL'e geçmek için zaman yok. Tüm node'lara ortak parola (`requirepass` + replikasyon için `"},{"k":"op","v":"net","l":"Ağ erişimini daralt (bind 0.0.0.0, protected-mode, firewall)","m":"Ağ ve şifreleme bind 0.0.0.0 protected-mode no DENIED Redis is running in protected mode 0.0.0.0:6379 port 6379 açık shodan firewall DENIED Redis is running in protected mode because protected mode is enabled and no password is set for the default user *:6379 Could not create server TCP listening socket Redis tüm arayüzlerde dinliyor ya da `protected-mode no`. bind yalnız localhost + iç IP'ye indi"},{"k":"op","v":"cmds","l":"Tehlikeli komutlar ve CONFIG istismarı (FLUSHALL, CONFIG, DEBUG, MODULE)","m":"Ağ ve şifreleme CONFIG SET dir dbfilename authorized_keys crontab FLUSHALL FLUSHDB DEBUG MODULE LOAD enable-protected-configs enable-debug-command enable-module-command rename-command @dangerous ERR CONFIG SET failed (possibly related to argument 'dir') - can't set protected config ERR DEBUG command not allowed CONFIG SET dbfilename rename-command CONFIG kötü amaçlı modül SLAVEOF istismarı `CONFIG"},{"k":"op","v":"tls","l":"Bağlantıları şifrele: TLS (istemci, replikasyon, Sentinel, cluster bus)","m":"Ağ ve şifreleme TLS SSL tls-port tls-replication tls-cluster tls-auth-clients şifresiz bağlantı Error accepting a client connection: error:0A00010B:SSL routines::wrong version number SSL_connect certificate verify failed rediss:// Connection reset by peer tls-cert-file şifreli bağlantı encryption in transit Trafik şifresiz. TLS portu mevcut portun yanında çalışırken açılır, replikasyon ve Sentinel"},{"k":"op","v":"perms","l":"Dosya izinleri ve çalışma kullanıcısı","m":"İz ve dosyalar redis.conf izin world readable chmod dump.rdb appendonly root ile çalışıyor running as root dosya izinleri Permission denied 640 User=redis redis root redis.conf (parola içerir), ACL dosyası, RDB/AOF ve log dosyaları başka kullanıcılar tarafından okunabiliyor ya da Redis root ile çalışıyor. İzinler 640/750'ye, sahiplik servis kullanıcısına çekilir."}]},{"id":"es-cluster","file":"install/guides/es-cluster.json","group":"Elasticsearch","engineId":"elasticsearch","category":"install","title":"Elasticsearch cluster kurulumu (3+ node, TLS, Kibana)","summary":"Sıfırdan 3 ya da daha fazla node'lu bir Elasticsearch 8.x / 9.x cluster'ı kurar: Elastic repo'su, RAM'e göre heap, memory lock, vm.max_map_count, ilk node'da otomatik güvenlik (TLS + elastic parolası), diğer node'ların e","level":"Orta","duration":"60–90 dk","topology":"3+ Elasticsearch node'u (+ isteğe bağlı Kibana sunucusu)","tags":["elasticsearch","elastic","kibana","cluster","küme","kurulum","install","enrollment","tls","heap","snapshot","rhel","ubuntu"],"order":1,"steps":54,"scenarios":[]},{"id":"es-rolling-upgrade","file":"install/guides/es-rolling-upgrade.json","group":"Elasticsearch","engineId":"elasticsearch","category":"upgrade","title":"Elasticsearch rolling upgrade (8.x minor ya da 8.19 → 9.x)","summary":"Kurulum değil: çalışan bir Elasticsearch cluster'ını node'ları tek tek güncelleyerek kesintisiz yeni sürüme taşır (8.x içinde minor ya da 8.19 → 9.x ana sürüm). Ön kontroller (sürüm, sağlık, deprecation API, system featu","level":"İleri","duration":"Node başına 15–30 dk","topology":"Mevcut 3+ node'lu cluster (+ Kibana)","tags":["elasticsearch","upgrade","rolling upgrade","minor","major","9.x","8.19","kibana","upgrade assistant","deprecation","snapshot","rollback","rolling upgrade","node roles","master-eligible","deprecation api","versionlock"],"order":2,"steps":34,"scenarios":[{"k":"path","v":"minor","l":"Aynı ana sürüm içinde (ör. 8.18 → 8.19, 9.1 → 9.2)","m":"Aynı ana sürüm içinde (8.18 → 8.19, 9.1 → 9.2): repo değişmez, deprecation kontrolü yine yapılır. Ara minor'ları atlamak desteklenir."},{"k":"path","v":"major","l":"Ana sürüm: 8.19.x → 9.x","m":"Kaynak cluster önce 8.19.x'e (son patch) güncellenmiş olmalı. Ön kontroller Upgrade Assistant / deprecation API ve system feature migration adımlarını içerir."}]},{"id":"es-snapshot","file":"install/guides/es-snapshot.json","group":"Elasticsearch","engineId":"elasticsearch","category":"backup","title":"Elasticsearch snapshot ve restore (fs / S3 repository, SLM)","summary":"Kurulu bir Elasticsearch 8.x / 9.x cluster'ı için snapshot (yedek) düzenini kurar ve geri dönüşü anlatır: paylaşımlı dosya sistemi (NFS + path.repo) ya da S3 (keystore) repository'si, rolling restart ile etkinleştirme ve","level":"Orta","duration":"45–90 dk","topology":"Elasticsearch 8.x / 9.x cluster (1–N node) + paylaşımlı dizin (NFS) ya da S3 uyumlu nesne depolama","tags":["elasticsearch","snapshot","restore","yedek","backup","geri yükleme","repository","path.repo","nfs","s3","keystore","slm","snapshot lifecycle","retention","rename_pattern","feature_states","readonly repository","migration","slm","snapshot lifecycle","quartz cron","utc","netrc"],"order":15,"steps":33,"scenarios":[]},{"id":"es-ops","file":"install/guides/es-ops.json","group":"Elasticsearch","engineId":"elasticsearch","category":"ops","title":"Elasticsearch günlük işletim ve arıza senaryoları (8.x / 9.x)","summary":"Kurulum değil: kurulu bir Elasticsearch 8.x / 9.x cluster'ını günlük olarak yönetmek ve bozulduğunda kurtarmak için senaryo bazlı runbook. Sağlık ve allocation explain, atanmamış shard çözümü (disk, filtering, retry_fail","level":"İleri","duration":"5 dk (kontrol) – saatler (reindex, node boşaltma)","topology":"Elasticsearch 8.x / 9.x cluster (1–N node), TLS ve kimlik doğrulama açık","tags":["elasticsearch","elastic","cluster health","red","yellow","unassigned","allocation explain","reroute","retry_failed","allocate_stale_primary","watermark","flood stage","read_only_allow_delete","exclude","voting_config_exclusions","enrollment token","reindex","alias","ILM","rollover","shrink","split","snapshot restore","işletim","arıza"],"order":20,"steps":6,"scenarios":[{"k":"scenario","v":"health","l":"Cluster sağlığı: status, node'lar, atanmamış shard'lar, disk","m":"İzleme ve teşhis red yellow _cluster/health _cat/shards UNASSIGNED allocation explain _cluster/allocation/explain status red status yellow cluster sağlığı pending tasks master_not_discovered_exception NoNodeAvailableException circuit_breaking_exception heap cluster sağlık kontrolü Salt-okur: green/yellow/red, node listesi, atanmamış (UNASSIGNED) shard'lar ve nedeni (allocation explain), disk kulla"},{"k":"scenario","v":"unassigned","l":"Atanmamış (UNASSIGNED) shard'ı çöz (explain'e göre)","m":"İzleme ve teşhis UNASSIGNED unassigned shards NODE_LEFT ALLOCATION_FAILED max_retry shard has exceeded the maximum number of retries retry_failed no_valid_shard_copy cannot allocate because a previous copy of the primary shard existed allocate_stale_primary allocate_empty_primary the node is above the high watermark same_shard awareness filter NO_VALID_SHARD_COPY CLUSTER_RECOVERED REPLICA_ADDED ca"},{"k":"scenario","v":"watermark","l":"Disk watermark ayarını gör / değiştir","m":"Disk ve bloklar watermark disk.watermark low disk watermark high disk watermark flood stage disk watermark disk dolu disk full cluster.routing.allocation.disk cluster.routing.allocation.disk.watermark.high disk usage exceeded disk eşiği Disk doluluğu yüzünden shard'lar taşınıyor ya da atanmıyor; watermark eşikleri (low / high / flood_stage) geçici olarak ya da kalıcı olarak değiştirilecek veya var"},{"k":"scenario","v":"readonly","l":"Index salt okunur oldu: read_only_allow_delete bloğunu kaldır","m":"Disk ve bloklar read_only_allow_delete FORBIDDEN/12/index read-only / allow delete (api) TOO_MANY_REQUESTS/12/disk usage exceeded flood-stage watermark cluster_block_exception index.blocks.read_only_allow_delete flood stage salt okunur read-only blocked by: [FORBIDDEN/12/index read-only / allow delete (api)] index read-only yazma reddedildi Yazmalar 'FORBIDDEN/12/index read-only / allow delete (ap"},{"k":"scenario","v":"add_node","l":"Cluster'a node ekle (enrollment token)","m":"Node yönetimi node ekle add node enrollment token elasticsearch-create-enrollment-token elasticsearch-reconfigure-node scale out join cluster master not discovered master not discovered yet, this node has not previously joined a bootstrapped cluster kapasite artır yeni node Kapasite gerekiyor: yeni sunucuya Elasticsearch kuruldu, enrollment token ile cluster'a katılır; shard'lar kendiliğinden deng"},{"k":"scenario","v":"remove_node","l":"Node'u güvenle çıkar (exclude, boşalt, kapat)","m":"Node yönetimi node çıkar remove node decommission cluster.routing.allocation.exclude._name exclude voting_config_exclusions relocating boşalt voting configuration node emekli sunucu değişimi Bir node emekliye ayrılıyor ya da donanımı değişecek: allocation exclude ile shard'ları diğer node'lara taşınır, boşaldığı doğrulanır, master-eligible ise voting exclusion verilir, sonra kapatılır."},{"k":"scenario","v":"reindex","l":"Reindex: mapping/ayar değişikliği için yeni index ve alias ile kesintisiz geçiş","m":"Index yönetimi _reindex reindex mapping değiştir mapper_parsing_exception illegal_argument_exception: mapper alias _aliases kesintisiz geçiş zero downtime task version_conflict_engine_exception cannot be changed from type mapper [ analyzer değiştir Mapping alan türü değişecek, analyzer ya da shard sayısı değişecek: yeni index oluşturulur, veri _reindex ile kopyalanır, alias atomik olarak yeni inde"},{"k":"scenario","v":"ilm","l":"Index lifecycle (ILM) ve rollover kur / sorun gider","m":"Index yönetimi ILM index lifecycle rollover _rollover _ilm/explain is_write_index rollover_alias ilm policy index.lifecycle.name ERROR step illegal_argument_exception: index.lifecycle.rollover_alias rollover_alias does not point to index ILM ERROR index silinmiyor log index büyüyor Log/zaman serisi index'leri büyüyor ya da silinmiyor: ILM politikası (rollover + delete), index template ve ilk index"},{"k":"scenario","v":"resize","l":"Shard sayısını düzelt: _shrink (azalt) / _split (artır)","m":"Index yönetimi _shrink _split shrink split shard sayısı number_of_shards too many shards aşırı shard oversharding index.blocks.write must be read-only to resize index must have all shards allocated on the same node to shrink index number_of_routing_shards Index'in shard sayısı yanlış seçilmiş: çok küçük shard'lar (aşırı shard) _shrink ile birleştirilir, çok büyük shard'lar _split ile bölünür; alia"},{"k":"scenario","v":"snaprestore","l":"Snapshot'tan tek index'i yeni adla geri getir","m":"Index yönetimi snapshot restore _restore tek index restore rename_pattern rename_replacement index silindi deleted index index_not_found_exception cannot restore index because an open index with same name already exists snapshot_missing_exception yanlışlıkla silindi index geri getir Bir index silindi ya da bozuldu: snapshot repository'den yalnız o index, canlı index'e dokunmadan yeni adla (rename)"},{"k":"un_fix","v":"retry","l":"Deneme sınırı aşıldı: yeniden dene (_cluster/reroute?retry_failed)","m":"max_retry shard has exceeded the maximum number of retries ALLOCATION_FAILED explain: 'shard has exceeded the maximum number of retries'. Önce asıl hata (disk, mapping, bellek) giderilir."},{"k":"un_fix","v":"replicas","l":"Replica sayısı node sayısından fazla: replica'yı azalt","m":"same_shard a copy of this shard is already allocated to this node explain: same_shard (aynı node'a kopya konmaz); tek node'lu cluster'da replica 0."},{"k":"un_fix","v":"filter","l":"Allocation filtering / exclude engelliyor: filtreyi kaldır","m":"filter node does not match index setting [index.routing.allocation node matches cluster setting [cluster.routing.allocation.exclude explain: filter decider ('node does not match index setting [index.routing.allocation…]' ya da cluster exclude)."},{"k":"un_fix","v":"disk","l":"Disk watermark engelliyor","m":"disk_threshold the node is above the low watermark the node is above the high watermark explain: disk_threshold decider. Watermark senaryosuna yönlendirir."},{"k":"un_fix","v":"stale","l":"Son çare: eski (stale) kopyadan primary ata","m":"no_valid_shard_copy all the copies of its data in the cluster are stale or corrupt allocate_stale_primary Primary'nin güncel kopyası kayıp, yalnız eski bir kopya var: o kopyadaki son yazmalar kaybolur."},{"k":"un_fix","v":"empty","l":"En son çare: boş primary ata (shard'ın tüm verisi kaybolur)","m":"no_valid_shard_copy there are no copies of its data in the cluster allocate_empty_primary Hiçbir kopya yok; index snapshot'tan restore edilemiyorsa."},{"k":"wm_op","v":"show","l":"Yalnız göster (disk kullanımı ve mevcut eşikler)","m":"Salt-okur: node başına disk ve geçerli eşikler."},{"k":"wm_op","v":"set","l":"Eşikleri değiştir","m":"Eşikleri geçici olarak yükseltmek (ör. büyük diskte yüzde yerine `50gb` kalan alan). Sorun çözülünce varsayılana döndürün."},{"k":"wm_op","v":"reset","l":"Varsayılana döndür (85% / 90% / 95%)","m":"Daha önce değiştirilmiş eşikleri silip varsayılana (85% / 90% / 95%) döner."},{"k":"ilm_op","v":"setup","l":"Yeni politika + template + ilk index (write alias)","m":"Politika (rollover + silme), index template ve ilk index (`-000001`, yazma alias'ı) oluşturulur. Yeni bir log akışı için."},{"k":"ilm_op","v":"debug","l":"Mevcut index'ler neden ilerlemiyor? (explain, retry)","m":"Index'ler rollover olmuyor ya da silinmiyor: `_ilm/explain` hatalı adımı gösterir, neden giderilince retry yapılır."},{"k":"ilm_op","v":"rollover","l":"Elle rollover yap","m":"Koşul beklemeden yeni yazma index'i açılır (mapping değişikliği sonrası ya da şişmiş index için)."},{"k":"rs_kind","v":"shrink","l":"_shrink: shard sayısını azalt (hedef, mevcutun böleni olmalı)","m":""},{"k":"rs_kind","v":"split","l":"_split: shard sayısını artır (hedef, mevcutun katı olmalı)","m":""}]},{"id":"es-security","file":"install/guides/es-security.json","group":"Elasticsearch","engineId":"elasticsearch","category":"security","title":"Elasticsearch güvenlik sıkılaştırma (security, TLS, roller, audit)","summary":"Kurulum ya da günlük işletim değil: çalışan bir Elasticsearch cluster'ını sıkılaştırmak için senaryo bazlı runbook. Salt-okur güvenlik denetimi, kapalı security'yi transport TLS ile açma (tam cluster yeniden başlatma), H","level":"İleri","duration":"10 dk (denetim) – 2 saat (tam sıkılaştırma)","topology":"1–12 node'lu Elasticsearch cluster (+ Kibana)","tags":["elasticsearch güvenlik","elasticsearch security","hardening","sıkılaştırma","xpack.security","TLS","elasticsearch-certutil","elasticsearch-users","API key","role mapping","elastic superuser","anonymous","audit logging","IP filtering","kibana_system","service account token","CIS"],"order":20,"steps":4,"scenarios":[{"k":"op","v":"audit","l":"Güvenlik durumu denetimi (salt-okur)","m":"Denetim elasticsearch güvenlik denetimi elasticsearch security audit CIS Elasticsearch hardening sıkılaştırma açık elasticsearch exposed elasticsearch xpack.security.enabled missing authentication credentials for REST request security_exception elasticsearch güvenlik kontrolü elasticsearch pentest RİSK Hiçbir şey değiştirmez. Security açık mı, kimliksiz erişim, HTTP/transport TLS, anonymous erişim"},{"k":"op","v":"all","l":"Tam sıkılaştırma (hepsi sırayla)","m":"Denetim tam sıkılaştırma full hardening elastic güvenlik projesi pentest bulgusu Denetim → security + transport/HTTP TLS (kapalıysa; tam cluster yeniden başlatma) → kullanıcılar/roller/API key, anonymous kapatma, elastic'i günlük işten çıkarma → ağ ve IP filtreleme → audit logging (lisans izin veriyorsa) → snapshot repo erişimi → Kibana bağlantısı → son denetim."},{"k":"op","v":"enable","l":"Security kapalı: güvenliği ve transport TLS'i aç","m":"Kimlik ve şifreleme xpack.security.enabled: false security disabled kimliksiz erişim Elasticsearch built-in security features are not enabled Transport SSL must be enabled if security is enabled invalid configuration for xpack.security.transport.ssl 7.x yükseltme güvenlik Security is disabled xpack.security.transport.ssl kimlik doğrulama yok `xpack.security.enabled: false` ya da 7.x'ten yükseltilm"},{"k":"op","v":"httptls","l":"HTTP (REST) trafiğini TLS'e geçir","m":"Kimlik ve şifreleme http.ssl xpack.security.http.ssl.enabled received plaintext http traffic on an https channel plaintext http https 9200 elasticsearch-certutil http SSLHandshakeException curl: (52) Empty reply from server http:// 9200 parola ağda açık Security açık ama 9200 portu düz HTTP: parolalar ağda okunabilir. HTTP sertifikaları dağıtılıp node'lar tek tek yeniden başlatılır; istemciler `ht"},{"k":"op","v":"users","l":"Kullanıcılar, roller, API key; elastic ve anonymous erişim","m":"Kimlik ve şifreleme elastic kullanıcı elastic superuser superuser role mapping API key api_key elasticsearch-users anonymous xpack.security.authc.anonymous action [indices:data/write/bulk[s]] is unauthorized is unauthorized for user unable to authenticate user action [indices:data/read/search] is unauthorized for user api key süresi süresiz api key break-glass Uygulamalar `elastic` süper kullanıcı"},{"k":"op","v":"auditlog","l":"Audit logging'i aç","m":"İz ve erişim audit log xpack.security.audit.enabled audit logging _audit.json denetim kaydı kim sildi KVKK PCI DSS xpack.security.audit.logfile.events.include erişim kaydı Kim hangi index'e erişti, başarısız oturum denemeleri, yetki reddi ve güvenlik ayarı değişiklikleri kayıt altına alınmalı. `xpack.security.audit.enabled` (statik, rolling yeniden başlatma) — lisans gerektirir (adım lisansı kontr"},{"k":"op","v":"net","l":"Ağ erişimi ve IP filtreleme","m":"İz ve erişim network.host 0.0.0.0 0.0.0.0:9200 port 9200 açık xpack.security.transport.filter xpack.security.http.filter ip filtering shodan firewall 0.0.0.0:9300 network.host: 0.0.0.0 _site_ genel IP 9200/9300 tüm arayüzlerde ya da herkese açık. `network.host` iç IP'ye indirilir, firewall ve Elasticsearch IP filtreleme ile yalnız node'lar, Kibana ve uygulama ağı izinli olur."},{"k":"op","v":"snapshot","l":"Snapshot repo erişimini güvenceye al","m":"İz ve erişim snapshot repo path.repo repository_exception s3.client access_key readonly repository snapshot güvenliği snapshot_operator Object Lock yedek güvenliği Snapshot dizini herkesçe okunabiliyor, repo'yu yönetme yetkisi geniş ya da bulut erişim anahtarları elasticsearch.yml'de. Dizin izinleri, snapshot operatör rolü, keystore ve ikinci cluster'da salt-okur repo kaydı."},{"k":"op","v":"kibana","l":"Kibana bağlantısını güvenceye al","m":"İz ve erişim kibana_system elasticsearch.username: elastic kibana.yml parola service account token elasticsearch.serviceAccountToken xpack.encryptedSavedObjects.encryptionKey Kibana server is not ready yet unable to retrieve version information from Elasticsearch nodes value of \"elastic\" is forbidden serviceAccountToken kibana.keystore Kibana `elastic` kullanıcısıyla ya da şifresiz bağlanıyor, par"}]},{"id":"mon-prometheus-grafana","file":"install/guides/mon-prometheus-grafana.json","group":"İzleme","engineId":null,"category":"monitoring","title":"Prometheus + Grafana ile veritabanı izleme","summary":"Merkezi bir izleme sunucusu (Prometheus, Alertmanager, Grafana) kurar ve izlenen sunuculara node_exporter ile seçtiğiniz veritabanı exporter'larını ekler: PostgreSQL, MySQL, Oracle, SQL Server, MongoDB, Redis, Elasticsea","level":"Orta","duration":"60–120 dk","topology":"1 izleme sunucusu + izlenen sunucular","tags":["prometheus","grafana","alertmanager","node_exporter","postgres_exporter","mysqld_exporter","oracledb_exporter","sql_exporter","mongodb_exporter","redis_exporter","elasticsearch_exporter","izleme","monitoring","alert","dashboard"],"order":1,"steps":44,"scenarios":[]},{"id":"ora19-install","file":"install/guides/ora19-install.json","group":"Oracle","engineId":"oracle","category":"install","title":"Oracle Database 19c tek instance kurulumu (EE / SE2)","summary":"Tek sunucuya, Oracle Linux / RHEL 7.9, 8 ya da 9 üzerinde Oracle Database 19c'yi sıfırdan kurar: işletim sistemi hazırlığı (preinstall RPM ya da elle), OFA dizinleri, Release Update ile birlikte sessiz (silent) yazılım k","level":"Orta","duration":"90–150 dk","topology":"1 sunucu","tags":["oracle","19c","kurulum","install","runInstaller","dbca","netca","silent","release update","applyRU","opatch","cdb","pdb","hugepages","rman","oracle linux","rhel","asm","ol7","multipath","oracle restart"],"order":1,"steps":38,"scenarios":[]},{"id":"ora23-install","file":"install/guides/ora23-install.json","group":"Oracle","engineId":"oracle","category":"install","title":"Oracle AI Database 26ai / 23ai kurulumu (Linux)","summary":"Tek sunucuya Oracle AI Database 26ai'yi (23ai'nin yerini alan, sürüm numarası 23.26.x olan yayın) kurar; üç resmi yoldan birini seçersiniz: üretim için gold image ZIP ile OFA kurulumu (runInstaller -setupDBHome + dbca; d","level":"Orta","duration":"45–120 dk","topology":"1 sunucu","tags":["oracle","26ai","23ai","ai database","kurulum","install","rpm","free","gold image","setupDBHome","dbca","cdb","pdb","oracle linux","rhel","asm","oracle restart"],"order":2,"steps":30,"scenarios":[]},{"id":"ora-storage-prep","file":"install/guides/ora-storage-prep.json","group":"Oracle","engineId":"oracle","category":"install","title":"Oracle için depolama hazırlığı: multipath, kalıcı disk adları, ASM diskleri","summary":"Oracle Grid Infrastructure, Oracle Restart ya da veritabanı kurulumundan önce bir kez uygulanır: SAN LUN'ları WWID ile tanınır, gerekiyorsa DM-Multipath alias'ları kurulur ve ASM diskleri udev kuralı ya da ASMLib etiketi","level":"Orta","duration":"30–90 dk","topology":"1 sunucu ya da RAC'te 2–8 node + SAN/iSCSI/VM diskleri","tags":["oracle","asm","multipath","device-mapper-multipath","dm-multipath","multipath.conf","wwid","udev","udev kuralı","asmlib","oracleasm","afd","asm filter driver","lvm","xfs","fstab","san","lun","depolama","storage","disk","rac","oracle restart"],"order":3,"steps":10,"scenarios":[]},{"id":"ora-grid-asm","file":"install/guides/ora-grid-asm.json","group":"Oracle","engineId":"oracle","category":"install","title":"Oracle Restart: Grid Infrastructure 19c + ASM (tek sunucu)","summary":"Tek sunucuda Oracle Restart (Grid Infrastructure 19c standalone, HA_CONFIG) ve ASM kurulumu: grid kullanıcısı ve ASM grupları, kalıcı disk adları (udev, ASMLib ya da ASM Filter Driver; tek yollu ya da multipath diskler),","level":"İleri","duration":"90–150 dk","topology":"1 sunucu + paylaşımsız ASM diskleri","tags":["oracle","19c","grid infrastructure","oracle restart","asm","gridSetup","HA_CONFIG","udev","asmlib","oracleasm","afd","asm filter driver","srvctl","asmcmd","kurulum","multipath","ol7"],"order":3,"steps":30,"scenarios":[]},{"id":"ora19-patch-ru","file":"install/guides/ora19-patch-ru.json","group":"Oracle","engineId":"oracle","category":"patch","title":"Oracle Database 19c Release Update (RU) uygulaması","summary":"Tek instance ya da Oracle Restart (Grid Infrastructure + ASM) 19c veritabanına çeyreklik Release Update: OPatch güncellemesi, çakışma ve alan ön kontrolleri, ORACLE_HOME yedeği ve guaranteed restore point, opatch apply (","level":"Orta","duration":"60–120 dk (kesinti: in-place 30–60 dk, out-of-place 10–20 dk)","topology":"1 sunucu (tek instance ya da Oracle Restart); RAC için rolling patch rehberi","tags":["oracle","19c","patch","release update","ru","opatch","opatchauto","datapatch","ojvm","out-of-place","rollback","restore point","oracle restart","rac","rolling","standby-first","data guard","standby","1265700.1"],"order":10,"steps":25,"scenarios":[]},{"id":"ora19-rac","file":"install/guides/ora19-rac.json","group":"Oracle","engineId":"oracle","category":"ha","title":"Oracle RAC 19c kurulumu (Grid Infrastructure + ASM + RAC veritabanı)","summary":"İki ya da daha fazla node'a sıfırdan Oracle Grid Infrastructure 19c (Flex ASM, SCAN) ve Oracle RAC 19c veritabanı kurar: ağ ve DNS planı, paylaşımlı disk hazırlığı (udev ya da ASMLib; multipath'li ya da tek yollu), kulla","level":"İleri","duration":"4–6 saat","topology":"2–8 node + paylaşımlı disk (SAN/iSCSI) + DNS'te SCAN","tags":["oracle","rac","19c","grid infrastructure","clusterware","asm","scan","gridsetup","dbca","srvctl","crsctl","cluster","ha","udev","asmlib","multipath","ol7","scan","ocr","voting disk"],"order":10,"steps":68,"scenarios":[]},{"id":"ora-rac-patch","file":"install/guides/ora-rac-patch.json","group":"Oracle","engineId":"oracle","category":"patch","title":"Oracle RAC 19c rolling Release Update (opatchauto)","summary":"Çalışan 2–8 node'lu RAC 19c cluster'ına çeyreklik GI Release Update'i kesintisiz (rolling) uygular: OPatch güncellemesi, opatchauto analyze ile çakışma kontrolü, OCR yedeği ve geri dönüş noktası, servisleri taşıyarak nod","level":"İleri","duration":"Node başına 45–90 dk","topology":"Mevcut 2–8 node'lu RAC 19c","tags":["oracle","rac","19c","patch","release update","ru","opatchauto","opatch","datapatch","rolling","grid infrastructure","rollback","scan","service","standby-first","srvctl"],"order":11,"steps":38,"scenarios":[]},{"id":"ora-rac-ops","file":"install/guides/ora-rac-ops.json","group":"Oracle","engineId":"oracle","category":"ops","title":"Oracle RAC günlük işletim ve arıza senaryoları","summary":"Kurulu ve çalışan bir Oracle RAC (Grid Infrastructure 19c) cluster'ının günlük işletimi ve arıza müdahalesi: sağlık kontrolü, node eviction teşhisi, node'u bakıma alma, tüm cluster'ı planlı kapatıp açma, node ekleme ve ç","level":"İleri","duration":"15 dk – 3 saat (senaryoya göre)","topology":"Mevcut 2–8 node'lu RAC (Grid Infrastructure 19c; 23ai/26ai farkları notlarda)","tags":["oracle","rac","grid infrastructure","clusterware","crsctl","srvctl","olsnodes","cluvfy","addnode","node ekleme","node çıkarma","delete node","ocr","olr","voting disk","votedisk","ocrconfig","ocrcheck","scan","vip","oifcfg","interconnect","eviction","ocssd","misscount","service","relocate","application continuity","taf","fan","günlük işletim","arıza"],"order":12,"steps":10,"scenarios":[{"k":"scenario","v":"health","l":"Cluster sağlık kontrolü (günlük / bakım öncesi)","m":"Kontrol ve teşhis crsctl check cluster crsctl stat res -t cluvfy OFFLINE kaynak CRS-4535 CRS-4530 CRS-4639 health check sağlık kontrolü INTERMEDIATE CRS-4537 CRS-2765 CRS-2878 CRS-4700 CRS-4701 crsctl check crs cluster durumu cluster status kaynak kapalı resource offline orachk tfactl bakım öncesi kontrol Hiçbir şey değiştirmez: Clusterware yığını, kaynaklar, OCR/voting, ASM, interconnect, saat ve"},{"k":"scenario","v":"eviction","l":"Bir node cluster'dan atıldı ya da kendiliğinden yeniden başladı (eviction teşhisi)","m":"Kontrol ve teşhis CRS-1609 CRS-1610 CRS-1611 CRS-1612 CRS-1615 CRS-1625 CRS-1632 CRS-1656 CRS-8011 node eviction evicted node reboot split brain ocssd.trc misscount disktimeout node atıldı CRS-1601 CRS-1606 CRS-1607 CRS-1608 CRS-1613 CRS-1614 CRS-8013 ORA-29740 ORA-29770 IPC Send timeout network heartbeat disk heartbeat node yeniden başladı sunucu kendiliğinden reboot oldu rebootless restart insta"},{"k":"scenario","v":"stopnode","l":"Bir node'u bakım için durdur ve geri aç","m":"Başlat / durdur crsctl stop crs crsctl start crs node bakımı OS patch reboot CRS-4133 CRS-4123 drain_timeout srvctl stop instance CRS-2673 CRS-2677 CRS-2675 crsctl disable crs crsctl enable crs bakım modu maintenance kernel update çekirdek güncelleme firmware Bir node'da işletim sistemi patch'i, çekirdek ya da donanım bakımı yapılacaksa seçin. Diğer node'lar çalışmaya devam eder; o node'daki insta"},{"k":"scenario","v":"stopall","l":"Tüm cluster'ı planlı kapat ve aç","m":"Başlat / durdur crsctl stop cluster -all crsctl start cluster -all tam kapatma cluster shutdown planlı kesinti srvctl stop database CRS-2677 CRS-4133 CRS-4123 crsctl stop crs crsctl start crs SAN bakımı veri merkezi bakımı datacenter maintenance power off tüm sunucuları kapat SAN ya da veri merkezi bakımı gibi tüm node'ların aynı anda kapanması gereken durumlarda seçin. Tam kesinti: tüm veritabanl"},{"k":"scenario","v":"addnode","l":"Cluster'a yeni node ekle","m":"Node ekle / çıkar addnode.sh addNode gridSetup.sh -addNode node ekleme add node cluvfy stage -pre nodeadd dbca -addInstance INS-06006 PRVG- PRVF- INS-13013 INS-40912 CLSRSC-184 PRVG-11050 PRVF-4664 PRVF-7617 cvuqdisk new node yeni sunucu ekle cluster genişletme Cluster'a yeni bir sunucu katılacaksa seçin (kapasite artışı, donanım yenileme). Kesintisiz: ön kontroller (cluvfy), Grid home (addnode.sh"},{"k":"scenario","v":"delnode","l":"Cluster'dan node çıkar","m":"Node ekle / çıkar crsctl delete node deinstall -local dbca -deleteInstance node çıkarma delete node remove node cluvfy stage -post nodedel crsctl unpin css CRS-4658 CRS-4661 runInstaller -updateNodeList srvctl remove instance decommission sunucuyu cluster'dan çıkar eski sunucuyu sök Bir sunucu kalıcı olarak cluster'dan çıkarılacaksa (iade, donanım arızası) seçin. Instance silinir, DB ve Grid home "},{"k":"scenario","v":"service","l":"Servis ekle, değiştir, taşı ya da sil","m":"Servis ve ağ srvctl add service srvctl modify service srvctl relocate service srvctl remove service ORA-12514 PRCD-1026 preferred available TAF Application Continuity TAC FAN servis taşıma PRKO-2017 PRCR-1090 ORA-12514: TNS:listener does not currently know of service srvctl start service srvctl status service failback servis geri dönmedi drain_timeout servis ekleme create service Uygulamanın bağla"},{"k":"scenario","v":"net","l":"SCAN, VIP, listener portu ya da interconnect değişikliği","m":"Servis ve ağ srvctl modify scan srvctl modify scan_listener srvctl modify nodeapps srvctl modify listener oifcfg setif oifcfg delif oifcfg getif IP değişikliği SCAN IP VIP değişikliği interconnect private network ORA-12545 listener port PRCS-1034 PRKO-2310 PRCR-1079 oifcfg HAIP 169.254 port değişikliği SCAN değişikliği VIP change remote_listener ASMNET1LSNR_ASM SCAN adı/IP'leri, bir node VIP'i, li"},{"k":"scenario","v":"ocr_backup","l":"OCR ve OLR yedeği al, yedekleri kontrol et","m":"OCR, OLR ve voting ocrconfig -manualbackup ocrconfig -showbackup ocrconfig -local -manualbackup OLR yedeği OCR yedeği OCR backup ocrcheck ocrdump PROT- ocrconfig -copy ocrconfig -showbackuploc OLR backup OCR yedeği nerede elle OCR yedeği Kesinti yok: elle OCR yedeği, her node'da OLR yedeği ve yedeklerin cluster disklerinin dışına kopyalanması. Patch, node ekleme/çıkarma, ağ değişikliği gibi riskli"},{"k":"scenario","v":"ocr_restore","l":"OCR bozuk ya da CRS disk group'u kayıp: yedekten geri yükle","m":"OCR, OLR ve voting PROT-602 PROC-26 CRS-4535 CRS-4000 CRS-1606 ocrconfig -restore crsctl start crs -excl -nocrs OCR corruption OCR bozuk CRS disk group kayıp voting disk kayıp ORA-15017 ORA-15063 PROT-35 PROT-19 ORA-15018 ORA-15033 ocrdump OCR restore CRSD başlamıyor Logical corruption check failed `ocrcheck` bozulma gösteriyorsa, CRSD açılmıyorsa (PROT-/PROC- hataları) ya da CRS disk group'u tama"},{"k":"scenario","v":"olr_restore","l":"Bir node'da Clusterware açılmıyor: OLR bozuk","m":"OCR, OLR ve voting ocrcheck -local ocrconfig -local -restore OLR bozuk OLR corrupt ohasd başlamıyor CRS-4124 CRS-4639 PROCL- CRS-4123 ohasd.trc olr.loc ocrconfig -local -showbackup Local registry integrity check failed OHASD başlamıyor tek node açılmıyor Diğer node'lar çalışırken yalnız bir node'da `crsctl start crs` OHASD'yi açamıyorsa ve `ocrcheck -local` OLR hatası veriyorsa seçin. Yalnız o nod"},{"k":"scenario","v":"ocrvote_move","l":"OCR ve voting dosyalarını başka disk group'a taşı","m":"OCR, OLR ve voting crsctl replace votedisk crsctl query css votedisk ocrconfig -add ocrconfig -delete voting disk taşıma votedisk OCR taşıma storage migration ORA-15274 ocrconfig -backuploc asmcmd spmove asmcmd pwmove CRS disk group taşıma voting dosyası taşıma OCR move depolama değişimi Kesintisiz: ocrconfig -add/-delete ve crsctl replace votedisk. Depolama (SAN) değişiminde, CRS disk group'unun "}]},{"id":"ora-asm-ops","file":"install/guides/ora-asm-ops.json","group":"Oracle","engineId":"oracle","category":"ops","title":"Oracle ASM günlük işletim ve arıza senaryoları","summary":"Kurulu bir Oracle Restart ya da RAC'te ASM disk group'larının günlük işletimi ve arıza anı: kapasite kontrolü (usable_file_mb), rebalance izleme, disk ekleme/değiştirme/çıkarma, offline disk, yeni disk group, mount/dismo","level":"İleri","duration":"10 dk – birkaç saat (rebalance süresine göre)","topology":"Oracle Restart (tek sunucu) ya da 2–8 node'lu RAC, Grid Infrastructure 19c (23ai/26ai farkları notlarda)","tags":["oracle","asm","disk group","diskgroup","add disk","drop disk","replace disk","rebalance","v$asm_operation","usable_file_mb","disk_repair_time","online disk","offline disk","failgroup","compatible.asm","asmcmd","spbackup","md_backup","asm_diskstring","dsset","udev","asmlib","afd","multipath","rac","oracle restart","günlük işletim","arıza"],"order":13,"steps":4,"scenarios":[{"k":"op","v":"capacity","l":"Kapasite ve disk group sağlığı kontrolü","m":"Kontrol ve izleme usable_file_mb required_mirror_free_mb asmcmd lsdg disk group dolu ASM doluluk free_mb kapasite ORA-15041 ORA-01653 ORA-17502 ORA-15041: diskgroup space exhausted diskgroup space exhausted disk group full ASM disk group full usable_file_mb negatif negative usable_file_mb ASM yer kalmadı asmcmd du Hiçbir şey değiştirmez: disk group doldu mu, ne kadar yer kaldı (usable_file_mb'nin "},{"k":"op","v":"rebal","l":"Rebalance'ı izle, hızlandır ya da yavaşlat","m":"Kontrol ve izleme v$asm_operation gv$asm_operation rebalance REBALANCE POWER asm_power_limit asmcmd lsop est_minutes resync compact rebalance yavaş rebalance slow rebalance takıldı rebalance hung ERRS ARB0 rebalance ne zaman biter Devam eden rebalance/resync işleminin ilerlemesi ve kalan süresi (v$asm_operation, est_minutes) ve POWER değişikliği. Veritabanı açık kalır; yalnız G/Ç yükü değişir."},{"k":"op","v":"add","l":"Disk group'a yeni disk ekle","m":"Disk işlemleri ADD DISK ALTER DISKGROUP ADD DISK disk ekleme yer açma kapasite artırma ORA-15041 ORA-15031 ORA-15033 ORA-15014 ORA-15410 ORA-15032 ORA-15075 ORA-17502 add disk yeni LUN new LUN disk group büyütme extend diskgroup Disk group'ta yer azaldı ya da büyütme gerekiyor: yeni LUN'u tüm node'larda hazırla (multipath/udev/ASMLib/AFD), ADD DISK ile ekle, rebalance'ı izle. Veritabanı açık kalır"},{"k":"op","v":"replace","l":"Bir diski yenisiyle değiştir (REPLACE DISK)","m":"Disk işlemleri REPLACE DISK disk değiştirme replace disk ORA-15145 storage migration disk yenileme ORA-15221 ORA-15033 replace failed disk arızalı diski değiştir disk replacement depolama taşıma storage migration ASM Arızalı (offline) ya da yenilenecek bir diski tek işlemle yenisiyle değiştirir; yalnız o diskin verisi kopyalanır (12.1+, NORMAL/HIGH). EXTERNAL'da ekle + çıkar tek komutta yapılır. V"},{"k":"op","v":"drop","l":"Disk group'tan disk çıkar","m":"Disk işlemleri DROP DISK disk çıkarma UNDROP DISKS FORMER ORA-15041 ORA-15067 LUN iade drop disk DROPPING disk söküm remove disk from diskgroup LUN geri verme Bir LUN'u iade etmek ya da depolamadan çıkarmak için: DROP DISK ile veri kalan disklere taşınır; rebalance bitip disk FORMER olmadan disk sökülmez. Veritabanı açık kalır."},{"k":"op","v":"failed","l":"Bir disk offline ya da arızalı (NORMAL/HIGH redundancy)","m":"Disk işlemleri ONLINE DISK OFFLINE DISK disk_repair_time repair_timer mode_status OFFLINE ORA-15042 ORA-15040 ORA-15130 ORA-15063 missing disk disk offline fast mirror resync ORA-15080 ORA-15081 ORA-27061 ORA-27072 ORA-15066 WARNING: Write Failed WARNING: Read Failed remaining active paths: 0 disk offline oldu SYNCING disk okunamıyor I/O error ASM NORMAL/HIGH disk group'ta bir disk OFFLINE görünüy"},{"k":"op","v":"create","l":"Yeni disk group oluştur","m":"Disk group yönetimi CREATE DISKGROUP disk group oluşturma au_size compatible.asm compatible.rdbms failgroup ORA-15018 ORA-15221 ORA-15072 ORA-15031 ORA-15033 create diskgroup new disk group yeni disk group Yeni bir veri, FRA ya da uygulama disk group'u açmak için: redundancy, AU boyutu, compatible.asm/rdbms öznitelikleri; RAC'te tüm node'larda mount ve Clusterware kaynağı. Mevcut disk group'lar et"},{"k":"op","v":"mount","l":"Disk group'u mount ya da dismount et","m":"Disk group yönetimi srvctl start diskgroup srvctl stop diskgroup ALTER DISKGROUP MOUNT DISMOUNT ORA-15027 ORA-15017 disk group mount olmuyor v$asm_client ORA-15063 ORA-15040 ORA-15130 ORA-15032 ORA-15042 PRCR-1065 CRS-2674 MOUNT FORCE diskgroup dismounted disk group açılmıyor insufficient number of disks Disk group'u planlı olarak kapatmak (dismount) ya da açılmayan/kapalı disk group'u açmak (moun"},{"k":"op","v":"spbackup","l":"ASM spfile, parola dosyası ve metadata yedeği","m":"Yapılandırma asmcmd spbackup asmcmd spget asmcmd pwget asmcmd pwcopy md_backup md_restore ASM spfile yedeği orapwASM asmcmd spcopy GPnP profile profile.xml ASM password file backup ASM metadata backup ASM yedeği Kesinti yok: ASM spfile, parola dosyası, disk group yapısı (md_backup) ve RAC'te GPnP profili ASM dışına yedeklenir; disk group'lar kaybolsa da ASM yapılandırması geri kurulabilsin. Kurulu"},{"k":"op","v":"dstring","l":"ASM disk keşif dizgesini (asm_diskstring) değiştir","m":"Yapılandırma asm_diskstring asmcmd dsset asmcmd dsget discovery string keşif dizgesi ORA-15014 kfod ORA-15020 discovered duplicate ASM disk afd_dsset asm_diskstring change disk bulunamıyor ASM'nin diskleri aradığı yol desenini değiştirmek için (ör. multipath'e geçiş, yeni udev dizini, ASMLib/AFD): önce kfod ile dener, sonra asmcmd dsset. Mevcut tüm diskler (OCR/voting dahil) yeni dizgeyle de bulun"}]},{"id":"ora-autoupgrade","file":"install/guides/ora-autoupgrade.json","group":"Oracle","engineId":"oracle","category":"upgrade","title":"19c → Oracle AI Database 26ai (23ai) upgrade: AutoUpgrade","summary":"Ana sürüm yükseltmesi (19c → 26ai) için açılır; aynı sürüm içindeki çeyreklik RU için \"Oracle Database 19c Release Update (RU) uygulaması\" rehberi kullanılır. Oracle'ın önerdiği AutoUpgrade aracıyla: en güncel autoupgrad","level":"İleri","duration":"2–4 saat (kesinti: veritabanı boyutuna ve bileşenlere göre 30–90 dk)","topology":"1 sunucu, Oracle Restart ya da RAC (26ai home tüm node'larda)","tags":["oracle","upgrade","autoupgrade","19c","26ai","23ai","noncdb","pdb","target_cdb","restore point","restoration","timezone","compatible","rollback","rac","oracle restart","cluster_database","srvctl"],"order":20,"steps":25,"scenarios":[]},{"id":"ora-dataguard","file":"install/guides/ora-dataguard.json","group":"Oracle","engineId":"oracle","category":"ha","title":"Oracle Data Guard 19c physical standby (Broker ile; tek instance, Oracle Restart, RAC)","summary":"Çalışan bir 19c primary veritabanı için RMAN DUPLICATE … FROM ACTIVE DATABASE ile physical standby kurar ve Data Guard Broker'a bağlar. Sonunda redo'yu gerçek zamanlı alıp uygulayan bir standby, SUCCESS durumunda bir bro","level":"İleri","duration":"2–4 saat (veri boyutuna göre)","topology":"Primary (tek instance / Oracle Restart / RAC 2–8 node) + physical standby (tek instance / Oracle Restart / RAC) + isteğe bağlı observer","tags":["oracle","data guard","dataguard","standby","physical standby","dgmgrl","broker","rman duplicate","switchover","failover","fast-start failover","observer","19c","dr","rac","oracle restart","srvctl","standby redo log","apply instance"],"order":20,"steps":43,"scenarios":[]},{"id":"ora-datapump","file":"install/guides/ora-datapump.json","group":"Oracle","engineId":"oracle","category":"backup","title":"Oracle Data Pump: export / import, taşıma, şema yenileme ve transportable","summary":"expdp/impdp ile tablo, şema, tablespace ya da full kapsamda export, import, iki veritabanı arasında taşıma (dump dosyası + scp + checksum ya da NETWORK_LINK) ve dump'tan DDL çıkarma (SQLFILE). Directory, kullanıcı ve par","level":"Orta","duration":"30–90 dk (veri boyutuna göre)","topology":"1 veritabanı (tek instance, Oracle Restart ya da RAC); taşımada kaynak + hedef","tags":["oracle","data pump","datapump","expdp","impdp","export","import","dump","parfile","remap_schema","network_link","sqlfile","table_exists_action","flashback_time","taşıma","migration","logical backup","mantıksal yedek","rac","scan","cluster","acfs","cron","wallet","zamanlama","refresh","şema yenileme","prod to test","drop user cascade","transportable tablespace","tts","xtts","full transportable","transportable=always","dbms_tts","transport_set_check","endian","rman convert","cross-platform","11g to 19c","non-cdb to pdb","encryption","encryption_password","compression","attach","kill_job","start_job","continue_client","orphan","dba_datapump_jobs","lob","securefile","data_options"],"order":20,"steps":16,"scenarios":[{"k":"op","v":"export","l":"Export: veritabanından dump dosyası üret","m":"Dışa / içe aktarma expdp export dump al mantıksal yedek logical backup ORA-39001 ORA-39000 ORA-39070 ORA-31633 ORA-01555 ORA-39095 ORA-39094 ORA-00439 LRM-00123 UDE-00002 ORA-39127 Tablo, şema, tablespace ya da tüm veritabanı dump dosyasına yazılır (expdp). Veritabanı açık kalır, uygulama çalışmaya devam eder. Mantıksal kopyadır: RMAN yedeğinin yerini tutmaz (zamana dönüş ve tam geri dönüş için RM"},{"k":"op","v":"import","l":"Import: dump dosyasını veritabanına al","m":"Dışa / içe aktarma impdp import dump yükle REMAP_SCHEMA REMAP_TABLESPACE TABLE_EXISTS_ACTION ORA-39002 ORA-39087 ORA-39142 ORA-39143 ORA-39083 ORA-12899 ORA-39171 ORA-39082 ORA-31684 ORA-31640 ORA-39059 ORA-01917 ORA-39151 ORA-39111 ORA-01653 ORA-30036 Daha önce alınmış dump dosyası impdp ile yüklenir; şema/tablespace/tablo adı değiştirilebilir. Hedef açık kalır; yüklenen nesneleri kullanan uygula"},{"k":"op","v":"move","l":"Taşıma: kaynak veritabanından hedefe aktar","m":"Taşıma ve yenileme taşıma migration NETWORK_LINK database link scp checksum ORA-31679 ORA-02085 ORA-39183 Export → dosya kopyalama → import ya da NETWORK_LINK ile dump dosyası olmadan doğrudan. Hedefte şema henüz yoksa (ilk yükleme) bu kartı seçin; hedefte aynı şema zaten varsa ve üretimdekiyle değiştirilecekse \"Şema yenileme\" kartı. Kaynak açık kalır."},{"k":"op","v":"sqlfile","l":"Dump dosyasından yalnız DDL çıkar (SQLFILE)","m":"Dışa / içe aktarma SQLFILE DDL çıkar dump içeriği dump'ta ne var metadata DBMS_METADATA Hiçbir şey yüklenmez; nesnelerin CREATE komutları bir .sql dosyasına yazılır. Veritabanında değişiklik olmaz."},{"k":"op","v":"refresh","l":"Üretimden teste şema yenileme (refresh)","m":"Taşıma ve yenileme refresh şema yenileme testi yenile prod to test üretimden teste UAT yenileme DROP USER CASCADE ORA-01940 ORA-02380 ORA-01917 ORA-31684 ORA-00031 TABLE_EXISTS_ACTION=REPLACE Test/UAT'de zaten var olan şema, üretimdeki güncel hâliyle değiştirilir: hedef şemanın yedeği, oturumların kapatılması, DROP USER … CASCADE ya da TABLE_EXISTS_ACTION=REPLACE, parola/profil ve yetkilerin korun"},{"k":"op","v":"tts","l":"Tablespace'i datafile kopyalayarak taşı (transportable tablespace)","m":"Transportable (datafile kopyalama) transportable tablespace TTS XTTS TRANSPORT_TABLESPACES TRANSPORT_DATAFILES DBMS_TTS TRANSPORT_SET_CHECK endian cross-platform RMAN CONVERT ORA-29335 ORA-29341 ORA-29342 ORA-29345 ORA-29349 ORA-19722 ORA-01647 Büyük tablespace'ler (yüzlerce GB ve üstü) satır satır değil datafile kopyalanarak taşınır; aynı ya da farklı platform/endian (RMAN CONVERT). Karakter setl"},{"k":"op","v":"fulltts","l":"Tüm veritabanını taşı: full transportable (11g/12c → 19c, non-CDB → PDB)","m":"Transportable (datafile kopyalama) full transportable TRANSPORTABLE=ALWAYS FULL=Y VERSION=12 11g to 19c 11g'den 19c'ye non-CDB to PDB PDB'ye taşıma migration upgrade by migration ORA-39123 ORA-01647 ORA-29349 ORA-39127 FULL=Y TRANSPORTABLE=ALWAYS ile kullanıcı tablespace'leri datafile olarak, geri kalan her şey (kullanıcılar, PL/SQL, yetkiler) metadata olarak yeni bir PDB'ye taşınır; 11.2.0.3+ kay"},{"k":"op","v":"jobfix","l":"Yarıda kalan / askıdaki Data Pump job'ı: izle, devam ettir, sonlandır","m":"İzleme ve arıza ATTACH START_JOB CONTINUE_CLIENT KILL_JOB STOP_JOB dba_datapump_jobs orphan master table NOT RUNNING IDLING askıda resumable ORA-39171 ORA-31626 ORA-31633 ORA-39002 ORA-31634 ORA-39097 ORA-39126 Bir expdp/impdp job'ı askıda (resumable wait), durdurulmuş ya da yarıda kalmış; ATTACH ile bağlanıp devam ettirmek, KILL_JOB ile kapatmak ya da orphan master tabloyu temizlemek istiyorsunuz"}]},{"id":"ora-dataguard-ops","file":"install/guides/ora-dataguard-ops.json","group":"Oracle","engineId":"oracle","category":"ops","title":"Oracle Data Guard günlük işletim ve arıza senaryoları (19c / 23ai)","summary":"Kurulu bir Data Guard (physical standby) yapılandırmasının günlük işletim ve arıza kurtarma runbook'u; kurulum için Data Guard kurulum rehberi kullanılır. Ne yapacağınızdan emin değilseniz 'Durum ve gecikme kontrolü' ile","level":"İleri","duration":"5 dk (kontrol) – 4 saat (yeniden kurma)","topology":"Primary (tek instance / Oracle Restart / RAC) + physical standby (tek instance / Oracle Restart / RAC) + isteğe bağlı observer","tags":["oracle","data guard","dataguard","standby","physical standby","dgmgrl","broker","switchover","failover","reinstate","archive gap","fal","recover from service","roll forward","snapshot standby","active data guard","redo apply","mrp","apply lag","transport lag","protection mode","fast-start failover","fsfo","observer","standby_file_management","standby redo log","unnamed","rman","runbook","dr","rac","19c","23ai"],"order":21,"steps":5,"scenarios":[{"k":"scenario","v":"health","l":"Durum ve gecikme kontrolü (her şey yolunda mı?)","m":"İzleme ve kontrol ORA-16809 ORA-16810 ORA-16853 ORA-16855 ORA-16857 ORA-16766 ORA-16825 apply lag transport lag gecikme lag SHOW CONFIGURATION WARNING Data Guard durumu ORA-16854 ORA-16856 ORA-16191 ORA-16198 ORA-03135 ORA-16714 ORA-16792 ORA-16047 standby geride mi transport lag yüksek Data Guard sağlık kontrolü health check Salt-okur: yapılandırma, transport/apply lag, arşiv boşluğu, süreçler ve"},{"k":"scenario","v":"switchover","l":"Planlı switchover (rolleri değiştir)","m":"Rol değişimi switchover rol değişimi role transition DR tatbikatı ORA-16475 ORA-16470 ORA-16467 Ready for Switchover ORA-16541 ORA-16516 switchover_status TO STANDBY SESSIONS ACTIVE switchback rolleri geri al planlı bakım site değişimi Primary ve standby sağlıklı, rolleri planlı olarak değiştirmek istiyorsunuz (bakım, DR tatbikatı, rolleri geri alma); veri kaybı olmaz, uygulama birkaç dakika kesil"},{"k":"scenario","v":"failover","l":"Primary kayıp: standby'a failover","m":"Arıza ve kurtarma failover primary çöktü primary down site kaybı disaster ORA-16472 ORA-01034 ORA-12541 FAILOVER TO ACTIVATE PHYSICAL STANDBY ORA-12514 ORA-12170 ORA-03113 ORA-16625 ORA-16778 primary erişilemiyor veri merkezi kaybı FAILOVER TO IMMEDIATE acil durum Primary'ye erişilemiyor ve geri gelmeyecek (sunucu, depolama, site kaybı); standby primary olur. Geri alınamaz: MaxPerformance'ta son s"},{"k":"scenario","v":"reinstate","l":"Failover sonrası eski primary'yi standby olarak geri al (reinstate)","m":"Arıza ve kurtarma reinstate ORA-16661 ORA-16795 ORA-38729 ORA-16653 needs to be reinstated eski primary flashback ORA-16649 split-brain eski primary açılmıyor FastStartFailoverAutoReinstate REINSTATE DATABASE standby_became_primary_scn Failover yapıldı, eski primary sunucusu geri geldi; Flashback Database açıksa yeniden kurmadan yeni primary'nin standby'ı yapılır. Yeni primary açık kalır. Flashbac"},{"k":"scenario","v":"gap","l":"Arşiv boşluğu (gap): standby eksik arşiv log bekliyor","m":"Arıza ve kurtarma archive gap arşiv boşluğu v$archive_gap FAL Fetching gap ORA-00308 ORA-16401 ORA-27037 ORA-16055 gap sequence waiting for log WAIT_FOR_GAP FAL[client] Media Recovery Waiting for thread eksik arşiv missing archive log ORA-16089 `v$archive_gap` satır dönüyor ya da alert log'da FAL/gap mesajı var; apply bir sequence'ta takıldı. Veritabanları açık kalır. Eksik arşivler hiçbir yerde y"},{"k":"scenario","v":"rollfwd","l":"Standby çok geride ya da arşivler yok: ileri sar (RECOVER FROM SERVICE)","m":"Arıza ve kurtarma roll forward ileri sar RECOVER STANDBY DATABASE FROM SERVICE nologging ORA-01578 ORA-26040 standby geride resync yeniden eşitle ORA-10567 BACKUP INCREMENTAL FROM SCN standby günlerce geride NONLOGGED BLOCK incremental roll forward Gap'teki arşivler hiçbir yerde yok, NOLOGGING işlemler standby'ı bozdu ya da standby günlerce geride; standby yeniden kurulmadan primary'den artımlı ol"},{"k":"scenario","v":"rebuild","l":"Standby'ı sıfırdan yeniden kur","m":"Arıza ve kurtarma rebuild yeniden kur re-create standby ORA-16795 DUPLICATE standby kayıp controlfile kayıp ORA-00205 ORA-01157 standby dosyaları silindi DROP DATABASE standby disk kaybı Reinstate (flashback yok) ve ileri sarma mümkün değil ya da standby'ın dosyaları/kontrol dosyası kayıp; standby silinip yeniden DUPLICATE edilir. Primary açık kalır ama kurulum bitene kadar korumasızdır (başka sta"},{"k":"scenario","v":"snapshot","l":"Snapshot standby'a çevir / geri al (test için yazılabilir kopya)","m":"Test ve okuma snapshot standby CONVERT TO SNAPSHOT STANDBY test ortamı read write standby ORA-16000 ORA-38784 ORA-16433 CONVERT TO PHYSICAL STANDBY SNAPSHOT STANDBY guaranteed restore point test için standby aç Standby'ı geçici olarak okuma-yazma açıp test yapmak, sonra değişiklikleri atıp physical standby'a dönmek istiyorsunuz; primary etkilenmez, redo alınmaya devam eder ama snapshot süresince b"},{"k":"scenario","v":"apply","l":"Redo Apply'ı durdur / başlat, apply instance değiştir, read-only aç","m":"Günlük işletim MRP redo apply APPLY-OFF APPLY-ON apply instance read only Active Data Guard ORA-16766 ORA-16136 ORA-01153 real-time query WAIT_FOR_LOG APPLYING_LOG READ ONLY WITH APPLY OPEN READ ONLY PreferredApplyInstance intended state apply durdu MRP çalışmıyor MRP'yi bakım için durdurmak ya da yeniden başlatmak, RAC standby'da apply'ı başka instance'a almak veya standby'ı rapor için açmak isti"},{"k":"scenario","v":"prot","l":"Koruma modu, Fast-Start Failover ve observer","m":"Günlük işletim protection mode MaxAvailability MaxPerformance MaxProtection SYNC ASYNC FSFO fast-start failover observer ORA-16627 ORA-16651 ORA-16820 ORA-16819 ORA-16072 ORA-16647 NetTimeout LogXptMode FASTSYNC protection_level koruma modu MaxPerformance / MaxAvailability / MaxProtection arasında geçmek, FSFO'yu açıp kapatmak ya da observer'ı yönetmek istiyorsunuz."},{"k":"scenario","v":"files","l":"Datafile, redo log ve standby redo log ekleme / UNNAMED dosya","m":"Günlük işletim standby_file_management UNNAMED ORA-01111 ORA-01110 ORA-01157 ORA-01274 datafile ekle add datafile redo log ekle standby redo log SRL ORA-16789 db_file_name_convert ADD STANDBY LOGFILE ORA-01136 datafile eklendi standby Primary'ye datafile ya da redo log eklenecek, standby'da UNNAMED dosya oluştu (ORA-01111/ORA-01274) ya da standby redo log eksik."},{"k":"scenario","v":"backup","l":"Standby'dan RMAN yedeği al","m":"Günlük işletim rman standby backup standby'dan yedek archivelog deletion policy RMAN-08137 recovery catalog offload backup RMAN-06820 BACKED UP 1 TIMES CONFIGURE DB_UNIQUE_NAME standby yedek Yedek yükünü primary'den almak için RMAN yedeğini standby'da çalıştırmak ve arşiv silme politikasını buna göre ayarlamak istiyorsunuz."}]},{"id":"ora-backup-strategy","file":"install/guides/ora-backup-strategy.json","group":"Oracle","engineId":"oracle","category":"backup","title":"Oracle yedekleme stratejisi ve otomasyon (RMAN + Data Pump)","summary":"Kurulu bir veritabanı için kalıcı, otomatik yedekleme düzeni kurar (arıza anındaki geri dönüş ayrı rehberdedir: \"RMAN ile restore ve recovery\"): haftalık level 0 + günlük level 1 (ya da her gün full), sık arşiv log yedeğ","level":"Orta","duration":"60–120 dk (ilk level 0 süresi hariç)","topology":"1 sunucu (tek instance ya da Oracle Restart) veya RAC (2–8 node)","tags":["oracle","rman","yedek","backup","strateji","level 0","level 1","incremental","archivelog","fra","retention","block change tracking","data pump","expdp","crontab","cron","systemd timer","dbms_scheduler","otomasyon","wallet","mkstore","rac","oracle restart","snapshot controlfile","asm","/etc/cron.d","ol7","recovery catalog","create catalog","register database","restore tatbikatı","restore drill","restore validate","preview"],"order":21,"steps":33,"scenarios":[]},{"id":"ora-rman-restore","file":"install/guides/ora-rman-restore.json","group":"Oracle","engineId":"oracle","category":"backup","title":"RMAN ile restore ve recovery","summary":"Arıza anında doğru RMAN geri dönüşünü adım adım yaptırır: 19 senaryo — datafile, SYSTEM/UNDO, tempfile, bozuk blok, online redo log, controlfile ve spfile kaybı; tam restore, başka dizine/ASM'e ve başka sunucuya restore;","level":"İleri","duration":"30 dk – birkaç saat (veritabanı boyutuna bağlı)","topology":"1 sunucu (tek instance ya da Oracle Restart) veya RAC; yeni host senaryosunda kaynak + hedef","tags":["oracle","rman","restore","recovery","geri dönüş","pitr","point in time","resetlogs","recover table","controlfile","spfile","autobackup","datafile","preview","validate","dbid","yeni sunucu","disaster recovery","rac","oracle restart","cluster_database","srvctl","asm","block corruption","bozuk blok","ORA-01578","redo log","ORA-00313","clear logfile","tempfile","tspitr","flashback database","restore point","dropped pdb","unplug","from service","data guard","restore archivelog","catalog start with","set newname","undo","system tablespace"],"order":22,"steps":10,"scenarios":[{"k":"scenario","v":"preview","l":"Prova: RESTORE … PREVIEW / VALIDATE (hiçbir şey değiştirmez)","m":"Prova ve yedek kayıtları RESTORE PREVIEW RESTORE VALIDATE restore provası restore testi yedek çalışıyor mu backup test restore drill tatbikat RMAN VALIDATE yedek sağlam mı Bir şey bozulmadı; yedeklerin gerçekten geri dönüşe yettiğini veri yazmadan görmek istiyorsunuz (veritabanı açık kalır). Aylık restore tatbikatı ve hangi senaryoyu seçeceğinizden emin olmadığınız durum için de ilk adımdır."},{"k":"scenario","v":"catalog","l":"Yedekler başka dizine taşındı / RMAN yedeği bulamıyor (CATALOG)","m":"Prova ve yedek kayıtları CATALOG START WITH RMAN-06023 RMAN-06025 RMAN-06026 ORA-19505 ORA-27037 EXPIRED yedek taşındı backup moved no backup found CROSSCHECK NFS değişti yedek bulunamıyor Yedek parçaları vardır ama RMAN bilmiyor (taşındı, NFS değişti, başka sunucudan geldi): RMAN-06023/06025 alıyorsunuz. Veritabanı açık kalır."},{"k":"scenario","v":"arch","l":"Yalnız arşiv log'ları geri yükle (RESTORE ARCHIVELOG)","m":"Prova ve yedek kayıtları RESTORE ARCHIVELOG ORA-00308 arşiv log geri yükle archive log restore archive gap LogMiner SET ARCHIVELOG DESTINATION LogMiner, standby boşluğu ya da elle recovery için belirli sequence aralığındaki arşivler diske lazım; veritabanı açık kalır, hiçbir dosyanın üzerine yazılmaz."},{"k":"scenario","v":"datafile","l":"Tek datafile ya da tablespace kaybı/bozulması (veritabanı açık kalır)","m":"Kayıp / bozulma ORA-01157 ORA-01110 ORA-01116 ORA-27041 ORA-00376 ORA-01113 datafile kayıp datafile silindi missing datafile lost datafile tablespace kayıp ORA-27037 ORA-01135 ORA-01115 ORA-01114 datafile bozuk Veritabanı açık, yalnız bir datafile ya da tablespace okunamıyor (ORA-01157/01110/01116); diğer her şey çalışıyor. Dosya SYSTEM/UNDO'ya aitse \"SYSTEM ya da UNDO\", tempfile ise \"Tempfile\", d"},{"k":"scenario","v":"block","l":"Bozuk blok var (ORA-01578, block media recovery)","m":"Kayıp / bozulma ORA-01578 ORA-26040 ORA-01110 bozuk blok block corruption corrupt block v$database_block_corruption RECOVER CORRUPTION LIST block media recovery nologging ORA-19566 Marked Corrupt Corrupt block relative dba DBVERIFY Bir sorgu ORA-01578/ORA-26040 veriyor, yedek ORA-19566 ile duruyor ya da VALIDATE bozuk blok buldu; dosyanın geri kalanı sağlam. Veritabanı açık kalır, yalnız bozuk blo"},{"k":"scenario","v":"sysdf","l":"SYSTEM ya da UNDO datafile kayıp (veritabanı açılmıyor)","m":"Kayıp / bozulma ORA-01157 ORA-01110 ORA-01116 ORA-01147 ORA-00376 ORA-01541 SYSTEM datafile UNDO datafile undo tablespace kayıp system tablespace lost veritabanı açılmıyor ORA-01113 system01.dbf undotbs Kayıp ya da bozuk dosya SYSTEM veya UNDO tablespace'ine ait: offline alınamaz, veritabanı (PDB dosyasıysa yalnız o PDB) kapanır ve MOUNT'ta geri yüklenir. Veri kaybı olmaz. Başka bir tablespace'in "},{"k":"scenario","v":"temp","l":"Tempfile kayıp ya da bozuk (TEMP tablespace)","m":"Kayıp / bozulma ORA-01157 ORA-01187 ORA-25153 ORA-01116 ORA-01122 ORA-01110 tempfile temp tablespace geçici tablespace TEMP kayıp temp01.dbf dba_temp_files Sıralama/hash işlemleri ORA-01157/ORA-01187/ORA-25153 veriyor ve dosya bir tempfile (hata mesajındaki numara `db_files` değerinden büyüktür, ör. `data file 201`). Restore gerekmez; yeni tempfile eklenir, veritabanı açık kalır."},{"k":"scenario","v":"redo","l":"Online redo log kayıp ya da bozuk","m":"Kayıp / bozulma ORA-00313 ORA-00312 ORA-00327 ORA-00366 ORA-00367 ORA-00353 ORA-00354 ORA-00316 ORA-01624 redo log kayıp online redo lost redo log CLEAR LOGFILE ORA-00314 ORA-00320 ORA-00321 ORA-00340 ORA-00350 ORA-00470 CLEAR UNARCHIVED Alert log'da ORA-00313/00312 (açılamıyor) ya da ORA-00327/00366/00367 (bozuk). Bir üye kayıpsa ya da grup INACTIVE ise veritabanı açık kalır; CURRENT grup kayıpsa"},{"k":"scenario","v":"controlfile","l":"Tüm controlfile kopyaları kayıp","m":"Kayıp / bozulma ORA-00205 ORA-00202 ORA-00210 ORA-27037 controlfile kayıp control file lost RESTORE CONTROLFILE autobackup ORA-00206 ORA-00214 ORA-00221 ORA-00227 controlfile bozuk Instance MOUNT aşamasında controlfile bulunamıyor ya da okunamıyor (ORA-00205/00202/00210); datafile ve redo sağlam. Kopyalardan biri sağlamsa restore gerekmez (teşhis adımı gösterir); hepsi kayıpsa autobackup'tan geri "},{"k":"scenario","v":"spfile","l":"spfile kayıp","m":"Kayıp / bozulma ORA-01078 LRM-00109 ORA-01565 spfile kayıp spfile lost parameter file RESTORE SPFILE CRS-5017 PRCR-1079 spfile silindi spfile silindi ya da bozuldu; instance açılmıyor (ORA-01078/LRM-00109) ya da açık ama dosya yok. Datafile'lara dokunulmaz, veri kaybı olmaz; instance hâlâ açıksa kesinti de olmaz."},{"k":"scenario","v":"full","l":"Tam restore, aynı sunucu (datafile'lar kayıp; controlfile ve redo sağlam)","m":"Kayıp / bozulma tüm datafile'lar kayıp all datafiles lost full restore RESTORE DATABASE disk arızası storage failure disk gitti LUN kayıp datafile'lar silindi Datafile'ların hepsi ya da çoğu gitti, controlfile ve online redo log sağlam; veritabanı kapanır, veri kaybı olmaz. Dosyaların eski diski/dizini artık kullanılamıyorsa \"başka dizine\" kartını, controlfile da kayıpsa önce \"controlfile\" kartını"},{"k":"scenario","v":"relocate","l":"Disk gitti: veritabanını başka dizine / ASM'e geri yükle (SET NEWNAME)","m":"Kayıp / bozulma SET NEWNAME SWITCH DATAFILE ALL başka dizine restore ASM'e restore new location disk değişti mount point kayıp relocate ORA-15001 ORA-15040 disk group dismounted Datafile'ların durduğu disk ya da disk grubu kullanılamaz; controlfile ve redo sağlam. Dosyalar yeni dizine ya da ASM disk grubuna geri yüklenir, veritabanı kapanır, veri kaybı olmaz."},{"k":"scenario","v":"pitr","l":"Zamana / SCN'e dönüş (PITR, RESETLOGS)","m":"Zamana dönüş ve geri alma PITR point in time recovery zamana dönüş SCN'e dönüş yanlış DELETE yanlış UPDATE TRUNCATE mantıksal hata logical error UNTIL TIME veri silindi DROP USER UNTIL SCN RESETLOGS Yanlış DELETE/UPDATE/TRUNCATE ya da hatalı uygulama sürümü: veritabanını (ya da yalnız PDB'yi) geçmiş bir ana götürür; o andan sonraki tüm değişiklikler kaybolur (RESETLOGS). Önce daha dar yollara bakı"},{"k":"scenario","v":"flashback","l":"Flashback Database ile geri sar (restore point / SCN / zaman)","m":"Zamana dönüş ve geri alma FLASHBACK DATABASE FLASHBACK PLUGGABLE DATABASE restore point guaranteed restore point geri sar upgrade geri dönüş test sonrası geri dön FLASHBACK_ON FLASHBACK TO RESTORE POINT Flashback açık ya da guaranteed restore point var ve hiçbir dosya kayıp değil: restore etmeden dakikalar içinde geri sarılır (Enterprise Edition). RESETLOGS gerekir. Açık mı: `SELECT flashback_on F"},{"k":"scenario","v":"tspitr","l":"Bir tablespace'i geçmiş bir ana döndür (TSPITR)","m":"Zamana dönüş ve geri alma TSPITR tablespace point in time RECOVER TABLESPACE AUXILIARY DESTINATION DBMS_TTS tablespace'i geri al ORA-29308 Hatalı işlem yalnız bir tablespace'teki nesneleri etkiledi; veritabanının geri kalanı bugünde kalmalı (Enterprise Edition). Tablespace işlem boyunca offline olur ve içindeki tüm nesneler hedef ana döner; yalnız bir-iki tablo etkilendiyse \"Tek tabloyu geri al\" d"},{"k":"scenario","v":"table","l":"Tek tabloyu geri al (RECOVER TABLE, 12c+ Enterprise Edition)","m":"Zamana dönüş ve geri alma RECOVER TABLE tablo silindi DROP TABLE tablo geri al table recovery ORA-00942 REMAP TABLE ORA-38305 FLASHBACK TABLE recyclebin PURGE Tek bir tablo yanlışlıkla silindi ya da bozuldu; veritabanının geri kalanı olduğu gibi kalmalı (12c+ Enterprise Edition). DROP edildiyse ve PURGE yapılmadıysa önce recyclebin'e bakın: `FLASHBACK TABLE … TO BEFORE DROP` saniyeler sürer (teşhi"},{"k":"scenario","v":"pdbdrop","l":"Silinmiş PDB'yi geri getir (DROP PLUGGABLE DATABASE)","m":"Zamana dönüş ve geri alma DROP PLUGGABLE DATABASE PDB silindi dropped PDB RMAN-06813 ORA-65011 ORA-65179 KEEP DATAFILES PDB geri getir unplug DBMS_PDB.RECOVER Bir PDB `DROP PLUGGABLE DATABASE` ile silindi. Dosyalar duruyorsa XML ile yeniden takılır; silindiyse yedekten getirilir (21c+ tek komut, 19c geçici CDB üzerinden). CDB açık kalır."},{"k":"scenario","v":"newhost","l":"Başka sunucuya restore (yeni host, controlfile autobackup'tan)","m":"Başka sunucu ve standby yeni sunucu başka sunucu sunucu kaybı disaster recovery DR new host klon clone test ortamı sunucu yandı server lost restore to another host Sunucu tamamen gitti ya da kopya/test ortamı kurulacak: yedek başka bir sunucuya geri yüklenir (yalnız tek instance, dosya sistemi). Yedeklenmiş son arşive kadar dönülür, sonrası kaybolur; kopya RESETLOGS ile açılır."},{"k":"scenario","v":"fromsvc","l":"Data Guard: dosyayı standby/primary'den ağ üzerinden al (FROM SERVICE)","m":"Başka sunucu ve standby RESTORE FROM SERVICE FROM SERVICE RECOVER STANDBY DATABASE standby'dan restore Data Guard standby geride archive gap standby controlfile ORA-01110 v$archive_gap apply lag Data Guard var: primary'deki kayıp datafile'ı standby'dan, geride kalmış standby'ı ya da kayıp standby controlfile'ını primary'den yedek parçası kullanmadan alırsınız (12c+)."}]},{"id":"ora-goldengate","file":"install/guides/ora-goldengate.json","group":"Oracle","engineId":"oracle","category":"ha","title":"Oracle GoldenGate Microservices: Oracle → Oracle tek yönlü replikasyon","summary":"GoldenGate 21c ya da 23ai/26ai Microservices ile bir PDB şemasını başka bir veritabanına sürekli (saniyeler gecikmeyle) replike eder. Sonunda kaynakta Integrated Extract ve Distribution Path, hedefte Parallel Replicat ça","level":"İleri","duration":"3–5 saat","topology":"Kaynak DB sunucusu (OGG kaynak deployment) + hedef DB sunucusu (OGG hedef deployment); RAC'te GoldenGate 1. node'da (ya da XAG ile cluster kaynağı olarak)","tags":["oracle","goldengate","ogg","microservices","replikasyon","replication","cdc","integrated extract","parallel replicat","distribution path","adminclient","oggca","21c","23ai","26ai","rac","scan","xag","acfs","tranlogoptions"],"order":30,"steps":42,"scenarios":[]},{"id":"ora-goldengate-ops","file":"install/guides/ora-goldengate-ops.json","group":"Oracle","engineId":"oracle","category":"ops","title":"Oracle GoldenGate günlük işletim ve arıza senaryoları (Microservices 21c / 23ai)","summary":"Kurulu bir GoldenGate Microservices replikasyonunun günlük işletim ve arıza kurtarma runbook'u (kurulum için GoldenGate kurulum rehberi). Ne yapacağınızdan emin değilseniz 'Sağlık ve gecikme kontrolü' ile başlayın: salt-","level":"İleri","duration":"5 dk (kontrol) – 2 saat (yükseltme, tablo ekleme)","topology":"Kaynak sunucu (kaynak deployment, Integrated Extract, Distribution Path) + hedef sunucu (hedef deployment, Parallel Replicat)","tags":["oracle","goldengate","ogg","microservices","adminclient","runbook","abend","extract","replicat","lag","stats","info all","heartbeat","report","discard","reperror","handlecollisions","cdr","conflict","add trandata","schematrandata","aftercsn","atcsn","mapexclude","tableexclude","resync","purge trail","purgeoldextracts","trail","alter extract scn","etrollover","upgrade","patch","opatch","oggHome","data guard","switchover","failover","handledlfailover","OGG-00664","OGG-01004","OGG-01296","OGG-02912","21c","23ai","26ai"],"order":31,"steps":8,"scenarios":[{"k":"scenario","v":"health","l":"Sağlık ve gecikme kontrolü (her şey yolunda mı?)","m":"İzleme ve kontrol INFO ALL lag gecikme STATS heartbeat GG_LAG Service Manager ggserr.log OGG-01027 OGG-01738 Long Running Transaction STOPPED RUNNING Distribution Path DISTPATH Receiver INFO DISTPATH replikasyon gecikiyor replication lag Salt-okur: Service Manager ve microservice'ler, INFO ALL, lag, STATS, heartbeat gecikmesi, veritabanındaki capture durumu ve ggserr.log; hiçbir şey değişmez. Ne y"},{"k":"scenario","v":"ext_abend","l":"Extract ABENDED (durdu, hata verdi)","m":"Arıza (ABEND) Extract ABENDED ABEND OGG-00664 OGG-00446 OGG-02171 OGG-02912 OGG-02022 OGG-02091 OGG-01044 OGG-01668 ORA-01291 ORA-01017 ORA-28001 ORA-04031 ORA-01031 missing log archived log not found logmining OGG-00868 Extract STARTING Extract durdu capture ABORTED Kaynaktaki Extract ABENDED ya da sürekli yeniden başlıyor: report dosyasındaki OGG-xxxxx hatasına göre neden (bağlantı, eksik arşiv "},{"k":"scenario","v":"rep_abend","l":"Replicat ABENDED (hedefe uygulanamıyor)","m":"Arıza (ABEND) Replicat ABENDED OGG-01004 OGG-01296 OGG-01154 OGG-00869 OGG-01161 OGG-01169 OGG-01431 OGG-00199 OGG-00423 ORA-01403 ORA-00001 ORA-02291 ORA-00942 ORA-01653 no data found unique constraint discard REPERROR HANDLECOLLISIONS CDR conflict Replicat durdu ORA-01400 ORA-12899 value too large Hedefteki Replicat bir transaction'ı uygulayamadı: report ve discard dosyasından tablo, işlem ve ha"},{"k":"scenario","v":"add_table","l":"Replikasyona dolu bir tablo ekle (ilk yükleme + AFTERCSN)","m":"Tablo yönetimi tablo ekle add table ADD TRANDATA ADD SCHEMATRANDATA AFTERCSN ATCSN initial load ilk yükleme flashback_scn MAPEXCLUDE yeni tablo Var olan ve içinde veri olan bir tabloyu çalışan replikasyona kesinti olmadan ekler: ADD TRANDATA, tutarlı SCN ile expdp/impdp ve yalnız bu tablo için bu SCN'den sonrasını uygulayan ayrı bir Replicat (AFTERCSN). Diğer tablolar akmaya devam eder."},{"k":"scenario","v":"remove_table","l":"Bir tabloyu replikasyondan çıkar","m":"Tablo yönetimi tablo çıkar remove table TABLEEXCLUDE MAPEXCLUDE DELETE TRANDATA exclude Tablo artık replike edilmeyecek: Extract'ta TABLEEXCLUDE (ya da TABLE satırını kaldırma), Replicat'ta MAPEXCLUDE, gerekirse DELETE TRANDATA. Süreçler kısa süreli yeniden başlatılır."},{"k":"scenario","v":"resync","l":"Tek bir tabloyu yeniden eşitle (resync)","m":"Tablo yönetimi resync yeniden eşitle out of sync veri farkı ayrıştı Veridata OGG-01004 ORA-01403 ORA-00001 row count satır sayısı farklı Bir tablonun hedefteki verisi kaynakla ayrıştı (elle değişiklik, atlanan hata, eksik ilk yükleme): tablo kaynaktan tutarlı SCN ile yeniden yüklenir ve geçici bir Replicat bu SCN'den sonrasını uygular. Diğer tablolar etkilenmez."},{"k":"scenario","v":"purge","l":"Trail dosyaları diski dolduruyor: temizlik (Purge Trail)","m":"Bakım trail purge PURGEOLDEXTRACTS Purge Trail disk dolu No space left on device trail temizliği var/lib/data trail dizini dolu ENOSPC Trail dizini büyüyor ya da disk dolmak üzere: hangi dosyaların okunduğu görülür, Purge Trail görevi (Classic'teki PURGEOLDEXTRACTS karşılığı) USECHECKPOINTS ile tanımlanır; acil durumda okunmuş dosyalar elle silinir."},{"k":"scenario","v":"reposition","l":"Extract'ı belirli bir SCN'den yeniden konumlandır","m":"Bakım reposition ALTER EXTRACT SCN BEGIN SCN ETROLLOVER SCN'den başlat trail kaybı first_scn geri sar Extract'ın baştan almasını istediğiniz bir SCN var (trail kaybı, yanlış başlangıç, hedefte geri dönüş): ALTER EXTRACT … SCN ve ETROLLOVER ile yeni trail dosyasından başlatılır. Hedefe aynı veriler ikinci kez gelebilir."},{"k":"scenario","v":"upgrade","l":"GoldenGate sürüm yükseltme / patch (Microservices)","m":"Bakım upgrade patch yükseltme OPatch out-of-place oggHome Service Manager upgrade bundle patch 21c 23ai 26ai release update GoldenGate patch Service Manager PATCH Yeni bir GoldenGate sürümüne ya da patch'e geçiş: out-of-place (yeni home kur, Service Manager ve deployment'ları REST ile yeni home'a al) ya da in-place OPatch. Extract/Replicat kısa süre durur; geri dönüş eski home'a dönmektir."},{"k":"scenario","v":"dg_role","l":"Kaynakta Data Guard switchover/failover sonrası Extract'ı sürdür","m":"Rol değişimi Data Guard switchover failover role transition HANDLEDLFAILOVER ORA-01033 ORA-16000 ORA-01109 yeni primary standby FSFO ORA-12514 rol değişimi Extract yeni primary FAILOVERTARGETDESTID Kaynak veritabanında switchover ya da failover oldu; Extract yeni primary'ye bağlanıp checkpoint'ten devam etmeli: bağlantı (credential alias/servis), capture durumu, HANDLEDLFAILOVER ve olası veri ayrı"}]},{"id":"ora-security","file":"install/guides/ora-security.json","group":"Oracle","engineId":"oracle","category":"security","title":"Oracle Database güvenlik sıkılaştırma (denetim, ağ, TLS, kimlik, yetki, Unified Auditing, TDE)","summary":"Kurulum rehberi değildir: çalışan bir Oracle 19c / 23ai (26ai) veritabanının (tek instance, Oracle Restart ya da RAC; CDB/PDB) açıklarını bulur ve kapatır. Önce salt-okur Durum denetimi açıkları önem sırasıyla listeler v","level":"İleri","duration":"5 dk (denetim) – 4 saat (tam sıkılaştırma)","topology":"Tek instance / Oracle Restart / RAC (2–8 node), CDB + PDB; uygulama sunucusu (istemci doğrulaması)","tags":["oracle","güvenlik","security","hardening","sıkılaştırma","cis benchmark","stig","tcps","wallet","orapki","sqlnet.ora","native network encryption","TCP.VALIDNODE_CHECKING","ALLOWED_LOGON_VERSION_SERVER","profile","ORA12C_STRONG_VERIFY_FUNCTION","unified auditing","AUDSYS","DBMS_AUDIT_MGMT","TDE","keystore","ADMINISTER KEY MANAGEMENT","UTL_FILE","PUBLIC","varsayılan parola"],"order":40,"steps":2,"scenarios":[{"k":"scenario","v":"scan","l":"Durum denetimi: açıklarım neler? (salt-okur)","m":"Başlangıç güvenlik denetimi security audit hardening check CIS STIG DBSAT açık zafiyet vulnerability pentest bulgusu dba_users_with_defpwd denetim sorgusu güvenlik taraması security scan KRİTİK İlk çalıştırılacak tarama: varsayılan parolalı ve açık hesaplar, eski parola doğrulayıcıları, profil, DBA/ANY yetkileri, PUBLIC'e açık UTL_* PL/SQL package'ları, audit, TDE, şifresiz oturumlar, listener ve "},{"k":"scenario","v":"all","l":"Tam sıkılaştırma (hepsi sırayla)","m":"Başlangıç hardening sıkılaştırma tam güvenlik full hardening CIS benchmark uygula STIG Yeni kurulmuş ya da hiç sıkılaştırılmamış veritabanı: tüm alanlar güvenli sırayla uygulanır; listener ve veritabanı bir-iki kez yeniden başlatılır (bakım penceresi gerekir)."},{"k":"scenario","v":"net","l":"Ağ ve bağlantı: kim nereden bağlanabilir? (listener, TCP.VALIDNODE_CHECKING, firewall)","m":"Ağ ve kimlik TCP.VALIDNODE_CHECKING TCP.INVITED_NODES listener 1521 5500 ORA-12537 TNS-12537 ORA-12541 ADMIN_RESTRICTIONS firewall TNS-12546 ORA-12170 invited nodes listener.log dışarıdan erişim erişim kısıtlama Listener her adrese açık, invited nodes tanımlı değil, 1521/5500 herkese açık. Listener yeniden başlatılır (açık oturumlar etkilenmez)."},{"k":"scenario","v":"tls","l":"Bağlantıyı şifrele (TCPS wallet ya da native network encryption)","m":"Ağ ve kimlik TCPS SSL TLS wallet orapki SQLNET.ENCRYPTION_SERVER ORA-28860 ORA-29024 ORA-28759 ORA-29106 ORA-12696 ORA-12660 SSL_SERVER_DN_MATCH sertifika süresi ORA-29003 ORA-29002 TNS-12560 TLS sertifika zinciri certificate chain native network encryption Ağ trafiği şifresiz; TLS (TCPS, wallet, sertifika, istemcide SSL_SERVER_DN_MATCH) ya da sertifikasız native encryption (SQLNET.ENCRYPTION_SERV"},{"k":"scenario","v":"auth","l":"Kimlik doğrulama ve parola (12C doğrulayıcı, profil, varsayılan hesaplar)","m":"Ağ ve kimlik ALLOWED_LOGON_VERSION_SERVER ORA-28040 ORA-01017 ORA-28000 ORA-28001 ORA-28003 ORA-28007 password_versions 10G PROFILE ORA12C_STRONG_VERIFY_FUNCTION varsayılan parola default password SCOTT ORA-65066 ORA-00988 password_versions 10G parola profili password policy FAILED_LOGIN_ATTEMPTS 10G/11G parola doğrulayıcıları, parola profili yok, varsayılan parolalı ya da örnek hesaplar açık; kiş"},{"k":"scenario","v":"priv","l":"En az yetki: roller, PUBLIC ve uygulama hesabı","m":"Yetki ve iz PUBLIC UTL_FILE UTL_TCP UTL_HTTP UTL_SMTP DBA role RESOURCE ANY privilege least privilege en az yetki ORA-01031 ORA-00942 schema-only account PLS-00201 ORA-04021 GRANT ANY UNLIMITED TABLESPACE yetki raporu Uygulama hesabında DBA/RESOURCE/ANY yetkileri, PUBLIC'e açık UTL_FILE/UTL_TCP/UTL_HTTP; şema sahibi, okuma/yazma rolleri ve yetki raporu. Kesinti yok."},{"k":"scenario","v":"audit","l":"Audit: kim ne yaptı? (Unified Auditing, AUDSYS temizliği)","m":"Yetki ve iz unified auditing AUDIT POLICY AUDSYS DBMS_AUDIT_MGMT UNIFIED_AUDIT_TRAIL ORA_LOGON_FAILURES ORA_SECURECONFIG UNIFIED_AUDIT_SYSTEMLOG SYSAUX dolu denetim izi SIEM ORA-46267 unified audit policy kim ne yaptı who changed Denetçi giriş, hesap ve şema değişikliği kayıtlarını istiyor; unified audit politikaları, AUDSYS'in saklama süresiyle temizlenmesi ve kayıtların syslog'a/merkeze gönderil"},{"k":"scenario","v":"tde","l":"Veriyi diskte şifrele (TDE)","m":"Veri ve yedek TDE transparent data encryption keystore wallet ADMINISTER KEY MANAGEMENT WALLET_ROOT ORA-28365 ORA-28374 ORA-46665 ENCRYPT_NEW_TABLESPACES encryption at rest ORA-28367 ORA-46658 ORA-28353 Advanced Security master key TDE_CONFIGURATION Datafile, yedek ya da disk kopyasının okunmasına karşı TDE: WALLET_ROOT, keystore, master key, tablespace şifreleme (online). Advanced Security lisans"},{"k":"scenario","v":"backup","l":"Yedeklerin güvenliği (RMAN şifreleme, parolasız otomasyon, izinler)","m":"Veri ve yedek RMAN encryption CONFIGURE ENCRYPTION ORA-19913 expdp ENCRYPTION secure external password store mkstore SEPS yedek izinleri ORA-19914 Advanced Security lisansı şifresiz yedek unencrypted backup ENCRYPTION_PWD_PROMPT RMAN/Data Pump yedekleri şifresiz, betiklerde düz parola, yedek dizini herkese açık; RMAN encryption, ENCRYPTION_PWD_PROMPT, wallet (SEPS) ve dizin izinleri. RMAN ve Data "},{"k":"scenario","v":"os","l":"İşletim sistemi tarafı (oracle hesabı, dosya izinleri, core dump, SELinux)","m":"Sunucu ve sürüm SELinux orapw oracle hesabı dosya izinleri core dump ORACLE_HOME izinleri sudo avc: denied passwd -l oracle setuid 6751 limits.d oracle hesabının parolası açık, parola dosyası/network admin/wallet izinleri gevşek, SELinux kapalı. Core dump sınırı yeni oturumda/yeniden başlatmada geçerli olur."},{"k":"scenario","v":"patch","l":"Yama ve sürüm: son RU'da mıyım?","m":"Sunucu ve sürüm RU release update CPU Critical Patch Update opatch lspatches datapatch dba_registry_sqlpatch CVE destek bitti opatch Doc ID 742060.1 yama takvimi Kurulu RU, datapatch durumu ve destek takvimi; uygulama için RU patch rehberine bağlanır. Salt-okur."}]},{"id":"ora-oem","file":"install/guides/ora-oem.json","group":"Oracle","engineId":"oracle","category":"monitoring","title":"Oracle Enterprise Manager Cloud Control 13c Release 5 (13.5) kurulumu","summary":"Oracle Enterprise Manager Cloud Control 13.5'i kurar: mevcut bir 19c veritabanı Management Repository olarak hazırlanır (belgedeki parametreler, optimizer ayarlarının sıfırlanması), OMS sunucusuna silent kurulum yapılır ","level":"İleri","duration":"3–5 saat","topology":"OMS sunucusu + repository veritabanı sunucusu (+ izlenecek hedef sunucular)","tags":["oracle","enterprise manager","oem","em13c","13.5","cloud control","oms","agent","emctl","emcli","monitoring","izleme","rac","cluster","discover_db","data guard","exportconfig"],"order":40,"steps":32,"scenarios":[]}]}}