/*-------------------------------------------------------------------------
*
* aio_funcs . c
* AIO - SQL interface for AIO
*
*
* Portions Copyright ( c ) 1996 - 2025 , PostgreSQL Global Development Group
* Portions Copyright ( c ) 1994 , Regents of the University of California
*
* IDENTIFICATION
* src / backend / storage / aio / aio_funcs . c
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
#include "postgres.h"
#include "fmgr.h"
#include "funcapi.h"
#include "nodes/execnodes.h"
#include "port/atomics.h"
#include "storage/aio_internal.h"
#include "storage/lock.h"
#include "storage/proc.h"
#include "storage/procnumber.h"
#include "utils/builtins.h"
#include "utils/fmgrprotos.h"
#include "utils/tuplestore.h"
/*
* Byte length of an iovec .
*/
static size_t
iov_byte_length(const struct iovec *iov, int cnt)
{
size_t len = 0 ;
for (int i = 0 ; i < cnt; i++)
{
len += iov[i].iov_len;
}
return len;
}
Datum
pg_get_aios(PG_FUNCTION_ARGS)
{
ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
InitMaterializedSRF(fcinfo, 0 );
#define PG_GET_AIOS_COLS 15
for (uint64 i = 0 ; i < pgaio_ctl->io_handle_count; i++)
{
PgAioHandle *live_ioh = &pgaio_ctl->io_handles[i];
int ioh_id = pgaio_io_get_id(live_ioh);
Datum values[PG_GET_AIOS_COLS] = {0 };
bool nulls[PG_GET_AIOS_COLS] = {0 };
ProcNumber owner;
PGPROC *owner_proc;
int32 owner_pid;
PgAioHandleState start_state;
uint64 start_generation;
PgAioHandle ioh_copy;
struct iovec iov_copy[PG_IOV_MAX];
/*
* There is no lock that could prevent the state of the IO to advance
* concurrently - and we don ' t want to introduce one , as that would
* introduce atomics into a very common path . Instead we
*
* 1 ) Determine the state + generation of the IO .
*
* 2 ) Copy the IO to local memory .
*
* 3 ) Check if state or generation of the IO changed . If the state
* changed , retry , if the generation changed don ' t display the IO .
*/
/* 1) from above */
start_generation = live_ioh->generation;
/*
* Retry at this point , so we can accept changing states , but not
* changing generations .
*/
retry:
pg_read_barrier();
start_state = live_ioh->state;
if (start_state == PGAIO_HS_IDLE)
continue ;
/* 2) from above */
memcpy(&ioh_copy, live_ioh, sizeof (PgAioHandle));
/*
* Safe to copy even if no iovec is used - we always reserve the
* required space .
*/
memcpy(&iov_copy, &pgaio_ctl->iovecs[ioh_copy.iovec_off],
PG_IOV_MAX * sizeof (struct iovec));
/*
* Copy information about owner before 3 ) below , if the process exited
* it ' d have to wait for the IO to finish first , which we would detect
* in 3 ) .
*/
owner = ioh_copy.owner_procno;
owner_proc = GetPGProcByNumber(owner);
owner_pid = owner_proc->pid;
/* 3) from above */
pg_read_barrier();
/*
* The IO completed and a new one was started with the same ID . Don ' t
* display it - it really started after this function was called .
* There be a risk of a livelock if we just retried endlessly , if IOs
* complete very quickly .
*/
if (live_ioh->generation != start_generation)
continue ;
/*
* The IO ' s state changed while we were " rendering " it . Just start
* from scratch . There ' s no risk of a livelock here , as an IO has a
* limited sets of states it can be in , and state changes go only in a
* single direction .
*/
if (live_ioh->state != start_state)
goto retry;
/*
* Now that we have copied the IO into local memory and checked that
* it ' s still in the same state , we are not allowed to access " live "
* memory anymore . To make it slightly easier to catch such cases , set
* the " live " pointers to NULL .
*/
live_ioh = NULL;
owner_proc = NULL;
/* column: owning pid */
if (owner_pid != 0 )
values[0 ] = Int32GetDatum(owner_pid);
else
nulls[0 ] = true ;
/* column: IO's id */
values[1 ] = Int32GetDatum(ioh_id);
/* column: IO's generation */
values[2 ] = Int64GetDatum(start_generation);
/* column: IO's state */
values[3 ] = CStringGetTextDatum(pgaio_io_get_state_name(&ioh_copy));
/*
* If the IO is in PGAIO_HS_HANDED_OUT state , none of the following
* fields are valid yet ( or are in the process of being set ) .
* Therefore we don ' t want to display any other columns .
*/
if (start_state == PGAIO_HS_HANDED_OUT)
{
memset(nulls + 4 , 1 , (lengthof(nulls) - 4 ) * sizeof (bool ));
goto display;
}
/* column: IO's operation */
values[4 ] = CStringGetTextDatum(pgaio_io_get_op_name(&ioh_copy));
/* columns: details about the IO's operation (offset, length) */
switch ((PgAioOp) ioh_copy.op)
{
case PGAIO_OP_INVALID:
nulls[5 ] = true ;
nulls[6 ] = true ;
break ;
case PGAIO_OP_READV:
values[5 ] = Int64GetDatum(ioh_copy.op_data.read.offset);
values[6 ] =
Int64GetDatum(iov_byte_length(iov_copy, ioh_copy.op_data.read.iov_length));
break ;
case PGAIO_OP_WRITEV:
values[5 ] = Int64GetDatum(ioh_copy.op_data.write.offset);
values[6 ] =
Int64GetDatum(iov_byte_length(iov_copy, ioh_copy.op_data.write.iov_length));
break ;
}
/* column: IO's target */
values[7 ] = CStringGetTextDatum(pgaio_io_get_target_name(&ioh_copy));
/* column: length of IO's data array */
values[8 ] = Int16GetDatum(ioh_copy.handle_data_len);
/* column: raw result (i.e. some form of syscall return value) */
if (start_state == PGAIO_HS_COMPLETED_IO
|| start_state == PGAIO_HS_COMPLETED_SHARED
|| start_state == PGAIO_HS_COMPLETED_LOCAL)
values[9 ] = Int32GetDatum(ioh_copy.result);
else
nulls[9 ] = true ;
/*
* column : result in the higher level representation ( unknown if not
* finished )
*/
values[10 ] =
CStringGetTextDatum(pgaio_result_status_string(ioh_copy.distilled_result.status));
/* column: target description */
values[11 ] = CStringGetTextDatum(pgaio_io_get_target_description(&ioh_copy));
/* columns: one for each flag */
values[12 ] = BoolGetDatum(ioh_copy.flags & PGAIO_HF_SYNCHRONOUS);
values[13 ] = BoolGetDatum(ioh_copy.flags & PGAIO_HF_REFERENCES_LOCAL);
values[14 ] = BoolGetDatum(ioh_copy.flags & PGAIO_HF_BUFFERED);
display:
tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
}
return (Datum) 0 ;
}
Messung V0.5 in Prozent C=93 H=87 G=89
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.15Bemerkung:
(vorverarbeitet am 2026-08-08)
¤
*Bot Zugriff