内容提要
Vitess使用Vindexes将表中的行与Keyspace ID关联,以实现数据分片和全局索引。Lookup Vindex作为二级索引,优化查询路由,避免性能损失。Consistent Lookup Vindex通过锁定和事务序列确保数据一致性,避免使用2PC协议。在数据修改时,Vitess通过三个连接执行DML操作,以确保在多分片环境中的一致性。
延伸解读
一致性查找Vindex如何避免2PC
在分片数据库中,维护用户表与查找Vindex表之间的一致性通常需要跨分片事务,而2PC协议虽然能保证原子性和隔离性,但成本高昂。一致性查找Vindex通过精心设计的锁定和事务序列,在不使用2PC的情况下确保一致性。具体来说,Vitess使用Pre、Main和Post三个连接执行DML操作,并按照固定顺序提交事务:先Pre,再Main,最后Post。如果任何一步失败,则按相同顺序回滚剩余事务。这种机制在保证数据一致性的同时,避免了2PC的开销。
删除操作中的一致性保障
删除操作涉及用户表和查找Vindex表。Vitess通过Post连接删除Vindex表中的行,通过Main连接删除用户表中的行。提交时,如果Main事务成功但Post事务失败,Vindex表可能残留已删除用户的行,导致Vindex表与用户表不一致。然而,当查询使用Vindex路由时,例如按name查询,Vindex会返回Keyspace ID,查询被路由到特定分片,但该分片中用户行已不存在,因此返回空结果。这样,尽管Vindex表可能不一致,查询结果仍与用户表保持一致。
插入操作与重复键错误处理
插入操作通过Pre连接向Vindex表插入行,通过Main连接向用户表插入行。如果Vindex表存在唯一约束,可能遇到重复键错误,例如之前删除操作失败留下的孤儿行。Vitess通过锁定Vindex行和用户表行来处理:先锁定Vindex行防止竞争,再锁定用户表行确认要插入的行不存在,从而识别出孤儿行,并将其更新为新的Keyspace ID。这确保了插入操作的正确性,同时维护了数据一致性。
更新操作的特殊情况与限制
更新操作被拆分为删除后插入:删除通过Post连接,插入通过Pre连接。如果更新时Vindex列的值未改变,删除操作持有的行锁会导致插入操作锁等待超时。为避免此问题,Vitess将Vindex列值不变的更新转为空操作。但如果在同一事务中,对相同的Vindex值先删除后插入(作为两个独立语句),仍可能遇到锁等待超时。这是当前实现的一个限制,需要开发者注意。
Q&A
什么是Vindex,它在Vitess中有什么作用?
Vindex是Vitess中的一种索引,用于将表中的行与Keyspace ID关联,从而实现数据分片和全局索引。
Consistent Lookup Vindex如何确保数据一致性?
Consistent Lookup Vindex通过锁定和事务序列来确保数据一致性,避免使用2PC协议。
在Vitess中,如何处理数据修改以确保一致性?
Vitess通过三个连接执行DML操作,确保在多分片环境中的一致性。
Lookup Vindex的作用是什么?
Lookup Vindex作为二级索引,优化查询路由,避免性能损失。
Vitess如何避免性能损失?
Vitess通过使用Lookup Vindex来优化查询路由,避免了散播-收集操作带来的性能损失。
在Vitess中,如何处理插入操作中的重复键错误?
在插入操作中,Vitess会锁定查找行以防止其他事务竞争,从而处理重复键错误。