PostgreSQL源码分析——initdb

news2024/11/24 14:01:28
数据库初始化

在安装完数据库后,需要进行初始化数据库操作,对应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 locales
  COLLATE:  en_US.UTF-8
  CTYPE:    en_US.UTF-8
  MESSAGES: en_US.UTF-8
  MONETARY: zh_CN.UTF-8
  NUMERIC:  zh_CN.UTF-8
  TIME:     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 ... ok

initdb: 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 start

postgres@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.coloradmin.cn/o/1834422.html

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

相关文章

一文读懂-Linux用户和权限

前言 最近换了台公司配的电脑,我的电脑本来就快坏了,结果放家里的门上挂着,pia的一下,摔了,a壳和b壳直接分离掉了(还好公司给配的电脑配置挺高的), 仔细回顾了一下,已经…

Spring Cloud 专题-前言篇(1)

引言 随着微服务架构的兴起,Spring Cloud 作为一套基于 Spring Boot 实现的云应用开发工具集,为开发者提供了在分布式系统(如配置管理、服务发现、断路器、智能路由、微代理、控制总线等)中快速构建一些常见模式的能力。本篇文档…

HTTP 415错误状态码

HTTP 415错误状态码是指"Unsupported Media Type"(不支持的媒体类型)。这通常发生在客户端向服务器发送请求时,请求中包含的媒体类型(例如Content-Type头部)不被服务器支持或识别的情况下。 解决方法&#…

【Linux】进程间通信3——system V进程间通信

1.system V进程间通信 管道通信本质是基于文件的,也就是说操作系统并没有为此做过多的设计工作,而system V IPC是操作系统特地设计的一种通信方式。但是不管怎么样,它们的本质都是一样的,都是在想尽办法让不同的进程看到同一份由操…

哪个充电宝牌子好用又实惠?盘点四大平价充电宝分享

在当今快节奏的生活中,充电宝已成为我们日常生活中不可或缺的一部分。然而,面对市场上琳琅满目的充电宝品牌和型号,许多消费者误以为选择容量越大、价格越高的充电宝就是最好的选择。实际上,买充电宝并不是一味追求高容量和高价格…

首批50辆苏州金龙纯电大巴交付!武汉通勤客运绿色发展提质升级

随着第一缕阳光跃上黄鹤楼的飞檐,城市逐渐苏醒。在车水马龙中,一辆辆通勤班车穿梭其中,确保通勤保障单位人员的安全出行。而这其中就有武汉市雄翔通勤汽车运输有限公司(以下简称“武汉雄翔”)的身影。 5月底&#xff…

MySQL数据库与基本操作(增删改查)

