Blog
Mert Özen'in yazılım geliştirme, backend, frontend ve DevOps üzerine blog yazıları.
Eski SQL Server'ları Okumak: 2016'dan 2025'e Motor Evrimi ve Compatibility Level Yükseltme Stratejisi
Motor sürümü ile compatibility level ayrı şeylerdir: SQL Server 2025 üzerinde 130 seviyesinde çalışan bir veritabanında table variable hâlâ 1 satır, MSTVF 100 satır tahmin edilir, scalar UDF 8.916 kez çağrılır ve REGEXP_LIKE tanınmaz. 2016'dan 2025'e özellik tablosu, Microsoft Lifecycle tarihleri ve motoru eski seviyede yükselt, Query Store'la topla, seviyeyi artır, regresyonda planı zorla akışının gerçek bir denemesi.
Teşhis Metodolojisi: Wait Statistics, DMV'ler ve Extended Events ile "Veritabanı Yavaş" Şikâyetini Çözmek
"Veritabanı yavaş" şikâyeti tahminle değil ölçümle çözülür: önce session ya da sunucu wait'leri neyin beklendiğini, sonra DMV'ler ve Extended Events hangi sorgunun kaç logical read yaptığını, plan nedenini söyler; düzeltme aynı metrikle doğrulanır. Örnekte yavaşlık index değil blocking'di; durum listesi bir index ile 7.707'den 3 logical read'e indi. Duplicate index tespiti, 2025'in time-bound XE session'ı ve OpenTelemetry ile endpoint'ten sorguya inmek.
SQL Server'da Güvenlik Modeli: Login, User, Schema, Role, Least Privilege ve Row-Level Security
Uygulama kullanıcısını db_owner yapmak, bir injection açığında tablo silme yetkisi vermektir; doğrusu runtime ve migration kimliklerini ayırmak, yetkiyi schema ve rol üzerinden vermek ve kritik satırları Row-Level Security ile korumaktır. SQL Server 2025'in PBKDF2 parola hash'i, DENY önceliği, SESSION_CONTEXT'li RLS ve predicate şeklinin performansa etkisi, DDM'nin neden güvenlik sınırı olmadığı ve TrustServerCertificate ile TDS 8.0 strict bağlantı denemesi.
tempdb, Temp Table ve Table Variable: Hangisi Ne Zaman?
Compatibility level 150'nin altında table variable 1 satır tahmin edilir ve 17.359 satırlık bir join 182.749 logical read'e çıkar; deferred compilation satır sayısını düzeltir ama kolon statistics'i olmadığı için filtre tahmini yine yanlıştır. Temp table, table variable ve CTE'nin statistics, rollback ve tekrar değerlendirme farkları, tempdb contention ve data file'lar, TVP ile toplu veri ve SQL Server 2025'in tempdb space resource governance'ı.
Function'lar ve Trigger'lar: Scalar UDF Inlining, Inline TVF, Multi-Statement TVF ve Trigger Tuzakları
Inline edilmeyen bir scalar UDF satır başına ayrı modül olarak çalışır: 17.359 siparişlik bir sorguda function 34.718 kez çağrıldı, 365.498 logical read STATISTICS IO'da hiç görünmedi ve plan paralel olamadı. SQL Server 2019 inlining'i, is_inlineable, inline TVF ile MSTVF'nin 100 satırlık sabit tahmini ve interleaved execution, trigger'da tek satır varsayımı, EF Core'un OUTPUT kısıtı ve audit için temporal table gerçek ölçümlerle.
Stored Procedure'ler: Parametreler, Hata Yönetimi, Yetki Zinciri ve Güvenli Dynamic SQL
Doğru stored procedure iskeleti SET NOCOUNT ON, SET XACT_ABORT ON, TRY/CATCH içinde ROLLBACK ve parametresiz THROW'dur; aksi hâlde bir CHECK hatası yarım siparişi commit edebilir. Output parameter ve return code'un Dapper'dan okunması, uygulama kullanıcısına yalnız EXECUTE veren ownership chaining, allowlist + QUOTENAME + sp_executesql ile güvenli dynamic SQL ve dynamic SQL'in kırdığı zinciri module signing ile onarmak gerçek çıktılarla.
SQL Server 2025 Optimized Locking: TID Locking, Lock After Qualification ve Davranış Değişiklikleri
Optimized locking açıldığında 1.000 satırı güncelleyen transaction 1.017 lock yerine tek bir XACT lock tutar ve escalation olmaz; RCSI de açıksa LAQ, UPDATE'in predicate'ini son commit edilmiş versiyonda lock almadan değerlendirir, blocking kalkar ama bazı eşzamanlı işlerin sonucu değişebilir. ADR ön koşulu, yeni LCK_M_S_XACT wait'leri, LAQ'ı kapatan hint'ler, deadlock graph'taki xactlock ve 2019/2022 farkı gerçek ölçümlerle.
Deadlock'lar: Deadlock Graph'ı Okumak, Yaygın Pattern'ler ve .NET'te Retry
SQL Server deadlock'ta geri alması en ucuz transaction'ı kurban seçer ve 1205 döner; çözüm graph'ı okumak, erişim sırasını sabitlemek, covering index ya da RCSI ile reader-writer döngüsünü kırmak ve bütün transaction'ı iş kuralını yeniden kontrol ederek tekrar denemektir. Ters sıra, HOLDLOCK'lu upsert ve key lookup deadlock'ları, DEADLOCK_PRIORITY, EF Core'un execution strategy'si ve Polly ile retry'ın iptali ezdiği gerçek bir örnek.
Lock'lar ve Blocking: Lock Mode'ları, Granularity, Lock Escalation ve Blocking Zincirini Bulmak
Tek satırlık bir UPDATE bile dört lock tutar ve SQL Server lock isteklerini sıraya koyar; bu yüzden zincirin kökünü sys.dm_exec_requests ve sys.dm_exec_sessions ile ararsın. Lock mode'ları ve compatibility matrisi, laboratuvarda 6.249 lock'ta ölçülen escalation, UPDLOCK/SERIALIZABLE ile güvenli upsert, READPAST ile queue table, LOCK_TIMEOUT ve migration'ın Sch-M ile bütün okuyucuları durdurması gerçek çıktılarla.
Isolation Level'lar ve Row Versioning: READ COMMITTED, RCSI, SNAPSHOT, REPEATABLE READ ve SERIALIZABLE
Isolation level'lar, eşzamanlı transaction'ların hangi anomaliyi görebileceğini locking ya da row versioning ile belirler: varsayılan READ COMMITTED okuyucuyu yazana bekletir, RCSI son commit edilmiş sürümü verir, SNAPSHOT transaction başındaki görüntüyü tutar ve çakışmada 3960 verir. İki oturumlu deneylerle dirty read, non-repeatable read, phantom, lost update, write skew, versioning'in 14 byte'lık bedeli ve .NET'ten IsolationLevel seçmek.
Transaction'lar ve Transaction Log: ACID'in Motor Tarafı, XACT_ABORT, Savepoint ve Accelerated Database Recovery
SQL Server'da atomiklik kendiliğinden gelmez: XACT_ABORT OFF iken hatalı ifadeden sonraki COMMIT yarım işi kalıcı yapar, iç COMMIT hiçbir şeyi commit etmez, tek bir açık transaction SIMPLE recovery'de bile log'un truncate edilmesini durdurur. XACT_ABORT ve TRY/CATCH/THROW kalıbı, savepoint, LSN/VLF/recovery model, 200.000 satırlık rollback'in ADR ile 200.031'den 1 log record'a inişi ve TransactionScope'un Linux/macOS'ta distributed transaction hatası.
Query Store ve Intelligent Query Processing: Regresyonu Bulmak, Plan Zorlamak ve Kod Değiştirmeden Hint Vermek
Query Store sorgu metinlerini, planları ve çalışma istatistiklerini veritabanında kalıcı tutar; böylece plan cache'in unuttuğu "dün nasıldı" sorusunu cevaplar, kötüleşen planı zorlamaya ve kodu değiştirmeden hint eklemeye izin verir. Regresyon sorgusu, plan zorlamanın bedeli, FORCE_LAST_GOOD_PLAN, EF Core sorgusuna Query Store hint'iyle RECOMPILE, 2025'in ABORT_QUERY_EXECUTION'ı ve IQP ailesi.