文档章节

PostgreSQL的pg_depend详解

kenyon_君羊
 kenyon_君羊
发布于 2014/04/25 18:49
字数 1016
阅读 507
收藏 0
pg_depend是postgres的一张系统表,用来记录数据库对象之间的依赖关系,除了常见的主外键,还有其他一些内部依赖关系,可以通过这个系统表呈现出来。

一、表结构:
postgres=# \d+ pg_depend
                       Table "pg_catalog.pg_depend"
   Column    |  Type   | Modifiers | Storage | Stats target | Description 
-------------+---------+-----------+---------+--------------+-------------
 classid     | oid     | not null  | plain   |              | 系统OID
 objid       | oid     | not null  | plain   |              | 对象OID
 objsubid    | integer | not null  | plain   |              | 
 refclassid  | oid     | not null  | plain   |              | 引用系统OID
 refobjid    | oid     | not null  | plain   |              | 引用对象ID
 refobjsubid | integer | not null  | plain   |              | 
 deptype     | "char"  | not null  | plain   |              | pg_depend类型
Indexes:
    "pg_depend_depender_index" btree (classid, objid, objsubid)
    "pg_depend_reference_index" btree (refclassid, refobjid, refobjsubid)
Has OIDs: no

--BTW:OID是Object Identifier的缩写,是对象ID的意思,因为是无符号的4字节类型,不够足够大,所以一般不用来做主键使用,仅系统内部,比如系统表等应用,可以与一些整型数字进行转换。与之相关的系统参数是default_with_oids,默认是off

pg_depend.deptype字段类型9.1之后多了一个extension的类型,目前类型有
DEPENDENCY_NORMAL (n)     :普通的依赖对象,如表与schema的关系
DEPENDENCY_AUTO (a)       :自动的依赖对象,如主键约束
DEPENDENCY_INTERNAL (i)   :内部的依赖对象,通常是对象本身
DEPENDENCY_EXTENSION (e)  :9.1新增的的扩展依赖
DEPENDENCY_PIN (p)        :系统内置的依赖

二、例子
wiki上有一个SQL可以列出系统和用户对象的各种依赖关系,低版本的可以看wiki上的另一个写法
SELECT classid::regclass AS "depender object class",
    CASE classid
        WHEN 'pg_class'::regclass THEN objid::regclass::text
        WHEN 'pg_type'::regclass THEN objid::regtype::text
        WHEN 'pg_proc'::regclass THEN objid::regprocedure::text
        ELSE objid::text 
    END AS "depender object identity",
    objsubid,
    refclassid::regclass AS "referenced object class",
    CASE refclassid
        WHEN 'pg_class'::regclass THEN refobjid::regclass::text
        WHEN 'pg_type'::regclass THEN refobjid::regtype::text
        WHEN 'pg_proc'::regclass THEN refobjid::regprocedure::text
        ELSE refobjid::text
    END AS "referenced object identity",
    refobjsubid,
    CASE deptype
        WHEN 'p' THEN 'pinned'
        WHEN 'i' THEN 'internal'
        WHEN 'a' THEN 'automatic'
        WHEN 'n' THEN 'normal'
    END AS "dependency type"
FROM pg_catalog.pg_depend WHERE (objid >= 16384 OR refobjid >= 16384);

BTW:我通常喜欢在where后面加个条件  and deptype <>'i'  排除internal依赖
建一张普通的表,执行上面的SQL
postgres=# create table tbl_parent(id int);
CREATE TABLE
postgres=# 执行上面的SQL;
 depender object class | depender object identity | objsubid | referenced object class | referenced object identity | refobjsubid | dependency type 
-----------------------+--------------------------+----------+-------------------------+------------- pg_class              | tbl_parent               |        0 | pg_namespace            | 2200                       |           0 | normal
(1 row)

--普通用户来看只是建了个表,但是没有约束,其实因为这个表是建立在schema下面,表是依赖于schema上面的
加一个主键约束
postgres=# alter table tbl_parent add primary key(id);
ALTER TABLE
 depender object class | depender object identity | objsubid | referenced object class | referenced object identity | refobjsubid | dependency type 
-----------------------+--------------------------+----------+-------------------------+------- pg_class              | tbl_parent               |        0 | pg_namespace            | 2200                       |           0 | normal
 pg_constraint         | 16469                    |        0 | pg_class                | tbl_parent                 |           1 | automatic
(2 rows)
--多了一个约束的信息,下面的这条信息表明这个主键约束是依赖于表上的,并且是自动模式,详细信息可以在系统表pg_constrant里面查询
三、非正常删除
正常情况下用户删除有依赖关系的对象时会提示需要先删除最里层没依赖的对象,但是如果通过删除系统表,但又删得不对,就会导致异常,比如上面这个例子会出现 cache lookup failed for constraint 
postgres=# select oid,conname,connamespace,contype from pg_constraint where conname like 'tbl_parent%';
  oid  |     conname     | connamespace | contype 
