问题标签 [mvcc]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
57 浏览

postgresql - Postgres 如何以原子方式更新二级索引?

我了解当事务执行更改时,Postgres mvcc 方案会存储一个包含更新数据的新行以及相关版本。

其他事务知道他们应该看到哪些版本,并选择适当的行。

我也知道表的主索引存储了行的所有版本。我可以看到如何更新主索引(您将其锁定以进行写入,追加行并解锁。我不确定这是否是它的工作方式,但这是一种潜在的方式)。

但是 Postgres 是如何自动更新二级索引的呢?我想当事务提交时,所有索引都需要使用行中的新数据进行更新。

Postgres 是否会锁定所有二级索引以自动更新它们?如果是这样,锁定的粒度是在索引级别还是在值级别(仅锁定特定值的索引部分)?

其他数据库引擎(如 InnoDB)中的方法是否相同?

我正在构建一个玩具数据库,我很难理解如何有效地更新二级索引。也欢迎任何有关该主题的论文!

非常感谢!

0 投票
1 回答
62 浏览

database - 为什么 PostgreSQL 索引不包含可见性信息?

我知道 PostgreSQL 中的物理存储如下所示:

所以Index-Only Scan需要帮助Visibility Map

我的问题是:为什么我们不将t_xmin,也存储t_xmax在索引中?

喜欢:

0 投票
1 回答
398 浏览

mysql - MVCC 如何与 MySql 中的 Lock 配合使用?

我知道在Mysql中使用锁或者MVCC可以实现并发控制,比如repeatable-reading。但我不知道 MVCC 如何避免幻读。在其他地方了解到一般是通过MVCC和Gap-Lock来实现的,但是我目前的理解是MVCC不需要锁,即更新和删除都是使用undo-logs来实现的。如果是这样,MVCC 和锁机制如何协同工作?

例如,为了避免幻读,MVCC 是否会在 T1 中的某些行上添加间隙锁?如果是这样,当 T2 发生更新时,MVCC 是如何做的,通常只是附加一个更新撤消日志?还是阻止它?

0 投票
1 回答
110 浏览

mysql - mysql INNODB如何实现READ-UNCOMMITTED?

我读到 mysql INNODB 使用 MVCC(乐观)来解决 READ_COMMITTED 和 REPEATABLE_READ 隔离级别(和)2PL(悲观)来解决 SERIALIZABLE。但是没有提到它是如何解决 READ_UNCOMMITTED 的。

  • 我打开了两个具有 READ_UNCOMMITTED 隔离级别的 mysql 会话。在这两个会话中,我都尝试更新相同的记录。在第一个会话中,它得到了更新,但在第二个会话中,它正在等待第一个会话提交/回滚。这是谁锁的?因为显然这里没有 MVCC 或 2PL 的参与。

  • 写-写冲突->另外,我在所有隔离级别中看到了相同的行为,至少在 READ_COMMITTED 和 REPEATABLE_READ 中,这是由 MVCC 解决的,当第一个会话更新一行时,第二个会话等待。我知道 MVCC 在以下情况下不会锁定,

    i) 第一次阅读(和)第二次阅读

    ii) 第一次写作(和)第二次阅读

    iii) 第一次阅读(和)第二次写作

这对“读者不会阻止作家,作家不会阻止读者”的说法是正确的。但是,在这种情况下,

iv) 第一个会话写入(和)第二个会话写入 - INNODB 是否锁定事务并等到其他提交/回滚?

Mysql 版本:5.7.32 引擎:INNODB

0 投票
1 回答
83 浏览

google-cloud-spanner - yugabytedb 如何保证垃圾回收时的快照一致?

例如:

  1. 有两个项目,k1 和 k2,时间为 t1。
  2. 然后,一个读事务(A)得到一个时间为 t1 的快照。事务(A)用 t1 成功读取了 k1。
  3. 同时,另一个事务(B)在时间 t2(t2>t1)写入 k2。
  4. yugabytedb 以某种方式进行垃圾收集,因此带有 t1 的 k1 将被删除。
  5. 如果事务(A)在时间 t1 读取 k2,它将找不到时间小于 t1 的任何版本的 k2。

我很困惑 yugabytedb 如何保持一致的快照。

几乎搜遍了 yugabytedb 的事务文档,但没有找到任何与垃圾回收相关的内容。

我看过google spanner关于垃圾回收的一些描述,就是将旧版本保留一小时。但是yugabytedb使用HLC而不是Truetime。

谁能介绍一下yugabytedb的垃圾回收机制?和扳手一样吗?

0 投票
1 回答
72 浏览

mysql - MVCC - 一致性读取的原子性问题

