Въведение
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, което използвах в една от предишните си разработки в бъдеща публикация в блога.