PostgreSQL 9.4内存分配请求大小突然无效

PostgreSQL 9.4内存分配请求大小突然无效,postgresql,Postgresql,我正在建立一个网站,将用于处理来自商店的excel文件,并对其进行操作(合并、查看等)。我使用PostgreSQL 9.4作为数据库,运行在Centos 6.6虚拟机上,内存为4GB。它有3个数据库,如下所示: postgres数据库 db_raw,用作数据的占位符。从网站上传的excel将被解析,数据将存储在这里。该数据库由几个用于保存处理excel所需数据的表和一个用于存储excel数据(当前列数>140,行数近100万)的大型表组成 db_processed,这是网站的主要数据库。它有几

我正在建立一个网站,将用于处理来自商店的excel文件,并对其进行操作(合并、查看等)。我使用PostgreSQL 9.4作为数据库,运行在Centos 6.6虚拟机上,内存为4GB。它有3个数据库,如下所示:

  • postgres数据库
  • db_raw,用作数据的占位符。从网站上传的excel将被解析,数据将存储在这里。该数据库由几个用于保存处理excel所需数据的表和一个用于存储excel数据(当前列数>140,行数近100万)的大型表组成
  • db_processed,这是网站的主要数据库。它有几个用于网站运行的小表(用户表、访问列表、日志记录等),还有8个表用于存储从db_raw处理的excel数据。这8个表中的每个表都有大约40列和大约100万行
直到今天早上,数据库都运行得很好。我尝试通过pgAdmin和PuTTY连接到db_,PostgreSQL给了我这个消息

FATAL:  invalid memory alloc request size 144115188075856068
db_raw工作正常,据我所知,从3天前开始就没有任何变化。我应该怎么做才能再次连接到数据库

更新:我照@CraigRinger说的做了,重新启动了服务。我设法连接到数据库,但所有的表都不见了:|现在它一直出现在日志中

< 2015-09-21 12:27:22.155 WIB >DEBUG:  performing replication slot checkpoint
< 2015-09-21 12:27:22.158 WIB >LOG:  request to flush past end of generated WAL; request 46/9E0981D8, currpos 46/771C69B0
< 2015-09-21 12:27:22.158 WIB >CONTEXT:  writing block 2 of relation base/18774/12766
< 2015-09-21 12:27:22.158 WIB >ERROR:  xlog flush request 46/9E0981D8 is not satisfied --- flushed only to 46/771C69B0
< 2015-09-21 12:27:22.158 WIB >CONTEXT:  writing block 2 of relation base/18774/12766
< 2015-09-21 12:27:22.158 WIB >WARNING:  could not write block 2 of base/18774/12766
< 2015-09-21 12:27:22.158 WIB >DETAIL:  Multiple failures --- write error might be permanent.
调试:执行复制插槽检查点 <2015-09-21 12:27:22.158 WIB>日志:请求刷新生成的WAL的末尾;请求46/9E0981D8,当前位置46/771C69B0 <2015-09-21 12:27:22.158 WIB>上下文:关系库的书写块2/18774/12766 <2015-09-21 12:27:22.158 WIB>错误:xlog刷新请求46/9E0981D8未满足---仅刷新到46/771C69B0 <2015-09-21 12:27:22.158 WIB>上下文:关系库的书写块2/18774/12766 <2015-09-21 12:27:22.158 WIB>警告:无法写入base/18774/12766的块2 <2015-09-21 12:27:22.158 WIB>详细信息:多个故障---写入错误可能是永久性的。
这是由损坏的行引起的

创建一个函数来“检测”损坏的行:

CREATE OR REPLACE FUNCTION is_bad_row(tableName TEXT, tabName TEXT, tidInitial tid)
RETURNS integer 
as $find_bad_row$
BEGIN
    EXECUTE 'SELECT (each(hstore(' || tabName || '))).* FROM ' || tableName || ' WHERE ctid = $1' USING tidInitial; 
    RETURN 0;
    EXCEPTION
        WHEN OTHERS THEN
        RAISE NOTICE '% = %: %', tidInitial, SQLSTATE, SQLERRM;
        RETURN 1;
END
$find_bad_row$
LANGUAGE plpgsql;
。。。然后创建一个“临时表”来存储坏行的ctid:

create table bad_rows as 
SELECT ctid as row_tid
FROM your_schema.your_table
where is_bad_row('your_schema.your_table', 'your_table', ctid) = 1
。。。然后,只需删除这些行:

delete from your_schema.your_table where ctid in (select row_tid from bad_rows)
。。。并删除“临时表”:


欧欧?完全正确。请检查PostgreSQL错误日志,可能会有更多信息。您可能需要在
postgresql.conf
中设置
log\u min\u messages='debug1'
,然后
pg\u ctl reload
重新读取配置。顺便说一句,二进制数字看起来可疑:
10000000000000000000000000000011000100
这是最好的答案。这样,您就不必猜测ctid,如果有多个损坏的行,也不必重复该过程。在我们的例子中,我们有一个表,其中有16M行,其中有一些损坏的行,在执行上述过程(第二个命令)时,系统连接意外关闭,我没有看到任何n/w、内存下降,一切都在本地主机上。我认为,一旦它找到损坏的行,连接就会关闭。有什么帮助吗?
drop table bad_rows