隔离级别和写冲突砖
表的隔离级别定义事务的程度必须从修改由孤立的并发操作。在砖写冲突取决于隔离级别。
三角洲湖提供ACID事务读写之间的担保。这意味着:
多个作家跨多个集群可以同时修改一个表分区。作家看到一致的快照视图的表和写一个串行顺序出现。
读者继续看到一致的快照视图的表数据砖工作开始的,即使在工作表被修改。
看到酸保证砖是什么?。
请注意
砖使用三角洲湖默认所有表。本文描述了行为三角洲湖砖。
没有读表三角洲湖什么时候提交?
三角洲湖插入
或附加操作不读表状态之前如果满足下列条件:
逻辑是表示使用
插入
SQL逻辑或追加模式。逻辑不包含子查询或条件,参考表写操作的目标。
在其他提交、三角洲湖验证和解析表版本提交使用元数据在事务日志,但没有版本的表实际上是阅读。
请注意
许多常见的模式使用合并
操作根据表插入数据条件。尽管它可能使用重写这个逻辑插入
声明,任何引用目标表中的数据触发条件相同的并发性限制合并
。
写冲突砖
下表描述了对写操作可以在每一个冲突隔离级别。
请注意
具有标识列的表不支持并发事务。看到使用标识列在三角洲湖。
插入(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()。执行()
现在这个操作是安全的并发运行在不同的日期和国家。
ProtocolChangedException
这个异常可以在下列情况下发生:
当δ表是版本升级到一个新的协议。未来成功的操作可能需要升级你的砖运行时。
当多个作家创建或替换一个表在同一时间。
当多个作家写一个空路径在同一时间。
看到砖三角洲湖管理功能的兼容性如何?为更多的细节。