Michał Płonka

Michał Płonka Programista PHP

Temat: Usuwanie rekordów, które ich nie usuwa

Witam,
mam dość dziwną sytuację. W tabeli mam ok. 1,7mln rekordów. Potrzebuję usuwać te rekordy, które są starsze niż 3 miesiące. Żaden problem! Najpierw napisałem bezpieczne zapytanie, które ustawi flagę is_deleted dla wybranych rekordów, żeby nie usunąć czegoś za dużo. Następnego dnia (zadanie uruchamiane w CRONie) sprawdziłem i zdecydowana większość rekordów została oznaczona jako te do usunięcia. Zmieniłem więc UPDATE na DELETE, sprawdziłem dziś - liczba rekordów się nie zmieniła. Zdziwiło mnie to, ale uruchomiłem zadanie ręcznie. Mieliło i mieliło, w końcu skończyło. SELECT COUNT(id) - znowu tyle samo rekordów. Zrobiłem dla pewności jeszcze VACUUM ANALYZE, po czym ponownie sprawdziłem ilość rekordów - bez zmian. Odpaliłem zapytanie z poziomu PgAdmina, znowu odczekałem ładne -naście minut, znowu wykonałem zliczenie rekordów i znowu bez zmian! Co może być przyczyną nie usuwania się rekordów?

Dodam, że:
- nie, nie ma na tabeli triggera zabezpieczającego przed usunięciem danych,
- tak, zapytanie usuwające na pewno jest poprawne.

Pozdrawiam,
Michał

konto usunięte

Temat: Usuwanie rekordów, które ich nie usuwa

Pokaż strukturę tej tabeli i zapytanie.

Przyczyną nieusuwania rekordów może być trigger (ale mówisz, że go nie ma) może być reguła, albo niepoprawne zapytanie.

A co do Crona, sprawdź logi, może jednak zapytanie odpalone z Crona nie było OK, albo się nie odpaliło, albo był inny błąd jakiś? Czy na pewno Cron się podłączył do dobrej bazy?

Stawiam jednak na to, że czary to nie są, najprawdopodobniej jakiś głupi błąd :)
Michał Płonka

Michał Płonka Programista PHP

Temat: Usuwanie rekordów, które ich nie usuwa

Dzięki za odpowiedź. Więc po kolei:

1. Struktury tabeli nie mogę pokazać. Samo zapytanie wygląda tak:
DELETE FROM tabela WHERE kolumna < 1323845895;

gdzie kolumna to kolumna typu BIGINT (taką bazę zastałem).
2. Triggera nie ma.
3. Reguł nie ma.
4. Zadanie z CRONa nawet jeśli się nie odpaliło to uruchomiłem je ręcznie, a potem sam wykonałem zapytanie na bazie. Zadanie CRON na pewno podłącza się pod dobrą bazę.

Teraz się zastanawiam, czy przypadkiem problemem nie jest założone na kluczach obcych ON DELETE NO ACTION zamiast CASCADE.

// Sprawdziłem teraz trop ON DELETE zakładając nową tabelę i przy próbie usunięcia rekordów otrzymuję błąd:
ERROR:  update or delete on table "test1" violates foreign key constraint "fk_test2_test1_id" on table "test2"

którego nie otrzymuję podczas wykonywania tego właściwego zapytania.

To chyba jednak to. Muszę przejrzeć całą strukturę bazy i pozmieniać relacje na CASCADE :/Michał Płonka edytował(a) ten post dnia 14.03.12 o godzinie 17:54

konto usunięte

Temat: Usuwanie rekordów, które ich nie usuwa

A czy dostajesz w ogóle cokolwiek jak zapytasz o coś takiego:


SELECT count(*) FROM tabela WHERE kolumna < 1323845895;
Michał Płonka

Michał Płonka Programista PHP

Temat: Usuwanie rekordów, które ich nie usuwa

Tak, dostaję. Jak pisałem: w dniu wczorajszym zamiast usuwać rekordy zmieniłem im flagę oznaczając je jako "te rekordy zostałyby usunięte". Przerobiłem aktualizację na usuwanie i klops. Teraz sprawdzam zachowanie po zmianach w relacji, ale najprawdopodobniej w tym był problem. Tak więc dzięki za nakierowanie mnie prośbą o podanie struktury tabeli bo przyznam, że nie domyśliłem się, że relacje ktoś mógł założyć z NO ACTION.

konto usunięte

Temat: Usuwanie rekordów, które ich nie usuwa

DELETE FROM tabela WHERE IS_DELETED = 1


