MySQL有没有办法不加锁?
我有一个每天运行一次的查询,它从数据库中获取某些表并将它们放入一个表中,以便我可以以我需要的任何格式快速导出信息。
然而,我遇到了一个问题,它给了我以下错误:“SQLSTATE[40001]:序列化失败:1213尝试获取锁时发现死锁;尝试重新启动事务”
据我所知,这听起来像是我的查询正在尝试获取当已经有锁时,锁定表。不过我承认我对表锁定或其工作原理一无所知。
实际上,我只是想读取其他表而不是写入它们,有没有办法可以创建查询但不请求锁定?
我的查询太长了,所以这就是我没有发布它的原因。如果您需要某些部分,请告诉我,我可以发布它们。
I have a query that I run once a day that takes certain tables from my database and puts them into a single table so that I can quickly export the information in any format I require.
I am running into a problem however that gives me the following error: "SQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction"
From what I understand it sounds like my query is trying to get a lock on the table when there already is a lock in place. However I confess that I do not know anything about table locking or how it works.
Really I am just trying to read the other tables and not write to them, is there a way that I can create the query but not request a lock?
My query is ridiculously long so that's why I did not post it. If there are certain parts that you need let me know and I can post them.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以尝试使用 INSERT DELAYED,这就是它的作用:
如果您愿意看到混合状态的数据,您可以更改事务隔离级别
我从另一个SO答案中了解到作者:Jon Erickson
You could try using INSERT DELAYED, here is what it does:
If you are willing to see data in a mixed state, you can change the transaction isolation level
I learned that one from another SO answer by Jon Erickson
如果您处于事务隔离模式 REPEATABLE_READ(这是默认值),则 select 不应创建任何锁。这是正常的。
但是,如果您使用 insert ... select,您当然会在目标表中获得锁。
因此,只要没有其他人写入目标表,并且您的程序最多有一个副本同时运行,您就永远不会出现死锁。
当两个(或更多)进程尝试做永远无法完成的冲突事情时,就会发生死锁。通常,这涉及以不同的顺序更新同一对行,但这可能取决于您的表结构。
需要考虑的想法:
您可以在死锁发生后立即使用 SHOW ENGINE INNODB STATUS 查看死锁中涉及的事务正在执行的操作。
您应该能够看到其他进程是什么以及它们在做什么。考虑打开常规日志或使用其他调试技术。
请务必在非生产系统中进行任何测试!
If you are in transaction isolation mode REPEATABLE_READ (which is the default), then selects should no create any locks. This is normal.
However if you're using insert ... select of course you'll get locks in the destination table.
So provided nobody else is writing to the destination table, AND there's at most one copy of your program running at once, you can never get a deadlock.
Deadlocks happen when two (or more) processes try to do conflicting things which could never complete. Normally this involves updating the same pair of rows in a differing order, but it can depend on your table structure.
ideas to consider:
You can see what the transactions involved in a deadlock were doing, using SHOW ENGINE INNODB STATUS, immediately after the deadlock.
You should be able to see what the other process(es) were and what they were doing. Consider turning the general log on or using other debug techniques.
Be sure to do any testing in a non-production system!