這是一個長系列,我們會記錄我們從PostgreSQL 遷移到PolarDB for PG的一個過程,這是長篇的第三篇,這一篇要説的是改變,逐步在生產中使用了PolarDB for PG後我們遇到了一個我們必須遇到,但很快被解決的問題。
這個問題其實我們在PolarDB for MySQL的時候遇到過,就是查詢系統信息的問題,這裏我們稍微給不懂polardb的小白在補充一點基礎知識。
1 PolarDB for PG PolarDB for MySQL 是一個雲原生的數據庫產品
2 PolarDB for M PolarDB for P 是一個shared storage 的結構 (注意PolarDB 是一個數據庫體系的名字,不是一個數據庫的名字,我們這裏僅僅針對我們上述的兩個系列裏面的產品)
3 PolarDB for PG ,PolarDB for MySQL 必須有代理,且代理是這個雲原生數據庫關鍵的部分。
那麼我們遇到了什麼問題呢? 對了查詢數據庫系統信息和對數據庫信息進行一些基礎操作的問題。
這裏我們舉例:我們要查詢 PolarDB for PG中的時間超過1分鐘的鏈接,並進行清理。 在單機PostgreSQL中,我們只需要運行如下的語句即可。
SELECT
pg_terminate_backend(pid)
FROM
pg_stat_activity
WHERE
state = 'active'
AND now() - query_start > interval '1 minute'
AND pid <> pg_backend_pid();
但是在PolarDB FOR PG中,這樣操作是錯誤的。為什麼? 想學PolarDB for PG的看這裏。
PolarDB的簡易架構圖
我們可以看到我們的所有的連接到數據庫中都是通過代理的,代理在接收到數據請求後,開始判斷我們的這次處理應該打到那個節點。
代理有以下的功能:
1 區分數據的讀或寫請求,自動進行可讀寫分離的語句的讀寫分離
2 對數據庫session進行代理級別的複用,降低建立連接的數量和速度
3 甄別從節點的數據與主節點的數據是否一致,如一致,將數據打入到讀庫,如果發現數據有不一致情況,將數據訪問返回到寫節點提取數據,全自動化。
那麼這裏有問題了,你查詢的節點一條查詢語句下去,pg_stat_activity讀取的數據是一個明確的節點,他要麼是,寫節點,要麼是讀節點,或另一個讀節點,因為PolarDB 支持15個讀節點同時在線。
這就產生一個問題,我們在查詢後,我們查殺會出現這樣的結果
1 我們查詢的節點,不是我們想要查殺的節點
2 我們查詢的數據後,再次發起查殺,兩次操作,可能並不是同一個節點。
那麼這裏,數據庫的狀態收集和數據庫的操作,就會出現問題。
怎麼辦!
方案1,建立功能明晰的代理(但有功能限制)
image
大家看方案1中,代理是可以建立多個,你一個節點建立一個代理是可以的,一個節點可能有多個代理,一個代理也可以有多個節點,有點像繞口令,簡略的説,一對多,多對多,多對一,在節點和代理之間的關係是非常靈活的。
方案1中的我們建立只讀節點代理,也就是我們圖上的從節點代理他只針對從節點,在大部分情況下,1個只讀節點就足夠了。這樣建立後,就形成了,只讀節點本身只負責自己的一個只讀節點,寫節點代理只負責自己的寫節點,集羣的代理給應用連接使用。
代理就分成兩個功能:
1 數據庫運行維護類的代理
2 應用系統代理
我們對我們的數據庫運維的程序進行重新的梳理, 對於一些操作直接接入主節點代理,而另一些則接入到兩個運行維護代理中進行使用。
而阿里雲的老師給我們一個提議,其實我們並不需要這麼麻煩,我們只需要對監控程序進行一個簡單的改造就可以,整體的工作並非我們想的那麼的複雜。
PolarDB的簡易架構圖
然後我們還是通過PolarDB 代理,稍微將語句進行一個改動在我們要 pg_stat_terminate(PID) 的select語句前面加入 /FORCE_ALL/ 即可進行廣播節點式的查殺工作。
這裏需要提醒,不能在查殺語句中直接使用now() 這樣的函數,原因很簡單,因為每個節點的NOW()得到的時間未必一致,可能有毫秒的差別,那麼now() 函數又怎麼能返回一個確定的值,所以語句需要修改,將now() 改成一個具體的時間,而這個具體的時間是一個變量我們輸入即可,而變量的時間可以通過任意方法產生。當然這不是一個重點。
所以之前是我們多想了,還弄出一個方案1,設計上PolarDB FOR PG FOR MYSQL 兩個數據庫可以通過集羣代理,來訪問到數據庫運維中所要去的所有節點,而這裏有人會提到。
有必要這麼麻煩嗎? 節點固定好不就可以了,你固定去定位到固定的節點也可以,實際上PolarDB 是一個serverless的數據庫,也就是他可能上一分鐘,是2個節點,下一分鐘就彈出一個節點,變成3個節點,你是無法固定這些節點的ID或者位置,所以記住今天説了這麼多,PolarDB 中的一個命令。
/Force_ALL/ 他可以解決你在單點上可以解決,在雲原生上你認為無法解決的 90%的問題。
好了今天就到這裏,每天都是學習知識的一天。