• 售前

  • 售后

热门帖子
入门百科

快速解决PostgreSQL中的Permission denied题目

[复制链接]
绘粹凭 显示全部楼层 发表于 2021-10-26 13:29:14 |阅读模式 打印 上一主题 下一主题
想开始学习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,那么我们在下令行中实行如下下令
  1. netstat -ano | find /i "5432"
复制代码
假如发现了某个历程利用了5432这个端口,这阐明是端口占用导致服务无法启动:

这个历程的pid是2364,你想查看它是什么历程,可以实行:
  1. tasklist | findstr "2364"
复制代码
实行结果如下:

你可以在任务管理器-历程页面中,大概通过下面的下令结束这个历程:
  1. taskkill /f /pid 5432
复制代码
小知识:
PostgreSQL 是多历程模子的数据库。它在运行时,会启动一个名为“pg_ctl”历程和若干个名为“postgres” 的历程。此中,历程pg_ctl是“先人”历程,它表现数据库处于运行状态,占用的内存很少;其他全部工作历程的名称都是postgres。
在 Windows 操纵体系上,假如 pg_ctl.exe 被异常关闭了,历程 postgres.exe 还会存在。数据库运行端口仍然被占用。会导致数据库无法启动。
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 文件夹,在这里打开下令行,实行下面的下令:
  1. .\pg_ctl start -D ..\data
复制代码
假如步调报出如下错误:
  1. ERROR: could not open control file “global/pg_control”: Permission denied
复制代码
则阐明当前操纵体系用户丢失了data文件夹及其内容的权限。
下面是办理方法:
1. 起首,进入postgresql 的安装路径,右键data文件夹,依次点击属性——安全——编辑,你能看到全部用户或用户组的权限。

2. 确保System 和 Administrator 拥有“完全控制”权限。Users 用户组默认只拥有“读取和实行”,“列出文件夹内容”和“读取”3种权限。当启动数据库提示“权限不足”时,应再添加“修改”和 “写入”。

3. 生存并实验再次在bin 文件夹下实行:
  1. .\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)粉碎了:
  1. LOG: could not open file "pg_xlog/0000000100000000000000E7" (log file 0, segment 231): No such file or directory
  2. LOG: invalid primary checkpoint record
  3. LOG: could not open file "pg_xlog/0000000100000000000000E7" (log file 0, segment 231): No such file or directory
  4. LOG: invalid secondary checkpoint record
  5. PANIC: could not locate a valid checkpoint record
复制代码
办理方法如下:
进入bin 文件夹,在这里打开下令行,实行下面的下令:
  1. .\pg_resetxlog.exe -f ..\data
复制代码
在日志重置后,再实验启动数据库。
2.1.5 failed to re-find parent key in index "227236" for split pages 370/371
偶然,数据库无法启动时,我们查看位于data文件夹下的pg_log中的数据库运行日志,会发现雷同下面的信息:
  1. LOG: redo starts at 270/55E04AE8
  2. LOG: could not open file pg_xlog/0000000100000270000000CC" (log file 624, segment 204): No such file or directory
  3. LOG: redo done at 270/CBFFE940
  4. LOG: last completed transaction was at log time 2018-11-26 01:55:01.259996-02
  5. FATAL: failed to re-find parent key in index "227236" for split pages 370/371
  6. LOG: startup process (PID 5011) exited with exit code 1
  7. 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
另有一种不常见的环境。假如日志中出现雷同下面的信息:
  1. ERROR: could not access status of transaction 710708
  2. DETAIL: Could not read from file "pg_clog/000E" at offset 172032: No error.
复制代码
则表现位于data文件夹下pg_clog中的名为 000E 的提交日志文件丢失了。
办理方法如下:
在linux 操纵体系中,实行下列下令:
  1. dd if=/dev/zero of=/root/000E bs=256k count=1
复制代码
大概在windows中安装 dd,随后实行:
  1. dd if=/dev/zero of=D:\000E bs=256k count=1
复制代码
然后将创建好的000E 文件拷贝至data文件夹下的pg_clog 中。
2.2 数据库启动后,部门数据库或表无法访问
这种环境下,你需要进入 data文件夹下的pg_log文件夹,查看标题发生时刻产生的运行日志。
2.2.1 permission denied for relation tb_door
假如运行日志出现雷同下面的信息,这阐明是当前访问用户没有表tb_door的某些权限:
  1. ERROR: permission denied for relation tb_door
复制代码
假如你盼望当前用户(以myuser为例)拥有特定访问权限(以SELECT,INSERT,UPDATE ,DELETE为例),可以如许办理:
起首,通过postgres用户或拥有tb_door 相应访问权限即授予权限的用户登录数据库;
实行如下下令,为用户授予权限:
  1. grant SELECT,INSERT,UPDATE,DELETE on tb_door to myuser
