PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Тези проклети големи обекти

Въведение

PostgreSQL дава на разработчиците възможността да избират между две възможни съоръжения за съхранение на големи двоични данни:Bytea и LargeObjects.

Големите обекти съществуват от дълго време и PostgreSQL има интелигентен начин за съхранение на големи двоични данни. Прави го, като го разделя на парчета LOBLKSIZE (една четвърт от BLCKSZ). По този начин кортежите от pg_largeobject не се разливат върху масата за тостове.

От друга странаbytea съхранява двоичните данни директно в кортежа, което може да доведе до лоша производителност в зависимост от това как изглежда вашата схема.

Това звучи страхотно, ако имате интелигентен интерфейс за работа с манипулирането на тези двоични файлове, особено ако актуализирането променя само малка част от целия двоичен файл.

Но обикновено не си правим труда да пишем код, който се възползва от това, а вместо това пишем отново всички двоични данни.

Едно от нещата, които според мен карат хората да приемат големи обекти, са наличните функции за импортиране и експортиране на файлове директно от сървъра на базата данни към неговата файлова система. Това има недостатък:ако приложението е на друг сървър, ще ви трябва повече код, за да преместите файла до мястото, където е необходимо.

Проблем, с който може да се сблъскате

Последните дни трябваше да разгледам база данни, използвана за съхраняване на информация за потребителски сесии от Java CAS система. Открих, че в базата данни има почти 100 милиона големи обекта, не много големи.

Прегледах потребителските таблици, проверявайки полетата, които имат oid поле и след това препращам стойностите в тези полета с pg_largeobject_metadata маса. Открих, че 96% от тези големи обекти са сираци. Това са големи обекти, които не са препращани от нито един кортеж от потребителските таблици.

По-нататъшно разследване заключи, че Hibernate не се е погрижил за прочистването на големите обекти, които е създал при изтриване или актуализиране на кортежи с oid полета. Така че генерираше голямо количество подуване, което не можеше да се почисти с прахосмукачка, а трябваше да бъде изчистено от таблицата pg_largeobjects ръчно.

В конкретния случай на базата данни CAS тази заявка служи за идентифициране на големите обекти, които все още се използват:

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

Заявката може да се използва за изключване от списъка с големи обекти, които да бъдат премахнати. Нещо като това:

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
)

Заключение

Големите обекти имат своите проблеми, точно както другите типове данни (особено когато се използват типове за съхранение на големи двоични данни). От разработчиците и администраторите на бази данни зависи да се възползват от предимствата и да смекчат минусите.

Дадохме възможна заявка за извършване на почистването, но има и хубаво разширение, което изчиства осиротелите големи обекти с тригери:Large Object Manager

Някои хора може да предпочетат да изпълняват заявка за почистване в тихи часове, вместо да изпълняват задействане при всяка АКТУАЛИЗИРАНЕ и ИЗТРИВАНЕ . На системи с много, много ниска АКТУАЛИЗИРАНЕ и/или ИЗТРИВАНЕ rate, тригер върху всяка таблица, която има oid поле, изглежда по-елегантно решение. И всяка загуба на производителност поради необходимостта от изпълнение на функцията за задействане би била излишна.

Във всеки случай големите обекти все още имат страхотни фенове, най-вероятно заради вътрешните функции, предоставени за импортиране и експортиране на двоични данни директно в локалната файлова система. С bytea обикновено използвате повече памет на нивото на приложението. Много често срещана процедура е да прочетете напълно двоичното поле в променлива и след това да го обработите.

Може да напиша нещо за използването на bytea, което използвах в една от предишните си разработки в бъдеща публикация в блога.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Актуализация на Postgresql с присъединяване

  2. Как Cosh() работи в PostgreSQL

  3. Postgresql не създава db с „createdb“ като суперпотребител, но не извежда грешки

  4. 3 начина за проверка на типа данни на колона в PostgreSQL

  5. Как да избягвате знака за въпросителен знак (?) с Spring JpaRepository