Одной из основных особенностей базы данных является то, что процессы видят ее последовательно. Это также означает, что разные клиенты видят разные состояния базы данных.
Это означает, что когда вы исправляете путь к файлу в базе данных и фиксируете изменение, любые транзакции, начатые до принятия, могут видеть старый путь в течение некоторого времени после принятия.
Таким образом, чтобы убедиться, что никто не будет пытаться прочитать старый путь к файлу, нужно дождаться завершения всех транзакций, прежде чем завершится фиксация. Это может занять миллисекунды или, в экстремальных ситуациях, дни. Если у вас есть
Я бы попробовал реализовать следующую схему (псевдокод):
sql("begin")
os.hardlink(old_path, new_path)
sql("update files set path=? where path=?, new_path, old_path)
sql("insert into files_to_clean values (?, txid_current())", old_path)
sql("commit")
if random()<CLEANUP_PROBABILITY:
sql("begin")
for delete_path in sql("
delete from files_to_clean
where txid<txid_snapshot_xmin(txid_current_snapshot())
returning path skip locked
"):
os.delete(delete_path)
sql("commit")