Els desenvolupadors d'OrioleDB van analitzar l'estat actual de l'API de baix nivell utilitzada per a les extensions per accedir a taules i índexs a PostgreSQL (API del mètode d'accés a la taula/índex (AM)) i van suggerir maneres de millorar-lo. Des de la introducció d'aquesta API a PostgreSQL 12, els desenvolupadors han estat capaços de crear mecanismes d'emmagatzematge de dades alternatius. Tanmateix, malgrat l'existència d'aquesta API i les limitacions conegudes del motor d'emmagatzematge integrat, encara no hi ha motors d'emmagatzematge transaccional totalment funcionals implementats únicament com a extensions.
Les funcions més populars per als motors de taula PostgreSQL alternatius són:
- Implementacions alternatives de MVCC, com ara botigues basades en registres UNDO.
- Taules organitzades per índex, on l'índex no és una addició opcional a la taula que accelera les consultes, sinó que és l'estructura de dades principal on s'emmagatzemen les dades de la taula.
Els canvis necessaris a l'API Table/Index AM per donar suport a implementacions alternatives de MVCC es discuteixen amb l'atenció de l'extensió OrioleDB, que es va dissenyar per abordar les deficiències conegudes del motor d'emmagatzematge PostgreSQL integrat. El problema és que la integració total d'OrioleDB amb PostgreSQL requereix canvis al codi PostgreSQL, fet que complica la implementació del projecte i posa de manifest la necessitat de modernitzar l'actual Table AM API.
La taula AM API no dicta directament com s'ha d'implementar MVCC. Tanmateix, l'API Table AM i l'API Index AM fan la següent suposició: cada TID (identificador de tuple/fila) s'indexa per tots els índexs o no s'indexa en absolut. Fins i tot si l'índex AM té diverses referències a un únic TID (per exemple, GIN), totes aquestes referències s'han de relacionar amb el mateix valor indexat.

Aquest principi ha estat criticat per augmentar el nombre d'operacions d'escriptura ("amplificació d'escriptura"): si s'actualitza un atribut indexat, s'han d'actualitzar tots els índexs de la taula. Si voleu aprofitar al màxim el registre UNDO, o crear un altre mètode d'emmagatzematge sense "amplificació d'escriptura" (com ara el mètode WARM), heu de trencar aquesta hipòtesi.

Una taula AM basada en UNDO que no infringirà aquesta hipòtesi s'assembla al mètode existent HOT (Heap-Only Tuples), excepte que les versions de fila antigues s'emmagatzemen al registre UNDO i no han d'encaixar a la mateixa pàgina. Però, segons els autors, aquest avantatge no és suficient per justificar l'existència d'una taula AM separada.
Limitacions pràctiques de l'API existent:
- Quan s'actualitza una fila de taula, els índexs s'actualitzen de manera de tot o res.
- L'API Index AM no té la capacitat d'eliminar selectivament tuples específiques. Actualment, és possible suprimir tuples dels índexs a granel mitjançant els mètodes ambulkdelete i amvacuumcleanup. Intentar implementar eliminacions puntuals a través d'aquesta API tindria una baixa eficiència, ja que la majoria de les implementacions actuals han d'escanejar tot l'índex. A més, l'API no us permet especificar quines tuples que fan referència al mateix TID s'han de suprimir. Només pot esborrar-los tots.
- Actualment els índexs fan referència a les files de la taula per número de bloc (32 bits) i nombre de compensació (16 bits). I només 11 bits del número de compensació es poden passar de manera segura de la taula TID a tots els mètodes d'accés a l'índex. Tanmateix, les implementacions alternatives de MVCC poden necessitar emmagatzemar càrrega útil addicional juntament amb el TID. Per exemple, OrioleDB requereix un o més bits per implementar índexs de "marcació d'eliminació" o informació de visibilitat completa.
Es proposen dues maneres de superar les limitacions a la pràctica:
Enfocament 1: l'API Index AM ofereix opcions per a una implementació alternativa de MVCC.
Tot i que Table AM continua sent responsable de tots els components de MVCC, Index AM ofereix les capacitats necessàries per a una implementació alternativa de MVCC, és a dir: emmagatzemar una càrrega útil de l'usuari juntament amb el TID, un mètode d'eliminació de punts i fins i tot un mètode d'actualització de punts (si el TID de l'índex no es pot canviar, la càrrega útil de l'usuari sí). A més, com que s'ha de permetre que diverses tuples d'índex facin referència al mateix TID, també s'han d'actualitzar els mètodes API utilitzats durant les exploracions d'índex.
Enfocament 2: índexs conscients de MVCC.
Una alternativa seria permetre índexs compatibles amb MVCC. És a dir, l'"executor" (o potser la taula AM) simplement crida als mètodes insert() i delete() a Index AM, mentre que Index AM proporciona capacitats d'escaneig conscients de MVCC. Això faria que l'exploració només d'índexs sigui molt més fàcil. Fins i tot tota la taula AM pot convertir-se en una capa intermèdia que emmagatzema dades en un índex.
El diagrama següent mostra un exemple. El valor de l'índex 2 s'actualitza per la transacció 11 del valor "A" al valor "B". Per tant, el valor "A" es marca com a xmax == 11, i el valor "B" es marca com a xmin == 11. D'aquesta manera, l'índex 2 es pot escanejar i només es poden recuperar les tuples visibles d'acord amb MVCC sense comprovacions d'heap. La recollida d'escombraries de l'índex 2 també es pot realitzar sense utilitzar el munt.

Amb totes les innovacions anteriors a l'API de mètodes d'accés a l'índex, és poc probable que tots els índexs es puguin actualitzar simultàniament per donar suport a totes les funcions noves. És més realista permetre implementacions múltiples per a un únic mètode d'accés a l'índex. Per exemple, a més de l'arbre B normal, l'extensió podrà implementar un arbre B alternatiu amb suport MVCC dins de l'índex i suport per a identificadors de registre de longitud arbitrària.

Per tant, es proposa revisar no només l'API Table AM, sinó també l'API Index AM, que ha servit bé a la comunitat PostgreSQL durant molts anys. A més, es proposa dividir l'índex AM en una capa lògica i una capa d'implementació. Aquesta arquitectura reimaginada permetrà a PostgreSQL suportar diversos models d'emmagatzematge.
Font: opennet.ru
