mysql vacuum_PostgreSQL DBA快速入门(四) - 体系架构

99076ec0b6f13d8d85e48fcdf3d3fbde.png PostgreSQL在开源关系型数据库市场是最先进的数据库。他的第一个版本在1989年发布,从那时开始,他得到了很多扩展。根据db-enginers上的排名情况,PostgreSQL目前在数据库领域排名第四。

本篇博客,我们来讨论一下PostgreSQL的内部架构,以及各个组件之间如何交互。这将是本期PostgreSQL DBA系列博客的基石。

一、PostgreSQL的架构

PostgreSQL的物理架构非常简单,它由共享内存、一系列后台进程和数据文件组成。 (如下图)

81270a1484ffa2a1f64928e5f0fc6405.png

二、Shared Memory

共享内存是服务器服务器为数据库缓存和事务日志缓存预留的内存缓存空间。其中最重要的组成部分是Shared Buffer和WAL Buffer。

Shared Buffer

Shared Buffer的目的是减少磁盘IO。为了达到这个目的,必须满足以下规则:

当需要快速访问非常大的缓存时(10G、100G等)

如果有很多用户同时使用缓存,需要将内容尽量缩小

频繁访问的磁盘块必须长期放在缓存中

WAL Buffer

WAL Buffer是用来临时存储数据库变化的缓存区域。存储在WAL Buffer中的内容会根据提前定义好的时间点参数要求写入到磁盘的WAL文件中。在备份和恢复的场景下,WAL Buffer和WAL文件是极其重要的。

三、PostgreSQL 进程类型

PostgreSQL有四种进程类型

Postmaster (Daemon) Process(主后台驻留进程)

Background Process(后台进程)

Backend Process(后端进程)

Client Process(客户端进程)

Postmaster Process

主后台驻留进程是PostgreSQL启动时第一个启动的进程。启动时,他会执行恢复、初始化共享内存爱你的运行后台进程操作。正常服役期间,当有客户端发起链接请求时,它还负责创建后端进程。

132865ad3df2730a8a762efc59ea4f69.png

如果通过pstree命令查看进程之间的关系,你会发现Postmaster进程是其他所有进程的父进程。

d3b661ecf7d0ea526003493c44090ed8.png

Background Process

PostgreSQL操作需要的后台进程列表如下:

进程

作用

logger

将错误信息写到log日志中

checkpointer

当检查点出现时,将脏内存块写到数据文件

writer

周期性的将脏内存块写入文件

wal writer

将WAL缓存写入WAL文件

Autovacuum launcher

当自动vacuum被启用时,用来派生autovacuum工作进程。autovacuum进程的作用是在需要时自动对膨胀表执行vacuum操作。

archiver

在归档模式下时,复制WAL文件到特定的路径下。

stats collector

用来收集数据库统计信息,例如会话执行信息统计(使用pg_stat_activity视图)和表使用信息统计(pg_stat_all_tables视图)

Backend Process

最大后台链接数通过max_connections参数设定,默认值为100。后端进程用于处理前端用户请求并返回结果。查询运行时需要一些内存结构,就是所谓的本地内存(local memory)。本地内存涉及的主要参数有:

work_mem:用于排序、位图索引、哈希链接和合并链接操作。默认值为4MB。

maintenance_work_mem:用于vacuum和创建索引操作。默认值为64MB。

temp_buffers:用于临时表。默认值为8MB。

Client Process

客户端进程需要和后端进程配合使用,处理每一个客户链接。通常情况下,Postmaster进程会派生一个紫禁城用来处理用户链接。

四、数据库结构

想要理解PostgreSQL的数据库结构,需要先了解一些重要的概念。

数据库相关概念:

PostgreSQL由一系列数据库组成。一套PostgreSQL程序称之为一个数据库群集。

当initdb()命令执行后,template0 , template1 , 和postgres数据库被创建。

template0和template1数据库是创建用户数据库时使用的模版数据库,他们包含系统元数据表。

initdb()刚完成后,template0和template1数据库中的表是一样的。但是template1数据库可以根据用户需要创建对象。

