iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >PostgreSQL中APP在涉及locks时需要注意的地方有哪些
  • 254
分享到

PostgreSQL中APP在涉及locks时需要注意的地方有哪些

2024-04-02 19:04:59 254人浏览 独家记忆
摘要

这篇文章主要讲解了“postgresql中APP在涉及locks时需要注意的地方有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Postgresql中A

这篇文章主要讲解了“postgresql中APP在涉及locks时需要注意的地方有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Postgresql中APP在涉及locks时需要注意的地方有哪些”吧!

测试数据:

[local]:5432 pg12@testdb=# drop table if exists tbl;
DROP TABLE
Time: 36.136 ms
[local]:5432 pg12@testdb=# create table tbl(id int,c1 varchar(20),c2 varchar(20));
CREATE TABLE
Time: 4.903 ms
[local]:5432 pg12@testdb=# 
[local]:5432 pg12@testdb=# insert into tbl select x,'c1'||x,'c2'||x from generate_series(1,1000000) as x;
INSERT 0 1000000
Time: 3677.812 ms (00:03.678)
[local]:5432 pg12@testdb=#

— session 1

[local]:5432 pg12@testdb=# select pg_backend_pid();
 pg_backend_pid 
----------------
           1541
(1 row)

— session 2

[local]:5432 pg12@testdb=# select pg_backend_pid();
 pg_backend_pid 
----------------
           1628
(1 row)
Time: 4.446 ms

1: Never add a column with a default value
表上新增列时获取的是AccessExclusiveLock,会阻塞RW(包括SELECT),为了尽快完成列的添加,新增有默认值的列,可拆分为新增列,然后执行UPDATE语句以免出现R阻塞.

-- session 1
[local]:5432 pg12@testdb=# begin;
BEGIN
Time: 0.929 ms
[local]:5432 pg12@testdb=#* alter table tbl add column c3 varchar(20) default 'c3';
ALTER TABLE
Time: 32.881 ms
[local]:5432 pg12@testdb=# 
-- session 2
[local]:5432 pg12@testdb=# select * from tbl;
-- 阻塞
-- session 3
[local]:5432 pg12@testdb=# select pid,locktype,relation::reGClass,mode,page,tuple,virtualxid,transactionid,virtualtransaction,granted,fastpath from pg_locks where relation='tbl'::regclass;
-[ RECORD 1 ]------+--------------------
pid                | 1541
locktype           | relation
relation           | tbl
mode               | AccessExclusiveLock
page               | 
tuple              | 
virtualxid         | 
transactionid      | 
virtualtransaction | 3/8
granted            | t
fastpath           | f
Time: 29.088 ms

使用先添加列,后更新默认值的方法

------ session 1
[local]:5432 pg12@testdb=# begin;
BEGIN
Time: 0.330 ms
[local]:5432 pg12@testdb=#* alter table tbl add column c4 varchar(20);
ALTER TABLE
Time: 0.460 ms
[local]:5432 pg12@testdb=#* end;
COMMIT
Time: 0.530 ms
[local]:5432 pg12@testdb=# begin;
BEGIN
Time: 0.199 ms
[local]:5432 pg12@testdb=#* update tbl set c4 = 'c4';
UPDATE 1000000
Time: 5286.769 ms (00:05.287)
[local]:5432 pg12@testdb=#* 
------ session 2
[local]:5432 pg12@testdb=# select * from tbl limit 1; 
 id | c1  | c2  | c3 | c4 
----+-----+-----+----+----
  1 | c11 | c21 | c3 | 
(1 row)
Time: 2.793 ms
------ session 3
[local]:5432 pg12@testdb=# select pid,locktype,relation::regclass,mode,page,tuple,virtualxid,transactionid,virtualtransaction,granted,fastpath from pg_locks where relation='tbl'::regclass;
-[ RECORD 1 ]------+-----------------
pid                | 1541
locktype           | relation
relation           | tbl
mode               | RowExclusiveLock
page               | 
tuple              | 
virtualxid         | 
transactionid      | 
virtualtransaction | 3/10
granted            | t
fastpath           | t
Time: 1.062 ms

虽然更新耗费的时间远比直接add column设置默认值要大,但锁等级是RowExclusiveLock,并不会阻塞读

2: Beware of lock queues, use lock timeouts
PG中每一个锁都有一个队列,在获取锁时如需等待存在冲突的其他锁,则会阻塞.可通过设置超时时间避免长时间的等待.这样虽然会失败,但可通过后台查询等方法获取数据库活动,保持数据库可控.

