合 PG之系统管理函数
系统管理函数
1. 配置设定函数
表 9.77展示了那些可以用于查询以及修改运行时配置参数的函数。
表 9.77. 配置设定函数
名称 | 返回类型 | 描述 |
---|---|---|
current_setting(* setting_name* [, * missing_ok* ]) | text | 获得设置的当前值 |
set_config(* setting_name*, * new_value*, * is_local*) | text | 设置一个参数并返回新值 |
current_setting
得到setting_name
设置的当前值。它对应于SQL命令SHOW
。一个例子:
1 2 3 4 5 6 | SELECT current_setting('datestyle'); current_setting ----------------- ISO, MDY (1 row) |
如果没有名为setting_name
的设置,除非提供missing_ok
并且其值为true
,current_setting
会抛出错误。
set_config
将参数setting_name
设置为new_value
。如果 is_local
设置为true
,那么新值将只应用于当前事务。 如果你希望新值应用于当前会话,那么应该使用false
。 它等效于 SQL 命令 SET
。例如:
1 2 3 4 5 6 | SELECT set_config('log_statement_stats', 'off', false); set_config ------------ off (1 row) |
2. 服务器信号函数
在表 9.78中展示的函数向其它服务器进程发送控制信号。默认情况下这些函数只能被超级用户使用,但是如果需要,可以利用GRANT
把访问特权授予给其他用户。
表 9.78. 服务器信号函数
名称 | 返回类型 | 描述 |
---|---|---|
pg_cancel_backend(* pid* int) | boolean | 取消一个后端的当前查询。如果调用角色是被取消后端的拥有者角色的成员或者调用角色已经被授予pg_signal_backend ,这也是允许的,不过只有超级用户才能取消超级用户的后端。 |
pg_reload_conf() | boolean | 导致服务器进程重载它们的配置文件 |
pg_rotate_logfile() | boolean | 切换服务器的日志文件 |
pg_terminate_backend(* pid* int) | boolean | 中止一个后端。如果调用角色是被取消后端的拥有者角色的成员或者调用角色已经被授予pg_signal_backend ,这也是允许的,不过只有超级用户才能取消超级用户的后端。 |
这些函数中的每一个都在成功时返回true
,并且在失败时返回false
。
pg_cancel_backend
和pg_terminate_backend
向由进程 ID 标识的后端进程发送信号(分别是SIGINT或SIGTERM)。一个活动后端的进程 ID可以从pg_stat_activity
视图的pid
列中找到,或者通过在服务器上列出postgres
进程(在 Unix 上使用ps或者在Windows上使用任务管理器)得到。一个活动后端的角色可以在pg_stat_activity
视图的usename
列中找到。
pg_reload_conf
给服务器发送一个SIGHUP信号, 导致所有服务器进程重载配置文件。
pg_rotate_logfile
给日志文件管理器发送信号,告诉它立即切换到一个新的输出文件。这个函数只有在内建日志收集器运行时才能工作,因为否则就不存在日志文件管理器子进程。 subprocess.
3. 备份控制函数
表 9.79中展示的函数可以辅助制作在线备份。这些函数不能在恢复期间执行(pg_is_in_backup
、pg_backup_start_time
和pg_wal_lsn_diff
除外)。
表 9.79. 备份控制函数
名称 | 返回类型 | 描述 |
---|---|---|
pg_create_restore_point(* name* text) | pg_lsn | 为执行恢复创建一个命名点(默认只限于超级用户,但是可以授予其他用户 EXECUTE 特权来执行该函数) |
pg_current_wal_flush_lsn() | pg_lsn | 得到当前的预写式日志刷写位置 |
pg_current_wal_insert_lsn() | pg_lsn | 获得当前预写式日志插入位置 |
pg_current_wal_lsn() | pg_lsn | 获得当前预写式日志写入位置 |
pg_start_backup(* label* text [, * fast* boolean [, * exclusive* boolean ]]) | pg_lsn | 准备执行在线备份(默认只限于超级用户或者复制角色,但是可以授予其他用户 EXECUTE 特权来执行该函数) |
pg_stop_backup() | pg_lsn | 完成执行排他的在线备份(默认只限于超级用户或者复制角色,但是可以授予其他用户 EXECUTE 特权来执行该函数) |
pg_stop_backup(* exclusive* boolean) | setof record | 结束执行排他或者非排他的在线备份 (默认只限于超级用户,但是可以授予其他用户 EXECUTE 特权来执行该函数) |
pg_is_in_backup() | bool | 如果一个在线排他备份仍在进行中则为真。 |
pg_backup_start_time() | timestamp with time zone | 获得一个进行中的在线排他备份的开始时间。 |
pg_switch_wal() | pg_lsn | 强制切换到一个新的预写式日志文件(默认只限于超级用户,但是可以授予其他用户 EXECUTE 特权来执行该函数) |
pg_walfile_name(* lsn* text) | pg_lsn | 转换预写式日志位置字符串为文件名 |
pg_walfile_name_offset(* lsn* text) | pg_lsn , integer | 转换预写式日志位置字符串为文件名以及文件内的十进制字节偏移 |
pg_wal_lsn_diff(* lsn* pg_lsn, * lsn* pg_lsn) | numeric | 计算两个预写式日志位置间的差别 |
pg_start_backup
接受一个参数,这个参数可以是备份的任意用户定义的标签(通常这是备份转储文件将被存储的名字)。当被用在排他模式中时,该函数向数据库集簇的数据目录写入一个备份标签文件(backup_label
)和一个表空间映射文件(tablespace_map
,如果在pg_tblspc/
目录中有任何链接),执行一个检查点,然后以文本方式返回备份的起始预写式日志位置。用户可以忽略这个结果值,但是为了可能需要的场合我们还是提供该值。 当在非排他模式中使用时,这些文件的内容会转而由pg_stop_backup
函数返回,并且应该由调用者写入到备份中去。
1 2 3 4 5 | 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
创建的tablespace_map
文件(如果存在)。在一次非排他备份中,backup_label
和tablespace_map
的内容会包含在该函数返回的结果中,并且应该被写入到该备份的文件中(这些内容不在数据目录中)。有一个可选的boolean
类型的第二参数。如果为假,pg_stop_backup
将在备份完成后立即返回而不等待WAL被归档。这种行为仅对独立监控WAL归档的备份软件有用。否则,让备份一致所要求的WAL可能会丢失,进而让备份变得毫无用处。当这个参数被设置为真时,在启用归档的前提下pg_stop_backup
将等待WAL被归档,在后备服务器上,这意味只有archive_mode = always
时才会等待。如果主服务器上的写活动很低,在主服务器上运行pg_switch_wal
以触发一次即刻的段切换会很有用。
当在主服务器上执行时,该函数还在预写式日志归档区里创建一个备份历史文件。这个历史文件包含给予pg_start_backup
的标签、备份的起始与终止预写式日志位置以及备份的起始和终止时间。返回值是备份的终止预写式日志位置(同样也可以被忽略)。在记录结束位置之后,当前预写式日志插入点被自动地推进到下一个预写式日志文件,这样结束的预写式日志文件可以立即被归档来结束备份。
pg_switch_wal
移动到下一个预写式日志文件,允许当前文件被归档(假定你正在使用连续归档)。返回值是在甘冈完成的预写式日志文件中结束预写式日志位置 + 1。如果从上一次预写式日志切换依赖没有预写式日志活动,pg_switch_wal
不会做任何事情并且返回当前正在使用的预写式日志文件的开始位置。
pg_create_restore_point
创建一个命名预写式日志记录,它可以被用作恢复目标,并且返回相应的预写式日志位置。这个给定的名字可以用于recovery_target_name来指定恢复要进行到的点。避免使用同一个名称创建多个恢复点,因为恢复会停止在第一个匹配名称的恢复目标。
pg_current_wal_lsn
以上述函数所使用的相同格式显示当前预写式日志的写位置。类似地,pg_current_wal_insert_lsn
显示当前预写式日志插入点,而pg_current_wal_flush_lsn
显示当前预写式日志的刷写点。在任何情况下,插入点是预写式日志的“逻辑”终止点,而写入位置是已经实际从服务器内部缓冲区写出的日志的终止点,刷写位置则是被确保写入到持久存储中的日志的终止点。写入位置是可以从服务器外部检查的终止点,对那些关注归档部分完成预写式日志文件的人来说,这就是他们需要的位置。插入和刷写点主要是为了服务器调试目的而存在的。这些都是只读操作并且不需要超级用户权限。
你可以使用pg_walfile_name_offset
从任何上述函数的结果中抽取相应的预写式日志文件名称以及字节偏移。例如:
1 2 3 4 5 | postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); file_name | file_offset --------------------------+------------- 00000001000000000000000D | 4039624 (1 row) |
相似地,pg_walfile_name
只抽取预写式日志文件名。当给定的预写式日志位置正好在一个预写式日志文件的边界,这些函数都返回之前的预写式日志文件的名称。这对管理预写式日志归档行为通常是所希望的行为,因为前一个文件是当前需要被归档的最后一个文件。
pg_wal_lsn_diff
以字节数计算两个预写式日志位置之间的差别。它可以和pg_stat_replication
或表 9.79中其他的函数一起使用来获得复制延迟。
关于正确使用这些函数的细节,请见第 25.3 节。
4. 恢复控制函数
表 9.80中展示的函数提供有关后备机当前状态的信息。这些函数可以在恢复或普通运行过程中被执行。
表 9.80. 恢复信息函数
名称 | 返回类型 | 描述 |
---|---|---|
pg_is_in_recovery() | bool | 如果恢复仍在进行中,为真。 |
pg_last_wal_receive_lsn() | pg_lsn | 获得最后一个收到并由流复制同步到磁盘的预写式日志位置。当流复制在进行中时,这将单调增加。如果恢复已经完成,这将保持静止在恢复过程中收到并同步到磁盘的最后一个 WAL 记录。如果流复制被禁用,或者还没有被启动,该函数返回 NULL。 |
pg_last_wal_replay_lsn() | pg_lsn | 获得恢复过程中被重放的最后一个预写式日志位置。当流复制在进行中时,这将单调增加。如果恢复已经完成,这将保持静止在恢复过程中被应用的最后一个 WAL 记录。如果服务器被正常启动而没有恢复,该函数返回 NULL。 |
pg_last_xact_replay_timestamp() | timestamp with time zone | 获得恢复过程中被重放的最后一个事务的时间戳。这是在主机上产生的事务的提交或中止 WAL 记录的时间。如果在恢复过程中没有事务被重放,这个函数返回 NULL。否则,如果恢复仍在进行这将单调增加。如果恢复已经完成,则这个值会保持静止在恢复过程中最后一个被应用的事务。如果服务器被正常启动而没有恢复,该函数返回 NULL。 |
表 9.81中展示的函数空值恢复的进程。这些函数只能在恢复过程中被执行。
表 9.81. 恢复控制函数
名称 | 返回类型 | 描述 |
---|---|---|
pg_is_wal_replay_paused() | bool | 如果恢复被暂停,为真。 |
pg_wal_replay_pause() | void | 立即暂停恢复(默认仅限于超级用户, 但是可以授予其他用户 EXECUTE 特权来执行该函数)。 |
pg_wal_replay_resume() | void | 如果恢复被暂停,重启之(默认仅限于超级用户,但是可以授予其他用户 EXECUTE 特权来执行该函数)。 |
在恢复被暂停时,不会有进一步的数据库改变被应用。如果在热备模式,所有新的查询将看到数据库的同一个一致快照,并且在恢复被继续之前不会有更多查询冲突会产生。
如果流复制被禁用,暂停状态可以无限制地继续而不出问题。在流复制进行时,WAL 记录将继续被接收,最后将会填满可用的磁盘空间,取决于暂停的持续时间、WAL 的产生率和可用的磁盘空间。
5. 快照同步函数
PostgreSQL允许数据库会话同步它们的快照。一个快照决定对于正在使用该快照的事务哪些数据是可见的。当两个或者更多个会话需要看到数据库中的相同内容时,就需要同步快照。如果两个会话独立开始其事务,就总是有可能有某个第三事务在两个START TRANSACTION
命令的执行之间提交,这样其中一个会话就可以看到该事务的效果而另一个则看不到。
为了解决这个问题,PostgreSQL允许一个事务导出它正在使用的快照。只要导出的事务仍然保持打开,其他事务可以导入它的快照,并且因此可以保证它们可以看到和第一个事务看到的完全一样的数据库视图。但是注意这些事务中的任何一个对数据库所作的更改对其他事务仍然保持不可见,和未提交事务所作的修改一样。因此这些事务是针对以前存在的数据同步,而对由它们自己所作的更改则采取正常的动作。
如表 9.82中所示,快照通过pg_export_snapshot
函数导出,并且通过SET TRANSACTION命令导入。
表 9.82. 快照同步函数
名称 | 返回类型 | 描述 |
---|---|---|
pg_export_snapshot() | text | 保存当前快照并返回它的标识符 |
函数pg_export_snapshot
保存当前的快照并且返回一个text
串标识该快照。该字符串必须被传递(到数据库外)给希望导入快照的客户端。直到导出快照的事务的末尾,快照都可以被导入。如果需要,一个事务可以导出多于一个快照。注意这样做只在 READ COMMITTED
事务中有用,因为在REPEATABLE READ
和更高隔离级别中,事务在它们的生命期中都使用同一个快照。一旦一个事务已经导出了任何快照,它不能使用PREPARE TRANSACTION。
关于如何使用一个已导出快照的细节请见SET TRANSACTION.
6. 复制函数
表 9.83中展示的函数 用于控制以及与复制特性交互。有关底层特性的信息请见 第 26.2.5 节、 第 26.2.6 节以及 第 50 章。这些函数只限于超级 用户使用。
很多这些函数在复制协议中都有等价的命令,见 第 53.4 节。
第 9.26.3 节、 第 9.26.4 节和 第 9.26.5 节 中描述的函数也与复制相关。
表 9.83. 复制 SQL 函数
函数 | 返回类型 | 描述 |
---|---|---|
pg_create_physical_replication_slot(* slot_name*name [, * immediately_reserve* boolean ]) | (slot_name name , xlog_position pg_lsn ) | 创建一个新的名为slot_name 的物理复制槽。第二个参数是可选的,当它为true 时,立即为这个物理槽指定要被保留的LSN。否则该LSN会被保留在来自一个流复制客户端的第一个连接上。来自一个物理槽的流改变只可能出现在使用流复制协议时 — 见第 53.4 节。当可选的第三参数temporary 被设置为真时,指定那个槽不会被持久地存储在磁盘上并且仅对当前会话的使用有意义。临时槽也会在发生任何错误时被释放。这个函数对应于复制协议命令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 , lsn pg_lsn ) | 使用输出插件plugin 创建一个名为 slot_name 的新逻辑(解码)复制槽。当可选的第三参数temporary 被设置为真时,指定那个槽不会被持久地存储在磁盘上并且仅对当前会话的使用有意义。临时槽也会在发生任何错误时被释放。对这个函数的调用与复制协议命令 CREATE_REPLICATION_SLOT ... LOGICAL 具有相同的效果。 |
pg_logical_slot_get_changes(* slot_name* name, * upto_lsn* pg_lsn, * upto_nchanges* int, VARIADIC * options* text[]) | (lsn pg_lsn , xid xid , data text ) | 返回槽slot_name 中的改变,从上一次已经被消费的点开始返回。 如果upto_lsn 和upto_nchanges 为 NULL,逻辑解码将一 直继续到 WAL 的末尾。如果upto_lsn 为非 NULL,解码将只包括那些在指 定 LSN 之前提交的事务。如果upto_nchanges 为非 NULL, 解码将在其产生的行数超过指定值后停止。不过要注意, 被返回的实际行数可能更大,因为对这个限制的检查只会在增加了解码每个新的提交事务产生 的行之后进行。 |
pg_logical_slot_peek_changes(* slot_name* name, * upto_lsn* pg_lsn, * upto_nchanges* int, VARIADIC * options* text[]) | (lsn 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[]) | (lsn 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[]) | (lsn pg_lsn , xid xid , data bytea ) | 行为就像pg_logical_slot_get_changes() 函数, 不过改变会以bytea 返回并且这些改变不会被消费, 即在未来的调用中还会返回这些改变。 |
pg_replication_slot_advance(* slot_name* name, * upto_lsn* pg_lsn) | (slot_name name , end_lsn pg_lsn ) bool | 名为slot_name 的复制槽的当前确认位置的增长。该槽将不会被反向移动,且它将不会被移动到超过当前插入位置的地方。返回该槽的名称以及它被推进到的真实位置。 |
pg_replication_origin_create(* node_name* text) | oid | 用给定的外部名称创建一个复制源,并且返回分配给它的内部 id。 |
pg_replication_origin_drop(* node_name* text) | void | 删除一个之前创建的复制源,包括任何相关的重放进度。 |
pg_replication_origin_oid(* node_name* text) | oid | 用名称查找复制源并且返回内部 id。如果没有找到则抛出错误。 |
pg_replication_origin_session_setup(* node_name*text) | void | 把当前会话标记为正在从给定的源进行重放,允许重放进度被跟踪。使用 pg_replication_origin_session_reset 可以取消 标记。只有之前没有源被配置时才能使用。 |
pg_replication_origin_session_reset() | void | 取消pg_replication_origin_session_setup() 的效果。 |
pg_replication_origin_session_is_setup() | bool | 当前会话中是否已经配置了一个复制源? |
pg_replication_origin_session_progress(* flush*bool) | pg_lsn | 返回当前会话中配置的复制源的重放位置。参数 flush 决定对应的本地事务是否被确保 已经刷入磁盘。 |
pg_replication_origin_xact_setup(* origin_lsn*pg_lsn, * origin_timestamp* timestamptz) | void | 标记当前事务为正在重放一个已经在给定的LSN 和时间戳提交的事务。只有当之前已经用 pg_replication_origin_session_setup() 配置过 一个复制源时才能被调用。 |
pg_replication_origin_xact_reset() | void | 取消pg_replication_origin_xact_setup() 的效果。 |
pg_replication_origin_advance(* node_name* text, * pos* pg_lsn) | void | 把给定节点的复制进度设置为给定的位置。这主要用于配置更改或者类似 操作之后设置初始位置或者新位置。注意这个函数的不当使用可能会导致 不一致的复制数据。 |
pg_replication_origin_progress(* node_name*text, * flush* bool) | pg_lsn | 返回给定复制元的重放位置。参数 flush 决定对应的本地事务是否被确保 已经刷入磁盘。 |
pg_logical_emit_message(* transactional* bool, * prefix* text, * content* text) | pg_lsn | 发出文本形式的逻辑解码消息。这可以被用来通过 WAL 向逻辑解码插件传递一般消息。参数transactional 指定该消息是否应该是当前事务的一部分或者当逻辑解码读到该记录时该消息是否应该被立刻写入并且解码。prefix 是逻辑解码插件用来识别它们感兴趣的消息的文本前缀。content 是消息的文本。 |
pg_logical_emit_message(* transactional* bool, * prefix* text, * content* bytea) | pg_lsn | 发出二进制逻辑解码消息。这可以被用来通过WAL向逻辑解码插件传递一般性消息。参数transactional 指定该消息是否应该成为当前事务的一部分或者是否应该在逻辑解码过程读到该记录时立刻进行写入和解码。参数prefix 是一个逻辑解码插件使用的文本前缀,逻辑解码插件用它来识别感兴趣的消息。参数content 是消息的二进制内容。 |
7. 数据库对象管理函数
表 9.84中展示的函数计算数据库对象使用的磁盘空间。
表 9.84. 数据库对象尺寸函数
名称 | 返回类型 | 描述 |
---|---|---|
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_bytes(text) | bigint | 把人类可读格式的带有单位的尺寸转换成字节数 |
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
接受一个表或 TOAST 表的 OID 或名称,并返回该表所使用的总磁盘空间,包括所有相关的索引。这个函数等价于pg_table_size
+
pg_indexes_size
。