学习postgresql spi(一)
#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(一)的更多相关文章
- Dubbo源码学习之-SPI介绍
前言 学习之路还是要戒骄戒躁,一以贯之的积累前行.之前的公司部门技术达人少,自己总向往那些技术牛人多的团队,想象自己进去之后能跟别人学到多少东西.如今进到一个这样的团队之后,却发现之前自己的想法过于幼 ...
- postgresql spi开发笔记
#include "postgres.h" #include "fmgr.h" #include <string.h> #ifdef PG_MODU ...
- Linux学习 :SPI通讯协议
SPI接口的全称是"Serial Peripheral Interface",意为串行外围接口,是Motorola首先在其MC68HCXX系列处理器上定义的.SPI接口主要应用在E ...
- STM32学习笔记——SPI串行通讯(向原子哥学习)
一.SPI 简介 SPI是 Serial Peripheral interface 的缩写,就是串行外围设备接口.SPI 接口主要应用在 EEPROM, FLASH,实时时钟,AD 转换器,还有数 ...
- gitlab不支持mysql,这就是我学习PostgreSQL的原因
Gitlab 官方宣布,将从 12.1 版本开始不再支持 MySQL 数据库.早在 2017年7月,Gitlab 就计划将弃用对 MySQL 的支持.而目前这个决定将从 12.1 版本开始. 编辑注: ...
- RTT学习之SPI设备
SPI分为主.从.设备:具体又分标准SPI/DUAL SPI/QUAD SPI(用80字节的RAMrt_err_t rt_spi_take_bus(struct rt_spi_device *devi ...
- #pg学习#postgresql的安装
1.按照官网给的步骤编译安装(Mac安装是比较容易的,相比Liunx) cd /Users/renlipeng/Desktop/postgresql-9.5.1 ./configure --prefi ...
- PostgreSQL的hook机制初步学习
磨砺技术珠矶,践行数据之道,追求卓越价值 回到上一级页面:PostgreSQL内部结构与源代码研究索引页 回到顶级页面:PostgreSQL索引页 本文的目的一是为了备忘,二是为了抛砖引玉,希望 ...
- PostgreSQL学习之【用户权限管理】说明
背景 最近在学习PostgreSQL,看了用户权限管理文档,涉及到的知识点比较多,顺便写篇文章进行整理并不定时更新,也方便自己后续进行查阅. 说明 注意:创建好用户(角色)之后需要连接的话,还需要修改 ...
随机推荐
- web前端sprite,精灵图,雪碧图
css sprite 俗称:精灵图,雪碧图,指将整个页面不同的图片or图标合并在一张图上:优点:使用CSS Sprite 可以减少网络请求,提高网页加载性能,不会出现网页上端加载完毕下面还在加载中这一 ...
- ubuntu16.04+Opencv3.4.0安装(slam版)
本文记录ubuntu下安装opencv过程,步骤来自 opencv官网可以对照官网步骤:https://docs.opencv.org/3.4.0/d7/d9f/tutorial_linux_inst ...
- python 函数3(模块)
1.将函数存储在模块中 1.1.导入整个模块 要将函数导入,得先创建模块,模块 是扩展名为.py的文件,包含要导入到程序中的代码. 首先定义编写一个.py的文件,命名为pizza.py,代码如下: d ...
- Git的指令
一,访问本地Git 上一节我们已学会了如何注册GitHub和安装Git 现在先打开电脑终端或Git Bash,首先和Git打个招呼,输入Git 二.新建文件/进入文件夹 mkdir + 文件名 ...
- Gorm与数据库(单复数)表结构之间的映射
Gorm连接MySQL: import ( _ "github.com/go-sql-driver/mysql" "github.com/jinzhu/gorm" ...
- [redis读书笔记] 第二部分 集群
1. 一个集群会包含多个节点(一个节点就是一个reid是服务器),CLUST MEET <ip><port>可以添加一个node到集群,命令执行后,两个node之间就会进行握手 ...
- Hibernate4.x 报错 Space is not allowed after parameter prefix ':'
1.问题描述 hibernate4.0使用原生sql: (SELECT a.user_id,(@rowno:=@rowno+1) as rowno,a.goods_value FROM n_wo ...
- 开源堡垒机jumpserver的安装
开源跳板机jumpserver安装 简介 Jumpserver 是全球首款完全开源的堡垒机, 使用GNU GPL v2.0 开源协议, 是符合4A 的专业运维审计系统 Jumpserver 使用Pyt ...
- 使用 pyenv 管理不同的 Python 版本
1. pyenv 的安装 $ yum install git -y $ yum install gcc make patch gdbm-devel openssl-devel sqlite-devel ...
- asp.net core 3.x 授权中的概念
前言 预计是通过三篇来将清楚asp.net core 3.x中的授权:1.基本概念介绍:2.asp.net core 3.x中授权的默认流程:3.扩展. 在完全没有概念的情况下无论是看官方文档还是源码 ...