a takie cuś? wiem że trywialne, ale może mu się cast nie podoba albo go robi źle?

@edit
w sumie może być bez przyrównania o ile to booleanPrzemek Czekaj edytował(a) ten post dnia 15.03.12 o godzinie 13:06
Michał Płonka

Michał Płonka Programista PHP

Temat: Usuwanie rekordów, które ich nie usuwa

Problem leżał w więzach integralności. Usunąłem dotychczasowe (NO ACTION) i zastąpiłem je CASCADE. Wczoraj przed 18 uruchomiłem kasowanie rekordów i widzę, że do tej pory zapytanie wisi (w PgAdmin: Narzędzia -> Status serwera). Trochę niepokoi mnie dlaczego wykonuje się to tak długo...

// Edit:
Na kolumnie, która jest porównywana w warunku jest założony indeks.Michał Płonka edytował(a) ten post dnia 15.03.12 o godzinie 17:17

konto usunięte

Temat: Usuwanie rekordów, które ich nie usuwa

Michał Płonka:
Problem leżał w więzach integralności. Usunąłem dotychczasowe (NO ACTION) i zastąpiłem je CASCADE. Wczoraj przed 18 uruchomiłem kasowanie rekordów i widzę, że do tej pory zapytanie wisi (w PgAdmin: Narzędzia -> Status serwera). Trochę niepokoi mnie dlaczego wykonuje się to tak długo...

// Edit:
Na kolumnie, która jest porównywana w warunku jest założony indeks.

To zobacz co się dzieje.
 SELECT * FROM pg_stat_activity;
W kolumnie current_query powinno być Twoje zapytanie. W kolumnie waiting bedzie informacja czy wisi na jakimś locku czy też normalnie idzie.
Michał Płonka

Michał Płonka Programista PHP

Temat: Usuwanie rekordów, które ich nie usuwa

Podaję zrzut statusu serwera:

// usunąłem obrazek

Są tam 2 zapytania usuwające: PID=22359 zostało uruchomione przeze mnie ręcznie, PID=22283 odpalił CRON (wczoraj wyłączyłem odpalanie tego w CRONie do momentu aż się skończy). Nie wiem czy mam anulować któryś z procesów czy cierpliwie czekać na jego zakończenie.Michał Płonka edytował(a) ten post dnia 16.03.12 o godzinie 13:07

konto usunięte

Temat: Usuwanie rekordów, które ich nie usuwa

Ja nie wiem dlaczego nie zauważyłem tej informacji o foreign key, to weź ubij process (postgres to mądra bestia, nic się nie stanie [potrafi odtworzyć zapytanie nawet jak prąd padnie a ups nie wyczymał]). Jak mu zmieniłeś constraina na on delete to teraz będziesz mógł wywalić te kolumny. Z tym że utracisz spójność w bazie, nie zmieniaj od tak sobie na CASCADE bo możesz się pozbyć całej bazy, lepiej utwórz procedure w pl/pgsql w której zadbasz o zachowanie spójności danych.
Michał Płonka

Michał Płonka Programista PHP

Temat: Usuwanie rekordów, które ich nie usuwa

Klucze obce już zmieniłem przedwczoraj. W zasadzie były tylko 2 odwołania z innych tabel do tabeli, z której usuwam dane, a do nich już nie było żadnych relacji. Tak więc wraz z rekordami, które kasuję polecą tylko powiązane z nimi inne z 2 tabel. Również sądziłem, że po zmianie na CASCADE dane w końcu polecą, no ale lecą już od środy i polecieć nie chcą. Nie wiem czy ubicie procesu coś da. Wówczas zabawa zacznie się od nowa, znowu wykonam to samo zapytanie i znowu będę czekał.

konto usunięte

Temat: Usuwanie rekordów, które ich nie usuwa

Grubo, uhm twarda bestia, półtora miliona rekordów to nie jest od tak sobie do łyknięcia na raz, ale i tak za długo to mieli. To może w drugą stronę, wyciągnij pierwej klucze obce tabel powiązanych na podstawie tej kolumny is_deleted, wywal tamte rekordy z tych relacji, a później wywal rekordy na podstawie idków, które pobrałeś wyciągając klucze obce, powinno szybko łyknąć taką operację.
Michał Płonka

Michał Płonka Programista PHP

Temat: Usuwanie rekordów, które ich nie usuwa

Ok, problem rozwiązany, dane poleciały. Okazuje się, że na kluczach obcych nie było indeksów... banalne i niestety przykre, że ktoś mógł stworzyć bazę w ten sposób. Dziękuję za zainteresowanie tematem.



Wyślij zaproszenie do