ProvSQL C/C++ API
Adding support for provenance and uncertainty management to PostgreSQL databases
Loading...
Searching...
No Matches
provsql_mmap.c File Reference

Background worker registration and IPC primitives for mmap-backed storage. More...

#include "provsql_mmap.h"
#include "provsql_rmgr.h"
#include "provsql_shmem.h"
#include "provsql_utils.h"
#include <errno.h>
#include <unistd.h>
#include <poll.h>
#include <math.h>
#include <assert.h>
#include "postgres.h"
#include "access/xact.h"
#include "postmaster/bgworker.h"
#include "fmgr.h"
#include "funcapi.h"
#include "utils/array.h"
#include "access/htup_details.h"
#include "utils/builtins.h"
#include "circuit_cache.h"
Include dependency graph for provsql_mmap.c:

Go to the source code of this file.

Macros

#define WORKER_READ_BUFFER   (64 * 1024)

Functions

bool provsql_worker_buffered (void)
 Whether the worker's read buffer holds unread bytes, which poll() cannot see.
bool provsql_worker_read (void *dst, size_t n)
 The worker's buffered read of the request pipe: what the pipe holds is read in one call, and the messages are parsed from the buffer.
bool provsql_read_all (int fd, void *dst, size_t n)
 Read exactly n bytes from fd into dst; false on EOF/error.
void provsql_mmap_worker (Datum ignored)
 Entry point for the ProvSQL mmap background worker.
void RegisterProvSQLMMapWorker (void)
 Register the ProvSQL mmap background worker with PostgreSQL.
static void provsql_store_sync_barrier (void)
 Send the sync barrier and wait for the worker's acknowledgement.
static void provsql_store_xact_callback (XactEvent event, void *arg)
static void provsql_log_store_write (const char *data, size_t len)
 What every store mutation does before it reaches the pipe: refuse it on a standby, and write it to the WAL.
static void provsql_before_store_write (const char *data, size_t len)
 The same, for a mutation made by a live transaction: it also arms the at-commit sync barrier.
void provsql_store_note_write (void)
 Note that this transaction has written to the circuit store.
bool provsql_store_written (void)
 Whether this transaction has written to the circuit store.
void provsql_circuit_cleanup_request (bool dry_run, const pg_uuid_t *roots, int64 nb_roots, provsql_cleanup_result *out)
 Ask the worker to rebuild this database's store, keeping only what roots reach.
void provsql_replay_store_message (const char *data, size_t len)
 Feed a logged store message back to the worker.
Datum check_store (PG_FUNCTION_ARGS)
 Report what does not add up in this database's circuit store.
gate_type provsql_fetch_gate (const pg_uuid_t *token, unsigned *nb_children_out, pg_uuid_t **children_out)
 PostgreSQL-callable wrapper for get_gate_type().
Datum get_gate_type (PG_FUNCTION_ARGS)
void provsql_internal_create_gate (const pg_uuid_t *token, gate_type type, unsigned nb_children, const pg_uuid_t *children_data)
 Internal entry point behind create_gate(): cache + worker IPC.
static provsql_set_prob_result provsql_send_set_prob (const pg_uuid_t *token, double prob, double *existing, bool tracked)
 Send a probability write and read back what the store made of it.
provsql_set_prob_result provsql_internal_set_prob (const pg_uuid_t *token, double prob, double *existing)
 Write a gate's probability from in-extension C/C++ code.
void provsql_internal_clear_prob (const pg_uuid_t *token)
 Drop a gate's probability, leaving it as it was before anyone wrote one.
bool provsql_internal_get_prob_written (const pg_uuid_t *token, double *prob)
 Report whether a probability has been written on a gate.
void provsql_internal_create_gate_with (const pg_uuid_t *token, gate_type type, unsigned nb_children, const pg_uuid_t *children, bool has_infos, unsigned info1, unsigned info2, const char *extra)
 Create a gate together with its infos and its text, in one message that is not answered.
Datum create_gate (PG_FUNCTION_ARGS)
 PostgreSQL-callable wrapper for create_gate().
static void send_unanswered (const char *msg, size_t len)
Datum set_infos (PG_FUNCTION_ARGS)
 Entry point of the set_infos of earlier versions' scripts.
Datum set_extra (PG_FUNCTION_ARGS)
 Entry point of the set_extra of earlier versions' scripts.
Datum get_extra (PG_FUNCTION_ARGS)
 PostgreSQL-callable wrapper for get_extra().
Datum get_nb_gates (PG_FUNCTION_ARGS)
 PostgreSQL-callable wrapper for get_nb_gates().
