游标长时间open导致表无法vacuum问题
一、问题描述
用户在实际中可能会碰到类似以下 dead rows 无法 vacuum的问题,一个可能的原因是由于游标未结束的原因。
test=# vacuum(verbose) t1;
INFO: vacuuming "public.t1"
INFO: "t1": found 0 removable, 985 nonremovable row versions in 66 out of 67 pages
DETAIL: 788 dead row versions cannot be removed yet, oldest xmin: 4996
There were 0 unused item identifiers.
Skipped 1 page due to buffer pins, 0 frozen pages.
0 pages are entirely empty.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
INFO: vacuuming "pg_toast.pg_toast_29558"
INFO: index "pg_toast_29558_index" now contains 0 row versions in 1 pages
DETAIL: 0 index row versions were removed.
0 index pages have been deleted, 0 are currently reusable.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
INFO: "pg_toast_29558": found 0 removable, 0 nonremovable row versions in 0 out of 0 pages
DETAIL: 0 dead row versions cannot be removed yet, oldest xmin: 4996
There were 0 unused item identifiers.
Skipped 0 pages due to buffer pins, 0 frozen pages.
0 pages are entirely empty.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
二、举例说明
1、事务不提交的情况
创建测试数据:
create table t1(id integer,name text);
create table t2(id integer);
insert insert t1 select generate_series(1,1000),repeat('a',500);
创建测试过程:
create or replace procedure proc01_nocommit as
cursor c01 is select id from t1;
v_id integer;
begin
open c01;
fetch c01 into v_id;
while (c01%FOUND) loop
insert into t2 values(v_id);
perform pg_sleep(1);
fetch c01 into v_id;
end loop;
end;
/
session 1:
call proc01_nocommit();
session 2:
test=# select * from pg_locks where relation='t1'::regclass;
locktype | database | relation | page | tuple | virtualxid | transactionid | classid | objid | objsubid | virtualtransaction | pid | mode | granted | fastpath
----------+----------+----------+------+-------+------------+---------------+---------+-------+----------+--------------------+--------+-----------------+---------+----------
relation | 29504 | 29558 | | | | | | | | 4/2737 | 360612 | AccessShareLock | t | t
(1 row) test=# delete from t1 where mod(id,5)<>1;
DELETE 200
无法 vacuum
test=# vacuum(verbose) t1;
INFO: vacuuming "public.t1"
INFO: "t1": found 0 removable, 985 nonremovable row versions in 66 out of 67 pages
DETAIL: 788 dead row versions cannot be removed yet, oldest xmin: 4996
There were 0 unused item identifiers.
Skipped 1 page due to buffer pins, 0 frozen pages.
0 pages are entirely empty.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
INFO: vacuuming "pg_toast.pg_toast_29558"
INFO: index "pg_toast_29558_index" now contains 0 row versions in 1 pages
DETAIL: 0 index row versions were removed.
0 index pages have been deleted, 0 are currently reusable.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
INFO: "pg_toast_29558": found 0 removable, 0 nonremovable row versions in 0 out of 0 pages
DETAIL: 0 dead row versions cannot be removed yet, oldest xmin: 4996
There were 0 unused item identifiers.
Skipped 0 pages due to buffer pins, 0 frozen pages.
0 pages are entirely empty.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
VACUUM
结论:可以看到对象有 AccessShareLock 锁(实际验证,不管只要 cursor 定义了,不管是否open ,都会有 AccessShareLock 锁)。
2、事务提交的情景
修改过程块如下:
create or replace procedure proc01_commit as
cursor c01 is select id from t1;
v_id integer;
begin
open c01;
fetch c01 into v_id;
while (c01%FOUND) loop
insert into t2 values(v_id);
perform pg_sleep(1);
fetch c01 into v_id;
commit;
end loop;
end;
/
可以看到在游标内部加了commit;
PS:KingbaseES 支持游标跨事务的场景。在 commit时,会将剩余未完成游标的结果取回到临时文件,这样可以保证MVCC 机制。
Session 1:
call proc01_commit()
Session 2:
test=# select * from pg_locks where relation='t1'::regclass;
locktype | database | relation | page | tuple | virtualxid | transactionid | classid | objid | objsubid | virtualtransaction | pid | mode | granted | fastpath
----------+----------+----------+------+-------+------------+---------------+---------+-------+----------+--------------------+--------+-----------------+---------+----------
(0 row) test=# delete from t1 where mod(id,5)<>0;
DELETE 800
结论:没有锁,可以vacuum。
test=# vacuum (verbose) t1;
INFO: vacuuming "public.t1"
INFO: "t1": removed 800 row versions in 67 pages
INFO: "t1": found 800 removable, 200 nonremovable row versions in 67 out of 67 pages
DETAIL: 0 dead row versions cannot be removed yet, oldest xmin: 4857
There were 0 unused item identifiers.
Skipped 0 pages due to buffer pins, 0 frozen pages.
0 pages are entirely empty.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
INFO: vacuuming "pg_toast.pg_toast_29549"
INFO: index "pg_toast_29549_index" now contains 0 row versions in 1 pages
DETAIL: 0 index row versions were removed.
0 index pages have been deleted, 0 are currently reusable.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
INFO: "pg_toast_29549": found 0 removable, 0 nonremovable row versions in 0 out of 0 pages
DETAIL: 0 dead row versions cannot be removed yet, oldest xmin: 4857
There were 0 unused item identifiers.
Skipped 0 pages due to buffer pins, 0 frozen pages.
0 pages are entirely empty.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
VACUUM
游标长时间open导致表无法vacuum问题的更多相关文章
- 防止shell脚本长时间执行导致ssh超时
在一些对安全性要求较高的场景下.ssh的超时时间是管理员预先设置好的,在闲置一段时间后ssh连接会自己主动断开. 这样的情况下假设通过ssh运行脚本,而脚本运行时间又比較长的话.会导致sshclien ...
- JVM 调优 —— GC 长时间停顿问题及解决方法
零. 简介 垃圾收集器长时间停顿,表现在 Web 页面上可能是页面响应码 500 之类的服务器错误问题,如果是个支付过程可能会导致支付失败,将造成公司的直接经济损失,程序员要尽量避免或者说减少此类情况 ...
- SQL一次查出相关类容避免长时间占用表(下)
/* server: db: EDI */ -- 以下案例多次查询同一张表,仅有Name条件不同 --可以使用一次查出相关类容避免长时间占用表 USE EDI GO DECLARE @FileType ...
- SQL一次查出相关类容避免长时间占用表(上)
/* server: db: EDI */ -- 以下案例多次查询同一张表,仅有组合条件Name+Direction不同 --可以使用一次查出相关类容避免长时间占用表 USE EDI GO DECLA ...
- kali长时间未使用导致数字签名过期无法更新源解决办法
kali长时间未使用,数字签名会过期,从而导致无法更新源. apt-get update:从源(Source)服务器那里下载最新的软件包列: apt-get upgrade:对已经安装的软件包本身进行 ...
- 查看Oracle中存储过程长时间被卡住的原因
1:查V$DB_OBJECT_CACHE SELECT * FROM V$DB_OBJECT_CACHE WHERE name='CUX_OE_ORDER_RPT_PKG' AND LOCKS!='0 ...
- ASP.NET 工作流:支持长时间运行操作的 Web 应用程序
ASP.NET 工作流 支持长时间运行操作的 Web 应用程序 Michael Kennedy 代码下载位置:MSDN 代码库 在线浏览代码 本文将介绍以下内容: 独立于进程的工作流 同步和异步活 ...
- ios之申请后台延时执行和做一个假后台的方法(系统进入长时间后台后,再进入前台部分功能不能实现)
转自:http://sis hu ok.com/forum/blogCategory/showByCategory.html?categories_id=138&user_id=10385 ...
- 为什么drop table的时候要在checking permissions花很长时间?
昨天,我drop一个表的时候在checking permissions花了20s+,这个时间花在哪里了呢?经常查找发现我的配置文件innodb_file_per_table=1的,innodb需要遍历 ...
随机推荐
- 数字图像处理-基于matlab-直方图均匀化,傅立叶变换,图像平滑,图像锐化
直方图均匀化 任务:用MATLAB或VC或Delphi等实现图像直方图均匀化的算法. clc;clear;close all; % 清除工作台 % path(path,'..\pics'); % 设置 ...
- Vue.js与ElementUI搭建无限级联层级表格组件
前言 今天,回老家了.第一件事就是回家把大屏安排上,写作的感觉太爽了,终于可以专心地写文章了.我们今天要做的项目是怎么样搭建一个无限级联层级表格组件,好了,多了不多说,赶快行动起来吧!项目一览 到底是 ...
- 【python基础】第03回 软件安装
上节内容回顾 1.计算机五大组成部分详解 1.控制器 控制计算机各个硬件的工作 2.运算器 数学运算.逻辑运算(核心) """CPU = 控制器 + 运算器"& ...
- map集合中对应key的value为null处理办法
问题: Map集合中对应key的value为null,但是现在需要将这个value转为Integer类型,这个value如果不是null,那么get到的是long类型或者是Bigdecimal类型 处 ...
- 强化学习-学习笔记7 | Sarsa算法原理与推导
Sarsa算法 是 TD算法的一种,之前没有严谨推导过 TD 算法,这一篇就来从数学的角度推导一下 Sarsa 算法.注意,这部分属于 TD算法的延申. 7. Sarsa算法 7.1 推导 TD ta ...
- CSS进阶内容—盒子和阴影详解
CSS进阶内容 在学习了CSS基本知识之后,我们需要进一步了解CSS,因此写下了这篇文章 当然如果没有学习之前的知识,可以到我的主页中查看之前的文章:秋落雨微凉 - 博客园 CSS三大特性 首先我们先 ...
- 掌握CSS中的z-index
前言 z-index是一个用于控制文档中图层顺序的属性.具有较高z-index值的元素将会出现在具有较低值的元素之上.就像页面上的x轴和y轴决定一个元素在水平和垂直方向上的位置一样,z-index控制 ...
- 30行自己写并发工具类(Semaphore, CyclicBarrier, CountDownLatch)是什么体验?
30行自己写并发工具类(Semaphore, CyclicBarrier, CountDownLatch)是什么体验? 前言 在本篇文章当中首先给大家介绍三个工具Semaphore, CyclicBa ...
- selenium环境配置和八大元素定位
一.环境配置 1.selenium下载安装 安装一:pip install selenium(多数会超时安装失败) 安装二:pip install -i https://pypi.tuna.tsing ...
- JUC源码学习笔记3——AQS等待队列和CyclicBarrier,BlockingQueue
一丶Condition 1.概述 任何一个java对象都拥有一组定义在Object中的监视器方法--wait(),wait(long timeout),notify(),和notifyAll()方法, ...