2009-10-26 30 views
5

Estoy tratando de eliminar más de 10000 archivos a la vez, atómicamente p. Ej. o bien todos deben eliminarse de una vez, o bien todos deben permanecer en su lugar.Eliminar atómico para grandes cantidades de archivos

Por supuesto, la respuesta obvia es mover todos los archivos a un directorio temporal y eliminarlo recursivamente si tiene éxito, pero eso duplica la cantidad de E/S requerida.

La compresión no funciona, porque 1) No sé qué archivos deberán eliminarse, y 2) los archivos deben editarse con frecuencia.

¿Hay algo por ahí que pueda ayudar a reducir el costo de E/S? Cualquier plataforma servirá.

EDITAR: supongamos que puede producirse un corte de energía en cualquier momento.

Respuesta

13

Kibbee es correcto: usted está buscando una transacción. Sin embargo, no necesita depender de las bases de datos ni de las características especiales del sistema de archivos si no lo desea. La esencia de una transacción es la siguiente:

  1. Escriba un registro en un archivo especial (a menudo denominado "registro") que enumera los archivos que va a eliminar.
  2. Una vez que este registro esté escrito con seguridad, asegúrese de que su aplicación actúe como si los archivos realmente se hubieran eliminado.
  3. Más tarde, comience a eliminar los archivos nombrados en el registro de la transacción.
  4. Después de eliminar todos los archivos, elimine el registro de la transacción.

Tenga en cuenta que, en cualquier momento después del paso (1), puede reiniciar su aplicación y continuará eliminando los archivos eliminados lógicamente hasta que finalmente se hayan ido.

Tenga en cuenta que no debe seguir este camino muy lejos: de lo contrario, está empezando a volver a implementar un sistema de transacción real. Sin embargo, si solo necesita unas pocas transacciones simples, el enfoque de "rodar por su cuenta" podría ser aceptable.

+1

+1: Marcar para eliminar; dejar de usar. La eliminación física puede ocurrir en cualquier momento después de eso. –

+0

¿Qué sucede si ocurre algo que hace que uno de los archivos no se pueda recuperar, como uno de los que está siendo utilizado por otro proceso? Podrías esperar a que se liberara, pero eso podría llevar un tiempo. ¿Cómo retrocedería en el caso de que no todo se pudiera eliminar? – Kibbee

+0

Esto es exactamente lo que necesito. +1 por "¿Por qué no pensé en eso?" –

2

En lugar de mover los archivos, cree enlaces simbólicos en el directorio temporal. Luego, si todo está bien, elimina los archivos. O bien, solo haga una lista de los archivos en algún lugar y luego elimínelos.

5

Creo que lo que realmente está buscando es la capacidad de tener una transacción. Como el disco solo puede escribir un sector a la vez, solo puede eliminar los archivos de a uno por vez. Lo que necesita es la capacidad de deshacer las eliminaciones anteriores si una de las eliminaciones no se realiza correctamente. Las tareas como esta generalmente se reservan para bases de datos. Si su sistema de archivos puede o no hacer transacciones depende de qué sistema de archivos y sistema operativo esté utilizando. NTFS en Windows Vista admite Transactional NTFS. No estoy muy seguro de cómo funciona, pero podría ser útil.

Además, hay algo llamado shadow copy para Windows, que en el mundo de Linux se llama LVM Snapshot. Básicamente es una instantánea del disco en un punto en el tiempo. Puede tomar una instantánea directamente antes de realizar la eliminación, y en caso de que no sea exitosa, copie los archivos de la instantánea. Creé instantáneas usando WMI en VBScript, estoy seguro de que también existen apis similares para C/C++.

Una cosa sobre Shadow Copy y LVM Snapsots. El trabajo en toda la partición. Entonces no puedes tomar una instantánea de un solo directorio. Sin embargo, tomar una instantánea de todo el disco tarda solo un par de segundos. Entonces tomarías una instantánea. Borre los archivos y luego, si no es exitoso, copie los archivos nuevamente fuera de la instantánea. Esto sería lento, pero dependiendo de la frecuencia con la que planeas retroceder, podría ser aceptable. La otra idea sería restaurar toda la instantánea. Esto puede o no ser bueno ya que revertiría todos los cambios en todo el disco. No es bueno si su sistema operativo u otros archivos importantes se encuentran allí. Si esta partición solo contiene los archivos que desea eliminar, la recuperación de la instantánea completa puede ser más fácil y rápida.

