20.1. 设计概述¶
20.1.1. 动机¶
PostGIS是一种应用广泛的易于部署的空间数据库,但它在单个表中可以处理的记录总数是有限的。该模块通过自动将数据分类到基于时间的分区,使得使用PostgreSQL的本地分区存储更大的数据集成为可能。
20.1.2. 概述¶
PostGIS分区模块是GeoTool的扩展模块 JDBC data store ,实现为自定义方言。它是为传感器数据设计的,其中每个记录都有一个时间戳,并且记录大多在生成后不久就被摄取。
写入数据时,会根据记录时间戳将其分类到分区中。最近的数据被分类到较小的分区中,一旦达到一定年龄,就会分类到较大的分区中。分区在时空上进行排序,以减少典型查询期间的页面读取。由于对数据进行了排序,因此可以使用空间对其进行有效索引 BRIN
索引,它比标准的索引小得多 GIST
指数。在查询过程中,PostgreSQL将使用标准分区修剪,自动跳过与查询不匹配的分区。这允许使用时态谓词高效地查询海量数据集,尽管非时态查询可能执行得不好。
20.1.3. 餐桌设计¶
数据分为一个主视图和三个表,其名称以要素类型为前缀:
主视图(根据要素类型命名)-a
UNION ALL
在其他表中,这是通常应该用于所有外部读取和写入的视图。
_wa
-预写表。使用触发器将对主视图的所有写入委托给该表。使用表继承对表进行分区(因为分区之间可能存在重叠),并且每10分钟滚动一次。只有最新的分区会被写入。
_wa_partition
-最新数据,使用声明性分区以10分钟为增量进行分区。最新的数据以空间排序的顺序存储在该表中,在滚动时从预写表复制出来(之后删除预写表分区)。该表旨在处理潜伏时间的数据,并存储足够填满整个主分区的数据,同时仍为查询提供分区修剪。
_partition
-主数据,使用声明性时间分区进行分区。将数据从复制到此表中_wa_partition
表,一旦经过了足够的时间(在此之后_wa_partition
分区被丢弃)。它使用Brin索引,该索引很小,但在排序数据上执行得很好。对数据进行排序还可以减少大多数空间查询所需的页面命中率。
20.1.4. 帮助器表¶
除上述表格外,还使用了以下其他表格:
_analyze_queue
-跟踪已修改的分区。修改后的分区将具有ANALYZE
在单独的进程中对它们进行调用。
_sort_queue
-跟踪无序插入到主分区表中。这可用于诊断速度较慢的查询,因为未排序的数据会对BRIN
指数。
20.1.5. 维护脚本¶
根据上述设计,使用了几个PLPG/SQL过程来移动数据。这个 pg_cron
使用扩展来调度这些任务。脚本名称以要素类型为前缀,并根据要素类型配置(即字段名、分区大小等)创建。这些程序包括:
_roll_wa
-每10分钟创建一个新的预写表
_partition_maintenance
一次调用所有分区脚本的伞形函数
_partition_wa
-将数据从旧的预写表移动到_wa_partition
表格
_merge_wa_partitions
-将数据从_wa_partition
表成主表_partition
表格
_age_off
(如果已配置)-删除已超过要保留的最大数据量的任何分区
_analyze_partitions
-运行ANALYZE
在任何已更新的分区上
_partition_sort
-手动调用以重新排序分区