Tekrar üretilemeyen hatalarla uğraşmak


73

Takımınızın iyi çalışan (oldukça şaşırtıcı bir şekilde!) Bir yazılım sistemi yazdığını varsayalım.

Bir gün mühendislerden biri yanlışlıkla bazı DB verilerini değiştiren bazı SQL sorguları çalıştırıyor, sonra unutuyor.

Bir süre sonra bozuk / hatalı verileri keşfedersiniz ve herkes kodun hangi kısmının buna neden olduğunu ve neden boşuna olmadığını çizer. Bu arada, proje yöneticisi, buna neden olan kodun bir kısmını bulduğumuzda ısrar ediyor.

Nasıl anlaştın onunla birlikte?


32
Mühendis bunu unuttuysa, bunun ne olduğunu nasıl bildin? Senaryo çalıştıran biri tarafından değil, böcek tarafından nasıl bozuldun?
DaveG

18
Bir veya iki gün sonra bir epifani oldu. Bu, hangisinin kolayca olabileceğini hatırlamaması durumunda varsayımsaldır.
Nik Kyriakides

12
Bu bir varsayımdır. Eminim Başbakan bize bunu hatırlatırsa elimizden geldiğince kovalamamıza neden olur. Yapacağımı biliyorum.
Nik Kyriakides

59
xkcd.com/583 ;) [NSFW dili]
Baldrickk

100
“Ekibinizin iyi çalışan bir yazılım sistemi yazdığını varsayalım.” Bana imkansız fanteziler vermeyi bırak!
Paul D. Waite

Yanıtlar:


134

Hiçbir proje yöneticisinin böyle bir soruna sonsuz miktarda zaman harcayacağı açık değildir. Aynı durumun tekrar yaşanmasını önlemek istiyorlar.

Bu hedefe ulaşmak için, böyle bir hatanın kök nedenini bulamamış olsanız bile, bazı önlemler almak mümkündür.

  • Bu tür arızaları, tekrar açmaları durumunda daha erken tespit edin.
  • Aynı başarısızlığın tekrar yaşanması olasılığını azaltın
  • Sistemi belirli tutarsızlıklara karşı daha sağlam hale getirin

Örneğin, daha ayrıntılı günlük kaydı, daha ayrıntılı hata yönetimi veya acil hata sinyali, aynı hatanın tekrar çarpmasını önlemeye ya da temel nedeni bulmaya yardımcı olabilir. Sisteminiz veritabanı tetikleyicileri eklemeye izin veriyorsa, belki de ilk etapta ortaya çıkan tutarsızlığı yasaklayan bir tetikleyici eklemek mümkündür.

Durumunuzda ne tür bir eylemin olabileceğini düşünün ve bunu takıma önerin; Proje yöneticinizden memnun kalacağınızdan eminim.

Bir gün mühendislerden biri yanlışlıkla bazı DB verilerini değiştiren bazı SQL sorguları çalıştırıyor, sonra unutuyor.

Başkaları tarafından belirtildiği gibi, böyle bir prosedürü yasaklamak iyi bir fikirdir (eğer sistemin nasıl işletileceğini etkiliyorsanız). Hiç kimsenin veritabanı içeriğini değiştiren belgesiz geçici sorgular çalıştırmasına izin verilmemelidir. Böyle bir sorguya ihtiyaç varsa, sorguyu yürütme tarihi, yürüten kişinin adı ve kullanılma nedenini belgelenmiş bir yerde saklamak için bir politika olduğundan emin olun.


8
@NicholasKyriakides Muhtemelen ikisi de. Bunların tümü, "ertelenmiş" hata ayıklamayı basitleştiren ortak-duyarlı önlemler. Muhtemelen sayısız prosedürde yazılmıştır.
Nic Hartley,

29
Zaman zaman bir üretim sisteminde bir tür ciddi sorun yaşamanız ve bunun ciddi bir çaba göstermesine rağmen sebebini belirleyememeniz gerçekleşti. Sonuçta, onu kozmik ışınlara bağlar ve raporlamayı iyileştirmeyi denersiniz (tekrar olursa, nedeni bulmada daha iyi bir şansınız olur) ve azaltma (eğer tekrar olursa hasar az olacaktır) ve görüp görmediğini kontrol edin. tekrarlar.
David Schwartz

