💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
# 9.26\. 系统管理函数 这节描述的函数用来控制和监视PostgreSQL安装。 ## 9.26.1\. 配置设置函数 [Table 9-58](#calibre_link-2336)显示了用于查询和修改运行时配置参数的函数。 **Table 9-58\. 配置设置函数** | 名字 | 返回类型 | 描述 | | --- | --- | --- | | ``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_local` 为`true`,那么新值将只应用于当前事务。 如果你希望新值应用于当前会话,那么应该使用`false`。 它等效于 SQL 命令`SET`。比如: ``` SELECT set_config('log_statement_stats', 'off', false); set_config ------------ off (1 row) ``` ## 9.26.2\. 服务器信号函数 [Table 9-59](#calibre_link-1377)里的函数向其他服务器进程发送控制信号。 通常这些函数的使用限制为超级用户,除了提到的例外。 **Table 9-59\. 服务器信号函数** | 名字 | 返回类型 | 描述 | | --- | --- | --- | | ``pg_cancel_backend(```pid` `int`) | `boolean` | 取消一个后端的当前查询。您可以对另一个后端执行这个函数, 这个后端有和调用这个函数的用户相同的角色。在所有其他情况下,您必须是超级用户。 | | ``pg_reload_conf()`` | `boolean` | 导致所有服务器进程重新装载它们的配置文件 | | ``pg_rotate_logfile()`` | `boolean` | 滚动服务器的日志文件 | | ``pg_terminate_backend(```pid` `int`) | `boolean` | 终止一个后端。您可以对另一个后端执行这个函数, 这个后端有和调用这个函数的用户相同的角色。在所有其他情况下,您必须是超级用户。 | 如果成功,这些函数返回`true`,否则返回`false`。 `pg_cancel_backend`和`pg_terminate_backend` 向由 pid 标识的后端进程发送一个信号(分别是SIGINT或SIGTERM)。 一个活动的后端进程的 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\. 备份控制函数 [Table 9-60](#calibre_link-1642)里的函数帮助我们进行在线备份。 这些函数不能在恢复时执行(除了`pg_is_in_backup`, `pg_backup_start_time`和`pg_xlog_location_diff`) **Table 9-60\. 备份控制函数** | 名字 | 返回类型 | 描述 | | --- | --- | --- | | ``pg_create_restore_point(```name` `text`) | `text` | 为执行恢复创建一个命名点 (限制为超级用户) | | ``pg_current_xlog_insert_location()`` | `text` | 获取当前事务日志的插入位置 | | ``pg_current_xlog_location()`` | `text` | 获取当前事务日志的写入位置 | | ``pg_start_backup(```label` `text` [, `fast` `boolean` ]) | `text` | 准备执行在线备份(限制为超级用户或复制的角色) | | ``pg_stop_backup()`` | `text` | 完成执行在线备份 (限制为超级用户或复制的角色) | | ``pg_is_in_backup()`` | `bool` | 如果在线专属备份仍在进行中则为真。 | | ``pg_backup_start_time()`` | `timestamp with time zone` | 获取进行中的在线专属备份的开始时间。 | | ``pg_switch_xlog()`` | `text` | 强制转向一个新的事务日志文件(限制为超级用户) | | ``pg_xlogfile_name(```location` `text`) | `text` | 将事务日志的位置字符串转换为文件名 | | ``pg_xlogfile_name_offset(```location` `text`) | `text`, `integer` | 将事务日志的位置字符串转换为文件名并返回在文件中的字节偏移量 | | ``pg_xlog_location_diff(```location` `text`, `location` `text`) | `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](#calibre_link-1691) 使用以指定恢复将进行到的点。避免使用相同的名字创建多个恢复点, 因为恢复将在第一个名字匹配恢复目标的位置停止。 `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`或[Table 9-60](#calibre_link-1642) 里面的一些函数一起使用以获取复制滞后。 有关正确使用这些函数的细节,参阅[Section 24.3](#calibre_link-466)。 ## 9.26.4\. 恢复控制函数 [Table 9-61](#calibre_link-1049)里显示的函数提供了当前备机状态的信息。 这些函数可能在恢复期间或正常运行中执行。 **Table 9-61\. 恢复信息函数** | 名字 | 返回类型 | 描述 | | --- | --- | --- | | ``pg_is_in_recovery()`` | `bool` | 如果恢复仍然在进行中则返回true。 | | ``pg_last_xlog_receive_location()`` | `text` | 获取最后一个事务日志接收并通过流媒体复制同步到磁盘的位置。 如果流复制仍在进行,这将单调增加。如果恢复已完成, 那么这个值将保持静止在恢复期间最后接收和同步到磁盘的WAL记录值。 如果不能用流复制,或还没有开始,这个函数返回NULL。 | | ``pg_last_xlog_replay_location()`` | `text` | 获取最后一个事物日志在恢复时重放的位置。如果恢复仍在进行,这将单调增加。 如果恢复已经完成,那么这个值将保持静止在恢复期间最后应用的WAL记录值。 当服务已经没有恢复的正常启动时,这个函数返回NULL。 | | ``pg_last_xact_replay_timestamp()`` | `timestamp with time zone` | 获取最后一个事物在恢复时重放的时间戳。这是为在主节点上生成的事务提交或终止WAL记录的时间。 如果没有事务在恢复时重放,那么这个函数返回NULL。否则,如果恢复仍在进行, 那么这将单调增加。如果恢复已经完成,那么这个值将保持静止在恢复时最后事务应用的值。 当服务已经没有恢复的正常启动时,这个函数返回NULL。 | [Table 9-62](#calibre_link-1693)里的函数控制恢复的进程。 这些函数可能只在恢复时被执行。 **Table 9-62\. 恢复控制函数** | 名字 | 返回类型 | 描述 | | --- | --- | --- | | ``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`函数输出的,在[Table 9-63](#calibre_link-2337) 里面显示,并且是由[SET TRANSACTION](#calibre_link-507)命令输入的。 **Table 9-63\. 快照同步函数** | 名字 | 返回类型 | 描述 | | --- | --- | --- | | ``pg_export_snapshot()`` | `text` | 保存当前的快照并返回它的标识符 | 函数`pg_export_snapshot`保存当前的快照并返回一个`text`字符串标识这个快照。 这个字符串必须传递(在数据库外面)给想要导入快照的客户端。这个快照只在事务结束输出它之前是可以导入的。 如果需要的话,一个事务可以输出多个快照。请注意,这样做只在`READ COMMITTED`事务中有用, 因为在`REPEATABLE READ`和更高的隔离级别,事务在他们的生存周期中使用相同的快照。 一旦一个事务已经输出了任何的快照,它就不能使用[PREPARE TRANSACTION](#calibre_link-903)做好准备了。 参阅[SET TRANSACTION](#calibre_link-507)获取如何使用一个输出的快照的信息。 ## 9.26.6\. 数据库对象管理函数 [Table 9-64](#calibre_link-1073)里显示的函数计算数据库对象使用的磁盘空间。 **Table 9-64\. 数据库对象尺寸函数** | 名字 | 返回类型 | 描述 | | --- | --- | --- | | ``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'`) 使用的磁盘空间 | | ``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_size`和`pg_tablespace_size` 接受一个数据库或表空间的OID或名字,并且返回该对象使用的总的磁盘空间。 `pg_relation_size`接受一个表、索引、压缩表的 OID 或者名字, 然后返回它们以字节计的磁盘大小。指定`'main'` 或省略第二个参数返回这个关系的主数据支路的大小。指定`'fsm'` 返回和这个关系有关的自由空间映射(参阅[Section 58.3](#calibre_link-1512))的大小。 指定`'vm'`返回和这个关系有关的可见性映射 (参阅[Section 58.4](#calibre_link-1513))的大小。请注意,这个函数只显示一个支路的大小; 更多的是想更方便的使用高级函数`pg_total_relation_size`或`pg_table_size`。 `pg_size_pretty`用于把其它函数的结果格式化成一种人类易读的格式, 可以根据情况使用KB 、MB 、GB 、TB 。 以上操作在表或索引上的函数接受一个`regclass`参数,这个参数简单的是表的OID 或`pg_class`系统目录中的索引。你不需要手动的去查看OID, 因为`regclass`数据类型的输入转换将为你做这件事。只需要写下包含在单引号中的表名, 这样看起来像是一个字符串常量。为了与普通的SQL名字的处理兼容, 这个字符串将被转换成小写,除非表名用双引号括起。 如果一个不代表活动对象的OID传递给以上一个函数的参数,那么返回NULL。 [Table 9-65](#calibre_link-2338)里显示的函数帮助标识指定的与数据库对象有关的磁盘文件。 **Table 9-65\. 数据库对象位置函数** | 名字 | 返回类型 | 描述 | | --- | --- | --- | | ``pg_relation_filenode(```relation` `regclass`) | `oid` | 指定关系的文件节点数 | | ``pg_relation_filepath(```relation` `regclass`) | `text` | 指定关系的文件路径名 | `pg_relation_filenode`接受一个表、索引、序列或压缩表的OID或者名字, 并且返回当前分配给它的"filenode"数。文件节点是关系使用的文件名字的基本组件 (参阅[Section 58.1](#calibre_link-1511)获取更多信息)。对大多数表来说, 结果和`pg_class`.`relfilenode`相同,但对确定的系统目录来说, `relfilenode`为0而且这个函数必须用来获取正确的值。 如果传递一个没有存储的关系,比如一个视图,那么这个函数返回NULL。 `pg_relation_filepath`类似于`pg_relation_filenode`, 但是它返回关系的整个文件路径名(相对于数据库集群的数据目录`PGDATA`)。 ## 9.26.7\. 通用文件访问函数 [Table 9-66](#calibre_link-2339) 里的函数提供了对数据库服务器所在机器上的文件的本地访问接口。 只有那些在数据库集群目录和`log_directory`目录里面的文件可以访问。 使用相对路径访问集群目录里面的文件,以及匹配`log_directory` 配置设置的路径访问日志文件。只有超级用户才能使用这些函数。 **Table 9-66\. 通用文件访问函数** | 名字 | 返回类型 | 描述 | | --- | --- | --- | | ``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`是负数,那么它就是相对于文件结尾回退的长度。 如果省略了`offset`和`length`,则返回整个文件。 从文件读取到的字节在服务器编码里被解释为一个字符串; 如果它们在那种编码下是不可用的则抛出一个错误。 `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.8\. 咨询锁函数 [Table 9-67](#calibre_link-2340)中的函数用于管理咨询锁(Advisory Lock)。 有关正确使用这些函数的细节,参阅[Section 13.3.4](#calibre_link-1164)。 **Table 9-67\. 咨询锁函数** | 名字 | 返回类型 | 描述 | | --- | --- | --- | | ``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`, 不同之处在于锁,如果得到,是自动在当前事务的结束释放的,而且不能被显式的释放。