雲計算

PostgreSQL 數據庫實例只讀鎖定(readonly) – 硬鎖定,軟鎖定,解鎖

PostgreSQL 數據庫實例只讀鎖定(readonly) - 硬鎖定,軟鎖定,解鎖

作者

digoal

日期

2019-01-30

標籤

PostgreSQL , 只讀 , 鎖定 , readonly , recovery.conf , 恢復模式 , pg_is_in_revoery , default_transaction_read_only


背景

在一些場景中,可能要將數據庫設置為只讀模式。

例如,

1、雲數據庫,當使用的容量超過了購買的限制時。切換到只讀(鎖定)模式,確保用戶不會用超。

2、業務上需要對數據庫進行遷移,準備割接時,可將主庫切換到只讀(鎖定),確保絕對不會有事務寫入。

鎖定的實現方法有若干種。

1、硬鎖定,直接將數據庫切換到恢復模式,絕對不會有寫操作出現。

2、軟鎖定,設置default_transaction_read_only為on,默認開啟的事務為只讀事務。用戶如果使用begion transaction read write可破解。

3、內核層面改進的鎖定,對於雲上產品,鎖定後實際上是期望用戶升級容量,或者用戶可以上去刪數據使得使用空間降下來的。那麼以上兩種鎖定都不適用,需要禁止除truncate, drop操作以外的所有操作的這種鎖定方式。而且最好是不需要重啟數據庫就可以實現。

實現

1 鎖定實例

硬鎖定

1、配置 recovery.conf

recovery_target_timeline = 'latest'  
standby_mode = on  

2、重啟數據庫

pg_ctl restart -m fast  

3、硬鎖定,不可破解

postgres=# select pg_is_in_recovery();  
 pg_is_in_recovery   
-------------------  
 t  
(1 row)  
  
postgres=# insert into t1 values (1);  
ERROR:  cannot execute INSERT in a read-only transaction  
  
postgres=# begin transaction read write;  
ERROR:  cannot set transaction read-write mode during recovery  

軟鎖定

1、設置default_transaction_read_only

postgres=# alter system set default_transaction_read_only=on;  
ALTER SYSTEM  

2、重載配置

postgres=# select pg_reload_conf();  
 pg_reload_conf   
----------------  
 t  
(1 row)  

3、所有會話自動進入read only的默認事務模式。

reload前

postgres=# show default_transaction_read_only ;  
 default_transaction_read_only   
-------------------------------  
 off  
(1 row)  

reload後

postgres=# show default_transaction_read_only ;  
 default_transaction_read_only   
-------------------------------  
 on  
(1 row)  
  
postgres=# insert into t1 values (1);  
ERROR:  cannot execute INSERT in a read-only transaction  

4、軟鎖定可破解

postgres=# begin transaction read write;  
BEGIN  
postgres=# insert into t1 values (1);  
INSERT 0 1  
postgres=# end;  
COMMIT  

2 解鎖實例

硬解鎖

1、重命名recovery.conf到recovery.done

cd $PGDATA  
  
mv recovery.conf recovery.done  

2、重啟數據庫

pg_ctl restart -m fast  

軟解鎖

1、設置default_transaction_read_only

postgres=# alter system set default_transaction_read_only=off;  
ALTER SYSTEM  

2、重載配置

postgres=# select pg_reload_conf();  
 pg_reload_conf   
----------------  
 t  
(1 row)  

3、所有會話自動進入read only的默認事務模式。

reload前

postgres=# show default_transaction_read_only ;  
 default_transaction_read_only   
-------------------------------  
 on  
(1 row)  

reload後

postgres=# show default_transaction_read_only ;  
 default_transaction_read_only   
-------------------------------  
 off  
(1 row)  
  
寫恢復  
postgres=# insert into t1 values (1);  
INSERT 0 1  

內核層鎖定

通過修改內核實現鎖定,鎖定後只允許:

1、truncate

2、drop

這樣,用戶可以在鎖定的情況下進行數據清理,可以跑任務的形式,檢查數據是否清理乾淨,進行解鎖設置。

阿里雲RDS PG已支持。

參考

https://www.postgresql.org/docs/11/recovery-config.html

https://www.postgresql.org/docs/11/runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT

https://www.postgresql.org/docs/11/functions-admin.html#FUNCTIONS-ADMIN-SIGNAL

免費領取阿里雲RDS PostgreSQL實例、ECS虛擬機

大量阿里雲PG解決方案: 任意維度實時圈人; 時序數據實時處理; 時間、空間、業務 多維數據實時透視; 獨立事件相關性分析; 海量關係實時圖式搜索; 社交業務案例; 流式數據實時處理案例; 物聯網; 全文檢索; 模糊、正則查詢案例; 圖像識別; 向量相似檢索; 數據清洗、採樣、脫敏、批處理、合併; GIS 地理信息空間數據應用; 金融業務; 異步消息應用案例; 海量數據 冷熱分離; 倒排索引案例; 海量數據OLAP處理應用;

德哥的 / digoal's PostgreSQL文章入口 - 努力做成PG資源最豐富的個人blog

德哥的微信 / digoal's wechat

Leave a Reply

Your email address will not be published. Required fields are marked *