2010-11-24 12 views
9

En mi entorno de producción hemos tenido lo que creemos que es un hash almacenable corrupto, creado por Storable.pm. No puedo replicar el comportamiento en Dev, lo que ha dificultado el diagnóstico exacto.Storable.pm - corrupto al guardar en un archivo no truncado

El código ha estado funcionando durante mucho tiempo, y el cambio que lo hizo se estaba eliminando del hash. Hasta hace poco, el hash se mantenía del mismo tamaño o crecía.

El archivo se abre en readwrite, y luego store_fd escribe en el archivo. Como el hash es ahora (a veces) más pequeño, escribirá, digamos, 1000bytes en este archivo de 2000 bytes. Los 1000 bytes de la cola son viejos, datos basura. En mis casos de prueba , cuando recupero el hash, se ignoran los datos basura, como se esperaba .

open($sf, "+< $self->{mod_state_filename}"); 
flock($sf, LOCK_EX); 
$self->{mod_state} = fd_retrieve($sf); 
delete ($self->{mod_state}{"somekey"}); 
seek($sf, 0, 0); 
store_fd($self->{mod_state}, $sf); 
flock($sf, LOCK_UN) 
close($sf); 

Mis preguntas:

  1. caso de este trabajo, o ¿es imperativo que truncan el archivo?
  2. ¿El hash almacenado utiliza algún tipo de carácter de terminador de archivo? Si es así, ¿de qué se trata?
  3. El código anterior, eliminar y agregar y eliminar y agregar, funciona perfectamente en mi caso de prueba. ¿Puede sugerir alguna secuencia de caso de prueba que pueda causar un error, debido a el archivo no truncado? (Sé que este es una pregunta muy vaga, así que sienta libre de ignorarlo).
+2

¿Por qué no utiliza las funciones almacenadas y recuperadas de almacenables? Storable también admite el bloqueo http://search.cpan.org/~ams/Storable-2.24/Storable.pm#ADVISORY_LOCKING – singingfish

+0

Sé que sí, pero no escribí el código. Fue de esta manera (a excepción de la eliminación) años antes de que lo heredé. Consideraría cambiar el código para usar Storable :: locking, pero no tengo idea de si lo solucionará (y sospecho que probablemente no). (Podría intentarlo, pero el problema solo aparece en producción, así que necesito estar seguro de la solución. No puedo probar y error). No creo que mi problema se deba al bloqueo. – Brock

Respuesta

1

no sé qué tan bien Storable trata de arrastre de basura, pero seguramente no puede hacer daño a añadir

truncate $sf, tell($sf); 

después de la llamada a store_fd, eliminando toda duda acerca de si se puede hacer frente a ahora y en el futuro.

+0

Peter, no me llames Shirley. Estoy de acuerdo, pero primero quería confirmarlo en condiciones de prueba, de ahí la pregunta. – Brock

0

Disculpa, creí haber actualizado esto.

Le pregunté a perl5-porters, y obtuve las respuestas a la pregunta.

No he implementado la corrección, ya que no puedo replicar bajo prueba, así que no quiero presionar a mi entorno de producción, mi trabajo es más seguro por el momento.

Truncar definitivamente es una buena idea, basado en las respuestas de perl5-porters.

No sabía que alguien tuviera (¡o pudiera!) Ponerle una recompensa a mi pregunta.

Cuestiones relacionadas