复制代码
2.2.2 must be owner of relation tb_door
假如运行日志出现雷同下面的信息,这阐明是当前用户没有表ac_door的全部权:
  1. ERROR: must be owner of relation tb_door
复制代码
你可以利用管理员postgres登录相应数据库,手动实行下面下令将tb_door的属主你盼望的用户,以myuser为例:
  1. Alter table tb_door owner to myuser;
复制代码
2.2.3 invalid page header in block 120 of relation base/272816/309624
假如日志中出现雷同下面的信息:
  1. ERROR: invalid page header in block 120 of relation base/272816/309624
复制代码
则表现数据表文件粉碎。这通常是由于异常断电或误操纵导致的。这里“272816”是发生标题的数据库的对象id(oid), “309624”表现发生标题的表的文件结点(filenode)
假如发生粉碎的表以及粉碎的页面数量较少,我们可以以断送部门数据的代价规复团体;假如粉碎的表数量过多,大概丧失的数据非常重要,就需要从备份中规复数据了。
当发生粉碎的表以及粉碎的页面数量较少时,办理方法如下:
确定发生标题的数据库。毗连任意数据库,实行下面的sql语句:
  1. select datname from pg_database where oid = 272816;
复制代码
查询结果如下:
  1. testdb
复制代码
这表现发生标题的数据库名是testdb
2. 查找粉碎的数据库对象。毗连发生标题的数据库,实行下面的sql语句:
  1. select relname,relkind from pg_class where relfilenode = 309624
复制代码
假如查询结果中 relkind = r,表现粉碎的是表。
比方:
  1. tb_door, r
复制代码
relname = tb_door这表现粉碎的表是tb_door。
假如查询结果中relkind = i,表现粉碎的是一个索引。
比方:
  1. dept_number_index, i
复制代码
大概:
  1. tb_dept_pkey, i
复制代码
需要留意,粉碎的大概是平凡索引,也大概是主键或唯一键。假如索引的名称中有“_pkey”等很大概属于主键,而名称中含有 “_key”则很大概属于唯一键。
还需要格外留意一点,表/索引可修复的条件条件是粉碎的表是应用步调创建的表/索引,而不是PostgreSQL的体系表和创建在其上的索引。假如体系表/创建在其上的索引发生粉碎,则需要从备份中规复数据库。判定一个表是否是体系表,最简朴的方法是:假如表名是“pg_”开头的,则阐明它是体系表。
小知识
pgclass.relkind 的值有下面几种:
r: 表现ordinary table(平凡表);
i: 表现index(索引);
S: 表现sequence(序列);
V: 表现view(视图);
m: 表现materialized view(物化视图);
c: 表现composite type(复合范例);
t: 表现TOAST table(TOAST 表);
f: 表现foreign table(外部表)
3. 修复粉碎的数据库对象。毗连发生粉碎的数据库,实行修复下令。
假如粉碎的是表,以tb_door为例,则依次实行下列下令即可完成修复:
  1. set zero_damaged_pages = on;
  2. vacuum full tb_door;
  3. reindex table tb_door;
复制代码
假如粉碎的是平凡索引,以dept_number_index为例, 则依次实行:
  1. set zero_damaged_pages = on;
  2. reindex index dept_number_index;
复制代码
假如粉碎的是主键或唯一键,则起首需要找到它所在的表,以tb_dept_pkey为例:
  1. Select tablename,indexname from pg_indexes where indexname = ‘tb_dept_pkey';
复制代码
查询结果:
  1. tb_dept, tb_dept_pkey
复制代码
然后获取索引的界说:
  1. select pg_get_constraintdef((select oid from pg_constraint where conname = ' tb_dept_pkey '));
复制代码
查询结果:
  1. PRIMARY KEY (dept_id)
复制代码
然后重新创建这个束缚:
  1. Alter table drop constriant tb_dept_pkey;
  2. Alter table add constraint tb_dept_pkey PRIMARY KEY (dept_id);
复制代码
2.2.4 could not read block 190 in file "base/272816/309624"
该标题的办理方法与2.2.2 节的标题完全相同。
2.2.5 could not open file "base/272816/379923": No such file or directory
假如日志中出现雷同下面的信息:
  1. 2019-01-21 14:28:03 HKT ERROR: could not open file "base/272816/379923": No such file or directory
复制代码
则阐明,oid为272816的数据库中,oid为379923的表对应的文件被删除了。
办理方法如下:
1. 起首判定是哪一个数据库中发生了此标题。毗连任意数据库,实行如下sql:
  1. select datname from pg_database where oid = 272816