------ session 1
[local]:5432 pg12@testdb=# begin;
BEGIN
Time: 1.148 ms
[local]:5432 pg12@testdb=#* alter table tbl add column c5 varchar(20) default 'c3';
ALTER TABLE
Time: 2.726 ms
[local]:5432 pg12@testdb=#* 
------ session 3
[local]:5432 pg12@testdb=# select pid,locktype,relation::regclass,mode,page,tuple,virtualxid,transactionid,virtualtransaction,granted,fastpath from pg_locks where relation='tbl'::regclass;
-[ RECORD 1 ]------+--------------------
pid                | 1541
locktype           | relation
relation           | tbl
mode               | AccessExclusiveLock
page               | 
tuple              | 
virtualxid         | 
transactionid      | 
virtualtransaction | 3/11
granted            | t
fastpath           | f
Time: 2.751 ms
------ session 2
[local]:5432 pg12@testdb=# begin;
BEGIN
Time: 0.861 ms
[local]:5432 pg12@testdb=#* SET lock_timeout TO '1s';
SET
Time: 0.689 ms
[local]:5432 pg12@testdb=#* select * from tbl limit 1;
ERROR:  canceling statement due to lock timeout
LINE 1: select * from tbl limit 1;
                      ^
Time: 1001.031 ms (00:01.001)
[local]:5432 pg12@testdb=#! end;
ROLLBACK
Time: 0.984 ms
[local]:5432 pg12@testdb=#!

3: Create indexes CONCURRENTLY
使用CONCURRENTLY模式创建Index.
新插入1000w数据

[local]:5432 pg12@testdb=# insert into tbl select x,'c1'||x,'c2'||x,'c3'||x from generate_series(1,10000000) as x;
INSERT 0 10000000
Time: 32784.183 ms (00:32.784)

普通模式创建索引

------ session 1
[local]:5432 pg12@testdb=# begin;
BEGIN
Time: 29.276 ms
[local]:5432 pg12@testdb=#* create index idx_tbl_id on tbl(id);
CREATE INDEX
Time: 7261.828 ms (00:07.262)
[local]:5432 pg12@testdb=#* 
------ session 2
[local]:5432 pg12@testdb=# begin;
BEGIN
Time: 0.358 ms
[local]:5432 pg12@testdb=#* insert into tbl(id) values(0);
-- 阻塞
------ session 3
[local]:5432 pg12@testdb=# select pid,locktype,relation::regclass,mode,page,tuple,virtualxid,transactionid,virtualtransaction,granted,fastpath from pg_locks where relation='tbl'::regclass;
-[ RECORD 1 ]------+-----------------
pid                | 1628
locktype           | relation
relation           | tbl
mode               | RowExclusiveLock
page               | 
tuple              | 
virtualxid         | 
transactionid      | 
virtualtransaction | 5/13
granted            | f
fastpath           | f
-[ RECORD 2 ]------+-----------------
pid                | 1541
locktype           | relation
relation           | tbl
mode               | ShareLock
page               | 
tuple              | 
virtualxid         | 
transactionid      | 
virtualtransaction | 3/13
granted            | t
fastpath           | f
Time: 0.795 ms

回滚事务后,使用CONCURRENTLY模式创建索引,要注意的是CONCURRENTLY模式不能用在事务中

[local]:5432 pg12@testdb=#* -- only blocks other DDL
[local]:5432 pg12@testdb=#* create index CONCURRENTLY idx_tbl_id on tbl(id);
ERROR:  CREATE INDEX CONCURRENTLY cannot run inside a transaction block
Time: 0.491 ms
[local]:5432 pg12@testdb=#!

不启动事务,直接执行

------ session 1
[local]:5432 pg12@testdb=# -- only blocks other DDL
create index CONCURRENTLY idx_tbl_id on tbl(id);
CREATE INDEX
Time: 9718.400 ms (00:09.718)
------ session 2
[local]:5432 pg12@testdb=# begin;
BEGIN
Time: 0.373 ms
[local]:5432 pg12@testdb=#* insert into tbl(id) values(0);
INSERT 0 1
Time: 0.686 ms
[local]:5432 pg12@testdb=#* 
------ session 3
[local]:5432 pg12@testdb=# select pid,locktype,relation::regclass,mode,page,tuple,virtualxid,transactionid,virtualtransaction,granted,fastpath from pg_locks where relation='tbl'::regclass;
-[ RECORD 1 ]------+-------------------------
pid                | 1541
locktype           | relation
relation           | tbl
mode               | ShareUpdateExclusiveLock
page               | 
tuple              | 
virtualxid         | 
transactionid      | 
virtualtransaction | 3/21
granted            | t
fastpath           | f
-[ RECORD 2 ]------+-------------------------
pid                | 1701
locktype           | relation
relation           | tbl
mode               | ShareUpdateExclusiveLock
page               | 
tuple              | 
virtualxid         | 
transactionid      | 
virtualtransaction | 6/71
granted            | t
fastpath           | f
Time: 0.754 ms

