MySQL MVCC(InnoDB)
MySQL MVCC (InnoDB)
问题是关于 MySQL InnoDB table 中同步 SELECT 和更新的行为 table:
我们有一个相对较大的 table,我们定期扫描读取多个字段,包括一个名为 LastUpdate
的字段。在扫描期间,我们更新以前扫描的行。更新在后台线程中分批执行 - 使用不同的连接。请务必注意,我们更新了 已被读取.
的行
三个问题:
- 由于 SELECT 仍在进行中,InnoDB 是否会保存更新行的先前版本?
- 使用 READ-UNCOMMITTED 对 SELECT 有帮助吗?
- 我如何确认 InnoDB 在其重做日志中保存或不保存修改行的先前版本。
忽略这个问题,编写不会惹麻烦的代码:
BEGIN;
SELECT id ... LIMIT 20; -- get list of _possible_ candidates for action
COMMIT;
**
foreach $candidate
BEGIN;
SELECT ..., is_candidate WHERE id = $candidate FOR UPDATE;
if still a candidate
process it
UPDATE ...;
COMMIT;
如果有人溜进来,比如说,在 **
,之后的检查将防止重复处理。此外,第二个 BEGIN..COMMIT 可防止任何人滑入。
FOR UPDATE
"locks"行;这很重要。
以这种方式处理的优点是交易快速,从而最大限度地减少对其他一切的影响。
问题是关于 MySQL InnoDB table 中同步 SELECT 和更新的行为 table:
我们有一个相对较大的 table,我们定期扫描读取多个字段,包括一个名为 LastUpdate
的字段。在扫描期间,我们更新以前扫描的行。更新在后台线程中分批执行 - 使用不同的连接。请务必注意,我们更新了 已被读取.
三个问题:
- 由于 SELECT 仍在进行中,InnoDB 是否会保存更新行的先前版本?
- 使用 READ-UNCOMMITTED 对 SELECT 有帮助吗?
- 我如何确认 InnoDB 在其重做日志中保存或不保存修改行的先前版本。
忽略这个问题,编写不会惹麻烦的代码:
BEGIN;
SELECT id ... LIMIT 20; -- get list of _possible_ candidates for action
COMMIT;
**
foreach $candidate
BEGIN;
SELECT ..., is_candidate WHERE id = $candidate FOR UPDATE;
if still a candidate
process it
UPDATE ...;
COMMIT;
如果有人溜进来,比如说,在 **
,之后的检查将防止重复处理。此外,第二个 BEGIN..COMMIT 可防止任何人滑入。
FOR UPDATE
"locks"行;这很重要。
以这种方式处理的优点是交易快速,从而最大限度地减少对其他一切的影响。