天天看點

資料庫平滑switchover的要素 - 會話資源漂移

postgresql , 中間件 , 連接配接池 , 平滑切換 , 會話設定 , 會話狀态 , 綁定變量語句 , prepared statement

資料庫遷移、切換是很普遍的一個話題,但是大多數的方案,對使用者來說都是有感覺的,是以使用者的體驗并不好。

例如使用者使用了綁定變量語句,主備角色切換後綁定變量語句沒有了,會導緻調用報錯。

我們需要維護主庫的硬體,那麼可以在中間件層面,将主備資料庫的角色進行平滑調換,維護好硬體,再平滑的調換回來。

資料庫主備切換時,如何做到會話級無感覺?首先我們要了解會話中都有哪些内容,哪些内容是需要随角色切換一起遷移的。進而做到使用者無感覺。

(本文ha指中間件層級的ha,并非app直連資料庫,vip切換的那種ha。)

簡單的switchover過程舉例:

等待所有會話的事務結束,會話都處于idle狀态,當機會話,不允許送出任何sql,然後進行角色切換,并将每個會話的資源狀态平移。

會話中有些什麼狀态?通過discard這條sql就可以了解。

<a href="https://www.postgresql.org/docs/10/static/sql-discard.html">https://www.postgresql.org/docs/10/static/sql-discard.html</a>

discard all相當于執行如下

會話資源中目前可能包含如下(每個pg版本可能有些許差異):

sessoin角色、參數設定、綁定變量語句、遊标、異步消息監聽、ad鎖、序列、臨時表等。

下面介紹一下每種資源的查詢方法,以及在新的主庫上進行資源複原的方法。

超級使用者可以将會話使用者設定為其他使用者,普通使用者無權切換使用者。

目前使用者為postgres,設定session authorization為test

當pg_stat_activity.usename不等于session authorization時,需要通過如下方法複原它。

postgresql的一些參數是允許使用者在會話、事務中進行設定的。如下context in ('user','superuser')時,使用者可以在會話或事務中設定。

設定例子

使用綁定變量可以減少資料庫的parser, plan開銷,提高高并發的查詢性能,同時避免sql注入。

不同的驅動,有不同的使用方法。

<a href="https://www.postgresql.org/docs/10/static/libpq-exec.html#libpq-exec-main">https://www.postgresql.org/docs/10/static/libpq-exec.html#libpq-exec-main</a>

使用綁定變量的例子

不同的驅動,複原方法不一樣。

請根據pg_prepared_statements的内容進行複原。

如果我們使用了hold選項,那麼遊标不會随事務結束而關閉,是以在遷移會話時也需要注意是否有這類遊标。

postgresql的異步消息,可以通過異步消息,推送事件。例子如下:

<a href="https://www.postgresql.org/docs/10/static/libpq-notify.html">https://www.postgresql.org/docs/10/static/libpq-notify.html</a>

<a href="https://www.postgresql.org/docs/10/static/libpq-example.html#libpq-example-2">https://www.postgresql.org/docs/10/static/libpq-example.html#libpq-example-2</a>

查詢已經開啟了哪些異步監聽

advisory lock可以用于秒殺、解決高并發鎖沖突問題、解決無空洞序列值問題等。

<a href="https://github.com/digoal/blog/blob/master/201705/20170507_02.md">《postgresql 使用advisory lock實作行級讀寫堵塞》</a>

<a href="https://github.com/digoal/blog/blob/master/201610/20161020_02.md">《postgresql 無縫自增id的實作 - by advisory lock》</a>

<a href="https://github.com/digoal/blog/blob/master/201610/20161018_01.md">《postgresql 使用advisory lock或skip locked消除行鎖沖突, 提高幾十倍并發更新效率》</a>

<a href="https://github.com/digoal/blog/blob/master/201611/20161117_01.md">《聊一聊雙十一背後的技術 - 不一樣的秒殺技術, 裸秒》</a>

advisory lock分為事務級鎖和會話級鎖,在會話遷移時,會話處于idle狀态, 隻需要關注會話級鎖。

注意複原時,需要指定是否為shared lock。

序列使用後,會在會話中存儲最後一次使用的序列的val,以及每個序列被使用後的最後一次擷取的val。

序列雖然可以設定目前值,但是會影響全局,強烈建議不要這麼做。

目前沒有好的方法複原序列在會話中的lastval。

主備切換時,将會話資源狀态進行平移,可以大幅提升用戶端的體驗,使得資料庫硬體維護、遷移等工作也會變得更加輕松。

中間件需要維護用戶端連接配接和資料庫會話的映射關系,平移後映射關系同樣需要保持一緻。