一、背景

在工作中,可能会遇到将表从一个表空间移动另一个表空间。例如

* 对数据进行冷处理
* 表空间所在的磁盘空间不足
* 建表时分配错了表空间

以上等等,可能需要你将一个表移动表空间。

二、表空间介绍

PostgreSQL的表空间

三、移动数据文件方法

我们先打造下环境;创建两个表空间

postgres=# CREATE TABLESPACE tsp01 OWNER lottu LOCATION '/data/pg6000/tsp01';
CREATE TABLESPACE
postgres=# CREATE TABLESPACE tsp02 OWNER lottu LOCATION '/data/pg6000/tsp02';
CREATE TABLESPACE

查看数据库默认表空间

postgres=# \c lottu lottu
You are now connected to database "lottu" as user "lottu".
lottu=> select d.datname,p.spcname from pg_database d, pg_tablespace p where d.datname='lottu' and p.oid = d.dattablespace;
 datname |  spcname   
---------+------------
 lottu   | pg_default
(1 row)

接下来我们在表空间tsp01建表tbl_lottu

lottu=> create table tbl_lottu(id int primary key, info text) TABLESPACE tsp01;
CREATE TABLE
lottu=> insert into tbl_lottu select generate_series(1,1000) ,md5(random()::text);
INSERT 0 1000
lottu=> \d tbl_lottu
              Table "lottu.tbl_lottu"
 Column |  Type   | Collation | Nullable | Default 
--------+---------+-----------+----------+---------
 id     | integer |           | not null | 
 info   | text    |           |          | 
Indexes:
    "tbl_lottu_pkey" PRIMARY KEY, btree (id)
Tablespace: "tsp01"

而表tbl_lottu数据文件的位置

lottu=> select pg_relation_filepath('tbl_lottu');
pg_relation_filepath
---------------------------------------------
pg_tblspc/90618/PG_12_201909212/24750/90620
(1 row)

3.1、alter table

将表从一个表空间移到另一个表空间

lottu=> ALTER TABLE tbl_lottu SET TABLESPACE tsp02;
ALTER TABLE

我们再查看表;已经成功移动表空间tsp02

lottu=> \d tbl_lottu 
              Table "lottu.tbl_lottu"
 Column |  Type   | Collation | Nullable | Default 
--------+---------+-----------+----------+---------
 id     | integer |           | not null | 
 info   | text    |           |          | 
Indexes:
    "tbl_lottu_pkey" PRIMARY KEY, btree (id)
Tablespace: "tsp02" lottu=> select pg_relation_filepath('tbl_lottu');
            pg_relation_filepath             
---------------------------------------------
 pg_tblspc/90619/PG_12_201909212/24750/90629
(1 row)

不足之处:在alter table这个过程中是锁表的;若是大表;执行时间久,在这个时间内表在dml操作一直处在等待。那有没有不锁表,或者锁表的时间极短的方法呢?

3.2、create + copy

我们想想,在做表的移动表空间操作步骤可以理解是,

新建一个表在tsp02中,再把数据copy过来,再用新表替换旧表。该方式操作太复杂了,同时也不能保证数据的完整性。在确保在这段时间内不对表进行任何操作;可以试下。

3.3、pg_repack

在生产环境处理表膨胀,我们会考虑用pg_repack来取代vacuum full,因为它在处理表膨胀的过程中可以避免表被长期锁定。pg_repack工作原理:创建一个新表,将数据从旧表移动到新表。为了避免表被独占锁定,创建了一个额外的日志表来记录原始表的改动,还添加了一个把INSERT / UPDATE / DELETE操作记录到日志表的触发器。当原始表中的数据全部导入到新表中,索引重建完毕,日志表的改动全部完成,pg_repack会连同新索引,用新表替换旧表,并将原旧表Drop掉。整个过程非常简单,非常可靠。同时它还支持在不同表空间迁移表和索引

我们开始实际操作下:

