2010-07-02 6 views
11

Мы используем простой файл File.Copy в C# для перемещения резервных копий базы данных в дополнительные места.Предельная скорость File.Copy

Однако на некоторых серверах сервер SQL практически не работает. Эти серверы имеют очень ограниченную память, поэтому они часто выгружают данные на жесткий диск.

Хотя мы должны купить больше памяти, это не произойдет в течение длительного времени: -/

Так мне интересно, если я могу каким-то образом ограничить скорость работы File.Copy? (Таким образом, предоставление SQL-серверу некоторого места для доступа к жесткому диску)

Я мог бы использовать подход «старой школы» с двумя потоками, читать и писать через буфер и просто спать 5 мс или около того между чтениями. Но я бы предпочел более качественное решение, если таковое доступно.

+0

Вы хотите ограничить скорость или, по сути, область памяти? – Frank

+0

Вы пробовали использовать код копирования в потоке с минимальным приоритетом? Не уверен, что это поможет, хотя он использует функцию kernel32 'CopyFile'. –

+0

Просто не делайте резервное копирование на тот же диск, что и один SQL Server для своей базы данных. –

ответ

7

CopyFileEx может делать то, что вам нужно - это имеет функцию обратного вызова, который можно использовать в качестве искусственного slowing method (не пробовал, что для этого сценария, хотя поэтому я не уверен в реальных эффектах - стоит попробовать ИМХО).

+0

Я могу сказать, что go - я посмотрю, есть ли в MSDN более подробная информация о обратном вызове (как часто это называется так далее) – Steffen

+1

Это должно быть быстрее, чем использование потоков C#. Буфер ** 65536B ** на WXP (уведомление происходит при копировании фрагмента). В Vista и W7 он больше. Вы также можете скопировать файл только на 1 машину и реплицировать файл оттуда в другие места резервного копирования. –

+0

Звучит неплохо, моя основная забота о потоках - это, по сути, его производительность по сравнению с встроенной функцией API (которая также является File.Copy: CopyFile) Я проверю это во вторник, так как я не могу получить работать на нем раньше. – Steffen

2

Вы пытались предоставить свой процесс копирования приоритет ниже обычного? Вы можете сделать это с помощью диспетчера задач или с помощью команды: start

> start myCopyApp.exe /BELOWNORMAL 
+3

Это будет работать, если система связана с CPU, но, возможно, если он связан с I/O? – ChrisW

+0

Как утверждает OP: «Эти серверы имеют очень ограниченную память», я бы предположил, что это ни одно из них, а ограничение памяти. – Frank

+0

@Frank Я думаю, что ограничение памяти вызывает доступ к диску (в файл подкачки) и поэтому эквивалентно привязке к I/O. – ChrisW

2

Один из них недоступен через File.Copy. У вас есть ряд других вариантов. Вы можете, как вы говорите, передавать байты вручную, иногда спать. Вы можете использовать реализацию BITS, хотя это немного OTT.

Кроме того, если проблема в памяти - скомпилируйте файл или скопируйте его в файлы меньшего размера, которые нужно перестроить позже.

+1

Примечание: для SQL Server 2008+ вы можете включить сжатие резервных копий на странице «База данных резервного копирования». –

+0

Хороший вызов с сжатием, однако они все еще застряли с SQL Server 2005 :-( – Steffen

1

Я мог бы использовать подход «старой школы» с двумя потоками, чтение и запись через буфер и просто спящий 5 мс между чтениями.

Если вы посмотрите на использовании флага FILE_FLAG_NO_BUFFERING: в противном случае, независимо от того, насколько мал ваш буфер приложение, файловая система не будет буферизации (и, следовательно, вызывает дополнительную замену).

+1

Поскольку буферная память будет использоваться LOT, Windows * должна * не менять эту часть памяти (+ имеет довольно небольшой объем памяти), но вместо этого Кроме того, операции ввода-вывода ЦП и диска значительно повысились. –

+0

@Jaroslav Jandek - FILE_FLAG_NO_BUFFERING на входных и выходных файлах повлияет на/исключить буферизацию (например, буферизацию с предварительным считыванием), которая в противном случае была бы выполняется неявно внутри/с помощью драйвера файловой системы. Я предполагаю, что эта буферизация должна быть отключена, поскольку включение этой буферизации файловой системы (по умолчанию она) занимает память и, следовательно, вызывает обмен, и он даже не нуждается в ней (потому что копия файла только хочет коснуться каждой части файла один раз). – ChrisW

+0

@ChrisW: вам нужно прочитать данные re (в буфер), а затем записать в файл (который может быть небуферизован - прямая запись). Если операция не будет последовательной, буфер будет потрачен впустую. В этом случае это необходимо независимо от того, что. Для копирования этот подход бесполезен, так как система уже делает это эффективно (если вы делали ReadFile и WriteFile вручную, это было бы иначе). Также потребуется много обработки WINAPI и правильности размеров буфера и выравнивания для многих секторов файловой системы ... –

Смежные вопросы