توسعه دهندگان OrioleDB وضعیت فعلی API سطح پایین مورد استفاده برای برنامه های افزودنی برای دسترسی به جداول و نمایه ها در PostgreSQL (API روش دسترسی جدول/ایندکس (AM)) را تجزیه و تحلیل کردند و راه هایی برای بهبود آن پیشنهاد کردند. از زمان معرفی چنین API در PostgreSQL 12، توسعه دهندگان توانسته اند مکانیسم های ذخیره سازی داده های جایگزین ایجاد کنند. با این حال، علیرغم وجود این API و محدودیت های شناخته شده موتور ذخیره سازی داخلی، هنوز هیچ موتور ذخیره سازی تراکنشی کاملاً کاربردی وجود ندارد که صرفاً به عنوان افزونه پیاده سازی شود.
محبوب ترین ویژگی های موتورهای جدول جایگزین PostgreSQL عبارتند از:
- پیاده سازی های جایگزین MVCC، مانند فروشگاه های مبتنی بر گزارش UNDO.
- جداول سازماندهی شده با نمایه، که در آن ایندکس یک اضافه اختیاری به جدول نیست که پرس و جوها را سرعت می بخشد، بلکه ساختار داده اولیه است که داده های جدول در آن ذخیره می شود.
تغییرات مورد نیاز در Table/Index AM API برای پشتیبانی از پیادهسازیهای جایگزین MVCC با توجه به پسوند OrioleDB مورد بحث قرار میگیرد، که برای رفع کاستیهای شناخته شده موتور ذخیرهسازی داخلی PostgreSQL طراحی شده است. مشکل این است که ادغام کامل OrioleDB با PostgreSQL به تغییراتی در کد PostgreSQL نیاز دارد که اجرای پروژه را پیچیده می کند و نیاز به مدرن سازی Table AM API فعلی را برجسته می کند.
API Table AM به طور مستقیم نحوه اجرای MVCC را تعیین نمی کند. با این حال، Table AM API و Index AM API فرض زیر را دارند: هر TID (Tuple/row Identifier) یا توسط همه ایندکس ها ایندکس می شود یا اصلا ایندکس نمی شود. حتی اگر Index AM چندین ارجاع به یک TID واحد داشته باشد (مثلاً GIN)، همه این ارجاعات باید به همان مقدار نمایه شده نگاشت شوند.

این اصل به دلیل افزایش تعداد عملیات نوشتن ("تقویت نوشتن") مورد انتقاد قرار گرفته است - اگر یک ویژگی ایندکس شده به روز شود، هر شاخص در جدول باید به روز شود. اگر میخواهید از فهرست UNDO نهایت استفاده را ببرید، یا روش ذخیرهسازی دیگری بدون «تقویت نوشتن» بسازید (مانند روش WARM)، باید این فرض را زیر پا بگذارید.

