问题标签 [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.
c# - 如何在 IdentityUser DbSet 和其他 DbSet 之间加入
我正在尝试使用 linkq 在 ApplicationUser (从 IdentityUser 继承)和另一个模式之间加入。我的 ApplicationUser 类:
我的应用上下文文件:
我有以下文件:
.....................
在 linq 查询中,“加入”被标记为错误,我收到以下错误:
join 子句中的表达式之一的类型不正确。对“加入”的调用中的类型推断失败。异常:ArgumentNullException。
我在编译时而不是在运行时收到此错误。
mysql - 更新后从另一个事务中可见,这是 MySQL MVCC 中的错误吗?
这是我的情况:
会议 A
会议 B
会议 A
会议 B
在这里我得到了预期的结果,因为Session B有一个独立的 row 副本id = 1
,即来自Session A的提交在这里不可见。
但是当我更新这一行时,隔离中断:
会议 B
根据这个关于 MVCC 的视频https://www.youtube.com/watch?v=sxabCqWsFHg(15'00 ),这个更新应该被拒绝。但是 MySQL 接受了这个更新。
会议 B
所以这个选择得到了一个意想不到的结果:来自Session A的提交在Session B中是可见的。
我的 MySQL 版本是 5.7.26,隔离级别是 REPEATABLE-READ。
=== 更新 ===
对于带有 RocksDB 引擎的 MariaDB 10.4.10,此案例按预期工作。
在会话 B
它返回
postgresql - PostgreSQL 事务 id (xmin) 是否按顺序出现在提交版本中?
由于 PostgreSQL 文档https://www.postgresql.org/docs/current/ddl-system-columns.html
xmin此行版本的插入事务的标识(事务 ID)(行版本是行的单独状态;行的每次更新都会为同一逻辑行创建新的行版本)。
我们正在使用它(不要问为什么,只是发生)同步数据并从 PostgreSQL 源数据库中提取(ETL 中的 E)更改,我们通过间隔扫描,特别是 xmin 间隔来实现它,例如我们已经同步了 xmin 间隔0 到 10002,当我们进行下一次同步时,在这种情况下,我们将从 10003 开始搜索 xmin。如果每个已提交且可见的事务都按顺序编号,则没有问题,所有数据更改都会按顺序编号,但如果事务在它们初始化的那一刻进行编号,则可能会发生下一种情况:
- 交易 10001 开始于 15:01
- 交易 10002 开始于 15:02
- 事务 10002 在 15:02 提交
- 事务 10001 在 15:03 提交
如果我们在 15:02 进行了同步,并且在目标 DB 中获得了 max xmin:10002,在这种情况下,在从 xmin 10003 开始的下一次同步中,我们将跳过 xmin 10001 并且将丢失更改。
那么 PostgreSQL 事务 id (xmin) 是否顺序出现在提交的版本中?
同一个文档中还有 xmax :
xmax删除事务的标识(事务 ID),或零表示未删除的行版本。在可见行版本中,此列可能不为零。这通常表明删除事务尚未提交,或者尝试的删除已回滚。
所以我们可以看到计划删除行的事务(如果它将被提交),所以也许 xmin 也显示了将更改行的事务?但由于 xmin 描述,这是不可能的:
...对于此行版本。(行版本是行的单个状态;行的每次更新都会为同一逻辑行创建一个新的行版本。)
因为,正如所写,它必须与我们读取的行版本匹配,这可能只有脏读(当我们看到未提交的数据时)才能匹配,但这在 PostgreSQL https://www.postgresql.org/docs/current中不会发生/transaction-iso.html
脏读:允许,但在 PG 中不允许
postgresql - 并发查询的 MVCC 快照限制
我正在尝试学习 PostgreSQL MVCC 架构。它说 MVCC 为每个并发查询创建一个单独的快照。这种方法内存不是效率低下吗?
例如,如果有 1000 个并发查询并且表大小很大。这将创建表的多个实例。
我的理解正确吗?
sql - 使用 txid 获取最新的未处理、更新的行
我的 PostgreSQL 中有一个表(实际上是它的多个表,但为了简单起见,我们假设它只有一个)和多个需要定期查询表以查找更改项的客户端。这些是更新或插入的项目(已删除项目的处理方式是首先将它们标记为删除,然后在宽限期后实际删除它们)。
现在显而易见的解决方案是只为每一行保留一个“修改过的”时间戳列,为每个客户端记住它,然后简单地获取更改的时间戳列
然后,修改后的列将使用以下触发器保持最新:
这里明显的问题是NOW()
交易开始的时间。因此,可能会发生事务在获取更新的行时尚未提交,并且在提交时,时间戳低于 saved_modified_timestamp,因此永远不会注册更新。
我想我找到了一个可行的解决方案,我想看看你是否能找到这种方法的任何缺陷。
基本思想是使用 xmin (或者更确切地说txid_current()
)而不是时间戳,然后在获取更改时,将它们包装在显式事务中,REPEATABLE READ
并从事务中读取txid_snapshot()
(或更确切地说是它包含的三个值txid_snapshot_xmin()
, txid_snapshot_xmax()
, txid_snapshot_xip()
)。
如果我正确阅读了 postgres 文档,那么所有更改为 <txid_snapshot_xmax()
而不是 in 的事务都txid_snapshot_xip()
应该在该 fetch 事务中返回。然后,此信息应该是再次获取时获取所有更新行所需的全部信息。然后选择将如下所示,xmin_version
替换modified
列:
触发器将如下所示:
这行得通吗?还是我错过了什么?
mysql - MySQL 中的默认并发控制实现
MySQL中并发控制的默认实现是什么?是乐观锁(多版本并发控制),还是悲观锁(2相锁)?更具体地说,InnoDb 是如何做到的?在内部,mysql(带有innodb)如何决定事务的开始是锁定行还是在冲突后回滚?
database - PostgreSQL - MVCC(多版本并发控制) - 何时获取实际锁?
根据我的理解,postgres 使用两个额外的字段 Xmin 和 Xmax 来实现 mvcc,假设我们有 Employee 表,其中包含 id 和 name 列。
下面是一些 crud 操作以及它们如何同时工作(考虑隔离级别 = READ_COMMITTED),问题是何时何地获取实际锁。
- 插入-> 新事务插入一条新记录,该记录在提交之前对其他事务不可见,因此在这种情况下没有问题,也不需要锁定或版本控制。假设 id = 1,name = "aa" 被插入。Postgres 为 mvcc Xmin = current txn id(假设为 100)和 Xmax = 0/null 添加了 2 个额外的列。
使用并发读取更新-
一个)。一个新事务开始将名称更新为“bb”(对于 id = 1)。同时还有另一个事务开始读取相同的数据。
乙)。使用 Xmin = 当前事务 id(假设为 200)和 Xmax = null 以及 id = 1、name = bb 创建一个新的元组(postgres 中的不可变对象表示一行)。旧版本的 id = 1 也被更新为 Xmax = 200。读取事务看到旧版本的数据 Xmin = 100 并返回。 在这种情况下是否需要任何锁定?我认为没有,但它可能会更新旧元组的 Xmax。
以下是多个版本的相同记录(仅用于解释目的),最新版本的 Xmax = null。
使用并发更新进行更新-
一个)。交易(txn id = 300)开始将 id = 1 更新为 name = cc。另一个事务(txn id = 400)开始将同一记录(id = 1)更新为name = dd。如果这种情况也通过创建新元组并标记旧元组的 Xmax 以同样的方式进行,那么我认为它会产生问题,因为 300 和 400 都会创建一个新元组并标记旧元组的 Xmax = txn id。在这种情况下,更新可能会丢失。
在这种情况下,排他锁是由第一个 txn 获取的,其他并发更新 txns 会等到任何正在进行的 txn 完成,或者 postgres 有其他方式处理它吗?
mysql - MySQL MVCC 2 事务更新一行,选择快照问题
MySQL 版本:5.7.29 Homebrew
ENGINE=InnoDB
可重复读取
MVCC 快照问题:
表格:
步骤:
-----事务A -------------| 交易B
--------------------------------|---------------- ------------
---------开始;-----------------| --
1、select * from r;-------------| ----------------------------------
| 开始;
--------------------------------| 更新 r 设置 v=v+1 其中 id = 1;
--------------------------------| 犯罪;
2、select * from r;-------------| --
更新 r 设置 v=v+1 其中 id = 1;| --
3、select * from r;-------------| --
----------提交;----------------| --
第 1 步和第 2 步 v = 1,但为什么第 3 步 v = 3,因为 MVCC 我认为 v 应该是 2。请帮帮我。
postgresql - TOAST 在 MVCC Postgres 中的行为方式
美好的一天,我正在阅读关于 TOAST 的 Postgres 文档,但我没有找到任何关于 TOAST 如何在 MVCC 方面工作的信息。根据 postgres 的文档。
仅当要存储在表中的行值大于 TOAST_TUPLE_THRESHOLD 字节(通常为 2 kB)时,才会触发 TOAST 管理代码。
据我了解,如果字段足够大并且具有可变长度,那么 postgres 不会将此字段直接存储在元组块中,而是存储对包含该字段的不同表(文件)的引用,其中包含 chunk_id 和 sequence_id。但是,MVCC 呢?假设我有一张桌子user(data jsonb , id int PK,name varchar(255))
。通常当更新行时,将创建新行,xmin 等于当前事务。假设 jsonb 字段在 TOAST 表中并且该字段未更新,postgres 会为更新的行创建一个新的 TOAST 实例,还是新行将对现有的 TOAST 值有一个新的引用?
postgresql - 使用 Postgres 进行稳定的分页
我想使用 Postgres 数据库作为后端来实现稳定的分页。稳定,我的意思是如果我使用一些分页标记重新阅读页面,结果应该是相同的。
使用插入时间戳将不起作用,因为时钟同步错误会使分页不稳定。
我正在考虑使用 pg_export_snapshot() 作为分页标记。这样,我可以在每次读取时重用它,并且数据库将保证我得到相同的结果,因为我总是使用相同的快照。但是文档说
“快照只能在导出它的事务结束之前导入。” (https://www.postgresql.org/docs/9.4/functions-admin.html)
有什么解决方法吗?即使在事务关闭后,是否有另一种导出快照的方法?