这一部分包含PostgreSQL服务器应用和支持工具的参考信息。这些命令只在数据库服务器所在的主机上运行才有用。
1、initdb
initdb — 创建一个新的PostgreSQL数据库集簇
大纲
initdb [option...] [ --pgdata | -D ] directory
描述
initdb创建一个新的PostgreSQL数据库集簇。一个数据库集簇是由一个单一服务器实例管理的数据库的集合。
一个数据库集簇的创建包括创建存放数据库数据的目录、生成共享目录表(属于整个集簇而不是任何特定数据库的表)并且创建template1和postgres数据库。当你后来创建一个新的数据库时,任何在template1数据库中的东西都会被复制(因此,任何已安装在template1中的东西都会被自动地复制到后来创建的每一个数据库中)。postgres数据库是便于用户、工具和第三方应用使用的默认数据库。
尽管initdb将尝试创建指定的数据目录,它可能没有权限(如果想要的数据目录的父目录被根用户拥有)。要在这样一种设置中初始化,作为 root 创建一个空数据目录,然后使用chown将该目录赋予给数据库用户账户,再然后su成为该数据库用户并运行initdb。
initdb必须以将拥有该服务器进程的用户运行,因为该服务器需要访问initdb创建的文件和目录。因为该服务器不能作为 root 运行,你不能以 root 运行initdb(事实上它会拒绝这样做)。
由于安全原因,由initdb创建的新集簇默认将只能由集簇拥有者访问。--allow-group-access选项允许与集簇拥有者同组的任何用户读取集簇中的文件。这对非特权用户执行备份很有用。
initdb初始化该数据库集簇的默认区域和字符集编码。当一个数据库被创建时,其字符集编码、排序顺序(LC_COLLATE)和字符集类(LC_CTYPE,例如大写、小写、数字)可以被独立设置。initdb为template1数据库确定那些设置,它们将作为所有其他数据库的默认值。
要修改默认排序顺序或字符集类,使用--lc-collate和--lc-ctype选项。除C或POSIX之外的排序顺序也有性能罚值。由于这些原因,在运行initdb时选择正确的区域很重要。
余下的区域分类可以在服务器启动之后改变。你也可以使用--locale来为所有区域分类设置默认值,包括排序顺序和字符集类。所有服务器区域值(lc_*)可以通过SHOW ALL显示。
要修改默认编码,使用--encoding。
选项
-A authmethod--auth=authmethod
这个选项为本地用户指定在pg_hba.conf中使用的默认认证方法(host和local行)。initdb将使用指定的认证方法为非复制连接以及复制连接填充pg_hba.conf项。
除非你信任你系统上的所有本地用户,不要使用trust。为了安装方便,trust是默认值。
--auth-host=authmethod
这个选项为通过 TCP/IP 连接的本地用户指定在pg_hba.conf中使用的认证方法(host行)。
--auth-local=authmethod
这个选项为通过 Unix 域套接字连接的本地用户指定在pg_hba.conf中使用的认证方法(local行)。
-D directory--pgdata=directory
这个选项指定数据库集簇应该存放的目录。这是initdb要求的唯一信息,但是你可以通过设定PGDATA环境变量来避免书写它,这很方便因为之后数据库服务器(postgres)可以使用同一个变量来找到数据库目录。
-E encoding--encoding=encoding
选择模板数据库的编码。这也将是后来创建的任何数据库的默认编码,除非你覆盖它。默认值来自于区域,或者如果该值不起作用则为SQL_ASCII。
-g--allow-group-access
允许与集簇拥有者同组的用户读取initdb创建的所有集簇文件。 Windows会忽略此选项,因为它不支持POSIX样式的组权限。
-k--data-checksums
在数据页面上使用校验码来帮助检测 I/O 系统造成的损坏。启用校验码将会引起显著的性能惩罚。这个选项只能在初始化期间被设置,并且以后不能修改。如果被设置,在所有数据库中会为所有对象计算校验码。
--locale=locale
为数据库集簇设置默认区域。如果这个选项没有被指定,该区域将从initdb所运行的环境中继承。
--lc-collate=locale--lc-ctype=locale--lc-messages=locale--lc-monetary=locale--lc-numeric=locale--lc-time=locale
和--locale相似,但是只在指定的分类中设置区域。
--no-locale
等效于--locale=C。
-N--no-sync
默认情况下,initdb将等待所有文件被安全地写到磁盘。这个选项会导致initdb不等待就返回,这当然更快,但是也意味着一次后续的操作系统崩溃可能让数据目录损坏。通常,这个选项对测试有用,但是不应该在创建生产安装时使用。
--pwfile=filename
让initdb从一个文件读取数据库超级用户的口令。该文件的第一行被当作口令。
-S--sync-only
安全地把所有数据库文件写入到磁盘并退出。这不会执行任何正常的initdb操作。
-T config--text-search-config=config
设置默认的文本搜索配置。详见default_text_search_config。
-U username--username=username
选择数据库超级用户的用户名。这个的默认值是实际运行initdb的用户的名称。超级用户的名字是什么真的不重要,但是你可以选择保留常用的名字postgres,即使操作系统的用户名不同。
-W--pwprompt
让initdb提示要求为数据库超级用户给予一个口令。如果你没有计划使用口令认证,这就不重要。否则在你设置一个口令之前你就无法使用口令认证。
-X directory--waldir=directory
这个选项指定预写式日志会被存储在哪个目录中。
--wal-segsize=size
设置WAL段尺寸,以兆字节为单位。这是WAL日志中每个文件的尺寸。默认的尺寸为16兆字节。该值必须位于2的1次幂和1024次幂(兆字节)之间。这个选项只能在初始化期间设置,并且之后不能更改。
调整这个值来控制WAL日志传送或者归档可能会有用。此外,在有大量WAL的数据库中,每个目录中数量巨大的WAL文件可能会成为性能和管理问题。增加WAL文件尺寸将会降低WAL文件的数量。
其他较少使用的选项:
-d--debug
打印来自引导后端的调试输出以及普通大众不那么感兴趣的一些消息。引导后端被程序initdb用来创建目录表。这个选项会生成大量极端无聊的输出。
-L directory
指定initdb应从哪里寻找它的输入文件来初始化数据库集簇。这通常没有必要。如果你需要显式指定它们的位置,你应该被告知。
-n--no-clean
默认情况下,当initdb确定有一个错误阻止它完整地创建数据库集簇,它会移除在它发现无法完成任务之前创建的任何文件。这个选项会抑制这种整理并且对调试有用。
其他选项:
-V--version
打印initdb版本并退出。
-?--help
显示有关initdb命令行参数的帮助并退出。
环境
PGDATA
指定数据库集簇应该被存放的目录,可以使用-D选项覆盖。
TZ
指定创建的数据集簇的默认时区。值应该是一个完整的时区名称。
和大部分其他PostgreSQL工具相似,这个工具也使用libpq支持的环境变量。
注解
initdb可以通过pg_ctl initdb被调用。
2、pg_archivecleanup
pg_archivecleanup — 清理PostgreSQL WAL 归档文件
大纲
pg_archivecleanup [option...] archivelocation oldestkeptwalfile
简介
pg_archivecleanup被设计用作 archive_cleanup_command在作为后备服务器运行时来清理 WAL 文件归档。 pg_archivecleanup也可以被用作一个单独的程序来清理 WAL 文件归档。
要配置一个后备服务器以使用pg_archivecleanup,把下面 的内容放在recovery.conf配置文件中:
archive_cleanup_command = 'pg_archivecleanup archivelocation %r'
其中archivelocation是要从中移除 WAL 段文件的目录。
当被用在archive_cleanup_command中时,所有逻辑上在 %r参数的值之前的 WAL 文件都将被从 archivelocation移除。这能最小化需要被保留的文件数量, 同时能保留崩溃后重启的能力。如果对于这台特定的后备服务器, archivelocation是一个短暂需要的区域,使用这个参数就是 合适的,但是当archivelocation要用作一个长期的 WAL 归档 区域或者当多个后备服务器正在从这个归档位置恢复时,使用这个参数就 不合适。
当被用作一个单独的程序时,所有逻辑上在oldestkeptwalfile 之前的 WAL 文件将被从archivelocation中移除。在这种模式 中,如果指定了.partial或者.backup文件名,则 只有该文件前缀将被用作oldestkeptwalfile。这种对 .backup文件名的处理允许你移除所有在一个特定基础备份之前归 档的 WAL 文件而不出错。例如,下面的例子将移除所有比 WAL 文件名 000000010000003700000010老的文件:
pg_archivecleanup -d archive 000000010000003700000010.00000020.backup
pg_archivecleanup: keep WAL file "archive/000000010000003700000010" and later
pg_archivecleanup: removing file "archive/00000001000000370000000F"
pg_archivecleanup: removing file "archive/00000001000000370000000E"
pg_archivecleanup假定 archivelocation是一个可读的目录并且对于服务器拥有者是可写的。
选项
pg_archivecleanup接受下列命令行参数:
-d
在stderr上打印很多调试日志输出。
-n
在stdout上打印将被移除的文件的名字(执行一次演习)。
-V--version
打印pg_archivecleanup版本并退出。
-x extension
提供一个扩展名,在决定所有的文件 是否应该被删除之前,将从文件名中剥离这个扩展名。这通常有助于清理已经 存储期间被压缩过并且被压缩程序增加了一个扩展名的归档。例如: -x .gz。
-?--help
显示pg_archivecleanup命令行参数的帮助并退出。
注解
在作为一个单独的工具时,pg_archivecleanup 被设计为与PostgreSQL 8.0 及其后的版本一起工作。如果 作为一个归档清理命令使用,则需要和PostgreSQL 9.0 及 其后的版本一起工作。
pg_archivecleanup以 C 写成并且具有很容易修改的 源代码,其中有特别指定的区域用于修改以符合你的需要
示例
在 Linux 或者 Unix 系统上,你可能会用:
archive_cleanup_command = 'pg_archivecleanup -d /mnt/standby/archive %r 2>>cleanup.log'
其中归档目录位于后备服务器上,这样archive_command通过 NFS 来访问它,但是文件对于后备服务器来说是本地的。这将会
-
在
cleanup.log中产生调试输出 -
从归档目录中移除不再需要的文件
3、pg_controldata
pg_controldata — 显示一个PostgreSQL数据库集簇的控制信息
大纲
pg_controldata [option] [[ --pgdata | -D ] datadir]
描述
pg_controldata打印在initdb期间初始化的信息,例如目录版本。它也显示关于预写式日志和检查点处理的信息。这种信息是集簇范围的,并且不针对任何一个数据库。
这个工具只能由初始化集簇的用户运行,因为它要求对数据目录的读访问。你可以在命令行中指定数据目录,或者使用环境变量PGDATA。这个工具支持选项-V和--version,它们打印pg_controldata版本并退出。它也支持选项-?和--help,它们输出支持的参数。
环境
PGDATA
默认的数据目录位置。
4、pg_ctl
pg_ctl — 初始化、启动、停止或控制一个PostgreSQL服务器
大纲
pg_ctl init[db] [-D datadir] [-s] [-o initdb-options]
pg_ctl start [-D datadir] [-l filename] [-W] [-t seconds] [-s] [-o options] [-p path] [-c]
pg_ctl stop [-D datadir] [-m s[mart] | f[ast] | i[mmediate] ] [-W] [-t seconds] [-s]
pg_ctl restart [-D datadir] [-m s[mart] | f[ast] | i[mmediate] ] [-W] [-t seconds] [-s] [-o options] [-c]
pg_ctl reload [-D datadir] [-s]
pg_ctl status [-D datadir]
pg_ctl promote [-D datadir] [-W] [-t seconds] [-s]
pg_ctl kill signal_name process_id
在Microsoft Windows上,还有:
pg_ctl register [-D datadir] [-N servicename] [-U username] [-P password] [-S a[uto] | d[emand] ] [-e source] [-W] [-t seconds] [-s] [-o options]
pg_ctl unregister [-N servicename]
描述
pg_ctl是一个用于初始化PostgreSQL数据库集簇,启动、停止或重启PostgreSQL数据库服务器(postgres),或者显示一个正在运行服务器的状态的工具。尽管服务器可以被手工启动,pg_ctl包装了重定向日志输出以及正确地从终端和进程组脱离等任务。它也提供了方便的选项用来控制关闭。
init或initdb模式会创建一个新的PostgreSQL数据库集簇,也就是将由一个单一服务器实例管理的数据库集合。这个模式调用initdb命令。详见initdb。
start模式启动一个新的服务器。该服务器被启动在后台,并且它的标准输出被附加到/dev/null(或 Windows 上的nul)。在 Unix 类系统上,默认情况下服务器的标准输出和标准错误被发送到pg_ctl的标准输出(不是标准错误)。pg_ctl的标准输出应该接着被重定向到一个文件或用管道导向另一个进程(例如日志轮转程序rotatelogs)。否则postgres将把它的输出写到控制终端(从后台)并且将不会离开 shell 的进程组。在 Windows 上,默认情况下服务器的标准输出和标准错误被发送到终端。这些默认行为可以使用-l追加服务器的输出到一个日志文件来改变。我们推荐使用-l或输出重定向。
stop模式关闭运行在指定数据目录中的服务器。对-m选项可以选择三种不同的关闭方法。“Smart”模式等待所有客户端断开连接以及任何在线备份结束。如果该服务器是热备,一旦所有的客户端已经断开连接,恢复和流复制将被终止。“Fast”模式(默认)不会等待客户端断开连接并且将终止进行中的在线备份。所有活动事务都被回滚并且客户端被强制断开连接,然后服务器被关闭。“Immediate”模式将立刻中止所有服务器进程,而不是做一次干净的关闭。这中选择将导致下一次重启时进行一次崩溃恢复。
restart模式实际上会先执行一个停止操作然后紧接着执行一个启动操作。这使得我们能够更改postgres的命令行选项,或者更改不通过重启服务器无法更改的配置文件选项。如果在服务器启动期间在命令行上使用了相对路径,则restart可能会失败,除非pg_ctl被运行在与上次启动服务器相同的目录中。
reload模式简单地向postgres服务器进程发送一个SIGHUP信号,导致它重新读取它的配置文件(postgresql.conf、pg_hba.conf等)。这允许改变配置文件选项而无需一次完整的服务器重启来让改变生效。
status模式检查一个服务器是否运行在指定的数据目录中。如果有一个服务器正在运行,其PID和用来调用它的命令行选项将被显示。如果服务器没有在运行,pg_ctl将返回退出状态 3。如果没有指定一个可以访问的数据目录,pg_ctl将返回退出状态 4。
promote模式命令运行在指定数据目录中的后备服务器结束后备模式并且开始读写操作。
kill模式向一个指定进程发送一个消息。这主要用于没有kill命令的Microsoft Windows。使用--help来查看受支持的信号名称列表。
register模式把PostgreSQL服务器注册为Microsoft Windows上的一个系统服务。-S选项允许选择服务启动类型,可以是“auto”(随系统自动启动)或“demand”(按需启动)。
unregister模式在Microsoft Windows上移除一个系统服务的注册。这会撤销register命令的效果。
选项
-c--core-files
在可行的平台上尝试允许服务器崩溃产生核心文件,方法是提升在核心文件上的任何软性资源限制。这通过允许从一个失败的服务器进程中获得一个栈跟踪而有助于调试或诊断问题。
-D datadir--pgdata=datadir
指定数据库配置文件的文件系统位置。如果这个选项被忽略,将使用环境变量PGDATA。
-l filename--log=filename
追加服务器日志输出到filename。如果该文件不存在,它会被创建。umask被设置成 077,这样默认情况下不允许其他用户访问该日志文件。
-m mode--mode=mode
指定关闭模式。mode可以是smart、fast或immediate,或者这三者之一的第一个字母。如果这个选项被忽略,则fast是默认值。
-o options--options=options
指定被直接传递给postgres命令的选项。-o可以被指定多次,所有给定的选项都会被传过去。
这些选项应该通常被单引号或双引号包围来确保它们被作为一个组传递。
-o initdb-options--options=initdb-options
指定要直接传递给initdb命令的选项。-o可以被指定多次,所有给定的选项都会被传过去。
这些选项应该通常被单引号或双引号包围来确保它们被作为一个组传递。
-p path
指定postgres可执行程序的位置。默认情况下,postgres可执行程序可以从pg_ctl相同的目录得到,或者如果没有在那里找到,则在硬写的安装目录中获得。除非你正在做一些不同寻常的事并且得到错误说没有找到postgres可执行程序,这个选项不是必需的。
在init模式中,这个选项类似于指定了initdb可执行程序的位置。
-s--silent
只打印错误,不打印信息性的消息。
-t seconds--timeout=seconds
指定等待一个操作完成时要等待的最大秒数(见选项-w)。默认为PGCTLTIMEOUT环境变量的值,如果该环境变量没有设置则默认为60秒。
-V--version
打印pg_ctl版本并退出。
-w--wait
等待操作完成。模式start、stop、restart、promote以及register支持这个选项,并且对那些模式是默认的。
在等待时,pg_ctl会一遍又一遍地检查服务器的PID文件,在两次检查之间会休眠一小段时间。当PID文件指示该服务器已经做好准备接受连接时,启动操作被认为完成。当服务器移除PID文件时,关闭操作被认为完成。pg_ctl会基于启动或关闭的成功与否返回一个退出代码。
如果操作在超时时间(见选项-t)内未能完成,则pg_ctl会以一个非零退出状态退出。但是注意该操作可能会在后台继续进行并且最终取得成功。
-W--no-wait
不等待操作完成。这是选项-w的对立面。
如果禁用等待,所请求的动作会被触发,但是不会有关于其成功与否的反馈。在这种情况下,可能必须用服务器日志文件或外部监控系统来检查该操作的进度以及成功与否。
在以前版本的PostgreSQL中,这是除stop模式之外的模式的默认选项。
-?--help
显示有关pg_ctl命令行参数的帮助并退出。
如果一个指定的选项有效,但与选中的操作模式无关,则pg_ctl会忽略它。
用于 Windows 的选项
-e source
作为一个 Windows 服务运行时,pg_ctl用来 在事件日志中记录日志的事件源的名称。默认是PostgreSQL。 注意这只控制由pg_ctl本身发送的消息,一旦开始, 服务器将使用event_source参数中指定的事件源。如果服务器在启动时很早(在该参数被设置前)就失败,它可能也会使用默认的事件源名称 PostgreSQL来记录。
-N servicename
要注册的系统服务的名称。这个名称将被用于服务名和显示名。默认是PostgreSQL。
-P password
用于运行该服务的用户的口令。
-S start-type
要注册的系统服务的启动类型。启动类型可以是auto、demand或者两者之一的第一个字母。如果这个选项被忽略,则auto是默认值。
-U username
用于运行该服务的用户的用户名。对于域用户,使用格式DOMAIN\username。
环境
PGCTLTIMEOUT
等待启动或者关闭完成时要等待的默认秒数限制。如果没有设置, 默认值是 60 秒。
PGDATA
默认的数据目录位置。
大部分的pg_ctl模式都要求知道数据目录的位置,因此-D选项是必需的,除非PGDATA被设置。
和大部分其他PostgreSQL工具相似,pg_ctl也使用libpq支持的环境变量。
更多影响服务器的变量请见postgres。
文件
postmaster.pid
pg_ctl在数据目录中检查这个文件来判断服务器当前是否正在运行。
postmaster.opts
如果这个文件存在于数据目录中,pg_ctl(处于restart模式中)将把该文件的内容作为选项传递给postgres,除非通过-o选项进行了覆盖。这个文件的内容也会被显示在status模式中。
例子
启动服务器
要启动服务器并且等到服务器接受连接:
$ pg_ctl start
要使用端口 5433 启动服务器并且运行时不使用fsync:
$ pg_ctl -o "-F -p 5433" start
停止服务器
要停止服务器,使用:
$ pg_ctl stop
-m选项允许控制服务器如何关闭:
$ pg_ctl stop -m smart
重启服务器
重启服务器几乎等价于停止服务器并且再次启动它,不过pg_ctl默认会保存并重用被传递给之前的运行实例的命令行选项。要以和之前相同的选项重启服务器,使用:
$ pg_ctl restart
但是如果指定了-o,则会替换任何之前的选项。要使用端口 5433 重启并在重启时禁用fsync:
$ pg_ctl -o "-F -p 5433" restart
显示服务器状态
这里是pg_ctl状态输出的例子:
$ pg_ctl status
pg_ctl: server is running (PID: 13718)
/usr/local/pgsql/bin/postgres "-D" "/usr/local/pgsql/data" "-p" "5433" "-B" "128"
第二行是在重启模式可能被调用的命令行。
5、pg_resetwal
pg_resetwal — 重置一个PostgreSQL数据库集簇的预写式日志以及其他控制信息
大纲
pg_resetwal [ --force | -f ] [ --dry-run | -n ] [option...] [ --pgdata | -D ] datadir
描述
pg_resetwal会清除预写式日志(WAL)并且有选择地重置存储在pg_control文件中的一些其他控制信息。如果这些文件已经被损坏,某些时候就需要这个功能。当服务器由于这样的损坏而无法启动时,这只应该被用作最后的手段。
在运行这个命令之后,就可能可以启动服务器,但是记住数据库可能包含由于部分提交事务产生的不一致数据。你应当立刻转储你的数据、运行initdb并且重新载入。重新载入后,检查不一致并且根据需要修复之。
这个工具只能被安装服务器的用户运行,因为它要求对数据目录的读写访问。出于安全原因,你必须在命令行中指定数据目录。pg_resetwal不使用环境变量PGDATA。
如果pg_resetwal抱怨它无法为pg_control决定合法数据,你可以通过指定-f(强制)选项强制它继续。在这种情况下,丢失的数据将被替换为看似合理的值。可以期望大部分域是匹配的,但是下一个 OID、下一个事务 ID 和纪元、下一个多事务 ID 和偏移以及 WAL 开始位置域可能还是需要人工协助。这些域可以使用下面讨论的选项设置。如果你不能为所有这些域决定正确的值,-f还是可以被使用,但是恢复的数据库还是值得怀疑:一次立即的转储和重新载入是势在必行的。在你转储之前不要在该数据库中执行任何数据修改操作,因为任何这样的动作都可能使破坏更严重。
选项
-f--force
即使pg_resetwal无法从pg_control中确定有效的数据(如前面所解释的),也强迫pg_resetwal继续运行。
-n--dry-run
-n/--dry-run选项指示pg_resetwal打印从pg_control重构出来的值以及要被改变的值,然后不修改任何东西退出。这主要是一个调试工具,但是可以用来在允许pg_resetwal真正执行下去之前进行完整性检查。
-V--version
显示版本信息然后退出。
-?--help
显示帮助然后退出。
只有当pg_resetwal无法通过读取pg_control确定合适的值时,才需要下列选项。安全值可以按下文所述来确定。对于接收数字参数的值,可以使用前缀0x指定 16 进制值。
-c xid,xid--commit-timestamp-ids=xid,xid
手工设置提交时间可以检索到的最老的和最新的事务 ID。
能检索到提交时间的最老事务 ID 的安全值(第一部分)可以通过在数据目录下pg_commit_ts目录中数字上最小的文件名来决定。反过来,能检索到提交时间的最新事务 ID 的安全值(第二部分)可以通过同一个目录中数字上最大的文件名来决定。文件名都是十六进制的。
-e xid_epoch--epoch=xid_epoch
手工设置下一个事务 ID 的 epoch。
事务 ID 的 epoch 实际上并没有存储在数据库中的任何地方,除了被pg_resetwal设置在这个域中,所以只要关心的是数据库本身,任何值都可以用。你可能需要调整这个值来确保诸如Slony-I和Skytools之类的复制系统正确地工作 — 如果确实需要调整,应该可以从下游的复制数据库的状态中获得一个合适的值。
-l walfile--next-wal-file=walfile
通过指定下一个WAL段文件名称来手工设置WAL开始位置。
下一个WAL段文件的名称应该比当前存在于数据目录下pg_wal目录中的任意 WAL 段文件名更大。这些名称也是十六进制的并且有三个部分。第一部分是“时间线 ID”并且通常应该被保持相同。例如,如果00000001000000320000004A是pg_wal中最大的项,则使用-l 00000001000000320000004B或更高的值。
注意在使用非默认WAL段尺寸时,WAL文件名中的数字与系统函数和系统视图报告的LSN不同。这个选项要的是WAL文件名而不是LSN。
注意:
pg_resetwal本身查看pg_wal中的文件并选择一个超出最新现存文件名的默认-l设置。因此,只有当你知道 WAL 段文件当前不在pg_wal中时,或者当pg_wal的内容完全丢失时,才需要对-l的手工调整,例如一个离线归档中的项。
-m mxid,mxid--multixact-ids=mxid,mxid
手工设置下一个和最老的多事务 ID。
确定下一个多事务 ID(第一部分)的安全值的方法:在数据目录下的pg_multixact/offsets目录中查找最大的数字文件名,然后在它的基础上加一并且乘以 65536 (0x10000)。反过来,确定最老的多事务 ID(-m的第二部分)的方法:在同一个目录中查找最小的数字文件名并且乘以 65536。文件名是十六进制的数字,因此实现上述方法最简单的方式是以十六进制指定选项值并且追加四个零。
-o oid--next-oid=oid
手工设置下一个 OID。
没有相对容易的方法来决定超过数据库中最大 OID 的下一个 OID。但幸运的是正确地得到下一个 OID 设置并不是决定性的。
-O mxoff--multixact-offset=mxoff
手工设置下一个多事务偏移量。
确定安全值的方法:查找数据目录下pg_multixact/members目录中最大的数字文件名,然后在它的基础上加一并且乘以 52352 (0xCC80)。文件名是十六进制数字。没有像其他选项那样追加零的简单方法。
--wal-segsize=wal_segment_size
设置新的WAL段尺寸,以兆字节为单位。这个值必须被设为2的1次幂和1024次幂(兆字节)之间。更多信息请参考initdb的相同选项。
注意:
虽然
pg_resetwal将把WAL起始地址设置成超过最新的现有WAL段文件,但一些段尺寸的改变可能导致之前的WAL文件名被重用。如果WAL文件名重叠会导致归档策略出现问题,推荐把-l和这个选项一起使用来手动设置WAL起始地址。
-x xid--next-transaction-id=xid
手工设置下一个事务 ID。
确定安全值的方法:在数据目录下的pg_xact目录中查找最大的数字文件名,然后在它的基础上加一并且乘以 1048576 (0x100000)。注意文件名是十六进制的数字。通常以十六进制的形式指定该选项值也是最容易的。例如,如果0011是pg_xact中的最大项,-x 0x1200000就可以(五个尾部的零就表示了前面说的乘数)。
注解
这个命令不能在服务器正在运行时被使用。如果在数据目录中发现一个服务器锁文件,pg_resetwal将拒绝启动。如果服务器崩溃那么一个锁文件可能会被留下,在那种情况下你能移除该锁文件来让pg_resetwal运行。但是在你那样做之前,再次确认没有服务器进程仍然存活。
pg_resetwal仅能在具有相同主版本的服务器上使用。
6、pg_rewind
pg_rewind — 把一个PostgreSQL数据目录与另一个从该目录中复制出来的数据目录同步
大纲
pg_rewind [option...] { -D | --target-pgdata } directory { --source-pgdata=directory | --source-server=connstr }
简介
pg_rewind是用于在集簇的时间线分叉以后,同步一个 PostgreSQL 集簇和同一集簇的另一份拷贝的工具。一种典型的场景是在失效后让一个旧的主服务器重新上线,同时有一个后备机跟随着新的主机。
其结果等效于把目标数据目录替换成源数据目录。关系文件中只有更改过的块才会被拷贝,所有其他的文件会被整个拷贝,包括配置文件。pg_rewind比起做一个新的基础备份或者rsync等工具的优势在于,pg_rewind不要求通读集簇中未更改的块。这使得它在数据库很大并且在集簇间只有小部分块不同时速度很快。
pg_rewind检查源集簇和目标集簇的时间线历史来判断它们在哪一点分叉,并且期望在目标集簇的pg_wal目录中找到 WAL 来返回到分叉点。分叉点可能会在目标时间线、源时间线或者它们的共同祖先上找到。在典型的失效场景中,目标集簇在分叉后很快就被关闭,这不是问题,但是如果目标集簇在分叉后已经运行了很长时间,旧的 WAL 文件可能已经不存在了。在这样的情况下,它们可以被手工从 WAL 归档复制到pg_wal目录,或者通过配置recovery.conf在启动时取得。pg_rewind的使用并不限于失效的场景,例如一个后备服务器可能被提升、运行一些写事务,然后被倒回再次成为一个后备。
当目标服务器在运行了pg_rewind之后第一次启动时,它将进入到恢复模式并且重放源服务器在分叉点之后产生的所有 WAL。当pg_rewind被运行时有某些 WAL 在源服务器上不可用,并且因此无法被pg_rewind会话所复制,则在目标服务器被启动时必须让这些 WAL 可用。这可以通过在目标数据目录中创建一个recovery.conf文件并且在其中使用一个适当的restore_command来实现。
pg_rewind要求目标服务器在postgresql.conf中启用了wal_log_hints选项,或者在用initdb初始化集簇时启用了数据校验。目前默认情况下这两者都没有被打开。full_page_writes也必须被设置为on,这是默认的。
警告:
如果在处理时pg_rewind失败,则目标的数据目录很可能不在可恢复的状态。在这种情况下,推荐创建一个新的备份。
如果pg_rewind发现它无法直接写入的文件,它将立刻失败。例如当源服务器和目标服务器为只读的SSL密钥及证书使用相同的文件映射,就会发生这种情况。如果在目标服务器上存在这样的文件,推荐在运行pg_rewind之前移除它们。在做了rewind之后,一些那样的文件可能已经被从源服务器拷贝,这样就有必要移除已经拷贝的数据并且恢复到rewind之前使用的链接集合。
选项
pg_rewind接受下列命令行参数:
-D directory--target-pgdata=directory
这个选项指定要与源数据目录同步的目标数据目录。在运行pg_rewind之前目标服务器必须被干净地关闭。
--source-pgdata=directory
指定要和目标服务器同步的源服务器的数据目录的文件系统路径。这个选项要求源服务器必须被干净地关闭。
--source-server=connstr
指定一个 libpq 连接串用于连接要与目标服务器同步的源PostgreSQL服务器。该连接必须是一个具有超级用户访问权限的普通(非复制)连接。这个选项要求源服务器正在运行且不处于恢复模式。
-n--dry-run
做除了实际修改目标目录之外的其他所有事情。
-P--progress
启用进度报告。在从源集簇拷贝数据时,打开这个选项将会发送一个近似的进度报告。
--debug
打印冗长的调试输出,这主要对于调试pg_rewind的开发者有用。
-V--version
显示版本信息然后退出。
-?--help
显示帮助然后退出。
环境
在使用--source-server选项时,pg_rewind也使用libpq支持的环境变量。
注解
如何工作
其基本思想是从源集簇拷贝所有文件系统级别的改变到目标集簇:
-
以源集簇的时间线历史从目标集簇分叉出来的点之前的最后一个检查点为起点,扫描目标集簇的 WAL 日志。对于每一个 WAL 记录,读取每一个被动过的数据块。这会得到在目标集簇中从源集簇被分支出去以后所有被更改过的数据块列表。
-
使用直接的文件系统访问(
--source-pgdata)或者 SQL (--source-server),把所有那些更改过的块从源集簇拷贝到目标集簇。 -
把所有其他诸如
pg_xact和配置文件(除了关系文件之外所有的东西)从源集簇拷贝到目标集簇。与基础备份类似,在从源集簇拷贝的数据中,目录pg_dynshmem/、pg_notify/、pg_replslot/、pg_serial/、pg_snapshots/、pg_stat_tmp/以及pg_subtrans/的内容会被忽略。任何以pgsql_tmp开始的文件或目录都会被忽略,backup_label、tablespace_map、pg_internal.init、postmaster.opts以及postmaster.pid也是这样。 -
从源集簇应用 WAL,从失效处创建的检查点开始(严格来说,pg_rewind并不应用 WAL,它只是创建一个备份标签文件,该文件让PostgreSQL从那个检查点开始向前重放所有 WAL)。
7、pg_test_fsync
pg_test_fsync — 为PostgreSQL判断最快的 wal_sync_method
大纲
pg_test_fsync [option...]
简介
pg_test_fsync是想告诉你在特定的系统上,哪一种 wal_sync_method最快,还可以在发生认定的 I/O 问题时提供诊断信息。不过,pg_test_fsync 显示的区别可能不会在真实的数据库吞吐量上产生显著的区别,特别是由于 很多数据库服务器被它们的预写日志限制了速度。 pg_test_fsync为 wal_sync_method报告以微秒计的平均文件同步操作时间, 也能被用来提示用于优化commit_delay值的方法。
选项
pg_test_fsync接受下列命令行选项:
-f--filename
指定要写入测试数据到其中的文件名。这个文件必须位于和 pg_wal目录所在或者将被放置的同一个文件系统中( pg_wal包含WAL文件)。默认是当前 目录中的pg_test_fsync.out。
-s--secs-per-test
指定每次测试的秒数。每个测试的时间越长,测试的精度就越高,但是 它需要更多时间来运行。默认是 5 秒,这允许程序在 2 分钟以内完成。
-V--version
打印pg_test_fsync版本并且退出。
-?--help
显示有关pg_test_fsync命令行参数的帮助并且退出。
8、pg_test_timing
pg_test_timing — 度量计时开销
大纲
pg_test_timing [option...]
描述
pg_test_timing是一种度量在你的系统上计时开销以及确认系统时间绝不会回退的工具。收集计时数据很慢的系统会给出不太准确的EXPLAIN ANALYZE结果。
选项
pg_test_timing接受下列命令行选项:
-d duration--duration=duration
指定测试的持续时间,以秒计。更长的持续时间会给出更好一些的精确度,并且更可能发现系统时钟回退的问题。默认的测试持续时间是 3 秒。
-V--version
打印pg_test_timing版本并退出。
-?--help
显示有关pg_test_timing的命令行参数,然后退出。
用法
结果解读
好的结果将显示大部分(>90%)的单个计时调用用时都小于 1 微秒。每次循环的平均开销将会更低,低于 100 纳秒。下面的例子来自于一台使用了一份 TSC 时钟源码的 Intel i7-860 系统,它展示了非常好的性能:
Testing timing overhead for 3 seconds.
Per loop time including overhead: 35.96 ns
Histogram of timing durations:
< us % of total count
1 96.40465 80435604
2 3.59518 2999652
4 0.00015 126
8 0.00002 13
16 0.00000 2
注意每次循环时间和柱状图用的单位是不同的。循环的解析度可以在几个纳秒(ns),而单个计时调用只能解析到一个微秒(us)。
度量执行器计时开销
当查询执行器使用EXPLAIN ANALYZE运行一个语句时,单个操作会被计时,总结也会被显示。你的系统的负荷可以通过使用psql程序计数行来检查:
CREATE TABLE t AS SELECT * FROM generate_series(1,100000);
\timing
SELECT COUNT(*) FROM t;
EXPLAIN ANALYZE SELECT COUNT(*) FROM t;
i7-860 系统测到运行该计数查询用了 9.8 ms 而EXPLAIN ANALYZE版本则需要 16.6 ms,每次处理都在 100,000 行上进行。6.8 ms 的差别意味着在每行上的计时负荷是 68 ns,大概是 pg_test_timing 估计的两倍。即使这样相对少量的负荷也造成了带有计时的计数语句耗时多出了 70%。在更大量的查询上,计时开销带来的问题不会有这么明显。
改变时间来源Changing time sources
在一些较新的 Linux 系统上,可以在任何时候更改用来收集计时数据的时钟来源。第二个例子显示了在上述快速结果的相同系统上切换到较慢的 acpi_pm 时间源可能带来的降速:
# cat /sys/devices/system/clocksource/clocksource0/available_clocksource
tsc hpet acpi_pm
# echo acpi_pm > /sys/devices/system/clocksource/clocksource0/current_clocksource
# pg_test_timing
Per loop time including overhead: 722.92 ns
Histogram of timing durations:
< us % of total count
1 27.84870 1155682
2 72.05956 2990371
4 0.07810 3241
8 0.01357 563
16 0.00007 3
在这种配置中,上面的例子EXPLAIN ANALYZE用了 115.9 ms。其中有 1061 ns 的计时开销,还是用这个工具直接度量结果的一个小倍数。这么多的计时开销意味着实际的查询本身只占了时间的一个很小的分数,大部分的时间都耗在了计时所需的管理开销上。在这种配置中,任何涉及到很多计时操作的EXPLAIN ANALYZE都会受到计时开销的显著影响。
FreeBSD 也允许即时更改时间源,并且它会记录在启动期间有关计时器选择的信息:
# dmesg | grep "Timecounter"
Timecounter "ACPI-fast" frequency 3579545 Hz quality 900
Timecounter "i8254" frequency 1193182 Hz quality 0
Timecounters tick every 10.000 msec
Timecounter "TSC" frequency 2531787134 Hz quality 800
# sysctl kern.timecounter.hardware=TSC
kern.timecounter.hardware: ACPI-fast -> TSC
其他系统可能只允许在启动时设定时间源。在旧的 Linux 系统上,“clock”内核设置是做这类更改的唯一方法。并且即使在一些更近的系统上,对于一个时钟源你将只能看到唯一的选项 "jiffies"。Jiffies 是老的 Linux 软件时钟实现,当有足够快的计时硬件支持时,它能够具有很好的解析度,就像在这个例子中:
$ cat /sys/devices/system/clocksource/clocksource0/available_clocksource
jiffies
$ dmesg | grep time.c
time.c: Using 3.579545 MHz WALL PM GTOD PIT/TSC timer.
time.c: Detected 2400.153 MHz processor.
$ pg_test_timing
Testing timing overhead for 3 seconds.
Per timing duration including loop overhead: 97.75 ns
Histogram of timing durations:
< us % of total count
1 90.23734 27694571
2 9.75277 2993204
4 0.00981 3010
8 0.00007 22
16 0.00000 1
32 0.00000 1
时钟硬件和计时准确性
收集准确的计时信息在计算机上通常是使用具有不同精度的时钟硬件完成的。使用一些硬件,操作系统能几乎直接把系统时钟时间传递给程序。一个系统时钟也可以得自于一块简单地提供计时中断、在某个已知时间区间内的周期性滴答的芯片。在两种情况中,操作系统内核提供一个隐藏这些细节的时钟源。但是时钟源的精确度以及能多快返回结果会根据底层硬件而变化。
不精确的计时能够导致系统不稳定性。对任何时钟源的更改都要仔细地测试。操作系统默认是有时会更倾向于可靠性而不是最好的精确性。并且如果你在使用一个虚拟机器,应查看与之兼容的推荐时间源。在模拟计时器时虚拟硬件面临着额外的困难,并且提供商常常会建议每个操作系统的设置。
时间戳计数器(TSC)时钟源是当前一代 CPU 上最精确的一种。当操作系统支持 TSC 并且 TSC 可靠时,它是跟踪系统时间更好的方式。有多种方式会使 TSC 无法提供准确的计时源,这会让它不可靠。旧的系统能有一种基于 CPU 温度变化的 TSC 时钟,这让它不能用于计时。尝试在一些就的多核 CPU 上使用 TSC 可能在多个核心之间给出不一致的时间报告。这可能导致时间倒退,这个程序会检查这种问题。并且即使最新的系统,在非常激进的节能配置下也可能无法提供准确的 TSC 计时。
更新的操作系统可能检查已知的 TSC 问题并且当它们被发现时切换到一种更慢、更稳定的时钟源。如果你的系统支持 TSC 时间但是并不默认使用它,很可能是由于某种充分的理由才禁用它。某些操作系统可能无法正确地检测所有可能的问题,或者即便在知道 TSC 不精确的情况下也允许使用 TSC。
如果系统上有高精度事件计时器(HPET)并且 TSC 不准确,该系统将会更喜欢 HPET 计时器。计时器芯片本身是可编程的,最高允许 100 纳米的解析度,但是在你的系统时钟中可能见不到那么高的准确度。
高级配置和电源接口(ACPI)提供了一种电源管理(PM)计时器,Linux 把它称之为 acpi_pm。得自于 acpi_pm 的时钟最好时将能提供 300 纳秒的解析度。
在旧的 PC 硬件上使用的计时器包括 8254 可编程区间计时器(PIT)、实时时钟(RTC)、高级可编程中断控制器(APIC)计时器以及 Cyclone 计时器。这些计时器是以毫秒解析度为目标的。
9、pg_upgrade
pg_upgrade — 升级PostgreSQL服务器实例
大纲
pg_upgrade -b oldbindir -B newbindir -d oldconfigdir -D newconfigdir [option...]
描述
pg_upgrade(之前被称为pg_migrator) 允许存储在PostgreSQL数据文件中的数据被升级到一个较晚 的PostgreSQL主版本而无需进行主版本升级(例如从9.5.8到9.6.4或者从10.7到11.2)通常所需的数据转储/重载。 对于次版本升级(例如从9.6.2到9.6.3或者从10.1到10.2)则不需要这个程序。
PostgreSQL主发行版本通常会加入新的特性,这些新特性常常会更改系统表的 布局,但是内部数据存储格式很少会改变。pg_upgrade 使用这一事实来通过创建新系统表并且重用旧的用户数据文件来执行快速升级。 如果未来的主发行版本更改了数据存储格式,导致旧数据格式不可读,那么 pg_upgrade将无法用于此类升级。(社区将努力避免这种情况)。
pg_upgrade会尽力(例如通过检查兼容的编译时设 置)确保新旧集簇在二进制上也是兼容的,包括 32/64 位二进制。保持 外部模块也是二进制兼容的也很重要,不过 pg_upgrade无法检查这一点。
pg_upgrade 支持从 8.4.X 及其后版本升级到当前的 PostgreSQL主发布,包括快照和 beta 发布。
选项
pg_upgrade接受下列命令行参数:
-b bindir--old-bindir=bindir
旧的 PostgreSQL 可执行文件目录; 环境变量PGBINOLD
-B bindir--new-bindir=bindir
新的 PostgreSQL 可执行文件目录; 环境变量PGBINNEW
-c--check
只检查集簇,不更改任何数据
-d datadir--old-datadir=datadir
旧的集簇数据目录;环境变量 PGDATAOLD
-D datadir--new-datadir=datadir
新的集簇数据目录;环境变量 PGDATANEW
-j--jobs
要同时使用的进程或线程数
-k--link
使用硬链接来代替将文件拷贝到新集簇
-o options--old-options options
直接传送给旧 postgres命令的选项,多个选项可以追加在后面
-O options--new-options options
直接传送给新 postgres命令的选项,多个选项可以追加在后面
-p port--old-port=port
旧的集簇端口号;环境变量 PGPORTOLD
-P port--new-port=port
新的集簇端口号;环境变量 PGPORTNEW
-r--retain
即使在成功完成后也保留 SQL 和日志文件
-U username--username=username
集簇的安装用户名;环境变量 PGUSER
-v--verbose
启用详细的内部日志
-V--version
显示版本信息,然后退出
-?--help
显示帮助,然后退出
使用
下面是用pg_upgrade执行一次升级的步骤:
-
移动旧集簇(可选)
如果你在使用一个与版本相关的安装目录(例如
/opt/PostgreSQL/11),你就不需要移动旧的集簇。 图形化的安装程序会使用版本相关的安装目录。如果你的安装目录不是版本相关的(例如
/usr/local/pgsql), 就有必要移动当前的 PostgreSQL 安装目录,以免它干扰新的 PostgreSQL安装。一旦当前的 PostgreSQL服务器被关闭,就可以安全地重命名 PostgreSQL 安装目录。假设旧目录是/usr/local/pgsql,你可以这样:mv /usr/local/pgsql /usr/local/pgsql.old来重命名该目录。
-
对于源码安装,编译新版本
用兼容旧集簇的
configure标记编译新的 PostgreSQL 源码。在开始升级之前,pg_upgrade 将检查pg_controldata来确保所有设置都是兼容的。 -
安装新的 PostgreSQL 二进制文件
安装新服务器的二进制文件和支持文件。pg_upgrade 会被包含在默认的安装中。
对于源码安装,如果你希望把新服务器安装在一个自定义的位置, 可以使用
prefix变量:make prefix=/usr/local/pgsql.new install -
初始化新的 PostgreSQL 集簇
使用
initdb初始化新集簇。这里也要使用与 旧集簇相兼容的initdb标志。许多预编译的 安装程序会自动做这个步骤。这里没有必要启动新集簇。 -
安装自定义的共享对象文件
把旧集簇使用的所有自定义共享对象文件(或者 DLL)安装到新集簇中, 例如
pgcrypto.so,不管它们是来自于contrib还是某些其他源码。不要安装模式定义 (例如CREATE EXTENSION pgcrypto),因为这些将会从旧集簇升级得到。 还有,任何自定义的全文搜索文件(词典、同义词、辞典、停用词)也必须 被复制到新集簇中。 -
调整认证
pg_upgrade将会多次连接到旧服务器和新服务器,因此 你可能想要在pg_hba.conf中把认证设置成peer或者使用一个~/.pgpass文件。 -
停止两个服务器
确认两个数据库服务器都被停止使用,例如在 Unix 上可以:
pg_ctl -D /opt/PostgreSQL/9.6 stop pg_ctl -D /opt/PostgreSQL/11 stop或者在 Windows 上使用正确的服务名:
NET STOP postgresql-9.6 NET STOP postgresql-11直到后面的步骤之前,流复制和日志传送后备服务器可以保持运行。
-
为后备服务器升级做准备
如果正在使用小节步骤10中给出的方法升级后备服务器,请对旧的主集簇和后备集簇运行pg_controldata以验证旧的后备服务器已经完全追上。验证“Latest checkpoint location”值在所有集簇中都匹配(如果旧后备服务器在旧的主服务器之前被关闭或者如果旧的后备服务器仍在运行,则将会出现失配)。此外,在新的主集簇上的
postgresql.conf文件中把wal_level改为replica。 -
运行 pg_upgrade
总是应该运行新服务器而不是旧服务器的pg_upgrade二进制文件。 pg_upgrade要求制定新旧集簇的数据和可执行文件(
bin)目录。你也可以指定用户和端口值,以及你是否想要用链接来 取代默认的复制行为对数据文件进行处理。如果你使用链接模式,升级将会快很多(不需要文件拷贝)并且将使用 更少的磁盘空间,但是在升级后一旦启动新集簇,旧集簇就无法被访问。 链接模式也要求新旧集簇数据目录位于同一个文件系统中(表空间和
pg_wal可以在不同的文件系统中)。完整的选项列表 可见pg_upgrade --help。--jobs选项允许多个 CPU 核心被用来复制/链接文件以及 并行地转储和重载数据库模式。这个选项一个比较好的值是 CPU 核心数 和表空间数的最大值。这个选项可以显著地减少升级运行在一台多处理 器机器上的多数据库服务器的时间。对于 Windows 用户,你必须以一个超级账号登录,并且以
postgres用户启动一个 shell 并且设置正确的路径:RUNAS /USER:postgres "CMD.EXE" SET PATH=%PATH%;C:\Program Files\PostgreSQL\11\bin;并且用带引号的目录运行pg_upgrade,例如:
pg_upgrade.exe --old-datadir "C:/Program Files/PostgreSQL/9.6/data" --new-datadir "C:/Program Files/PostgreSQL/11/data" --old-bindir "C:/Program Files/PostgreSQL/9.6/bin" --new-bindir "C:/Program Files/PostgreSQL/11/bin"一旦启动,
pg_upgrade将验证两个集簇是否兼容并且 执行升级。你可以使用pg_upgrade --check来只执行检查, 这种模式即使在旧服务器还在运行时也能使用。pg_upgrade --check也将列出任何在更新后需要做的手工 调整。如果你将要使用链接模式,你应该使用--link选项和--check一起来启用链接模式相关的检查。pg_upgrade要求在当前目录中的写权限。显然,没有人可以在升级期间访问这些集簇。pg_upgrade 默认会在端口 50432 上运行服务器来避免意外的客户端连接。在做升级时, 可以对两个集簇使用相同的端口号,因为新旧集簇不会在同时被运行。不过, 在检查一个旧的运行中服务器时,新旧端口号必须不同。
如果在恢复数据库模式时发生错误,
pg_upgrade将会退出 并且你必须按照下文步骤16中所说的恢复 旧集簇。要再次尝试pg_upgrade,你将需要修改 旧集簇,这样 pg_upgrade 模式会成功恢复。如果问题是一个contrib模块, 你可能需要从旧集簇中卸载该模块并且在升级后重新把它安装在新集簇中,不过 这样做的前提是该模块没有被用来存储用户数据。 -
升级流复制和日志传送后备服务器
如果使用链接模式并且有流复制或者日志 传送后备服务器,你可以遵照下面的 步骤对它们进行快速的升级。你将不用在这些后备服务器上运行 pg_upgrade,而是在主服务器上运行rsync。 到这里还不要启动任何服务器。
如果你没有使用链接模式、没有或不想使用rsync或者想用一种更容易的解决方案,请跳过这一节中的过程并且在pg_upgrade完成并且新的主集簇开始运行后重建后备服务器。
-
在后备服务器上安装新的 PostgreSQL 二进制文件
确保新的二进制和支持文件被安装在所有后备服务器上。
-
确保不存在新的后备机数据目录
确保新的后备机数据目录不存在或者为空。如果 运行过initdb,请删除后备服务器的新数据目录。
-
安装自定义共享对象文件
在新的后备机上安装和新的主集簇中相同的自定义共享对象文件。
-
停止后备服务器
如果后备服务器仍在运行,现在使用上述的指令停止它们。
-
保存配置文件
从旧后备机的配置目录保存任何需要保留的配置文件,例如
postgresql.conf、recovery.conf, 因为这些文件在下一步中会被重写或者移除。 -
运行rsync
在使用链接模式时,后备服务器可以使用rsync快速升级。为了实现这一点,在主服务器上一个高于新旧数据库集簇目录的目录中为每个后备服务器运行这个命令:
rsync --archive --delete --hard-links --size-only --no-inc-recursive old_cluster new_cluster remote_dir其中
old_cluster和new_cluster是相对于主服务器上的当前目录的,而remote_dir是后备服务器上高于新旧集簇目录的一个目录。在主服务器和后备服务器上指定目录之下的目录结构必须匹配。指定远程目录的详细情况请参考rsync的手册,例如:rsync --archive --delete --hard-links --size-only --no-inc-recursive /opt/PostgreSQL/9.5 \ /opt/PostgreSQL/9.6 standby.example.com:/opt/PostgreSQL可以使用rsync的
--dry-run选项验证该命令将做的事情。虽然在主服务器上必须为至少一台后备运行rsync,可以在一台已经升级过的后备服务器上运行rsync来升级其他的后备服务器,只要已升级的后备服务器还没有被启动。这个命令所做的事情是记录由pg_upgrade的链接模式创建的链接,它们连接主服务器上新旧集簇中的文件。该命令接下来在后备服务器的旧集簇中寻找匹配的文件并且为它们在该后备的新集簇中创建链接。主服务器上没有被链接的文件会被从主服务器拷贝到后备服务器(通常都很小)。这提供了快速的后备服务器升级。不幸地是,rsync会不必要地拷贝与临时表和不做日志表相关的文件,因为通常在后备服务器上不存在这些文件。
如果有表空间,你将需要为每个表空间目录运行一个类似的rsync命令,例如:
rsync --archive --delete --hard-links --size-only --no-inc-recursive /vol1/pg_tblsp/PG_9.5_201510051 \ /vol1/pg_tblsp/PG_9.6_201608131 standby.example.com:/vol1/pg_tblsp如果你已经把
pg_wal放在数据目录外面,也必须在那些目录上运行rsync。 -
配置流复制和日志传送后备服务器
为日志传送配置服务器(不需要运行
pg_start_backup()以及pg_stop_backup()或者做文件系统备份,因为从属机 仍在与主机同步)。
-
-
恢复
pg_hba.conf如果你修改了
pg_hba.conf,则要将其恢复到原始的设置。 也可能需要调整新集簇中的其他配置文件(例如postgresql.conf)来匹配旧集簇。 -
启动新服务器
现在可以安全地启动新的服务器,并且可以接着启动任何 rsync过的后备服务器。
-
升级后处理
如果需要做任何升级后处理,pg_upgrade 将在完成后发出警告。它也将 生成必须由管理员运行的脚本文件。这些脚本文件将连接到每一个需要做 升级后处理的数据库。每一个脚本应该这样运行:
psql --username=postgres --file=script.sql postgres这些脚本可以以任何顺序运行并且在运行之后立即删除。
小心
通常在重建脚本运行完成之前访问重建脚本中引用的表是不安全的,这样做 可能会得到不正确的结果或者很差的性能。没有在重建脚本中引用的表可以 随时被访问。 -
统计信息
由于
pg_upgrade并未传输优化器统计信息,在升级的尾声 你将被指示运行一个命令来生成这些信息。你可能需要设置连接参数来匹配你 的新集簇。 -
删除旧集簇
一旦你对升级表示满意,你就可以通过运行
pg_upgrade完成时提到的脚本来删除旧集簇的 数据目录(如果在旧数据目录中有用户定义的表空间就不可能实现自动删除)。 你也可以删除旧安装目录(例如bin、share)。 -
恢复到旧集簇
在运行
pg_upgrade之后,如果你希望恢复到 旧集簇,有几个选项:-
如果你运行了带有
--check的pg_upgrade,则没有对旧集簇做修改并且 可以在任何时候重新使用它。 -
如果你运行了带有
--link的pg_upgrade,数据文件在新旧集簇之间 共享。如果你开启了新集簇,并且新服务器已经对这些共享文件做了写 入,那么使用旧集簇就不安全。 -
如果你运行了不带
--link的pg_upgrade或者没有启动新服务器, 旧集簇还没有被修改,如果已经执行了链接,会在$PGDATA/global/pg_control后追加一个.old后缀。要重用旧集簇,可以从$PGDATA/global/pg_control移除.old后缀,然后你就能重启旧集簇了。
-
注解
pg_upgrade不支持对某些数据库的升级,此类 数据库包含以下reg*开头的 OID 引用的系统数据类型: regproc、regprocedure、 regoper、regoperator、 regconfig以及regdictionary( regtype可以被升级)。
如果失败、重建和重索引会影响你的安装,pg_upgrade 将会报告这些情况。用来重建表和索引的升级后脚本将会自动被建立。 如果你正在尝试自动升级很多集簇,你应该发现具有相同数据库模式的集簇 对所有集簇升级都要求同样的升级后步骤,这是因为升级后步骤是基于数据 库模式而不是用户数据。
对于部署测试,创建一个只有模式的旧集簇副本,在其中插入假数据并且升级。
如果你在升级一个PostgreSQL 9.2 之前的集簇,并且 它使用一个只有配置文件的目录,你必须向pg_upgrade 传递真正的数据目录位置,并且把配置目录位置传递给服务器,例如 -d /real-data-directory -o '-D /configuration-directory'。
如果正在使用的一个 9.1 之前的旧服务器用的是一个非默认Unix 域套接字目录 或者使用的默认值不同于新集簇的默认值,请把PGHOST设置为 指向旧服务器的套接字位置(这与 Windows 无关)。
如果你想要使用链接模式并且你不想让你的旧集簇在新集簇启动时被修改, 可以复制一份旧集簇并且在副本上以链接模式进行升级。要创建旧集簇的一 份合法拷贝,可以在服务器运行时使用rsync创建旧集簇的 一份脏拷贝,然后关闭旧服务器并且再次运行rsync --checksum 把更改更新到该拷贝以让其一致(--checksum是必要的,因为 rsync在判断文件修改时间的更改时的精度只能到秒级)。你可能想要排除 一些文件,例如postmaster.pid。如果你的文件系统支持文 件系统快照或者 copy-on-write 文件副本,你可以使用它们来创建旧集簇和 表空间的一个备份,不过快照和副本必须被同时创建或者在数据库服务器关闭 期间被创建。
10、pg_verify_checksums
pg_verify_checksums — verify data checksums in a PostgreSQL database cluster
大纲
pg_verify_checksums [option...] [[ -D | --pgdata ] datadir]
简介
pg_verify_checksums在一个PostgreSQL集簇中验证数据的校验和。在运行pg_verify_checksums之前,服务器必须被干净地关闭。如果没有校验和错误,则这个程序的退出状态为零,否则为非零。
选项
有下列命令行选项可用:
-D directory--pgdata=directory
指定存放数据库集簇的目录。
-v--verbose
启用详细输出。列出所有被检查的文件。
-r relfilenode
仅验证指定relfilenode对应的关系中的校验和。
-V--version
打印pg_verify_checksums版本并且退出。
-?--help
显示有关Show help about pg_verify_checksums命令行参数的帮助,并且退出。
环境
PGDATA
指定存放该数据库集簇的目录,可以用-D选项重载。
11、pg_waldump
pg_waldump — 以人类可读的形式显示一个PostgreSQL 数据库集簇的预写式日志
大纲
pg_waldump [option...] [startseg [endseg] ]
简介
pg_waldump显示预写式日志(WAL),它主要 用于调试或者教育目的。
这个工具只能由安装该服务器的用户运行,因为它要求对数据目录的只读访问。
选项
下列命令行选项控制输出的位置和格式:
startseg
从指定的日志段文件开始读取。这也隐含地决定了要搜索文件的路径以及 要使用的时间线。
endseg
在读取指定的日志段文件后停止。
-b--bkp-details
输出有关备份块的细节。
-e end--end=end
在指定的WAL位置停止读取,而不是一直读取到日志流的末尾。
-f--follow
在到达可用 WAL 的末尾之后,保持每秒轮询一次是否有新的 WAL 出现。
-n limit--limit=limit
显示指定数量的记录,然后停止。
-p path--path=path
指定搜索日志段文件的目录或包含这些文件的包含pg_wal子目录的目录。 缺省值是在当前目录中搜索,当前目录的pg_wal子目录和 PGDATA的pg_wal子目录。
-r rmgr--rmgr=rmgr
只显示由指定资源管理器生成的记录。如果把list作为资源管理器名称 传递给这个选项,则打印出可用资源管理器名称的列表然后退出。
-s start--start=start
要从哪个WAL位置开始读取。默认是从找到的最早的文件的第一个可用日志记录开始。
-t timeline--timeline=timeline
要从哪个时间线读取日志记录。默认是使用startseg(如果指定) 中的值,否则默认为 1。
-V--version
打印pg_waldump版本并且退出。
-x xid--xid=xid
只显示用给定事务 ID 标记的记录。
-z--stats[=record]
显示概括统计信息(记录的数量和尺寸以及全页镜像)而不是显示 每个记录。可以选择针对每个记录生成统计信息,而不是针对每个 资源管理器生成。
-?--help
显示有关pg_waldump命令行参数的帮助并且退出。
注解
当服务器正在运行时可能会给出错误的结果。
只有指定的时间线 会被显示(如果没有指定,则显示默认时间线)。 其他时间线上的记录会被忽略。
pg_waldump不能读取具有后缀.partial 的 WAL 文件。如果需要读取那些文件,需要从文件名中移除 .partial后缀。
12、postgres
postgres — PostgreSQL数据库服务器
大纲
postgres [选项...]
描述
postgres是PostgreSQL数据库服务器。一个客户端应用为了能访问一个数据库,它会(通过一个网络或者本地)连接到一个运行着的postgres实例。该postgres实例接着会开始一个独立的服务器进程来处理该连接。
一个postgres实例总是管理正好一个数据库集簇的数据。一个数据库集簇是一个数据库的集合,它们被存储在一个共同的文件系统位置(“数据区”)上。 一个系统上可以同时运行多个postgres实例,只要它们使用不同的数据区和不同的通信端口(见下文)。postgres启动时需要知道数据区的位置,该位置必须通过-D选项或PGDATA环境变量指定,对此是没有默认值的。通常,-D或PGDATA会直接指向由initdb创建的数据区目录。
默认情况下,postgres会在前台启动并将日志消息打印到标准错误流。但在实际应用中,postgres应当作为一个后台进程启动,而且多数是在系统启动时自动启动。
postgres还能在单用户模式中被调用。这种模式的主要用途是在启动过程中由initdb使用。有时候它也被用于调试或者灾难性恢复。注意,运行一个单用户模式服务器并不真地适合调试服务器,因为不会发生实际的进程间通信和锁定。当从 shell 中调用单用户模式时,用户可以输入查询并且结果会被以一种更适合开发者阅读(不适合普通用户)的形式打印在屏幕上。在单用户模式中,会话用户将被设置为 ID 为 1 的用户,并且这个用户会被隐式地赋予超级用户权限。该用户不必实际存在,因此单用户模式运行可以被用来对某些意外损坏的系统目录进行手工恢复。
选项
postgres接受下列命令行参数。你也可以通过设置一个配置文件来减少键入大部分这些选项。有些(安全)选项还可以从连接的客户端以一种与应用相关只应用于会话的方法设置。例如,如果设置了PGOPTIONS环境变量,那么基于libpq的客户端将都把那个字符串传递给服务器,它将被服务器解释成postgres命令行选项。
通用选项
-B nbuffers
设置被服务器进程使用的共享内存缓冲区数量。这个参数的默认值是initdb自动选择的。指定这个选项等效于设置shared_buffers配置参数。
-c name=value
设置一个命名的运行时参数。大多数其它命令行选项实际上都是这种参数赋值的短形式。-c可以出现多次用于设置多个参数。
-C name
打印命名运行时参数的值,并且退出(详见上面的-c选项)。这可以被用在一个运行服务器上,并且从postgresql.conf中返回值,这些值可能被在这次调用中的任何参数修改过。它并不反映集簇启动时提供的参数。
这个选项用于与一个服务器实例交互的其他程序来查询配置参数值,例如pg_ctl。面向用户的应用应该使用SHOW或者pg_settings视图。
-d debug-level
设置调试级别。数值设置得越高,写到服务器日志的调试输出就越多。取值范围是从 1 到 5。还可以针对某个特定会话使用-d 0来阻止父postgres进程的服务器日志级别被传播到这个会话。
-D datadir
指定数据库配置文件的文件系统位置。
-e
把默认日期风格设置为“European”,也就是输入日期域的顺序是DMY。这也导致在一些日期输出格式中把日打印在月之前。
-F
禁用fsync调用以提高性能,但是要冒系统崩溃时数据损坏的风险。指定这个选项等效于禁用fsync配置参数。在使用之前阅读详细文档!
-h hostname
指定postgres监听来自客户端应用 TCP/IP 连接的 IP 主机名或地址。该值也可以是一个用逗号分隔的地址列表,或者*表示监听所有可用的地址。一个空值表示不监听任何 IP 地址,在这种情况下可以使用 Unix 域套接字连接到服务器。缺省只监听localhost。声明这个选项等效于设置listen_addresses配置参数。默认只监听localhost。指定这个选项等效于设置listen_addresses配置参数。
-i
允许远程客户端使用 TCP/IP (互联网域)连接。没有这个选项,将只接受本地连接。这个选项等效于在postgresql.conf中或者通过-h选项将listen_addresses设为*。
这个选项已经被废弃,因为它不允许访问listen_addresses的完整功能。所以最好直接设置listen_addresses。
-k directory
指定postgres用来监听来自客户端应用连接的 Unix 域套接字的目录。这个值也可以是一个逗号分隔的目录列表。一个空值指定不监听任何 Unix 域套接字,在这种情况下只能用 TCP/IP 套接字来连接到服务器。默认值通常是/tmp,但是可以在编译的时候修改。指定这个选项等效于设置unix_socket_directories配置参数。
-l
启用使用SSL的安全连接。要使这个选项可用,编译PostgreSQL时必须打开SSL支持。
-N max-connections
设置该服务器将接受的最大客户端连接数。该参数的默认值由initdb自动选择。指定这个选项等效于设置max_connections配置参数。
-o extra-options
在extra-options中指定的命令行风格的参数会被传递给所有由这个postgres进程派生的服务进程。
extra-options中的空格被视作 参数分隔符,除非用反斜线(\)转义。要表示一个字面意 义上的反斜线,可以写成\\。通过多次使用-o 也可以指定多个参数。
这个选项的使用已经被废弃。用于服务器进程的所有命令行选项可以在postgres命令行上直接指定。
-p port
指定postgres用于监听客户端应用连接的 TCP/IP 端口或本地 Unix 域套接字文件扩展。默认为PGPORT环境变量的值。如果PGPORT没有设置,那么默认值是编译期间设立的值(通常是 5432)。如果你指定了一个非默认端口,那么所有客户端应用都必须用命令行选项或者PGPORT指定同一个端口。
-s
在每条命令结束时打印时间信息和其它统计信息。这个选项对测试基准和调节缓冲区数量有用处。
-S work-mem
指定内部排序和散列在使用临时磁盘文件之前能使用的内存数量.
-V--version
打印postgres版本并退出。
--name=value
设置一个命名的运行时参数;其缩写形式是-c。
--describe-config
这个选项会用制表符分隔的COPY格式导出服务器的内部配置变量、描述以及默认值。设计它的目的是用于管理工具。
-?--help
显示有关postgres的命令行参数,并且退出。
半内部选项
这里描述的选项主要被用于调试目的,并且在某些情况下可以协助恢复严重受损的数据库。在生产数据库环境中应该不会去使用它们。在这里列举它们只是为了让PostgreSQL系统开发者使用。此外,这些选项可能在将来的版本中更改或删除而不另行通知。
-f { s | i | o | b | t | n | m | h }
禁止某种扫描和连接方法的使用:s和i分别禁用顺序和索引扫描, o、b和t分别禁用只用索引扫描、位图索引扫描以及 TID 扫描,而n、m和h则分别禁用嵌套循环、归并和哈希连接。
顺序扫描和嵌套循环连接都不可能完全被禁用。-fs和-fn选项仅仅是在有其他选择时不鼓励优化器使用这些计划类型。
-n
该选项主要用于调试导致服务器进程异常崩溃的问题。对付这种情况的一般策略是通知所有其它服务器进程,让它们终止并且接着重新初始化共享内存和信号量。这是因为一个错误的服务器进程可能在终止之前就已经对共享状态造成了破坏。该选项指定postgres将不会重新初始化共享数据结构。一个有经验的系统程序员这时就可以使用调试器检查共享内存和信号量状态。
-O
允许修改系统表的结构。这个选项用于initdb。
-P
读取系统表时忽略系统索引(但在更改系统表时仍然更新索引)。这在从损坏的系统索引中恢复时有用。
-t pa[rser] | pl[anner] | e[xecutor]
打印与每个主要系统模块相关的查询的时间统计。这个选项不能和-s选项一起使用。
-T
该选项主要用于调试导致服务器进程异常崩溃的问题。对付这种情况的一般策略是通知所有其它服务器进程,让它们终止并且接着重新初始化共享内存和信号量。这是因为一个错误的服务器进程可能在终止之前就已经对共享状态造成了破坏。该选项指定postgres将通过发送SIGSTOP信号停止其他所有服务器进程,但是并不让它们终止。这样就允许系统程序员手动从所有服务器进程收集内核转储。
-v protocol
声明这次会话使用的前/后服务器协议的版本数。该选项仅在内部使用。
-W seconds
在一个新服务器进程被启动时,它实施认证过程之后会延迟这个选项所设置的秒数。这就留出了机会来用一个调试器附着在服务器进程上。
用于单用户模式的选项
下面的选项仅适用于单用户模式(见单用户模式)。
--single
选择单用户模式。这必须是命令行中的第一个选项。
database
指定要访问的数据库的名称。这必须是命令行中的最后一个参数。如果省略它,则默认为用户名。
-E
在执行命令之前回显所有命令到标准输出。
-j
使用跟着两个新行的分号而不是仅用新行作为命令终止符。
-r filename
将所有服务器日志输出发送到filename中。 只有在作为一个命令行选项提供时,这个选项才会兑现。
环境
PGCLIENTENCODING
客户端使用的默认字符编码(客户端可以独立地覆盖它)。这个值也可以在配置文件中设置。
PGDATA
默认的数据目录位置。
PGDATESTYLE
DateStyle运行时参数的默认值(这个环境变量的使用已被废弃)。
$ ps -ef | grep postgres
PGPORT
默认端口号(在配置文件中设置更好)
诊断
一个提到了semget或shmget的错误消息可能意味着你需要配置内核来提供足够的共享内存和信号量。你也可以通过降低shared_buffers值减少PostgreSQL的共享内存消耗, 或者降低max_connections值减少信号量消耗,这样可以推迟对内核的重新配置。
如果一个消息说另外一个服务器已经在运行,应该仔细地检查,例如根据你的系统可以用命令
$ ps ax | grep postgres
或
$ ps -ef | grep postgres
如果你确信没有冲突的服务器正在运行,那么你可以删除消息中提到的锁文件然后再次尝试。
如果一个失败消息指示它无法绑定到一个端口,可能意味着该端口已经被某些非PostgreSQL进程所使用。如果你终止postgres并且立即使用相同的端口重启它,你也可能会得到这种错误。在这种情况系,你必须等待几秒直到操作系统关闭该端口,然后再重试。最后,如果你指定了一个操作系统认为需要保留的端口号,你可能也会得到这个错误。例如,很多版本的 Unix 认为低于 1024 的端口号是“可信的”并且只允许 Unix 超级用户访问它们。
注解
实用命令pg_ctl可以用来安全方便地启动和关闭postgres服务器。
只要有可能,就不要使用SIGKILL杀死主postgres服务器。这样会阻止postgres在终止前释放它持有的系统资源(例如共享内存和信号量)。这样可能会导致启动新的postgres进程时出现问题。
要正常地终止postgres服务器,可以使用SIGTERM、SIGINT或者SIGQUIT信号。第一个在退出前将等待所有客户端终止,第二个将强行断开所有客户端的连接,第三个会不做正确的关闭立即退出并且会导致重启时的恢复。
SIGHUP信号会重新加载服务器配置文件。也可以向一个单独的服务器进程发送SIGHUP信号,但是这样做通常没什么意义。
要取消一个正在运行的查询,可以向运行该查询的进程发送SIGINT信号。要干净地终止一个后端进程,可向它发送SIGTERM。在 SQL 中可调用的与这两种动作等效的命令可参考第 9.26.2 节中的pg_cancel_backend和pg_terminate_backend。
postgres服务器使用SIGQUIT来告诉子服务器进程终止但不做正常的清理。该信号不应该被用户使用。向一个服务器进程发送SIGKILL也是不明智的 — 主postgres进程将把这解释为一次崩溃,并且作为其标准崩溃恢复过程的一部分,它将强制所有的后代进程退出。
缺陷
--选项在FreeBSD或OpenBSD上无法运行,应该使用-c。这在受影响的系统里是个缺陷; 如果这个缺陷没有被修复,将来的PostgreSQL版本将提供一种解决方案。
单用户模式
要启动一个单用户模式的服务器,使用这样的命令
postgres --single -D /usr/local/pgsql/data other-options my_database
用-D给服务器提供正确的数据库目录的路径,或者确保环境变量PGDATA被设置。同时还要指定你想在其中工作的特定数据库的名字。
通常,单用户模式的服务器会把换行符当做命令输入的终止符。它不明白分号的作用,因为那属于psql。要想把一个命令分成多行,必须在最后一个换行符以外的每个换行符前面敲一个反斜线。这个反斜线和旁边的新行都会被从输入命令中去掉。注意即使在字符串或者注释中也会这样做。
但是如果使用了-j命令行选项,那么单个新行将不会终止命令输入。相反,分号-新行-新行的序列才会终止命令输入。也就是说,输入一个紧跟着空行的分号。在这种模式下,反斜线-新行不会被特殊对待。此外,在字符串或者注释内的这类序列也不会被特殊对待。
不管在哪一种输入模式中,如果输入的一个分号不是正好在命令终止符之前或者不是命令终止符的一部分,它会被认为是一个命令分隔符。当真正输入一个命令终止符时,已经输入的多个语句将被作为一个单个事务执行。
要退出会话,输入EOF(通常是Control+D)。如果从上一个命令终止符以来已经输入了任何文本,那么EOF将被当作命令终止符,并且如果要退出则需要另一个EOF。
请注意单用户模式的服务器不会提供复杂的行编辑特性(例如没有命令历史)。但用户模式也不会做任何后台处理,例如自动检查点或者复制。
例子
要用默认值在后台启动postgres:
$ nohup postgres >logfile 2>&1 </dev/null &
要用指定端口启动postgres,例如 1234:
$ postgres -p 1234
要使用psql连接到这个服务器,用 -p 选项指定这个端口:
$ psql -p 1234
或者设置环境变量PGPORT:
$ export PGPORT=1234
$ psql
命名运行时参数可以用这些形式之一设置:
$ postgres -c work_mem=1234
$ postgres --work-mem=1234
两种形式都覆盖postgresql.conf中可能存在的work_mem设置。请注意在参数名中的下划线在命令行可以写成下划线或连字符。除了用于短期的实验外,更好的习惯是编辑postgresql.conf中的设置, 而不是倚赖命令行开关来设置参数。
13、postmaster
postmaster — PostgreSQL数据库服务器
大纲
postmaster [option...]
描述
postmaster是postgres的一个废弃的别名。
本文包含PostgreSQL服务器应用和支持工具的参考信息,这些命令仅在数据库服务器所在主机运行有效。介绍了initdb、pg_archivecleanup等多个工具,涵盖其大纲、描述、选项、环境等内容,还提及使用注意事项和示例。
670

被折叠的 条评论
为什么被折叠?