一、数据库的基本概念 数据库要学习的四个基本概念,主要是:数据、数据库系统、数据库、数据管理系统。数据(Date)是描述事物的记录,数据库系统(DBS),数据库管理系统(DBMS…

大学物理(动量定理)

目录 冲量与动量 质点动量定理 质点系动量定理:​编辑 例题 ​编辑 例题 ​编辑 动量守恒定律:。 例题 ​编辑 例题 ​编辑 角动量 ​编辑 例题 ​编辑 力矩与角动量定理​编辑 角动量守恒定律: ​编辑 例题 冲量与动量 质点动量定理 质点系动量定理: 例题 例…

Java的三个接口Comparable,Comparator,Cloneable(浅拷贝与深拷贝)

Comparable 当我们要进行对象的比较的时候&#xff0c;我们是不能直接用>、< 这些符号直接进行比较的。 由于这是引用类型变量也是自定义类型变量&#xff0c;直接进行比较的时候&#xff0c;我们是通过对象的地址进行比较的&#xff0c;我们可以使用、! 进行两个对象的…

用这个神级提示词插件,能让你的AI绘画工具Stable diffusion提示词直接写中文!

大家好&#xff0c;我是设计师阿威 最近&#xff0c;有同学在使用AI绘画工具 Stable Diffusion的时候和我说&#xff1a;老师&#xff0c;我英文不好&#xff0c;能不能直接让我写中文提示词啊&#xff1f;最好可以直接在SD的输入框就能直接写中文&#xff0c;不用切换网页或者…

在有限的分数有限下如何抉择?是选好专业还是选好学校

随着2024年高考的落幕&#xff0c;无数考生和家长站在了人生的重要十字路口。面对成绩单上的数字&#xff0c;一个难题摆在了面前&#xff1a;在分数限制下我们该如何平衡“心仪的专业”与“知名度更高的学校”之间的选择&#xff1f; 一、专业决定未来职业走向 选择一个好的专…

低压电器航空插座端子

低压电器航空插座的定义和功能 低压电器航空插座通常指在交流电压1200V或直流电压1500V以下工作的电器&#xff0c;其主要功能是连接或断开电路&#xff0c;以实现对电路或非电对象的切换、控制、保护、检测、变换和调节。航空插座具有多种芯数和配置&#xff0c;例如2芯、3芯…

Java+Angular+Nginx+RESTful API 医院云HIS系统源码 全国中小型诊所都在用的诊所his系统门诊业务流程 自主版权

JavaAngularNginxRESTful API 医院云HIS系统源码 全国中小型诊所都在用的诊所his系统门诊业务流程 自主版权 HIS系统&#xff08;Hospital Information System&#xff09;在门诊业务中的应用带来了许多显著的优势&#xff0c;这些优势不仅提高了医疗服务的质量和效率&#xf…

如何经营好中医诊所?方法有哪些

在当今竞争激烈的医疗市场中&#xff0c;要想成功经营一家中医诊所&#xff0c;并不仅仅是提供传统的医疗服务&#xff0c;更需要与时俱进的战略思维和精细化的管理。过去被动获客、低效管理的模式已经不再适用&#xff0c;而如何拓展客源、提升服务质量、优化业务模式成为了中…

国际期货常见技术面分析

技术分析方法&#xff1a;通过对市场行为本身的分析来预测价格的变动方向&#xff0c;及主要是对期货市场的日常交易状况&#xff0c;包括价格、交易量与持仓量等数据&#xff0c;按照时间顺序绘制成图形、图表/形成一定的指标系统。然而针对这些图形、图表/指标系统进行分析研…

超多细节—app图标拖动排序实现详解

前言&#xff1a; 最近做了个活动需求大致类似于一个拼图游戏&#xff0c;非常接近于咱们日常app拖动排序的场景。所以想着好好梳理一下&#xff0c;改造改造干脆在此基础上来写一篇实现app拖动排序的文章&#xff0c;跟大家分享下这个大家每天都要接触的场景&#xff0c;到底…

经纬恒润国内首个物理区域控制器量产

当前&#xff0c;智能化汽车的电子电气架构正在从传统的功能域架构向新一代的中央计算加区域控制的架构演进中&#xff0c;国内新能源汽车厂商都在竞相基于新一代架构理念推出新平台车型。物理区域控制器可以实现车辆区域智能传感器及执行器配电、网关路由、信号采集以及执行器…

OpenSearch 与 Elasticsearch主要差异

1. 什么是 Elasticsearch&#xff1f; Elasticsearch 是一个基于 Apache Lucene 构建的开源、RESTful、分布式搜索和分析引擎。它旨在处理大量数据&#xff0c;使其成为日志和事件数据管理的流行选择。 Elasticsearch 还以其实时功能而闻名&#xff0c;允许用户在数据模式发生…

解决linux下载github项目下载不下来,下载失败, 连接失败的问题

第一步&#xff1a;打开/etc/hosts文件 linux vim /etc/hosts 第二步&#xff1a;文件拉到最下面&#xff0c;输入以下内容 linux #GitHub Start 140.82.113.3 github.com 140.82.114.20 gist.github.com 151.101.184.133 assets-cdn.github.com 151.101.184.133 raw.githubus…

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

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