#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. shell正则表达式提取数字

    grep 提取数字 grep -Po "\d+\.\d+"

  2. [Python]获取win平台文件的详细信息

    import win32api def getFileProperties(fname): """ 读取给定文件的所有属性, 返回一个字典. ""&q ...

  3. Python爬虫小结

    有些数据是没有专门的数据集的,为了找到神经网络训练的数据,自然而然的想到了用爬虫的方法开始采集数据.一开始采用了网上的一个动态爬虫的代码,发现爬取的图片大多是重复的,有效图片很少. 动态爬虫: fro ...

  4. 安装Mysql时提示尚未安装Python 解决方案

    我明明安装了python,结果在安装mysql是却提示没有安装python. 原因,没有将python添加到path中. 解决方法:卸载python,然后重装python,在安装界面中勾选将path添 ...

  5. 简化 Spring Boot 项目部署,Flyway 搞起来

    虽然我之前录了一个微人事(https://github.com/lenve/vhr)部署视频(新版微人事部署教程来啦),但是由于这次升级涉及到了 Redis 和 RabbitMQ,所以在本地跑微人事还 ...

  6. 总结JavaScript对象的深浅拷贝

    十四.对象的浅拷贝与深拷贝 什么是对象的拷贝? 将一个对象赋值给另外一个对象, 我们称之为对象的拷贝 什么是深拷贝, 什么是浅拷贝? 我们假设将A对象赋值给B对象 浅拷贝是指, 修改B对象的属性和方法 ...

  7. GO语言slice详解(结合源码)

    一.GO语言中slice的定义 slice 是一种结构体类型,在源码中的定义为: src/runtime/slice.go type slice struct { array unsafe.Point ...

  8. 基于原生的 html css js php ajax做的一个 web登录和注册系统

    完整代码下载: 百度网盘地址 https://pan.baidu.com/s/1D1gqHSyjgfoOtYCZm7ofJg 提取码 :nf0b 永久有效 注意: 1 如果要正常运行此示例, 本地需要 ...

  9. javascript 完全正确的数据库indexedDB

    //indexedDB var dbName = 'whx', version = '1', dbTableName = 'bbg', request, db, conCls, updateKey, ...

  10. php面试笔记(4)-php基础知识-流程控制

    本文是根据慕课网Jason老师的课程进行的PHP面试知识点总结和升华,如有侵权请联系我进行删除,email:guoyugygy@163.com 在面试中,考官往往喜欢基础扎实的面试者,而流程控制相关的 ...