OID 相关技巧
- 显示下一个 OID
-
场景:您想知道下一个将使用哪个 OID
解决方案:执行
SELECT next_oid FROM pg_control_checkpoint()来显示下一个 OID 的近似值(截至最近一次 检查点)postgres=# SELECT next_oid FROM pg_control_checkpoint(); next_oid ---------- 95549 (1 row)对于 PostgreSQL 9.6 之前的版本,请使用
pg_controldata来提取NextOID字段postgres $ pg_controldata /path/to/pgdata | grep OID Latest checkpoint's NextOID: 2254511
- 获取当前数据库的 OID
-
在 PostgreSQL 18 及更早版本中,没有
regdatabase修饰符,唯一的方法是结合一个识别当前会话的查询和 系统目录 表,该表可以将该标识与特定数据库关联起来,例如:SELECT oid FROM pg_database WHERE datname = current_database()
或
SELECT datid FROM pg_stat_activity WHERE pid = pg_backend_pid()
在 PostgreSQL 19 及更高版本中,可以像这样使用
regdatabase:postgres=# select current_database()::regdatabase; current_database ------------------ postgres (1 row)
- 显示带有 OID 的表
-
场景:您有一个旧版数据库(PostgreSQL 11 或更早版本),并想检查哪些表(如果有的话)仍然启用了 OID。
解决方案:执行以下查询
testdb=> SELECT n.nspname, c.relname, c.relhasoids FROM pg_class c JOIN pg_namespace n ON (c.relnamespace=n.oid) WHERE n.nspname !~ '^pg_' AND c.relkind='r' AND c.relhasoids IS TRUE; nspname | relname | relhasoids ---------+-------------------------+------------ appdb | entry | t appdb | form_session | t appdb | action | t appdb | language | t appdb | markup_language_variant | t (5 rows) - 从所有仍带有 OID 的表中移除 OID
-
以下匿名代码块查找所有带有 OID 的表,并动态执行
ALTER TABLE ... SET WITHOUT OIDS(PostgreSQL 11 及更早版本)DO LANGUAGE plpgsql $$ DECLARE rec_table RECORD; BEGIN FOR rec_table IN SELECT n.nspname, c.relname FROM pg_namespace n INNER JOIN pg_class c ON n.oid=c.relnamespace WHERE n.nspname !~ '^pg_' AND c.relkind='r' AND c.relhasoids IS TRUE ORDER BY 1 LOOP RAISE NOTICE 'Removing OIDs from table %.%', rec_table.nspname, rec_table.relname; EXECUTE FORMAT ('ALTER TABLE %I.%I SET WITHOUT OIDS', rec_table.nspname, rec_table.relname); END LOOP; END $$;
