标簽
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-SIGNALhttps://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虛拟機