使用CONCURRENTLY模式创建索引,获取的lock是ShareUpdateExclusiveLock,不会阻塞INSERT/UPDATE/DELETE操作(请求的锁是RowExclusiveLock)

4: Take aggressive locks as late as possible
这个跟编程中定义变量类似 : 离需要用到的地方越近的地方才定义.文中的例子见仁见智,选择使用.

5: Adding a primary key with minimal locking
重新构建测试数据

[local]:5432 pg12@testdb=# truncate table tbl;
TRUNCATE TABLE
Time: 91.815 ms
[local]:5432 pg12@testdb=# insert into tbl select x,'c1'||x,'c2'||x,'c3'||x from generate_series(1,12000000) as x;
INSERT 0 12000000
Time: 59285.694 ms (00:59.286)

把add primary key这一个动作拆解为先添加唯一索引,再添加primary key constraint这两个动作.

------ session 1
[local]:5432 pg12@testdb=# begin;
BEGIN
Time: 1.155 ms
[local]:5432 pg12@testdb=#* alter table tbl add primary key(id);
ALTER TABLE
Time: 10572.201 ms (00:10.572)
[local]:5432 pg12@testdb=#* 
------ session 2
[local]:5432 pg12@testdb=# begin;
BEGIN
Time: 0.703 ms
[local]:5432 pg12@testdb=#* insert into tbl(id) values(0);
-- 阻塞
------ session 3
[local]:5432 pg12@testdb=# select pid,locktype,relation::regclass,mode,page,tuple,virtualxid,transactionid,virtualtransaction,granted,fastpath from pg_locks where relation='tbl'::regclass;
-[ RECORD 1 ]------+--------------------
pid                | 1628
locktype           | relation
relation           | tbl
mode               | RowExclusiveLock
page               | 
tuple              | 
virtualxid         | 
transactionid      | 
virtualtransaction | 5/18
granted            | f
fastpath           | f
-[ RECORD 2 ]------+--------------------
pid                | 1541
locktype           | relation
relation           | tbl
mode               | ShareLock
page               | 
tuple              | 
virtualxid         | 
transactionid      | 
virtualtransaction | 3/28
granted            | t
fastpath           | f
-[ RECORD 3 ]------+--------------------
pid                | 1541
locktype           | relation
relation           | tbl
mode               | AccessExclusiveLock
page               | 
tuple              | 
virtualxid         | 
transactionid      | 
virtualtransaction | 3/28
granted            | t
fastpath           | f
-[ RECORD 4 ]------+--------------------
pid                | 1907
locktype           | relation
relation           | tbl
mode               | ShareLock
page               | 
tuple              | 
virtualxid         | 
transactionid      | 
virtualtransaction | 6/127
granted            | t
fastpath           | f
Time: 1.397 ms

拆解后,使用CONCURRENTLY模式创建索引,与第3点类似

------ session 1
[local]:5432 pg12@testdb=# -- takes a long time, but doesn’t block queries
[local]:5432 pg12@testdb=# CREATE UNIQUE INDEX CONCURRENTLY idx_tbl_id ON tbl (id); 
CREATE INDEX
Time: 9908.405 ms (00:09.908)
[local]:5432 pg12@testdb=# -- blocks queries, but only very briefly
[local]:5432 pg12@testdb=# ALTER TABLE tbl ADD CONSTRAINT pk_tbl PRIMARY KEY USING INDEX idx_tbl_id;  
NOTICE:  ALTER TABLE / ADD CONSTRAINT USING INDEX will rename index "idx_tbl_id" to "pk_tbl"
ALTER TABLE
Time: 4582.013 ms (00:04.582)

6: Never VACUUM FULL

