2010-07-02 17 views
11

Estamos usando un File.Copy simple en C# para mover nuestras copias de seguridad de la base de datos a ubicaciones adicionales.Limite la velocidad de File.Copy

Sin embargo, en algunos servidores, esto hace que el servidor SQL prácticamente deje de funcionar. Estos servidores tienen memoria muy limitada, por lo que están enviando datos al disco duro de vez en cuando.

Mientras que debe comprar más memoria, esto no va a suceder durante mucho tiempo: -/

Así que me pregunto si de alguna manera puedo limitar la velocidad de la operación File.Copy? (De este modo, le da al servidor SQL un espacio para acceder al disco duro)

Podría utilizar un enfoque de "escuela vieja" con dos flujos, leyendo y escribiendo a través de un búfer, y simplemente duermo aproximadamente 5 ms entre lecturas. Pero realmente preferiría una solución más ordenada, si tal una está disponible.

+0

¿Desea limitar la velocidad o, de hecho, la huella de memoria? – Frank

+0

¿Ha intentado ejecutar el código de Copia en un hilo con 'prioridad mínima'? Sin embargo, no estoy seguro si ayudará ya que usa la función kernel32 'CopyFile'. –

+0

Simplemente no realice la copia de seguridad en la misma unidad que está utilizando SQL Server para su dbase. –

Respuesta

7

CopyFileEx podría hacer lo que tiene - que tiene una función de devolución de llamada que se puede utilizar como un slowing method artificial (no hemos probado que para este escenario, aunque así que no estoy seguro acerca de los efectos reales, vale la pena intentarlo en mi humilde opinión).

+0

Podría intentarlo - Veré si MSDN tiene más información sobre la devolución de llamada (con qué frecuencia se llama así sucesivamente) – Steffen

+1

Debería ser mucho más rápido que usar transmisiones C#. El búfer es ** 65536B ** en WXP (la notificación se produce cuando se copia el fragmento). En Vista y W7 es más grande. También puede copiar el archivo solo en 1 máquina y replicar el archivo desde allí a otras ubicaciones de respaldo. –

+0

Suena bien, mi principal preocupación con las transmisiones es, de hecho, el rendimiento en comparación con una función API nativa (que también es File.Copy: CopyFile) Lo veré el martes, ya que no puedo obtener para trabajar en ello antes. – Steffen

2

¿Ha intentado darle a su proceso de copia una prioridad por debajo de lo normal? Puede hacerlo a través del Administrador de tareas o mediante el comando start:

> start myCopyApp.exe /BELOWNORMAL 
+3

Eso funcionará si el sistema está vinculado a la CPU, pero quizás no si está vinculado a E/S? – ChrisW

+0

Como el OP dice 'Estos servidores tienen memoria muy limitada', supongo que no es ninguno de estos, sino una restricción de memoria. – Frank

+0

@Frank Creo que la restricción de memoria provoca el acceso al disco (al archivo de intercambio) y, por lo tanto, es equivalente a estar vinculado a E/S. – ChrisW

2

Uno no está disponible a través de File.Copy. Usted tiene una cantidad de otras opciones. Puedes, como dices, transmitir los bytes manualmente, ocasionalmente durmiendo. Podría usar una implementación de BITS, aunque esto es un poco OTT.

Además, si el problema es la memoria, comprima el archivo o escúpelo en archivos más pequeños para reconstruirlo más tarde.

+1

Nota: para SQL Server 2008+ puede habilitar la compresión de copias de seguridad en la página "Copia de seguridad de la base de datos". –

+0

Buena llamada con compresión, sin embargo estos todavía están trabajados con SQL Server 2005 :-( – Steffen

1

Podría utilizar un enfoque de "vieja escuela" con dos flujos, leyendo y escribiendo a través de un búfer, y simplemente dormiría 5 ms o más entre lecturas.

Si lo hace, buscar en el uso de la bandera FILE_FLAG_NO_BUFFERING: de lo contrario, no importa cuán pequeño sea su tampón de aplicación es, el sistema de archivos será buffering (y por lo tanto haciendo que el intercambio adicional).

+1

Dado que la memoria intermedia se usaría MUCHO, Windows * no debería * intercambiar esa parte de la memoria (+ tiene una huella de memoria bastante pequeña) sino intercambiar otras partes (menos usadas) de la memoria Además, las operaciones de IO de la CPU y del disco aumentarían significativamente. –

+0

@Jaroslav Jandek - FILE_FLAG_NO_BUFFERING en los archivos de entrada y salida afectaría/deshabilitaría el almacenamiento en búfer (por ejemplo, almacenamiento intermedio de lectura anticipada) que de otro modo sería ejecutado implícitamente en/por el controlador del sistema de archivos. Sugiero que este almacenamiento en búfer debe deshabilitarse, porque tener este sistema de almacenamiento en búfer habilitado (que es por defecto) toma memoria y por lo tanto causa intercambio, y ni siquiera lo necesita (porque una copia de archivo solo quiere tocar cada parte del archivo una vez). – ChrisW

+0

@ChrisW: Necesita leer los datos alguna vez re (a un búfer) y luego escriba en un archivo (que puede ser sin búfer - escritura directa). Si la operación no fuera secuencial, se desperdiciará el buffer. En este caso, se requiere sin importar qué. Para copiar, ese enfoque es inútil ya que el sistema ya lo hace de manera efectiva (si estuviera haciendo ReadFile y WriteFile manualmente, sería diferente). También requeriría mucho manejo de WINAPI y corregir los tamaños de búfer y la alineación, en gran parte de los sectores del sistema de archivos ... –

Cuestiones relacionadas