支持 DELETE 和 UPDATE¶
Presto 引擎提供 API 来支持行级 SQL DELETE 和 UPDATE。要实现 DELETE 或 UPDATE,连接器必须
在连接器的
ConnectorPageSource之上层叠一个UpdatablePageSource定义
ConnectorMetadata方法以获取 rowId 列句柄使用
beginUpdate()或beginDelete()启动操作使用
finishUpdate()或finishDelete()完成操作
DELETE 和 UPDATE 数据流¶
DELETE 和 UPDATE 具有类似的流程
对于每个拆分,连接器将创建一个
UpdatablePageSource实例,层叠在连接器的ConnectorPageSource之上,以代表 Presto 引擎读取页面,并将删除或更新写入底层数据存储。连接器的
UpdatablePageSource.getNextPage()实现从底层ConnectorPageSource获取下一页,可选地重新格式化页面,然后将其返回到 Presto 引擎。Presto 引擎对读取的页面执行过滤和投影,生成一个已过滤、已投影的结果页面。
Presto 引擎将该已过滤、已投影的结果页面传递给连接器的
UpdatablePageSourcedeleteRows()或updateRows()方法。这些方法将删除或更新持久化到底层数据存储中。当特定拆分的全部页面都已处理完毕后,Presto 引擎会调用
UpdatablePageSource.finish(),它将返回一个Collection<Slice>,其中包含表示连接器特定信息的一组片段,这些信息与对deleteRows或updateRows的调用所处理的行有关。当所有拆分的全部页面都已处理完毕后,Presto 引擎会调用
ConnectorMetadata.finishDelete()或finishUpdate,并传递一个包含所有拆分的所有片段的集合。连接器将执行完成操作所需的操作,例如提交事务。
rowId 列句柄抽象¶
Presto 引擎和连接器使用 rowId 列句柄抽象来就待更新或删除行的标识达成一致。rowId 列句柄对 Presto 引擎来说是不透明的。根据连接器的不同,rowId 列句柄抽象可能代表多个物理列。
用于 DELETE 的 rowId 列句柄¶
Presto 引擎使用连接器特定的 rowId 列句柄来标识待删除的行,该句柄由连接器的 ConnectorMetadata.getDeleteRowIdColumnHandle() 方法返回,该方法的完整签名为
ColumnHandle getDeleteRowIdColumnHandle(
ConnectorSession session,
ConnectorTableHandle tableHandle)
用于 UPDATE 的 rowId 列句柄¶
Presto 引擎使用连接器特定的 rowId 列句柄来标识待更新的行,该句柄由连接器的 ConnectorMetadata.getUpdateRowIdColumnHandle() 方法返回。除了标识行的列外,对于 UPDATE,rowId 列还将包含连接器执行 UPDATE 操作所需的任何列。
UpdatablePageSource API¶
如上所述,要支持 DELETE 或 UPDATE,连接器必须定义 UpdatablePageSource 的一个子类,层叠在连接器的 ConnectorPageSource 之上。有趣的方法是
Page getNextPage()。当 Presto 引擎调用getNextPage()时,UpdatablePageSource会调用其底层的ConnectorPageSource.getNextPage()方法来获取页面。某些连接器在将页面返回到 Presto 引擎之前会重新格式化它。void deleteRows(Block rowIds)。Presto 引擎会调用同一UpdatablePageSource实例的deleteRows()方法,该实例提供了原始页面,并传递一组 rowId,该组 rowId 由 Presto 引擎根据ConnectorMetadata.getDeleteRowIdColumnHandle()返回的列句柄创建。void updateRows(Page page, List<Integer> columnValueAndRowIdChannels)。Presto 引擎会调用同一UpdatablePageSource实例的updateRows()方法,该实例提供了原始页面,并传递一组投影列,每个投影列代表一列已更新的列,最后一列代表 rowId 列。投影列的顺序由 Presto 引擎定义,该顺序反映在columnValueAndRowIdChannels参数中。updateRows()的工作是从投影页面中提取已更新的列块和 rowId 块。
按照连接器存储所需的任何顺序将它们组合在一起。
将更新结果存储到底层文件存储中。
CompletableFuture<Collection<Slice>> finish()。当拆分的全部页面都已处理完毕后,Presto 引擎会调用finish()。连接器返回一个包含Slice集合的 future,该集合表示连接器特定信息,这些信息与已处理的行有关。通常,这将包括行计数,并且可能包括诸如已创建或更改的文件或分区之类的信息。
ConnectorMetadata DELETE API¶
实现 DELETE 的连接器必须指定三个 ConnectorMetadata 方法。
getDeleteRowIdColumnHandle():ColumnHandle getDeleteRowIdColumnHandle( ConnectorSession session, ConnectorTableHandle tableHandle)此方法返回的 ColumnHandle 提供 rowId 列句柄,连接器使用该句柄来标识待删除的行,以及连接器完成
DELETE操作所需的任何其他行字段。对于 JDBC 连接器,该 rowId 通常是表的 primary key,不需要其他字段。对于其他连接器,识别行的所需信息通常由多个物理列组成。beginDelete():ConnectorTableHandle beginDelete( ConnectorSession session, ConnectorTableHandle tableHandle)作为创建
DELETE执行计划的最后一步,连接器的beginDelete()方法被调用,并传入session和tableHandle。beginDelete()执行连接器中开始处理DELETE所需的任何编排。此编排因连接器而异。beginDelete()返回一个ConnectorTableHandle,其中包含连接器在将句柄传回finishDelete()和拆分生成机制时所需的任何附加信息。对于大多数连接器,返回的表句柄包含一个标志,用于识别表句柄为DELETE操作的表句柄。finishDelete():void finishDelete( ConnectorSession session, ConnectorTableHandle tableHandle, Collection<Slice> fragments)在
DELETE处理过程中,Presto引擎会累积由UpdatablePageSource.finish()返回的Slice集合。在处理完所有拆分后,引擎会调用finishDelete(),并传入表句柄以及该Slice片段的集合。作为响应,连接器会采取适当的措施来完成Delete操作。这些操作可能包括提交事务,假设连接器支持事务范式。
ConnectorMetadata UPDATE API¶
实现UPDATE的连接器必须指定三个ConnectorMetadata方法。
getUpdateRowIdColumnHandle:ColumnHandle getUpdateRowIdColumnHandle( ConnectorSession session, ConnectorTableHandle tableHandle, List<ColumnHandle> updatedColumns)updatedColumns列表包含由UPDATE操作在表列顺序中更新的所有列的列句柄。此方法返回的ColumnHandle提供连接器用于识别要更新的行的rowId,以及连接器完成
UPDATE操作所需的行的任何其他字段。beginUpdate:ConnectorTableHandle beginUpdate( ConnectorSession session, ConnectorTableHandle tableHandle, List<ColumnHandle> updatedColumns)作为创建
UPDATE执行计划的最后一步,连接器的beginUpdate()方法被调用,并传入定义连接器的UPDATE的参数。除了session和tableHandle之外,参数还包括在表列顺序中的已更新列句柄列表。beginUpdate()执行连接器中开始处理UPDATE所需的任何编排。此编排因连接器而异。beginUpdate返回一个ConnectorTableHandle,其中包含连接器在将句柄传回finishUpdate()和拆分生成机制时所需的任何附加信息。对于大多数连接器,返回的表句柄包含一个标志,用于识别表句柄为UPDATE操作的表句柄。对于某些支持分区的连接器,表句柄将反映该分区。finishUpdate:void finishUpdate( ConnectorSession session, ConnectorTableHandle tableHandle, Collection<Slice> fragments)在
UPDATE处理过程中,Presto引擎会累积由UpdatablePageSource.finish()返回的Slice集合。在处理完所有拆分后,引擎会调用finishUpdate(),并传入表句柄以及该Slice片段的集合。作为响应,连接器会采取适当的措施来完成UPDATE操作。这些操作可能包括提交事务,假设连接器支持事务范式。