第一步:先创建表tbl_repack;

lottu=# create table tbl_repack(id int primary key, info text) TABLESPACE tsp01;
CREATE TABLE
lottu=# insert into tbl_repack select generate_series(1,1000000) ,md5(random()::text);
INSERT 0 1000000
lottu=# select pg_relation_filepath('tbl_repack');
            pg_relation_filepath             
---------------------------------------------
 pg_tblspc/90618/PG_12_201909212/24750/90681
(1 row)

第二步:执行pg_repack

[postgres@lottu ~]$ pg_repack -t lottu.tbl_repack -s tsp02 -j 2 -d lottu -U lottu
NOTICE: Setting up workers.conns
INFO: repacking table "lottu.tbl_repack"

执行的同时;我们对表tbl_repack执行delete操作;实验是否堵塞dml操作

lottu=# delete from tbl_repack where id < 100;
DELETE 99

第三步:查看是否移动成功

lottu=# select pg_relation_filepath('tbl_repack');
            pg_relation_filepath             
---------------------------------------------
 pg_tblspc/90619/PG_12_201909212/24750/90704
(1 row)
lottu=# \d tbl_repack;
             Table "lottu.tbl_repack"
 Column |  Type   | Collation | Nullable | Default 
--------+---------+-----------+----------+---------
 id     | integer |           | not null | 
 info   | text    |           |          | 
Indexes:
    "tbl_repack_pkey" PRIMARY KEY, btree (id)
Tablespace: "tsp02"
lottu=# select count(1) from tbl_repack ;
 count  
--------
 999901
(1 row)

限制之处:

  1. 执行pg_repack操作需要超级用户
[postgres@lottu ~]$ pg_repack -t tbl_repack -s tsp02 -j 2 -d lottu -U lottu
NOTICE: Setting up workers.conns
ERROR: pg_repack failed with error: You must be a superuser to use pg_repack
  1. 移动的表需要有主键或者唯一索引;这个取决于pg_repack实现原理;大家可以去查看官方文档
[postgres@lottu ~]$ pg_repack -t lottu.tbl_repack -s tsp02 -j 2 -d lottu -U lottu
NOTICE: Setting up workers.conns
WARNING: relation "lottu.tbl_repack" must have a primary key or not-null unique keys

