【问题标题】:handle locks in redshift红移中的手柄锁
【发布时间】:2017-02-27 14:48:10
【问题描述】:

我有一个 python 脚本,它在 Redshift 中执行多个 sql 脚本(一个接一个)。这些sql脚本中的一些表可以被多次查询。例如。表 t1 可以在一个脚本中选择,并且可以在另一个脚本中删除/重新创建。这整个过程在一个事务中运行。现在,有时,我收到检测到死锁的错误,整个事务被回滚。如果表出现死锁,我想等表释放后再重试sql执行。对于其他类型的错误,我想回滚事务。从文档中,看起来表锁直到事务结束才被释放。我想实现所有或没有数据更改(通过使用事务来完成),但也想处理死锁。关于如何实现这一点的任何建议?

【问题讨论】:

    标签: amazon-redshift database-deadlocks


    【解决方案1】:

    我会在一个带有重试循环的事务中执行您所指的所有 SQL。下面是我用来处理并发问题和重试的逻辑(为简洁起见,伪代码)。我没有让系统无限期地等待锁被释放。相反,我通过随着时间的推移重试来在应用程序中处理它。

    begin transaction
    while not successful and count < 5
        try 
            execute sql
            commit
        except
            if error code is '40P01' or '55P03'
                # Deadlock or lock not available
                sleep a random time (200 ms to 1 sec) * number of retries
            else if error code is '40001' or '25P02'
                # "In failed sql transaction" or serialized transaction failure
                rollback
                sleep a random time (200 ms to 1 sec) * number of retries
                begin transaction
            else if error message is 'There is no active transaction'
                sleep a random time (200 ms to 1 sec) * number of retries
                begin transaction
        increment count
    

    关键组件捕获每个type of error,知道哪些情况需要回滚,并拥有exponential backoff for retries

    【讨论】:

    • 如果我理解正确,您建议在每个 sql 脚本之后提交,并仅回滚出错的脚本。出现死锁错误时,有没有办法保证所有的sql脚本都在一个事务下运行?
    • 我建议您在一个事务中运行所有 SQL(我的 execute sql 行)。如果它死锁或失败,你重试整个事情。您可能也对保存点感兴趣,尽管我自己从未使用过它们,也不知道它是否在 redshift 中可用:postgresql.org/docs/current/static/sql-savepoint.html
    • 忽略我关于使用保存点的评论。回滚到保存点在 redshift 中不可用:docs.aws.amazon.com/redshift/latest/dg/…
    • Redshift 和事务要考虑的其他事项 - 您需要确保您的连接已将 AutoCommit 设置为 false,否则使用回滚命令本身以及您想要的所有内容都会出错回滚将被提交。连接上的 AutoCommit 功能会忽略事务结构。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多