用于生产中的rds的MySQL Debezium连接器导致死锁

时间:2019-10-04 08:47:24

标签: mysql apache-kafka rds cdc debezium

我们正在创建从RDS中的Mysql到弹性搜索的数据管道,以创建搜索索引, 为此,使用debezium cdc及其mysql源和弹性接收器连接器。

现在,由于mysql进入rds,我们必须授予mysql用户LOCK TABLE权限,以获取我们想要cdc的两个表,如文档中所述。

我们还有其他各种mysql用户在执行事务,这可能需要两个表中的任何一个。

将mysql连接器连接到生产数据库后,立即创建了一个锁,整个系统崩溃了,意识到这一点后,我们很快停止了kafka并删除了该连接器,但是锁仍在增加,并且仅通过停止运行生产代码并手动终止进程来停止所有新查询后,解决了该问题。

这可能是什么潜在原因,我们如何防止这种情况发生?

3 个答案:

答案 0 :(得分:2)

使用副本来防止锁表语句被执行,为什么debezium需要锁表?所有CDC工具都从bin日志中获取事件。

答案 1 :(得分:1)

我只是在猜测,因为我不知道您的查询流量。我认为您看到的锁增加是等待表锁释放的查询积压。

我的意思是以下顺序是我所相信的:

  1. Debezium在您的两个表上启动表锁定。
  2. 该应用程序仍在工作,并且正在尝试执行访问那些锁定表的查询。查询开始等待释放锁。他们将等待长达1年(这是默认的lock_wait_timeout值)。
  3. 您花了几分钟的时间来弄清楚为什么您的网站没有响应,所以大量的查询被堆积起来。可能多达max_connections。在所有允许的连接都充满了被阻止的查询之后,应用程序将根本无法连接到MySQL。
  4. 最后,您停止试图读取其数据初始快照的Debezium进程。释放表锁。
  5. 立即释放表锁时,可以继续进行等待的查询。

    • 但是,如果它们是INSERT / UPDATE / DELETE / REPLACE或SELECT ... FOR UPDATE或其他锁定语句,它们中的许多确实也需要获取锁。
    • 由于有许多这样的查询排队,因此它们更有可能请求重叠的锁,这意味着它们必须等待彼此完成并释放锁。
    • 此外,由于同时执行数百个查询,因此它们使系统资源(如CPU)超负荷运行,从而导致系统负载高,这也使它们都变慢了。因此,完成查询需要更长的时间,因此,如果彼此阻塞,则必须等待更长的时间。
  6. 同时,应用程序仍在尝试接受请求,因此正在添加更多查询以执行。它们还受到排队和资源枯竭的影响。

  7. 最终,您停止了该应用程序,这至少使等待查询的队列逐渐完成。随着系统负载的降低,MySQL能够更有效地处理查询并很快完成所有查询。

另一个答案的建议是为您的Debezium快照使用只读副本。如果您的应用程序可以在一段时间内从MySQL主实例读取,则在Debezium锁定副本时,不会在副本上阻止任何查询。最终,Debezium将完成所有数据的读取,并释放锁,然后继续仅读取binlog。然后,该应用可以将副本作为读取实例来继续使用。

如果您的binlog使用GTID,则应该能够使Debezium这样的CDC工具从副本中读取快照,然后完成操作后,切换到主数据库以读取binlog。但是,如果您不使用GTID,那将更加棘手。该工具必须知道主副本上的binlog位置与副本上的快照相对应。

答案 2 :(得分:1)

如果锁定存在问题,并且您无法在锁定与一致性之间进行权衡,那么请查看snapshot.locking.mode配置选项。