PostgreSQL中快速对系统表实现vacuum full

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目录下查看这几个文件

@linuxidc:/home/gpadmin/cxf/aligp-1/base/16384>ll -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

@linuxidc:/home/gpadmin/cxf/aligp-1/base/16384>ll -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

@linuxidc:/home/gpadmin/cxf/aligp-1/base/16384>mv 1259 1259.bak

@linuxidc:/home/gpadmin/cxf/aligp-1/base/16384>mv 1259.1 1259.1.bak

@linuxidc:/home/gpadmin/cxf/aligp-1/base/16384>mv 15687137 15687137.bak

@linuxidc:/home/gpadmin/cxf/aligp-1/base/16384>mv 15687138 15687138.bak

@linuxidc:/home/gpadmin/cxf/aligp-1/base/16384>cp 19317362 1259

@linuxidc:/home/gpadmin/cxf/aligp-1/base/16384>cp 19317367 15687137

@linuxidc:/home/gpadmin/cxf/aligp-1/base/16384>cp 19317368 15687138

@linuxidc:/home/gpadmin/cxf/aligp-1/base/16384>

7.重启数据库,验证

@linuxidc:/home/gpadmin/cxf/aligp-1/base/16384>PGOPTIONS="-c 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

本文原创发布php中文网,转载请注明出处,感谢您的尊重!

mysql vacuum_PostgreSQL中快速对系统表实现vacuum full相关推荐

  1. mysql数据库搜索字符_在MySQL数据库中快速搜索字符串?

    使用FULLTEXT搜索来快速搜索字符串.让我们首先创建一个表-mysql> create table DemoTable1554 -> ( -> Title text ->  ...

  2. 数据库分片教程mysql_简述MySQL分片中快速数据迁移

    操作实践背景: travelrecord表定义为10个分片,尝试将10个分片中的2个分片转移到第二台MySQL上,并完成记录, 要求最快的数据迁移做法,中断业务时间最短 思路一利用mysqldump: ...

  3. mysql 分片 数据迁移_简述MySQL分片中快速数据迁移_MySQL

    推荐阅读:MySQL 数据库跨操作系统的最快迁移方法 mysql 备份与迁移 数据同步方法 操作实践背景: travelrecord表定义为10个分片,尝试将10个分片中的2个分片转移到第二台MySQ ...

  4. Mysql 事务中Update 会锁表吗?

    Mysql 事务中Update 会锁表吗? 两种情况: 1.带索引 2.不带索引 前提介绍: 方式:采用命令行的方式来模拟 1.mysq由于默认是开启自动提交事务,所以首先得查看自己当前的数据库是否开 ...

  5. 通过JSP网页连接MySQL数据库,从MySQL数据库中读出一张表并显示在JSP网页中

    1.安装所需软件 ①安装java和tomcat,建立JSP网页最基础的软件 ②安装MySQL数据库(下载地址:https://www.mysql.com/) ③安装Navicat Premium来查看 ...

  6. mysql数据库中,查询一个表的下一条数据减上一条数据的值的写法

    mysql数据库中,查询一个表的下一条数据减上一条数据的值的写法: select a.nodeId,a.cpuCharge-b.cpuCharge cpuCharge, a.chargeTime fr ...

  7. mysql 快速复制_MySQL中快速复制数据表方法汇总

    本文将着重介绍两个MySQL命令的组合,它将以原有数据表为基础,创建相同结构和数据的新数据表. 这可以帮助你在开发过程中快速的复制表格作为测试数据,而不必冒险直接操作正在运行 的数据表. 示例如下: ...

  8. MySQL中快速复制数据表方法汇总

    本文将着重介绍两个MySQL命令的组合,它将以原有数据表为基础,创建相同结构和数据的新数据表. 这可以帮助你在开发过程中快速的复制表格作为测试数据,而不必冒险直接操作正在运行 的数据表. 示例如下: ...

  9. mysql 复制表中的数据_MySQL中快速复制数据表方法汇总

    本文将着重介绍两个MySQL命令的组合,它将以原有数据表为基础,创建相同结构和数据的新数据表. 这可以帮助你在开发过程中快速的复制表格作为测试数据,而不必冒险直接操作正在运行 的数据表. 示例如下: ...

最新文章

  1. 为啥我的页面模板的from提交不了数据_小程序,组件与模板对比,及其简单使用
  2. 如何将命令行参数传递给Node.js程序?
  3. https 不会被中间人攻击——因为中间人即使拿到了数据,也是加密的
  4. MyBatis设计模式总结
  5. 安装在谷歌axure小工具
  6. mysql and 和where,关于mysql:连接sql查询中where和and子句的区别
  7. python struct pack一个数组_Python中struct.pack的一个疑问
  8. 一个比较简单驱动程序初学者可以看看
  9. 导入hbase_HBase基础学习之bulkload了解
  10. Big Event in HDU
  11. python tornado高并发_tornado IO并发真的很高么?
  12. 毕业生简单的用Python实现一个信息管理系统【含示例代码】
  13. 跟我学AngularJs:Directive指令用法解读(上)
  14. python爬虫笔记---1.13---第一篇
  15. 三菱FX3U源码在V10.5的基础上增加了禁止上传功能
  16. Zotero 知网文章不能转成pdf 的解决办法。
  17. java图形验证码去除干扰,使用python 对验证码图片进行降噪处理
  18. 如何防止网站内容被采集
  19. java lcs_LCS最长公共子序列java实现
  20. 建“数字风洞”,永信至诚开启安全测试评估专业赛道

热门文章

  1. Reading22. Understanding Balance Sheets
  2. 最近最开心的一件事情
  3. exit status 145: Ŀ¼���ǿյġ� exit s
  4. 威马汽车任命前高盛高管为首席战略官 新一轮融资将超30亿
  5. 干货 应用阿里AI一句话识别 java 实现语音实时识别
  6. 【学习】如何制作手机端html模板(REM的实际应用)
  7. 上海亚商投顾:沪指重返3100点
  8. 淘宝反腐!26家网店因贿赂淘宝小二被关停
  9. 数值分析北航第八题第三次计算实习任务(附百度云源码java版)
  10. 【图像处理】简单的车牌识别