【测试类型:统计函数】【测试版本:2.0.0】
【操作系统和硬件信息】(查询命令: cat /etc/system-release, uname -a):
openGauss:x86+centos
【测试环境】(单机/1主x备x级联备): 1主1备
【被测功能】: 统计信息函数,统计执行结果
【测试类型】: 功能测试
【数据库版本】(查询命令: gaussdb –V):
gaussdb (openGauss 2.1.0 build da72ef3c) compiled at 2021-09-27 20:24:34 commit 0 last mr
【预置条件】:数据正常
【操作步骤】(请填写详细的操作步骤):
2.1.0版本以下统计函数与2.0.0版本统计结果均不一致:
pg_stat_get_db_blocks_hit
pg_stat_get_dead_tuples
pg_stat_get_function_calls
pg_stat_get_function_total_time
pg_stat_get_tuples_changed
pg_stat_get_tuples_inserted
pg_stat_get_tuples_updated
pg_stat_get_db_xact_commit
pg_indexes_size
已 pg_stat_get_dead_tuples 为例
1.测试用例
--记录的是更新和删除的行数
alter system set autovacuum to off;
SELECT pg_sleep(10);
drop table if exists sales;
select pg_stat_reset();
SELECT pg_sleep(10);
--创建表sales
CREATE TABLE sales
(prod_id NUMBER(6),
cust_id NUMBER,
time_id DATE,
channel_id CHAR(1),
promo_id NUMBER(6),
quantity_sold NUMBER(3),
amount_sold NUMBER(10,2)
);
-- 无数据查询
select pg_stat_get_dead_tuples(a.oid) from PG_CLASS a where a.relname = 'sales';
-- 数据插入sales
INSERT INTO sales VALUES(1, 12, '2019-01-10 00:00:00', 'a', 1, 1, 1);
INSERT INTO sales VALUES(1, 12, '2019-02-01 00:00:00', 'b', 1, 1, 1);
select pg_stat_get_dead_tuples(a.oid) from PG_CLASS a where a.relname = 'sales';
-- 更新一行数据,旧的其实还在,只是指针指向了新数据,因此dead记录1
update sales set time_id = '2019-06-02 10:00:00' where channel_id = 'b';
SELECT pg_sleep(10);
select pg_stat_get_dead_tuples(a.oid) from PG_CLASS a where a.relname = 'sales';
-- 再添加数据 1
INSERT INTO sales VALUES(1, 12, '2019-02-05 00:00:00', 'c', 1, 1, 1);
INSERT INTO sales VALUES(1, 12, '2019-02-03 00:00:00', 'd', 1, 1, 1);
INSERT INTO sales VALUES(1, 12, '2019-02-05 00:00:00', 'e', 1, 1, 1);
SELECT pg_sleep(10);
select pg_stat_get_dead_tuples(a.oid) from PG_CLASS a where a.relname = 'sales';
-- 更新多行 4
update sales set time_id = '2015-06-02 10:00:00' where channel_id = 'c';
update sales set time_id = '2013-06-02 10:00:00' where channel_id = 'd';
update sales set time_id = '2012-06-02 10:00:00' where channel_id = 'e';
SELECT pg_sleep(10);
select pg_stat_get_dead_tuples(a.oid) from PG_CLASS a where a.relname = 'sales';
-- 删除一行 5
delete from sales where channel_id = 'b';
SELECT pg_sleep(10);
select pg_stat_get_dead_tuples(a.oid) from PG_CLASS a where a.relname = 'sales';
-- 删除多行 8
delete from sales where channel_id = 'c';
delete from sales where channel_id = 'd';
delete from sales where channel_id = 'e';
SELECT pg_sleep(10);
select pg_stat_get_dead_tuples(a.oid) from PG_CLASS a where a.relname = 'sales';
drop table sales cascade;
alter system set autovacuum to on;
【实际输出】
--记录的是更新和删除的行数
alter system set autovacuum to off;
SQL SUCCESS
SELECT pg_sleep(10);
+----------+
| pg_sleep |
+----------+
| |
+----------+
drop table if exists sales;
SQL SUCCESS
select pg_stat_reset();
+---------------+
| pg_stat_reset |
+---------------+
| |
+---------------+
SELECT pg_sleep(10);
+----------+
| pg_sleep |
+----------+
| |
+----------+
--创建表sales
CREATE TABLE sales
(prod_id NUMBER(6),
cust_id NUMBER,
time_id DATE,
channel_id CHAR(1),
promo_id NUMBER(6),
quantity_sold NUMBER(3),
amount_sold NUMBER(10,2)
);
SQL SUCCESS
-- 无数据查询
select pg_stat_get_dead_tuples(a.oid) from PG_CLASS a where a.relname = 'sales';
+-------------------------+
| pg_stat_get_dead_tuples |
+-------------------------+
| 0 |
+-------------------------+
-- 数据插入sales
INSERT INTO sales VALUES(1, 12, '2019-01-10 00:00:00', 'a', 1, 1, 1);
SQL SUCCESS
INSERT INTO sales VALUES(1, 12, '2019-02-01 00:00:00', 'b', 1, 1, 1);
SQL SUCCESS
select pg_stat_get_dead_tuples(a.oid) from PG_CLASS a where a.relname = 'sales';
+-------------------------+
| pg_stat_get_dead_tuples |
+-------------------------+
| 0 |
+-------------------------+
-- 更新一行数据,旧的其实还在,只是指针指向了新数据,因此dead记录1
update sales set time_id = '2019-06-02 10:00:00' where channel_id = 'b';
SQL SUCCESS
SELECT pg_sleep(10);
+----------+
| pg_sleep |
+----------+
| |
+----------+
select pg_stat_get_dead_tuples(a.oid) from PG_CLASS a where a.relname = 'sales';
+-------------------------+
| pg_stat_get_dead_tuples |
+-------------------------+
| 1 |
+-------------------------+
-- 再添加数据 1
INSERT INTO sales VALUES(1, 12, '2019-02-05 00:00:00', 'c', 1, 1, 1);
SQL SUCCESS
INSERT INTO sales VALUES(1, 12, '2019-02-03 00:00:00', 'd', 1, 1, 1);
SQL SUCCESS
INSERT INTO sales VALUES(1, 12, '2019-02-05 00:00:00', 'e', 1, 1, 1);
SQL SUCCESS
SELECT pg_sleep(10);
+----------+
| pg_sleep |
+----------+
| |
+----------+
select pg_stat_get_dead_tuples(a.oid) from PG_CLASS a where a.relname = 'sales';
+-------------------------+
| pg_stat_get_dead_tuples |
+-------------------------+
| 1 |
+-------------------------+
-- 更新多行 4
update sales set time_id = '2015-06-02 10:00:00' where channel_id = 'c';
SQL SUCCESS
update sales set time_id = '2013-06-02 10:00:00' where channel_id = 'd';
SQL SUCCESS
update sales set time_id = '2012-06-02 10:00:00' where channel_id = 'e';
SQL SUCCESS
SELECT pg_sleep(10);
+----------+
| pg_sleep |
+----------+
| |
+----------+
select pg_stat_get_dead_tuples(a.oid) from PG_CLASS a where a.relname = 'sales';
+-------------------------+
| pg_stat_get_dead_tuples |
+-------------------------+
| 4 |
+-------------------------+
-- 删除一行 5
delete from sales where channel_id = 'b';
SQL SUCCESS
SELECT pg_sleep(10);
+----------+
| pg_sleep |
+----------+
| |
+----------+
select pg_stat_get_dead_tuples(a.oid) from PG_CLASS a where a.relname = 'sales';
+-------------------------+
| pg_stat_get_dead_tuples |
+-------------------------+
| 4 | -------此处统计结果有误
+-------------------------+
-- 删除多行 8
delete from sales where channel_id = 'c';
SQL SUCCESS
delete from sales where channel_id = 'd';
SQL SUCCESS
delete from sales where channel_id = 'e';
SQL SUCCESS
SELECT pg_sleep(10);
+----------+
| pg_sleep |
+----------+
| |
+----------+
select pg_stat_get_dead_tuples(a.oid) from PG_CLASS a where a.relname = 'sales';
+-------------------------+
| pg_stat_get_dead_tuples |
+-------------------------+
| 8 |
+-------------------------+
drop table sales cascade;
SQL SUCCESS
alter system set autovacuum to on;
SQL SUCCESS
【原因分析】: 暂无
【日志信息】(请附上日志文件、截图、coredump信息):
Hey @zhanghuan96, Welcome to openGauss Community.
All of the projects in openGauss Community are maintained by @opengauss-bot.
That means the developers can comment below every pull request or issue to trigger Bot Commands.
Please follow instructions at https://gitee.com/opengauss/community/blob/master/contributors/command.en.md to find the details.
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。
数据库版本:
openGauss=# select version();
version | (openGauss 2.1.0 build 590b0f8e) compiled at 2021-10-16 01:38:18 commit 0 last mr debug on x86_64-unknown-linux-gnu, compiled by g++ (GCC) 7.3.0, 64-bit
集群信息:
dusx 21085 85.1 9.8 3138720 785484 pts/1 Sl 07:49 17:10 /home/dusx/openGauss-server/dest/bin/gaussdb -D /home/dusx/openGauss-server/data/master -M primary dusx 21162 4.1 8.2 2675784 662160 pts/1 Sl 07:50 0:48 /home/dusx/openGauss-server/dest/bin/gaussdb -D /home/dusx/openGauss-server/data/slave -M standby
统计语句:
select pg_stat_get_dead_tuples(a.oid) from PG_CLASS a where a.relname = 'sales';
未复现此问题
非问题,建议修改用例中的sleep(10)为sleep(6);sleep(6);
pgstat系列的统计原理为backend线程将自身业务产生的数据发送给collect线程,collect线程异步进行整理归档,而backend线程发送时机为执行sql前,将前一条sql的数据发送,但是如果距离上一次发送时间间隔太短的话不会发送。
因此以update为例,用例中update、sleep、select、update、sleep、select的顺序。对应的数据生产和发送时机也分别是 update(data1)、sleep、(send1) select、(时间不够不发) update(data2)、(时间不够不发) sleep、(send2)select
可以看到对于data2的发送一定是在select执行前。在这之后,一边collect线程收到data2并整理归档,另一边backend线程开始执行select进行查询,两者同时进行,能不能查到就看谁比较快了。之前用例可以过是因为以前collect业务比较轻,速度明显大于select。
改成连续两个sleep,第一个sleep满足发送间隔,第二个sleep发送且正好可以等待collect线程归档完成,之后select可保证会是最新的。
pg_indexes_size是代码逻辑变动,对于unusable的索引,不再统计其大小。另外这个用例里不用sleep。
修改用例,连跑无误
登录 后才可以发表评论