阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

postgres unlogged表的数据丢失问题

209次阅读
没有评论

共计 12549 个字符,预计需要花费 32 分钟才能阅读完成。

一环境

数据库版本 Postgres 9.5.1

操作系统系统:CentOS 6.5 64

二问题发现结果

(1) 一个 unlogged 表 (不管是否 checkpoint), 当数据库异常关机重启后,该表数据被清空。

(2) 一个 unlogged 表, 插入数据,切换日志,之后用 pg_rman 备份数据库与归档日志,然后正常关闭数据库,利用备份还原恢复数据库时,会把 unlogged 表中的数据清空。

(3) 利用 pg_dump 逻辑导出 unlogged 表数据时,如果采用文本文件方式可以发现,其定义创建语句也是 unlogged 方式,恢复时请注意。

注意

大家是不是要小心使用 unlogged 表了 - 能提升数据插入时的性能,但是插入完成一定记得改为 logged 表。

三实验

postgres 版本

PostgreSQL9.5.1 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.4.7 20120313 (RedHat 4.4.7-4), 64-bit

(1row)

3.1 测试 1

创建普通表和日志表,插入数据测试 (checkpoint),正常关闭数据库。

结果:普通表和日志表数据都不丢失

// 建表
test=# create  unlogged table  test_unlogged (id integer, name text);

test=# create  table  test (id integer, name text);

// 插入数据测试 (不 checkpoint)

test=# insert into test  select generate_series(1,10000),’test’;

INSERT 0 10000

test=# insert into test_unlogged  select generate_series(1,10000),’test’;

INSERT 0 10000

// 正常关机重启后查数据

pg_ctl  -D  /pgdb/data stop;

test=# select count(*) from  test;

 count

——-

 10000

(1 row)

test=# select count(*) from  test_unlogged;

 count

——-

 10000

(1 row)

3.2 测试 2

创建普通表和日志表

插入数据测试 (不 checkpoint)

异常关闭数据库 pg_ctl  -D  /pgdb/data  stop -m immediate

操作过程同上。

结果:异常关闭数据库重启后 unlogged 表 test_unlogged 数据清空;logged 表 test 数据不丢失。

3.3 测试 3

创建普通表和日志表

插入数据测试 (checkpoint)

异常关闭数据库 pg_ctl  -D  /pgdb/data  stop -m immediate,之后重启

操作步骤同上

结果:异常关闭数据库重启后,unlogged 表 test_unlogged 数据无;logged 表 test 数据不丢失。

test=# drop table test;

test=# drop table test_unlogged;

test=# create  unlogged table  test_unlogged (id integer, name text);

test=# create  table  test (id integer, name text);

test=# select relname,relpersistence  from pg_class where relname  like ‘test%’;

    relname    | relpersistence

—————+—————-

 test          | p

 test_unlogged  | u

test=# insert into test_unlogged  select generate_series(1,10000),’test’;

INSERT 0 10000

Time: 6.687 ms    // 可以看出插入时间

test=# insert into test  select generate_series(1,10000),’test’;

INSERT 0 10000

Time: 48.511 ms  // 可以看出插入时间

test=# checkpoint;

CHECKPOINT

Time: 100.727 ms

// 此处异常关闭数据库 pg_ctl  -D  /pgdb/data  stop -m immediate,并重启

test=# \q

[postgres@pg1 ~]$ psql  -d  test  -U dba -p 5432

psql (9.5.1)

Type “help” for help.

test=# \dt

          List of relations

 Schema |    Name      | Type  | Owner

——–+—————+——-+——-

 public | test          | table | dba

 public | test_unlogged | table | dba

(2 rows)

test=# select count(*)  from  test;

 count

——-

 10000

(1 row)

test=# select count(*)  from  test_unlogged;

 count

——-

    0

(1 row)

3.4 测试 4

创建 unlogged 表 test_unlogged

插入数据,正常关机,之后,test_unlogged 数据正常不丢失,

然后再次插入数据,异常关机,重启之后 unlogged 表 test_unlogged 数据无。

test=# \dt

          List of relations

 Schema |    Name      | Type  | Owner

——–+—————+——-+——-

 public | test          | table | dba

 public | test_unlogged | table | dba

(2 rows)

test=# select count(*)  from  test_unlogged;

 count

——-

    0

(1 row)

test=# select relname,relpersistence  from pg_class where relname  like ‘test%’;

    relname    | relpersistence

—————+—————-

 test          | p

 test_unlogged | u

(2 rows)

test=# insert into test_unlogged  select generate_series(1,10000),’test’;

INSERT 0 10000

