Greenplum如何从无到有?Greenplum使用PostgreSQL的初始化机制来初始化集群,PostgreSQL使用initdb创建一个PostgreSQL实例。initdb从无到有创建单个空的可用的PostgreSQL数据库,也就是在一个空的目录中创建PostgreSQL运行所需要的所有文件,包括全局数据字典、控制文件和三个数据库:template0、template1、postgres。由于PostgreSQL自身历史的原因,先创建template1数据库,然后拷贝整个目录成为另外两个数据库。为了创建template1,首先initdb以bootstrap模式运行postgres进程,并使用postgres.bki文件的内容进行初始化;也就是创建PostgreSQL运行需要的重要的元数据,然后通过运行SQL以单节点模式初始化更多元数据。

Initdb

Initdb有大量参数,main()函数入口一开始对各种各样的参数进行检查,然后分为5个阶段进行数据库初始化。
第一阶段,设置数据库安装路径、二进制路径、版本、各种数据模板和locale等,主要函数有:get_restricted_token(),Windows平台相关处理,目的是放弃掉管理员权限,以允许Windows的管理员角色运行initdb初始化数据库;setup_pgdata(),设置PGDATA环境变量,为了运行postgres进程做准备,目的是避免命令行参数引起奇怪的特殊字符转义问题,比如路径中包含空格、#等字符;setup_bin_paths(),设置bin路径,否则找不到postgres二进制文件;effective_user()设置owner信息,如果一起ok,会显示一条输出信息"The files belong to this database system will be owned by user ‘yydzero’. This user must also own the server process.";set_info_version(),从PG_VERSION提取版本信息,后面设置Information schema时需要;setup_data_file_paths(),设置初始化过程中使用的主要数据文件的完整路径,所有数据文件都来自于INSTALLPATH,这些文件包括postgres.bki,postgres.description,postgres.shdescription,pg_hba.conf.sample,pg_indent.conf.sample,postgresql.conf.sample,conversioin_create.sql,information_schema.sql,sql_features.txt,system_views.sql(Greenplum还有一个特定的目录cdb_init.d);setup_locale_encoding(),设置locale编码;setup_text_search(),设置full text search配置。
第二阶段,创建PGDATA目录、其子目录以及三个主要的配置文件和version文件。这个阶段为使用bootstrap模式创建template1做好准备。主要函数有:setup_signals(),设置信号处理函数;create_data_directory(),创建PGDATA目录;create_xlog_or_symlink(),创建WAL日志目录pg_wal;创建PGDATA的子目录,包括global、pg_commit_ts、pg_dynshmem、pg_notify、pg_snapshots、pg_twophase、pg_multixact、base、base/1、pg_replslot、pg_tblspc、pg_xact、pg_stat、pg_logical、pg_distributedlog、log等,其中有的目录为greeplum独有,比如pg_distributedlog;write_version_file(),创建PG_VERSION文件,bootstrapper需要这个文件;setup_config(),设置配置文件,主要有三个配置文件postgresql.conf、pg_hba.conf、pg_ident.conf。
第三阶段,也叫bootstrap,这个阶段使用BKI进行最核心的初始化,主要函数为bootstrap_template1(),该函数以bootstrap模式运行postgres进程,并以BKI文件供养postgres进程,首先对BKI文件中的变量进行替换处理,包括NAMEDATALEN、SIZEOF_POINTER、FLOAT4PASSBYVAL、POSTGRES、ENCODING、LC_COLLATE等,然后使用管道执行命令,输入为BKI数据文件的内容,进程启动命令postgres -boot -x1 -k ‘boot_options’ args,逐行处理BKI文件内容foreach lines: PG_CMD_PUTS(*line),这个函数会输出很多内容,如Creating template1 database in %s/base/1 … OK。
第四阶段,也叫post-bootstrap,主要使用SQL完成剩余的元数据的初始化,write_version_file(“base/1”)创建文件base/1/PG_VERSION,可以用这个文件来判断Initdb的进展;Setup_auth()初始化pg_authid表,主要是回收所有权限,使得任何人都不能读这张表REVOKE ALL on pg_authid FROM public;get_set_pwd()处理passwd;Setup_depend()插入元数据到pg_depend和pg_shdepend;setup_sysviews()从system_views文件读取指令,并逐条执行SQL,完成system views的初始化;setup_description()加载系统对象的description信息,主要信息来自于desc_file文件,也是前面提到的那些安装目录下的元数据文件postgres.description;setup_conversion()加载conversion_create.sql文件;setup_dictionary()加载词典文件,比如snowball_create.sql;setup_privileges()为内建的数据库对象设置权限;setup_schema()加载information_schema.sql文件;load_plpgsql()加载plpgsql并CREATE EXTENSION plpgsql;setup_cdb_schema()创建Greenplem特定的schema,源数据位于cdb_init.d目录下;vacuum_db()运行Analyze和Vacuum freeze。
第五阶段,主要是数据的copy&paste,直接拷贝template1,创建template0和postgres数据库:make_tempalte0()、make_postgres()。

PostgreSQL/Greenplum的三种模式

  • Bootstrap模式:从无到有创建数据库的模式,postgres --boot -x1 -k -F
  • Single模式:单用户模式,只允许单个用户执行SQL命令。Bootstrap创建了最核心的元数据之后使用single模式创建其他数据,对应着postbootstrap阶段
  • Normal模式:多用户的正常模式

postgres命令行参数:
-c:设置run-time参数
-d 1-5:设置表示级别
-F:设置fsync为off
-O:允许修改系统表结构
-W:等待n秒,比方便开发者调试
自举模式:
–boot:指定自举模式
-r:发送标准错误和标准输出到文件中
-x NUM:内部使用
单用户模式:
–single:指定单用户模式
-E:执行前echo语句
-j:不适用换行作为交互式查询的分隔符
-r:发送标准错误和标准输出到文件中

管道技术

BKI数据的处理通过管道技术实现:PG_CMD_OPEN、PG_CMD_CLOSE、PG_CMD_PUTS,底层使用标准C库函数popen、pclose。

故障分析

initdb的noclean选型和debug选项对分析数据库初始化过程中发生的错误很有帮助。