Synchronizacja bazadanych a pliki

0

Hej - przejąłem niedawno projekt w którym wersjonowanie wpisów wygląda następująco:
tworzony jest wpis w tabeli versions która ma postać: id, page_id, user_id, create_date oraz tworzony jest plik na dysku z serializowanymi danymi odpowiadającymi rekordowi o id page_id.
Wszystko działa ok wersje się zapisują i można je przywracać. Nałożone jest dodatkowo ograniczenie do 5 wersji wstecz. I tu jest problem - okazało się że skrypt napisany jest nieco wadliwie - usuwa stare wersję z bazy ale nie z dysku - w ten sposób powstała niespójność danych w bazie i na dysku. Plików wersji jest obecnie 12 mln a wpisów w bazie 2mln. Pytanie czy jest jakiś sensowny sposób no usunięcie plików z dysku których odpowiedników nie ma w bazie?

1

Ten pomysł z ręcznym trzymaniem danych na dysku to żart, tak? :|

0

Trzymanie wersji jest zrobione tak jak opisałem - póki co mechanizm musi zostać jak jest - szukam sposobu na szybkie usunięcie plików których odpowiedników nie ma w bazie

0

Jak mają się nazwy plików do atrybutów z tabeli versions? Page_ID jest nazwą pliku czy fragmentem nazwy?

0

page_id jest fragmentem nazwy pliku

0

12mln plików to jest za dużo jak na excela.

Ja bym zrobił tak:

  1. przygotował plik CSV zawierający listę plików z file systemu + informację o page_id z pliku, czyli pliku o strukturze:
scieżka absolutna do pliku,page_id
  1. Załadował plik do bazy danych do jakiejś tabeli tymczasowej o kolumnach:
file_name 
page_id
  1. Zrobił anti-joina między tabelą tymczasową i tabelą version. Tak by odfiltrować z listy plików te, dla których brakuje wpisu w bazie:
select 'rm '||file_name from tabelka_tymczasowa t where not exists (select 1 from version v where t.page_id=t.page_id);

Wynik zapytania, to tak naprawdę będzie lista komend shellowych do usuwania plików.

  1. Uruchomił wygenerowany plik:
chmod +x mojMegaSkrypt.sh
./mojMegaSkrypt.sh

Pkt. 1 pod linuxem realizuje się trywialnie, np. jednolinijkowcem:
find /proc -type f | awk -F/ '{print $0";"$NF}'

I otrzymać coś w stylu:

/proc/2510/auxv,auxv
/proc/2510/status,status
/proc/2510/personality,personality
/proc/2510/limits,limits
/proc/2510/sched,sched
/proc/2510/autogroup,autogroup
/proc/2510/comm,comm

Jak masz nazwę pliku: FOO_XYZ_<PAGE_ID>_<DATA>.html czy coś tam, to trzeba inaczej wycinać ten <PAGE_ID>. sed/awk Twoim przyjacielem.

Pkt. 3 wyprodukuje coś w stylu:

rm /proc/2510/status
rm /proc/2510/personality
rm /proc/2510/limits

Katalog /proc jest oczywiście poglądowo.

Szkic masz. Produkcyjnie zrobiłbym to inaczej ;) Do skonstruowania tej listy użyłbym perla i napisał te kilka linijek więcej. (12m plików to jednak może być nieco za dużo jak na zestaw narzędzi shellowych, np. ls wymiękał mi przy katalogach z 1 mln plików).

1 użytkowników online, w tym zalogowanych: 0, gości: 1