用户数据库是通过克隆template1数据库来创建的;

表空间相关概念:

initdb()后马上创建pg_default和pg_global表空间。

建表时如果没有指定特定的表空间,表默认被存在pg_default表空间中。

用于管理整个数据库集群的表默认被存储在pg_global表空间中。

pg_default表空间的物理位置为$PGDATA\base目录。

pg_global表空间的物理位置为$PGDATA\global目录。

一个表空间可以被多个数据库同时使用。此时,每一个数据库都会在表空间路径下创建为一个新的子路径。

创建一个用户表空间会在$PGDATA\pg_tblspc目录下面创建一个软连接,连接到表空间制定的目录位置。

表相关概念:

每个表有三个数据文件。

一个文件用于存储数据,文件名是表的OID。

一个文件用于管理表的空闲空间,文件名是OID_fsm。

一个文件用于管理表的块是否可见,文件名是OID_vm。

索引没有_vm文件,只有OID和OID_fsm两个文件

其他需要注意的地方

表和索引创建时文件名是OID,此时的OID和pg_class.relfilenode的值是一样的。不管怎样,当我们执行重写操作时(truncate,cluster,vacuum full,reindex等),被修改对象的relfilenode值也会被修改,文件名也会随着reffilenode值一起改变。我们可以通过pg_relation_filepath('')视图很容易的检查文件位置和名称。

五、运行测试

initdb()完成后,如果登录数据库查询视图pg_database,我们可以看到template0 , template1和 postgres数据库已经被创建好了。

849d55f828eb03d908e9e0bb2b6e88b4.png

通过datistemplate列,我们可以看到template0和template1是用户创建数据库时使用的模版数据库,其他的都不是模版数据库。

通过datlowconn列,可以看出该数据库是否允许访问。因为template0数据库不能被访问,所以该数据库的内容不能被修改。

设置两个模版数据库的原因是template0是初始状态,而template1数据库则是可以集成用户某些需求的模版数据库。

postgres数据库时使用模版template1创建的默认数据库,如果链接时不指定数据库名称,默认连接到postgres数据库。

数据库存储在$PGDATA\base目录下。路径的名称和数据库OID的名称一致。

315ee22e077b28c3b352a5f91bb4842f.png

六、创建用户数据库

上文提过,用户数据库创建是通过克隆template1数据库。为了验证这个规则,我们现在template1中创建一个表t1,紧接着创建一个mydb01数据库,检查t1表是否在mydb01中存在。

9337e21e58581154e9273d47d1ebb379.png

pg_default tablespace

initdb()后,如果登录数据库查询pg_tablespace视图,会发现pg_global和pg_default表空间已经创建好。

c0857cafb31c4f7c598b6d89e1b432ab.png

pg_default表空间的位置为$PGDATA\base。每一个数据库都拥有一个以自己OID命令的子路径。

b5e48befb9238c57e28649263d29a542.png

pg_global表空间

pg_global表空间用于存储集群级别的数据。

例如pg_开头的表

pg_global表空间路径为$PGDATA\global.

七、创建用户表空间

pg_tablespace视图显示myts01表空间已经被创建好。

f7643a46b416fa602857e781e3cc121a.png

$PGDATA/pg_tblspc路径下有一个符号链接指到目标目录。

1886518294cd457703f57fb39a5a3930.png

下面分别连接到postgres和mydb01数据库,创建表。

a94f8e141881d5961f75bba7581dbf15.png

如果查看/data01路径下的内容,会发现上面创建的两个数据库中的t1表,分别在下面有一个对应OID的文件夹存在。

65d0ca73b1e6da2476556557ccbb699f.png

修改表空间位置

PostgreSQL在创建表空间时指定一个特定的路径。因此,如果该特定路径已经满了,数据就不能在向里面存储了。为了解决该问题,我们可以使用磁盘管理程序扩展空间。但是如果不想使用磁盘管理程序,我们可以通过该表表空间的位置来解决该问题。命令如下:

bc26636dcdfa8b8eb047aa34b4ecdc31.png