// 此处正常关闭数据库 [postgres@pg1 ~]$ pg_ctl  -D  /pgdb/data  stop

// 再启动查询

test=# select count(*)  from test_unlogged;

 count

——-

 10000

(1 row)

// 再次插入数据

test=# insert into test_unlogged  select generate_series(1,10000),’test’;

INSERT 0 10000

test=# checkpoint

test-# ;

CHECKPOINT

// 此处异常关闭数据库 [postgres@pg1 ~]$ pg_ctl  -D  /pgdb/data  stop -m immediate

// 再启动, 查看数据

test=# select count(*)  from test_unlogged;

 count

——-

    0

(1 row)

3.5 测试 5

同测试 4,,不过异常关机改为 kill  checkpointer process 进程,结果结论同测试 4,重启之后 unlogged 表 test_unlogged 数据无。

test=# select count(*)  from test_unlogged;

 count

——-

    0

(1 row)

test=# select relname,relpersistence  from pg_class where relname  like ‘test%’;

    relname    | relpersistence

—————+—————-

 test          | p

 test_unlogged | u

(2 rows)

test=# insert into test_unlogged  select generate_series(1,10000),’test’;

INSERT 0 10000

// 此处正常关闭数据库,重启

test=# select count(*)  from test_unlogged;

 count

——-

 10000

(1 row)

test=# insert into test_unlogged  select generate_series(1,10000),’test’;

INSERT 0 10000

test=# checkpoint;

CHECKPOINT

// 此处准备杀 checkpointer process,以使数据库重启

//[postgres@pg1 ~]$ ps -ef |grep postgres

//[postgres@pg1 ~]$ kill -9  checkpointer process 进程号

test=# select count(*)  from test_unlogged;

 count

——-

    0

(1 row)

四其他

4.1pg_dump 逻辑导出数据

Unlogged 表逻辑 dump 之后,在 dump 文件中建表语句也是 Unlogged 方式,可想而知恢复导入时也是 Unlogged 表。

4.2pg_rman 物理备份数据

postgres=# create  unlogged table  test_unlogged (id integer, name text);

postgres=# select relname,relpersistence  from pg_class where relname  like ‘test%’;

    relname    | relpersistence

—————+—————-

 test_unlogged | u

postgres=# select count(*)  from test_unlogged;

 count

——-

    0

test=# insert into test_unlogged values (1,’twj1′);

INSERT 0 1

// 此时备份数据库全备:

[root@pg1 Desktop]# mkdir  /pgdb/backup/pg_rman

[root@pg1 Desktop]# chown  -R  postgres:postgres  /pgdb

[root@pg1 Desktop]# su – postgres

[postgres@pg1 ~]$ pg_rman init -B /pgdb/backup/pg_rman

[postgres@pg1 ~]$ export BACKUP_PATH=/pgdb/backup/pg_rman

[postgres@pg1 ~]$ export ARCLOG_PATH=/pgdb/archive5432

[postgres@pg1 ~]$ pg_rman backup  -b  full  -p 5432  -U dba

[postgres@pg1 ~]$ pg_rman validate

 postgres@pg1 ~]$ pg_rman show

==========================================================

 StartTime          Mode  Duration    Size  TLI  Status

==========================================================

2016-04-13 18:07:40  FULL        0m    58MB    1  OK

// 之后插入数据继续

test=# insert into test_unlogged values (2,’twj2′);

INSERT 0 1

test=# insert into test_unlogged values (3,’twj3′);

INSERT 0 1

test=# select *  from  test_unlogged;

 id | name

—-+——

  1 | twj1

  2 | twj2

  3 | twj3

postgres=#  select  pg_switch_xlog();

 pg_switch_xlog

—————-

 0/30000B8

(1 row)

postgres=# select  *    from pg_xlogfile_name_offset(‘0/30000B8’);

        file_name        | file_offset

————————–+————-

 000000010000000000000003 |        184

(1 row)   

// 同时观察归档文档:

[postgres@pg1 ~]$ cd  /pgdb/archive5432

[postgres@pg1 ~]$ls

000000010000000000000001  000000010000000000000002.00000028.backup

000000010000000000000002  000000010000000000000003

// 继续归档日志

[postgres@pg1 ~]$ pg_rman backup  -b  archive  -p 5432  -U dba

[postgres@pg1 ~]$ pg_rman validate

[postgres@pg1 ~]$ pg_rman show

==========================================================

 StartTime          Mode  Duration    Size  TLI  Status

==========================================================

2016-04-13 18:12:25  ARCH        0m    16MB     1  OK

2016-04-13 18:07:40  FULL        0m    58MB    1  OK

