我有一个最初使用PostgreSQL实例构建的数据库,该实例的自定义页面大小比默认的要大得多。我正在尝试将其内容迁移到一个标准的8k页数据库中。
因为由PostgreSQL中的标准索引索引的数据必须不超过页面大小的1/3,所以如果不修改索引定义,旧数据库中包含的某些数据就无法在新数据库中表示。进行模式更改不是一个立即可用的选项;删除行(从我希望涉及的表中删除)是一个选项。
在PostgreSQL中查找索引的总体大小很容易,而且有很好的文档记录。找出相关索引大小超过阈值的单个行是我遇到的问题。
如何找到包含索引值的行(跨模式中的所有表),其中所述值的索引太大,无法在标准PostgreSQL构建中表示(也就是说,大于2712字节)?
发布于 2015-08-13 20:40:49
让我以一个警告开始这个答复:我从来没有遇到过这个确切的问题,所以我不完全理解它的本质。然而,我会给出我的建议,这样也许它能给你完成任务所需的洞察力。
pageinspect扩展最近版本的PostgreSQL附带了一个扩展,您可以安装它,允许您对存储在数据库中的元素进行检查各个页面。
首先,使用它所需要做的就是运行命令
CREATE EXTENSION pageinspect;它已经准备好出发了。
现在,我仍然不完全理解这个问题,但是您似乎关心索引条目的大小,而不一定是堆中的实际行条目。
对于这种情况,您应该使用来自pageinspect扩展的函数调用来查询BTree索引的页面,如下
SELECT * FROM bt_page_items('idx_123', 1);你会得到一些结果
itemoffset ctid itemlen nulls vars data
-----------------------------------------------------------------
1 (1,182) 16 f f "00 3e 9b ac b2 02 01 00"
2 (0,1) 16 f f "00 20 d6 fa 65 02 01 00"
3 (0,2) 16 f f "00 09 7b 30 66 02 01 00"
4 (0,3) 16 f f "00 f2 1f 66 66 02 01 00"
5 (0,4) 16 f f "00 db c4 9b 66 02 01 00"
6 (0,5) 16 f f "00 c4 69 d1 66 02 01 00"
...想必,尽管您应该根据自己的数据进行检查,但通过检查itemlen字段,您可以看到索引键正在使用的字节数。我打赌你可以用这个来检查你预先确定的限制,你说的是2712字节,在这种情况下,用这个信息收集所有违反你条件的ctids。
从广义上讲,您需要创建一个PL/pgSQL函数来迭代索引页(S),检查itemlen,收集堆条目的ctids,一旦完成,因为您声明删除违反行是可以的,然后用一个
DELETE FROM my_table WHERE my_table.ctid = *** your ctid list ***;我希望这能帮到你!
https://dba.stackexchange.com/questions/110964
复制相似问题