隔离级别和写冲突砖

表的隔离级别定义事务的程度必须从修改由孤立的并发操作。在砖写冲突取决于隔离级别。

三角洲湖提供ACID事务读写之间的担保。这意味着:

  • 多个作家跨多个集群可以同时修改一个表分区。作家看到一致的快照视图的表和写一个串行顺序出现。

    • 读者继续看到一致的快照视图的表数据砖工作开始的,即使在工作表被修改。

看到酸保证砖是什么?

请注意

砖使用三角洲湖默认所有表。本文描述了行为三角洲湖砖。

没有读表三角洲湖什么时候提交?

三角洲湖插入或附加操作不读表状态之前如果满足下列条件:

  1. 逻辑是表示使用插入SQL逻辑或追加模式。

  2. 逻辑不包含子查询或条件,参考表写操作的目标。

在其他提交、三角洲湖验证和解析表版本提交使用元数据在事务日志,但没有版本的表实际上是阅读。

请注意

许多常见的模式使用合并操作根据表插入数据条件。尽管它可能使用重写这个逻辑插入声明,任何引用目标表中的数据触发条件相同的并发性限制合并

写冲突砖

下表描述了对写操作可以在每一个冲突隔离级别

插入(1)

更新、删除、合并

优化

插入

不冲突

更新、删除、合并

可以在可序列化的冲突,不能WriteSerializable冲突

能在序列化和WriteSerializable冲突

优化

不冲突

能在序列化和WriteSerializable冲突

能在序列化和WriteSerializable冲突

重要的

(1)所有插入操作在上面的表中描述不读任何附加操作相同的数据表之前。插入包含子查询的操作读取相同的表支持相同的并发性合并

写可序列化的与可序列化的隔离级别

表的隔离级别定义事务的程度必须隔绝修改由并发事务。三角洲湖上砖支持两种隔离级别:序列化和WriteSerializable。

  • 可序列化的:最强的隔离级别。它确保承诺写操作和所有读取可序列化的。操作是允许的,只要存在一个连续的序列产生一次执行表中看到的结果一样。写操作,串行序列是一模一样的表的历史。

  • WriteSerializable(默认):隔离级别低于可序列化的。它确保只写操作(即不会读)是可序列化的。然而,这仍然是比快照隔离。WriteSerializable是默认的隔离级别,因为它提供了极好的平衡数据一致性和可用性最常见的操作。

    在这种模式下,三角洲表的内容可能不同于预计的的操作序列表中看到的历史。这是因为这种模式允许某对并发写操作(操作X和Y)继续等,其结果将是如果Y是之前执行X(即它们之间序列化),尽管历史会表明,X Y后承诺不允许重新排序,隔离级别设置表导致这些交易失败是可序列化的。

读操作总是使用快照隔离。写隔离级别决定了读者是否有可能看到一个表的快照,,根据历史上,“不存在”。

可串行化的水平,读者总是只能看到表符合历史。WriteSerializable水平,读者可以看到一个表中不存在三角洲日志。

例如,考虑txn1,一个长时间运行的删除和txn2插入txn1删除的数据。txn2和txn1完整记录在订单上。根据历史数据插入txn2表中不应该存在。可串行化的水平,读者永远不会看到txn2插入的数据。然而,对于WriteSerializable层面,读者可以在某种程度上看到txn2插入的数据。

类型的操作的更多信息可以在每个隔离级别和相互冲突可能的错误,明白了避免使用分区和不相交的命令冲突的条件

设置隔离级别

使用设置隔离级别改变命令。

改变<- - - - - -的名字>TBLPROPERTIES(“delta.isolationLevel”=<水平- - - - - -的名字>)

在哪里<级别名称>可序列化的WriteSerializable

例如,改变默认的隔离级别WriteSerializable可序列化的运行:

改变<- - - - - -的名字>TBLPROPERTIES(“delta.isolationLevel”=“序列化”)

避免使用分区和不相交的命令冲突的条件

在所有情况下都标记为“冲突”,这两个操作是否会冲突取决于他们是否使用相同的文件集。你可以不相交的两套文件分区中使用的表的列的操作条件。例如,这两个命令更新在哪里日期>“2010-01-01”删除在哪里日期<“2010-01-01”按日期将冲突如果表没有分区,既可以尝试修改相同的一组文件。分区的表日期会避免冲突。因此,分区表根据条件常用命令可以显著减少冲突。然而,分区表的列,高基数可以导致其他性能问题由于大量的子目录。

冲突异常

当一个事务冲突发生时,您将观察以下例外:

ConcurrentAppendException

此异常发生在并发操作添加同一个分区中的文件(或任何一个分区表)读取你的操作。文件添加可以造成的插入,删除,更新,或合并操作。

使用默认隔离级别WriteSerializable文件还说,由盲目的插入操作(也就是说,盲目操作,添加数据没有阅读任何数据)不与任何操作冲突,即使他们接触相同的分区(或者任何一个分区表)。如果设置隔离级别可序列化的,那么盲目的附加可能冲突。

这通常是在并发抛出异常删除,更新,或合并操作。而并发操作可能身体上更新不同分区目录,其中一个可能读取相同的分区,同时另一个更新,造成冲突。您可以显式分离,从而避免这种状况的操作。考虑下面的例子。

/ /目标的deltaTable分区按日期和国家deltaTable作为(“t”)。合并(作为(“s”),”年代。user_id = t。user_id和s。日期= t。日期AND s.country = t.country")whenMatched()。updateAll()whenNotMatched()。insertAll()执行()

假设你运行以上代码同时为不同日期或国家。因为每个工作都是工作在一个独立的分区目标三角洲表,你别指望任何冲突。然而,条件不够明确,可以扫描整个表,可以与并发冲突操作更新其他分区。相反,您可以重写你的声明中添加特定的日期和国家合并条件,如以下示例所示。

/ /目标的deltaTable分区按日期和国家deltaTable作为(“t”)。合并(作为(“s”),”年代。user_id = t。user_id和s。日期= t。日期AND s.country = t.country AND t.date = '"+<日期>+“和t。国家='"+<国家>+“”)whenMatched()。updateAll()whenNotMatched()。insertAll()执行()

现在这个操作是安全的并发运行在不同的日期和国家。

ConcurrentDeleteReadException

此异常发生在并发操作删除一个文件,你的读操作。常见的原因是删除,更新,或合并重写的操作文件。

ConcurrentDeleteDeleteException

此异常发生在并发操作删除一个文件,你的操作也删除。这可能是由于两个并发修改相同的文件压缩操作。

MetadataChangedException

此异常发生在三角洲的并发事务更新元数据表。常见的病因是改变操作或写入你的三角洲表,表的更新模式。

ConcurrentTransactionException

如果流查询使用相同的检查点位置同时多次启动和试图写三角洲的表在同一时间。你永远不应该有两个流查询使用相同的检查点位置和同时运行。

ProtocolChangedException

这个异常可以在下列情况下发生:

  • 当δ表是版本升级到一个新的协议。未来成功的操作可能需要升级你的砖运行时。

  • 当多个作家创建或替换一个表在同一时间。

  • 当多个作家写一个空路径在同一时间。

看到表协议版本为更多的细节。