复制代码
查询结果如下:
  1. testdb
复制代码
2. 从备份中规复该数据库。
2.3 数据库启动后,部门数据库或表无法访问
2.3.1 No buffer space available
偶然,在服务管理器中,PostgreSQL 表现为 正在运行状态,但是利用客户端毗连使,提示“could not connect to server: No buffer space available”,在postgresql运行日志中,也能看到雷同日志。
办理方法如下:
起首,在服务管理器中关闭 PostgreSQL 服务。
实验用 PostgreSQL 自身的下令启动它。进入postgresql安装路径下的 bin 文件夹,在这里打开下令行,实行下面的下令:
  1. .\pg_ctl start -D ..\data
复制代码
3. 观察提示信息。假如提示PostgreSQL启动成功,则用客户端毗连数据库;假如启动不成功,则参考 2.1 章的内容。
4. 假如仍然有如许的错误提示,那阐明很大概是内存不足。你需要在操纵体系中查看内存,假如发现可用内存较少,那你需要观察是否有服务内存异常过高,并处置惩罚它。在 Windows 上 有一种特别的环境,各种服务起来正常,但内存很少,这是因为 windows Socket 毗连关闭后,内存不开释。对于windows 2008,办理方法是打 windows补丁 KB2577795。
2.3.2 no pg_hba.conf entry for host

假如日志中出现雷同下面的信息:
  1. FATAL: no pg_hba.conf entry for host "192.168.0.123", user "testuser", database "testdb"
复制代码
则表现数据库服务器没有答应来自所在192.168.0.123的 testuser 用户访问数据库testdb。
办理的方法如下:
查抄 data 目次中的设置文件 postgresql.conf 中的参数 listen_addresses,把它的值改为 '*', 大概包含客户端的IP。
修改data 目次中的访问权限设置文件 pg_hba.conf。假如你盼望全部所在的全部用户可以访问此服务器中的全部数据库,可以添加下面这一行:
  1. host all    all   0.0.0.0/0     md5
复制代码
假如你只盼望192.168.0.123 上的用户可以访问此数据库,则添加:
  1. host all    all   192.168.0.123/32     md5
复制代码
大概你仅仅盼望192.168.0.123 上的 testuser 用户可以访问此数据库,则添加:
  1. host testuser    all   192.168.0.123/32     md5
复制代码
重启数据库即可。
小知识:
pg_hba.conf 是 postgresql 服务端的访问权限控制文件,控制来自哪里的什么用户,以什么创建方式毗连,以什么方法认证,访问哪一个数据库。每行是一个访问控制条目,内容的示比方下:
  1. host all    all   127.0.0.1/32     md5
复制代码
每列的含义如下:
第一列表现访问域的范例,其值有local,host,hostssl,hostnossl。一样平常选择 host,表现利用 TCP/IP 创建的毗连。
第二列表现答应访问的数据库用户,“all” 表现全部用户可以访问。
第三列表现答应被访问的数据库名,“all” 表现全部数据库都答应被访问。
第四列表现答应访问的ip所在,127.0.0.1/32表现当地IP所在,192.168.0.123/32 表现所在192.168.0.123,192.168.0.0/24表现子网192.168.0.0 ~ 192.168.0.255,0.0.0.0/0表现任何IP所在。
第五列是认证的方式。“md5” 表现MD5暗码认证,trust表现无暗码认证。
2.3.3 No connection could be made because the target machine actively refused it.
假如日志中出现雷同下面的信息:
  1. LOG: could not receive data from client: No connection could be made because the target machine actively refused it.
复制代码
则表现有一些因素使数据库服务器拒绝了客户端的毗连。
办理的思绪如下:
起首查抄平台有没有单点登录。假如有,关闭。
查抄有没有安装防火墙,假如有,答应5432端口毗连。
查抄 data 目次中的设置文件 postgresql.conf 中的参数 listen_addresses,把它的值改为 '*', 大概包含客户端的IP。
修改data 目次中的访问权限设置文件 pg_hba.conf。假如你盼望全部所在的全部用户可以访问此服务器中的全部数据库,可以添加下面这一行:
  1. host all    all   0.0.0.0/0     md5
复制代码
假如你只盼望192.168.0.123 上的用户可以访问此数据库,则添加:
  1. host all    all   192.168.0.123/32     md5
复制代码
5. 重启数据库,观察能否访问。
以上为个人经验,盼望能给各人一个参考,也盼望各人多多支持草根技术分享。如有错误或未思量完全的地方,望不吝见教。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作