2
@Nicholas Kyriakides: Yıllar boyunca kişisel deneyim.
Doktor Brown

4
Ayrıca, bir böcek olsa bile, artık orada olamayabileceği çok muhtemeldir. Bazen yapabileceğiniz en iyi şey, verileri düzeltmek ve aynı sorunun bir daha oluşmamasını sağlamak için testleri / prosedürleri iyileştirmektir.
kutschkem

2
Kesintili sorunları bulmak, tüm bunları günlüğe kaydetme ve ortaya çıktıklarında algılayabilecek bir boğulma noktası bulma, sonra kaynağı saptamak için oradan geriye yürüme ile ilgilidir. Bazen, sadece hatanın ne zaman / nerede olduğunu anlamak için tetikleyiciler gibi nahoş şeyler veya gürültülü hata günlüğü ile kod dağıtımı gerektirir.
AaronLS

51

Bu bir hata değil

En azından kodunda değil. Bu sizin bir hata olduğunu süreç . Proje yöneticiniz, işleminiz için kodunuzdan çok daha fazla endişeli olmalıdır.

Nasıl anlaştın onunla birlikte?

Oldukça basit, mühendislerin üretimi veya paylaşılan geliştirme veritabanlarını değiştirmelerine izin vermeyerek .


Bunun paylaşılan bir gelişme veritabanı olduğunu varsayalım:

İdeal olarak, eğer mümkünse, ilk etapta paylaşılan bir veritabanına sahip olmaktan kaçının . Bunun yerine, kısa ömürlü geliştirici başına veritabanları var. Bu komut dosyasıyla otomatikleştirilmelidir, aksi takdirde test etme maliyeti çok artar ve test etmemeye özendirici olur. Bu veritabanlarını geliştiricinin iş istasyonunda veya merkezi bir sunucuda bulabilirsiniz.

Bazı nedenlerden dolayı, kesinlikle paylaşılan bir veritabanınızın olması GEREKİRDİRse, fikstür kullanmalısınız - esas olarak, her kullanmanız gerektiğinde veritabanını iyi bilinen bir duruma ayarlayan bir şey. Bu, geliştiricilerin başkalarının değişikliklerinden ısırılmasını önler.

Veritabanına kalıcı değişiklikler uygulamanız gerekiyorsa, bunları kaynak kontrolünüze vermelisiniz . Veritabanınızı, cihazların doğrudan yazma iznine sahip olmayacak ve değişiklikleri kaynak denetiminden alan ve uygulayan bir program olacak şekilde ayarlayın.

Son olarak, bir şeyleri nasıl debug ettiğinize dair açıklamanızdan, CI kullanmıyorsunuz gibi geliyor . CI kullanın . Kurulması biraz üzücü ama uzun vadede çok fazla zaman kazandıracak, yeniden üretilemeyen veritabanı hataları hakkında endişelenmekten vazgeçmekten bahsetmiyoruz. Şimdi sadece heisenbugs için endişelenmen gerekecek !


Bunun bir üretim veritabanı olduğunu varsayarsak:

Eğer devleriniz üretim veritabanlarını değiştiriyorsa, değişiklikler kesinlikle doğru olsa bile, birçok şey çok yanlış gitti.

Geliştiriciler asla üretim veritabanlarına erişmemelidir . Kesinlikle hiçbir sebep yok ve çok yanlış gidebilecek pek çok şey var .

Bir üretim veritabanındaki bir şeyi düzeltmeniz gerekiyorsa , önce yedekleme yapın, bu yedeği farklı (geliştirme) bir örneğe geri yükleyin ve sonra o geliştirme veritabanını oynayın. Bir düzeltmenin hazır olduğunu düşünüyorsanız (kaynak kontrolünde!), Geri yüklemeyi yeniden yapın, düzeltmeyi uygulayın ve sonucu görün. Ardından, işleri tekrar yedekledikten sonra (ve aynı zamanda eşzamanlı güncellemeleri önlemek için), ideal olarak bir yazılım yaması aracılığıyla üretim örneğini düzeltirsiniz.

