暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

PostgreSQL 9.0 开始大对象的改进 - 增加 pg_largeobject_metadata 表用于查询大对象oid和对应的owner与权限

digoal 2021-01-05
2335

作者

digoal

日期

2021-05-07

标签

PostgreSQL , 大对象


背景

PostgreSQL 9.0 开始大对象的改进 - 增加 pg_largeobject_metadata 表用于查询大对象oid和对应的owner与权限.

以前的版本pg_largeobject是对public开放的, 所以存在很大的风险, 所有用户都能查看pg_largeobject的内容(包括数据).

如果你的应用程序还停留在9.0以前, 你会发现迁移到大版本后, 没法查pg_largeobject这个表了, 不要着急, 改一下查询pg_largeobject_metadata就可以, 这是更安全的做法.

https://www.postgresql.org/docs/13/catalog-pg-largeobject.html

例子

1、导入大对象

```
vi abc.txt

hello world, i am digoal.
i love postgresql.
today is 2021-05-07
```

```
IT-C02YW2EFLVDL:~ digoal$ psql
psql (13.2)
Type "help" for help.

postgres=> \lo_import pwd/abc.txt
lo_import 16404
postgres=> \lo_import pwd/abc.txt
lo_import 16405
```

2、在table中引用大对象

postgres=> create table abc(id int, file oid); CREATE TABLE postgres=> insert into abc values(1, 16404); INSERT 0 1

3、查询大对象属性

```
postgres=> \lo_list
Large objects
ID | Owner | Description
-------+--------+-------------
16404 | digoal |
16405 | digoal |
(2 rows)

postgres=> select * from pg_largeobject_metadata ;
oid | lomowner | lomacl
-------+----------+--------
16404 | 16394 |
16405 | 16394 |
(2 rows)
```

4、直接查询pg_largeobject报权限出错

postgres=> select * from pg_largeobject; ERROR: permission denied for table pg_largeobject postgres=> select loid from pg_largeobject; ERROR: permission denied for table pg_largeobject

5、大对象权限配置

```
postgres=> \c postgres postgres
You are now connected to database "postgres" as user "postgres".
postgres=# create role new;
CREATE ROLE
postgres=# alter role new login;
ALTER ROLE

postgres=# \c postgres digoal
You are now connected to database "postgres" as user "digoal".
postgres=> \h alter large
Command: ALTER LARGE OBJECT
Description: change the definition of a large object
Syntax:
ALTER LARGE OBJECT large_object_oid OWNER TO { new_owner | CURRENT_USER | SESSION_USER }

URL: https://www.postgresql.org/docs/13/sql-alterlargeobject.html

postgres=> \h grant large
Command: GRANT
Description: define access privileges
```

```
postgres=> grant select on large object 16404 to new;
GRANT

postgres=> select * from pg_largeobject_metadata ;
oid | lomowner | lomacl
-------+----------+---------------------------------
16405 | 16394 |
16404 | 16394 | {digoal=rw/digoal,new=r/digoal}
(2 rows)
```

6、owner导出大对象

```
postgres=# \c postgres digoal
You are now connected to database "postgres" as user "digoal".

postgres=> \lo_export 16405 pwd/abc1.txt
lo_export

IT-C02YW2EFLVDL:~ digoal$ cat abc1.txt
hello world, i am digoal.
i love postgresql.
today is 2021-05-07
```

7、非owner导出大对象

`` postgres=> \c postgres new You are now connected to database "postgres" as user "new". postgres=> \lo_export 16405pwd`/abc2.txt
ERROR: permission denied for large object 16405

postgres=> \lo_export 16404 pwd/abc2.txt
lo_export

IT-C02YW2EFLVDL:~ digoal$ cat abc2.txt
hello world, i am digoal.
i love postgresql.
today is 2021-05-07
```

8、查询没有link的大对象

实际上就是检查oid类型的字段中是否有大对象对应的oid. 没有就说明这个大对象没有被关联

IT-C02YW2EFLVDL:~ digoal$ vacuumlo -n -v -U postgres postgres Connected to database "postgres" Test run: no large objects will be removed! Checking file in public.abc Would remove 1 large objects from database "postgres".

9、清除没有link的大对象大对象

```
客户端命令 :

vacuumlo -v -U postgres postgres

或 SQL :

select lo_unlink(oid);

或 psql :

\lo_unlink oid
```

