9.26. 系统管理函数

这节描述的函数用来控制和监视PostgreSQL安装。

9.26.1. 配置设置函数

表 9-63显示了用于查询和修改运行时配置参数的函数。

表 9-63. 配置设置函数

名字返回类型描述
current_setting(setting_name) text获取当前的设置值
set_config(setting_name, new_value, is_local) text设置参数并返回新值

current_setting用于以查询形式获取setting_name 设置的当前值。它和SQL命令SHOW是等效的。比如:

SELECT current_setting('datestyle');

 current_setting
-----------------
 ISO, MDY
(1 row)

set_config将参数setting_name 设置为new_value。如果is_localtrue,那么新值将只应用于当前事务。 如果你希望新值应用于当前会话,那么应该使用false。 它等效于 SQL 命令SET。比如:

SELECT set_config('log_statement_stats', 'off', false);

 set_config
------------
 off
(1 row)

9.26.2. 服务器信号函数

表 9-64里的函数向其他服务器进程发送控制信号。 通常这些函数的使用限制为超级用户,除了提到的例外。

表 9-64. 服务器信号函数

名字返回类型描述
pg_cancel_backend(pid int) boolean取消一个后端的当前查询。您可以对另一个后端执行这个函数, 这个后端有和调用这个函数的用户相同的角色。在所有其他情况下,您必须是超级用户。
pg_reload_conf() boolean导致所有服务器进程重新装载它们的配置文件
pg_rotate_logfile() boolean滚动服务器的日志文件
pg_terminate_backend(pid int) boolean终止一个后端。您可以对另一个后端执行这个函数, 这个后端有和调用这个函数的用户相同的角色。在所有其他情况下,您必须是超级用户。

如果成功,这些函数返回true,否则返回false

pg_cancel_backendpg_terminate_backend 向由 pid 标识的后端进程发送一个信号(分别是SIGINTSIGTERM)。 一个活动的后端进程的 PID 可以从pg_stat_activity视图的 pid字段找到,或者在服务器上列出postgres进程 (在Unix上使用ps或在Windows上使用Task Manager)。 一个活动的后端角色可以从pg_stat_activity视图的 usename字段找到。

pg_reload_conf给服务器发送一个SIGHUP信号, 导致所有服务器进程重新装载配置文件。

pg_rotate_logfile给日志文件管理器发送信号,告诉它立即切换到一个新的输出文件。 这个函数只有在内建的日志收集器运行的时候才有用,否则根本不存在日志文件管理器子进程。

9.26.3. 备份控制函数

