#include "postgres.h"
#include
#include "fmgr.h"
#include "access/xlog.h"
#include "replication/walreceiver.h"
#include "utils/elog.h"
#include "utils/builtins.h"
#include "utils/timestamp.h"
#include "funcapi.h"
#include "access/htup_details.h"
#include "catalog/pg_type.h"
#include "utils/pg_lsn.h" #ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif PG_FUNCTION_INFO_V1(get_rcv_replication_stat); Datum
get_rcv_replication_stat(PG_FUNCTION_ARGS)
{
Assert(PG_NARGS() == ); // 表示没有输入参数 if (!RecoveryInProgress()) // 在数据库处于恢复状态下时运行,否则不允许
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("recovery is not in progress"),
errhint("This functions can only be executed during recovery."))); /* use volatile pointer to prevent code rearrangement */
volatile WalRcvData *walrcv = WalRcv; // 共享内存中用于管理流复制的数据结构 src/include/replication/walreceiver.h
TupleDesc tupdesc; // 创建一个行描述变量
Datum DatumValue[]; // 创建一个存储值的Datum数组, 需要返回几个字段, 创建相应长度的数组
bool nulls[]; // 元组中的属性数 typedef struct TupleDescData -> natts; /* Initialise DatumValue and NULL flags arrays 初始化 */
MemSet(DatumValue, , sizeof(DatumValue));
MemSet(nulls, , sizeof(nulls)); /* Initialise attributes information in the tuple descriptor 定义字段类型和字段名, 到相应的头文件src/include/catalog/pg_type.h找到对应的类型 */ /*
CreateTemplateTupleDesc
该函数分配一个空的元组描述符结构。
元组类型的ID信息被初始设置为一个匿名记录类型;
如果需要调用者可以覆盖此。 TupleDescInitEntry: 此函数在先前分配的元组描述符中初始化单个属性结构。
如果attributeName为NULL,则attname字段将设置为空字符串(这是在我们不知道或不需要该字段名称的情况下)。
另外,某些调用者使用此功能来更改现有tupdesc中与数据类型相关的字段;例如, 它们传递attributeName = NameStr(att-> attname)来指示不应修改attname字段。
请注意,attcollation设置为指定数据类型的默认值。 如果需要非默认排序规则,请稍后使用TupleDescInitEntryCollation插入它。
*/
tupdesc = CreateTemplateTupleDesc(, false);
TupleDescInitEntry(tupdesc, (AttrNumber) , "last_walend_time",
TIMESTAMPTZOID, -, );
TupleDescInitEntry(tupdesc, (AttrNumber) , "last_recv_lsn",
LSNOID, -, );
TupleDescInitEntry(tupdesc, (AttrNumber) , "last_apply_lsn",
LSNOID, -, );
TupleDescInitEntry(tupdesc, (AttrNumber) , "last_apply_delay_ms",
INT4OID, -, );
TupleDescInitEntry(tupdesc, (AttrNumber) , "receiver_pid",
INT4OID, -, );
TupleDescInitEntry(tupdesc, (AttrNumber) , "receiver_state",
INT4OID, -, );
TupleDescInitEntry(tupdesc, (AttrNumber) , "receiver_start_time",
INT8OID, -, );
TupleDescInitEntry(tupdesc, (AttrNumber) , "receiver_conninfo",
TEXTOID, -, );
BlessTupleDesc(tupdesc); // 完成对返回类型的构造, 参考src/include/funcapi.h // 接下来将每个值转换为对应的Datum存储到DatumValue数组, 对应的nulls数组仅当值为空时设置为true.
TimestampTz receipttime;
receipttime = walrcv->latestWalEndTime; // TimestampTz latestWalEndTime;
DatumValue[] = TimestampTzGetDatum(receipttime); // #define TimestampTzGetDatum(X) Int64GetDatum(X)
XLogRecPtr recvPtr; // src/include/access/xlogdefs.h 指向XLOG中的位置的指针。 这些指针为64位宽,因为我们不希望它们溢出。 /*
src/backend/replication/walreceiverfuncs.c: GetWalRcvWriteRecPtr
返回walreceiver已写入的最后1个字节位置。
(可选)返回上一个块开始,即在最近的walreceiver刷新周期中写入的第一个字节。 对该值不感兴趣的调用者可以为lastChunkStart传递NULL。 与receiveTLI相同。
*/
recvPtr = GetWalRcvWriteRecPtr(NULL, NULL); // XLogRecPtr recptr;
if (recvPtr == )
nulls[] = true;
else
DatumValue[] = LSNGetDatum(recvPtr); // #define LSNGetDatum(X) (Int64GetDatum((int64) (X))) /*
xlog.c: GetXLogReplayRecPtr
获取最新的重做apply position。
导出以允许WALReceiver直接读取指针。 */
XLogRecPtr applyPtr;
applyPtr = GetXLogReplayRecPtr(NULL);
if (recvPtr == )
nulls[] = true;
else
DatumValue[] = LSNGetDatum(applyPtr);
int apply_delay_ms; /*
walreceiverfuncs.c: GetReplicationApplyDelay
如果没有应用延迟信息,则返回复制应用延迟(以毫秒为单位)或-1
*/
apply_delay_ms = GetReplicationApplyDelay();
if (apply_delay_ms == -)
nulls[] = true;
else
DatumValue[] = Int32GetDatum(apply_delay_ms);
DatumValue[] = Int32GetDatum(walrcv->pid);
DatumValue[] = Int32GetDatum(walrcv->walRcvState);
DatumValue[] = Int64GetDatum(walrcv->startTime);
DatumValue[] = PointerGetDatum(cstring_to_text((char *)walrcv->conninfo));
// 返回
/* Returns the record as Datum 把元组变成 datum */
PG_RETURN_DATUM(HeapTupleGetDatum( heap_form_tuple(tupdesc, DatumValue, nulls))); // heap_form_tuple 构造一个tuple 返回 HeapTupleHeader , HeapTupleGetDatum 将HeapTupleHeader指针转换为Datum。 }

