开源数据库 PostgreSQL 是 1980 年以加利福尼亚大学为中心开发出来的 DBMS,与 MySQL 一样,都是世界上广泛应用的开源数据库(DB)。

本文将会介绍使用 64 位版的 Windows 安装程序(Win x86-64)在 Windows Server 2019(64 位)系统中安装 PostgreSQL 的步骤,请大家结合自身实际下载相应的安装程序。

数据库安装包下载地址:Download PostgreSQL (enterprisedb.com) 

运行安装程序的时候,鼠标右键点击安装文件,然后选择“以管理员身份运行”,默认的安装路径是“C:\Program Files\PostgreSQL\14”,选择数据保存路径的,默认路径“C:\PostgreSQL\14\data” ,我们改到了F:\pgdata.

在接下来的数据库管理员密码设置画面中输入任意密码,点击“Next >”按钮。登录 PostgreSQL 时会用到这个密码,请大家务必牢记。 接下来会出现端口号设置画面,无需修改,保持默认的5432,直接点击“Next >”按钮。通常情况下保持默认选项即可。

接下来是 PostgreSQL 地区设置画面。选择默认值,有一次改成了“Chinese(Simplified),Singapore”,出现了下面的错误页面。

安装完成的时候出现了如下画面:

image

只好手工来完成最后一步:

  1. 切换到安装目录下的bin目录
  2. 管理员权限执行initdb "F:\pgdata"
  3. 如果服务未自动启动,使用pg_ctl start -D "F:\pgdata"启动服务
  4. 创建用户cmd执行createuser -s -r postgres

image

使用安装时设置的管理员密码登陆pgadmin(安装路径下/pgAdmin 4/bin/pgAdmin4.exe)

46ee43eea1a41c95e92f219a44483d9

ERROR: character with byte sequence 0xe5 0x91 0xa8 in encoding "UTF8" has noequivalent in encoding"WIN1252"

通过修改PostgreSQL配置文件,在运行日志(不是WAL和提交日志)中输出SQL语句执行情况,可以准确定位到哪个表会引发错误。具体方法是:

  • 修改配置文件postgresql.conf,通常在$pgdata目录下,本例中是在F:\pgdata目录;
  • 找到“where to log”块,将logging_collector设置为on,这意味着开启运行日志,所在目录由log_directory参数指定;
  • 找到“what to log”块,将log_statement设置为mod或all,这意味着sql语句被记录到运行日志;
  • 仍在“when to log”块,确保log_min_error_statement为error或更低级别,以记录错误信息;因缺省值已是error,一般无须修改;
  • 仍在“when to log”块,确保log_min_message为info或更低级别,这样成功执行的sql语句所绑定的变量也能查到(可选);
  • 重启PostgreSQL,执行那个导入程序,此时运行日志已记录下执行的sql语句情况,根据报错信息即可具体定位是哪个表引起。

日志里看到如下的sql:

2022-12-22 08:19:23.510 UTC [1888] ERROR:  character with byte sequence 0xe5 0x91 0xa8 in encoding "UTF8" has no equivalent in encoding "WIN1252"
2022-12-22 08:19:23.510 UTC [1888] STATEMENT:  /*pga4dash*/
     SELECT
         pid,
         datname,
         usename,
         application_name,
         client_addr,
         pg_catalog.to_char(backend_start, 'YYYY-MM-DD HH24:MI:SS TZ') AS backend_start,
         state,
         wait_event_type || ': ' || wait_event AS wait_event,
         pg_catalog.pg_blocking_pids(pid) AS blocking_pids,
         query,
         pg_catalog.to_char(state_change, 'YYYY-MM-DD HH24:MI:SS TZ') AS state_change,
         pg_catalog.to_char(query_start, 'YYYY-MM-DD HH24:MI:SS TZ') AS query_start,
         pg_catalog.to_char(xact_start, 'YYYY-MM-DD HH24:MI:SS TZ') AS xact_start,
         backend_type,
         CASE WHEN state = 'active' THEN ROUND((extract(epoch from now() - query_start) / 60)::numeric, 2) ELSE 0 END AS active_since
     FROM
         pg_catalog.pg_stat_activity
     WHERE
         datname = (SELECT datname FROM pg_catalog.pg_database WHERE oid = 13754)ORDER BY pid

上面这个问题的原因在postgrsql 里是一个普遍的问题,由于客户端和服务器的编码不对。