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,一经查实,立即删除!

相关文章

(ab)使用Java 8 FunctionalInterfaces作为本地方法

如果您使用Scala或Ceylon甚至JavaScript等更高级的语言进行编程,则“嵌套函数”或“本地函数”是您非常常见的习惯用法。 例如,您将编写诸如fibonacci函数之类的东西: def f() {def g() "a string!"g() "– says g" …

mysql的配置实现远程访问_MySQL 远程连接配置的正确实现 | 学步园

此文章主要向大家描述的是MySQL远程连接配置的实际操作步骤,以及在其实际操作中值得我们大家注意的相关事项的描述, 以下就是具体方案的描述,希望在你今后的学习中会有所帮助。MySQL远程配置GRANT ALL PRIVILEGES ON *.* TO root% IDENTIFIED…

oracle 用户账户被锁处理

一、以管理员身份登录 SQL> conn sys/sys as sysdba; (分号是必须的但是我是以system登录的所在这不应该写conn sys/sys as sysdba应该写conn system/orcl as sysdba;)Connected. 二、解锁被锁用户SQL> alter user scott account unlock;User alte…

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

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

提高团队协作效率

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

mysql远程访问时间长无反应_远程MySQL访问需要很长时间

Running a MySQL query on a local database takes only about 20-30ms but running the same query through a remote connection(internet) takes 500ms. Is this normal? If not what could be the possible reason for such delay?This is a wireshark time extract for …

c# 利用AForge和百度AI开发实时人脸识别

baiduAIFaceIdentify项目是C#语言,集成百度AI的SDK利用AForge开发的实时人脸识别的小demo,里边包含了人脸检测识别,人脸注册,人脸登录等功能 人脸实时检测识别功能 思路是利用AForge打开摄像头,通过摄像头获取到的图像…

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

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

python读二进制文件遍历_使用python反向读取二进制文件

从这个问题中我可以看出代码中有几点需要改进。首先,while循环在Python中很少使用,因为使用for循环或使用一些内置函数几乎总是有更好的方法来表达相同的内容。在我想代码纯粹是为了培训目的。否则,我会首先问真正的目标是什么(因为知道了问题…

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,…

小看--单例设计模式

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

动态方法注入 grails_Grails动态下拉菜单

动态方法注入 grails最近,我有一个UI要求,客户希望从两个单独的下拉列表中选择值。 第一个下拉列表的值实质上过滤了第二个下拉列表的值。 鉴于我们支持的财务项目对UI的要求并不严格,因此我不得不进行一些初步的学习和试验,以实现…

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类就可以实现多继承的关系。但是在继承类和实现接口的时候&#xff…

js符号转码_JS 文字符串转换unicode编码函数

AJAX传递中文字符串时必须把中文字符串编码成unicode,一般会用到JS的自带函数escape().不过找到了更好的函数来确决中文字符转换成unicode编码的函数function uniencode(text){text escape(text.toString()).replace(/\/g, "%2B");var matches text.match(/(%([0-9…

ASP.NET Core 2.0 MVC 发布部署--------- ASP.NET Core 发布的具体操作

ASP.NET Core 发布的具体操作 下面使用C# 编写的ASP.NET Core Web项目示例说明发布的全过程。 1、创建项目 选择“文件” > “新建” > “项目”。 在“添加新项目”对话框中,在“已安装” “Visaul C#” “Web” 项目类型窗格中选择“ASP.NET Core Web 应用…