Datum get_children (PG_FUNCTION_ARGS)
 PostgreSQL-callable wrapper for get_children().
Datum get_prob (PG_FUNCTION_ARGS)
 PostgreSQL-callable wrapper for get_prob().
Datum get_infos (PG_FUNCTION_ARGS)
 PostgreSQL-callable wrapper for get_infos().

Variables

char buffer [PIPE_BUF] ={}
 Shared write buffer used with STARTWRITEM / ADDWRITEM / SENDWRITEM.
unsigned bufferpos =0
 Current write position within buffer.
static char worker_buffer [WORKER_READ_BUFFER]
static size_t worker_buffer_pos = 0
static size_t worker_buffer_len = 0
bool provsql_synchronous_commit = false
 Global variable set by the provsql.synchronous_commit run-time configuration parameter: when true, a transaction that has written to the circuit store forces the store to stable storage before it commits.
static bool store_written = false
 Whether the current transaction has written anything to the store.
static bool store_callbacks_registered = false

Detailed Description

Background worker registration and IPC primitives for mmap-backed storage.

Implements the PostgreSQL background worker lifecycle functions declared in provsql_mmap.h:

The IPC between normal backends and the background worker is handled in MMappedCircuit.cpp. This file provides the PostgreSQL-specific glue (background worker API, signal handling).

Also declares the shared write buffer buffer[] and position counter bufferpos used by the STARTWRITEM / ADDWRITEM / SENDWRITEM macros in provsql_mmap.h.

The gate-creation SQL functions (e.g. create_gate()) that backends call are also implemented here; they acquire the IPC lock, write a message to the background worker, and wait for an acknowledgment.

Definition in file provsql_mmap.c.

Macro Definition Documentation

◆ WORKER_READ_BUFFER

#define WORKER_READ_BUFFER   (64 * 1024)

Definition at line 76 of file provsql_mmap.c.

Function Documentation

◆ check_store()

Datum check_store ( PG_FUNCTION_ARGS )

Report what does not add up in this database's circuit store.

A store nothing has damaged answers zero to every count. A non-zero one means a write was interrupted at a point the ordering rules do not cover, or that a set of files was copied at different instants – a file-level backup of a running server, or a base backup. provsql.circuit_cleanup() rebuilds the store from what is still reachable.

Definition at line 394 of file provsql_mmap.c.

Here is the call graph for this function:

◆ create_gate()

Datum create_gate ( PG_FUNCTION_ARGS )

PostgreSQL-callable wrapper for create_gate().

Definition at line 783 of file provsql_mmap.c.

Here is the call graph for this function:

◆ get_children()

Datum get_children ( PG_FUNCTION_ARGS )

PostgreSQL-callable wrapper for get_children().

Definition at line 969 of file provsql_mmap.c.

Here is the call graph for this function:

◆ get_extra()

Datum get_extra ( PG_FUNCTION_ARGS )

PostgreSQL-callable wrapper for get_extra().

Definition at line 911 of file provsql_mmap.c.

Here is the call graph for this function:

◆ get_gate_type()

Datum get_gate_type ( PG_FUNCTION_ARGS )

Definition at line 521 of file provsql_mmap.c.

Here is the call graph for this function:

◆ get_infos()

Datum get_infos ( PG_FUNCTION_ARGS )

PostgreSQL-callable wrapper for get_infos().

Definition at line 1067 of file provsql_mmap.c.

Here is the call graph for this function:

◆ get_nb_gates()

Datum get_nb_gates ( PG_FUNCTION_ARGS )

PostgreSQL-callable wrapper for get_nb_gates().

Definition at line 947 of file provsql_mmap.c.

Here is the call graph for this function:

◆ get_prob()

Datum get_prob ( PG_FUNCTION_ARGS )

PostgreSQL-callable wrapper for get_prob().

Definition at line 1037 of file provsql_mmap.c.

Here is the call graph for this function:

◆ provsql_before_store_write()

void provsql_before_store_write ( const char * data,
size_t len )
static

The same, for a mutation made by a live transaction: it also arms the at-commit sync barrier.

Definition at line 267 of file provsql_mmap.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ provsql_circuit_cleanup_request()

void provsql_circuit_cleanup_request ( bool dry_run,
const pg_uuid_t * roots,
int64 nb_roots,
provsql_cleanup_result * out )

Ask the worker to rebuild this database's store, keeping only what roots reach.

The caller must hold the database exclusively; see provsql.circuit_cleanup in circuit_cleanup.c.

Definition at line 287 of file provsql_mmap.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ provsql_fetch_gate()

