You can debug this by enabling query logging.
You'll notice in the trace that this observer is firing: Mage_ConfigurableSwatches_Model_Observer::productListCollectionLoadAfter()
If you follow the trace, you'll find where things are being deleted in Mage_Catalog_Model_Resource_Product_Attribute_Backend_Media
protected function _removeDuplicates(&$result)
{
$fileToId = array();
foreach (array_keys($result) as $index) {
if (!isset($fileToId[$result[$index]['file']])) {
$fileToId[$result[$index]['file']] = $result[$index]['value_id'];
} elseif ($fileToId[$result[$index]['file']] != $result[$index]['value_id']) {
$this->deleteGallery($result[$index]['value_id']);
unset($result[$index]);
}
}
$result = array_values($result);
return $this;
}
public function deleteGallery($valueId)
{
if (is_array($valueId) && count($valueId)>0) {
$condition = $this->_getWriteAdapter()->quoteInto('value_id IN(?) ', $valueId);
} elseif (!is_array($valueId)) {
$condition = $this->_getWriteAdapter()->quoteInto('value_id = ? ', $valueId);
} else {
return $this;
}
$this->_getWriteAdapter()->delete($this->getMainTable(), $condition);
return $this;
}
It seems that when you enable configurable swatches (it may happen all the time, but I'm only noticing it when using built in configurable swatches), Magento will try to self-clean any duplicate images it finds with your products. Pretty stupid feature if you ask me.
One solution would be to rewrite the function to something like
protected function _removeDuplicates(&$result)
{
$fileToId = array();
foreach (array_keys($result) as $index) {
if (!isset($fileToId[$result[$index]['file']])) {
$fileToId[$result[$index]['file']] = $result[$index]['value_id'];
} elseif ($fileToId[$result[$index]['file']] != $result[$index]['value_id']) {
# Don't actually delete from the DB, just don't show on frontend
# $this->deleteGallery($result[$index]['value_id']);
unset($result[$index]);
}
}
$result = array_values($result);
return $this;
}