简体   繁体   English

一般的 InnoDB UPDATE 是否锁定整个表并阻止传入的特定 UPDATE?

[英]Does a general InnoDB UPDATE lock the entire table and block incoming specific UPDATEs?

Suppose I ran this statement:假设我运行了这条语句:

UPDATE Employees set country='AU'

On an InnoDB table, Employees, with about 10 million rows.在 InnoDB 表 Employees 上,大约有 1000 万行。

This table is also actively being updated by other users through SQL queries like the one below:其他用户也通过 SQL 查询积极更新此表,如下所示:

Eg a User, ID = 20, changes their country to NZ:例如,ID = 20 的用户将其国家/地区更改为 NZ:

UPDATE Employees set country='NZ' where id = 20
  1. In that case, will any further updates to this table block until the general update completes?在那种情况下,在一般更新完成之前,是否会阻止对该表的任何进一步更新?
  2. If so, is there a way to allow specific updates and the general update to run concurrently, if they are not updating the same row?如果是这样,有没有办法允许特定更新和一般更新同时运行,如果它们不更新同一行? (To clarify what I mean here: suppose the general update finishes updating Employees with Id 1 - 50, and is now updating Emplyoees 51 - ~10 million, a singular update on Employee with id of 20 should go through without waiting for the general update to finish) (为了澄清我在这里的意思:假设一般更新完成更新 ID 为 1 - 50 的员工,现在正在更新员工 51 - ~1000 万,对 ID 为 20 的员工的单一更新应该 go 通过而不等待一般更新完成)
  1. Yes, the first update will place exclusive locks on all records in the table, blocking other queries from updating it.是的,第一次更新会在表中的所有记录上放置独占锁,阻止其他查询更新它。 The locks are held until the transaction is commited.锁一直持有到事务被提交。

  2. No. The locks are held while the transaction is running and a released when the transaction is commited.不会。锁在事务运行时保持,在事务提交时释放。 You may want to update the table in chuncks, rather than in one big bang, avoiding the first update locking the entire table.您可能希望分块更新表,而不是一次性更新表,避免第一次更新锁定整个表。 Or execute the update outside of business hours, if possible.或者,如果可能,在工作时间之外执行更新。

Let's "think out of the box"...让我们“跳出框框思考”......

Have 2 columns.有 2 列。 One with the counter ;一个与counter ; one ( dy ) with the DATE of the last increment of the counter.一个 ( dy ) 与计数器最后一次递增的DATE Then make the bumping of the counter a little more complex -- namely to reset it to 1 if the date is before today.然后使计数器的碰撞稍微复杂一些——也就是说,如果日期早于今天,则将其重置为 1。 Also (always) update the date to CURDATE() .还(总是)将日期更新为CURDATE()

Something like就像是

UPDATE t
    SET counter = IF (dy = CURDATE(), counter + 1, 1),
        dy = CURDATE()
    WHERE id = 123

This eliminates the big, nightly, update.消除了每晚的大更新。

To fetch the counter for the current day ,要获取当天的计数器,

SELECT  IF (dy = CURDATE(), counter, 0) AS counter
    WHERE id = 123;

This technique also avoids having to run the big update at exactly midnight.这种技术还避免了必须在午夜时分运行大更新。 And a second-order "bug" if the machine happened to be down at midnight (and the update fails to get run for the day).如果机器碰巧在午夜停机(并且当天无法运行更新),则会出现二阶“错误”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM