数据库的路上

从数据库源码比较 PostgreSql和OpenGauss的启动过程

测试环境版本:

  • Postgresql 17
  • OpenGauss 6.0

启动命令比较

数据库 启动命令 起始代码文件 执行启动数据库的命令
postgresql pg_ctl start pg_ctl.c 通过execl 调用postgres 程序
opengaussdb gs_ctl start pg_ctl.cpp 通过execl 调用gaussdb 程序

Postgresql的堆栈和具体代码 Postgresql

opengauss的堆栈和具体代码 opengauss

数据库主进程对比

数据库名 主函数路径 进程名
Postgresql src/backend/main/main.c postgres
opengauss src/gausskernel/process/main/main.cpp gaussdb

openGauss 与 PostgreSQL 的 main 函数比较

openGauss 和 PostgreSQL 的 main 函数都是数据库系统的入口点,但它们在实现上有一些重要区别。以下是主要比较点:

相似之处

  1. 基本功能:两者都作为数据库系统的入口点,负责初始化环境并分发到不同的运行模式(如 postmaster、单用户模式、引导模式等)。

  2. 命令行参数处理:都支持类似的命令行参数,如 --help--version--boot--single 等。

  3. 安全检查:都会检查是否以 root 用户运行,并禁止以 root 身份启动数据库。

  4. 本地化设置:都会设置区域信息(locale)。

主要差异

  1. 线程模型 vs 进程模型

    • openGauss 使用线程模型:
      knl_thread_init(MASTER_THREAD);
      t_thrd.fake_session = create_session_context(t_thrd.top_mem_cxt, 0);
      
    • PostgreSQL 使用进程模型,没有线程相关的初始化。
  2. 透明大页(THP)禁用

    • openGauss 在启动时禁用透明大页以优化性能:
      #if defined(ENABLE_LITE_MODE) && defined(__linux__) && defined(PR_SET_THP_DISABLE)
          prctl(PR_SET_THP_DISABLE, 1, 0, 0, 0);
      #endif
      
    • PostgreSQL 没有这个特性。
  3. 云存储支持

    • openGauss 有 OBS(对象存储服务)相关初始化。
    • PostgreSQL 没有云存储集成。
  4. 加密支持

    • openGauss 支持以加密模式运行:
      if (!strcmp(progname, "gs_encrypt")) {
          return encrypte_main(argc, argv);
      }
      
    • PostgreSQL 没有这个特性。
  5. MMAP 阈值设置

    • openGauss 允许通过环境变量设置 MMAP 阈值:
      mmap_env = gs_getenv_r("GAUSS_MMAP_THRESHOLD");
      if (mmap_env != NULL) {
          check_backend_env(mmap_env);
          mmap_threshold = (size_t)atol(mmap_env);
      }
      
    • PostgreSQL 没有这个特性。
  6. 命令行选项

    • openGauss 支持更多的命令行选项,如 -M 指定服务器模式(主、备、待机等)。
    • PostgreSQL 的选项相对较少。

总结

openGauss 的 main 函数在 PostgreSQL 的基础上进行了大量扩展,主要增强了:

  1. 线程模型替代进程模型
  2. 更复杂的内存管理
  3. 性能优化(如禁用透明大页)
  4. 云原生支持
  5. 更丰富的运行模式
  6. 更强的安全特性(如加密支持)

PostmasterMain 函数对比

PostmasterMain 函数是两款数据库的主服务进程入口函数,它负责整个数据库实例的生命周期管理,主要职责包括初始化进程,进程管理,连接管理等,是数据库中最重要的函数之一。

Postmaster 主函数源文件路径
Postgresql src/backend/postmaster/postmaster.c
OpenGauss src/gausskernel/process/postmaster/postmaster.cpp

openGauss 的 PostmasterMain函数与 PostgreSQL 的同名函数有许多相似之处,但也存在显著差异。以下是主要比较点:

相似之处

  1. 基本框架:两者都是数据库服务器的主入口函数,负责初始化系统、处理命令行参数、设置监听端口和启动各种后台进程。

  2. 命令行参数处理:都使用类似的选项解析机制,许多参数如 -D(数据目录)、-p(端口)等保持一致。

  3. 内存管理初始化:都会初始化内存上下文系统,创建 postmaster 内存上下文。

  4. 配置文件处理:都会读取和处理配置文件(postgresql.conf)。

