快速解决PostgreSQL中的Permissiondenied问题
想开始学习SQL和Excel那本书,觉得⾃⼰亲⼿去输⼊才是正道。发现程序后续会⽤到窗⼝函数,可是我的mysql没有窗⼝函数,这本书所提供的数据脚本分别是MS SQL Sever和PostreSQL。
上午我先安装的sql sever,可是由于⽐较⼤且在安装时出现了⼀些⼩的问题(安装缓慢,服务启动不了)。⽆奈选择了PostreSQL,体积⼩,安装顺利。
导⼊数据⽐较特别,先建⼀个表,然后把同名txt导⼊进去。⼀定要⽤unix⽅式的路径。
copy这个语句先前在mysql上没有遇到过。学习下。。。。
根据我的错误代码发现是权限不够,之前⽤mysql的时候并没有注意到权限这个问题。
哇,被权限搞的真的头⽪发⿇。中间的曲折过程就不表了,第⼀次了解到数据库超级⽤户这个概念,还有就是postresql的结构和
mysql也很不同。数据库-模式-表。最后是⽤postres创建了⼀个超级⽤户。但是发现还是报错,拒绝访问。我就想到可能是txt放在了C盘不能随便访问,所以我将data⽂件放到了D盘,导⼊成功。
成功了!今天⼀个下午算是折在这上⾯了,不过总算有收获。了解了⽤户,postresql中的copy。明天开始照着书做吧。
PS:(虽然这回的数据没有中⽂)
补充:PostgreSQL的⼏种常见问题和解决⽅法
1. 前⾔
1.1 概述
本⽂介绍了postgresql的⼏种常见问题,并从现象出发,逐步排查问题,分析导致问题的原因并给出解决⽅案。
本⽂介绍的问题分为两⼤类:⼀类是关于PostgreSQL⽆法启动的问题,另⼀类是PostgreSQL启动后,部分数据库对象⽆法访问的问题。
1.2 软件环境
本⽂使⽤的 PostgreSQL 版本是 9.6。
1.3 ⼀些约定术语
PostgreSQL安装路径:默认是 “D:\Program Files\PostgreSQL\9.6”
bin ⽂件夹:PostgreSQL安装路径下的bin⽂件夹。
data ⽂件夹:PostgreSQL安装路径下的data⽂件夹。
2. 问题和解决⽅法
2.1 PostgreSQL⽆法启动
PostgreSQL 没有正常启动时,在 “服务”中再次启动失败。
2.1.1 端⼝占⽤
我们⾸先需要判断是不是该服务的端⼝被占⽤。PostgreSQL服务的默认端⼝是5432,那么我们在命令⾏中执⾏如下命令
netstat -ano | find /i "5432"
如果发现了某个进程使⽤了5432这个端⼝,这说明是端⼝占⽤导致服务⽆法启动:
这个进程的pid是2364,你想查看它是什么进程,可以执⾏:
tasklist | findstr "2364"
执⾏结果如下:
你可以在任务管理器-进程页⾯中,或者通过下⾯的命令结束这个进程:
taskkill /f /pid 5432
⼩知识:
PostgreSQL 是多进程模型的数据库。它在运⾏时,会启动⼀个名为“pg_ctl”进程和若⼲个名为“postgres
” 的进程。其中,进程pg_ctl是“祖先”进程,它表⽰数据库处于运⾏状态,占⽤的内存很少;其他所有⼯作进程的名称都是postgres。
在 Windows 操作系统上,如果 被异常关闭了,进程 还会存在。数据库运⾏端⼝仍然被占⽤。会导致数据库⽆法启动。
2.1.2 ⽂件 postmaster.pid 残留
进⼊ PostgreSQL的data ⽂件夹,查看是否有残留的⽂件 postmaster.pid。正常情况下,PostgreSQL 在启动时会创建这个⽂件,其内容是 PostgreSQL 的主进程的 pid。如果它存在,则数据库会认为⾃⼰已经启动了,所以启动失败。
因此需要删除这个⽂件,再尝试启动数据库。
2.1.3 could not open control file “global/pg_control”:Permission denied
如果端⼝没有被占⽤,那么你可以⽤PostgreSQL原⽣的命令启动它。
进⼊postgresql安装路径下的 bin ⽂件夹,在这⾥打开命令⾏,执⾏下⾯的命令:
.\pg_ctl start -D ..\data
如果程序报出如下错误:
ERROR: could not open control file “global/pg_control”: Permission denied
则说明当前操作系统⽤户丢失了data⽂件夹及其内容的权限。
下⾯是解决⽅法:
mysql数据库损坏修复
1. ⾸先,进⼊postgresql 的安装路径,右键data⽂件夹,依次点击属性——安全——编辑,你能看到所有⽤户或⽤户组的权限。
2. 确保System 和 Administrator 拥有“完全控制”权限。Users ⽤户组默认只拥有“读取和执⾏”,“列出⽂件夹内容”和“读取”3种权限。当启动数据库提⽰“权限不⾜”时,应再添加“修改”和 “写⼊”。
3. 保存并尝试再次在bin ⽂件夹下执⾏:
.\pg_ctl start -D ..\data
观察PostgreSQL数据库能否启动。
2.1.4 could not locate a valid checkpoint record
如果启动数据库时,提⽰“正在启动服务器进程”,且长时间⽆法启动成功,如下图所⽰,需要查看数据库运⾏⽇志,它们位于data⽂件夹下的pg_log中的。
打开问题发⽣时的数据库运⾏⽇志,查看信息。
如果⽇志中出现类似下⾯⿊体字的信息,说明是PostgreSQL数据库中的预写式⽇志(write ahead log,简称WAL,⼜称事务⽇志,简称xlog)损坏了:
LOG: could not open file "pg_xlog/0000000100000000000000E7" (log file 0, segment 231): No such file or directory
LOG: invalid primary checkpoint record
LOG: could not open file "pg_xlog/0000000100000000000000E7" (log file 0, segment 231): No such file or directory
LOG: invalid secondary checkpoint record
PANIC: could not locate a valid checkpoint record
解决⽅法如下:
进⼊bin ⽂件夹,在这⾥打开命令⾏,执⾏下⾯的命令:
.\ -f ..\data
在⽇志重置后,再尝试启动数据库。
2.1.5 failed to re-find parent key in index "227236" for split pages 370/371
有时,数据库⽆法启动时,我们查看位于data⽂件夹下的pg_log中的数据库运⾏⽇志,会发现类似下⾯的信息:
LOG: redo starts at 270/55E04AE8
LOG: could not open file pg_xlog/0000000100000270000000CC" (log file 624, segment 204): No such file or directory
LOG: redo done at 270/CBFFE940
LOG: last completed transaction was at log time 2018-11-26 01:55:01.259996-02
FATAL: failed to re-find parent key in index "227236" for split pages 370/371
LOG: startup process (PID 5011) exited with exit code 1
LOG: aborting startup due to startup process failure
上⾯⿊体字的信息,同样说明是PostgreSQL数据库中的预写式⽇志⽂件损坏了。
该问题的解决⽅法和2.1.3节的问题的解决⽅法相同。
2.1.6 ⽆法到来⾃源 PostgreSQL 的事件 ID 0 的描述。
如果上⾯的⽅法没有解决问题,那么我们需要进⼊事件管理器中查看是否有错误⽇志:
在事件查看器-Windows⽇志-应⽤程序中,查看是否有如下错误⽇志:
⽆法到来⾃源 PostgreSQL 的事件 ID 0 的描述。本地计算机上未安装引发此事件的组件,或者安装已损坏。可以安装或修复本地计算机上的组件。
如果出现了这样的信息,则说明PostgreSQL软件已经损坏,需要重新安装。不过,数据⽂件不⼀定损坏了,因此如果上次备份⾄今,数据库中产⽣过⾮常重要的数据(⽐如账单信息),你应该将data⽂件夹复制到另⼀个⽬录,然后重新安装平台,并恢复data⽂件夹。
2.1.7 Could not read from file "pg_clog/000E" at offset 172032
还有⼀种不常见的情况。如果⽇志中出现类似下⾯的信息:
ERROR: could not access status of transaction 710708
DETAIL: Could not read from file "pg_clog/000E" at offset 172032: No error.
则表⽰位于data⽂件夹下pg_clog中的名为 000E 的提交⽇志⽂件丢失了。
解决⽅法如下:
在linux 操作系统中,执⾏下列命令:
dd if=/dev/zero of=/root/000E bs=256k count=1
或者在windows中安装 dd,随后执⾏: