pg数据库学习知识要点分析-1

知识要点1 对象标识OID

在PostgreSQL内部,所有的数据库对象都通过相应的对象标识符(object identifier,oid)进行管理,这些标识符是无符号的4字节整型。数据库对象与相应oid 之间的关系存储在对应的系统目录中,依具体的对象类型而异。例如数据库和堆表对象的 oid 分别存储在pg_database和pg_class中,因此,当你希望找出oid时,可以执行以下查询:

​​​​​​sampledb=# SELECT datname, oid FROM pg_database WHERE datname = 'sampledb';
​​​​ sampledb=# SELECT relname, oid FROM pg_class WHERE relname = 'sampletbl';
​​​​ 

OID不变,但是relfilenode在进行ddl操作后会发生变化。

知识要点2 软件物理结构

1 PGBASE,PGDATA,CONF文件。

4个配置文件

pg_hba.conf 控制PG数据库客户端认证

pg_ident.conf控制用户名映射。

postgresql.conf配置参数

postgresql.auto.conf存储使用alter system调整的参数

表空间文件结构布局

select pg_relation_filepath(sampletbl);

postgres=# select pg_relation_filepath('pg_class');
 base/13593/1259
 

PG中表空间是基础PGDATA目录之外的附加数据区域。8.0版本引入该功能。

执行 CREATE TABLESPACE语句会在指定的目录下创建表空间。在该目录下还会创建版本特定的子目录(例如PG_9.4_201409291)。版本特定的命名方式为:
​​​​​​PG_主版本号_目录版本号​​

例如在/pg/data/ 目录中创建表空间 new_TBLSPC 对应的OID为 16384,则会在表空间下创建一个名为 pg_version_banben的字目录。

cd /pg/data/pg_11.2_20220121/16384

如果在表空间中创建新表,则新表对应的OID值 创建在/pg/data/pg_11.2_20220121/16384中,而且对应的数据段大小可以在初始化时制定大小,超过大小后分裂为OID.1,OID.2文件(热点快数据优化?)。还有表及其他对象对应的管理文件(空闲空间映射,可见性映射等fsm和vm文件)

$PGDATA/pg_tblspc/16384   -------------> /pg/data/

PG进程和内存架构

本地内存区域和共享内存区域。

本地内存区域:由每个后端进程分配供自己使用 类似pga。

1 PG时CS架构,采用多进程架构。

2 PG服务进程是所有进程的父进程。postgres server process.

3 后端进程,backed process负责处理客户端发出的查询语句。

4 各种后台进程background process 负责执行各种数据库管理任务(例如清理过程和存档过程)

5 各种复制进程(replication associate process负责复制流。)

6 pg_ctl start会启动postgres server process父进程,它会在内存中分配共享内存区域,启动各种后台进程。如果有必要还要启动replication并等待客户端的连接请求。有客户端连接它就会启动一个后端进程,然后由后端进程处理该客户端的所有查询请求。(oracle 1-1的专享连接模式)

7 PG没有原生的资源池,可以采用池化中间件pgbouncer pgpool-II

PG后台进程解释

登录pg服务器,使用ps -ef|grep postgres可以发现有很对pg进程以下简要解释下各个后台进程的含义。

background writer 本进程负责吧共享池中的脏页刷新到磁盘中。

checkpointer负责检查点。

autoavcuum launcher自动清理死元组清理工作

WAL writer 预写日志管理。

statistic collector收集统计信息,例如pg_STAT_ACTIVITY,PG_STAT_DATABASE等。

logging collector日志采集统计

archiver wal日志归档。

backed process,例如10.228.11.1:577423 progres格式。

事务标识

每个事务开始时,事务管理器会为其分配一个事务标识 tid,最大值42亿,32位无符号整型。

select txid_current();--查看当前事务的txid。012表示预留的txid。

txid可以互相比较大小,例如txid=100 则小于100的属于过去,大于100的属于未来。

