PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Te cholerne duże obiekty

Wprowadzenie

PostgreSQL daje programistom możliwość wyboru między dwoma możliwymi możliwościami przechowywania dużych danych binarnych:Bytea i LargeObjects.

Duże obiekty istnieją od dawna, a PostgreSQL ma sprytny sposób przechowywania dużych danych binarnych. Robi to, dzieląc go na kawałki LOBLKSIZE (jedna czwarta BLCKSZ). W ten sposób krotki z pg_largeobject nie rozlewają się na stół tostowy.

Z drugiej strony bytea przechowuje dane binarne bezpośrednio w krotce, co może prowadzić do słabej wydajności w zależności od wyglądu schematu.

Brzmi to świetnie, jeśli masz inteligentny interfejs do manipulowania tymi plikami binarnymi, szczególnie jeśli aktualizacja modyfikuje tylko niewielką część całego pliku binarnego.

Ale zwykle nie zawracamy sobie głowy pisaniem kodu, który to wykorzystuje, a zamiast tego piszemy ponownie całe dane binarne.

Uważam, że jedną z rzeczy, które sprawiają, że ludzie adoptują duże obiekty, są dostępne funkcje do importowania i eksportowania plików bezpośrednio z serwera bazy danych do jego systemu plików. Jest w tym wada:jeśli aplikacja znajduje się na innym serwerze, będziesz potrzebować więcej kodu, aby przenieść plik do lokalizacji, w której jest potrzebny.

Problem, z którym możesz się zmierzyć

W ostatnich dniach musiałem zbadać bazę danych służącą do przechowywania informacji o sesjach użytkowników z systemu Java CAS. Odkryłem, że w bazie danych było prawie 100 milionów dużych obiektów, niezbyt dużych.

Przejrzałem tabele użytkowników, sprawdzając pola, które miały oid pole, a następnie odwołuję się do wartości w tych polach za pomocą pg_largeobject_metadata stół. Odkryłem, że 96% tych dużych obiektów to przedmioty osierocone. Są to duże obiekty, do których nie odwołuje się żadna krotka z tabel użytkowników.

Dalsze dochodzenie wykazało, że Hibernate nie zadbał o czyszczenie dużych obiektów, które utworzył podczas usuwania lub aktualizowania krotek z polami oid. Generował więc dużą ilość wzdęć, których nie można było usunąć przez odkurzanie, ale trzeba było je usunąć ręcznie z tabeli pg_largeobjects.

W konkretnym przypadku bazy danych CAS to zapytanie posłużyło do zidentyfikowania dużych obiektów, które są nadal w użyciu:

SELECT unnest(array[expiration_policy,
                    authentication,
                    services_granted_access_to])
       FROM public.ticketgrantingticket
UNION
SELECT unnest(array[expiration_policy, 
                    service])
       FROM public.serviceticket

Zapytanie może posłużyć do wykluczenia z listy dużych obiektów, które mają zostać usunięte. Coś takiego:

SELECT lo_unlink(pg_largeobject_metadata.oid)
       FROM pg_largeobject_metadata
       WHERE pg_largeobject_metadata.oid NOT IN (
             SELECT unnest(array[expiration_policy,
                                 authentication,
                                 services_granted_access_to])
             FROM public.ticketgrantingticket
             UNION
             SELECT unnest(array[expiration_policy, 
                                 service])
             FROM public.serviceticket
)

Wniosek

Duże obiekty mają swoje problemy, podobnie jak inne typy danych (zwłaszcza w przypadku używania typów do przechowywania dużych danych binarnych). To od programistów i administratorów baz danych zależy wykorzystanie zalet i złagodzenie wad.

Daliśmy możliwe zapytanie, aby wykonać czyszczenie, ale jest też fajne rozszerzenie, które czyści osierocone duże obiekty za pomocą wyzwalaczy:Menedżer dużych obiektów

Niektóre osoby mogą preferować uruchamianie zapytania czyszczącego w godzinach ciszy niż uruchamianie wyzwalacza przy każdej AKTUALIZACJI i USUŃ . W systemach z bardzo, bardzo niskim poziomem AKTUALIZACJI i/lub USUŃ rate, wyzwalacz nad każdą tabelą, która ma oid dziedzinie, wydaje się bardziej eleganckim rozwiązaniem. A jakakolwiek utrata wydajności spowodowana koniecznością uruchomienia funkcji wyzwalacza byłaby zbędna.

W każdym razie duże obiekty wciąż mają świetnych fanów, najprawdopodobniej ze względu na wewnętrzne funkcje importu i eksportu danych binarnych bezpośrednio do lokalnego systemu plików. W przypadku bytea zwykle zużywasz więcej pamięci w warstwie aplikacji. Jest to bardzo powszechna procedura polegająca na całkowitym wczytaniu pola binarnego do zmiennej, a następnie przetworzeniu go.

Mógłbym napisać coś o używaniu bytea, którego użyłem w jednym z moich wcześniejszych osiągnięć w przyszłym poście na blogu.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Zwróć wiersze SETOF z funkcji PostgreSQL

  2. Jak INTERSECT działa w PostgreSQL

  3. Wykonaj zapytanie o godziny pracy w PostgreSQL

  4. Wzorce i modyfikatory szablonów do formatowania liczb w PostgreSQL

  5. Scalanie wartości JSONB w PostgreSQL?