6

En * nix, mover archivos dentro de un solo sistema de archivos es una operación de muy bajo costo, funciona haciendo un enlace fijo al nuevo nombre y luego desvinculando el archivo original. Ni siquiera cambia ninguno de los tiempos de archivo.

Si pudieras mover los archivos a un único directorio, podrías renombrar ese directorio para sacarlo del camino como una verdadera operación atómica, y luego eliminar los archivos (y el directorio) más tarde de una manera más lenta, no- moda atómica

¿Estás seguro de que no solo quieres una base de datos? Todos ellos tienen compromiso de transacción y retrotracción incorporados.

+0

¿Por qué crees que mudarte es más barato que eliminar? –

+0

Como no sé con anticipación qué archivos se eliminarán, este enfoque es aún más costoso que el mío por un directorio de renombrado. Sin embargo sería bueno. –

+2

@ralu: todos los sistemas de transacción lo hacen es registrar la intención e identificar y coordinar el punto de no retorno, antes de hacer cualquier cosa que no se puede revertir. Intentaba invocar un enfoque transaccional para eliminar archivos. Tiene más gastos generales que simplemente deshacerse con 'unlink (2)', pero ese es el precio de tener una transacción. Sin embargo, debería haberlo dicho. – DigitalRoss

1

Creo que el método de copiar y eliminar es prácticamente la manera estándar de hacerlo. ¿Sabe con certeza que no puede tolerar la E/S adicional?

No me consideraría una exportación en los sistemas de archivos, pero me imagino que cualquier implementación para realizar una transacción necesitaría primero intentar realizar todas las acciones deseadas, y luego tendría que volver atrás y comprometerse esas acciones. ES DECIR. no puede evitar realizar más E/S que hacerlo de forma no atómica.

1

¿Tiene una capa de abstracción (por ejemplo, una base de datos) para acceder a los archivos? (Si su software va directamente al sistema de archivos, entonces mi propuesta no se aplica).

Si la condición es "correcta" para eliminar los archivos, cambie el estado a "eliminado" en su capa de abstracción y comience un trabajo en segundo plano para "realmente" eliminarlos del sistema de archivos.

Por supuesto, esta propuesta incurre en un cierto coste en la apertura/cierre de los archivos, sino que ahorra algo de E/S en la creación de enlaces simbólicos, etc.

2

¿No podrías construir la lista de nombres de ruta a borrar, escribir este enumere en un archivo to_be_deleted.log, asegúrese de que el archivo haya tocado el disco (fsync()), luego comience a hacer las eliminaciones. Después de que se hayan realizado todas las eliminaciones, elimine el registro de transacciones to_be_deleted.log.

Cuando inicie la aplicación, debería verificar la existencia de to_be_deleted.log, y si está allí, reproducir las eliminaciones en ese archivo (ignorando los errores "no existe").

1

En Windows Vista o posterior, Transactional NTFS debe hacer lo que necesita:

HANDLE txn = CreateTransaction(NULL, 0, 0, 0, 0, NULL /* or timeout */, TEXT("Deleting stuff")); 
if (txn == INVALID_HANDLE_VALUE) { 
    /* explode */ 
} 
if (!DeleteFileTransacted(filename, txn)) { 
    RollbackTransaction(txn); // You saw nothing. 
    CloseHandle(txn); 
    die_horribly(); 
} 
if (!CommitTransaction(txn)) { 
    CloseHandle(txn); 
    die_horribly(); 
} 
CloseHandle(txn); 
1

La respuesta básica a su pregunta es "No". La respuesta más compleja es que esto requiere el apoyo del sistema de archivos y muy pocos sistemas de archivos tienen ese tipo de soporte. Aparentemente NT tiene un FS transaccional que sí lo admite. Es posible que BtrFS para Linux sea compatible con esto también.

En ausencia de soporte directo, creo que la opción hardlink, move, remove es lo mejor que va a obtener.

Cuestiones relacionadas