因为txid在逻辑上是无限的,而实际系统中的txid空间不足(4B整型的取值空间大小约42亿),因此PostgreSQL将txid空间视为一个环。对于某个特定的txid,其前约21亿个txid属于过去,其后约21亿个txid属于未来

提交日志PG_XACT

postgresql在提交日志中CLOG,中保存事务的状态,提交日志分配在内存中,并用于事务处理的全过程,

事务状态

postgresql定义了4种事务状态,in_process,commited,aborted和sub commited。

提交日志如何工作

提交日志是一个数组,在共享内存中一些列8K页面组成。数组的序列号代表的事务的标识tid,其内容则是事务的状态,

T1:txid 200提交;txid 200的状态从IN_PROGRESS变为COMMITTED。
T2:txid 201中止;txid 201的状态从IN_PROGRESS变为ABORTED。
txid 不断前进,当 CLOG空间耗尽无法存储新的事务状态时,就会追加分配一个新的页面。
当需要获取事务的状态时,PostgreSQL将调用相应内部函数读取CLOG,并返回所请求事务的状态。
5.4.3 提交日志的维护
当PostgreSQL关机或执行存档过程时,CLOG数据会写入pg_clog子目录下的文件中(注意,在10.0版本中,pg_clog被重命名为pg_xact)。这些文件被命名为0000,0001等。文件的最大尺寸为256 KB。例如当CLOG使用8个页面时,从第1页到第8页的总大小为64 KB,这些数据会写入文件0000(64 KB)中,而当CLOG使用37个页面时(296 KB),数据则会写入0000和0001两个文件中,其大小分别为256 KB和40 KB。
当PostgreSQL启动时会加载存储在pg_clog(pg_xact)中的文件,用其数据初始化CLOG。
CLOG的大小会不断增长,因为只要CLOG一填满就会追加新的页面。但并非所有数据都是必要的。

clog是如何删除的那???

CLOG存储着事务的状态。当更新pg_database.datfrozenxid时, PostgreSQL会尝试删除不必要的CLOG文件。注意,相应的CLOG页面也会被删除。
图 6.7 给出了一个例子。如果 CLOG 文件 0002 中包含最小的 pg_database.datfro zenxid,则可以删除旧文件(0000 和0001),因为存储在这些文件中的所有事务在整个数据库集簇中已经被视为冻结了。

元组

元祖包含的隐藏列

txid xmin xmax ctid 数据。(前面只显示核心的4个字段。)

postgres=# select txid_current(),xmin,xmax,ctid from pg_class limit 10;
          488 |   36 |    0 | (0,46)
          488 |  273 |    0 | (0,47)
          488 |    1 |    0 | (1,19)
          488 |    1 |    0 | (1,20)
          488 |    1 |    0 | (1,21)
          488 |    1 |    0 | (1,22)
          488 |    1 |    0 | (1,23)
          488 |    1 |    0 | (1,24)
          488 |    1 |    0 | (1,25)
          488 |    1 |    0 | (1,26)

postgres=# 

postgres=# 

元组的增删改FSM:用于插入和更新元组的自由空间映射。

通常不需要的元组,在POSTgres中被称为死元组。

增:

在插入中,新元组直接插入目标表的page中,如图所示:

Tuple_1:
· t_xmin设置为99,因为此元组由txid=99的事务所插入。
· t_xmax设置为0,因为此元组尚未被删除或更新。
· t_cid设置为0,因为此元组是由txid=99的事务所执行的第一条命令插入的。
· t_ctid设置为(0,1),指向自身,因为这是该元组的最新版本。

pageinspect
PostgreSQL自带了一个第三方贡献的扩展模块pageinspect,可用于检查数据库页面的具体内容。
​​​​​​testdb=# CREATE EXTENSION pageinspect;
​​​​

CREATE EXTENSION 
​​​​

testdb=# CREATE TABLE tbl (data text);
​​​​

CREATE TABLE
​​​​

testdb=# INSERT INTO tbl VALUES(A);


​​​​INSERT 0 1
​​​​

