子图 > 最佳实践
10 分钟
子图最佳实践6-使用嫁接快速部署修补程序
TLDR
嫁接是子图开发中的一个强大功能,它允许您构建和部署新的子图,同时重用现有子图中的索引数据。
概述
此功能可快速部署关键问题的修补程序,无需从头开始重新索引整个子图。通过保留历史数据,移植可以最大限度地减少停机时间,并确保数据服务的连续性。
嫁接修复补丁的好处
-
快速部署
- 最小化停机时间:当子图遇到严重错误并停止索引时,嫁接使您能够立即部署修复程序,而无需等待重新索引。
- 立即恢复:新的子图从最后一个索引块继续,确保数据服务保持不间断。
-
数据保存
- 重用历史数据:嫁接会从基础子图复制现有数据,这样就不会丢失有价值的历史记录。
- 一致性:保持数据连续性,这对于依赖一致历史数据的应用程序至关重要。
-
效率
- 节省时间和资源:避免重新索引大型数据集的计算开销。
- 专注于修复:允许开发人员专注于解决问题,而不是管理数据恢复。
使用嫁接修复补丁的最佳实践
-
无嫁接的初始部署
- 开始清理:始终部署初始子图而不进行嫁接,以确保其稳定并按预期运行。
- 彻底测试:验证子图的性能,以尽量减少对未来补丁的需求。
-
用嫁接实现补丁
- 识别问题:当发生严重错误时,确定最后一个成功索引事件的块号。
- 创建新子图:开发一个包含修补程序的新子图。
- 配置嫁接:使用嫁接将数据从失败的子图复制到识别的块号。
- 快速部署:发布嫁接的子图,尽快恢复服务。
-
发布修补程序操作
- 监控性能:确保嫁接的子图正确索引,并且修补程序解决了该问题。
- 无嫁接的重新发布:一旦稳定,部署新版本的子图,无需嫁接以进行长期维护。
注意:不建议无限期地依赖嫁接,因为这会使未来的更新和维护复杂化。
- 更新引用:重定向任何服务或应用程序以使用新的、未嫁接的子图。
-
重要注意事项
- 谨慎块选择:仔细选择嫁接块编号,以防止数据丢失。
- 提示:使用最后一个正确处理的事件的块号。
- 使用部署ID:确保引用基子图的部署ID,而不是子图ID。
- 注意:部署ID是特定子图部署的唯一标识符。
- 特征声明:记住在特征下的子图清单中声明嫁接。
示例:使用嫁接部署修补程序
假设你有一个子图跟踪一个因严重错误而停止索引的智能合约。以下是如何使用嫁接来部署修补程序。
-
失败的子图清单(Subgraph.yaml)
1specVersion: 1.3.02schema:3 file: ./schema.graphql4dataSources:5 - kind: ethereum/contract6 name: OldSmartContract7 network: sepolia8 source:9 address: '0xOldContractAddress'10 abi: Lock11 startBlock: 500000012 mapping:13 kind: ethereum/events14 apiVersion: 0.0.915 language: wasm/assemblyscript16 entities:17 - Withdrawal18 abis:19 - name: Lock20 file: ./abis/OldLock.json21 eventHandlers:22 - event: Withdrawal(uint256,uint256)23 handler: handleOldWithdrawal24 file: ./src/old-lock.ts
-
新的嫁接子图清单(Subgraph.yaml)
1specVersion: 1.3.02schema:3 file: ./schema.graphql4dataSources:5 - kind: ethereum/contract6 name: NewSmartContract7 network: sepolia8 source:9 address: '0xNewContractAddress'10 abi: Lock11 startBlock: 6000001 # Block after the last indexed block12 mapping:13 kind: ethereum/events14 apiVersion: 0.0.915 language: wasm/assemblyscript16 entities:17 - Withdrawal18 abis:19 - name: Lock20 file: ./abis/Lock.json21 eventHandlers:22 - event: Withdrawal(uint256,uint256)23 handler: handleWithdrawal24 file: ./src/lock.ts25features:26 - grafting27graft:28 base: QmBaseDeploymentID # Deployment ID of the failed Subgraph29 block: 6000000 # Last successfully indexed block
说明:
- 数据源更新:新的子图指向0xNewContractAddress,这可能是智能合约的固定版本。
- 开始块:设置为最后一个成功索引块后的一个块,以避免重新处理错误。
- 嫁接配置::
- base:失败子图的部署ID。
- block:应该开始嫁接的块号。
-
部署步骤
- 更新代码:在映射脚本中实现修补程序(例如handleWithdrawal)。
- 调整Manifest:如上所示,使用嫁接配置更新
subgraph.yaml
。 - 部署子图:
- 使用Graph CLI进行身份验证。
- 使用
graph deploy
部署新的子图。
-
部署后
- 验证索引:检查子图是否从嫁接点正确索引。
- 监控数据:确保正在捕获新数据,并且修补程序有效。
- 重新发布计划:安排部署非嫁接版本以实现长期稳定性。
警告和注意事项
虽然嫁接是快速部署修补程序的强大工具,但在某些特定情况下,为了保持数据完整性并确保最佳性能,应该避免嫁接。
- 不兼容的模式更改:如果您的修补程序需要更改现有字段的类型或从模式中删除字段,则嫁接是不合适的。Grafting期望新子图的模式与基础子图的模式兼容。不兼容的更改可能会导致数据不一致和错误,因为现有数据与新模式不一致。
- 重要的映射逻辑大修:当修补程序涉及对映射逻辑的重大修改时,例如更改事件的处理方式或更改处理程序函数,嫁接可能无法正常工作。新逻辑可能与在旧逻辑下处理的数据不兼容,导致数据不正确或索引失败。
- 部署到The Graph网络:不建议对用于The Graph去中心化网络(主网)的子图进行嫁接。它可能会使索引复杂化,并且可能不会得到所有索引人的完全支持,从而可能导致意外行为或成本增加。对于主网部署,从头开始重新索引子图以确保完全兼容性和可靠性更安全。
风险管理
- 数据完整性:不正确的块号可能会导致数据丢失或重复。
- 测试:在部署到生产环境之前,始终在开发环境中测试嫁接。
结论
嫁接是在子图开发中部署修补程序的有效策略,使您能够:
- 无需重新索引即可快速从关键错误中恢复。
- 保留历史数据,保持应用程序和用户的连续性。
- 通过最大限度地减少关键修复期间的停机时间来确保服务可用性。
然而,明智地使用嫁接并遵循最佳实践来降低风险非常重要。使用修补程序稳定子图后,计划部署非嫁接版本以确保长期可维护性。
其他资源
通过将嫁接纳入子图开发工作流程,您可以提高快速响应问题的能力,确保您的数据服务保持健壮和可靠。