F.14. file_fdw

file_fdw模块提供外部数据包装器file_fdw,它能被用来访问服务器的文件系统中的数据文件或者执行服务器上的程序读取其输出。数据文件或者程序输出必须是能够被COPY FROM读取的格式,详见COPY。当前只能读取这种数据文件。

用这个包装器创建的一个外部表可以有下列选项:

filename

指定要被读取的文件。必须是一个绝对路径名称。必须指定filename或者program中的一个,但不能两者都指定。

program

指定要被执行的命令。这个命令的标准输出将被按照使用COPY FROM PROGRAM的方式读取。必须指定program或者filename中的一个,但不能两者都指定。

format

指定数据的格式,和COPYFORMAT选项相同。

header

指定数据是否具有一个头部行,和COPYHEADER选项相同。

delimiter

指定数据的定界符字符,和COPYDELIMITER选项相同。

quote

指定数据的引用字符,和COPYQUOTE选项相同。

escape

指定数据的转义字符,和COPYESCAPE选项相同。

null

指定数据的空字符串,和COPYNULL选项相同。

encoding

指定数据的编码,和COPYENCODING选项相同。

注意虽然COPY允许不为诸如HEADER之类的选项指定值,但是外部表选项要求在所有情况下都出现一个值。要激活通常不写值的COPY选项,用户可以传递值TRUE,因为所有这类选项都是布尔型的。

使用这个包装器创建的表的一列可以具有下列选项:

force_not_null

这是一个布尔选项。如果为真,它指定该列的值不应该与空字符串匹配(也就是表级别的null选项)。这和把该列放在COPYFORCE_NOT_NULL选项中具有相同的效果。

force_null

这是一个布尔选项。如果为真,它指定匹配空值字符串的列值会被返回为NULL, 即使该值被引号引用。如果没有这个选项,只有匹配空值字符串的未被引用的值会被返回为 NULL。这和在COPYFORCE_NULL 选项中列出该列有同样的效果。

COPYOIDSFORCE_QUOTE选项当前不被file_fdw支持。

这些选项只能为一个外部表及其列指定,而不能在file_fdw外部数据包装器的选项中指定,也不能在使用该包装器的服务器或者用户映射的选项中指定。

更改表级选项要求用户是一个超级用户或者具有默认角色pg_read_server_files(使用文件)或者默认角色pg_execute_server_programs(使用程序)的特权,出于安全原因:只有特定用户能够控制读取哪个文件或者运行哪个程序。原则上普通用户可以被允许更改其他的选项,但是当前还不支持。

在指定program选项时,记住该选项字符串是由shell执行的。如果用户需要为该命令传递来自不可信来源的参数,用户必须要小心地剥离或者转义那些可能对shell有特殊含义的字符。出于安全原因,最好使用固定的命令字符串,或者至少避免在其中传入用户输入。

对于一个使用file_fdw的外部表,EXPLAIN显示要被读取的文件名或者要被运行的程序。对于文件,除非指定COSTS OFF,文件尺寸(以字节计)也会被显示。

Example F.1. 为 PostgreSQL CSV 日志创建一个外部表

一种file_fdw的用法是把可用的 PostgreSQL 活动日志变成一个表用于查询。要这样做,首先你必须正在将日志记录到一个 CSV 文件,这里我们称其为pglog.csv。首先,将file_fdw安装为一个扩展:

CREATE EXTENSION file_fdw;

然后创建一个外部服务器:

CREATE SERVER pglog FOREIGN DATA WRAPPER file_fdw;

现在你已经准备好创建外部数据表。使用CREATE FOREIGN TABLE命令,你将需要为该表定义列、CSV 文件名以及格式:

CREATE FOREIGN TABLE pglog (
  log_time timestamp(3) with time zone,
  user_name text,
  database_name text,
  process_id integer,
  connection_from text,
  session_id text,
  session_line_num bigint,
  command_tag text,
  session_start_time timestamp with time zone,
  virtual_transaction_id text,
  transaction_id bigint,
  error_severity text,
  sql_state_code text,
  message text,
  detail text,
  hint text,
  internal_query text,
  internal_query_pos integer,
  context text,
  query text,
  query_pos integer,
  location text,
  application_name text
) SERVER pglog
OPTIONS ( filename '/home/josh/data/log/pglog.csv', format 'csv' );

就是这样了 — 现在你能够直接查询你的日志了。当然,在生产中你会需要定义一些方法来处理日志轮转。