大數據“復活”記
946
2025-04-01
GaussDB(DWS)中,PG_DEPEND系統表記錄數據庫對象之間的依賴關系。這個信息允許DROP命令找出哪些對象必須由DROP CASCADE刪除,或是在DROP RESTRICT的情況下避免刪除。PG_SHDEPEND系統表記錄數據庫對象和共享對象(比如角色)之間的依賴性關系,作用與PG_DEPEND類似,只是PG_SHDEPEND是在集群里面所有的數據庫之間共享的:每個數據庫集群只有一個PG_SHDEPEND,而不是每個數據庫一個。
1.查看對象依賴關系
如前所述,如需查看依賴關系,可通過對象的OID去PG_DEPEND和PG_SHDEPEND中查看:
postgres=# select * from pg_depend where objid = 24642 or refobjid = 24642; classid | objid | objsubid | refclassid | refobjid | refobjsubid | deptype ---------+-------+----------+------------+----------+-------------+--------- 1247 | 24644 | 0 | 1259 | 24642 | 0 | i 1259 | 24642 | 0 | 2615 | 2200 | 0 | n 9001 | 24642 | 0 | 1259 | 24642 | 0 | i 2604 | 24645 | 0 | 1259 | 24642 | 2 | a 1259 | 24640 | 0 | 1259 | 24642 | 2 | a (5 rows) postgres=# select * from pg_shdepend where objid = 24636 or refobjid = 24636; dbid | classid | objid | objsubid | refclassid | refobjid | deptype | objfile -------+---------+-------+----------+------------+----------+---------+--------- 15258 | 2615 | 24637 | 0 | 1260 | 24636 | o | (1 row)
其中,refobjid表示被引用對象的OID,objid表示依賴對象的OID。例如,create view v1 as select * from t1,則查詢依賴關系的時候,objid為v1的oid,refobjid為t1的oid。
2. 案例一:刪除表時報錯:cannot drop table test because other objects depend on it
tddb=# create table t1 (a int, b serial) distribute by hash(a); NOTICE: CREATE TABLE will create implicit sequence "t1_b_seq" for serial column "t1.b" CREATE TABLE tddb=# create table t2 (a int, b int default nextval('t1_b_seq')) distribute by hash(a); CREATE TABLE tddb=# drop table t1; ERROR: cannot drop table t1 because other objects depend on it DETAIL: default for table t2 column b depends on sequence t1_b_seq HINT: Use DROP ... CASCADE to drop the dependent objects too.
該例中,創建t1表后,隱式創建了sequence,然后創建t2表的時候,引用了該sequence,然后刪除t1表的時候,由于會級聯刪除sequence,但是該sequence被其他對象依賴,因此導致該報錯。如不需保留t2,可通過DROP CASCADE的方式級聯刪除,如需保留該表和該sequence,可以:
tddb=# drop table t1; ERROR: cannot drop table t1 because other objects depend on it DETAIL: default for table t2 column b depends on sequence t1_b_seq HINT: Use DROP ... CASCADE to drop the dependent objects too. tddb=# tddb=# alter sequence t1_b_seq owned by none; ALTER SEQUENCE tddb=# tddb=# drop table t1; DROP TABLE tddb=#
這樣,drop t1的時候就不會級聯刪除sequence,t2表得到保留。
3. 案例二:刪除用戶時報錯:role "xxx" cannot be dropped because some objects depend on it
tddb=# drop user usr1; ERROR: role "usr1" cannot be dropped because some objects depend on it DETAIL: 1 object in database postgres
根據報錯內容,是postgres庫下存在該視圖的依賴,去postgres庫下查看:
postgres=# select usename,usesysid from pg_user where usename = 'usr1'; usename | usesysid ---------+---------- usr1 | 24670 (1 row) postgres=# select * from pg_depend where refobjid = '24670'; classid | objid | objsubid | refclassid | refobjid | refobjsubid | deptype ---------+-------+----------+------------+----------+-------------+--------- (0 rows) postgres=# select * from pg_shdepend where refobjid = '24670'; dbid | classid | objid | objsubid | refclassid | refobjid | deptype | objfile -------+---------+-------+----------+------------+----------+---------+--------- 15258 | 2615 | 24671 | 0 | 1260 | 24670 | o | (1 row) postgres=# select oid,relname from pg_class where oid = 2615; oid | relname ------+-------------- 2615 | pg_namespace (1 row) postgres=# select * from pg_namespace where oid = 24671; nspname | nspowner | nsptimeline | nspacl | permspace | usedspace ---------+----------+-------------+--------+-----------+----------- usr1 | 24670 | 0 | | -1 | 0 (1 row)
查詢pg_depend視圖為空,繼續查詢pg_shdepend視圖可以看到一條記錄,根據classid查到依賴對象所在的系統表,根據objid查到該對象的名字,從上面的結構可以看到,是usr1在postgres庫下的同名schema導致用戶無法被drop,刪除該schema后用戶能夠重新刪除。
EI企業智能 Gauss AP 數據倉庫服務 GaussDB(DWS)
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。