八、Vacuum是什么?

vacuum执行如下操作:

收集表和索引的统计信息

整理表

清理表和索引中的死亡块

被XID冻结,防止XID回绕

#1 和 #2 是数据库管理需要的。#3 和 #4 PostgreSQL MVCC 特性的要求。

九、PostgreSQL和Oracle MySQL之间的区别

二者之间最大的不同是MVCC模型和共享池(shared pool)。

指标

ORACLE

PostgreSQL

MVCC模型

UNDO

Store previous

实现方法

Segment

record within block

共享池

exists

it does not exist

MVCC模型的区别

为了增加并发,必须遵循“读操作不阻塞写操作,写操作不阻塞读操作”的原则。为了实现这个原则,多版本并发控制(MVCC)理论被引入。Oracle使用UNDO段实现MVCC。而PostgreSQL存储之前的记录在数据块中,它通过事务XID和事务的xmin、xmax来控制事务版本。

Shared Pool

PostgreSQL不提供共享池。这对于熟悉Oracle的用户来说有点尴尬。共享池是Oracle中最基本和最重要的组件。PostgreSQL在进程级别提供SQL信息的共享能力,而不是共享池。换句话说,如果我们在同一个进程中多次执行相同的SQL,它只会硬解析一次。

非常感谢拜读本篇博客,下次再见~

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

总结mysql的基础语法_mysql 基础sql语法总结 (二)DML