Bir şeyi üretim veritabanında test etmeniz gerekirse ... hayır, yapmazsınız. Yapmanız gereken testler ne olursa olsun, bir geliştirme durumunda yapmalısınız. Testleri yapmak için bazı verilere ihtiyacınız olursa, o verileri oraya alırsınız.


12
Yani, önerilen çözümünüz zaman yolculuğu mu?
Benubird

7
Her ne kadar bu verilen örnek için iyi bir çözüm olsa da, soru, yeniden üretilemeyen hatalarla ve bunların ikna edilmesini isteyen yöneticilerle başa çıkma konusunda çok daha genel bir içeriğe sahiptir. Bu sadece veritabanı sorunları ve izin yönetiminden daha fazlası için geçerli olabilir. Bu cevabın aslında verilen soruyu yanıtlamadığını hissediyorum, sadece verilen örneği.
Kyle Wardle

@KyleWardle Anlaşıldı. Doktor Brown'un cevabının genel durumu oldukça iyi karşıladığını düşünüyorum (detaylı kayıt ve hata yönetimi, koruma koşulları). Çoğunlukla benimkileri ekledim çünkü kimsenin soruna yol açan süreç başarısızlıklarını ilk etapta
görmediğini gördüm

2
@ Benubird bence cevap "bununla başa çıkma şeklini tekrar etmesini önlüyor" şeklinde cevaplanıyor. Bozuk bir üretim veritabanını bir yazılım mühendisliği perspektifinden "çözebileceğinizi" sanmıyorum.
goncalopp

1
Dev veritabanına veri koymak için kod değiştirmeyeceksiniz. Çalıştığım her yerde, büyük şirketler dahil, geliştiriciler test verilerini eklemek ve uygulamanın kullandığı aynı bilgileri kullanmakta serbesttirler.
David Conrad

13

Bir üretim veritabanı tam erişim günlüğüne ve rol tabanlı erişim kontrollerine sahip olmalıdır. Bu nedenle, veritabanına KİM KİM NE YAPTIĞINI ve bu nedenle dikkatini koddan zayıf operasyonel güvenliğe taşıdığına dair sağlam kanıtlara sahip olmalısınız.


2
Veri bozulmalarının ne zaman gerçekleştiğini tam olarak bilemeyecek gibi görünüyorlar, bu da hangi logları araştırmak istediklerini anlamayı zorlaştırabilir.
Nathanael

3
Maalesef bunlardan birinin izini sürdüğümüzde, kütüklerin de silindiğini keşfettik. (Evet, bu. Böcek gerçekti.)
Joshua

Zamanlanmış işlerle veri bütünlüğünü denetleyen çift kaydı, yalnızca bir gecede olsa bile, sorunların erken işaretlenebileceği ve çözülebileceği anlamına gelir. Gerçekten dikkatli olmak istiyorsanız, değişiklikler için akran incelemesi gerekir.
Keith

Çalıştığım her yerde devs, veritabanına, uygulamanın kullandığı aynı kimlik bilgileriyle bağlanıyor, bu nedenle erişim günlüğü yalnızca bu kimliğin bir programdan ziyade bir insan tarafından yapıldığını göstermediğini gösterir. Sanırım, uygulamanın o sırada db'ye yazacak bir şey yapıp yapmadığını görmek için zaman damgasını uygulama günlükleriyle karşılaştırabilirsiniz.
David Conrad

@DavidConrad: Devs, uygulamanın üretimde kullandığı kimlik bilgilerine neden erişiyor? Bir çeşit gizli yönetim kullanmanız gerekir; böylece bu kimlik bilgileri, uygulama hizmet hesabınız haricinde, üretim uygulama sunucularından bile okunamaz.
Daniel Pryden

6

Bu durumda, nihayetinde sebebi çözdün, ama yapmadığın varsayımını alarak ...

İlk önce neyin değiştiğini analiz edin. Sistem daha önce iyi çalışıyorsa, son zamanlarda yapılan her şeye dikkatlice bakmak, hataya neden olan değişikliği ortaya çıkarabilir. Bir şeylerin değişip değişmediğini görmek için sürüm kontrolünüzü, CI / dağıtım sistemlerinizi ve yapılandırma kontrolünüzü sistematik olarak gözden geçirin. İkili arama yapmak için git bisect komutunu veya eşdeğer bir mekanizmayı çalıştırın. Günlükleri kontrol et. Sahip olduğunuzu bilmediğiniz günlükleri araştırın. Son zamanlarda bir şey yapıp yapmadıklarını görmek için sisteme erişimi olan herkesle konuşun. Sorununuz için, eğer bu süreçte yeterince iyiyseniz, bu umarım unutulmuş SQL sorgularını ortaya çıkarmalıdır.

