我最近在typecho上保存文章时碰到了这个问题,在点击保存草稿按钮后会转跳到错误页面,但是刷新页面后又会显示保存正常。而且不仅保存草稿有时会出现这个问题,在发布文章功能上也会出现,严重时甚至会出现丢失刚写的文章的问题。故用此篇文章来记录分析和解决问题的过程。

系统环境:
ubuntu 22.04
postgres 12.11

关键词: typecho database postgresql

一、问题分析

1.开启Typecho Debug模式

因为database query 500问题可能涉及的方面太广泛了,大概率可能是安装的插件有bug或者冲突的原因,也可能就是数据库异常的问题,故需要开启调试模式查看详细日志来确定问题

a.打开www目录下typecho程序

b.编辑config.inc.php文件,向其中添加以下内容

vim config.inc.php
define('__TYPECHO_DEBUG__', true);

c.:wq保存并退出

2.重复之前会导致问题的操作,复现问题

现在看到的错误就明晰多了,问题发生在数据库中,而且还是blog_contents_pkey的表发生了问题,前面的语义大概意思是,blog_contents_pkey是唯一的,现在插入的值与其中的值重复造成了冲突,所以现在就需要进入数据库,验证是否为该问题

duplicate key value violates unique constraint blog_contents_pkey

3.进入postgresql数据库

a.打开psql

su - root
su - postgresql -c psql

显示如下内容即为正常

psql (12.11 (Ubuntu 12.11-0ubuntu0.20.04.1))
Type "help" for help.

postgres=#

b.列出所有数据库

\l

\l 与 \list 等效

c.进入typecho数据库

\c 数据库名

\c 与 \connect 等效

d.显示数据库中所有表

  • \dt

返回值

typechodb=# \dt
               List of relations
 Schema |        Name        | Type  |  Owner  
--------+--------------------+-------+---------
 public | blog_comments      | table | typecho
 public | blog_contents      | table | typecho
 public | blog_fields        | table | typecho
 public | blog_metas         | table | typecho
 public | blog_options       | table | typecho
 public | blog_relationships | table | typecho
 public | blog_users         | table | typecho
(7 rows)
  • \displaytable

返回值

typechodb=# \displaytable
                             List of relations
 Schema |          Name           |   Type   |  Owner  |       Table        
--------+-------------------------+----------+---------+--------------------
 public | blog_comments           | table    | typecho | 
 public | blog_comments_cid       | index    | typecho | blog_comments
 public | blog_comments_created   | index    | typecho | blog_comments
 public | blog_comments_pkey      | index    | typecho | blog_comments
 public | blog_comments_seq       | sequence | typecho | 
 public | blog_contents           | table    | typecho | 
 public | blog_contents_created   | index    | typecho | blog_contents
 public | blog_contents_pkey      | index    | typecho | blog_contents
 public | blog_contents_seq       | sequence | typecho | 
 public | blog_contents_slug_key  | index    | typecho | blog_contents
 public | blog_fields             | table    | typecho | 
 public | blog_fields_float_value | index    | typecho | blog_fields
 public | blog_fields_int_value   | index    | typecho | blog_fields
 public | blog_fields_pkey        | index    | typecho | blog_fields
 public | blog_metas              | table    | typecho | 
 public | blog_metas_pkey         | index    | typecho | blog_metas
 public | blog_metas_seq          | sequence | typecho | 
 public | blog_metas_slug         | index    | typecho | blog_metas
 public | blog_options            | table    | typecho | 
 public | blog_options_pkey       | index    | typecho | blog_options
 public | blog_relationships      | table    | typecho | 
 public | blog_relationships_pkey | index    | typecho | blog_relationships
 public | blog_users              | table    | typecho | 
 public | blog_users_mail_key     | index    | typecho | blog_users
 public | blog_users_name_key     | index    | typecho | blog_users
 public | blog_users_pkey         | index    | typecho | blog_users
 public | blog_users_seq          | sequence | typecho | 
(27 rows)

\dt 与 \displaytable不完全等效,前者只显示当前数据库下有什么表,后者还会显示表中的Indexes

e.查询blog_contents表结构

\d blog_contents

返回值

cid          | integer                |           | not null | nextval('blog_contents_seq'::regclass)

可以看到首行的cid使用了自增控制

cid是唯一的且cid在数据库中是自增的. 而现在数据库中存在的cid的值大于了cid现在应该自增的值.比如现在数据库blog_content表中现在的cid是100,而cid自增才增长到95.那你在添加一条数据的时候,cid是96,cid为96的这条数据已经有了,所以cid就违反了唯一性约束

4.验证问题

a.先查看这张表中已经存在的cid的最大值是多少

SELECT max(cid) from blog_contents;

b.查询这张表的cid的自增序列是多少

SELECT nextval('blog_contents_seq');

如果这张表中已经存在的id的最大值大于cid的自增序列的值。那就证明添加的时候会出现id被占用,而导致id违反唯一性约束的问题

二、解决方案

只需要重新给id的自增序列赋值,赋一个大于现在表中id的最大值就可以了

SELECT setval('blog_contents_seq', xxx);

重新查询修改后的id的自增序列的值是多少

SELECT nextval('blog_contents_seq');

设置成功后再次尝试保存文章草稿问题消失

三、参考链接

postgres 错误duplicate key value violates unique constraint 解决方案
查看PostgreSQL数据库中所有表

文章作者:四文鱼Max

本文链接:https://blog.awolon.fun/archives/typecho-draft-database-query-500.html

许可协议:CC BY-SA 4.0

标签: postgresql, typecho

添加新评论