PostgreSQL源码分析——initdb

数据库初始化

在安装完数据库后,需要进行初始化数据库操作,对应PostgreSQL数据库中就是需要进行initdb后,才能对数据库进行启动。initdb的过程,其实就是创建数据库实例的过程,生成模板数据库和相应的目录、文件信息,系统表也是在这个阶段生成的。我们想一下,数据库运行都需要什么? 数据库是用来存取数据的,需要有存放数据的目录,执行过程中需要存放WAL日志,需要pg_wal目录存放日志,需要配置文件,最重要的是数据库怎么把一些文件抽象为表,表在数据库中存储形式就是文件,那么怎么对文件进行“解码”呢?那就是系统表,通过系统表,我们知道表中有多少列,每个列是什么类型,有什么约束等等。可以说,系统表是至关重要的。而initdb最重要的事情之一,就是生成系统表。

我们先看一下initdb后,

postgres@slpc:~/pgsql$ ./bin/initdb -D pgdata/
The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.The database cluster will be initialized with localesCOLLATE:  en_US.UTF-8CTYPE:    en_US.UTF-8MESSAGES: en_US.UTF-8MONETARY: zh_CN.UTF-8NUMERIC:  zh_CN.UTF-8TIME:     zh_CN.UTF-8
The default database encoding has accordingly been set to "UTF8".
The default text search configuration will be set to "english".Data page checksums are disabled.fixing permissions on existing directory pgdata ... ok
creating subdirectories ... ok
selecting dynamic shared memory implementation ... posix
selecting default max_connections ... 100
selecting default shared_buffers ... 128MB
selecting default time zone ... Asia/Shanghai
creating configuration files ... ok
running bootstrap script ... ok
performing post-bootstrap initialization ... ok
syncing data to disk ... okinitdb: warning: enabling "trust" authentication for local connections
You can change this by editing pg_hba.conf or using the option -A, or
--auth-local and --auth-host, the next time you run initdb.Success. You can now start the database server using:./bin/pg_ctl -D pgdata/ -l logfile startpostgres@slpc:~/pgsql$ cd pgdata/ && ls
base           pg_logical    pg_stat      pg_wal
global         pg_multixact  pg_stat_tmp  pg_xact
pg_commit_ts   pg_notify     pg_subtrans  postgresql.auto.conf
pg_dynshmem    pg_replslot   pg_tblspc    postgresql.conf
pg_hba.conf    pg_serial     pg_twophase
pg_ident.conf  pg_snapshots  PG_VERSION
源码分析

PostgreSQL初始化流程:

  1. 编译阶段,由genbki.pl脚本读取系统表定义文件(src/backend/catalog/pg_*.h),生成postgres.bki文件
# genbki.pl
#    Perl script that generates postgres.bki and symbol definition
#    headers from specially formatted header files and data files.
#    postgres.bki is used to initialize the postgres template database.
  1. initdb创建目录
  2. initdb生成template1数据库
  3. 由template1生成template0和postgres数据库

其核心的说明可以参考其代码注释:

