学习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,看了用户权限管理文档,涉及到的知识点比较多,顺便写篇文章进行整理并不定时更新,也方便自己后续进行查阅. 说明 注意:创建好用户(角色)之后需要连接的话,还需要修改 ...
随机推荐
- POJ_3663_贪心
题目描述: 给你一堆数和一个限定的空间大小,要求求出两个数的和小于等于空间大小的对数. 思路: 贪心,先给一堆数从大到小排序. 第一个数取数组第一个,第二个数从第二个开始依次往后取,只要某个第二个数满 ...
- Mysql事务结合spring管理
spring事务相关问题记录 遇到情况: 在本地单体应用调试代码时,发现在一个加了@transaction注解的方法里进行先更新后查询的操作,查询的结果是可以看到更新的内容的.而在微服务环境中同样的代 ...
- Shiro权限验证说明
1.简介 shiro是一个安全框架,是Apache的一个子项目.shiro提供了:认证.授权.加密.会话管理.与web集成.缓存等模块. 1.1.模块介绍 Authentication:用户身份识别, ...
- 虚拟机ubuntu的网络连接类型
图很好 https://jingyan.baidu.com/article/91f5db1b17e8a01c7f05e3e6.html 很详细,有实例 https://www.cnblogs.com/ ...
- css架构技巧
1. 写一个reset.css 用于清除浏览器标签默认样式并定义全局样式,这样就不会因为浏览器默认样式出现问题,因为不同浏览器的默认样式还是不一样的
- rysnc知识梳理
rsync语法: Local: rsync [OPTION...] SRC... [DEST] #<===本地传输数据 Access via remote shell: #<===借助通道 ...
- 杭电-------2043密码(C语言写)
#include<stdio.h> #include<string.h> ]; ] = { '~','!','@','#','$','%','^' }; ] = { }; in ...
- PHP独立环境配置
php 下载地址: http://windows.php.net/download/ Apache 下载地址: http://www.apachelounge.com/download/ mysql ...
- Java基于过滤器进行重定向不成功问题的兩種解決辦法,以及基於JSF的ajax重定向解決辦法
我创建了一个过滤器,只要用户没有登陆就不能连接到主界面,但是在doFilter方法中用重定向在前端跳转页面不成功. 原因:由于我的登陆界面是基于ajax请求的,而ajax默认不支持重定向,他只能局部更 ...
- 【5min+】后台任务的积木。.NetCore中的IHostedService
系列介绍 [五分钟的dotnet]是一个利用您的碎片化时间来学习和丰富.net知识的博文系列.它所包含了.net体系中可能会涉及到的方方面面,比如C#的小细节,AspnetCore,微服务中的.net ...