天天看點

PostgreSQL 資料庫執行個體隻讀鎖定(readonly) - 硬鎖定,軟鎖定,解鎖

标簽

PostgreSQL , 隻讀 , 鎖定 , readonly , recovery.conf , 恢複模式 , pg_is_in_revoery , default_transaction_read_only

https://github.com/digoal/blog/blob/master/201901/20190130_02.md#%E8%83%8C%E6%99%AF 背景

在一些場景中,可能要将資料庫設定為隻讀模式。

例如,

1、雲資料庫,當使用的容量超過了購買的限制時。切換到隻讀(鎖定)模式,確定使用者不會用超。

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

鎖定的實作方法有若幹種。

1、硬鎖定,直接将資料庫切換到恢複模式,絕對不會有寫操作出現。

2、軟鎖定,設定default_transaction_read_only為on,預設開啟的事務為隻讀事務。使用者如果使用begion transaction read write可破解。

3、核心層面改進的鎖定,對于雲上産品,鎖定後實際上是期望使用者更新容量,或者使用者可以上去删資料使得使用空間降下來的。那麼以上兩種鎖定都不适用,需要禁止除truncate, drop操作以外的所有操作的這種鎖定方式。而且最好是不需要重新開機資料庫就可以實作。

https://github.com/digoal/blog/blob/master/201901/20190130_02.md#%E5%AE%9E%E7%8E%B0 實作

https://github.com/digoal/blog/blob/master/201901/20190130_02.md#1-%E9%94%81%E5%AE%9A%E5%AE%9E%E4%BE%8B 1 鎖定執行個體

https://github.com/digoal/blog/blob/master/201901/20190130_02.md#%E7%A1%AC%E9%94%81%E5%AE%9A 硬鎖定

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  
           

https://github.com/digoal/blog/blob/master/201901/20190130_02.md#%E8%BD%AF%E9%94%81%E5%AE%9A 軟鎖定

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  
           

https://github.com/digoal/blog/blob/master/201901/20190130_02.md#2-%E8%A7%A3%E9%94%81%E5%AE%9E%E4%BE%8B 2 解鎖執行個體

https://github.com/digoal/blog/blob/master/201901/20190130_02.md#%E7%A1%AC%E8%A7%A3%E9%94%81 硬解鎖

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

cd $PGDATA  
  
mv recovery.conf recovery.done  
           
pg_ctl restart -m fast  
           

https://github.com/digoal/blog/blob/master/201901/20190130_02.md#%E8%BD%AF%E8%A7%A3%E9%94%81 軟解鎖

postgres=# alter system set default_transaction_read_only=off;  
ALTER SYSTEM  
           
postgres=# select pg_reload_conf();  
 pg_reload_conf   
----------------  
 t  
(1 row)  
           
postgres=# show default_transaction_read_only ;  
 default_transaction_read_only   
-------------------------------  
 on  
(1 row)  
           
postgres=# show default_transaction_read_only ;  
 default_transaction_read_only   
-------------------------------  
 off  
(1 row)  
  
寫恢複  
postgres=# insert into t1 values (1);  
INSERT 0 1  
           

https://github.com/digoal/blog/blob/master/201901/20190130_02.md#%E5%86%85%E6%A0%B8%E5%B1%82%E9%94%81%E5%AE%9A 核心層鎖定

通過修改核心實作鎖定,鎖定後隻允許:

1、truncate

2、drop

這樣,使用者可以在鎖定的情況下進行資料清理,可以跑任務的形式,檢查資料是否清理幹淨,進行解鎖設定。

阿裡雲RDS PG已支援。

https://github.com/digoal/blog/blob/master/201901/20190130_02.md#%E5%8F%82%E8%80%83 參考

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

https://github.com/digoal/blog/blob/master/201901/20190130_02.md#%E5%85%8D%E8%B4%B9%E9%A2%86%E5%8F%96%E9%98%BF%E9%87%8C%E4%BA%91rds-postgresql%E5%AE%9E%E4%BE%8Becs%E8%99%9A%E6%8B%9F%E6%9C%BA 免費領取阿裡雲RDS PostgreSQL執行個體、ECS虛拟機

PostgreSQL 資料庫執行個體隻讀鎖定(readonly) - 硬鎖定,軟鎖定,解鎖