以下分 2 种情况

(1) 这个模拟故障恢复

[postgres@pg1 ~]$  pg_ctl  -D  /pgdb/data  stop -m immediate

waiting for server to shut down… done

server stopped

开始恢复(直接在原库操作,原库假设认为损坏)

[postgres@pg1 archive1975]$ pg_rman restore

[postgres@pg1 ~]$  pg_rman restore

INFO: the recovery target timeline ID is not given

INFO: use timeline ID of current database cluster as recovery target: 1

INFO: calculating timeline branches to be used to recovery target point

INFO: searching latest full backup which can be used as restore start point

INFO: found the full backup can be used as base in recovery: “2016-04-13 18:07:40”

INFO: copying online WAL files and server log files

INFO: clearing restore destination

INFO: validate: “2016-04-13 18:07:40” backup and archive log files by SIZE

INFO: backup “2016-04-13 18:07:40” is valid

INFO: restoring database files from the full mode backup “2016-04-13 18:07:40”

INFO: searching incremental backup to be restored

INFO: searching backup which contained archived WAL files to be restored

INFO: backup “2016-04-13 18:07:40” is valid

INFO: restoring WAL files from backup “2016-04-13 18:07:40”

INFO: validate: “2016-04-13 18:12:25” archive log files by SIZE

INFO: backup “2016-04-13 18:12:25” is valid

INFO: restoring WAL files from backup “2016-04-13 18:12:25”

INFO: restoring online WAL files and server log files

INFO: generating recovery.conf

INFO: restore complete

HINT: Recovery will start automatically when the PostgreSQL server is started.

// 启动数据库

[postgres@pg1 ~]$  pg_ctl  -D  /pgdb/data  start

server starting

[postgres@pg1 ~]$ LOG:  database system was interrupted; last known up at 2016-04-13 18:07:41 PDT

LOG:  starting archive recovery

LOG:  restored log file “000000010000000000000002” from archive

LOG:  redo starts at 0/2000098

LOG:  consistent recovery state reached at 0/20000C0

LOG:  restored log file “000000010000000000000003” from archive

cp: cannot stat `/pgdb/archive1975/000000010000000000000004′: No such file or directory

LOG:  redo done at 0/30000A0

LOG:  last completed transaction was at log time 2016-04-13 18:08:58.930459-07

LOG:  restored log file “000000010000000000000003” from archive

cp: cannot stat `/pgdb/archive1975/00000002.history’: No such file or directory

LOG:  selected new timeline ID: 2