/* initdb --- initialize a PostgreSQL installation** initdb creates (initializes) a PostgreSQL database cluster (site,* instance, installation, whatever).  A database cluster is a* collection of PostgreSQL databases all managed by the same server.** To create the database cluster, we create the directory that contains* all its data, create the files that hold the global tables, create* a few other control files for it, and create three databases: the* template databases "template0" and "template1", and a default user* database "postgres".** The template databases are ordinary PostgreSQL databases.  template0* is never supposed to change after initdb, whereas template1 can be* changed to add site-local standard data.  Either one can be copied* to produce a new database.** For largely-historical reasons, the template1 database is the one built* by the basic bootstrap process.  After it is complete, template0 and* the default database, postgres, are made just by copying template1.** To create template1, we run the postgres (backend) program in bootstrap* mode and feed it data from the postgres.bki library file.  After this* initial bootstrap phase, some additional stuff is created by normal* SQL commands fed to a standalone backend.  Some of those commands are* just embedded into this program (yeah, it's ugly), but larger chunks* are taken from script files.

现在我们分析一下initdb的源码,核心代码在src/bin/initdb/initdb.c中, 源码的解析可以参考《PostgreSQL数据库内核分析》第2章。

main(int argc, char *argv[])
--> atexit(cleanup_directories_atexit);    // 如果执行失败,清除已创建的目录文件
--> setup_pgdata();                     // 获取PGDATA目录,或从-D 中获取
--> setup_data_file_paths();        
--> initialize_data_directory();--> create_data_directory();        // 创建PGDATA目录--> create_xlog_or_symlink();       // 创建pg_wal目录--> mkdir(path, pg_dir_create_mode) //创建其他的目录,base,global, pg_xact等等--> write_version_file(NULL);       // 创建PG_VERSION文件,写入主版本号, 数据库启动时会检查应用程序与实例版本好是否兼容--> set_null_conf();                // 创建配置文件postgresql.conf--> test_config_settings();--> setup_config();                 // 写配置文件,postgresql.conf pg_hba.conf postgresql.auto.conf--> bootstrap_template1();          // run the BKI script in bootstrap mode to create template1,数据存储在base/1中--> snprintf(cmd, sizeof(cmd), "\"%s\" --boot -x1 -X %u %s %s %s %s", backend_exec, wal_segment_size_mb * (1024 * 1024), data_checksums ? "-k" : "", boot_options, extra_options, debug ? "-d 5" : "");--> PG_CMD_OPEN;for (line = bki_lines; *line != NULL; line++){PG_CMD_PUTS(*line);free(*line);}--> PG_CMD_CLOSE;--> write_version_file("base/1");--> setup_auth(cmdfd);--> setup_run_file(cmdfd, system_constraints_file);--> setup_run_file(cmdfd, system_functions_file);--> setup_depend(cmdfd);--> setup_run_file(cmdfd, system_views_file);--> load_plpgsql(cmdfd);            // load PL/pgSQL server-side language--> vacuum_db(cmdfd);--> make_template0(cmdfd);-->	make_postgres(cmdfd);

创建数据库其实并不是initdb独立去完成的,只是initdb向Postgres进程发送命令,由postgres进程通过--boot进入特殊的bootstrap模式运行执行。bootstrap_template1,这个比较重要,主要是启动postgres进程,执行postgres.bki中特殊的语句,创建系统表。这里说明一下,PG_CMD_OPENPG_CMD_PUTSPG_CMD_CLOSE是什么意思:

#define PG_CMD_OPEN \
do { \cmdfd = popen_check(cmd, "w"); \if (cmdfd == NULL) \exit(1); /* message already printed by popen_check */ \
} while (0)/* Open a subcommand with suitable error messaging */
static FILE * popen_check(const char *command, const char *mode)
{FILE	   *cmdfd;fflush(stdout);fflush(stderr);errno = 0;cmdfd = popen(command, mode);if (cmdfd == NULL)pg_log_error("could not execute command \"%s\": %m", command);return cmdfd;
}

实质是调用popen函数去执行指定的命令。

最后,借用阿里云的分享文档,已加深大家对此的理解。详细文档见PostgreSQL体系结构。

image.png

参考文档:
《PostgreSQL数据库内核分析》 第2章
《openGauss数据库源码解析》 第3章

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

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

相关文章

uniapp小程序限制微信群访问(图文教程)

我有一个微信小程序 “程序员实用资源” 我现在只想让我的微信群可以访问这个小程序的所有功能 所以我必须对我小程序的来源进行限制,让部分功能在正常访问的时候提示没有加群,不可访问,只有从群内点击进入小程序的时候才可以访问这部分功能…

目标检测顶会新成果!20个突破性方法,更高性能,更强理解与分析能力!

【目标检测】在近年来的深度学习领域中备受关注,它通过识别和定位图像中的目标对象,提升了模型在图像理解和分析方面的能力。目标检测技术在自动驾驶、安防监控和医疗影像分析等任务中取得了显著成果。其独特的方法和卓越的表现使其成为研究热点之一。 为…

ESP32蓝牙串口通讯

文章目录 一、前言二、代码三、运行 一、前言 ESP32支持经典蓝牙和低功耗蓝牙(BLE),经典蓝牙可在计算机上模拟出一个串口,使得ESP32可以以串口的方式和计算机通信。 二、代码 #include "BluetoothSerial.h"String device_name …

2025计算机毕业设计选题题目推荐-毕设题目汇总大全

选题在于精,以下是推荐的容易答辩的选题: SpringBoot Vue选题: 基于SpringBoot Vue家政服务系统 基于SpringBoot Vue非物质文化遗产数字化传承 基于SpringBoot Vue兽医站管理系统 基于SpringBoot Vue毕业设计选题管理系统 基于SpringBoot Vue灾害应急救援…

软考中级证在手里,感觉白躺家里了?

软考中级,最适合考的专业是《系统集成项目管理工程师》,特别适合零基础的人! 2022年中级职称的报名条件和要求非常宽松,即使没有学历、零基础和相关工作经验也可以考试!!! 一、职称的含金量 …

docker 中 File Sharing 和Volumes 的区别

在 Docker 中,File Sharing 和 Volumes 都涉及到将文件和目录从主机系统映射到容器中,但它们的用途和实现方式有一些重要的区别: 一、简介 File Sharing 是 Docker Desktop 在 Windows 和 macOS 上的一项功能,允许你将主机文件系…