gate_type provsql_fetch_gate ( const pg_uuid_t * token,
unsigned * nb_children_out,
pg_uuid_t ** children_out )

PostgreSQL-callable wrapper for get_gate_type().

Fetch a gate's type and children, cache-first with a worker round-trip (and cache fill) on a miss.

On cache miss this fetches BOTH the gate type and its children from the worker, in one critical section, then caches them together. If we cached only the type (with an empty children list), a subsequent get_children() call for the same token would consult the cache, find the entry, and return 0 children : never querying the worker for the real children. provsql.provenance_evaluate hits exactly that pattern (it calls get_gate_type first, then unnest(get_children(...))) and silently folds plus/times gates over an empty set.

Fetch a gate's type and children, cache-first with a worker round-trip (and cache fill) on a miss. Factored out of the get_gate_type() wrapper for in-extension callers that walk the circuit from C (e.g. the annotation-transparent set_prob()). On return *children_out is a calloc'd array to be freed by the caller, or NULL when the gate has no children.

Definition at line 456 of file provsql_mmap.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ provsql_internal_clear_prob()

void provsql_internal_clear_prob ( const pg_uuid_t * token)

Drop a gate's probability, leaving it as it was before anyone wrote one.

The rollback path of probability_store.c, and the only way to unset a probability: there is none from SQL. Unlike a write it does not arm the at-commit sync barrier – it runs when the transaction that would have committed is already gone.

Definition at line 679 of file provsql_mmap.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ provsql_internal_create_gate()

void provsql_internal_create_gate ( const pg_uuid_t * token,
gate_type type,
unsigned nb_children,
const pg_uuid_t * children_data )

Internal entry point behind create_gate(): cache + worker IPC.

Create a gate from in-extension C/C++ code (cache + worker IPC).

Factored out of the SQL-callable wrapper so in-extension C/C++ code (e.g. the decomposition-aligned reachability materialiser) can create gates without Datum marshalling or gate-type-OID lookups. Same semantics: write-through to the per-session cache, then the C message to the background worker; MMappedCircuit::createGate is idempotent on already-mapped tokens.

Definition at line 545 of file provsql_mmap.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ provsql_internal_create_gate_with()

void provsql_internal_create_gate_with ( const pg_uuid_t * token,
gate_type type,
unsigned nb_children,
const pg_uuid_t * children,
bool has_infos,
unsigned info1,
unsigned info2,
const char * extra )

Create a gate together with its infos and its text, in one message that is not answered.

For the gates whose address determines what they record (a value gate and its text, an annotation, a comparison and its operator, an aggregate), so that the write-once rule has nothing to refuse and nobody needs to wait for its answer. extra NULL records no text; has_infos false records no infos.

Definition at line 706 of file provsql_mmap.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ provsql_internal_get_prob_written()

bool provsql_internal_get_prob_written ( const pg_uuid_t * token,
double * prob )

Report whether a probability has been written on a gate.

Distinct from get_prob(), which reports the value an evaluation would use and so answers 1 for a gate nobody gave a probability.

Parameters
tokenUUID of the gate.
probOn true return, the written probability.

Definition at line 684 of file provsql_mmap.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ provsql_internal_set_prob()

provsql_set_prob_result provsql_internal_set_prob ( const pg_uuid_t * token,
double prob,
double * existing )

Write a gate's probability from in-extension C/C++ code.

Probabilities are written once (see MMappedCircuit::setProb), so this reports which of the four cases applied rather than a bare success flag. Callers that write a probability on a gate they have just created can treat anything but PROVSQL_SET_PROB_NOT_PROB_GATE as success; set_prob() itself raises on PROVSQL_SET_PROB_ALREADY_SET.

Note that this is the raw store operation: it does not record the write in the transaction's undo list. SQL-level writers go through provsql_set_prob_tracked() in probability_store.c so a rollback drops what they wrote.

Parameters
tokenUUID of the gate.
probProbability value in [0,1], or NaN to clear.
existingOn PROVSQL_SET_PROB_ALREADY_SET, the stored value.

Definition at line 672 of file provsql_mmap.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ provsql_log_store_write()

void provsql_log_store_write ( const char * data,
size_t len )
static

What every store mutation does before it reaches the pipe: refuse it on a standby, and write it to the WAL.

data is the complete message, opcode first.

Definition at line 251 of file provsql_mmap.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ provsql_mmap_worker()

void provsql_mmap_worker ( Datum ignored)

Entry point for the ProvSQL mmap background worker.

Called by the postmaster when it launches the background worker. Enters the main loop (provsql_mmap_main_loop()) and never returns normally. The single Datum argument is required by the background-worker API but is not used.

