PostgreSQL数据库实例只读锁问题
2020-07-10 本文已影响0人
Hmcf
锁定的实现方法有若干种。
- 硬锁定,直接将数据库切换到恢复模式,绝对不会有写操作出现。
- 软锁定,设置default_transaction_read_only为on,默认开启的事务为只读事务。用户如果使用begion transaction read write可破解。
- 内核层面改进的锁定,对于云上产品,锁定后实际上是期望用户升级容量,或者用户可以上去删数据使得使用空间降下来的。那么以上两种锁定都不适用,需要禁止除truncate, drop操作以外的所有操作的这种锁定方式。而且最好是不需要重启数据库就可以实现。
锁定实例
硬锁定
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
解锁实例
硬解锁
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