testdb=# SELECT lp as tuple, t_xmin, t_xmax, t_field3 as t_cid, t_ctid
​​​​                FROM heap_page_items(get_raw_page(tbl, 0));
​​​​

tuple | t_xmin | t_xmax | t_cid | t_ctid
​​​​-------+--------+--------+-------+--------
​​​​    

1 |      99 |       0 |      0 | (0,1)
​​​​(1 row)​​

12.18环境

postgres=# CREATE EXTENSION pageinspect;
​​​​ 
ERROR:  could not open extension control file "/home/postgres/postgresql/share/extension/pageinspect.control": No such file or directory
postgres-# 
 

实验

postgres=# create table test(id int);
CREATE TABLE

postgres=# insert into test select 1;
INSERT 0 1

postgres=# select txid_current(),xmin,xmax,ctid from test limit 10;
 txid_current | xmin | xmax | ctid  
--------------+------+------+-------
          491 |  490 |    0 | (0,1)

postgres=# insert into test select 2;
INSERT 0 1
postgres=# select txid_current(),xmin,xmax,ctid from test limit 10;
 txid_current | xmin | xmax | ctid  
--------------+------+------+-------
          493 |  490 |    0 | (0,1)  ----490事务插入
          493 |  492 |    0 | (0,2)   ----492事务插入

postgres=# update test set id=10;
UPDATE 2

postgres=# select txid_current(),xmin,xmax,ctid from test limit 10;
 txid_current | xmin | xmax | ctid  
--------------+------+------+-------
          495 |  494 |    0 | (0,3)
          495 |  494 |    0 | (0,4)  --全部被494事务更新update。

在删除操作中,目标元组只是在逻辑上被标记为删除。目标元组的t_xmax字段将被设置成delete命令事务的txid。

假设tuple_1被事务111删除,在这种情况下Tuple_1的首部字段被t_xmax设置成111,如果事务txid=111已经提交,就不一定要tuple_1元组,通常不需要的元组此时已经成为死元组。

死元组最终将从页面中被移除,清除死元组的过程称为:VACUUM。

在更新操作中,PG在逻辑上实际执行的是删除最新的元组,并插入一条新的元组。

假设由txid=99的事务插入的行,被txid=100的事务更新两次。
当执行第一条UPDATE命令时,Tuple_1的t_xmax被设为txid 100,在逻辑上被删除,然后Tuple_2被插入,接下来重写Tuple_1的t_ctid以指向Tuple_2。Tuple_1和Tuple_2的头部字段设置如下。
Tuple_1:
· t_xmax被设置为100。
· t_ctid从(0,1)被改写为(0,2)。
Tuple_2:
· t_xmin被设置为100。
· t_xmax被设置为0。
· t_cid被设置为0。
· t_ctid被设置为(0,2)。
当执行第二条UPDATE命令时,和第一条UPDATE命令类似,Tuple_2被逻辑删除,Tuple_3被插入。Tuple_2和Tuple_3的首部字段设置如下。
Tuple_2:
· t_xmax被设置为100。
· t_ctid从(0,2)被改写为(0,3)。
Tuple_3:
· t_xmin被设置为100。
· t_xmax被设置为0。
· t_cid被设置为1。
· t_ctid被设置为(0,3)。
与删除操作类似,如果txid=100的事务已经提交,那么Tuple_1和Tuple_2就成了死元组,而如果txid=100的事务中止,Tuple_2和Tuple_3就成了死元组。

事务快照

select txid_current_snapshot();

xmin:xmax:xip_list。

postgres=# select txid_current_snapshot();
 489:489:

postgres=# 

事务快照是一个数据集,存储某个特定事务在某个特定时间所看到的事务状态信息。哪些事务处于活跃状态(事务正在进行或者还没开始)。事务快照在PostgreSQL内部的文本表示格式为100:100,

100:100 意味着txid<100的事务处于非活跃状态,txid>=100的事务处于活跃状态。

清理过程VACUUM

为了移除死元组,清理过程有另种模式分别为并发清理与完整清理,清理过程会删除表文件每个页面的死元组而其他事务可以在运行时继续读取该表。