PostgreSQL在不同的表空间移动数据文件的更多相关文章

  1. Oracle的表空间和数据文件

    一. 概念 表空间:是一个或多个数据文件的逻辑集合 表空间逻辑存储对象: 永久段-->如表与索引 临时段-->如临时表数据与排序段 回滚段-->用于事物回滚或闪回内存的撤销数据 表空 ...

  2. 管理表空间和数据文件<六>

    数据库管理 -- 管理表空间和数据文件  介绍 表空间是数据库的逻辑组成部分.从物理上讲,数据库数据存放在数据文件中:从逻辑上讲,数据库则是存放在表空间中,表 空间由一个或多个数据文件组成. 数据库 ...

  3. 【转】Oracle 表空间与数据文件

    --============================== --Oracle 表空间与数据文件 --============================== /* 一.概念 表空间:是一个或 ...

  4. Oracle-11g 从表空间删除数据文件

    从表空间删除数据文件前提条件 如果欲从表空间中删除数据文件,那么该数据文件必须为空,否则将报出"ORA-03262: the file is non-empty"的错误.   从表 ...

  5. 【基础】Oracle 表空间和数据文件

    多个表空间的优势:1.能够将数据字典与用户数据分离出来,避免由于字典对象和用户对象保存在同一个数据文件中而产生的I/O冲突2.能够将回退数据与用户数据分离出来,避免由于硬盘损坏而导致永久性的数据丢失3 ...

  6. RMAN数据库恢复之恢复表空间和数据文件

    执行表空间或数据文件恢复时,数据库既可以是MOUNT状态,也可以是OPEN状态.1.恢复表空间在执行恢复之前,如果被操作的表空间未处理OFFLINE状态,必须首先通过ALTER TABLESPACE… ...

  7. oracle维护表空间和数据文件

    1:重要参考 wiki 2: oracle doc 表空间参考 3:来自dba-oracle的参考 26,27,28,29 一:oracle 表空间概念 表空间是联系数据库的物理磁盘(数据文件)和逻辑 ...

  8. 十四、oracle 数据库管理--管理表空间和数据文件

    一.概念表空间是数据库的逻辑组成部分.从物理上讲,数据库数据存放在数据文件中:从逻辑上讲,数据库数据则是存放在表空间中,表空间由一个或多个数据文件组成. 二.数据库的逻辑结构oracle中逻辑结构包括 ...

  9. ORACLE - 管理表空间和数据文件

    ORACLE表空间是一个逻辑分区,一个数据文件只能属于一个表空间,一个表空间可以拥有多个数据文件. 一般情况下,如果一个实例分配给多个应用使用,需要创建不同的表空间,每个用户使用自己的表空间. 一.表 ...

随机推荐

  1. 2019 HL SC day10

    10天都过去了 4天都在全程懵逼.. 怎么可以这么难啊 我服了 现在想起依稀只记得一些结论 什么 反演? 什么后缀自动机?什么组合数的应用?什么神仙东西 ,不过讲课人的确都是神仙.(实名羡慕. mzx ...

  2. CPU监控 线段树裸题

    LINK:bzoj3064 此题甚好码了20min停下来思考的时候才发现不对的地方有点坑... 还真不好写来着 可这的确是线段树的裸题...我觉得我写应该没有什么大问题 不过思路非常的紊乱 如果是自己 ...

  3. bzoj 2125 最短路 点双 圆方树

    LINK:最短路 一张仙人掌图 求图中两点最短路. \(n<=10000,Q<=10000,w>=1\) 考虑边数是多少 m>=n-1 对于一张仙人掌图 考虑先构建出来dfs树 ...

  4. bzoj 3436小K的农场

    3436: 小K的农场 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 2327 Solved: 1105 [Submit][Status][Discu ...

  5. Fragment为什么须要无参构造方法

    日前在项目代码里遇到偷懒使用重写Fragment带参构造方法来传参的做法,顿生好奇,继承android.support.v4.app.Fragment而又不写无参构造方法不是会出现lint错误编译不通 ...

  6. 基于深度学习的人脸识别系统Win10 环境安装与配置(python+opencv+tensorflow)

    一.需要下载的软件.环境及文件 (由于之前见识短浅,对Anaconda这个工具不了解,所以需要对安装过程做出改变:就是Python3.7.2的下载安装是可选的,因为Anaconda已经为我们解决Pyt ...

  7. 我用python远程探查女友每天的网页访问记录,她不愧是成年人!

    利用Python制作远程查看别人电脑的操作记录,与其它教程类似,都是通过邮件返回. 利用程序得到目标电脑浏览器当中的访问记录,生产一个文本并发送到你自己的邮箱,当然这个整个过程除了你把python程序 ...

  8. Unity 笔记

    摄像机 Main Camera 跟随主角移动,不看 UI 剧情摄像机 当进入剧情时,可以关闭 main camera,启用剧情摄像机,不看 UI UI 摄像机 看 UI Unity编辑器常用的sett ...

  9. react 样式冲突解决方案 styled-components

    前置 在 react 中解决组件样式冲突的方案中,如果您喜欢将 css 与 js 分离,可能更习惯于 CSS-Modules:如果习惯了 Vue.js 那样的单文件组件,可能习惯于使用 styled- ...

  10. Ubuntu用户都应该了解的快捷键

    无论我们使用什么操作系统还是什么软件,快捷键都是非常有用的,因为可以在启动应用程序或跳转到所需窗口,可以快速进行很多操作,而无需动鼠标到处点,节省时间和精力,提高效率. 就像在Windows中一样,U ...