Definition at line 146 of file provsql_mmap.c.

Here is the call graph for this function:

◆ provsql_read_all()

bool provsql_read_all ( int fd,
void * dst,
size_t n )

Read exactly n bytes from fd into dst; false on EOF/error.

Definition at line 111 of file provsql_mmap.c.

◆ provsql_replay_store_message()

void provsql_replay_store_message ( const char * data,
size_t len )

Feed a logged store message back to the worker.

Implemented in provsql_mmap.c, where the IPC primitives live.

Definition at line 341 of file provsql_mmap.c.

Here is the call graph for this function:

◆ provsql_send_set_prob()

provsql_set_prob_result provsql_send_set_prob ( const pg_uuid_t * token,
double prob,
double * existing,
bool tracked )
static

Send a probability write and read back what the store made of it.

tracked arms the at-commit sync barrier; the one caller that passes false is the rollback path, which runs when the transaction that would have committed is already gone.

Definition at line 642 of file provsql_mmap.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ provsql_store_note_write()

void provsql_store_note_write ( void )

Note that this transaction has written to the circuit store.

Arms the at-commit sync barrier (provsql.synchronous_commit) and the PREPARE TRANSACTION refusal.

Definition at line 273 of file provsql_mmap.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ provsql_store_sync_barrier()

void provsql_store_sync_barrier ( void )
static

Send the sync barrier and wait for the worker's acknowledgement.

Definition at line 209 of file provsql_mmap.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ provsql_store_written()

bool provsql_store_written ( void )

Whether this transaction has written to the circuit store.

Definition at line 282 of file provsql_mmap.c.

Here is the caller graph for this function:

◆ provsql_store_xact_callback()

void provsql_store_xact_callback ( XactEvent event,
void * arg )
static

Definition at line 225 of file provsql_mmap.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ provsql_worker_buffered()

bool provsql_worker_buffered ( void )

Whether the worker's read buffer holds unread bytes, which poll() cannot see.

Definition at line 80 of file provsql_mmap.c.

Here is the caller graph for this function:

◆ provsql_worker_read()

bool provsql_worker_read ( void * dst,
size_t n )

The worker's buffered read of the request pipe: what the pipe holds is read in one call, and the messages are parsed from the buffer.

false on EOF or error.

Definition at line 85 of file provsql_mmap.c.

◆ RegisterProvSQLMMapWorker()

void RegisterProvSQLMMapWorker ( void )

Register the ProvSQL mmap background worker with PostgreSQL.

Must be called from the extension's _PG_init() function so that the postmaster starts the worker on the next connection.

Definition at line 162 of file provsql_mmap.c.

Here is the caller graph for this function:

◆ send_unanswered()

void send_unanswered ( const char * msg,
size_t len )
static

Definition at line 845 of file provsql_mmap.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_extra()

Datum set_extra ( PG_FUNCTION_ARGS )

Entry point of the set_extra of earlier versions' scripts.

Definition at line 887 of file provsql_mmap.c.

Here is the call graph for this function:

◆ set_infos()

Datum set_infos ( PG_FUNCTION_ARGS )

Entry point of the set_infos of earlier versions' scripts.

Definition at line 864 of file provsql_mmap.c.

Here is the call graph for this function:

Variable Documentation

◆ buffer

char buffer[PIPE_BUF] ={}

Shared write buffer used with STARTWRITEM / ADDWRITEM / SENDWRITEM.

Definition at line 69 of file provsql_mmap.c.

◆ bufferpos

unsigned bufferpos =0

Current write position within buffer.

Definition at line 70 of file provsql_mmap.c.

◆ provsql_synchronous_commit

bool provsql_synchronous_commit = false

Global variable set by the provsql.synchronous_commit run-time configuration parameter: when true, a transaction that has written to the circuit store forces the store to stable storage before it commits.

Definition at line 202 of file provsql_mmap.c.

◆ store_callbacks_registered

bool store_callbacks_registered = false
static

Definition at line 206 of file provsql_mmap.c.

◆ store_written

bool store_written = false
static

Whether the current transaction has written anything to the store.

Definition at line 205 of file provsql_mmap.c.

◆ worker_buffer

char worker_buffer[WORKER_READ_BUFFER]
static

Definition at line 77 of file provsql_mmap.c.

◆ worker_buffer_len

size_t worker_buffer_len = 0
static

Definition at line 78 of file provsql_mmap.c.

◆ worker_buffer_pos

size_t worker_buffer_pos = 0
static

Definition at line 78 of file provsql_mmap.c.