学习postgresql spi(一)的更多相关文章

  1. Dubbo源码学习之-SPI介绍

    前言 学习之路还是要戒骄戒躁,一以贯之的积累前行.之前的公司部门技术达人少,自己总向往那些技术牛人多的团队,想象自己进去之后能跟别人学到多少东西.如今进到一个这样的团队之后,却发现之前自己的想法过于幼 ...

  2. postgresql spi开发笔记

    #include "postgres.h" #include "fmgr.h" #include <string.h> #ifdef PG_MODU ...

  3. Linux学习 :SPI通讯协议

    SPI接口的全称是"Serial Peripheral Interface",意为串行外围接口,是Motorola首先在其MC68HCXX系列处理器上定义的.SPI接口主要应用在E ...

  4. STM32学习笔记——SPI串行通讯(向原子哥学习)

    一.SPI  简介 SPI是 Serial Peripheral interface 的缩写,就是串行外围设备接口.SPI 接口主要应用在  EEPROM, FLASH,实时时钟,AD 转换器,还有数 ...

  5. gitlab不支持mysql,这就是我学习PostgreSQL的原因

    Gitlab 官方宣布,将从 12.1 版本开始不再支持 MySQL 数据库.早在 2017年7月,Gitlab 就计划将弃用对 MySQL 的支持.而目前这个决定将从 12.1 版本开始. 编辑注: ...

  6. RTT学习之SPI设备

    SPI分为主.从.设备:具体又分标准SPI/DUAL SPI/QUAD SPI(用80字节的RAMrt_err_t rt_spi_take_bus(struct rt_spi_device *devi ...

  7. #pg学习#postgresql的安装

    1.按照官网给的步骤编译安装(Mac安装是比较容易的,相比Liunx) cd /Users/renlipeng/Desktop/postgresql-9.5.1 ./configure --prefi ...

  8. PostgreSQL的hook机制初步学习

    磨砺技术珠矶,践行数据之道,追求卓越价值 回到上一级页面:PostgreSQL内部结构与源代码研究索引页    回到顶级页面:PostgreSQL索引页 本文的目的一是为了备忘,二是为了抛砖引玉,希望 ...

  9. PostgreSQL学习之【用户权限管理】说明

    背景 最近在学习PostgreSQL,看了用户权限管理文档,涉及到的知识点比较多,顺便写篇文章进行整理并不定时更新,也方便自己后续进行查阅. 说明 注意:创建好用户(角色)之后需要连接的话,还需要修改 ...

随机推荐

  1. android 基础学习笔记2

    1.容器布局 一.线性布局 (LineaLayout) 方向:orientation =vertical / horizontal 重力(对齐) :gravity =bottom/right/left ...

  2. Algorithms - Insertion Sort - 插入排序

    Insertion Sort - 插入排序 插入排序算法的 '时间复杂度' 是输入规模的二次函数, 深度抽象后表示为, n 的二次方. import time, random F = 0 alist ...

  3. mysql 查询指定数据库所有表, 指定表所有列, 指定列所有表 所有外键及索引, 以及索引的创建和删除

    查询指定 数据库 中所有 表 (指定数据库的,所有表) // 可以把 TABLE_NAME 换成 * 号, 查看更丰富的信息 SELECT TABLE_NAME FROM information_sc ...

  4. vue路由--动态路由

    前面介绍的路由都是路径和组件一对一映射的 有时候需要多个路径映射到一个组件,这个组件根据参数的不同动态改变,这时候需要用到动态路由 动态路由这样定义路由路径: path: '/foo/:id'--可以 ...

  5. 五分钟了解抽象语法树(AST)babel是如何转换的?

    抽象语法树 什么是抽象语法树? It is a hierarchical program representation that presents source code structure acco ...

  6. .net core 轻量级容器 ServiceProvider 源码分析

    首先看 ServiceCollection 的定义 //定义 public class ServiceCollection : IServiceCollection { private readonl ...

  7. ASP.NET Core MVC学习笔记

    最近由于疫情紧张,遂在家办公,在领导的带领下,学习了一下.Net Core MVC. 一,构建web应用 1.选择c#-所有平台-web  找到ASP.NET Core web应用程序 2.项目命名之 ...

  8. MySQL导出数据时提示文件损坏

    使用Navicat工具,优先将整个数据库的表和数据导出. 如果遇到文件损坏错误可以在表实例界面选中所有表,然后将表转储为SQL文件(结构和数据). 在目标数据库执行导出的SQL文件,导入结构和数据. ...

  9. No mapping found for HTTP request with URI [/SLSaleSystem/js/jquery.dataTables.min.js] in DispatcherServlet with name 'spring' 静态资源文件访问不到,无解!!!!!!!

    报错信息:   网上三种修改 web.xml 文件方法尝试未果 尝试未果:<mvc:default-servlet-handler/> 尝试未果:方法2:直接告诉spring,这个你就得这 ...

  10. PMP--1.4 项目描述

    一. 项目定义 项目:是为了创造 独特的产品.服务或成果而进行的临时性工作.  说明: (1)独特 即使某些项目中存在重复发元素,但重复不会改变项目本质上的独特性. (2)产品.服务或成果 1)一个独 ...