Mysql 事务数据库和防止死锁
我正在开发云服务,将本地数据库(订单接收POS系统)同步到中央远程数据库。我们的远程数据库正在为每个表运行最新版本的mysql 5.6和innoDB表引擎。基本上,它是一个事务性数据库,经历了大量的事务,主要是写入(即插入和更新),有时在查看报告时还经历了读取等。我们不可避免地遇到了第一次数据库死锁(请注意,这发生在升级mysql 5.6之前),我对死锁原因的理解可能是,有两个连接试图同时读取或写入一行。我也知道死锁很常见,需要正确的代码来尝试/捕获我认为我已经成功实现的死锁。 为了缓解死锁,我考虑设置两个相互镜像的数据库 A) 写入的数据库 b) 已读取的数据库 基本上,从本地到远程的同步将写入数据库A,在后台使用rsync将数据库A镜像到B,哪个数据库B将用于读取和查询报告,因为rsync不使用数据库连接来读取用于同步的数据 我的问题是,这种结构在缓解死锁方面是否有效,并且在服务器上是否存在任何重大性能问题 我希望我的问题对我想要实现的目标有意义Mysql 事务数据库和防止死锁,mysql,database,innodb,rsync,database-deadlocks,Mysql,Database,Innodb,Rsync,Database Deadlocks,我正在开发云服务,将本地数据库(订单接收POS系统)同步到中央远程数据库。我们的远程数据库正在为每个表运行最新版本的mysql 5.6和innoDB表引擎。基本上,它是一个事务性数据库,经历了大量的事务,主要是写入(即插入和更新),有时在查看报告时还经历了读取等。我们不可避免地遇到了第一次数据库死锁(请注意,这发生在升级mysql 5.6之前),我对死锁原因的理解可能是,有两个连接试图同时读取或写入一行。我也知道死锁很常见,需要正确的代码来尝试/捕获我认为我已经成功实现的死锁。 为了缓解死锁,我
提前感谢。数据库复制有助于提高性能和可用性。但是,在开始复制数据库之前,您可能需要检查许多方面 我假设您已打开旋钮来记录慢速查询。我建议您进行分析,看看是否有机会优化导致问题的查询。 另一件事是,尽管重新建模数据并不总是那么容易,但它有时会有所帮助。 验证您的报告查询是否根据需要使用索引。 您还可以研究数据分区
有时,根据您的数据量和报告要求,您可以考虑使用NoSQL数据库进行分析数据。死锁不是两个连接试图同时写入同一行的结果。只是比那复杂一点 会产生死锁的场景如下所示: 有两个资源(可能是一个表中的两行、两个表、两个文件等,我们将其标识为“a”和“B”)
在数据库中,从行到页再到表,这种事情可以在任何粒度级别发生,也可以在数据或索引中发生。让数据库引擎自行执行乐观锁定通常可以提供最佳性能,但可能会导致死锁。您可能需要在可序列化的事务中执行一些插入/更新(尽管这会导致性能下降)。考虑在一个死锁场景中触摸多个表作为潜在参与者的事务。 < P>放弃完全消除死锁。专注于“减轻”它们 只要可行,按某种规范的顺序触摸表和行。一个简单的例子是在子句中对
中的元素进行排序。我认为以下情况可能导致僵局:
UPDATE ... WHERE id IN (3,7) -- in one connection
UPDATE ... WHERE id IN (7,3) -- in another connection
但是,如果对所有事务中的ID进行排序,最糟糕的情况是一个连接会等待另一个连接释放行锁。(这就是innodb\u lock\u wait\u timeout
发挥作用的地方。)
另一个例子涉及
BEGIN;
SELECT ... FROM table1 FOR UPDATE;
SELECT ... FROM table2 FOR UPDATE;
...
COMMIT;
当然,在某些情况下,您无法预测事务中需要哪些ID或表,因此无法进行简单的排序。这就是为什么你必须准备好抓住僵局
当您遇到死锁时,只需重播事务即可。好的,如果事务中有其他代码,这可能并不简单。我相信我已经正确地索引了,但是我的表没有使用自动递增,而是使用外键组合作为主索引。例如orderid,clientid。是否所有表都应该使用in id自动递增?顺便说一句,我正在记录慢速查询并优化我的查询。另一方面,我在表中添加了另外两个索引以优化查询时间,不确定多个索引是否也有助于导致死锁,感谢您更好地向我解释死锁。*考虑在一个死锁场景中触摸多个表作为潜在参与者的事务。您是指插入多个表还是使用SelectPrimary时,并发插入和/或更新将是死锁场景中的罪魁祸首。并发选择永远不会成为问题。带有插入/更新的选择也不应该,但我不会说“从不”;根据使用的事务模式,可能会在仅执行选择的事务和执行插入或更新的事务之间引发死锁。