PostgreSQL原始碼定製:線上global read only
基於某雲上功能需求,最近實現了類似於MySQL global read only的功能。PG的read only功能,也不再需要透過重起PG實現來實現。直接可以online更改PG例項級別
global read only 和 global read write功能, 以達到快速實現主備切換的功能。大大縮短了主備切換時間,提高了PG的高可性。彌補了PG在這一功能上的不足。
此次透過原始碼定製更改實現的PG版本global read only有許多明顯的優勢:
1.在設定global read only時,新的查詢不會被堵
新進來session,read only直接生效,不需要重起PG例項。並用在設定global read only時,不會堵住新會話。因此避免了連線擁堵現象。
2.正在跑的事務,分級別對待
a.如果是事務塊,也就是使用者發起的”BEGIN”語句,那麼已經執行完畢的語句不受影響。對於此事務中後面執行的語句,會受read only約束,不能執行DML操作。本事務會被終止。
b.如果是正在跑的語句,比如說有一個大的insert或者update。那麼此操作不會受影響,設定 global read only需要等待此操作完成後,才返回。
global read only操作會等待所有running 的DML操作完成,並且做完”Immediate Checkpoint”後,再返回響應。這樣做的理由是為了確保資料庫狀態的一致性。
尤其是在主備切換的情況下,更為關鍵和重要。
3.中斷處理
如果在設定 global read only時失敗,那麼會被回滾,會被重新置為read write狀態。
下面展示下原始碼patch實現結果:
session 1:檢視當前資料庫read only狀態,顯示當前為”Read Write”狀態,即PG例項級別可以讀寫。
session 2:起事務,事務中為兩個insert語句。我們先執行一個insert語句,但是不提交事務。
表建立語句:
create table grl_test (id int);
begin;
insert into grl_test values(1);
session 1:嘗試將PG例項設定為global read only。此時可以看到,不能設定為”Read Only“狀態,設定”Read Only”操作沒有返回。
原因為 session 2並沒有提交。這個符合我們的設計初衷,就是read only設定成功返回時,資料庫為一致狀態,此後沒有user 級別寫事務。
session 2:嘗試發起第二條insert語句。可以看到insert失敗了。原因為session 1嘗試設定為 global read only時,雖然操作沒有返回,
但是新的任何DML操作以及新的事務已經被約束為read only狀態。不允許新的寫事務容易理解,但是為什麼不允許之前已經發起的事務中,不能DML操作呢?
這樣做的原因是:
我們不想讓先於設定read only之前的事務塊,無限制的跑下去。這會讓設定global read only的操作一直進行下去。如果read only設定不成功,
直接影響到主備的快速切換。細心的同學可能會發現,這隻限於事務塊。的確如此,事務塊與一般事務的區別,請見我另外一篇文章”PostgreSQL 事務模型介紹“。
因為一般事務,只在command級別,跑完就結束了。我們可以等待,一般使用者也容易理解,如果我們強行終止此類操作,會對應用影響比較大。一般command
級別的事務總是非常快的結束,尤其在OLTP系統中,基本上都是簡單的command級別事務。事務塊一般邏輯比較複雜,有這一限制,也是為了資料一致性考慮,
失敗了,頂多重新跑就行了。總體上來講,這也是基於目前市面上OLTP類應用系統的現實需求而定製的。
insert into grl_test values(2);
session 1:此時我們再來看session 1時,設定global read only已經成功了。session 2因為第二個命令違背了read only,導致事務被終止了。因此,也就再沒有
running transaction了。global read only設定完成後,checkpoint向前推。我們就可以以此checkpoint為準,進行主備一致性切換。
上面完全實現了線上更改PG例項read only狀態。我們再將例項線上改回到read write。是不是非常方便呢?
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/30088583/viewspace-1669961/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Innodb Read Only Mode
- oracle 表空間和表 read only遷移後不再read onlyOracle
- read only tablespace backup restoreREST
- 事務的read only mode
- 關於tablespace在read only狀態下的DML ,DDL操作--Read-Only Tablespaces
- MySQL 5.6 global read lock 介紹MySql
- CSS :read-only 選擇器CSS
- 當從READ ONLY到READ WRITE都做什麼了
- Oracle SYS使用者無法設定session級別的read onlyOracleSession
- 3.2.3 Opening a Database in Read-Only ModeDatabase
- DG -- READ ONLY模式開啟物理Standby模式
- Oracle Isolation Levels : Read-only (317)Oracle
- 原始碼分析:如何定製Semantic-UI原始碼UI
- 如何不使用 trn log 將read only (且能使用trn 恢復)的庫設定為read/write
- 原始碼安裝postgresql原始碼SQL
- PostgreSQL 定製psql提示符SQL
- MySQL5.7 Waiting for global read lockMySqlAI
- Open a Database in Read-Only Mode (301)Database
- MySQl報錯之@@GLOBAL.GTID_PURGED can only be set when @@GLOBAL.GTID_MODE = ONMySql
- Seed Database (pdb$seed) - Read Write OR Read Only Mode in Oracle Database 12cDatabaseOracle
- Oracle vs PostgreSQL Develop(31) - Index Only ScanOracleSQLdevIndex
- PostgreSQL MVCC 原始碼實現SQLMVC原始碼
- MySQL 報錯'Variable 'XXX' is a read only variable'MySql
- RMAN結合Read Only、Exclude的備份策略
- 作業系統報:read-only file system作業系統
- 影視APP系統原始碼,定製開發功能APP原始碼
- PostgreSQL 原始碼解讀(3)- 如何閱讀原始碼SQL原始碼
- 線上直播原始碼,npm設定映象的方法 可切換原始碼NPM
- Why NHibernate updates DB on commit of read-only transactionMIT
- Read-Only Tables in Oracle Database 11g Release 1OracleDatabase
- 啟動dataguard備庫到read-only狀態
- oracle實驗記錄 (恢復read only tablespace(1))Oracle
- oracle實驗記錄 (恢復read only tablespace(2))Oracle
- 仿微信APP聊天IM原始碼出售轉讓,可定製APP原始碼
- 電影APP系統原始碼,定製功能開發APP原始碼
- 短影片APP系統原始碼,定製開發功能APP原始碼
- PostgreSQL:原始碼目錄結構SQL原始碼
- PostgreSQL-原始碼安裝(一)SQL原始碼