İkincisi, enstrümantasyon. Bir hatanın nedenini doğrudan bulamıyorsanız, sorunla ilgili verileri toplamak için etrafına araçlar ekleyin. Kendinize "bu hatayı komutta yeniden üretebilseydim, hata ayıklayıcıda neye bakmak isterdim" diye sorun ve bunu günlüğe kaydedin. Sorunu daha iyi anlayana kadar gerektiği kadar tekrarlayın. Doc Brown'un önerdiği gibi, hatayla ilgili durumlar için günlük kaydı ekleyin. Bozuk verileri algılayan iddialar ekleyin. Örneğin, hatanız bir uygulama çökmesiyse, bir çökme günlüğü mekanizması ekleyin. Zaten bir tane büyük varsa, kilitlenme ile ilgili potansiyel durumu kaydetmek için kilitlenme günlüklerine ek açıklamalar ekleyin. Eşzamanlılık sorunlarının dahil edilip edilemeyeceğini düşünün ve iş güvenliği için test yapın .

Üçüncüsü, esneklik. Hatalar kaçınılmazdır, bu nedenle kendinize sistemlerinizi daha dayanıklı olacak şekilde nasıl geliştirebileceğinizi sorun. Böylelikle böcek kurtarma işlemi daha kolaydır. Yedekleriniz geliştirilebilir mi (yoksa mevcut olabilir)? Daha iyi izleme, yerine çalışma ve uyarı? Daha fazla fazlalık mı? Daha iyi hata işleme? Bağımlı hizmetleri birbirinden ayırmak? Veritabanlarına erişim ve manuel sorgular çevresindeki süreçlerinizi geliştirebilir misiniz? En iyi ihtimalle, bu şeyler hatanızın sonuçlarını daha az şiddetli hale getirecek ve en kötüsü, muhtemelen yine de yapılacak iyi şeyler.


5
  1. Proje yöneticinize en muhtemel nedenlerin manuel veritabanına erişim olduğunu düşündüğünüzü açıklayın .
  2. Yine de, buna neden olan kodu aramanızı istiyorlarsa, gidin ve koda bir kez daha bakın.
  3. Birkaç saat içinde geri dönün (veya uygun bir zamanda) ve buna neden olacak herhangi bir kod bulamadığınızı söyleyin, bu nedenle en muhtemel nedenlerin manuel veritabanı erişimi olduğuna inanıyorsunuz.
  4. Onlar ise hâlâ kod için bakmak istiyorum, onlar bunu harcamak istiyorum ne kadar zaman sorun. Nazikçe onlara bunu yaparken, X, hata Y veya Z geliştirme üzerinde çalışmayacağınızı hatırlatın.
  5. İstedikleri kadar zaman geçirin. Hala en muhtemel sebebin manuel veritabanı erişimi olduğunu düşünüyorsanız, onlara bunu söyleyin.
  6. Onlar ise hâlâ kod bakmak istiyorum bu açıkça takımın bir zaman verimsiz kullanımı haline gelmiştir olarak, sorunu iletmek.

Gelecekte bu tür bir soruna neden olan manuel veritabanı erişim olasılığını azaltmak için ek bir işlem eklemeniz gerekip gerekmediğini de düşünebilirsiniz.


1
Mühendislerden birinin manuel güncelleme yaptığını bilmiyordum + mühendisler neredeyse doğrudan veritabanında sorgu çalıştırmıyorlardı. Bu sadece bir kereye mahsus bir şey yaptı ve unuttu. Bir gün geçirdik + neyin yanlış olduğunu bulmak için tam bir hafta geçirmeye hazırlandık. Sorum şu ki, sebebi bulamazsanız ve potansiyel sebebin ne olabileceğini öneremezseniz ne olur.
Nik Kyriakides

