标签: serialization

PostgreSQL 中并发 DELETE / INSERT 的锁定问题

这很简单,但我对 PG 所做的(v9.0)感到困惑。我们从一个简单的表开始:

CREATE TABLE test (id INT PRIMARY KEY);
Run Code Online (Sandbox Code Playgroud)

和几行:

INSERT INTO TEST VALUES (1);
INSERT INTO TEST VALUES (2);
Run Code Online (Sandbox Code Playgroud)

使用我最喜欢的 JDBC 查询工具 (ExecuteQuery),我将两个会话窗口连接到该表所在的数据库。它们都是事务性的(即 auto-commit=false)。我们称它们为 S1 和 S2。

每个相同的代码位:

1:DELETE FROM test WHERE id=1;
2:INSERT INTO test VALUES (1);
3:COMMIT;
Run Code Online (Sandbox Code Playgroud)

现在,以慢动作运行它,在窗口中一次执行一个。

S1-1 runs (1 row deleted)
S2-1 runs (but is blocked since S1 has a write lock)
S1-2 runs (1 row inserted)
S1-3 runs, releasing the write lock
S2-1 runs, now that it can get the lock. But reports …
Run Code Online (Sandbox Code Playgroud)

postgresql concurrency locking serialization

38
推荐指数
4
解决办法
3万
查看次数

SQL Server 的可序列化隔离级别是否锁定整个表

我和我的一位同事讨论了使用可序列化隔离级别的含义。他说它锁定了整个表,但我不同意告诉他它可能可以但它尝试应用范围锁并且它不应用真正的序列化,如此处所述:可序列化隔离级别

我在文档中找不到“锁定整个表”的任何内容:SET TRANSACTION ISOLATION LEVEL

该文档说明了一系列关于范围锁的内容,因此理论上您可以通过简单地拥有一个范围锁来锁定整个表,该范围锁可以锁定表中可能值的整个范围,但它不会锁定表。

我在这里完全错了吗?它实际上是否锁定了整个表(或多个表)?

sql-server isolation-level serialization

11
推荐指数
2
解决办法
2028
查看次数

在某些情况下,遵循 thomas 写入规则的时间戳协议是否允许不可视图序列化的计划?

我在教科书(Avi Silberschatz、Henry F. Korth 和 S. Sudarshan $6e$ 的《数据库系统概念教科书》)中遇到了以下行。686:

Thomas 的写入规则允许不可冲突序列化但仍然正确的调度。那些允许的非冲突可序列化调度满足视图可序列化调度的定义(参见示例框)。

我从上面几行中了解到,遵循 Thomas 的写入规则的时间戳协议生成的每个时间表都是视图可序列化的。

现在让我们采用以下小时间表:$S:R_1(X)、W_2(X)、W_1(X)$。

这个时间表 $S$ 在时间戳协议下是允许的,该协议遵循 Thomas 的写入规则。

并且序列化顺序是 $R_1(X), W_1(X).$

但我无法证明它是视图可序列化的。

其实我认为它是非视图可序列化的,因为,

  1. 考虑串行顺序为 $T_1, T_2$

    现在 $X$ 的最终值由 $T_2$ 写入。所以不等价。

  2. 下一个替代序列是 $T_2, T_1$

    在这里,$R_1(X)$ 将读取由 $T_1$ 写入的 $X$ 的值,而不是在两个事务开始之前存在的原始值。所以这也不是视图等价的。

这里出了什么问题?请帮我解决这个问题。

concurrency timestamp serialization protocol

7
推荐指数
1
解决办法
268
查看次数

调试 PostgreSQL 序列化失败

我想我们的PostgreSQL 9.4的事务级数据库迁移READ COMMITTED要么REPEATABLE READSERIALIZABLE。在任何一种情况下,我都会遇到一组新的格式错误:

(for both)
ERROR:  could not serialize access due to concurrent update
(just for SERIALIZABLE)
ERROR:  could not serialize access due to read/write dependencies among transactions
Run Code Online (Sandbox Code Playgroud)

在阅读了 SSI 上的 wiki 页面文档后,我彻底了解了可能导致这些错误的错误条件、如何处理它们,甚至是避免它们的最佳实践。

但是,我看不到从 PostgreSQL 可以提供的任何调试输出或任何调试信息中确定导致它们的数据依赖性的方法。有没有办法从数据库中获取这些信息,要么在回滚时执行额外的查询,要么通过某种日志机制?

有了这些信息,我就可以进行应用程序级别的更改(锁定、不同的查询等),从而消除一些数据竞争以避免过多的回滚。

postgresql isolation-level serialization postgresql-9.4

6
推荐指数
1
解决办法
1492
查看次数

在两个表中的触发器函数中选择

我在 x86_64-unknown-linux-gnu 上的 PostgreSQL 9.4.3 中的表和触发器,由 gcc (Debian 4.9.2-10) 4.9.2,64 位编译:

CREATE TABLE measurements (
        measurement_id SERIAL PRIMARY KEY NOT NULL,
        measurement_size_in_bytes INTEGER NOT NULL
    );    

CREATE TABLE file_headers (
        header_id SERIAL PRIMARY KEY NOT NULL, 
        measurement_id INTEGER NOT NULL, 
        file_header_index_start INTEGER,
        file_header_index_end INTEGER
    );

