经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 数据库/运维 » PostgreSQL » 查看文章
Postgresql 如何选择正确的关闭模式
来源:jb51  时间:2021/1/18 19:54:48  对本文有异议

停止数据库的命令:

  1. pg_ctl stop -D $PGDATA [-m shutdown-mode]

shutdown-mode有如下几种模式:

1. smart: 等所有的连接中止后,关闭数据库。如果客户端连接不终止, 则无法关闭数据库。

开启一个空会话:

  1. [root@localhost ~]# su - postgres
  2. [postgres@localhost ~]$ psql
  3. psql (9.4.4)
  4. Type "help" for help.
  5. postgres=#

用smart关闭数据库:

  1. [postgres@localhost ~]$ pg_ctl stop -D $PGDATA -m smart
  2. waiting for server to shut down............................................................... failed
  3. pg_ctl: server does not shut down
  4. HINT: The "-m fast" option immediately disconnects sessions rather than
  5. waiting for session-initiated disconnection

2. fast: 快速关闭数据库, 断开客户端的连接,让已有的事务回滚,然后正常关闭数据库。

  1. [postgres@localhost ~]$ pg_ctl stop -D $PGDATA -m fast
  2. waiting for server to shut down.... done
  3. server stopped

查看关闭日志:

  1. LOG: received fast shutdown request
  2. LOG: aborting any active transactions
  3. FATAL: terminating connection due to administrator command
  4. LOG: shutting down
  5. LOG: database system is shut down

会话被强制中断,然后关闭数据库。

起一个事务,然后测试关闭:

  1. postgres=# create table t(id int primary key, name varchar(9));
  2. CREATE TABLE
  3. postgres=# begin;
  4. BEGIN
  5. postgres=# insert into t values(1,'a')
  6. postgres-# ;
  7. INSERT 0 1

不提交, 然后用FAST MODE去关闭数据库:

  1. [postgres@localhost ~]$ pg_ctl stop -D $PGDATA -m fast
  2. waiting for server to shut down.... done
  3. server stopped

查看日志:

  1. LOG: received fast shutdown request
  2. LOG: aborting any active transactions
  3. LOG: autovacuum launcher shutting down
  4. FATAL: terminating connection due to administrator command
  5. LOG: shutting down
  6. LOG: database system is shut down

同样是直接中断会话, 而不去管事务有没有提交。

  1. postgres=# select * from t;
  2. id | name
  3. ----+------
  4. (0 rows)

没有提交的数据, 在重启之后并不能查到。

3. immediate: 立即关闭数据库,立即停止数据库进程,直接退出,下次启动时会进行实例恢复。

  1. postgres=# insert into t values(1,'a')
  2. ;
  3. INSERT 0 1
  4. postgres=# select * from t;
  5. id | name
  6. ----+------
  7. 1 | a
  8. (1 row)

关闭数据库:

  1. [postgres@localhost ~]$ pg_ctl stop -D $PGDATA -m immediate
  2. waiting for server to shut down.... done
  3. server stopped

查看日志:

  1. LOG: received immediate shutdown request
  2. WARNING: terminating connection because of crash of another server process
  3. DETAIL: The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory.
  4. HINT: In a moment you should be able to reconnect to the database and repeat your command.
  5. WARNING: terminating connection because of crash of another server process
  6. DETAIL: The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory.
  7. HINT: In a moment you should be able to reconnect to the database and repeat your command.

启动数据库:

  1. [postgres@localhost ~]$ pg_ctl -D /apps/pgsql/pgdata -l 1.log start
  2. server starting

查看日志:

  1. LOG: database system was interrupted; last known up at 2017-04-27 18:56:47 PDT
  2. LOG: database system was not properly shut down; automatic recovery in progress #提示非正常关机,自动开启恢复。
  3. LOG: redo starts at 0/181F910
  4. LOG: record with zero length at 0/181FA90
  5. LOG: redo done at 0/181FA60
  6. LOG: last completed transaction was at log time 2017-04-27 18:59:13.727213-07
  7. LOG: MultiXact member wraparound protections are now enabled
  8. LOG: autovacuum launcher started
  9. LOG: database system is ready to accept connections

查看数据:

  1. [postgres@localhost ~]$ psql
  2. psql (9.4.4)
  3. Type "help" for help.
  4. postgres=# select * from t;
  5. id | name
  6. ----+------
  7. 1 | a
  8. (1 row)

提交的数据已通过实例恢复。

小结:

对比以上三种关库模式:

smart最为安全,但最慢, 需要将所有连接都断开后,才会关库,默认关库模式。

