2010-07-02 28 views
11

Veritabanı yedeklerimizi ekstra konumlara taşımak için C# 'da basit bir File.Copy kullanıyoruz. Ancak bazı sunucularda bu SQL sunucusunun çalışmayı durdurmasına neden olur. Bu sunucularda çok sınırlı bellek var, bu yüzden her zaman sık sık harddrive'a veri gönderiyorlar.File.Copy'nin hız sınırı

iken biz gerektiği fazla bellek satın Bu uzun zamandır ne olacak değildir: -

/

Bir şekilde File.Copy operasyonun hızını sınırlayabilir diye merak ediyorum? (Bu sayede SQL sunucusuna harddrive'a erişmek için bir yer veriliyor)

İki akışlı bir "eski okul" yaklaşımı kullanabilirim, bir arabelle okuma ve yazma ve sadece okuma arasında 5 ms'lik bir uyku. Ama böyle bir mevcutsa gerçekten daha iyi bir çözüm tercih ederim.

+0

Hızınızı mı yoksa aslında bellek ayak izini mi sınırlamak istiyorsunuz? – Frank

+0

Kopyalama kodunu 'minimum öncelikli' olan bir iş parçasında çalıştırmayı denediniz mi? Kernel32 'CopyFile' işlevini kullandığı için yardımcı olacağından emin değil. –

+0

Sadece bir SQL Server'ın dbase için kullandığı sürücüye yedekleme yapmayın. –

cevap

7

CopyFileEx neye ihtiyacınız yapabilir - bu yapay slowing method (denemedim bu senaryo için sanki kullanabileceği bir geri arama işlevi vardır bu yüzden gerçek efektlerden emin değilim - bir denemeye değer IMHO).

+0

Ben bunu bir go - Ben MSDN geri çağırma hakkında daha fazla bilgi (ne kadar sık ​​denir) – Steffen

+1

C# akımları kullanmaktan daha hızlı olması gerekir göreceğiz. Arabellek WXP'de ** 65536B ** (yığın kopyalandığında bildirim yapılır). Vista ve W7'de daha büyüktür. Ayrıca dosyayı yalnızca 1 makineye kopyalayabilir ve dosyayı diğer yedekleme konumlarına çoğaltabilirsiniz. –

+0

İyi geliyor, akarsularla olan temel ilgim, aslında yerel API işlevine göre performans gösteriyor (File.Copy ayrıca: CopyFile) Söyleyemediğim gibi salı günü Daha önce üzerinde çalışmak. – Steffen

2

Kopyalama işleminizin normalin altında bir öncelik vermeyi denediniz mi? Görev Yöneticisi aracılığıyla bunu yapmak veya start komutunu kullanarak yapabilirsiniz:

> start myCopyApp.exe /BELOWNORMAL 
+3

Sistem CPU bağlıysa, ancak belki de çalışmıyor I/O bağlıysa? – ChrisW

+0

OP durumları 'Bu sunucularda çok sınırlı bellek var' olduğundan, bunların hiçbiri değil, bellek kısıtlaması olduğunu varsayalım. – Frank

+0

@Frank Bellek kısıtlamasının disk erişimine (takas dosyasına) neden olduğunu düşünüyorum ve bu nedenle G/Ç bağlı olmakla eşdeğerdir. – ChrisW

2

Bir dosya File.Copy aracılığıyla kullanılamaz. Bir dizi başka seçeneğiniz var. Söylediğiniz gibi, baytları manuel olarak, arada sırada uyuyabilirsiniz. Bu biraz OTT olsa, BITS'in bir uygulamasını kullanabilirsiniz.

Ayrıca, sorun bellekse - dosyayı sıkıştırın veya daha sonra yeniden oluşturulacak daha küçük dosyalara parçalayın.

+1

Not: SQL Server 2008+ için "Yedekleme Veritabanı" sayfasında yedeklerin sıkıştırılmasını etkinleştirebilirsiniz. –

+0

Sıkıştırma ile iyi bir çağrı, ancak hala SQL Server 2005 ile sıkışmış durumda :-( – Steffen

1

İki akışla "eski bir okul" yaklaşımını kullanabilirim, bir arabellekten okumak ve yazmak ve sadece okuma arasında 5 ms yatarım. Bunu yaparsanız

, FILE_FLAG_NO_BUFFERING bayrağını kullanarak bakmak aksi olursa olsun uygulama tampon ne kadar küçük, dosya sistemi (ekstra takas neden dolayısıyla ve) ara belleğe olacaktır.

+1

Arabellek bellek bir LOT kullanılacaktır, Windows * bellek * bu bellek bölümünü (+ oldukça küçük bellek ayak izi) değil diğer (daha az kullanılan) bellek bölümlerini değiştirin. Ayrıca, CPU ve disk IO işlemleri önemli ölçüde artacaktır. –

+0

@Jaroslav Jandek - FILE_FLAG_NO_BUFFERING giriş ve çıkış dosyalarında, aksi takdirde önbelleğe alma (örneğin okuma önbelleği) etkilenir/devre dışı bırakılır dosya sistemi sürücüsü tarafından dolaylı olarak gerçekleştirildi.Bu dosya sisteminin arabelleğe alınmasını etkinleştirdiğinden (ki bu varsayılan olarak) bellek aldığından ve bu nedenle değiştirilmeye neden olduğundan, bu arabelleğin devre dışı bırakılması gerektiğini öneririm. (Çünkü bir dosya kopyası sadece dosyanın her bir parçasına dokunmak ister). – ChrisW

+0

@ChrisW: Verileri bir daha okumalısınız. Yeniden (bir arabelleğe) ve sonra bir dosyaya yazabilirsiniz (bu arabelleğe alınabilir - doğrudan yazma). İşlem sıralı olmazsa, tampon boşa harcanırdı. Bu durumda ne olursa olsun gereklidir. Kopyalama için, bu yaklaşım zaten sistem zaten etkili olduğu için (çünkü ReadFile ve WriteFile elle yapıyor olsaydınız, farklı olurdu) yararsızdır. Ayrıca çok sayıda WINAPI işleme ve doğru arabellek boyutları ve hizalama gerektirir, dosya sisteminin sektörlerine kadar ... –