------ session 1
[local]:5432 pg12@testdb=# vacuum full;
------ session 2
------ session 3
[local]:5432 pg12@testdb=# select pid,locktype,relation::regclass,mode,page,tuple,virtualxid,transactionid,virtualtransaction,granted,fastpath from pg_locks where relation='tbl'::regclass;
-[ RECORD 1 ]------+--------------------
pid                | 1541
locktype           | relation
relation           | tbl
mode               | AccessExclusiveLock
page               | 
tuple              | 
virtualxid         | 
transactionid      | 
virtualtransaction | 3/49
granted            | t
fastpath           | f
Time: 0.803 ms

vacuum full请求的锁是AccessExclusiveLock,会阻塞读写,在目前vacuum full并不智能的情况下,手工发起对单个表的vacuum full会保险许多.

7: Avoid deadlocks by ordering commands
注意命令的顺序,避免死锁

------ session 1
[local]:5432 pg12@testdb=# begin;
BEGIN
Time: 0.440 ms
[local]:5432 pg12@testdb=#* delete from tbl where id = 1;
DELETE 1
Time: 0.567 ms
[local]:5432 pg12@testdb=#* 
------ session 2
[local]:5432 pg12@testdb=# begin;
BEGIN
Time: 0.960 ms
[local]:5432 pg12@testdb=#* delete from tbl where id = 2;
DELETE 1
Time: 1.783 ms
[local]:5432 pg12@testdb=#* 
------ session 3

产生死锁

------ session 1
[local]:5432 pg12@testdb=#* delete from tbl where id = 2;
------ session 2
[local]:5432 pg12@testdb=#* delete from tbl where id = 1;
ERROR:  deadlock detected
DETAIL:  Process 1628 waits for ShareLock on transaction 623; blocked by process 1541.
Process 1541 waits for ShareLock on transaction 624; blocked by process 1628.
HINT:  See server log for query details.
CONTEXT:  while deleting tuple (0,1) in relation "tbl"
Time: 1004.485 ms (00:01.004)
[local]:5432 pg12@testdb=#! 
------ session 3

感谢各位的阅读,以上就是“PostgreSQL中APP在涉及locks时需要注意的地方有哪些”的内容了,经过本文的学习后,相信大家对PostgreSQL中APP在涉及locks时需要注意的地方有哪些这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

您可能感兴趣的文档:

--结束END--

本文标题: PostgreSQL中APP在涉及locks时需要注意的地方有哪些