5
“Benim sorum, sebebi bulamıyorsanız ve potansiyel sebebin ne olabileceğini öneremezseniz ne olur?” Bu, 'düzeltmeyecek - kopyalanamaz' bayrağının icat edilmesinin tam nedenidir.
esoterik

4

Bir müşteri bozuk bir veritabanına sahip olduğunu bildirdiğinde bir ana bilgisayar veritabanı ürünü için geliştirme ekibi üzerinde çalışıyordum. Diskteki bitlerin iç durumunun, veri tabanının veri tabanı yazılımı yoluyla okunamadığı anlamına geldiği yönündeki yolsuzluk. Ana bilgisayar dünyasında müşteriler size milyonlarca dolar ödüyorlar ve bunu ciddiye almalısınız. Yaptığımız şey bu:

Adım 0: Veritabanını onararak müşterinin tekrar ayağa kalkıp çalışmaya başlamasına yardımcı olun.

Adım 1: Diskteki dosyayı hex düzeyinde inceleyerek yolsuzluğun sistematik olduğunu belirledik: aynı yolsuzluğun birçok örneği vardı. Bu yüzden kesinlikle veritabanı yazılımı düzeyinde neden oldu. Aslında, çok iş parçacıklı problemleri ekarte edebileceğimizi hissetmemiz yeterince sistematikti.

Diğer birçok teoriyi ortadan kaldırdıktan sonra, veritabanının fiziksel olarak yeniden düzenlenmesi için kullanılabilecek bir yardımcı programa bağlı kaldık. Doğru seviyede verilere erişimi olan tek kod gibi görünüyordu. Ardından, sorunu ortaya çıkaran, dikkatlice seçilmiş seçeneklerle bu yardımcı programı çalıştırmanın bir yolunu keşfettik. Müşteri, yaptıklarının bu olduğunu onaylayamadı veya inkâr edemedi, ancak ortaya çıkarabileceğimiz tek açıklama olduğundan, olası nedeni olduğuna karar verdik ve teşhisimizi kabul etmekten başka çareleri kalmayacaktı. .

Adım 2: Daha sonra yazılımda iki değişiklik yaptık: (a) bu etkinin yanlışlıkla “evet, ne yaptığımı biliyorum” kullanıcı arayüzü aracılığıyla neden olmasını zorlaştırdık ve (b) yeni bir günlük dosyası tanıtıldıysa, bir daha oldu, kullanıcı eylemlerinin kaydını tutacağız.

Bu nedenle, temel olarak (a) hasarı onarın ve canlı çalışmayı geri kazanın, (b) kök nedenini bulun, (c) tekrar olmasını önlemek veya tekrar meydana geldiğinde kolay teşhisi etkinleştirmek için ne gerekiyorsa yapın.


3

Tecrübelerime göre patronunuzun istediği şey, bunun tekrarlanmayacağına dair bir seviye güvencedir. Nedeni hiçbir kodun olmadığı durumdaysa, birlik testi ile garanti edildiğinden, kod tabanınızda zaten test kapsamı bulunduğunu varsayarsak, çözüm veritabanınıza "test" eklemeli. Don Gilman'ı alıntılayacağım, çünkü o orada çivilenmiş:

Bir üretim veritabanı tam erişim günlüğüne ve rol tabanlı erişim kontrollerine sahip olmalıdır. Bu nedenle, veritabanına KİM KİM NE YAPTIĞINI ve bu nedenle dikkatini koddan zayıf operasyonel güvenliğe taşıdığına dair sağlam kanıtlara sahip olmalısınız.

Ancak, üretimdeki verileri değiştirmek için Standart Çalışma Prosedürüne sahip olmalısınız. Örneğin, hiçbir DBA veriyi değiştirmemeli, hiçbir geliştirici değişikliği kendisi yapmamalı ve SÇP'de tanımlandığı gibi, posta yoluyla veya biletle resmen değişiklik yapmalı.

Bana böyle teklif veremezsen, bunun gibi bir yerde bir teklif olmalı:

Şeflerin tuvaletleri temizlemekten sorumlu olmayanlar olmasının mükemmel bir nedeni var.


1

Tekrar edilemeyen hatalarla yapılması gereken birkaç şey var.

  1. Bunun için bir bilet oluşturun

