问题标签 [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.
couchdb - CouchDB 文档版本控制
嗨,我想在我的 CouchDB 数据库中实现文档版本控制,在该数据库中,对文档的每一次编辑都将被记录在哪些字段被更改、谁进行了更改以及更改何时发生。
是否有任何 CouchDB 引擎提供这种支持,或者我必须在客户端手动处理它?
sql - 有没有办法以原子方式执行 SQL 合并?
我正在寻找一种方法以非锁定方式将一组值与随机 UUID 连接起来,并且不会由于并发限制而导致事务失败。
我需要编辑的表包含几个应该由 UUID 描述的值。在此示例中,表被命名foo
并声明了两个字符串列bar
,qux
它们指向单个字段uuid
。(bar, qux)
要求在整个表中是唯一的。UUID 本质上是独一无二的。
我想知道 SQL(使用 Oracle 12c)是否能够以原子方式执行以下操作:
作为我的数据库查询的结果,我希望元组(bar, qux)
与随机 UUID 连接。对于任何并发事务,此 UUID 必须相同,并且我不希望竞争请求因为另一个(随机)UUID 的并发插入而失败。
作为背景:这些插入是相当长时间运行的事务的一部分,这些事务在很大程度上彼此独立,但具有这个共享标识符表,其中值不能不一致。许多编程语言都提供 CAS,这就是我在这种情况下所追求的,但我不知道 SQL 中的一个 smilar 特性。
作为一个想法,我想知道允许脏读(未提交的读隔离级别)是否是一种解决方案,但我不知道在这种情况下合并语句是否是原子的并且对其他事务可见。(这在 Oracle 中是不可能的。)通过 JDBC 但可能从多个 VM 节点访问数据库。
postgresql - 使用 PostgreSQL MVCC 跨多个表的事务隔离
问题摘要
这是一个关于 SQL 事务中查询的可序列化性的问题。
具体来说,我使用的是 PostgreSQL。可以假设我使用的是最新版本的 PostgreSQL。根据我的阅读,我相信用于支持我正在尝试做的事情的技术被称为“多版本并发控制”或“MVCC”。
总结一下:如果我有一个主表,并且有多个外键链接表连接到该主表,我如何保证,对于表中的给定键,以及任意数量的 SELECT 语句在一个事务中使用该键,每个事务都从任何链接表中进行选择,我将获得启动事务时存在的数据?
其他问题
这个问题类似,但范围更广,而且问题和答案并没有专门与 PostgreSQL 相关: Transaction isolation and reading from multiple tables on SQL Server Express and SQL Server 2005
例子
假设我有 3 张桌子:
砖厂一次生产一块砖。它在其 4 个象限中的每个象限中制作可能具有不同颜色的砖块。
稍后有人分析砖块以确定它们的颜色组合,并将结果写入brick_colors 表。
其他人分析砖块以确定它们的重量,并将结果写入brick_weight 表。
在任何给定时间,现有的砖块可能有也可能没有记录的颜色,可能有也可能没有记录的重量。
存在一个应用程序,并且该应用程序接收到有人想要购买特定砖块的消息(此时应用程序已经通过它的砖厂/完成时间组合键知道)。
应用程序希望在它开始查询的确切时间选择砖块的所有已知属性。
如果在 MID-TRANSACTION 中添加颜色或重量信息,应用程序不想知道它。
应用程序想要执行 SEPARATE QUERIES(而不是具有多个 JOIN 到外键链接表的 SELECT,这可能会因为 brick_colors 表而返回多行)。
这个例子故意简单;如果我的示例包括 10 个外键链接表,并且它们中的许多或全部可以为同一个主键返回多行(就像 brick_colors 在上面的例子)。
尝试的解决方案
到目前为止,这是我想出的:
仅出于确保可序列化的目的而将第一个 SELECT 与 JOIN 一起使用似乎很浪费。
有没有其他方法可以做到这一点?
参考
postgresql - PostgreSQL ISOLATION LEVEL 生效的时间似乎是在第一次 SELECT 之后
我正在运行 PostgreSQL 9.5.3。
我试图理解为什么我看到下面两个例程之间的行为有所不同。我发现这种行为违反直觉,但可能有一个很好的理由;如果是这样,我只想知道它是什么。
设置ISOLATION LEVEL REPEATABLE READ
似乎直到第一个SELECT
语句之后才生效。
这两个例程之间的唯一区别是,在“例程 2”中我添加了多余的SELECT 1 ;
语句,而在“例程 1”中我没有这样做。我在“常规 2”中得到了我想要的结果。
请参阅我之前发布的(过长)问题,我错误地认为我看到的行为与我正在查询的特定表有关。
我已经从krokodilko的回答中修改了例程,以展示我所看到的。谢谢,鳄鱼!
这些是按列出的顺序连续执行的,在两个单独的会话之间来回切换。
例程 1
第 1 节:
第 2 节:
第 1 节:
第 2 节:
(为什么我在这里看到了会话 1 的效果?)
第 2 节:
第 1 节:
第 2 节:
(为什么我必须这样做?)
第 1 节:
第 2 节:
(这就是我期望看到的!)
第 2 节:
(这也是我期望看到的)
orientdb - OrientDB 是否真的实现了 MVCC?
东方数据库文档在这里:
http://orientdb.com/docs/last/Concurrency.html#atomic-operations http://orientdb.com/docs/last/Distributed-Architecture.html#distributed-transactions
说明 OrientDB 实现了 MVCC。但是 OrientDB 真的保留了多个版本的记录吗?我没有看到任何关于如何选择时间戳、如何以及何时清理过去版本的记录、如何在分布式上下文中工作以及是否支持跨集群的一致数据扫描的任何文档。
有人可以澄清一下吗?
postgresql - PostgreSQL 索引如何处理 MVCC
在 PostgreSQL 中,每次更新元组都会创建新的元组版本。所以在一段时间内可能会有很多版本的相同元组,不同的事务可以看到不同版本的元组(使用可见性规则)
索引在事务完成之前更新。这如何与 SI 一起工作?
那么当一个事务更新元组然后索引条目更新以指向新版本的元组时?
sql - 如何避免“插入一次,更新一次”表中的数据碎片?
我有大量“插入一次”的表,然后是只读的。即:在INSERT
记录的首字母之后,永远不会有任何UPDATE
或DELETE
语句。因此,磁盘上表的数据碎片很少。
我现在正在考虑needs_action
为每个表添加一个布尔字段。该字段只会更新一次,并且会缓慢/定期更新。作为 MVCC 的结果,当在VACUUM
之后出现(甚至更慢的时间表)时UPDATE
,表变得非常碎片化,因为它清除了最初插入的元组,并且它们随后被新的插入回填。
简而言之:添加这个“始终更新一次”字段将表格从设计上的最小碎片化变为设计上的高度碎片化。
是否有某种方法可以有效地实现单needs_action
记录标记,从而避免产生的表碎片?
.
.
.
.
<现在获取一些背景/补充信息... >
到目前为止考虑的一些选项...
冒着使这个问题变得庞大(因此被忽视?)的风险,以下是迄今为止已经考虑过的一些选项:
只需将列添加到每个表中,
UPDATE
然后不要担心会产生碎片,直到它实际上被证明是一个问题。- 我意识到这里过早的优化,但是随着一些表变大(> 1M,甚至> 1B),我宁愿把设计放在前面。
制作一个独立的跟踪表(对于每个表),仅包含 A)主表中的 PK 和 B)
needs_action
标志。AFTER INSERT
使用主表中的触发器在跟踪表中创建记录- 这将在主表上保留“仅插入”最小碎片级别......以增加(显着?)前期写入开销为代价
- 将跟踪表放在单独的模式中也可以巧妙地将功能与核心表分开
强制
needs_action
字段为 HOT 更新以避免元组复制- 需要索引
WHERE needs_action = TRUE
似乎排除了这个选项,但也许还有另一种方法可以快速找到它们?
- 需要索引
使用表格填充因子(50?)为不可避免的事情留出空间
UPDATE
- 例如:将 fillfactor 设置为 50 为 留出空间
UPDATE
,因此将其保持在同一页面中 UPDATE
但是......似乎只有一个,这将使表格包装分数永远保持在 50% 并占用两倍的存储空间?我还没有 100% 理解这个选项……还在学习。
- 例如:将 fillfactor 设置为 50 为 留出空间
在主表记录中找到一个特殊/神奇的字段/位,可以在没有 MVCC 影响的情况下进行旋转。
- 这似乎在 postgres 中不存在。即使这样做,也需要对其进行索引(或具有类似于
WHERE needs_action = TRUE
部分索引的其他快速查找机制) - 能够选择性地抑制特定列上的 MVCC 操作似乎在这里会很好(尽管肯定充满危险)
- 这似乎在 postgres 中不存在。即使这样做,也需要对其进行索引(或具有类似于
存储在 postgres
needs_action
之外(例如:作为<table_name>:needs_copying
redis 中的 PK 列表)以避免由于 mvcc 造成的碎片。- 不过,我担心保持这种原子性。也许
redis_fdw
在触发器中使用(或其他一些 fdw?)AFTER INSERT
可以保持原子性?我需要了解有关 fdw 功能的更多信息……不过,我能找到的所有 fdw 似乎都是只读的。
- 不过,我担心保持这种原子性。也许
运行具有背景碎片整理/压缩的精美视图,如这篇精彩的文章中所述
- 似乎对所有桌子都做了很多事情。
只需在 postgres 表中跟踪需要复制的 ids/PKs
- 只需将需要操作的 id 作为记录存储到快速惰性表中(例如:无 PK),以及
DELETE
操作完成时的记录 - 类似于
RPUSH
ing 到离线 redis 列表(但绝对是ACID) - 这似乎是目前最好的选择。
- 只需将需要操作的 id 作为记录存储到快速惰性表中(例如:无 PK),以及
还有其他选择吗?
更多关于驱动这个的具体用例......
我对如何避免这种碎片的一般情况感兴趣,但这里有更多关于当前用例的信息:
- 读取性能比所有表的写入性能重要得多(但避免疯狂的慢写显然是可取的)
- 一些表将达到数百万行。少数可能会达到数十亿行。
SELECT
查询将跨越广泛的表范围(不仅仅是最近的数据),范围可以从单个结果记录到 100k+- 表格设计可以从头开始...无需担心现有数据
- PostgreSQL 9.6
transactions - Marklogic MVCC:同时期与非阻塞
我试图通过一个例子来理解同时期和非阻塞的参数。请让我知道我是否正确。
假设我们有事务 T1、T2、T3 发生在时间戳 =
10。T1、T2、T3 分别在 30、40、50 提交。如果查询事务在 35 出现:
for contemporaneous:查询读取已提交 T1 的版本,并让 T2 和 T3 等待读取完成。
对于非阻塞:只有在所有 3 个事务 T1、T2、T3 在 50 处提交后,查询才能读取。
mysql - 关于mysql innodb mvcc的一个测试
我现在正在学习 InnoDB mvcc,我尝试了一个测试节目,如下所示:
mysql版本:
表架构:
然后用这样的数据初始化:
起初我在不同的终端打开了两个会话,测试步骤如下所示:
t1:
t2:
t1:
这让我感到困惑,为什么 t1 可以在 t1 提交之前更新 t2 插入的行?我的 tx_isolation 级别是可重复读取的,为什么此更新 sql 有效?
我的隔离显示如下:
感谢提前:)
postgresql - 直接使用PostgreSQL的多版本并发控制
是否可以直接使用多版本并发控制作为 PostgreSQL 数据库的客户端?我想手动浏览/添加/删除/恢复旧版本。
我的用例需要保留多个以前版本的数据(我有很多数据和很多版本)。
在官方文档中描述了 MVCC 机制(https://www.postgresql.org/docs/9.5/static/mvcc-intro.html),但没有任何 API 可以直接使用它。