PostgreSQL:系统表pg_attribute膨胀解决方案

本文涉及的产品
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 50GB
简介: vacuum full table;datafile

场景模拟

​ 执行一段脚本模拟数据库大量删除表创建表导致pg_attribute膨胀

  • 执行脚本
select pg_relation_size('pg_attribute');
create table test001(id int4,name text);
create table test002(id int4,name text);
create or replace function f_tmp() returns void as $$
declare
begin
create temp table temp_test001 as  select * from test001;
insert into test002 select * from temp_test001 limit 1;
end;
$$
language plpgsql;
 select pg_relation_size('pg_attribute');
  • 执行脚本效果
ysys=# select pg_relation_size('pg_attribute');
 pg_relation_size
------------------
           368640
(1 row)

ysys=# create table test001(id int4,name text);
CREATE TABLE
ysys=# create table test002(id int4,name text);
CREATE TABLE
ysys=# create or replace function f_tmp() returns void as $$
ysys$# declare
ysys$# begin
ysys$# create temp table temp_test001 as  select * from test001;
ysys$# insert into test002 select * from temp_test001 limit 1;
ysys$# end;
ysys$# $$
ysys-# language plpgsql;
CREATE FUNCTION
ysys=# select pg_relation_size('pg_attribute');
 pg_relation_size
------------------
           368640
(1 row)
  • 利用shell脚本完成1000次执行调度
$ cat /home/ysys/cde.sql
select f_tmp()
$ cat d1000.sh

#!/bin/bash

for i in {1..1000}
do
  psql -f /home/ysys/cde.sql -d ysys
done
$ chmod +x d1000.sh
$ ./d1000.sh
  • 脚本可能需要多执行几遍查看膨胀效果(vacuum)
ysys=# select pg_relation_size('pg_attribute');
 pg_relation_size
------------------
          1490944

方案一 推荐方案

vacuum full pg_attribute;

方案二(测试通过)

第一步要找到pg_attribute会有几个文件(表文件,索引文件)

ysys=# \d+ pg_attribute
                        Table "pg_catalog.pg_attribute"
    Column     |   Type    | Modifiers | Storage  | Stats target | Description
---------------+-----------+-----------+----------+--------------+-------------
 attrelid      | oid       | not null  | plain    |              |
 attname       | name      | not null  | plain    |              |
 atttypid      | oid       | not null  | plain    |              |
 attstattarget | integer   | not null  | plain    |              |
 attlen        | smallint  | not null  | plain    |              |
 attnum        | smallint  | not null  | plain    |              |
 attndims      | integer   | not null  | plain    |              |
 attcacheoff   | integer   | not null  | plain    |              |
 atttypmod     | integer   | not null  | plain    |              |
 attbyval      | boolean   | not null  | plain    |              |
 attstorage    | "char"    | not null  | plain    |              |
 attalign      | "char"    | not null  | plain    |              |
 attnotnull    | boolean   | not null  | plain    |              |
 atthasdef     | boolean   | not null  | plain    |              |
 attisdropped  | boolean   | not null  | plain    |              |
 attislocal    | boolean   | not null  | plain    |              |
 attinhcount   | integer   | not null  | plain    |              |
 attcollation  | oid       | not null  | plain    |              |
 attacl        | aclitem[] |           | extended |              |
 attoptions    | text[]    |           | extended |              |
 attfdwoptions | text[]    |           | extended |              |
Indexes:
    "pg_attribute_relid_attnam_index" UNIQUE, btree (attrelid, attname)
    "pg_attribute_relid_attnum_index" UNIQUE, btree (attrelid, attnum)

第二步尽量在这个期间不要出现新表的创建

ysys=# create table test003 as select * from pg_attribute where 1 = 0;
SELECT 0
ysys=# begin;
BEGIN
ysys=# lock pg_attribute;
LOCK TABLE
ysys=# insert into test003 select * from pg_attribute;
INSERT 0 2493
ysys=# commit;
COMMIT
ysys=# select count(1) from test003;
 count
-------
  2493
(1 row)

ysys=# select count(1) from pg_attribute;
 count
-------
  2493
(1 row)

第三步 只要获取当前pg_attribute的relfilenode就可以了

​ 索引是通过(attrelid,attname)(attrelid, attnum)元组创建,后期需要重新reindex即可

ysys=# select pg_relation_filepath(oid) from pg_class where relname='pg_attribute';
 pg_relation_filepath
----------------------
 base/28460/1249
(1 row)

ysys=# select pg_relation_filepath(oid) from pg_class where relname='test003';
 pg_relation_filepath
----------------------
 base/28460/46499
(1 row)

第四步 cp复制即可

[ysys@gh003 ~]$ cd /usr/local/pgsql/data/base/28460/
[ysys@gh003 28460]$ cp 1249 /home/ysys/1249_bak
[ysys@gh003 28460]$ cp 46499 1249
[ysys@gh003 28460]$ ls -lt
total 12744
-rw-------. 1 ysys ysys  376832 Jul 16 00:26 1249
-rw-------. 1 ysys ysys  376832 Jul 16 00:21 46499

第五步 需要重启

pg_ctl stop -m fast
pg_ctl start

第六步 重建索引

ysys=# reindex table pg_attribute;
REINDEX

​ 逻辑上来说,也可以创建类似索引提供出来替换目录

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
6月前
|
安全 关系型数据库 MySQL
【MySQL】表的增删查改
【MySQL】表的增删查改
|
6月前
|
关系型数据库 MySQL 数据库
数据迁移脚本优化过程:从 MySQL 到 Django 模型表
在大规模的数据迁移过程中,性能问题往往是开发者面临的主要挑战之一。本文将分析一个数据迁移脚本的优化过程,展示如何从 MySQL 数据库迁移数据到 Django 模型表,并探讨优化前后的性能差异。
|
6月前
|
SQL 关系型数据库 MySQL
mysql sql语句删除一个库下的所有表
mysql sql语句删除一个库下的所有表
44 1
|
6月前
|
分布式计算 DataWorks MaxCompute
DataWorks产品使用合集之需要将mysql 表(有longtext类型字段) 迁移到odps,但odps好像没有对应的类型支持,该怎么办
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
|
5月前
|
SQL 监控 关系型数据库
实时计算 Flink版操作报错合集之在设置监控PostgreSQL数据库时,将wal_level设置为logical,出现一些表更新和删除操作报错,怎么办
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
|
5月前
|
存储 SQL 关系型数据库
MySQL设计规约问题之在数据库设计中,为什么要适当考虑反范式的表设计
MySQL设计规约问题之在数据库设计中,为什么要适当考虑反范式的表设计
|
5月前
|
SQL 存储 数据库
MySQL设计规约问题之如何处理日志类型的表
MySQL设计规约问题之如何处理日志类型的表
|
6月前
|
关系型数据库 MySQL
蓝易云 - 如何修复MySQL中损坏的表
最后,为了防止数据丢失,定期备份数据是非常重要的。
156 3
|
5月前
|
运维 关系型数据库 MySQL
实时计算 Flink版产品使用问题之在处理MySQL表新增数据记录时,没有正确触发变更事件,该如何解决
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
6月前
|
SQL 存储 关系型数据库
MySQL数据库——SQL(1)-SQL通用语法、SQL分类、DDL(数据库操作、表操作)
MySQL数据库——SQL(1)-SQL通用语法、SQL分类、DDL(数据库操作、表操作)
63 1