Ask HN: Gerçek bir UUID v4 çakışması yaşadım...
(news.ycombinator.com)- Veritabanı bugün yinelenen bir UUID v4 tespit etti ve mevcut değer, 2025'te eklenen bir kaydın
b6133fd6-70fe-4fe3-bed6-8ca8fc9386cddeğeriyle tamamen aynıydı - Kullanılan paket npm’deki uuid ve
import { v4 as uuidv4 } from "uuid";sonrasındaconst document_id = uuidv4();ile üretip veritabanına eklediklerini söylüyor - Veritabanında yalnızca yaklaşık 15.000 kayıt var; bu da istatistiksel olarak imkânsız görünüyor. Aynı şeyi yaşamış biri olup olmadığını soruyor
1 yorum
Hacker News görüşleri
jandrewrogers: Bu aslında şaşırtıcı derecede yaygın. UUIDv4'ün güvenliği, yüksek kaliteli bir entropi kaynağı olduğu varsayımına dayanıyor; ancak donanım arızaları, yaygın yazılım hataları ve geliştiricilerin entropiyi yeterince anlamaması nedeniyle bu varsayım kolayca bozuluyor
Entropi kaynağının bozulup bozulmadığını tespit etmek oldukça maliyetli olduğundan bunu neredeyse kimse yapmıyor ve sonuçta sorun ancak çakışma olduktan sonra fark ediliyor. Bu yüzden birçok yüksek güvenilirlikli ve yüksek güvence gerektiren sistemde UUIDv4 açıkça yasaktır
Entropi kaynağı ne kadar çoksa o kadar iyidir ve bunların önemli bir kısmı deterministik olmamalıdır. Küçük ölçekli oyunlarda bile fare koordinatları, tuş girişleri arasındaki süreler, başlat düğmesine basılmadan önce geçen frame sayısı gibi değerleri başlangıç tohumuna katarsanız, içeride sözde rastgele sayı üreteci kullanılsa bile tahmin etmek çok daha zor hale gelir. CloudFlare 100'den az entropi kaynağı kullanıyorsa hayal kırıklığına uğrardım
Eskiden Go tarafında olduğu gibi “N bayt istedim ama sadece 3 bayt döndü, o halde N-3 baytı yeniden istemeliyim” türü dönüş değerlerini doğrulamazsanız böyle olur. Çoğu donanımda ya da işletim sisteminde bu sorun çıkmadığı için insanlar kontrol etmiyor, sonra bir gün üretim ortamında on binlerce çakışma olarak ortaya çıkıyor
throwaway_19sz: İnanması güç ama komik bir gerçek hikâye. 10 yıl önce bir arkadaşım hızlı büyüyen bir startup'a CTO olarak katıldı; şirkette yaklaşık 200 geliştirici vardı ve ilk hafta yalnızca UUID üretmek için çalışan bir mikroservis olduğunu fark etti
Tek bir endpoint için üç tam zamanlı mühendis, hatta bir veritabanı sorumlusu bile vardı. Yeni bir “güvenli” UUID gerektiğinde bütün ekipler bu servisi çağırmak zorundaydı; servis UUID'yi üretiyor, kendi veritabanında daha önce verilmiş UUID var mı diye kontrol ediyor, yoksa ekleyip geri döndürüyordu. Bu sadece iç rahatlığı için miydi bilinmez ama o ekibin kendi Kanban panosu ve sprintleri bile vardı
Sonradan girdiğim startup'ta ise biri yeni bir endişe uydurduğunda hemen yeni bir mikroservis ve yeni bir ekip ortaya çıkıyordu. Çeyrek hedefleri arasında açıkça mühendislik ekibinin boyutunu büyütmek vardı ve 3-4 kişilik ekipler kendi sprintleriyle planlama toplantılarında kendilerine iş çıkarıyordu. İstikrarlı bir projedeki insanları acil bir işe kaydırmayı önerdim ama belirli bir mühendis sayısına ulaşma KPI'larıyla çeliştiği için engellendi
Yüksek erişilebilirlik ve dünya çapında dağıtım için her instance'a özel bir ID aralığı vererek shard da edebilirsiniz. Üst bitlerin bir kısmını veri merkezi kimliği için, birkaç biti de oradaki ID üretici instance'ı için ayırmanız yeterli. Bir dakika, bunu sanki bir yerden hatırlıyorum… Twitter hâlâ bunu mu kullanıyor, yoksa sonunda değiştirdi mi merak ediyorum
Her gün DB dump alınıyor, “geçici” ID üretiminde buna karşı kontrol yapılıyor ve ancak CMDB'ye düzgün şekilde gönderildikten sonra “kesinleşmiş” sayılıyordu. Geçici ID'lerin üretimde kullanılmaması için koruyucu önlemler vardı ve kullanılmamış kesin ID'leri geri dönüştürme prosedürü bile bulunuyordu. En son duyduğumda yerel DB önbelleğini Zookeeper'a taşıyan 6 aylık proje 18. ayındaydı
CodesInChaos: Genelde sebep yetersiz tohumlanmış sözde rastgele sayı üreteci olur. UUID'nin backend'de mi frontend'de mi üretildiği önemlidir
Frontend, kasıtlı çakışmalar dahil birçok sebeple doğası gereği güvenilmezdir; bu yüzden çakışma işleme gerekir. Backend tarafı güvenilir biçimde yapılabilir. Geçmişte VM'lerde böyle sorunlar olurdu ama bugün çözülmüş olması gerekirdi; yine de güçlü şekilde sandbox'lanmış bir process güvenli olmayan alternatif rastgelelik yoluna düşerse sorun çıkabilir. Process veya VM fork'ları da durum kopyalayarak çakışma üretebilir
kst: “Pro Git”ten bir bölüm aklıma geldi. <https://git-scm.com/book/en/v2>
Dünyadaki 6,5 milyar insanın her saniye Linux kernel'inin tüm geçmişi kadar kod üretip tek bir dev Git deposuna push etmesi durumunda bile, SHA-1 nesne çakışması olasılığının %50'ye ulaşması yaklaşık 2 yıl sürer örneği verilmişti. Bu yüzden doğal bir SHA-1 çakışmasının, ekipteki herkesin aynı gece birbirinden bağımsız kurt saldırılarıyla ölme ihtimalinden düşük olduğu benzetmesini sevmiştim. SHA-1 hash'i rastgele değildir ve 160 bittir, dolayısıyla UUIDv4 ile aynı şey değil ama bağımsız kurt saldırıları benzetmesini seviyorum
Ekvator boyunca her 1 milyar yılda bir adım atarak Dünya'nın çevresinde dolaşmak, her turda Pasifik Okyanusu'ndan bir damla su eksiltmek, okyanus boşalınca bir kâğıt yaprağı koymak ve bu işlemi yığın Güneş'e ulaşana kadar tekrarlamak gibi benzetmeler yapıyor; yine de 52! saniyelik bir zamanlayıcının ilk üç hanesi değişmiyor
e12e: İlgili tartışma burada: https://github.com/uuidjs/uuid/issues/546
Örneğin
crypto.getRandomValues()fonksiyonunu googlebot üzerinde test ettiklerinde deterministik çıktığı söyleniyoradyavanapalli: Bahsedilen şey o kadar nadirdir ki şu anda tüm Dünya'nın bir asteroid tarafından yok edilme ihtimali daha yüksektir
Gerçekte meteor çarpmasına uğrayıp bacağından yaralı şekilde hayatta kalan bir kadının olduğu söyleniyordu. Eğer UUID çakışması olduysa, bunun bir yazılım hatası ya da bilgisayar arızası olma ihtimali ezici biçimde daha yüksektir; kozmik ışın da olabilir. Kozmik ışınların bellek ya da CPU'yu etkilemesi sanıldığından daha yaygındır
juancn: Rastgele sayı üretecinin başlatılması bozuk ya da entropi yetersiz olabilir mi? Özelleştirme yapılmadıysa
crypto.getRandomValues(rnds8)kullanılıyor, amagetRandomValuesasgari entropi miktarını belirtmiyorGeee: Kuantum mekaniğinin çoklu dünyalar yorumuna göre, tüm UUID'lerin aynı olduğu en az bir evren dalı vardır. O dünyadaki insanların ne düşündüğünü hayal ediyorum
mittermayr: Bunun mantıksız olduğu konusunda tamamen katılıyorum. Yine de tahmin etmem gerekirse, eskiden UUIDv4 kullanıcıların telefonunda üretilip DB'ye gönderiliyordu, bu sabah çakışan UUID ise Ubuntu sunucusunda üretildi
UUIDv4'ün tam olarak nasıl üretildiğini, üretildiği makinenin özelliklerinin algoritmaya girip girmediğini bilmiyorum ama aklıma gelen tek değişiklik, eskiden cihazda üretilirken birkaç aydır sunucuda üretiliyor olması
Ama sunucuda, özellikle 2026 yılında, böyle olmamalı. Eskiden VM rastgelelik tohumu sorunluydu ama bugün daha az olmalı. UUID'lerden biri kötü üretilmiş olsa bile gerçekten rastgele bir UUID'nin onunla çakışma olasılığı çok düşüktür; demek ki her iki üreteçte de sorun olması gerekir
dweez: Şu eğlenceli yazıyı yeniden görme zamanı: https://jasonfantl.com/posts/Universal-Unique-IDs/
Tüm evreni dev bir bilgisayara çevirip ısıl ölüme kadar sadece UUID üretseydik, ID uzayı için kaç bite ihtiyaç olurdu?
beejiu: UUID'nin istemci tarafında mı yoksa sunucu tarafında mı üretildiğini merak ediyorum. İstemci tarafındaysa sebep crawler bot olabilir. Örneğin Googlebot, JavaScript'i deterministik “rastgelelikle” çalıştırır
Bu tür açıklamalar, gerçekten rastgele bir çakışmadan birkaç mertebe daha olasıdır
merlindru: Büyük ihtimalle tohum sorunu. Aksi olduğunu kanıtlayabilirseniz muhtemelen biraz ünlü olursunuz
erlkonig: Yeterince veri varsa rastgele değerler bir gün çakışabilir ve o zaman yazılımın ne kadar sağlam olduğunu görürsünüz diye ekibe sürekli söylüyorum
Buna rağmen deneyimli geliştiriciler, ekip liderleri ve CIO'lar arasında bunun imkânsız olduğuna inanıp bu durumu ele alan kodu hiç yazmayan çok kişi var. Böyle olunca kötü bir RNG sistemi beklenenden çok daha erken bozabilir ve tespit ile yeniden üretim olmadan eşzamanlı veri bozulması da yaşanabilir. Bana
malloc()başarısını kontrol etmeyen insanları hatırlatıyor. “İmkânsızsa neden bu kadar çok bit kullanıyoruz?” diye soruyorum bazenleni536: Bunun tesadüfen olduğu fikrine inanmıyorum; bir yerde hata var. Kabaca baktığımda paket, JS çalışma zamanındaki
crypto.randomUUID()fonksiyonunu çağırıyor gibi görünüyor ve bunun her zaman doğru biçimde tohumlanmış olması gerekirÇalışma zamanında bir bug olma ihtimali çok düşük görünüyor ama imkânsız değil. Hangi JS runtime'ının kullanıldığını merak ediyorum
jbverschoor: En olası sebep,
uuidpaketinin bağımlı olduğu rastgele sayı üretim paketinin yakın zamanda ele geçirilip “rastgele” sayıların öngörülebilir hale getirilmiş olmasıdır. Bu durumda tedarik zinciri saldırısı yüzünden pek çok kriptografi, SSL ve finansal işlem projesi risk altında olabiliruuid/src/rng.tsiçinde rastgele diziconstyapılmış. Böylece tüm çağrılar aynı rastgele diziyi paylaşır hale geliyorSonraki çağrılar önceki rastgele kodu güncellediği için, önemli bir şey ürettiyseniz şansınıza güvenmeniz gerekir. Eski kod
slice()ile yeni bir kopya oluşturuyordu. Bu istemeden yapılmış bir değişiklik olabilir ama iki rastgele sayı üretip farklı olduklarını kontrol eden bir testten bile geçmemesi gerekirken bunun nasıl geçtiğini anlamıyorumpif: Yüksek kaliteli bir entropi kaynağı olsa bile, “muhtemelen böyledir” ifadesini “kesinlikle böyledir”e çeviremezsiniz. Tahmin edilmesi zor değerler istiyorsanız kriptografiye bakın; ama garanti benzersizlik istiyorsanız bunu kendiniz üretmelisiniz
athrowaway3z: Basit bir pratik kural, ID'ye rastgeleliğe ek olarak timestamp koyup koyamayacağınızı düşünmektir. Çoğu zaman cevap evettir ve UUIDv7 yeterlidir
Bilgi sızıntısının kabul edilemez olduğuna dair kanıtı kendiniz yazabilecek kadar sorunu derinlemesine incelediyseniz tebrikler. Muhtemelen sisteminiz, güçlü bir kriptografik hash ya da uğraşmak istemiyorsanız UUIDv5 kullanmayı gerektirecek kadar karmaşık ve yavaştır
darqis: PostgreSQL 18 artık uuidv7'yi yerel olarak destekliyor; varsayılanı
uniqueveuuid7()olarak ayarlamak yeterlitumdum_: Kötü tohumlanmış sözde rastgele sayı üreteci
serf: 4.72 × 10²⁸'de 1, yani 47.3 oktilyonda 1 seviyesinde. Gerçekten buysa piyango bileti almadan önce race condition ya da başka basit bir hatadan şüphelenirdim
evnix: Olasılık hesabını bir kenara bıraksak bile, yaşadığımız gerçeklikte en iyi donanım rastgele sayı üreticileri bile düşündüğümüz kadar rastgele olmayabilir
Güvenliğin kritik olmadığı yerlerde TSID gibi bir şey, ya da uuidv7'ye geçmek pratikte bu tür olayları fiilen ortadan kaldırır. Bence bu, kodu yeniden denemelerle aşırı karmaşıklaştırmaktan daha iyidir
jordiburgos:
b6133fd6-70fe-4fe3-bed6-8ca8fc9386cdkullanmayın lütfen. DB'me baktım, zaten kullanıyormuşum16b55183-1697-496e-bc8a-854eb9aae0f3kullanıyorum ve muhtemelen daha da vardır. Herkes burada kendi listesini paylaşsa tekrarları kontrol edebiliriz belki?pyuser583: Bugünlerde hangi UUID'nin tercih edildiğini merak ediyorum
smokel: Defalarca, derleyiciyi, kozmik ışınları, kuantum etkilerini, en azından obscure bir kernel bug'ını suçlayıp sonunda hatanın kaynağının ben olduğumu fark ettim
15.000 kayıtta çakışma fazla düşük bir olasılık, bu yüzden önce başka sebeplerden şüphelenirdim: tekrar eden işlemler, yeniden gönderilen istekler, yeniden kullanılan nesneler, yanıltıcı loglar, başka bir kod yolunda tanımlayıcıların yeniden kullanılması gibi. Çevredeki koddan biraz daha paylaşırsanız birlikte bakabiliriz
wazoox: Henüz başıma gelmedi ama iki gün önce üretimdeki bir PHP kod tabanının derinliklerinde şunu buldum:
md5(uniqid('', true))ile üretilmiş bir değeri kesip UUID gibi birleştiren bircreateUUID()fonksiyonuBu dehşetin nasıl olup da hâlâ bizim şah damarımıza yapışmadığını bilmiyorum
sedatk:
uuidjs/uuidiçinde, Googlebot gibi deterministik RNG kullanan istemcilerde yinelenen UUID'ler üretilebileceğine dair uyarı varİstemci tarafında üretilen UUID'lerin her zaman benzersiz olmasını bekleyen uygulamalar için bu sorun olabilir; bu yüzden tekrarları kontrol edip zarif biçimde başarısız olmak ya da Googlebot istemcilerinin yazma işlemlerini devre dışı bırakmak gerektiği söyleniyor: https://github.com/uuidjs/uuid/commit/91805f665c38b691ac2cbd...
xyzzy123: Linux tabanlı bir dağıtık sistemde uzun süreli yük testi yinelenen UUID'ler yüzünden başarısız olmuştu
Uzun incelemenin sonunda bunun bir kernel bug'ı, daha doğrusu bir race condition olduğu ortaya çıktı. Çok işlemcili sistemlerde iki process aynı anda
/dev/randomokursa çok nadiren, kabaca milyonda bir ihtimalle aynı baytları alabiliyordu. Önce rastgele sayı üreticisinin başlatılmasına bakardımbaq: Çalışan VM tüm entropiyi sanallaştırma yüzünden çöpe atmış gibi görünüyor
glaslong: Birkaç lava lambası almak lazım
0xfffafaCrash: UUID'nin frontend'de mi backend'de mi üretildiğini merak ediyorum. Frontend'de üretildiyse entropi sorunundan çok, istemci kodunun ya da isteğin kurcalanıp zaten bilinen bir UUID'nin enjekte edilmiş olabileceğine oynardım
latentframe: Mühendislikte en tehlikeli ifadelerden biri istatistiksel olarak imkânsız sözüdür. Ölçek yeterince büyüdüğünde uç vakalar teori olmaktan çıkar, operasyon olayı haline gelir
8organicbits: Geçen yıl gerçek bir çakışmayı ve ilgili kütüphaneyi de içeren bir yazı yazmıştım: https://alexsci.com/blog/uuid-oops/
UUID'nin çakışmaya dayanıklı olması için sıkı biçimde korunması gereken birçok kısıt var ve bu olayda sorun büyük ihtimalle rastgele sayı üretecinde gibi görünüyor
nu11ptr: Sonuçta mesele entropi kaynağı. Bu yüzden ben her zaman döngü içinde üretip ekliyorum. Çakışma olursa zarif şekilde ele alınabilir
sbuttgereit: Bu “teknik olarak imkânsız” değil. Aksine teknik olarak mümkün. İyi rastgelelik varsa sadece çok, çok düşük olasılıklıdır ve UUIDv4'ün yinelenen değer üretmesini teknik olarak engelleyen bir şey yoktur
beardyw: Aptalca bir soru olabilir ama tarihin kendisini, en azından saniye cinsinden onaltılık biçimde, ekleyemez miyiz? Birkaç bayt daha eklemek, bugün yeterli olanın gelecekte de yeterli kalmasını garanti eder gibi geliyor
mdavid626: Başka açıklamalar da mümkün. Örneğin biri isteği ya da DB'yi elle değiştirmiş olabilir
radial_symmetry: Ben de bir kez böyle bir şey yaşayıp aklımı kaçırdığımı sanmıştım; buradaki yorumları okuyunca rahatladım
NKosmatos: Bu “teknik olarak imkânsız” değil. İmkânsız değil, sadece çok ama çok düşük olasılıklı. Galiba piyango ya da Powerball bileti almalısınız
“improbable” kelimesini her duyduğumda https://hitchhikers.fandom.com/wiki/Infinite_Improbability_D... aklıma geliyor
sudb: Projelerimden birinde CUID2 seçmiş olmanın gerçekten iyi bir fikir olduğunu ilk kez hissediyorum: https://github.com/paralleldrive/cuid2