postgres的initdb解析——从一次插件升级失败说起
我们公司基于postgres开发了一款数据库产品,不用说我们对OSS的源码做了改动,并且也集成和自己编写了一些插件。因此,当postgresql和相关插件升级时,我们也需要将升级反应到自己的产品中去,这是背景。
这次的问题是在我们升级postgresql的插件orafce(3.2.0-->3.6.0)时发生的。按照往常惯例我们将该插件升级后,组织源码进行编译,OK编译通过。
然而,在我们进行测试时,程序在initdb时就报错停止了。报错如下:
[postgres@localhost data]$ initdb -D `pwd`
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 locale "en_US.UTF-8".
The default database encoding has accordingly been set to "UTF8".
The default text search configuration will be set to "english". (15541)
Data page checksums are disabled. (18153)
fixing permissions on existing directory /data ... ok (15516)
creating subdirectories ... ok (15516)
selecting default max_connections ... 100
selecting default shared_buffers ... 128MB
selecting dynamic shared memory implementation ... posix
creating configuration files ... ok (15516)
creating template1 database in /data/base/1 ... ok (15516)
initializing pg_authid ... ok (15516)
initializing dependencies ... ok (15516)
creating information schema ... FATAL: relation "information_schema.columns" does not exist (10414)
......
(以下省略)
众人费解。只是升级了插件,怎么会导致无法创建initdb呢?
我注意到报错中的这行:
creating information schema ... FATAL: relation "information_schema.columns" does not exist (10414)
似乎挺熟悉?我看看了orafce最新的升级文件。发现在文件中有以下SQL文:
-- Oracle system views
create view oracle.user_tab_columns as
select table_name,
column_name,
data_type,
coalesce(character_maximum_length, numeric_precision) AS data_length,
numeric_precision AS data_precision,
numeric_scale AS data_scale,
is_nullable AS nullable,
ordinal_position AS column_id,
is_updatable AS data_upgraded,
table_schema
from information_schema.columns;
似乎对上了,真的是升级惹的祸?不应该啊,社区应该没这么蠢啊,再说只是个插件,怎么会影响postgres呢?这个时候还没导入插件呢,怎么会存在这个错误?
困惑。
因为我们产品中的postgresql的代码也有我们自己添加的代码,为了确定错误来源,我先取了一份postgresql的source,在contrib目录下放入最新的orafce代码。然后make world。
在运行initdb命令:
(以上省略)
copying template1 to postgres ... ok (15516)
syncing data to disk ... ok (15516)
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:
pg_ctl -D /data -l logfile start
成功了!说明不是OSS的问题。
很好,那么就是我们的修正代码的问题了。然而initdb这一块代码不是我们team维护的,我不知道我们的产品修改了什么。好的,老老实实看看差分代码吧。
结果差分代码一看,initdb.c文件我们就修改了两行代码,看了看,也只是改善性代码,和本次的问题毫无关系。费解。。。。
好吧,既然是initdb出了问题,我看看initdb的代码,理理思路吧。跑过去看看抛出出错信息的代码。再加上自己的整理。大概搞清楚了原因。
具体是什么原因先卖个关子。我们先看看postgresql在initdb时会执行哪些操作(缩进代表调用关系):
main
确保stdout和stderr的缓冲行为与交互式使用中的行为相匹配
设置特定于应用程序的区域设置和服务目录
process command-line options
sync_only模式
密码与服务器认证相关
setup_pgdata()设置pgdata环境
setup_bin_paths()获取postgres命令的路径,判断是否与initdb版本匹配
set_info_version()提取信息模式所需的版本号
setup_data_file_paths() check初始化脚本和配置文件模板
setup_locale_encoding()设置编码方式
setup_text_search()根据encoding设置text search方式
do_sync模式
initialize_data_directory
create_data_directory()创建数据库目录pgdata
create_xlog_or_symlink()创建pgdata下的pg_xlog目录
创建其他子目录
创建并配置postgresql.conf文件
bootstrap_template1()调用postgres在Bootstrap模式下创建模板数据库template1
(以下的配置均针对模板数据库template1)
setup_auth()设置template1的密码表
setup_depend()建立系统表pg_depend,该表描述了数据库对象之间的依赖关系
setup_sysviews()运行脚本system_views.sql创建系统视图★
setup_description()创建系统表pg_description和pg_shdescription
setup_collation()创建系统表pg_collation,该表描述了可用的排序规则,其本质是从一个SQL名字到操作系统locale分类的映射
setup_conversion()运行脚本conversion_create.sql创建系统表pg_conversion,该表描述编码转换过程
setup_dictionary()运行脚本snowball_create.sql创建一些额外的目录
setup_privileges()为postgres内置的一些object设置默认权限
setup_schema()运行脚本information_schema.sql创建模式information_schema★
load_plpgsql()加载plpgsql服务端编程语言
vacuum_db()清理template1
make_template0()根据做好的template1,拷贝复制一份作为template0
make_postgres()根据做好的template1,拷贝复制一份作为postgres
告诉用户initdb执行结束
以上就是initdb的执行过程。很清晰也很简单。其中最重要的是initialize_data_directory()函数。正是该函数一步步地建立起了数据库的基本元素。因此,出问题的地方就在这个函数"内部"。
聪明的朋友可能看出来了,我在上面打了两处"★"。是的,没有错,正是这两块代码的问题,哦不,确切的说是sql的问题。
下面来说。
我们可爱的开发人员在system_views.sql中加入了以下两行(询问发现是客户希望使用orafce功能,但又不想手动创建,想"透明"地使用):
CREATE EXTENSION orafce;
SET search_path TO DEFAULT;
我们知道orafce的初始化引用了 information_schema.columns这个视图,而这个视图在information_schema.sql中被创建。
而由上面的initdb执行过程可以看到:system_views.sql的执行顺序在information_schema.sql之前,也是就说:
我们在初始化 orafce的时候,information_schema.columns还不存在,因此,会在执行system_views.sql时,报以上错误。
知道了原因就很好改了,只要保证加入的那两行sql代码在创建information_schema之后即可~
以上
postgres的initdb解析——从一次插件升级失败说起的更多相关文章
- taskctl命令行类(sh、exe、python新增scp)插件升级扩展
转载自: http://www.taskctl.com/forum/detail_129.html 上次写了一个帖子 TASKCTL中不使用代理,通过ssh免密连接执行远程脚本配置(SSH插件扩展)h ...
- 【Devops】【Jenkins】Jenkins插件安装失败处理方法
本篇解释:Jenkins插件安装失败处理方法 不论是刚启动成功后进行的推荐插件安装,还是后期使用Jenkins过程中进行插件的安装.出现插件安装失败的问题,可以通过本篇解决! [注意,插件下载安装失败 ...
- Sublime Text 无法使用Package Control或插件安装失败的解决方法
Sublime Text用了一年多了,公司搬家近期突然发现Package Control无法安装新插件了.尽管不影响原有功能的使用.还是要解决它.因为本人用Windows系统,仅仅讨论Windosw下 ...
- egret inspect插件安装失败处理方法
egret inspect插件安装失败处理方法谷歌浏览器版本太高不兼容了 换个69就行了 然后点击加载已解压的扩展程序选择EgretInspector-v2.5.5这个文件夹 就安装成功了 重启下浏览 ...
- Jenkins中插件下载失败的解决办法
插件下载失败原因:通过国外服务器下载镜像,有较高的失败率,某些插件下载失败或者中断会引起其他有依赖关系的插件也下载失败 解决方案:1. 使用VPN.2. Jenkins镜像地址改为国内镜像地址:系统管 ...
- 解决 VS Code 中 golang.org 被墙导致的 Go 插件安装失败问题
微软官方开发的 Go for Visual Studio Code 插件为 Go 语言 提供了丰富的支持.在 VS Code 中首次打开 Go 工作区后,VS Code 会自动检测当前开发环境为 Go ...
- Jenkins插件安装失败
插件安装失败 通常要下载国外的软件插件之类的时候,链接到国外会太慢或者被墙,这就需要我们去换镜像源 修改配置文件 我们在jenkins里更改升级站点的url后 若安装插件时还是一直卡在"安装 ...
- json解析—Gson以及GsonFormat插件的运用
最近开始慢慢做毕业设计了,遇到一个功能是获取天气预报的,我选择的是和风天气的api,返回的是JSON数据,所以遇到了解析JSON的问题 首先简单说下JSON,JSON(JavaScript Objec ...
- 小程序解析html标签wxPrase插件
微信小程序的标签和原来我们习惯用的标签是不一样的,例如视图容器标签小程序是view,然而html就很多比如常用的div就和小程序的view类似. 通常我们在开发小程序(从列表页跳转到详情页)通过富文本 ...
随机推荐
- linux apache虚拟主机配置(基于ip,端口,域名)
配置环境: linux版本:Centos6.4 httpd版本: [root@centos64Study init.d]# pwd/etc/init.d[root@centos64Study init ...
- Java贪吃蛇感想
暑假敲代码的效率真的不高呀,一个这种小游戏从最开始构思到最后实施代码,从最开始的Demo版本到最后的第四版本,花了一个星期了.本想再更新一个版本,加入双人对战模式,还想写个AI版,可是我估计按照现在我 ...
- Effective Java 第三版——17. 最小化可变性
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- 使用redis设计一个简单的分布式锁
最近看了有关redis的一些东西,了解了redis的一下命令,就记录一下: redis中的setnx命令: 关于redis的操作命令,我们一般会使用set,get等一系列操作,数据结构也有很多,这里我 ...
- 阿里云服务器Tomcat无法从外部访问
一.环境 阿里云 Ubuntu 12.04.5 LTS tomcat和java都是阿里云默认的7的版本,如下图 二.问题 部署后./startup.sh启动tomcat 之后外部访问http://ip ...
- 0.python class
http://pythonprogramminglanguage.com/ 什么是python? python是一款让你工作比起用其他语言更快的编程语言.老练的程序员用其他的语言会比用python更顺 ...
- 【算法】赫夫曼树(Huffman)的构建和应用(编码、译码)
参考资料 <算法(java)> — — Robert Sedgewick, Kevin Wayne <数据结构> ...
- Spring--AOP(面向切面)编程
AOP 切面就像一把菜刀,将Java处理业务流程进行分割,在分割处添加特定的业务处理.主要应用于声明事务.安全和缓存.在本文中,主要介绍两种切面的实现方法--Java配置和XML配置. Java配置 ...
- 2017 ICPC区域赛(西安站)--- J题 LOL(DP)
题目链接 problem description 5 friends play LOL together . Every one should BAN one character and PICK o ...
- SPATRA的使用
SPATRA是kali里的集成工具,可以自动化渗透测试 在命令行里键入:sparta即可进入 进去后单机左边空白处 输入你要进行渗透测试的IP 正在扫描中 点击bute可以进入hydra