fast强制中断会话,而不管有操作有没有提交,在做系统维护(系统维护时一般应用都正常关闭了,或者不再会有事务操作。)时,需要这种模式来关闭数据库。

immediate最暴力的方式,不管数据有没有落盘(POSGRE是遵循WAL机制),就直接关掉, 待启动时进行实例恢复, 如果在关库前有大量的事务没有写入磁盘, 那这个恢复过程可能会非常的漫长。

补充:postgresql 异步 stream replication 环境关闭 master 的验证

os: ubuntu 16.04

db: postgresql 9.6.8

验证在异步 stream replication环境下,主动关闭master时,数据是否有丢失,能丢失多少。

版本

  1. # lsb_release -a
  2. No LSB modules are available.
  3. Distributor ID: Ubuntu
  4. Description: Ubuntu 16.04.5 LTS
  5. Release: 16.04
  6. Codename: xenial
  7. # su - postgres -c "psql -c \"select version();\""
  8. version
  9. ----------------------------------------------------------------------------------------------------------------------------------------------
  10. PostgreSQL 9.6.8 on x86_64-pc-linux-gnu (Ubuntu 9.6.8-1.pgdg16.04+1), compiled by gcc (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609, 64-bit
  11. (1 row)

用 pgbench 模拟数据库的大量数据操作

  1. postgres=# create database pgbenchdb;
  2. # su - postgres
  3. $ pgbench -i -s 20 pgbenchdb
  4. $ pgbench -r -j2 -c4 -T300 pgbenchdb

关闭 master

  1. # su - postgres
  2. $ /usr/lib/postgresql/9.6/bin/pg_ctl stop -m fast -D "/data/pg9.6/main"

提升 slave

  1. # su - postgres
  2. $ /usr/lib/postgresql/9.6/bin/pg_ctl promote -D "/data/pg9.6/main"

查看 old master 的 xlog location

  1. $ /usr/lib/postgresql/9.6/bin/pg_xlogdump 000000010000000000000016
  2. rmgr: XLOG len (rec/tot): 106/ 106, tx: 0, lsn: 0/16000028, prev 0/152C9A10, desc: CHECKPOINT_SHUTDOWN redo 0/16000028; tli 1; prev tli 1; fpw true; xid 0:118746; oid 16432; multi 1; offset 0; oldest xid 543 in DB 1; oldest multi 1 in DB 1; oldest/newest commit timestamp xid: 550/118745; oldest running xid 0; shutdown
  3. pg_xlogdump: FATAL: error in WAL record at 0/16000028: invalid record length at 0/16000098: wanted 24, got 0

可以看到 lsn: 0/16000028, prev 0/152C9A10, desc: CHECKPOINT_SHUTDOWN redo 0/16000028;

查看 new master 的 .history文件

  1. $ ls -lt|more
  2. total 360456
  3. -rw------- 1 postgres postgres 16777216 Nov 30 10:32 000000020000000000000016
  4. drwx------ 2 postgres postgres 4096 Nov 30 10:16 archive_status
  5. -rw------- 1 postgres postgres 42 Nov 30 10:16 00000002.history
  6. -rw------- 1 postgres postgres 16777216 Nov 30 10:16 000000010000000000000016.partial
  7. -rw------- 1 postgres postgres 16777216 Nov 30 10:16 000000010000000000000015
  8. -rw------- 1 postgres postgres 16777216 Nov 30 10:16 000000010000000000000014
  9. -rw------- 1 postgres postgres 16777216 Nov 30 10:05 000000010000000000000013
  10. $ cat 00000002.history
  11. 1 0/16000098 no recovery target specified
  12. $ /usr/lib/postgresql/9.6/bin/pg_xlogdump 000000010000000000000016
  13. rmgr: XLOG len (rec/tot): 106/ 106, tx: 0, lsn: 0/16000028, prev 0/152C9A10, desc: CHECKPOINT_SHUTDOWN redo 0/16000028; tli 1; prev tli 1; fpw true; xid 0:118746; oid 16432; multi 1; offset 0; oldest xid 543 in DB 1; oldest multi 1 in DB 1; oldest/newest commit timestamp xid: 550/118745; oldest running xid 0; shutdown
  14. rmgr: XLOG len (rec/tot): 42/ 42, tx: 0, lsn: 0/16000098, prev 0/16000028, desc: END_OF_RECOVERY tli 2; prev tli 1; time 2018-11-30 10:16:57.249408 CST
  15. rmgr: Standby len (rec/tot): 50/ 50, tx: 0, lsn: 0/160000C8, prev 0/16000098, desc: RUNNING_XACTS nextXid 118746 latestCompletedXid 118745 oldestRunningXid 118746
  16. rmgr: XLOG len (rec/tot): 51/ 312, tx: 0, lsn: 0/16000100, prev 0/160000C8, desc: FPI_FOR_HINT , blkref #0: rel 1664/0/1260 blk 0 FPW
  17. rmgr: Standby len (rec/tot): 50/ 50, tx: 0, lsn: 0/16000238, prev 0/16000100, desc: RUNNING_XACTS nextXid 118746 latestCompletedXid 118745 oldestRunningXid 118746
  18. pg_xlogdump: FATAL: error in WAL record at 0/16000238: invalid record length at 0/16000270: wanted 24, got 0

可以看到关键记录

  1. lsn: 0/16000028, prev 0/152C9A10, desc: CHECKPOINT_SHUTDOWN redo 0/16000028
  2. lsn: 0/16000098, prev 0/16000028, desc: END_OF_RECOVERY

而 END_OF_RECOVERY 对应的 lsn 为 0/16000098,和 00000002.history 时间线文件的内容完全一致。

所以在异步 stream replication 环境下,主动关闭master时,会将最后一条记录(CHECKPOINT_SHUTDOWN)发送给slave,不会造成数据的丢失。

而 synchronous_commit = on 保证事务有两份持久化的落盘数据。

分析 pg_log 日志

old master 上的最后几条日志

  1. 2018-11-30 10:16:40.986 CST,"postgres","pgbenchdb",7559,"[local]",5c009d79.1d87,4,"UPDATE waiting",2018-11-30 10:16:25 CST,,0,LOG,00000,"disconnection: session time: 0:00:15.723 user=postgres database=pgbenchdb host=[local]",,,,,,,,,"pgbench"
  2. 2018-11-30 10:16:40.993 CST,"postgres","pgbenchdb",7558,"[local]",5c009d79.1d86,3,"idle",2018-11-30 10:16:25 CST,4/0,0,FATAL,57P01,"terminating connection due to administrator command",,,,,,,,,"pgbench"
  3. 2018-11-30 10:16:40.994 CST,"postgres","pgbenchdb",7560,"[local]",5c009d79.1d88,3,"idle",2018-11-30 10:16:25 CST,5/0,0,FATAL,57P01,"terminating connection due to administrator command",,,,,,,,,"pgbench"
  4. 2018-11-30 10:16:40.994 CST,"postgres","pgbenchdb",7558,"[local]",5c009d79.1d86,4,"idle",2018-11-30 10:16:25 CST,,0,LOG,00000,"disconnection: session time: 0:00:15.729 user=postgres database=pgbenchdb host=[local]",,,,,,,,,"pgbench"
  5. 2018-11-30 10:16:40.994 CST,"postgres","pgbenchdb",7560,"[local]",5c009d79.1d88,4,"idle",2018-11-30 10:16:25 CST,,0,LOG,00000,"disconnection: session time: 0:00:15.725 user=postgres database=pgbenchdb host=[local]",,,,,,,,,"pgbench"
  6. 2018-11-30 10:16:40.999 CST,"postgres","pgbenchdb",7561,"[local]",5c009d79.1d89,3,"idle",2018-11-30 10:16:25 CST,6/0,0,FATAL,57P01,"terminating connection due to administrator command",,,,,,,,,"pgbench"
  7. 2018-11-30 10:16:41.001 CST,"postgres","pgbenchdb",7561,"[local]",5c009d79.1d89,4,"idle",2018-11-30 10:16:25 CST,,0,LOG,00000,"disconnection: session time: 0:00:15.731 user=postgres database=pgbenchdb host=[local]",,,,,,,,,"pgbench"
  8. 2018-11-30 10:16:41.010 CST,,,7156,,5c009735.1bf4,7,,2018-11-30 09:49:41 CST,,0,LOG,00000,"shutting down",,,,,,,,,""
  9. 2018-11-30 10:16:41.209 CST,,,7156,,5c009735.1bf4,8,,2018-11-30 09:49:41 CST,,0,LOG,00000,"checkpoint starting: shutdown immediate",,,,,,,,,""
  10. 2018-11-30 10:16:47.623 CST,,,7156,,5c009735.1bf4,9,,2018-11-30 09:49:41 CST,,0,LOG,00000,"checkpoint complete: wrote 29357 buffers (89.6%); 0 transaction log file(s) added, 0 removed, 0 recycled; write=5.931 s, sync=0.399 s, total=6.418 s; sync files=53, longest=0.179 s, average=0.007 s; distance=311294 kB, estimate=311294 kB",,,,,,,,,""
  11. 2018-11-30 10:16:47.683 CST,"repl","",7227,"192.168.56.90:52556",5c009795.1c3b,3,"streaming 0/16000098",2018-11-30 09:51:17 CST,,0,LOG,00000,"disconnection: session time: 0:25:30.149 user=repl database= host=192.168.56.90 port=52556",,,,,,,,,"walreceiver"
  12. 2018-11-30 10:16:47.730 CST,,,7153,,5c009735.1bf1,5,,2018-11-30 09:49:41 CST,,0,LOG,00000,"database system is shut down",,,,,,,,,""

注意倒数第二条信息 streaming 0/16000098 ,说明当时的master关闭时,已经和salve沟通过,确认已经接收到 END_OF_RECOVERY 之前所有的数据了。

old slave 日志

  1. 2018-11-30 10:16:47.660 CST,,,7256,,5c009795.1c58,2,,2018-11-30 09:51:17 CST,,0,LOG,00000,"replication terminated by primary server","End of WAL reached on timeline 1 at 0/16000098.",,,,,,,,""
  2. 2018-11-30 10:16:47.660 CST,,,7256,,5c009795.1c58,3,,2018-11-30 09:51:17 CST,,0,FATAL,XX000,"could not send end-of-streaming message to primary: no COPY in progress
  3. ",,,,,,,,,""
  4. 2018-11-30 10:16:47.660 CST,,,7255,,5c009795.1c57,5,,2018-11-30 09:51:17 CST,1/0,0,LOG,00000,"invalid record length at 0/16000098: wanted 24, got 0",,,,,,,,,""
  5. 2018-11-30 10:16:47.854 CST,,,7443,,5c009d8f.1d13,1,,2018-11-30 10:16:47 CST,,0,FATAL,XX000,"could not connect to the primary server: could not connect to server: Connection refused
  6. Is the server running on host ""192.168.56.119"" and accepting
  7. TCP/IP connections on port 5432?
  8. ",,,,,,,,,""
  9. 2018-11-30 10:16:52.668 CST,,,7444,,5c009d94.1d14,1,,2018-11-30 10:16:52 CST,,0,FATAL,XX000,"could not connect to the primary server: could not connect to server: Connection refused
  10. Is the server running on host ""192.168.56.119"" and accepting
  11. TCP/IP connections on port 5432?
  12. ",,,,,,,,,""
  13. 2018-11-30 10:16:56.875 CST,,,7255,,5c009795.1c57,6,,2018-11-30 09:51:17 CST,1/0,0,LOG,00000,"received promote request",,,,,,,,,""
  14. 2018-11-30 10:16:56.875 CST,,,7255,,5c009795.1c57,7,,2018-11-30 09:51:17 CST,1/0,0,LOG,00000,"redo done at 0/16000028",,,,,,,,,""
  15. 2018-11-30 10:16:56.875 CST,,,7255,,5c009795.1c57,8,,2018-11-30 09:51:17 CST,1/0,0,LOG,00000,"last completed transaction was at log time 2018-11-30 10:16:40.986869+08",,,,,,,,,""
  16. 2018-11-30 10:16:56.888 CST,,,7255,,5c009795.1c57,9,,2018-11-30 09:51:17 CST,1/0,0,LOG,00000,"selected new timeline ID: 2",,,,,,,,,""
  17. 2018-11-30 10:16:57.166 CST,,,7255,,5c009795.1c57,10,,2018-11-30 09:51:17 CST,1/0,0,LOG,00000,"archive recovery complete",,,,,,,,,""
  18. 2018-11-30 10:16:57.267 CST,,,7255,,5c009795.1c57,11,,2018-11-30 09:51:17 CST,1/0,0,LOG,00000,"MultiXact member wraparound protections are now enabled",,,,,,,,,""
  19. 2018-11-30 10:16:57.267 CST,,,7257,,5c009795.1c59,1,,2018-11-30 09:51:17 CST,,0,LOG,00000,"checkpoint starting: force",,,,,,,,,""
  20. 2018-11-30 10:16:57.275 CST,,,7253,,5c009795.1c55,3,,2018-11-30 09:51:17 CST,,0,LOG,00000,"database system is ready to accept connections",,,,,,,,,""
  21. 2018-11-30 10:16:57.276 CST,,,7447,,5c009d99.1d17,1,,2018-11-30 10:16:57 CST,,0,LOG,00000,"autovacuum launcher started",,,,,,,,,""

信息也是相当的清晰。

wal_retrieve_retry_interval = 5s 控制 salve 到 master 失败时,再次重试的等待时间。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持w3xue。如有错误或未考虑完全的地方,望不吝赐教。

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号