博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
postgresql中快速对系统表实现vacuum full
阅读量:4031 次
发布时间:2019-05-24

本文共 3503 字,大约阅读时间需要 11 分钟。

     vacuum full会锁表,而且效率很低,在实际中不可能使用vacuum来缩小pg_class,这样会有很长的停机时间。

     其实要实现vacuum full最简单的方法就是将一个表重新复制一遍,create table b as select * from a;然后再使用b表代替a表使用就可以了。
     鉴于pg_class是所有表的基础,我们就算将其拷贝也无法将其取代掉。这样,我们可以以另外一种方式来实现,替换底层数据文件。由于pg_class有一个系统列,oid,这一个列我们无法简单的直接copy,所以我们采用一种迂回的方法。
1.新建一个表with oid, create table cxf with oids as select * from pg_class limit 0;
   在这个表中建立跟pg_class一样的索引,因为如果我们将底层数据文件替换掉,而还是用老的索引文件的话,会错乱的
2.将整个pg_class使用copy命令导成文本(使用参数with oids)将oid也导出
3.然后将这个数据文件用copy with oids命令存入到第一步建的表中
4.停止数据库(让所有在缓存的数据全部写入到文件中)
5.替换底层的数据文件跟索引文件
6.重启数据库即可

 

使用这种方法使pg_class的数据文件大小从1.4G变成了63M,pg_attribute从1.5G变成602M,实现了vacuum full的效果,具体步骤如下:

1.查看一下关于pg_class的表以及索引信息

aligputf8=# select oid,relname,relfilenode from pg_class where relname like '%pg_class%';
   oid    |          relname           | relfilenode
----------+----------------------------+-------------
     1259 | pg_class                   |        1259
     2662 | pg_class_oid_index         |    15687137
     2663 | pg_class_relname_nsp_index |    15687138

2.在数据库base目录下查看这几个文件

-h 1259 1259.* 15687137 15687137.* 15687138 15687138.*
ls: 15687137.*: No such file or directory
ls: 15687138.*: No such file or directory
-rw------- 1 gpadmin gpadmin 1.0G Dec 11 20:14 1259
-rw------- 1 gpadmin gpadmin 395M Dec 11 20:16 1259.1
-rw------- 1 gpadmin gpadmin  20M Dec 11 20:16 15687137
-rw------- 1 gpadmin gpadmin  83M Dec 11 20:16 15687138

3.创建一个表,结构跟pg_class一致,建表的时候必须加上with oids

aligputf8=# create table cxf with oids as select * from pg_class limit 0;
SELECT 0
aligputf8=# create index cxf_pg_class_oid_index on cxf(oid);
CREATE INDEX
aligputf8=# create index cxf_pg_class_relname_nsp_index on cxf(relname, relnamespace);
CREATE INDEX
创建索引,由于启动数据库的时候他会去找pg_class,然后通过索引去查找记录,所以这里我们需要重建索引,最后也一起把底层文件给覆盖掉
   oid    |            relname             | relfilenode
----------+--------------------------------+-------------
 19317362 | cxf                            |    19317362
 19317367 | cxf_pg_class_oid_index         |    19317367
 19317368 | cxf_pg_class_relname_nsp_index |    19317368
(3 rows)

可以看出两个表的字段信息跟字段内容是一致的

aligputf8=# select count(*) from pg_attribute where attrelid = 19317362;
 count
-------
    38
(1 row)

aligputf8=# select count(*) from pg_attribute where attrelid = 1259;

 count
-------
    38
(1 row)

4.查看pg_class现在的数据量

aligputf8=# select count(*) from pg_class;
 count 
--------
 331799
(1 row)

5.将pg_class 导出成文件,然后再导入到cxf中
aligputf8=# copy pg_class to '/tmp/pg_class_cxf' with null as '' delimiter E'/5' oids;
COPY 331799
aligputf8=# copy cxf from '/tmp/pg_class_cxf' with null as '' delimiter E'/5' oids;
COPY 331799

6.关闭数据库,备份现有的pg_class数据文件跟索引文件,以免发生意外,然后替换底层的数据文件(必须关闭数据库,如果不关闭数据库,刚刚copy回去的信息可能还没有刷到硬盘中,这个时候覆盖原有的文件会有问题的,我之前试过,结果由于数据丢失,连pg_class表也找不到了,整个数据库都不能用了)。
$GPHOME/bin/pg_ctl -w -D /home/gpadmin/cxf/aligp-1/ -o "   -E  -i -p 5132 --silent-mode=true " stop
-h 19317362 19317367 19317368
-rw------- 1 gpadmin gpadmin  63M Dec 11 20:39 19317362
-rw------- 1 gpadmin gpadmin 9.8M Dec 11 20:39 19317367
-rw------- 1 gpadmin gpadmin  47M Dec 11 20:39 19317368

1259 1259.bak

1259.1 1259.1.bak
15687137 15687137.bak
15687138 15687138.bak
19317362 1259
19317367 15687137
19317368 15687138
>

7.重启数据库,验证

gp_session_role=utility" psql -E
psql (8.2.13)
Type "help" for help.

aligputf8=# select count(*) from pg_class;

 count 
--------
 331799
(1 row)

aligputf8=# explain select * from pg_class where oid = 1259;

                                      QUERY PLAN                                      
---------------------------------------------------------------------------------------
 Index Scan using pg_class_oid_index on pg_class  (cost=0.00..200.58 rows=1 width=268)
   Index Cond: oid = 1259::oid
(2 rows)

8.使用同样的方法给pg_attribute,这个时候直接insert就可以了,不用copy成外部表,因为这个表没有oid。

数据量由1.5G变成602M

转载地址:http://neebi.baihongyu.com/

你可能感兴趣的文章
GBK编码下jQuery Ajax中文乱码终极暴力解决方案
查看>>
jQuery性能优化指南
查看>>
Oracle 物化视图
查看>>
PHP那点小事--三元运算符
查看>>
解决国内NPM安装依赖速度慢问题
查看>>
Brackets安装及常用插件安装
查看>>
在CentOS 7系统上搭建LNMP 环境
查看>>
Centos 7(Linux)环境下安装PHP(编译添加)相应动态扩展模块so(以openssl.so为例)
查看>>
fastcgi_param 详解
查看>>
Nginx配置文件(nginx.conf)配置详解
查看>>
标记一下
查看>>
一个ahk小函数, 实现版本号的比较
查看>>
IP报文格式学习笔记
查看>>
autohotkey快捷键显示隐藏文件和文件扩展名
查看>>
Linux中的进程
查看>>
学习python(1)——环境与常识
查看>>
学习设计模式(3)——单例模式和类的成员函数中的静态变量的作用域
查看>>
深度学习库安装与使用
查看>>
keras句子分类 keras_demo_for_sentence_classification (simplified version)
查看>>
MySQL for Windows 解压缩版配置安装
查看>>