Postgresql 整数超出范围,剩余磁盘空间太小,无法将id转换为bigint和其他解决方案

Postgresql 整数超出范围,剩余磁盘空间太小,无法将id转换为bigint和其他解决方案,postgresql,primary-key,disk,diskspace,Postgresql,Primary Key,Disk,Diskspace,当我insert时,我得到的整数超出范围,因为我的id/主键被错误地创建为int,而不是bigint或bigserial。我试过: ALTER TABLE tbl ALTER COLUMN id TYPE BIGINT 但是我得到以下错误,因为我的可用磁盘空间不够大 错误:无法扩展文件“base/16401/3275205”:设备上没有剩余空间 提示:检查可用磁盘空间。 SQL状态:53100 我现在不能增加磁盘空间,因为令人沮丧的原因,我将不深入讨论 我还尝试重用ID(我从这个表中删除了很多记

当我
insert
时,我得到的
整数超出范围
,因为我的id/主键被错误地创建为
int
,而不是
bigint
bigserial
。我试过:

ALTER TABLE tbl ALTER COLUMN id TYPE BIGINT

但是我得到以下错误,因为我的可用磁盘空间不够大

错误:无法扩展文件“base/16401/3275205”:设备上没有剩余空间
提示:检查可用磁盘空间。
SQL状态:53100

我现在不能增加磁盘空间,因为令人沮丧的原因,我将不深入讨论

我还尝试重用ID(我从这个表中删除了很多记录,因此有很大的差距),通过这样做来启动我的
seq

但对于该链接中的解决方案#1: 我想我没有磁盘空间了。这个表是117GB,我在
…data/base
中有大约24GB的可用空间。我的临时文件存储位置(不同的装载)有150GB的可用空间,这不是默认配置,但这样做是为了在
…data/base
中为数据库存储节省空间。如果我可以在临时文件位置创建表,这可能会起作用,但我不知道怎么做

该链接中的解决方案2: 当我进入
update
部分时,我会在pgAdmin4中看到:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>500 Internal Server Error</title>
<h1>Internal Server Error</h1>
<p>The server encountered an internal error and was unable to complete your request.  Either the server is overloaded or there is an error in the application.</p>
错误:整数超出范围

当您尝试插入以下内容时,将创建一个重复的密钥:

ALTER SEQUENCE seq RESTART WITH 1;
UPDATE t SET idcolumn=nextval('seq');
还有什么我可以试试的吗


PostgreSQL 9.6

Scott Marlowe和Vao Tsun的评论有效:

在(linux)服务器上打开终端

导航到新名称空间的位置

创建目录:
mkdir dirname

将所有权授予postgres:
chown postgres:postgres dirname

创建表:
createtablespacenew\u tbl\u space LOCATION'/path/dirname'

将表放入表空间:
altertable tbl set tablespace'/path/dirname'

执行占用这么多磁盘空间的操作:
altertable tbl ALTER COLUMN id TYPE BIGINT

将表空间更改回:
alter table tbl set table space pg_default

删除表空间:我在pgadmin4中的
表空间
节点/对象中这样做了

(这是出于记忆。如果我遗漏了什么,请告诉我。)


编辑:这样做的副作用是像完全真空一样重写整个表,释放所有死掉的磁盘空间。

在其他驱动器上是否有空间可以创建一个表空间并将该表移动到那里进行操作?否则你就卡住了。在某个地方创建表空间,
alter set tablespace new\u tbs
alter type bigint
,然后移回原始表空间pg\u default?。@VaoTsun-在概念上,是的。我以前从未对表空间做过任何事情。
new\u tbs
是路径吗?现在看医生。是的,先在备用机器上练习。您不想学习在生产服务器上使用表空间。不过这很容易。创建一个目录,将所有权设置为postgres,将其初始化为表空间,在其上创建一个表空间,然后修改table set tablespace以使其达到目的。非常方便的东西将数据(或pg_dump)转储到.tsv,删除,重新创建,从.tsv或dump加载。@ScottMarlowe-如果有兴趣,我的表大小会被删除。试图找出确切的原因和/或找到更好的策略:执行此操作时,必须锁定并重写整个表,因此它很可能会像真空填充或集群一样清除大量死元组。@ScottMarlowe-好的。有没有一种方法可以在不使用真空吸尘器的情况下减少这种浮肿?另外,这对我来说是一个惊喜,因为pg文档说如果你打算再次写入到表中,就不需要完全真空。好吧,一定量的死区是一件好事。如果其所在的块中有空空间,PostgreSQL可以就地更新许多行,这比写入新块并更新所有索引要快得多。这称为仅堆元组更新,是一个非常好的性能特性。OTOH有很多死空间,这使得它的速度变慢,因为现在db在扫描块时必须毫无代价地通过所有额外的空间。实现这一点的唯一方法是真空填充/改变表(需要重写)和集群。所有这些都是阻塞操作。你所寻找的死区是一个合理的平衡。大约10%到20%的空/死空间是一个不错的数字。所以,如果你有一个表,比如说100MB,没有死区空间,并且它会膨胀到120到150MB,那么就有足够的死区进行更新,但不会造成太大的伤害。但如果它的测量值是500MB,那么就太多了,真空度也跟不上。有一些真空自动真空设置,您可以进行调整,使自动真空更具攻击性。专门将真空度自动真空度成本延迟设置得更低,从20ms降低到3或4ms。有很大的不同。当心别让你的IO-tho进水
ALTER SEQUENCE seq RESTART WITH 1;
UPDATE t SET idcolumn=nextval('seq');