二、DML(增、删、改)1)插入数据第一种写法:INSERT INTO 表名 (列名1,列名2,,......)VALUES(列值1,列值2,......)第二种写法:INSERT INTO 表名 VALUES(列值1,列值2,......…

提高团队协作效率

提高团队协作效率 分工合理,责任明确 团队是由个人组成的,团队中的个人往往经历不同、背景不同、性格有差异、水平有高低。在团队形成后、正式开工前,首先应该进行合理分工,要结合每个 人的特点和爱好,充分发挥出每个人…

Java中Array和ArrayList之间的9个区别

array和ArrayList都是Java中两个重要的数据结构,在Java程序中经常使用。 即使ArrayList在内部由数组支持,了解Java中的数组和ArrayList之间的差异对于成为一名优秀的Java开发人员也至关重要。 如果您知道相似点和不同点,则可以明智地决定何时…

vue 在已有的购买列表中(数据库返回的数据)修改商品数量

连续加班一个月 连续通宵三天 到最后还是少了一个功能 心碎 简介:一个生成好的商品列表(数据库返回的数据) 首先拿到我们需要渲染的数组 在data中定义 我是在测试的时候 直接写了两条数据 下面开始点击删除 点击添加是一样的代码 只不过加号…

python饼状图教程_Python数据可视化:饼状图的实例讲解

使用python实现论文里面的饼状图:原图:python代码实现:# # 饼状图# plot.figure(figsize(8,8))labels [uCanteen, uSupermarket, uDorm, uOthers]sizes [73, 21, 4, 2]colors [red, yellow, blue, green]explode (0.05, 0, 0, 0)patches,…

小看--单例设计模式

(一)单例设计描述 只要了解过设计模式的同学都会知道:单例设计模式,大家都知道单例设计模式是一种创建行的设计模式。既然是创建型,那么先来讲讲,对象的创建的过程吧。 --静态成员:静态成员在程…

selenium原理python_从python角度解析selenium原理

1、selenium工作流程2、selenium工作原理(1)客户端和服务端之间实际是通过http协议进行通信,服务端的接口文档可参考:https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#sessionsessionidelement(2)客户端按照服务端接口要求传入请求方式、…

Jmeter(二)Jmeter目录介绍

看过许多有关Jmeter的博客,算得上的收获颇丰;不过最牛逼的博客还是“官方文档”,官方文档是ApacheJmeter自己对自己产品的说明,论起对自己产品的理解程度,那肯定是自己嘛。。。因此推荐大家从Jmeter的官方文档开始学习…

使用Spring Data MongoDB和Spring Boot进行数据聚合

MongoDB聚合框架旨在对文档进行分组并将其转换为聚合结果。 聚合查询包括定义将在管道中执行的几个阶段。 如果您对有关该框架的更深入的细节感兴趣,那么 mongodb docs是一个很好的起点。 这篇文章的重点是编写一个用于查询mongodb的Web应用程序,以便从…

结合前段修改mysql表数据_jquery实现点击文字可编辑并修改保存至数据库

这个方法网上可以查到很多,但是好多只有点击文字编辑并保持,但是没有完整的代码写怎么保存到数据库。因为本人才疏学浅,费啦好长时间才写好把修改的内容只用一条sql语句保存到数据库,今天在这里和大家分享这是运行图片这是前台页面…

java 设置两个方法互斥_分享两个操作Java枚举的实用方法

1. 前言Java枚举在开发中是非常实用的。今天再来分析几个小技巧并且回答一些同学的的疑问。首先要说明的是我的枚举建立在以下的范式之中:枚举统一接口范式2. 如何把枚举值绑定的下拉列表这种场景非常常见,如果你把状态、类别等属性封装成枚举的结构&…

Spring管理的交易说明-第2部分(JPA)

在本系列的第一部分中 ,我展示了事务如何在普通JDBC中工作 。 然后,我展示了Spring如何管理基于JDBC的事务。 在本系列的第二部分中,我将首先展示事务如何在普通的JPA中工作。 然后展示Spring如何管理基于JPA的事务。 资金转移 为了帮助说明…

CCC数字钥匙设计【BLE】--车主配对之BLE OOB配对

本文主要介绍CCC3.0采用BLE进行车主配对时,关于蓝牙OOB配对的内容。 首先,介绍下BLE Pairing的一些基础知识,有一些基本概念。之后,再着重介绍CCC规范定义的BLE OOB配对流程。 1、BLE Pairing基础知识 下面先简单介绍下BLE 5.0协…

Linux 查看内存状态

# 查看系统内存 命令:free 注:默认k单位显示注:-m 以MB注:-g以GB 单位显示total used free shared buffers cached Mem: 497 463 33 0 13 124 -/ buffe…

Altium Designer导入pcb原件之后都是绿的

转载于:https://www.cnblogs.com/chulin/p/8342041.html

在JConsole和VisualVM中查看DiagnosticCommandMBean

我已经将JConsole用作合适的通用JMX客户端已有很多年了。 该工具通常随Oracle JDK一起提供,并且易于使用。 在JMX交互方面,JConsole优于VisualVM的最大优点是JConsole带有内置的MBeans选项卡,而必须为VisualVM中的相同功能应用插件。 但是&am…

人人商城生成app教程_人人商城APP打包教程(APICLOUD版)

一.APP环境搭建和配置编译1.登录APICLOUD后台新建应用step1 注册账号注册apicloud 账号并登录APICLOUD控制台step2 新建应用再账户下面找到开发控制台>开发控制台>创建应用 填写应用名和说明,必选Native App创建Native App2 .开发工具下载安装APICLOUD开发工具…

WPF快速入门系列(2)——深入解析依赖属性

一、引言 感觉最近都颓废了,好久没有学习写博文了,出于负罪感,今天强烈逼迫自己开始更新WPF系列。尽管最近看到一篇WPF技术是否老矣的文章,但是还是不能阻止我系统学习WPF。今天继续分享WPF中一个最重要的知识点——依赖属性。 二…

圆台下料展开计算方法_怎么画 圆锥台展开图

展开全部1、 画出圆台的主视抄图(等腰梯形)袭:圆台的上bai下底直径为等腰梯形du的上zhi下底,圆台的高为等dao腰梯形的高;2、将等腰梯形补画成等腰三角形;(图中的虚线三角形即为补画部分);3、以三角形的顶点为圆心&…

.31-浅析webpack源码之doResolve事件流(3)

放个流程图: 这里也放一下request对象内容,这节完事后如下(把vue-cli的package.json也复制过来了): /*{ context: { issuer: , compiler: undefined },path: d:\\workspace\\doc,request: ./input.js,query: ,module: false,directory: false…