主要差异

  1. 集群模式支持

    • openGauss 增加了 -M 参数支持多种运行模式:
      case 'M':
          if (0 == strncmp(optCtxt.optarg, "primary", strlen("primary"))) {
              t_thrd.xlog_cxt.server_mode = PRIMARY_MODE;
          } else if (0 == strncmp(optCtxt.optarg, "standby", strlen("standby"))) {
              t_thrd.xlog_cxt.server_mode = STANDBY_MODE;
          }
          // 还支持 pending、normal、cascade_standby、hadr_main_standby 等模式
      
  2. 分布式架构支持

    • openGauss 增加了 --coordinator--datanode 选项,支持分布式部署:
      if (name != NULL && strcmp(name, "coordinator") == 0 && value == NULL)
          g_instance.role = VCOORDINATOR;
      else if (name != NULL && strcmp(name, "datanode") == 0 && value == NULL)
          g_instance.role = VDATANODE;
      
  3. 安全特性

    • openGauss 增加了安全模式选项:
      if (name != NULL && strlen(name) == SECURITY_MODE_NAME_LEN &&
          strncmp(name, SECURITY_MODE_NAME, SECURITY_MODE_NAME_LEN) == 0) {
          isSecurityMode = true;
      }
      
  4. 云存储支持

    • openGauss 增加了 OBS(对象存储服务)支持:
      #ifndef ENABLE_LITE_MODE
          initOBSCacheObject();
          S3_init();
      #endif
      
  5. UDF 隔离执行

    • openGauss 增加了 Fenced UDF 模式:
      if (FencedUDFMasterMode) {
          // 初始化线程参数池等
          FencedUDFMasterMain(0, NULL);
          return 0;
      }
      
  6. DSS 设备支持

    • openGauss 增加了分布式存储服务支持:
      if (dss_device_init(...) != DSS_SUCCESS) {
          write_stderr("failed to init dss device\n");
          ExitPostmaster(1);
      }
      
  7. 线程模型

    • openGauss 使用线程而非进程模型:
      t_thrd.proc_cxt.MyProcPid = PostmasterPid = gs_thread_self();
      
    • PostgreSQL 使用进程模型:MyProcPid = PostmasterPid = getpid();
  8. 网络监听处理

    • openGauss 有更复杂的网络监听管理,支持动态重建监听地址:
      static void rebuild_listen_address_socket()
      
  9. 并行恢复配置

    • openGauss 增加了并行恢复相关配置:
      ConfigRecoveryParallelism();
      ProcessRedoCpuBindInfo();
      

总结

openGauss 的 PostmasterMain 函数在 PostgreSQL 的基础上进行了大量扩展,主要增强了:

  1. 企业级特性(安全模式、高可用性)
  2. 分布式架构支持(协调节点、数据节点)
  3. 云原生能力(对象存储集成)
  4. 性能优化(并行恢复、CPU绑定)
  5. 线程模型替代进程模型

这些差异反映了 openGauss 作为企业级数据库的定位,更注重高可用、高性能和云原生特性。

启动完成后进程对比

postgresql 采用的是多进程架构

129644 ?        Ss     0:00 /home/postgres/pgsql/bin/postgres
129645 ?        Ss     0:00  \_ postgres: checkpointer 
129646 ?        Ss     0:00  \_ postgres: background writer 
129648 ?        Ss     0:00  \_ postgres: walwriter 
129649 ?        Ss     0:00  \_ postgres: autovacuum launcher 
129650 ?        Ss     0:00  \_ postgres: logical replication launcher

opengauss 采用的是单进程多线程架构

[opengauss@edc-pdf-dmdb02 include]$ ps -T -p 1085
   PID   SPID TTY          TIME CMD
  1085   1085 ?        00:00:00 gaussdb
  1085   1091 ?        00:00:00 jemalloc_bg_thd
  1085   1141 ?        00:00:00 gaussdb
  1085   1142 ?        00:00:00 syslogger
  1085   1143 ?        00:00:00 auditor
  1085   1144 ?        00:00:00 jemalloc_bg_thd
  1085   1145 ?        00:00:00 alarm
  1085   1146 ?        00:00:00 jemalloc_bg_thd
  1085   1147 ?        00:00:00 reaper
  1085   1148 ?        00:00:00 jemalloc_bg_thd
  1085   1172 ?        00:00:00 gaussdb
  1085   1173 ?        00:00:00 gaussdb
  1085   1174 ?        00:00:00 gaussdb
  1085   1188 ?        00:00:00 checkpointer
  1085   1189 ?        00:00:00 Spbgwriter
  1085   1190 ?        00:00:00 pagewriter
  1085   1191 ?        00:00:00 pagewriter
  1085   1192 ?        00:00:00 pagewriter
  1085   1193 ?        00:00:00 pagewriter
  1085   1194 ?        00:00:00 pagewriter
  1085   1212 ?        00:00:00 WALwriter
  1085   1213 ?        00:00:00 WALwriteraux
  1085   1215 ?        00:00:00 AVClauncher
  1085   1216 ?        00:00:00 Jobscheduler
  1085   1217 ?        00:00:00 asyncundolaunch
  1085   1218 ?        00:00:00 globalstats
  1085   1220 ?        00:00:00 applylauncher
  1085   1221 ?        00:00:00 statscollector
  1085   1222 ?        00:00:00 CfsShrinker
  1085   1223 ?        00:00:00 percentworker
  1085   1224 ?        00:00:00 ashworker
  1085   1226 ?        00:00:00 TrackStmtWorker
  1085   1227 ?        00:00:00 2pccleaner
  1085   1228 ?        00:00:00 faultmonitor
  1085   1229 ?        00:00:00 WLMworker
  1085   1230 ?        00:00:00 WLMmonitor
  1085   1231 ?        00:00:00 WLMarbiter
  1085   1233 ?        00:00:00 undorecycler

总结

从数据库启动流程的视角来看,openGauss在设计构建时大量借鉴了PostgreSQL的理念。在openGauss的代码中,PostgreSQL的影响清晰可辨,许多模块和逻辑都能看到其影子 。同时,openGauss积极创新,增添了一系列关键功能。例如,它支持云存储,满足了当下云计算环境下数据存储的需求;引入分布式架构,提升了系统的扩展性与性能,可应对大规模数据处理任务。此外,openGauss还进行了底层架构的重大变革,将原本的架构改为多线程架构。