大型对象增强
此维基页面是关于为 二进制数据待办事项 开发的非官方待办事项的备忘录。
TOAST 值上的大型对象接口
TOAST 关系定义如下,它是一个存在于pg_largeobject.
pg_toast_%u ( chunk_id oid, chunk_seq int4, chunk_data bytea, unique(chunk_id, chunk_seq) )
pg_largeobject( loid oid, pageno int4, data bytea, unique(loid, pageno) )
中的相同结构。将大型对象的内容部署到其 toast 关系上,以及将大型对象接口增强以访问 toast 数据结构的部分内容,这是很自然的。在这种情况下,pg_largeobject将被用来管理大型对象的元数据。
它也能够解决非常大的TEXT或BYTEA数据中的一个问题。在规范中,它允许存储 1G 字节长度的 varlena 数据,但它需要在提取时将整个块数据帧扩展到本地内存中。显然,这对于存储非常大的数据是不合适的。
问题
Toast 格式
当给定的数据被 toasted 时,它可以被压缩以减少存储消耗,对于 attstorage 为 'm' 或 'x' 的列。然而,这使得难以估计哪个块存储了所需的数据区域,因此它不适合部分访问。当前TEXT和BYTEA类型定义为pg_type.typstorage为 'x',因此需要一种新的 varlena 类型来存储未压缩的数据以允许部分访问。
当 varlena 数据足够小时,它可以存储在元组内,无需任何外部 toast 关系。然而,这使得无法部分更新它们,因为它需要整个更新。
因此,允许大型对象接口的新 varlena 数据类型必须具有以下特性:
- 它总是使用外部 toast 关系,独立于给定 varlena 的大小。
- 它永远不会压缩给定的 varlena,以便正确地估计哪个块存储了哪个偏移量。
在我的计划中,一种新的 varlena 类型BLOB将被添加,并具有上述要求。
块的空洞
当前的 TOASTing 机制没有考虑块的空洞。大型对象功能可以包含不连续的页面帧。如果我们尝试读取有空洞的页面,它会返回零填充的页面。重新设计的 TOASTing 机制需要处理有空洞的页面。
一个有争议的事情是,应该从toast_raw_datum_size()和toast_datum_size().
返回什么值
模式支持
语句
postgres=# CREATE SCHEMA lotest; CREATE SCHEMA postgres=# ALTER LARGE OBJECT 1234 SET SCHEMA lotest; ALTER LARGE OBJECT postgres=# DROP SCHEMA lotest; ERROR: cannot drop schema lotest because other objects depend on it DETAIL: largeobject 1234 depends on schema lotest HINT: Use DROP ... CASCADE to drop the dependent objects too. postgres=# DROP SCHEMA lotest CASCADE; NOTICE: drop cascades to largeobject 1234 DROP SCHEMA
ALTER LARGE OBJECT
CREATE LARGE OBJECT在我看来,CREATE [TEMP] LARGE OBJECT
使用完全限定的命名空间是一个有用的功能。
命名大型对象
postgres=# SELECT lo_open('my_lobject', x'40000'::int); postgres=# SELECT lo_open('pg_temp.your_lobject', x'40000'::int);
目前,大型对象接口只支持数字标识符,但是,使用人类可读标识符并不不可能,如下所示后面的例子通过pg_temp
模式限定了大型对象的名称。
创建大型对象的权限在数据库 DAC 模型中,ACL_CREATE
在存储新数据库对象的模式上进行检查,但是,大型对象不受任何特定模式的支配。如果我们需要检查创建大型对象的权限,则需要用某个模式对象来覆盖它。
已完成的项目
为大型对象添加安全检查这提供了对大型对象的拥有权和读/写权限管理的支持。该和readwrite权限是显而易见的。这些应该在, loread()和lowrite()lo_truncate()上进行检查。此外,只有大型对象的拥有者(以及超级用户)可以使用.
lo_unlink()
删除它们。数据结构一个新的系统目录,用来管理大型对象的元数据(所有权和安全属性),与页面帧分开。该pg_largeobject_metadata.oid.