本文链接: https://www.lsjlt.com/news/63668.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • PostgreSQL中APP在涉及locks时需要注意的地方有哪些
    这篇文章主要讲解了“PostgreSQL中APP在涉及locks时需要注意的地方有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“PostgreSQL中A...
    99+
    2024-04-02
  • PostgreSQL有哪些需要注意的问题
    这篇文章主要讲解了“PostgreSQL有哪些需要注意的问题”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“PostgreSQL有哪些需要注意的问题”吧!1:...
    99+
    2024-04-02
  • java继承中需要注意的地方有哪些
    这篇文章给大家分享的是有关java继承中需要注意的地方有哪些的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1、注意点(1)Java之中只允许多层继承,不允许多重继承,Java存在单继承局限。(2)在Java中,所...
    99+
    2023-06-15
  • 在 Go 中使用 NumPy 索引:有哪些需要注意的地方?
    NumPy 是一个广泛使用的 Python 科学计算库,它提供了高效的数组操作和数学函数。然而,由于 Python 的解释执行特性,NumPy 在处理大型数据集时可能会变得缓慢。为了解决这个问题,一些开发者开始使用 Go 语言来实现高性能...
    99+
    2023-06-27
    文件 numpy 索引
  • Java关键字在开发中有哪些需要注意的地方?
    Java作为一种面向对象的编程语言,其关键字(keywords)在开发过程中扮演着非常重要的角色。这些关键字有时候会对程序的性能、可读性、可维护性等产生影响。在本篇文章中,我们将探讨Java关键字在开发中需要注意的地方,并附带演示代码。 一...
    99+
    2023-09-12
    关键字 开发技术 文件
  • Redis中redis-cluster需要注意哪些地方
    本篇内容主要讲解“Redis中redis-cluster需要注意哪些地方”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Redis中redis-cluster需要...
    99+
    2024-04-02
  • Vue2.0路由开启keep-alive时需要注意的地方有哪些
    这篇文章主要为大家展示了“Vue2.0路由开启keep-alive时需要注意的地方有哪些”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Vue2.0路由开启kee...
    99+
    2024-04-02
  • 使用redis集群需要注意的地方有哪些
    小编给大家分享一下使用redis集群需要注意的地方有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Redis集群相对单机在功...
    99+
    2024-04-02
  • Bash 脚本编写有哪些需要注意的地方?
    Bash 脚本是一种非常方便的编程语言,可以用于自动化任务、管理系统、实现批处理等多种应用场景。但是,由于 Bash 脚本的语法比较灵活,很容易出现错误,因此编写 Bash 脚本需要注意一些细节,以确保脚本的正确性和可靠性。本文将介绍 B...
    99+
    2023-07-23
    bash leetcode 并发
  • oracle首次安装需要注意的地方有哪些
    这篇文章给大家分享的是有关oracle首次安装需要注意的地方有哪些的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。 首次安装时,需要确认的以下列表: 1、创建控制文件时,需要确...
    99+
    2024-04-02
  • 在css中有哪些规则需要注意的
    小编给大家分享一下在css中有哪些规则需要注意的,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!在css中,属性与其属性之间需要使用英文的":"...
    99+
    2023-06-14
  • Git在Unix系统下的使用:有哪些需要注意的地方?
    Git是一款非常流行的版本控制工具,可以帮助开发人员轻松地管理代码的版本,同时也可以协助团队协作开发。在Unix系统下使用Git也非常方便,但是仍然有一些需要注意的地方。本文将详细介绍使用Git时需要注意的事项,并提供一些演示代码。 安...
    99+
    2023-08-09
    leetcode git unix
  • Java中的HTTP二维码API:有哪些需要注意的地方?
    在当今数字化时代,二维码已经成为了人们常用的信息传递方式之一。二维码可以在不同的场景中使用,比如商业活动、广告宣传、门票验证等等。Java作为一门广泛使用的编程语言,也提供了HTTP二维码API来支持二维码的生成和解码。在使用Java中的...
    99+
    2023-08-23
    http 二维码 api
  • 基于Java8并行流有哪些需要注意的地方
    这篇文章主要介绍了基于Java8并行流有哪些需要注意的地方,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。Java8并行流(parallelStream)注意点在最初使用并行流...
    99+
    2023-06-20
  • 数组同步在Python编程中的应用有哪些需要注意的地方?
    在Python编程中,数组同步是一个非常重要的概念。它指的是将多个数组中的元素进行同步操作,以保证它们的值始终保持一致。在实际编程中,我们经常会遇到需要对多个数组进行同步操作的情况,这时就需要注意一些细节问题,以确保程序能够正确运行。本文...
    99+
    2023-10-11
    编程算法 数组 同步
  • 在高防服务器租用时需要注意的方面有哪些
    高防服务器租用时需要注意的方面:1.服务提供商的资质情况。2.高防服务器的机房保护能力。3.防火墙系统是否符合防御标准。4.是否符合足够的带宽。5.选择正确高防服务器线,最好选择电信线。具体内容如下:一、看IDC服务商的运营时间和规模,是否...
    99+
    2024-04-02
  • IDE 文件中的 ASP 重定向:有哪些需要注意的地方?
    在 ASP 的开发中,我们经常需要使用重定向功能来实现页面的跳转。ASP 重定向是一种非常常见的页面跳转方式,它可以帮助用户快速地跳转到目标页面,同时也能够帮助开发人员更好地管理页面之间的关系。在本文中,我们将介绍 ASP 重定向的相关知...
    99+
    2023-10-29
    重定向 ide 文件
  • 日本服务器租用需要注意的地方有哪些
    日本服务器租用需要注意的有:1、确认日本服务器质量,如类型和品牌、稳定性、安全性等;2、确认日本服务器机房带宽情况,可用ping命令测试IDC服务商客户的网站;3、看日本服务器机房是否有好的数据中心冗余。具体内容如下:确认服务器质量日本服务...
    99+
    2024-04-02
  • js中使用原型对象prototype需要注意的地方有哪些
    这篇文章主要为大家展示了“js中使用原型对象prototype需要注意的地方有哪些”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“js中使用原型对象prototy...
    99+
    2024-04-02
  • 租用美国服务器有哪些地方需要注意的
    租用美国服务器需要注意的地方有:1、美国服务器配置,根据业务需求进行合理选择;2、服务器售后服务质量是否可靠;3、选择合适的服务器带宽资源;4、对美国服务器的稳定性进行测试考察。具体内容如下:选择合适的配置,要根据自己业务的需求情况选择合适...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作