表 9-65里的函数帮助我们进行在线备份。 这些函数不能在恢复时执行(除了pg_is_in_backup, pg_backup_start_timepg_xlog_location_diff

表 9-65. 备份控制函数

名字返回类型描述
pg_create_restore_point(name text) pg_lsn为执行恢复创建一个命名点 (限制为超级用户)
pg_current_xlog_insert_location() pg_lsn获取当前事务日志的插入位置
pg_current_xlog_location() pg_lsn获取当前事务日志的写入位置
pg_start_backup(label text [, fast boolean ]) pg_lsn准备执行在线备份(限制为超级用户或复制的角色)
pg_stop_backup() pg_lsn完成执行在线备份 (限制为超级用户或复制的角色)
pg_is_in_backup() bool如果在线专属备份仍在进行中则为真。
pg_backup_start_time() timestamp with time zone获取进行中的在线专属备份的开始时间。
pg_switch_xlog() pg_lsn强制转向一个新的事务日志文件(限制为超级用户)
pg_xlogfile_name(location pg_lsn) text将事务日志的位置字符串转换为文件名
pg_xlogfile_name_offset(location pg_lsn) text, integer将事务日志的位置字符串转换为文件名并返回在文件中的字节偏移量
pg_xlog_location_diff(location pg_lsn, location pg_lsn) numeric计算两个事务日志位置之间的区别

pg_start_backup接受一个用户定义的备份标签(通常这是备份转储文件存放地点的名字)。 这个函数向数据库集群的数据目录写入一个备份标签文件(backup_label),执行一次检查点, 然后以文本方式返回备份的事务日志起始位置。用户可以忽略这个返回值,提供它只是为了万一需要的场合。

postgres=# select pg_start_backup('label_goes_here');
 pg_start_backup
-----------------
 0/D4445B8
(1 row)

这个函数有第二个可选的类型为boolean的参数。如果为true, 那么指定尽可能快的执行pg_start_backup。这强制一个立即的检查点, 将导致I/O操作有一个尖峰,减缓任何当前执行的查询。

pg_stop_backup删除pg_start_backup创建的标签文件, 并且在事务日志归档区里创建一个备份历史文件。这个历史文件包含给予pg_start_backup 的标签、备份的事务日志起始与终止位置、备份的起始和终止时间。 返回值是备份的事务日志终止位置(同样也可以忽略)。计算出终止位置后, 当前事务日志的插入点将自动前进到下一个事务日志文件,这样, 结束的事务日志文件可以被立即归档从而完成备份。

pg_switch_xlog移动到下一个事务日志文件,以允许将当前日志文件归档 (假定你使用连续归档)。返回值是刚刚完成的事务日志文件的事务日志结束位置 + 1。 如果自从最后一次事务日志切换以来没有活动的事务日志,那么pg_switch_xlog 什么事也不做,直接返回当前使用的事务日志文件的开始位置。

pg_create_restore_point创建一个可以用作恢复目标的命名的事务日志记录, 并返回相应的事务日志位置。给定的名字可以被recovery_target_name 使用以指定恢复将进行到的点。避免使用相同的名字创建多个恢复点, 因为恢复将在第一个名字匹配恢复目标的位置停止。

pg_current_xlog_location使用与前面那些函数相同的格式显示当前事务日志的写入位置。 类似的,pg_current_xlog_insert_location显示当前事务日志的插入位置。 插入点是事务日志在某个瞬间的"逻辑终点", 而实际的写入位置则是从服务器内部缓冲区写出时的终点。写入位置是可以从服务器外部检测到的终点, 如果想归档部分完成的事务日志文件,那么这个通常就是你想要的结果。插入点主要用于服务器调试目的。 上述两个函数既是只读操作也不需要超级用户权限。

可以使用pg_xlogfile_name_offset 从前述函数的返回结果中抽取相应的事务日志文件名称和字节偏移量。例如:

postgres=# SELECT * FROM pg_xlogfile_name_offset(pg_stop_backup());
        file_name         | file_offset 
--------------------------+-------------
 00000001000000000000000D |     4039624
(1 row)

类似的,pg_xlogfile_name仅仅抽取事务日志文件名称。 如果给定的事务日志位置恰好位于事务日志文件的交界上,这两个函数都返回前一个事务日志文件的名字。 这对于管理事务日志归档来说通常是期望的行为,因为前一个文件是当前最后一个需要归档的文件。

pg_xlog_location_diff计算两个事务日志位置之间在字节上的不同。 它可以和pg_stat_replication表 9-65 里面的一些函数一起使用以获取复制滞后。

有关正确使用这些函数的细节,参阅第 24.3 节

9.26.4. 恢复控制函数

表 9-66里显示的函数提供了当前备机状态的信息。 这些函数可能在恢复期间或正常运行中执行。

表 9-66. 恢复信息函数

名字返回类型描述
pg_is_in_recovery() bool如果恢复仍然在进行中则返回true。
pg_last_xlog_receive_location() pg_lsn获取最后一个事务日志接收并通过流媒体复制同步到磁盘的位置。 如果流复制仍在进行,这将单调增加。如果恢复已完成, 那么这个值将保持静止在恢复期间最后接收和同步到磁盘的WAL记录值。 如果不能用流复制,或还没有开始,这个函数返回NULL。
pg_last_xlog_replay_location() pg_lsn获取最后一个事物日志在恢复时重放的位置。如果恢复仍在进行,这将单调增加。 如果恢复已经完成,那么这个值将保持静止在恢复期间最后应用的WAL记录值。 当服务已经没有恢复的正常启动时,这个函数返回NULL。
pg_last_xact_replay_timestamp() timestamp with time zone获取最后一个事物在恢复时重放的时间戳。这是为在主节点上生成的事务提交或终止WAL记录的时间。 如果没有事务在恢复时重放,那么这个函数返回NULL。否则,如果恢复仍在进行, 那么这将单调增加。如果恢复已经完成,那么这个值将保持静止在恢复时最后事务应用的值。 当服务已经没有恢复的正常启动时,这个函数返回NULL。

表 9-67里的函数控制恢复的进程。 这些函数可能只在恢复时被执行。

表 9-67. 恢复控制函数

名字返回类型描述
pg_is_xlog_replay_paused() bool如果恢复暂停则返回true。
pg_xlog_replay_pause() void立即暂停恢复(受限于超级用户)。
pg_xlog_replay_resume() void如果恢复暂停了那么重新启动(受限于超级用户)。

当恢复暂停时,没有进一步的数据库更改。如果是在热备里,所有新的查询将看到相同一致的数据库快照, 并且不会有进一步的查询冲突产生,直到恢复继续。

如果不能使用流复制,那么暂停状态将没有问题的无限的延续。 当流复制正在进行时,将连续接收WAL记录,这将最终填满可用磁盘空间,取决于暂停的持续时间, WAL生成的速度和可用的磁盘空间。

9.26.5. 快照同步函数

PostgreSQL允许数据库会话同步他们的快照。snapshot 决定哪个数据对于使用这个快照的事务是可见的。当两个或更多会话需要查看数据库中相同的内容时, 快照同步是必须的。如果两个会话只是单独的启动它们的事务,仍然可能有某些事务在这两个 START TRANSACTION命令执行之间提交,所以一个会话看到了那个事务的影响而另外一个没有看到。

要解决这些问题,PostgreSQL允许一个事务export 它正在使用的快照。只要导出事务保持打开,其他事务可以import 它的快照,因此来保证他们看到的是与第一个事务看到的完全相同的数据库视图。 但是要注意的是,由任一这些事务做出的任何数据库更改对其他事务保持不可见, 对由未提交的事务做出的更改同样适用。所以事务是与已经存在的数据同步的, 但是对它们自己做的更改正常动作。

快照是由pg_export_snapshot函数输出的,在表 9-68 里面显示,并且是由SET TRANSACTION命令输入的。

表 9-68. 快照同步函数

名字返回类型描述
pg_export_snapshot() text保存当前的快照并返回它的标识符

函数pg_export_snapshot保存当前的快照并返回一个text字符串标识这个快照。 这个字符串必须传递(在数据库外面)给想要导入快照的客户端。这个快照只在事务结束输出它之前是可以导入的。 如果需要的话,一个事务可以输出多个快照。请注意,这样做只在READ COMMITTED事务中有用, 因为在REPEATABLE READ和更高的隔离级别,事务在他们的生存周期中使用相同的快照。 一旦一个事务已经输出了任何的快照,它就不能使用PREPARE TRANSACTION做好准备了。

参阅SET TRANSACTION获取如何使用一个输出的快照的信息。

9.26.6. 复制函数

表 9-69中显示的函数是为了控制和与复制功能交互的。 参阅第 25.2.5 节第 25.2.6 节 获取关于基本功能的信息。这些函数的使用受限于超级用户。

在复制协议中有许多这些函数的相等命令;参阅第 49.3 节

第 9.26.5 节第 9.26.4 节第 9.26.3 节中描述的函数也是与复制相关的。

表 9-69. 复制 SQL 函数

函数返回类型描述
pg_create_physical_replication_slot(slot_name name) (slot_name name, xlog_position pg_lsn) 创建一个名为slot_name的新物理复制槽。 从物理槽流动更改仅在有流复制槽协议的时候是可能的——参阅 第 49.3 节。对应于复制协议命令 CREATE_REPLICATION_SLOT ... PHYSICAL
pg_drop_replication_slot(slot_name name) void 删除名为slot_name的物理或逻辑复制槽。 和复制协议命令DROP_REPLICATION_SLOT相同。
pg_create_logical_replication_slot(slot_name name, plugin name) (slot_name name, xlog_position pg_lsn) 使用输出插件plugin创建一个新的名为 slot_name的逻辑(解码)复制槽。 调用此函数和复制协议命令CREATE_REPLICATION_SLOT ... LOGICAL 的效果相同。
pg_logical_slot_get_changes(slot_name name, upto_lsn pg_lsn, upto_nchanges int, VARIADIC options text[]) (location pg_lsn, xid xid, data text) 返回槽slot_name中的变化,从最后一次访问的点开始。 如果upto_lsnupto_nchanges为NULL, 逻辑解码将持续到WAL的结束。如果upto_lsn非空, 解码将只包括那些在指定LSN之前提交的事务。如果 upto_nchanges非空, 解码将在解码的行数超过指定的值时停止。不过,请注意, 实际返回的行数可能稍多些,因为这个限制仅在解码每个新的事务提交, 产生添加的行之后检查。
pg_logical_slot_peek_changes(slot_name name, upto_lsn pg_lsn, upto_nchanges int, VARIADIC options text[]) (location text, xid xid, data text) 表现就像pg_logical_slot_get_changes()函数那样, 除了没有消耗修改;也就是它们将在未来的调用中再次返回。
pg_logical_slot_get_binary_changes(slot_name name, upto_lsn pg_lsn, upto_nchanges int, VARIADIC options text[]) (location pg_lsn, xid xid, data bytea) 表现就像pg_logical_slot_get_changes()函数那样, 除了修改作为bytea返回。
pg_logical_slot_peek_binary_changes(slot_name name, upto_lsn pg_lsn, upto_nchanges int, VARIADIC options text[]) (location pg_lsn, xid xid, data bytea) 表现就像pg_logical_slot_get_changes()函数, 除了修改作为bytea返回,并且不消耗修改; 也就是,它们将在未来的调用中再次返回。

9.26.7. 数据库对象管理函数

表 9-70里显示的函数计算数据库对象使用的磁盘空间。

表 9-70. 数据库对象尺寸函数

名字返回类型描述
pg_column_size(any)int存储一个指定的数值需要的字节数(可能压缩过)
pg_database_size(oid) bigint指定 OID 代表的数据库使用的磁盘空间
pg_database_size(name) bigint指定名称的数据库使用的磁盘空间
pg_indexes_size(regclass) bigint 附加到指定表的索引使用的总磁盘空间
pg_relation_size(relation regclass, fork text) bigint 指定表或索引的指定分叉树('main', 'fsm' 'vm''init')使用的磁盘空间
pg_relation_size(relation regclass) bigint pg_relation_size(..., 'main')的简写
pg_size_pretty(bigint) text 把用64位整数表示的字节计算的尺寸转换成一个人类易读的尺寸
pg_size_pretty(numeric) text 把用数值表示的字节计算的尺寸转换成一个人类易读的尺寸
pg_table_size(regclass) bigint 指定的表使用的磁盘空间,不计索引(但是包含TOAST,自由空间映射和可见性映射)
pg_tablespace_size(oid) bigint指定 OID 代表的表空间使用的磁盘空间
pg_tablespace_size(name) bigint指定名字的表空间使用的磁盘空间
pg_total_relation_size(regclass) bigint 指定的表使用的总磁盘空间,包括所有的索引和TOAST数据

pg_column_size显示用于存储某个独立数据值的空间。

pg_total_relation_size接受一个表或压缩表的OID或名字, 并且返回那个表使用的总的在磁盘上的空间,包括所有相关的索引。 这个函数相当于pg_table_size + pg_indexes_size

pg_table_size接受一个表的OID或名字,并且返回那个表需要的磁盘空间, 不包括索引。(包含TOAST空间,自由空间映射和可见性映射)

pg_indexes_size接受一个表的OID或名字, 并且返回所有附加到这个表上的索引使用的总的磁盘空间。

pg_database_sizepg_tablespace_size 接受一个数据库或表空间的OID或名字,并且返回该对象使用的总的磁盘空间。 要使用pg_database_size,你必须在指定的数据库上 拥有CONNECT权限(缺省赋予的)。要使用pg_tablespace_size, 你必须在指定的表空间上拥有CREATE权限,除非它是当前数据库的缺省表空间。

pg_relation_size接受一个表、索引、压缩表的 OID 或者名字, 然后返回该关系的一个分支以字节计的磁盘大小。(请注意, 对于大多数场合,使用高级函数pg_total_relation_sizepg_table_size更加方便,它们统计所有分支的总和。) 带有一个参数,它返回该关系的主数据分支的大小。 可以提供第二个参数声明检测那个分支:

pg_size_pretty用于把其它函数的结果格式化成一种人类易读的格式, 可以根据情况使用KB 、MB 、GB 、TB 。

以上操作在表或索引上的函数接受一个regclass参数,这个参数简单的是表的OID 或pg_class系统目录中的索引。你不需要手动的去查看OID, 因为regclass数据类型的输入转换将为你做这件事。只需要写下包含在单引号中的表名, 这样看起来像是一个字符串常量。为了与普通的SQL名字的处理兼容, 这个字符串将被转换成小写,除非表名用双引号括起。

如果一个不代表活动对象的OID传递给以上一个函数的参数,那么返回NULL。

表 9-71里显示的函数帮助标识指定的与数据库对象有关的磁盘文件。

表 9-71. 数据库对象位置函数

名字返回类型描述
pg_relation_filenode(relation regclass) oid 指定关系的文件节点数
pg_relation_filepath(relation regclass) text 指定关系的文件路径名
pg_filenode_relation(tablespace oid, filenode oid) regclass 找出与一个给定表空间和节点相关的关系

pg_relation_filenode接受一个表、索引、序列或压缩表的OID或者名字, 并且返回当前分配给它的"filenode"数。文件节点是关系使用的文件名字的基本组件 (参阅第 59.1 节获取更多信息)。对大多数表来说, 结果和pg_class.relfilenode相同,但对确定的系统目录来说, relfilenode为0而且这个函数必须用来获取正确的值。 如果传递一个没有存储的关系,比如一个视图,那么这个函数返回NULL。

pg_relation_filepath类似于pg_relation_filenode, 但是它返回关系的整个文件路径名(相对于数据库集群的数据目录PGDATA)。

pg_filenode_relationpg_relation_filenode的逆反。 给出一个"tablespace" OID和"filenode", 它返回相关关系的OID。对于一个数据库的缺省表空间中的表, 该表空间可以指定为0。

9.26.8. 通用文件访问函数

表 9-72 里的函数提供了对数据库服务器所在机器上的文件的本地访问接口。 只有那些在数据库集群目录和log_directory目录里面的文件可以访问。 使用相对路径访问集群目录里面的文件,以及匹配log_directory 配置设置的路径访问日志文件。只有超级用户才能使用这些函数。

表 9-72. 通用文件访问函数

名字返回类型描述
pg_ls_dir(dirname text) setof text列出目录中的文件
pg_read_file(filename text [, offset bigint, length bigint]) text返回一个文本文件的内容
pg_read_binary_file(filename text [, offset bigint, length bigint]) bytea返回一个文件的内容
pg_stat_file(filename text) record返回一个文件的信息

pg_ls_dir返回指定目录里面的除了特殊项"."".."之外的所有名字。

pg_read_file返回一个文本文件的一部分,从offset开始, 返回最多length字节(如果先达到文件结尾,则小于这个数值)。 如果offset是负数,那么它就是相对于文件结尾回退的长度。 如果省略了offsetlength,则返回整个文件。 从文件读取到的字节在服务器编码里被解释为一个字符串; 如果它们在那种编码下是不可用的则抛出一个错误。

pg_read_binary_file类似于pg_read_file, 除了结果是bytea值;因此,不执行编码检查。 与convert_from函数结合,这个函数可以用来读取用指定编码的一个文件。

SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8');

pg_stat_file返回一个记录,这个记录包含文件大小, 最后访问的时间戳,最后修改的时间戳,最后文件状态改变的时间戳(只在Unix平台上), 文件创建的时间戳(只在Windows),和一个boolean表明是否为一个路径。 典型的用法包括:

SELECT * FROM pg_stat_file('filename');
SELECT (pg_stat_file('filename')).modification;

9.26.9. 咨询锁函数

表 9-73中的函数用于管理咨询锁(Advisory Lock)。 有关正确使用这些函数的细节,参阅第 13.3.5 节

表 9-73. 咨询锁函数

名字返回类型描述
pg_advisory_lock(key bigint) void获取排他会话级别咨询锁
pg_advisory_lock(key1 int, key2 int) void获取排他会话级别咨询锁
pg_advisory_lock_shared(key bigint) void获取共享会话级别咨询锁
pg_advisory_lock_shared(key1 int, key2 int) void获取共享会话级别咨询锁
pg_advisory_unlock(key bigint) boolean释放一个排他会话级别咨询锁
pg_advisory_unlock(key1 int, key2 int) boolean释放一个排他会话级别咨询锁
pg_advisory_unlock_all() void释放所有当前会话持有的会话级别咨询锁
pg_advisory_unlock_shared(key bigint) boolean释放一个共享会话级别咨询锁
pg_advisory_unlock_shared(key1 int, key2 int) boolean释放一个共享会话级别咨询锁
pg_advisory_xact_lock(key bigint) void获取排他事务级别咨询锁
pg_advisory_xact_lock(key1 int, key2 int) void获取排他事务级别咨询锁
pg_advisory_xact_lock_shared(key bigint) void获取共享事务级别咨询锁
pg_advisory_xact_lock_shared(key1 int, key2 int) void获取共享事务级别咨询锁
pg_try_advisory_lock(key bigint) boolean尝试获取排他会话级别咨询锁
pg_try_advisory_lock(key1 int, key2 int) boolean尝试获取排他会话级别咨询锁
pg_try_advisory_lock_shared(key bigint) boolean尝试获取共享会话级别咨询锁
pg_try_advisory_lock_shared(key1 int, key2 int) boolean尝试获取共享会话级别咨询锁
pg_try_advisory_xact_lock(key bigint) boolean尝试获取排他事务级别咨询锁
pg_try_advisory_xact_lock(key1 int, key2 int) boolean尝试获取排他事务级别咨询锁
pg_try_advisory_xact_lock_shared(key bigint) boolean尝试获取共享事务级别咨询锁
pg_try_advisory_xact_lock_shared(key1 int, key2 int) boolean尝试获取共享事务级别咨询锁

pg_advisory_lock锁定一个应用程序定义的资源, 该资源可以用一个 64 位或两个不重叠的 32 位键值标识。如果已经有另外的会话锁定了该资源, 那么该函数将会阻塞到该资源可用为止。这个锁是排它的。多个锁定请求将会被压入栈中,因此, 如果同一个资源被锁定了三次,那么它必须被解锁三次以将资源释放给其它会话使用。

pg_advisory_lock_shared类似于pg_advisory_lock, 不同之处仅在于共享锁可以和其它请求共享锁的会话共享,但排他锁除外。

pg_try_advisory_lock类似于pg_advisory_lock, 不同之处在于该函数不会阻塞以等待资源的释放。它要么立即获得锁并返回true, 要么返回false表示目前不能锁定。

pg_try_advisory_lock_shared类似于pg_try_advisory_lock, 不同之处在于该函数尝试获得一个共享锁而不是一个排它锁。

pg_advisory_unlock释放先前取得的排他会话级别咨询锁。 如果释放成功则返回true。如果指定的锁并未持有, 那么它将返回false并且服务器会报告一条 SQL 警告消息。

pg_advisory_unlock_shared类似于pg_advisory_unlock, 不同之处在于该函数释放的是共享会话级别咨询锁。

pg_advisory_unlock_all将会释放当前会话持有的所有会话级别咨询锁, 该函数在会话结束的时候被隐含调用,即使客户端异常地断开连接也是一样。

pg_advisory_xact_lock类似于pg_advisory_lock, 不同之处在于锁是自动在当前事务的结束释放的,而且不能被显式的释放。

pg_advisory_xact_lock_shared类似于 pg_advisory_lock_shared, 不同之处在于锁是自动在当前事务的结束释放的,而且不能被显式的释放。

pg_try_advisory_xact_lock类似于pg_try_advisory_lock, 不同之处在于锁,如果得到,是自动在当前事务的结束释放的,而且不能被显式的释放。

pg_try_advisory_xact_lock_shared类似于pg_try_advisory_lock_shared, 不同之处在于锁,如果得到,是自动在当前事务的结束释放的,而且不能被显式的释放。