中国最厉害的改名大师颜廷利:食物的真正人生意义是识悟

在探索人生意义的深邃征途中,我们本应以“识悟”为航标,不断扬帆远航,以实现自我的升华。然而,当回望人世繁华,古往今来,无论男女老少,似乎都在“食物”的陪伴下,徘徊往复&#xff0…

计算机网络复习

2024年whut 概述 1.计算机网络的目标:信息传输和资源共享 2.网络协议的要素(必考): 语法:数据信息和控制信息的结构或格式 语义:要发出何种控制信息,完成何种动作,做出何种响应 同…

safari浏览器无法连接到服务器

问题:MacBook pro,网络连接正常,可以使用各种软件上网,唯独safari浏览器打不开网页,报错说Safari无法连接到服务器; 原因:使用了VPN,VPN自动更改了网络设置,导致Safari浏…

监控局域网电脑屏幕的办法,最简单的三种方法,好用!

在现代企业管理和家庭教育环境中,对局域网内电脑屏幕进行有效监控成为了保障信息安全、提升工作效率和监督行为规范的重要手段。 监控局域网电脑屏幕不仅可以帮助管理者了解员工的工作状态,确保资源的合理使用,还能在一定程度上预防潜在的网…

银行卡归属地查询-银行卡归属地接口-银行卡归属地API

接口简介:通过银行卡号查询国内外银行名称、银行卡卡种、卡品牌以及银行卡发卡省份和城市,支持借记卡和部分贷记卡的发卡省市查询。 若银行卡是农村信用社,归属地无法区分到城市,只能到省份 接口地址:https://www.wapi…

CentOS 7 安装MySQL以及常见问题解决

访问网站:http://repo.mysql.com 找到适配CentOS 7版本的MySQL 的YUM仓库包rpm文件,如下图 下载后,找到安装包的位置 空白处右键,选择在终端打开 查看当前目录下文件 # 安装MySQL 5.7的YUM仓库包rpm -ivh mysql57-community-rele…

中科数安 | 加密管理系统

中科数安提供的加密管理系统是一套全面而高效的数据安全解决方案,旨在保护企业核心文件资料的安全。该系统结合了多种先进的技术手段和管理策略,确保企业数据在存储、传输和使用过程中都得到严格的保护。 www.weaem.com 以下是中科数安加密管理系统的主要…

固定式土壤墒情监测仪—土壤状况进行长期跟踪和分析

TH-TS600 固定式土壤墒情监测仪是一种专门用于长期、连续、自动监测土壤墒情的设备。能够实时监测土壤的水分、温度、湿度等关键参数,确保农民和管理者能即时获取土壤状况信息,便于及时做出农业决策。由于是自动监测,数据采集的准确性和可靠性…

[答疑]订单、预约单的流水号是冗余属性吗

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 陈磊 2024-6-12 20:40 老师好!我学习了软件方法的类图内容,也已经认真做题了,现有一个问题想请老师解惑。 像订单、预约单这样的单据生成的时候&a…

铁砧帝国延迟高?铁砧帝国延迟严重这样解决

铁砧帝国是一款少见的多人在线游戏,游戏能支持上千名玩家建立帝国并互相作战。而且这款游戏在细节方面也做足准备,设计了攻城梯和攻城锤等设备,以攻破坚固的城墙和要塞,不过具体获取方法就需要玩家自己摸索。因为最近开放了测试申…

【免费API推荐】:满足您的开发需求,加速项目上线

免费API助力项目开发,为开发者们提供了强大的支持和工具。这些API提供了各种功能和服务,能够帮助项目开发者们快速构建出高质量的应用。无论是地理位置服务、支付接口、社交媒体集成还是图像识别,这些免费API为项目开发者们提供了丰富的功能和…

Cortex-A510——Cache

Cortex-A510——Cache 小狼http://blog.csdn.net/xiaolangyangyang 1、Cortex-A510 Cache组织结构 以cache-size为32k,cache-line为32Byte为例: 组相连(常用结构):4-way,256-set直接映射:相当于…

supOS浅度集成

一、浅度集成介绍 浅度集成是根据项目或者演示要求而做的集成工作,通过接入supOS的单点登录,UI调整,菜单栏的集成,从而达到客户使用supOS平台来使用各个应用的能力。 二、浅度集成的作用 通过较少的研发投入使APP应用浅度融入到…

uniapp 自定义页面顶部导航栏

效果图 1.移除原生导航栏 {"path": "pages/common/homePage/homePage","style": {"navigationBarTitleText": "","navigationStyle": "custom"} } 2.获取不同手机顶部自带 电量高度、信号、时间导航栏…