数据库主进程挂了,原有的连接还能继续操作数据库,你信吗?下面,由DBA+杭州群联合发起人周正中告诉你,PostgreSQL是怎么可以做到的。
专家简介
周正中
网名:德哥@Digoal
DBA+杭州群联合发起人之一
PostgreSQL中国社区发起人之一,负责杭州分会,兼任社区CTO一职。曾就职于斯凯网络,负责数据库部门。现就职于阿里巴巴,负责RDS PG内核组事务。
数据库主进程挂了,原有的连接还能继续操作数据库,PostgreSQL就可以做到,并且原来的进程对数据库的操作是持久化的,不会丢数据哦。这得益于PostgreSQL的进程结构设计。而且postmaster进程只负责了简单的工作,例如监听端口。
有人会问了,wal writer、backgroup writer进程都挂了,数据还能持久化?没错,因为backend process也可以完成这些操作,所以不用担心数据丢失。
创建测试表。
将postgres主进程杀掉。
杀掉主进程后,只剩下backend process和logger进程,(当然wal buffer和shared buffer还在)。
然后在backend process对应的会话中写入记录。可以正常操作。
退出会话后,所有相关的进程都不在了,logger也退出了。
启动数据库。
查看不到之前插入的数据,原因是那个事务是异步的,而wal writter process进程当时已经不在了,backend process虽然可以完成flush wal buffer的功能,但是不像wal writter进程是周期性刷的,而是在申请不到BUFFER时才会触发刷BUFFER的动作。
所以一条记录就这样丢失了。
接下来,我们使用同步事务,可以保证数据不丢失。
使用同步事务写入数据并退出。
启动数据库。
可以看到,数据是持久化存储的。
注意,虽然backend process可以写wal buffer和shared buffer, 但是不能执行checkpoint, 因为这个操作是checkpoint做的,backend process只会告知它。当我们在postgres主进程被杀掉后,如果执行一个比较大的操作导致触发checkpoint的话,会在日志中看到这样的信息。
包括autovacuum, stat collecter process都不在了,所以这些操作也会失败。
例如:
可以看到对应的日志:
统计信息进程没了,所以统计信息也无法获取。
这里还引发一个问题,如果我们使用长连接来监控数据库状态的话,无法了解主进程是否健康,所以最好还是用短连接来监控数据库,至少可以判断认证这块还有主进程是否是正常的。不过短连接也有一定的问题,就是可能数据库的连接被占满了,无法获得连接。有利有弊,长连接+短连接的方式监控可能更加全面。
[其他]
关于crash自动重启的参数:
restart_after_crash (boolean)
对应的代码,某些场景会导致数据库重启。
src/backend/postmaster/postmaster.c
例如autovacuum进程被kill。断开所有backend process,重启autovacuum lanucher。
本文来自云栖社区合作伙伴"DBAplus",原文发布时间:2015-10-30