یک جدول AM مبتنی بر UNDO که این فرض را نقض نمیکند، شبیه روش HOT (فقط Heap-Only Tuples) است، با این تفاوت که نسخههای ردیف قدیمی در گزارش UNDO ذخیره میشوند و لازم نیست در همان صفحه قرار بگیرند. اما، به گفته نویسندگان، این مزیت برای توجیه وجود جدول AM جداگانه کافی نیست.
محدودیت های عملی API موجود:
- هنگامی که یک ردیف جدول به روز می شود، نمایه ها بر اساس همه یا هیچ به روز می شوند.
- Index AM API توانایی حذف انتخابی تاپل های خاص را ندارد. در حال حاضر با استفاده از روشهای ambulkdelete و amvacuumcleanup میتوان تاپلها را از فهرستها به صورت انبوه حذف کرد. تلاش برای پیادهسازی حذفهای نقطهای از طریق این API منجر به راندمان پایین میشود، زیرا اکثر پیادهسازیهای فعلی باید کل فهرست را اسکن کنند. علاوه بر این، API به شما اجازه نمی دهد که مشخص کنید کدام تاپل هایی که به یک TID ارجاع می دهند باید حذف شوند. او فقط می تواند همه آنها را حذف کند.
- نمایه ها در حال حاضر به ردیف های جدول بر اساس شماره بلوک (32 بیت) و شماره افست (16 بیت) اشاره می کنند. و تنها 11 بیت از عدد افست را می توان با خیال راحت از TID جدول به همه روش های دسترسی به فهرست منتقل کرد. با این حال، پیاده سازی های جایگزین MVCC ممکن است نیاز به ذخیره بار اضافی همراه با TID داشته باشند. به عنوان مثال، OrioleDB به یک یا چند بیت برای پیادهسازی شاخصهای «حذف علامتگذاری» یا اطلاعات قابل مشاهده کامل نیاز دارد.
دو راه برای غلبه بر محدودیت ها در عمل پیشنهاد شده است:
رویکرد 1: Index AM API گزینه هایی را برای اجرای جایگزین MVCC فراهم می کند.
در حالی که Table AM همچنان مسئول تمام اجزای MVCC است، Index AM قابلیت های لازم را برای اجرای جایگزین MVCC فراهم می کند، یعنی: ذخیره یک بار کاربر همراه با TID، یک روش حذف نقطه، و حتی یک روش به روز رسانی نقطه (اگر TID در ایندکس قابل تغییر نباشد، بار کاربر می تواند). علاوه بر این، از آنجایی که چندین تاپل ایندکس باید اجازه داشته باشند تا به یک TID یکسان ارجاع دهند، روشهای API مورد استفاده در طول اسکن فهرست نیز باید بهروزرسانی شوند.
رویکرد 2: شاخص های آگاه از MVCC.
یک جایگزین، اجازه دادن به شاخص هایی است که از MVCC پشتیبانی می کنند. به این معنا که "اجرا" (یا شاید جدول AM) به سادگی متدهای insert() و delete() را در Index AM فراخوانی می کند، در حالی که Index AM قابلیت های اسکن MVCC-aware را ارائه می دهد. این اسکن فقط فهرست را بسیار آسان تر می کند. حتی کل Table AM میتواند به یک لایه میانی تبدیل شود که دادهها را در یک فهرست ذخیره میکند.
نمودار زیر یک مثال را نشان می دهد. ارزش شاخص 2 توسط تراکنش 11 از مقدار "A" به مقدار "B" به روز می شود. بنابراین، مقدار "A" به عنوان xmax == 11، و مقدار "B" به عنوان xmin == 11 علامت گذاری می شود. به این ترتیب، شاخص 2 را می توان اسکن کرد و فقط تاپل های قابل مشاهده را می توان مطابق با MVCC بدون بررسی هیپ بازیابی کرد. جمع آوری زباله های شاخص 2 نیز می تواند بدون استفاده از هیپ انجام شود.

با همه نوآوریهای بالا در API روشهای دسترسی به فهرست، بعید است که همه فهرستها بتوانند به طور همزمان برای پشتیبانی از همه ویژگیهای جدید بهروزرسانی شوند. اجازه دادن به پیاده سازی های متعدد برای یک روش دسترسی به فهرست، واقعی تر است. به عنوان مثال، علاوه بر درخت B معمولی، افزونه قادر خواهد بود یک درخت B جایگزین را با پشتیبانی از MVCC در داخل شاخص و پشتیبانی از شناسههای رکورد با طول دلخواه پیادهسازی کند.

بنابراین، پیشنهاد میشود که نه تنها Table AM API، بلکه Index AM API نیز بازنگری شود، که برای سالها به جامعه PostgreSQL خدمت کرده است. علاوه بر این، پیشنهاد شده است که Index AM به یک لایه منطقی و یک لایه پیاده سازی تقسیم شود. این معماری مجدداً به PostgreSQL اجازه می دهد تا از چندین مدل ذخیره سازی پشتیبانی کند.
منبع: opennet.ru