完整清理:不仅移除死元组,还会对活的元组进行碎片整理,此时表不可访问。

在8.0以前需要手动清理,直到出现autovacuum守护进程实现自动化。

由于清理过程需要全表扫描,因此代价过于高昂。 可见性映射提高了(VM)移除死元组的效率,并在后期的版本中VM增强。

postgresql  FDW

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/591081.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何使用 Node.js 开发一个文件上传功能?

在 Node.js 中实现文件上传功能可以通过多种方式完成&#xff0c;但其中最常用的方法之一是使用 Express 框架和 Multer 中间件。Express 是一个流行的 Node.js Web 框架&#xff0c;而 Multer 是一个用于处理文件上传的中间件。 步骤 1: 准备工作 首先&#xff0c;确保你已经…

基于Springboot的旅游管理系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的旅游管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&…

数字旅游以科技创新为核心竞争力:推动旅游服务的智能化、高效化,满足游客日益增长的旅游需求

一、引言 随着科技的飞速发展&#xff0c;数字旅游作为旅游业与信息技术结合的产物&#xff0c;正以其独特的魅力改变着传统旅游业的格局。科技创新作为数字旅游的核心竞争力&#xff0c;不仅推动了旅游服务的智能化、高效化&#xff0c;更满足了游客日益增长的旅游需求。本文…

HIVE数据导出

HIVE数据导出 1.INSERT OVERWRITE LOCAL DIRECTORY "路径" SELECT 查询语句; INSERT OVERWRITE LOCAL DIRECTORY "/usr/local/soft/hive-3.1.2/data/output" select * from learn2.partition_student6; 导出数据时 通过执行MapReduce任务导出到本地文件系统…

Python安装win32api

&#x1f4da;博客主页&#xff1a;knighthood2001 ✨公众号&#xff1a;认知up吧 &#xff08;目前正在带领大家一起提升认知&#xff0c;感兴趣可以来围观一下&#xff09; &#x1f383;知识星球&#xff1a;【认知up吧|成长|副业】介绍 ❤️感谢大家点赞&#x1f44d;&…

【云原生】Docker 实践(二):什么是 Docker 的镜像

【Docker 实践】系列共包含以下几篇文章&#xff1a; Docker 实践&#xff08;一&#xff09;&#xff1a;在 Docker 中部署第一个应用Docker 实践&#xff08;二&#xff09;&#xff1a;什么是 Docker 的镜像Docker 实践&#xff08;三&#xff09;&#xff1a;使用 Dockerf…

【neteq】tgcall的调用

G:\CDN\P2P-DEV\Libraries\tg_owt\src\call\call.cc基本是按照原生webrtc的来的:G:\CDN\P2P-DEV\tdesktop-offical\Telegram\ThirdParty\tgcalls\tgcalls\group\GroupInstanceCustomImpl.cpptg对neteq的使用 worker 线程创建call Call的config需要neteqfactory Call::CreateAu…

Git可视化工具tortoisegit 的下载与使用

一、tortoisegit 介绍 TortoiseGit 是一个非常实用的版本控制工具&#xff0c;主要用于与 Git 版本控制系统配合使用。 它的主要特点包括&#xff1a; 图形化界面&#xff1a;提供了直观、方便的操作界面&#xff0c;让用户更易于理解和管理版本控制。与 Windows 资源管理器…

MATLAB中自定义栅格数据地理坐标R,利用geotifwrite写入tif

场景描述&#xff1a; 有时候将nc格式的数据转成tiff&#xff0c;或者是将一个矩阵输出成带有地理坐标信息tiff数据时&#xff0c;常常涉及到空间参考的定义和geotiffwrite()函数。 问题描述&#xff1a; 以全球数据为例&#xff0c;今天发现在matlab中对矩阵进行显示后&…

android zygote进程启动流程

一&#xff0c;启动入口 app_main.cpp int main(int argc, char* const argv[]) {if (!LOG_NDEBUG) {String8 argv_String;for (int i 0; i < argc; i) {argv_String.append("\"");argv_String.append(argv[i]);argv_String.append("\" ")…