cp: cannot stat `/pgdb/archive1975/00000001.history’: No such file or directory

LOG:  archive recovery complete

LOG:  MultiXact member wraparound protections are now enabled

LOG:  database system is ready to accept connections

LOG:  autovacuum launcher started

// 然后连接查看:

postgres=# select *  from  test_unlogged;

 id | name

—-+——

(0 rows)

结果数据为空。

(2) 这个模拟正常关机后恢复

[postgres@pg1 ~]$ pg_ctl  -D /pgdb/data  stop

 [postgres@pg1 ~]$ pg_rman restore

INFO: the recovery target timeline ID is not given

INFO: use timeline ID of current database cluster as recovery target: 1

INFO: calculating timeline branches to be used to recovery target point

INFO: searching latest full backup which can be used as restore start point

INFO: found the full backup can be used as base in recovery: “2016-04-13 18:07:40”

INFO: copying online WAL files and server log files

INFO: clearing restore destination

INFO: validate: “2016-04-13 18:07:40” backup and archive log files by SIZE

INFO: backup “2016-04-13 18:07:40” is valid

INFO: restoring database files from the full mode backup “2016-04-13 18:07:40”

INFO: searching incremental backup to be restored

INFO: searching backup which contained archived WAL files to be restored

INFO: backup “2016-04-13 18:07:40” is valid

INFO: restoring WAL files from backup “2016-04-13 18:07:40”

INFO: validate: “2016-04-13 18:12:25” archive log files by SIZE

INFO: backup “2016-04-13 18:12:25” is valid

INFO: restoring WAL files from backup “2016-04-13 18:12:25”

INFO: restoring online WAL files and server log files

INFO: generating recovery.conf

INFO: restore complete

HINT: Recovery will start automatically when the PostgreSQL server is started.

// 连接查询

postgres=# select *  from  test_unlogged;

 id | name

—-+——

(0 rows)

同样结果没有数据。

(3) 再上例的环境下,再次新建表,再备份之后原机恢复或者异机恢复备份数据。

test=# select *  from  test_unlogged;

 id | name

—-+——

  1 | twj1

  2 | twj2

  3 | twj3

// 再次建一个 logged 表与插入数据

postgres=# create table  tt(id int);

CREATE TABLE

postgres=# insert into tt values(1);

INSERT 0 1

// 备份日志

[postgres@pg1 ~]$ pg_rman backup  -b  archive  -p 5432  -U dba

[postgres@pg1 ~]$ pg_rman show

==========================================================

 StartTime          Mode  Duration    Size  TLI  Status

==========================================================

2016-04-13 18:38:33  ARCH        0m    16MB    1  OK

2016-04-13 18:12:25  ARCH        0m    16MB    1  OK

2016-04-13 18:07:40  FULL        0m    58MB    1  OK

[postgres@pg1 ~]$ pg_ctl  -D  /pgdb/data  stop

// 这里手工保存最后一次正常关闭后归档的日志,然后移除原库或者异机恢复

[postgres@pg1 ~]$ pg_rman restore

ERROR: could not open pg_controldata file “/pgdb/data/global/pg_control”: No such file or directory

[postgres@pg1 ~]$ mkdir  -p /pgdb/data/global/

[postgres@pg1 ~]$

 cp ‘/pgdb/backup/pg_rman/20160413/180740/database/global/pg_control’  /pgdb/data/global/pg_control // 从备份中获取控制文件信息

[postgres@pg1 ~]$ pg_rman restore

[postgres@pg1 ~]$ pg_ctl  -D  /pgdb/data  start

[postgres@pg1 ~]$ FATAL:  data directory “/pgdb/data” has group or world access

DETAIL:  Permissions should be u=rwx (0700).

[root@pg2 Desktop]# chmod  -R  0700  /pgdb/data

[postgres@pg1 ~]$ pg_ctl  -D  /pgdb/data  start

 [postgres@pg1 ~]$ LOG:  database system was interrupted; last known up at 2016-04-13 18:07:41 PDT

LOG:  starting archive recovery

LOG:  restored log file “000000010000000000000002” from archive

LOG:  redo starts at 0/2000098

LOG:  consistent recovery state reached at 0/20000C0

LOG:  restored log file “000000010000000000000003” from archive

LOG:  restored log file “000000010000000000000004” from archive

LOG:  restored log file “000000010000000000000005” from archive

cp: cannot stat `/pgdb/archive1975/000000010000000000000006′: No such file or directory

LOG:  redo done at 0/5000050

LOG:  last completed transaction was at log time 2016-04-13 18:38:34.097399-07

LOG:  restored log file “000000010000000000000005” from archive(该日志为最后一次正常关闭产生)

p: cannot stat `/pgdb/archive1975/00000002.history’: No such file or directory

LOG:  selected new timeline ID: 2

cp: cannot stat `/pgdb/archive1975/00000001.history’: No such file or directory

LOG:  archive recovery complete

LOG:  MultiXact member wraparound protections are now enabled

LOG:  database system is ready to accept connections

LOG:  autovacuum launcher started

之后启动数据库再次访问表,结果 unlogged 表数据无;logged 表数据与实际一致,没丢失。

postgres=# select *  from  test_unlogged;

 id | name

—-+——

(0 rows)

 

postgres=# select *  from  tt;

 id

—-

  1

(1 row)

ok.

———————————— 华丽丽的分割线 ————————————

在 CentOS 6.5 上编译安装 PostgreSQL 9.3 数据库 http://www.linuxidc.com/Linux/2016-06/132272.htm

CentOS 6.3 环境下 yum 安装 PostgreSQL 9.3 http://www.linuxidc.com/Linux/2014-05/101787.htm

PostgreSQL 缓存详述 http://www.linuxidc.com/Linux/2013-07/87778.htm

Windows 平台编译 PostgreSQL http://www.linuxidc.com/Linux/2013-05/85114.htm

Ubuntu 下 LAPP(Linux+Apache+PostgreSQL+PHP) 环境的配置与安装 http://www.linuxidc.com/Linux/2013-04/83564.htm

Ubuntu 上的 phppgAdmin 安装及配置 http://www.linuxidc.com/Linux/2011-08/40520.htm

CentOS 平台下安装 PostgreSQL9.3 http://www.linuxidc.com/Linux/2014-05/101723.htm

PostgreSQL 配置 Streaming Replication 集群 http://www.linuxidc.com/Linux/2014-05/101724.htm

———————————— 华丽丽的分割线 ————————————

PostgreSQL 的详细介绍 :请点这里
PostgreSQL 的下载地址 :请点这里

本文永久更新链接地址 :http://www.linuxidc.com/Linux/2016-11/137240.htm

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-22发表,共计12549字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中