一个要努力的人
能力说明:
了解变量作用域、Java类的结构,能够创建带main方法可执行的java应用,从命令行运行java程序;能够使用Java基本数据类型、运算符和控制结构、数组、循环结构书写和运行简单的Java程序。
暂时未有相关云产品技术能力~
阿里云技能认证
详细说明在自己的测试中发现
创建表是对于该表来说是最小的xid,那么relfrozenxid的值就是创建表的xid,不论后面更新插入删除,relfrozenxid都不会变,当age(relfrozenxid)>阀值时,就是强制调用vacuum freeze table;其实age()只是相对数,就是当前的事务id-表的最小事务id,随着当前事务id的增大,表被freeze后,relfrozenxid也会变大,只是中间的间隔变小。
而对于行来说,如果是vacuum table时,只要自己行的xid与最新的事务id相距不超过vacuum_freeze_min_age阀值时,就不会发生变化,如果超过这个阀值,行的xid就会变为freezeid(2),但是表的relfrozenxid取得的是除了2之外的最小值;就是有点难理解
不知道这样测试对不对,依据这个测试得出的结论不知道对不对
测试
osdba=# create table t_1(id int);
CREATE TABLE
osdba=# select pg_relation_filepath('t_1');
base/16384/16392
(1 row)
osdba=# dt+ t_1;
List of relations
Schema | Name | Type | Owner | Size | Description |
---|---|---|---|---|---|
public | t_1 | table | osdba | 0 bytes |
(1 row)
这是查看路径下的文件大小
[osdba@pg41 16384]$ ls -ls 16392 && ls -ls 1639
0 -rw-------. 1 osdba osdba 0 Feb 4 02:24 16392
0 -rw-------. 1 osdba osdba 0 Feb 4 02:24 16392
下面开启一个事务A:存入100数据并回滚
osdba=# begin;
BEGIN
osdba=# insert into t_1 (id) select generate_series(1,100);
INSERT 0 100
osdba=# rollback;
ROLLBACK
osdba=# dt+ t_1;
List of relations
Schema | Name | Type | Owner | Size | Description |
---|---|---|---|---|---|
public | t_1 | table | osdba | 16 kB |
(1 row)
在另外一个窗口发现
[osdba@pg41 16384]$ ls -ls 16392 && ls -ls 1639
8 -rw-------. 1 osdba osdba 8192 Feb 4 02:27 16392
8 -rw-------. 1 osdba osdba 8192 Feb 4 02:27 16392
下面开启一个事务B:存入100数据并提交
osdba=# begin;
BEGIN
osdba=# insert into t_1 (id) select generate_series(1,100);
INSERT 0 100
osdba=# commit;
COMMIT
osdba=# dt t_1;
List of relations
Schema | Name | Type | Owner |
---|---|---|---|
public | t_1 | table | osdba |
(1 row)
在另外一个窗口发现
[osdba@pg41 16384]$ ls -ls 16392 && ls -ls 1639
8 -rw-------. 1 osdba osdba 8192 Feb 4 02:32 16392
16 -rw-------. 1 osdba osdba 16384 Feb 4 02:31 16392_fsm
0 -rw-------. 1 osdba osdba 0 Feb 4 02:31 16392_vm
8 -rw-------. 1 osdba osdba 8192 Feb 4 02:32 16392
16 -rw-------. 1 osdba osdba 16384 Feb 4 02:31 16392_fsm
0 -rw-------. 1 osdba osdba 0 Feb 4 02:31 16392_vm
下面开启一次事务C:truncate table 后插入100数据,先不要提交或者回滚
osdba=# begin;
BEGIN
osdba=# truncate table t_1;
TRUNCATE TABLE
osdba=# insert into t_1 select generate_series(1,100);
INSERT 0 100
osdba=# select pg_relation_filepath('t_1');
base/16384/16395
(1 row)
在另外一个窗口发现
[osdba@pg41 16384]$ ls -ls 16392 && ls -ls 1639
8 -rw-------. 1 osdba osdba 8192 Feb 4 02:32 16392
16 -rw-------. 1 osdba osdba 16384 Feb 4 02:31 16392_fsm
0 -rw-------. 1 osdba osdba 0 Feb 4 02:31 16392_vm
8 -rw-------. 1 osdba osdba 8192 Feb 4 02:32 16392
16 -rw-------. 1 osdba osdba 16384 Feb 4 02:31 16392_fsm
0 -rw-------. 1 osdba osdba 0 Feb 4 02:31 16392_vm
8 -rw-------. 1 osdba osdba 8192 Feb 4 02:33 16395
通过测试发现truncate table 后,其实并没有真正的删除该文件,而是重新创建一个文件,当新的数据入库时,存入的是新的文件,但是对于上层访问的表来说,表的结构等并没有发生变化。也就是可以理解为什么在postgres事务内,truncate table 这种ddl语句可以支持回滚的原因。
事务C回滚后,就会发现事务中的操作都会撤销。
osdba=# rollback;
ROLLBACK
$ ls -ls 16392 && ls -ls 1639
8 -rw-------. 1 osdba osdba 8192 Feb 4 02:35 16392
16 -rw-------. 1 osdba osdba 16384 Feb 4 02:31 16392_fsm
0 -rw-------. 1 osdba osdba 0 Feb 4 02:31 16392_vm
8 -rw-------. 1 osdba osdba 8192 Feb 4 02:35 16392
16 -rw-------. 1 osdba osdba 16384 Feb 4 02:31 16392_fsm
0 -rw-------. 1 osdba osdba 0 Feb 4 02:31 16392_vm
而新出现的文件名16395就被彻底删除
事务C提交后,文件16392存在一段时间后,之后被回收。
osdba=# begin;
BEGIN
osdba=# truncate table t_1;
TRUNCATE TABLE
osdba=# select pg_relation_filepath('t_1');
base/16384/16396
(1 row)
osdba=# insert into t_1 select generate_series(1,100);
INSERT 0 100
osdba=# commit;
COMMIT
[osdba@pg41 16384]$ ls -ls 16392 && ls -ls 1639
0 -rw-------. 1 osdba osdba 0 Feb 4 02:48 16392
0 -rw-------. 1 osdba osdba 0 Feb 4 02:48 16392
8 -rw-------. 1 osdba osdba 8192 Feb 4 02:48 16396
事务C如果提交,就会发现16392其他后缀文件被删除,_fsm的文件记录每个数据块的空闲空间,_vm的文件用来标记数据块中是否存在需要清理的行。
在过一段时间再次执行查看文件名
[osdba@pg41 16384]$ ls -ls 1639*
8 -rw-------. 1 osdba osdba 8192 Feb 4 02:50 16396
只有一个t_1的最新文件16396存在。
那么现在新的问题出现了,在刚开始创建表时,空间大小是0kb,在文件里面也是,那么表的结构约束不占用空间吗?还是存在了其他地方?还有一个问题,数据存入到文件中,只是数据存入到文件,而表的字段是否也跟着数据一条一条存入到数据文件中呢?
猜测
1、bgwriter写入数据
2、wal切换时要求写入数据
3、wal切换通知checkpoint,要求将data buffer写入到磁盘中
4、data buffer不足,写入磁盘
这是上面的那一种情况呢?
在A点 做完基础备份后,分别在B点切换xlog日志,在C点切换xlog日志,现在恢复到B点后,在D点切换xlog日志,在E点切换xlog日志,现在模拟数据库被删除,从基础备份A点开始,恢复到D,E点失败,恢复到B点,C点成功,问题如下,是否在第一次恢复到B点时,就要做一个基础备份,才能恢复D点和E点?
问题应该是找到了recovery_target_timeline,重新恢复到B点时,timeline切换了,而recovery.conf文件默认的recovery_target_timeline='lastest',在文章中timeline写到The default behavior of recovery is to recover along the same timeline that was current when the base backup was taken. If you wish to recover into some child timeline (that is, you want to return to some state that was itself generated after a recovery attempt), you need to specify the target timeline ID in recovery.conf,就是说默认按照基础备份时间线来处理,我们就需要在recovery.conf的recovery_target_timeline来制定其他时间线。本次我的方案切换的时间刻度线是00000002,修改参数recovery_target_timeline = '00000002'
后面还有一种测试环境是standby数据库异常挂掉,但是主机正常,standby网络正常,当主机大批量入数据时,standby一直在做归档,之后启动standby的postgres数据库,是有归档日志恢复的
这个问题也有遇到,基本是大量的数据(千万级)量在同步,没有找到解决办法
是这样一个情况,我在部署安装greenplum时,gp封装了ssh,可以对着远程执行很多命令,包括时间统一,关闭机器,我就想着是否这一直接使用ssh这种方式来关闭机器等一系列可以同时执行的操作
当新的会话(事务)对其数据修改默认值重新变成0,对吗?请教一个问题,在配置日志文件时,其中syslog,stderr,其中一个标准错误,但是syslog是什么?如果我将log_statement设置为all,那么是否使用外部表或者copy方式插入数据,日志会变得更大?