vacuumlo -v -U postgres postgres Connected to database "postgres" Checking file in public.abc Successfully removed 1 large objects from database "postgres".

202012/20201205_01.md 《PostgreSQL 大对象使用》
201906/20190607_04.md 《PostgreSQL psql的元素周期表 - 包括大对象操作》
201802/20180201_03.md 《[转] 关于入侵PostgreSQL的那些事儿(文件读取写入、命令执行的办法) -大对象》
201702/20170213_01.md 《大对象 - 数据库common安全自动渗透测试与防范 - sqlmap》
201610/20161018_02.md 《大对象攻击 - Hacking PostgreSQL》
201606/20160614_01.md 《在java中正确使用PostgreSQL大对象和字节流(bytea)类型的姿势》
201306/20130626_01.md 《PostgreSQL 大对象或bytea存取pdf,jpg等文件 - PostgreSQL export regular file like pdf, word, text, doc stored in bytea type》
201305/20130510_02.md 《大对象 - PostgreSQL 9.3 Add API for 64-bit large object access》
201303/20130306_01.md 《大对象 - Use PostgreSQL server program import binary data into database bytea type》
201301/20130109_01.md 《PostgreSQL large row|column performance tuning case - 包括大对象》

说明

1、large object 不支持逻辑订阅, 因为数据在pg_largeobjects中, 不是在publication的table中, 也许未来可以支持. 但还需要解决权限问题, 因为每条object的权限都是可以单独赋予的.

https://www.postgresql.org/docs/current/logical-replication-restrictions.html

2、pg_dump逻辑导出支持导出大对象, 导出导入时支持大对象的权限、owner相关属性的备份和恢复.

```

-- Name: 16404; Type: BLOB; Schema: -; Owner: digoal

SELECT pg_catalog.lo_create('16404');

ALTER LARGE OBJECT 16404 OWNER TO digoal;

-- -- Name: 16416; Type: BLOB; Schema: -; Owner: digoal --

SELECT pg_catalog.lo_create('16416');

ALTER LARGE OBJECT 16416 OWNER TO digoal;

-- -- Name: 16417; Type: BLOB; Schema: -; Owner: digoal --

SELECT pg_catalog.lo_create('16417');

ALTER LARGE OBJECT 16417 OWNER TO digoal;

-- -- Data for Name: abc; Type: TABLE DATA; Schema: public; Owner: digoal --

COPY public.abc (id, file) FROM stdin; 1 16404 .

-- -- Data for Name: BLOBS; Type: BLOBS; Schema: -; Owner: - --

BEGIN;

SELECT pg_catalog.lo_open('16404', 131072); SELECT pg_catalog.lowrite(0, '\x68656c6c6f20776f726c642c206920616d206469676f616c2e0a69206c6f766520706f737467726573716c2e0a746f64617920697320323032312d30352d30370a'); SELECT pg_catalog.lo_close(0);

SELECT pg_catalog.lo_open('16416', 131072); SELECT pg_catalog.lowrite(0, '\x68656c6c6f20776f726c642c206920616d206469676f616c2e0a69206c6f766520706f737467726573716c2e0a746f64617920697320323032312d30352d30370a'); SELECT pg_catalog.lo_close(0);

SELECT pg_catalog.lo_open('16417', 131072); SELECT pg_catalog.lowrite(0, '\x68656c6c6f20776f726c642c206920616d206469676f616c2e0a69206c6f766520706f737467726573716c2e0a746f64617920697320323032312d30352d30370a'); SELECT pg_catalog.lo_close(0);

COMMIT;

-- -- Name: LARGE OBJECT 16404; Type: ACL; Schema: -; Owner: digoal --

GRANT SELECT ON LARGE OBJECT 16404 TO new;

```

PostgreSQL 许愿链接

您的愿望将传达给PG kernel hacker、数据库厂商等, 帮助提高数据库产品质量和功能, 说不定下一个PG版本就有您提出的功能点. 针对非常好的提议,奖励限量版PG文化衫、纪念品、贴纸、PG热门书籍等,奖品丰富,快来许愿。开不开森.

9.9元购买3个月阿里云RDS PostgreSQL实例

PostgreSQL 解决方案集合

德哥 / digoal's github - 公益是一辈子的事.

digoal's wechat

文章转载自digoal,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论