CREATE TRIGGER measurement_ids AFTER INSERT 
        ON measurements FOR EACH ROW 
        EXECUTE PROCEDURE ins_function('SELECT measurement_id FROM measurements 
        ORDER BY measurement_id desc limit 1;', 1, 666 ); 
Run Code Online (Sandbox Code Playgroud)

在那里我假设 SELECT 的数据类型自 SERIAL 以来是 INTEGER 但它显然是错误的,因为我从这个启动触发器的命令中收到错误消息:

INSERT INTO measurements …
Run Code Online (Sandbox Code Playgroud)

postgresql trigger datatypes plpgsql serialization

6
推荐指数
1
解决办法
2万
查看次数

如何在可序列化隔离级别为事务实现 insert-if-not-found?

我很难弄清楚如何准确实现“如果未找到则插入”功能。考虑以下。

我们有一个名为artist2 列的表,(name, id)其中name是唯一id键,是串行主键。这是一个人为的例子,但它说明了我的问题:

    SESSION A                     SESSION B
1.                                SELECT id FROM artist
                                    WHERE name = 'Bob';
2.  INSERT INTO artist (name)
      VALUES ('Bob')
3.                                INSERT INTO artist (name)
                                    VALUES ('Bob')
4.   code that users 'Bob'
     (e.g., a FK to Bob's ID)
5.                                ??? Bob already exists, but we
                                  can't find it
4.  COMMIT
Run Code Online (Sandbox Code Playgroud)

会话 B 开始尝试找到一个artist叫 Bob 的人,但失败了。但是,会话 A 然后创建了 Bob。会话 B 尝试插入名为 Bob 的艺术家,但由于违反主键而失败。但这是我明白的一点——如果我将操作 3 更改 …

postgresql transaction serialization

5
推荐指数
1
解决办法
3132
查看次数

顺序保留冲突可序列化计划的含义是什么?

我正在研究冲突序列化类中的顺序保留的概念,并且遇到了顺序保留冲突可序列化(简称 OCSR)。以下是我查到的OCSR的定义:

\n\n
\n

如果h是等价于串行历史hs 的冲突,其中 t,t'\xe2\x88\x88h:如果t完全出现在h中的t'之前,则历史 h 是可序列化的保留冲突顺序的冲突,那么hs中也同样成立。

\n
\n\n

以下是 OCSR 中的计划示例之一:

\n\n
\n

w3(y) c3 w1(x)r2(x) c2 w1(y) c1

\n
\n\n

但我不明白为什么这个时间表在 OCSR 中。因为根据我的理解,这是冲突图 t3 --- > t1 ---- > t2

\n\n

它显示了一个串行时间表,其中 t1 在 t2 之前。但在原始的交错时间表中,t2 完全出现在 t1 之前。那么给定的示例如何说是在 OCSR 中呢?\n谁能帮我更好地理解这一点吗?

\n

serialization

5
推荐指数
1
解决办法
940
查看次数

不同 ID 上的 PostgreSQL 序列化失败

可序列化隔离模式可用于避免更新插入相等 id 时的竞争条件。因此,create table u(uid int primary key, name text);如果我们运行两个相似的事务 T1 和 T2:

begin isolation level serializable;
select * from u where uid = 1;
Run Code Online (Sandbox Code Playgroud)

然后继续 T1 和 T2:

insert into u (uid, name) values (1, 'A');
Run Code Online (Sandbox Code Playgroud)

commit;只有第一个成功,而另一个抛出序列化失败之后。

这是该模式的一个非常巧妙的功能,可以处理复杂交易中的独特密钥违规,而不是诉诸特定的“黑客” insert ... on conflict然而,即使 uid 不同,例如uid = 2uid = 3,事务 T1 和 T2仍然无法提交。

怎么可能?据说他们创建了不同的谓词 SIReadlocks 并select使用索引扫描。窍门在哪里?

postgresql isolation-level serialization upsert

5
推荐指数
1
解决办法
970
查看次数

关键与差距的挑战?

我有一个触发器错误,导致在 x86_64-unknown-linux-gnu 上的 PostgreSQL 9.4.3 中出现错误,由 gcc (Debian 4.9.2-10) 4.9.2, 64 位编译。每次出错期间,SERIAL 的主键都会增加。修复错误后,表格测量结果

 measurement_id | measurement_size_in_bytes |             time              
----------------+---------------------------+-------------------------------
              1 |                     77777 | 2015-07-14 18:29:56.858703+03
              2 |                       888 | 2015-07-14 18:29:56.882552+03
              3 |                       888 | 2015-07-14 18:30:15.505957+03
              4 |                       888 | 2015-07-14 18:41:01.878106+03
             39 |                     77777 | 2015-07-15 12:11:21.21391+03
             40 |                     77777 | 2015-07-15 12:11:59.551973+03
             41 |                     77777 | 2015-07-15 12:12:05.48982+03
             42 |                     77777 | 2015-07-15 12:13:02.402053+03
             43 |                     77777 | 2015-07-15 12:13:02.419412+03
             44 |                       888 | 2015-07-15 …
Run Code Online (Sandbox Code Playgroud)

postgresql serialization errors

4
推荐指数
1
解决办法
761
查看次数

内联表值函数的强制序列化

如果这是一个愚蠢的问题,请道歉。我们正在尝试将我们的多语句表值函数 (MSTVF) 转换为内联表值函数 (ITVF),以避免强制序列化查询。

我有以下 ITVF 函数(淡化了),但执行计划仍然说它的并行度为 1。所讨论的实际函数具有三个由 UNION ALL 分隔的基本 SELECT 语句。

我错过了什么吗?我怎样才能避免在这里强制序列化?

CREATE FUNCTION dbo.Test (@i int)
RETURNS TABLE
AS
RETURN
SELECT @i as [i];
GO

SELECT * FROM dbo.Test (2);
GO
Run Code Online (Sandbox Code Playgroud)

https://www.brentozar.com/pastetheplan/?id=Hyn8o50D7

该实例具有以下设置:

  • 并行的成本阈值 = 5
  • 最大并行度 = 0

sql-server parallelism t-sql serialization

4
推荐指数
1
解决办法
715
查看次数