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 -手动调用以重新排序分区