同时读取和写入同一个元组可能会导致读取逻辑异常,因为写入元组覆盖的非原子动作。

对于 MySql 中的 MVCC,

从概念上讲,由于 ReadView,可以通过可见性规则避免访问正在写入的元组,从而避免发生在同一区域的读取和写入之间的竞争

但是在实现细节上,我还有一个疑问:覆盖一个元组的一个字段会替换堆中的数据。如果有读操作进来,会读写同一个区域,可能会导致读写冲突(字节复制不是原子的)。

如何避免这种读写冲突?是锁吗?


没把我的意思表达的很好,其实是想表达一下锁竞争的问题:</p>

Insert into tableA(age,num) values(1,1) 假设数据库中有一条数据。

此时,在读提交下,以下两个事务同时运行: 事务1:select * from tableA 事务2:更新tableA set age=2

它们在数据库中运行的步骤如下:

  1. 事务1访问页面中唯一的一条数据:访问该行数据的事务id,通过可见性规则判断数据可见
  2. 事务2定位到该行数据,发现写入的age字段与当前数据占用的大小相同,于是开始执行替换逻辑
  3. 事务2将当前数据中age字段的值复制到undo,然后将undo指针指向过去,事务id更新
  4. 事务 2 将值 2 写回当前数据的年龄字段
  5. 事务1开始访问age字段,读取到当前数据值为2,访问num字段的值为1,返回(2, 1)
  6. 事务 2 提交

通过以上步骤的操作,可以看到事务1返回的结果不是预期的,根本原因是读取事务id的动作和写数据的动作(undo、transaction id、new数据)不是互斥的

mvcc 是一种访问设计,但是数据库引擎在访问和写入元组时仍然会竞争同一个区域。Innodb在实现mvcc时如何巧妙避免读写冲突?

0 投票
2 回答
122 浏览

postgresql - 在 Postgres 中禁用 MVCC

我有数十年的 MSSQL 经验,但没有使用 Postgres 及其 MVCC 并发控制风格。

在 MSSQL 中,如果我有一个非常大的只读数据集,我会将数据库设置为只读(为了安全起见)并使用未提交的事务隔离级别,这样可以避免数据集不需要的锁争用反正。

在 Postgres 中,有没有等价的?将数据库设置为只读并确保完全安全的 PG 不使用 MVCC 的某种方式,只需读取而不制作行副本?因为 MVCC 似乎有一些相当大的开销,对于非常大的被动数据集的多个读取器来说,这似乎可能是昂贵的。

编辑:评论说我误解了只有在写作发生时才制作副本,而不是像我想象的那样阅读。

0 投票
0 回答
25 浏览

database - 为什么需要 PostgreSQL 中的 CommandID

我很难理解为什么在 PostgreSQL 中需要CommandId(记录在此处)。CommandId 有时也称为cminand cmax

我了解交易 ID ( xmin/xmax) 是必需的。然而,cmin/cmax值被记录为仅与当前事务相关。

我几乎到处都在环顾四周,但即使是 PostgreSQL 代码库中的.c/.h文件也很少谈论它。

0 投票
0 回答
26 浏览

php - 使用 postgresql 事务状态进行调试

我有一个用 PHP 编写的应用程序,它使用 Doctrine 作为 ORM,并且一堆代码在单个数据库事务中执行。一旦事务被提交,就会执行很多查询。有没有办法在 postgres 中使用“脏读”?

使用 MySQL,我曾经使用 PHPStorm 内置的数据库工具在调试代码时查看数据库状态。但是,对于 PostgreSql,情况并非如此,因为此 RDMS 中的“未提交读取”隔离级别不允许脏读。这确实是一个问题,因为我们无法查看数据库的当前事务状态。

我知道这是一个非同寻常的问题,在生产中我们不会使用 Read uncommitted 隔离级别,但它对于调试客户端代码至关重要。如果您有任何解决方法或有任何帮助 - 我将非常感激。

0 投票
1 回答
20 浏览

database - MVCC下的relpages和reltuples

如果我理解正确,在 MVCC(多版本并发控制)下,死元组会留在页面中,直到真空进入并将它们标记为“未使用”,直到“真空已满”进入并重新组织它们以对空间进行碎片整理 - - 所以我们为相同的数据使用更少的空间。

我有一张桌子,在一个尚未完成的环境中vacuum full

在另一个环境中经历过vacuum full

看起来relpages确实大幅下降,这符合我的理解。然而,reltuples没有。(relpages 有 250 倍的变化,而 reltuples 只有 1.33 倍)这是否意味着reltuples不包括死元组?如果是这种情况,reltuples用于设计查询计划的查询计划器是否有办法解决死元组?