DiffSeg——基于Stable Diffusion的无监督零样本图像分割

概述 基于计算机视觉的模型的核心挑战之一是生成高质量的分割掩模。大规模监督训练的最新进展已经实现了跨各种图像风格的零样本分割。此外&#xff0c;无监督训练简化了分割&#xff0c;无需大量注释。尽管取得了这些进展&#xff0c;构建一个能够在没有注释的零样本设置中分…

ElementUI从unpkg.com完整下载到本地的方法 - 解决unpkg.com不稳定的问题 - 自建镜像站 - 不想打包只想cdn一下

方法 方法1&#xff09;随便弄个文件夹&#xff0c;根据官网npm方法下载包&#xff0c;提取即可 npm i element-ui -S cd /node_modules/element-ui/ ls src 安装npm方法&#xff1a;https://nodejs.org/en 方法2&#xff09;不推荐 - 在github中搜索对应的库zip包&#xff0…

视频编辑软件pitivi基本功之将三个相关视频合并成一个视频

视频编辑软件pitivi基本功之将三个相关视频合并成一个视频 一、素材来源&#xff1a;网站下载 到http://cpc.people.com.cn/GB/67481/435238/437822/437828/437900/index.html下载以下三个视频&#xff0c;鼠标右击视频——另存视频为 庆祝中国共产党成立100周年大会即将开始—…

用keras识别狗狗

一、需求场景 从照片从识别出狗狗 from keras.applications.resnet50 import ResNet50 from keras.preprocessing import image from keras.applications.resnet50 import preprocess_input, decode_predictions import numpy as np# 加载预训练的ResNet50模型 model ResNet5…

240503-关于Unity的二三事

240503-关于Unity的二三事 1 常用快捷键 快捷键描述CtrlP播放/停止Ctrl1打开Scene窗口Ctrl2打开Game窗口Ctrl3打开Inspect窗口Ctrl4打开Hierarchy窗口Ctrl5打开Project窗口Ctrl6打开Animation窗口 2 关联VisualStudio2022 3 节约时间&#xff1a;将最新声明的参数移动到最上…

华为机考入门python3--(20)牛客20- 密码验证合格程序

分类&#xff1a;字符串 知识点&#xff1a; 遍历字符串的每个字符 for char in my_str: 可以直接比较字符范围 a < char < z 列表统计元素个数 my_list.count(elem) 寻找子串 my_str.find(sub_str) 题目来自【牛客】 import re import sysdef check_…

【算法系列】字符串

目录 leetcode题目 一、最长公共前缀 二、最长回文子串 三、二进制求和 四、字符串相加 五、字符串相乘 六、仅仅反转字母 七、字符串最后一个单词的长度 八、验证回文串 九、反转字符串 十、反转字符串 II 十一、反转字符串中的单词 III leetcode题目 一、最长公…

如何使用提示测试为LLMs构建单元测试?

原文地址&#xff1a;how-to-build-unit-tests-for-llms-using-prompt-testing 确保您的人工智能交付&#xff1a;快速测试完美生成应用程序的基本指南 2024 年 4 月 26 日 如果你曾经编写过软件&#xff0c;你就会知道测试是开发过程中必不可少的一部分。特别是单元测试&#…

华为机考入门python3--(19)牛客19- 简单错误记录

分类&#xff1a;字符串 知识点&#xff1a; 分割字符串 my_str.split(\\) 字符串只保留最后16位字符 my_str[-16:] 列表可以作为队列、栈 添加元素到第一个位置 my_list.insert(0, elem) 增加元素到最后一个位置 my_list.append(elem) 删除第一个 my_list.pop(0)…

Redis---------实现商品秒杀业务,包括唯一ID,超卖问题,分布式锁

订单ID必须是唯一 唯一ID构成&#xff1a; 代码生成唯一ID&#xff1a; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Component; import java.time.LocalDateTime; import java.time.ZoneOffset; import java.tim…
最新文章