原生Patroni对接PostgreSQL时,可以记录主备切换历史到etcd(或其它dcs,具体是history键的值),虽然我有点看不懂,但是当Patroni适配Opengauss时,这个功能完全不能用了。
有时候生产系统由于软硬件环境不稳定,导致主备切换,有了这个历史信息,切换的时间和机器一目了然,再配合日志,利于分析问题和改进调优。
这里需求就是,Patroni管理的Opengauss集群,当某个节点从备机切换到主机时,会向etcd的history键的值中增加一条记录,记录内容包括切换为主机的node名称、时间、和表示切换的消息。
为此对Patroni源码做了修改,涉及patroni/ctl.py和patroni/ha.py两个文件。
在patroni/ha.py中替换掉enforce_master_role()对update_cluster_history()的调用,改为调用update_promote_history(),update_promote_history()就是我实现的、保存当前主节点信息的函数。
主节点每次循环enforce_master_role()都会被调用一次,进而update_promote_history()也会被调用一次。因此,当节点升为主时要做判断,保证只记录一次。
patroni/ha.py 修改如下:
@@ -596,7 +614,7 @@ class Ha(object):
# It may be unaware of it if postgres is promoted manually.
self.state_handler.set_role('master')
self.process_sync_replication()
- self.update_cluster_history()
+ self.update_promote_history()
return message
elif self.state_handler.role == 'master':
self.process_sync_replication()
@@ -621,6 +639,18 @@ class Ha(object):
args=(self.dcs.loop_wait, self._async_response, on_success))
return promote_message
+ def update_promote_history(self):
+ if self.patroni.config['opengauss']['update_promote_history']:
+ history = self.cluster.history and self.cluster.history.lines or []
+ node_name = self.patroni.config['name']
+ # python list[-1] 表示倒数第一个,即最后一个元素
+ if len(history) > 0 and history[-1][1] == node_name:
+ return
+ ts = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
+ row = [ts, node_name, 'Promoted to master']
+ history.append(row)
+ self.dcs.set_history_value(json.dumps(history, separators=(',', ':')))
+
patroni/ctl.py 修改如下:(这里的修改是为了执行patronctl -c patroni.yml history时查看历史能够正确显示)
def history(obj, cluster_name, fmt):
cluster = get_dcs(obj, cluster_name).get_cluster()
history = cluster.history and cluster.history.lines or []
- for line in history:
- if len(line) < 4:
- line.append('')
- print_output(['TL', 'LSN', 'Reason', 'Timestamp'], history, {'TL': 'r', 'LSN': 'r'}, fmt)
+ # history 格式为 [['c0', 'c1', 'c2'], ['c0', 'c1', 'c2'], ['c0', 'c1', 'c2']]
+ # alignment 控制表头的左右对齐
+ print_output(['Timestamp', 'Node', 'Event'], history, {'Timestamp': 'r', 'Node':'r', 'Event': 'r'}, fmt)
在配置文件patroni.yml中增加了使能记录历史的配置项:update_promote_history
设为true时表示记录主备切换历史,为false时表示不记录主备切换历史。
需要增加一个功能:delete history