-------+-----------------+--------------+---------
 16469 | tbl_parent_pkey |         2200 | p
(1 row)

postgres=# delete from pg_constraint where conname like 'tbl_parent%';
DELETE 1
postgres=# select oid,conname,connamespace,contype from pg_constraint where conname like 'tbl_parent%';
 oid | conname | connamespace | contype 
-----+---------+--------------+---------
(0 rows)

postgres=# drop table tbl_parent;
ERROR:  cache lookup failed for constraint 16469   --16496是约束的OID
postgres=# 
--出现这个问题,是因为手工把约束对象删除了,但是在pg_depend依赖关系里面却仍然存在关系,所以删除该表时发现最里层的依赖对象找不到了就报错了,
解决:
1.手工恢复该表的约束对象,比较难也比较烦
2.删除该表所有的系统依赖信息 上面的问题需要删除
postgres=# delete from pg_depend where objid = 16469 or refobjid = 16469 ;
DELETE 2
postgres=# drop table tbl_parent;
DROP TABLE
3.要说一点的是不要去手工删除一些系统表信息来达到删除约束的目的,容易因删不干净而造成各种异常

参考:
http://wiki.postgresql.org/wiki/Pg_depend_display

© 著作权归作者所有

共有 人打赏支持
kenyon_君羊
粉丝 499
博文 170
码字总数 121714
作品 0
杭州
其他
私信 提问
加载中

评论(2)

kenyon_君羊
kenyon_君羊

引用来自“sunday12345”的评论

呃,这篇文章,分类到了:Oracle管理 。。。
调整了,3Q
sunday12345
sunday12345
呃,这篇文章,分类到了:Oracle管理 。。。
PostgreSQL 自动创建分区实践 - 写入触发器

标签 PostgreSQL , 自动创建分区 , 触发器 , 写入 , 动态创建分区 背景 数据写入时,自动创建分区。 目前pg_pathman这个分区插件,有这个功能,如果你不是用的这个插件,可以考虑一下用触发器...

德哥
2018/06/21
0
0
Postgres XL FAQ

Q. What does XL stand for? XL is short for eXtensible Lattice. It also connotes an extra large version of PostgreSQL, in this case across multiple systems. Q. Is this a “NoSQL......

javasql
2014/07/31
0
0
postgresql9.6主从高可用源码环境编译配置详解

系统版本:centos7 8核 32G内存 主从服务器IP: 192.168.125.33 postgreSQL master 192.168.125.34 postgreSQL slave 1、创建数据库管理账户 # groupadd pggroup # useradd -g pggroup pgus......

断臂人
01/06
0
0
PostgreSQL 恢复大法 - 恢复部分数据库、跳过坏块、修复无法启动的数据库

标签 PostgreSQL , 恢复部分数据库 , 跳过坏块 , 修复无法启动的数据库 , 时间点恢复 , 逻辑备份 , 连续备份 背景 一个较大的数据库,如何只恢复一部分数据(例如只恢复某个DB)。 如果访问有...

德哥
2018/04/18
0
0
Ubuntu 12.04下PostgreSQL-9.1安装与配置详解(在线安装)

说明: 我是用root用户在终端登陆的,如果是非root用户,那在命令前需要加上"sudo",你懂的... 第一步:在Ubuntu下安装Postgresql 1.使用 apt-get install安装 root@server2-virtual-machine...

今幕明
2015/03/17
0
0

没有更多内容

加载失败,请刷新页面

加载更多

python学习04:函数的定义及基本使用

python可以像c++一样,可以直接定义函数。具体格式如下: def(关键字) 函数名(形参01,形参02...): do_something... #如果有返回值,则调用以下语句 return 返回值...

太空堡垒
10分钟前
0
0
深夜杂想

今天周六,从上午9点钟一直码代码到下午5点钟。然后下午又睡了很久。吃过晚饭后来本想晚上再写点代码,不知道为啥,没有任何状态,一直发呆到现在。想起自己计划在元旦节(或者春节)写点自己...

元谷
12分钟前
0
0
day16: swap及lvm使用

1、手动创建一个 swap 空间: 比如有时候服务要求的 swap 空间比较大,总不至于重新安装系统了; 在文件系统里模拟出一个虚拟磁盘出来; dd if=/dev/zero of=/tmp/newdisk bs=1M count=100 [r...

芬野de博客
15分钟前
0
0
sqlalchemy和flask-sqlalchemy查询结果转json

Flask-RESTful 有一个专门做这个的东西,叫 marshal_with, 具体介绍在这里:http://flask-restful.readthedocs.org/en/latest/fields.html 我一般都是用它来格式化返回值 marshal_with 实际...

stys35
22分钟前
0
0
MariaDB重置密码

登录MariaDB 正常情况使用密码登录MariaDB,-p后面是密码 mysql -uroot -ppasscode 重置root密码 如果忘记root密码 编辑/etc/my.cnf,增加:skip-grant,重启服务 [root@localhost ~]# vi ...

李超小牛子
28分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部