Bir bilet oluşturun ve bilette aklınıza gelebilecek her şeyi kaydedin. Ayrıca bu "hata" nın daha önce kaydedilmiş olup olmadığını kontrol edin ve biletleri birbirine bağlayın. Sonunda, böceğin nasıl çoğaltılacağı konusunda bir kalıp oluşturmak için yeterli bilet alabilirsiniz. Buna bir önlemeyi denemek için kullanılan ortamlar da dahildir. Bu tek örnek olsa bile, ilk kez varsa, sonunda ikinci kez olacak. Sebebi bulduğunuzda, sebebin ne olduğunu açıklayan bir biletle bileti kapatın; böylece, tekrar olursa ne olacağı konusunda güçlü bir fikriniz olsun (kötü birleşme ile kaybolan düzeltme)

  1. Sertleştirme analizi yapın

Sisteme bakın, ne oldu ve nasıl başarısız oldu. Başarısızlığı daha az olası kılmak için güncellenebilecek kodun alanını bulmaya çalışın. Bazı örnekler...

  • Geçici kodu özel bir aramayla değiştir ( execute(<query>)ileexecuteMyStoredProcedure(<params>)
  • Veri bütünlüğünü doğrulamak için her gece doğrulama komut dosyasını çalıştırın (böylece bir dahaki sefere 24 saat içinde tespit edilebilir)
  • Günlüğe kaydetme ve arşivleme (yedekleme) ekleme / iyileştirme.
  • Uygun olmayan güvenlik sınırlarını değiştirin (örneğin, yalnızca verileri okuyan kişiler / programlar yazma iznine sahip değildir; üretimden sorumlu olmayan geliştiricilerin, üretim sunucularına giriş yapabilmelerine izin vermemek)
  • Eksik olduğunda veri doğrulama / sanitasyon ekleyin

Bu, hatayı düzeltmeyebilir, ancak olmasa da, sistem artık daha istikrarlı / güvenli olduğundan, yine de karşılığını verir.

  1. Sistem uyarıları ekle

2'nin bir parçası, ama bir şeyler oldu ve bir daha ne zaman olacağını bilmen gerekiyor. Sistemi izlemek için bazı sağlık kontrolü komut dosyaları / programları oluşturmalısınız, böylece yöneticiler hatanın yeniden yüzeylenmesinden sonraki 24 saat içinde uyarılabilirler (ne kadar az gecikme olursa o kadar iyi olurlar). Bu temizlik çok daha kolay hale getirecek. (Veritabanlarının günlüklerine ek olarak, işletim sisteminin de oturum açanların ve yaptıkları okunmamış eylemlerin günlüklerini kaydetmesi gerektiğine dikkat edin. En azından, bu makineye yönelik trafik ağı günlükleri olmalı)


0

Sorununuz, yazılımınızdaki bir hatadan değil, veritabanına bağlı biri tarafından kaynaklandı. Yanlış giden şeyleri "hata" olarak adlandırırsanız, böcek kolayca yeniden üretilebilir: Birisi veritabanına aptalca şeyler yaptığında işler her zaman yanlış gidecektir. Ayrıca, veritabanının manuel olarak değiştirilmesine izin vermeden veya denenmemiş yazılım kullanarak ve veritabanını kimin değiştirebileceğini kesinlikle kontrol ederek bu "hata" dan kaçınmanın yolları vardır.

Veritabanınızdaki hataları yalnızca bir "hata" olarak adlandırırsanız, yeniden üretilemez bir hataya sahip değilsinizdir. Bir hata raporunuz olabilir, ancak sorunun bir hatanın neden olmadığına dair kanıtlarınız da var. Böylece hata raporunu "yeniden üretilemez" olarak değil, "zarar görmüş veritabanı" gibi bir şey olarak kapatabilirsiniz. Soruşturmanın hata olmadığını gösterdiği yerde hata raporları vermek nadir değildir, ancak bir kullanıcı yazılımı yanlış kullanmış, kullanıcının beklentileri yanlış vs.

Bu durumda, hala tekrarlanmasını istemediğiniz bir sorun olduğunu biliyorsunuz, bu nedenle ilk durumda olduğu gibi aynı işlemi yapıyorsunuz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.