博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
nilfs (a continuent snapshot file system) used with PostgreSQL
阅读量:6182 次
发布时间:2019-06-21

本文共 6898 字,大约阅读时间需要 22 分钟。

NILFS 是NTT开发的一个文件系统, 持续的提供快照, 为误操作提供回滚可能. 
相比lvm的快照, nilfs更有利于SSD环境. 因为在写频繁的环境中不需要大量的cow. 

简介 : 

NILFS is a log-structured file system supporting versioning of the entire file system and continuous snapshotting which allows users to even restore files mistakenly overwritten or destroyed just a few seconds ago.

NILFS was developed by NTT Laboratories and published as an open-source software under GPL license, and now available as a part of Linux kernel.

This site provides information and source code of programs related to the NILFS filesystem.
2.6.30以后的内核, 已经包含了nilfs, 用户只需要下载对应的管理包即可.

NILFS was merged into the Linux kernel 2.6.30. For the 2.6.30 kernel or later, you only need to download the utility package.

Userland utilities    Apr 8, 2014 JST.

Include SET_SUINFO ioctl support which helps to reduce unfruitful segment cleaning, and lssu command is enhanced to help analysys of the ratio of in-used blocks for every segment.
For changes from past versions, see .

The latest version of nilfs-utils 2.0 series is as follows:

  •  Dec 5, 2011 JST.

结合PostgreSQL使用的话, 可以实现异步流复制主备切换后, 老的主库因为XLOG相异导致无法直接切换为备库的场景.
老唐写了一篇文章, 详细的介绍这块功能, 请参考.
以下内容转载自老唐的blog.

引言:

我们知道在使用PostgreSQL的流复制做的高可用方案,即使使用同步的流复制,当主库由于操作系统或硬盘故障宕机时,当我们把备机提升为主库后,原主库通常无法转成备库。这是因为,在流复制的同步过程中,当有大量更新时,主库总是比备库超前一点,当切换后,备库提升为主库后,原主库就无法变成与新主库的Standby,如下图所示:

old_master_can_not_connect_promoted_slave.png

如果我们能把原主库回滚一段时间,让其与备库在同一个时间序列上,这时我们就可以把原主库变成新主库的备库了,如下图所示:

rollback_old_master_can_connect_promoted_slave.png

那么如何把原先的主库回滚到前一阶段呢?这就用到了本文讲的nilfs文件系统。有人说,不用nilfs文件系统,使用Linux下的LVM的快照功能也能实现这个回滚的功能,如每5分钟建一个快照,始终保持两个快照,这样我总是能把主库回滚到5分钟前的状态,这样也能实现这个回滚的功能。但LVM的快照功能会对性能有较大的影响。LVM的快照功能是通过COW(copy on write)来实现的,也就是当打开快照功能后,当写一个数据时,需要把旧数据拷贝到快照的空间中,这时相当于把写放大的一倍。于是有人就想如果每次写入新数据时,都不要覆盖旧数据,写到新的地方去,就象PostgreSQL表本身实现的多版本一样,这样就不能有这么大的性能损耗了。nilfs文件系统就是这样的一种文件系统。nilfs原本是为flash或SSD来设计的文件系统,对于SSD来说,重写代价比较大,所以每次写都写到新的地方,这样就能提高写的性能。这刚好能满足我们的这个需要。

本文后面就详细讲解如何使用nilfs实现如上的功能。

1. 本文所使用的测试环境

主库:192.168.56.11,db01主库:192.168.56.12,db02

操作系统都是ubuntu12.04 server 数据库都安装在操作系统用户osdba下。

2. 初始化环境

在192.168.56.11和192.168.56.12上都做以下的操作。

为了使用nilfs,先安装nilfs的相关软件包:

sudo aptitude install nilfs-tools

我们的数据库数据目录在/home/osdba/pgdata下,我们格式化一个nilfs的文件系统,挂载到/home/osdba/pgdata下:

sudo mkfs -t nilfs2 -L pgdata  /dev/sdb1sudo mount /dev/sdb1 /home/osdba/pgdatasudo chown -R osdba:osdba pgdatasudo chmod 700 pgdatasudo rm /home/osdba/pgdata/.nilfs

编译安装PostgreSQL,具体可见:

安装完后,在.bashrc后面设置了:

export LD_LIBRARY_PATH=/home/osdba/pgsql/lib:$LD_LIBRARY_PATHexport PATH=/home/osdba/pgsql/bin:$PATHexport PGDATA=/home/osdba/pgdataalias pgstart='pg_ctl -D $PGDATA start'alias pgstop='pg_ctl -D $PGDATA stop -m fast'

3. 建主库

执行下面的命令,把数据库建起来:

initdb -k

改动/home/osdba/pgdata/postgresql.conf的配置如下:

listen_addresses = '*'wal_level = hot_standbymax_wal_senders = 5hot_standby = onlogging_collector = on

改动/home/osdba/pgdata/pg_hba.conf的配置如下:

host    all             all          192.168.56.0/24         md5host    replication     osdba        192.168.56.0/24         md5

启动数据库:

pgstart

在主库上把数据库超级用户osdba,设置一个密码,以便于后面建备库时使用密码连接主库:

osdba@db01:~$ psql postgrespsql (9.3.3)Type "help" for help.postgres=# alter user osdba password '123456';ALTER ROLEpostgres=#

4. 建备库

使用pg_basebackup建备库,执行如下命令:

pg_basebackup -h 192.168.56.11 -U osdba -F p -P -x -R -D /home/osdba/pgdata -l osdbabackup

实际执行过程如下:

osdba@db02:~$ pg_basebackup -h 192.168.56.11 -U osdba -F p -P -x -R -D /home/osdba/pgdata -l osdbabackupPassword: 36002/36002 kB (100%), 1/1 tablespace

这样备库就建好了,后面我们配置备库,新建备库的/home/osdba/pgdata/recovery.conf文件,其内容如下:

recovery_target_timeline = 'latest'standby_mode = 'on'primary_conninfo = 'application_name=standby01 user=osdba password=123456 host=192.168.56.11 port=5432 sslmode=disable sslcompression=1'

启动备库:

osdba@db02:~$ pgstartserver startingosdba@db02:~$ LOG:  redirecting log output to logging collector processHINT:  Future log output will appear in directory "pg_log".osdba@db02:~$ psql postgrespsql (9.3.3)Type "help" for help.postgres=# select pg_is_in_recovery(); pg_is_in_recovery ------------------- t(1 row)

这样环境就完全搭建好了。

5. 做测试

为了让测试更真实,我们运行pgbench不断的产生一些读写,然后做切换。 先初始化pgbench:

pgbench -i -h 192.168.56.11 postgres

启动pgbench的压力测试:

pgbench -h 192.168.56.11 -c 10 -T 1800 postgres

这时我们按192.168.56.11的电源,让其关机,模拟这台机器出故障的情况。同时记录时间。我们关机的时间为:

osdba@osdba-laptop:~$ date2014年 03月 03日 星期一 23:28:46 CST

我们然后把备库192.168.56.12提升为主库:

osdba@db02:~$ pg_ctl promoteserver promotingosdba@db02:~$ psql postgrespsql (9.3.3)Type "help" for help.postgres=# select pg_is_in_recovery(); pg_is_in_recovery ------------------- f(1 row)

可以看到192.168.56.12已变成主库了。

这时我们需要把原先的主库192.168.56.11变成192.168.56.12的备库。把192.168.56.11重新开机,并把nilfs再mount上来:

sudo mount /dev/sdb1 /home/osdba/pgdata

这时我们只需要把192.168.56.11上的文件系统回滚到刚才关机前的一个时间,这个时间的WAL日志已同步到192.168.56.12上就可以了,我们先看nilfs的checkpoint点,nilfs会自动产生很多个checkpoint点,每个checkpoint点都可以转换成快照,然后就可以把快照mount上来。因为nilfs没有提供直接把文件系统回滚到一个快照点的功能,把nilfs回滚到快照点的方法是把快照点mount上来,然后使用rsync把快照的数据同步到当前的文件系统中。

下面的操作在192.168.56.11机器上: 我们先查看一下我们要回滚到文件系统的哪个checkpoint点,使用nilfs的lscp命令,如下所示:

osdba@db01:~$ lscp                 CNO        DATE     TIME  MODE  FLG     NBLKINC       ICNT                   1  2014-03-03 23:06:21   cp    -           11          2                   2  2014-03-03 23:06:55   cp    -            8          2............................................                9935  2014-03-03 23:28:40   cp    -           19        806                9936  2014-03-03 23:28:41   cp    -           19        806                9937  2014-03-03 23:28:41   cp    -           19        806.....................

估计回滚到9935这个checkpoint应该是可以的,执行下面命令把这个checkpoint转换到snapshot

sudo chcp ss /dev/sdb1 9935

然后挂载上来:

mkdir /home/osdba/snapsudo mount -t nilfs2 -o ro,cp=9935 /dev/sdb1 /home/osdba/snap

注意挂载snapshot的方法是"-o ro,cp=9935",“ro”表示只读,“cp=9935”表示挂载哪个snapshot。

把快照的数据同步到当前的文件系统中:

rsync -axv --delete /home/osdba/snap/ /home/osdba/pgdata/

把192.168.56.11上的数据库转成备库,建/home/osdba/pgdata/recovery.conf,内容如下:

recovery_target_timeline = 'latest'standby_mode = 'on'primary_conninfo = 'application_name=standby01 user=osdba password=123456 host=192.168.56.12 port=5432 sslmode=disable sslcompression=1'

启动192.168.56.11上的数据库,这样就完成了切换。这时192.168.56.11转换成了192.168.56.12的备库了。我们可以到192.168.56.12上看同步的情况 :

postgres=# select * from pg_stat_replication; pid  | usesysid | usename | application_name |  client_addr  | client_hostname | client_port |         backend_start         |   state   | sent_location | write_location | flush_location | replay_location | sync_priority | sync_state ------+----------+---------+------------------+---------------+-----------------+-------------+-------------------------------+-----------+---------------+----------------+----------------+-----------------+---------------+------------ 1267 |       10 | osdba   | standby01        | 192.168.56.11 |                 |       40594 | 2014-03-03 23:47:59.920158+08 | streaming | 0/51D1E70     | 0/51D1E70      | 0/51D1E70      | 0/51D1E70       |             0 | async(1 row)

上面的信息可以看出192.168.56.11上的备库已经连接到192.168.56.12上,同步也正常。

你可能感兴趣的文章
NVIDIA新作解读:用GAN生成前所未有的高清图像(附PyTorch复现) | PaperDaily #15
查看>>
CString、CTime和COleDateTime转换
查看>>
在linux虚机中装vmtools
查看>>
WCF技术剖析之十三:序列化过程中的已知类型(Known Type)
查看>>
linux设备驱动程序--类class的实现
查看>>
中国云计算应用进入集中爆发期
查看>>
算法精解---计数排序
查看>>
DockOne微信分享(一二八):容器如何监控?
查看>>
谈谈分布式事务(Distributed Transaction)[共5篇]
查看>>
如何确保快递“最后一公里” ,亚马逊打算送到你的汽车后备箱
查看>>
Gartner:财务应用迁移到云 速度超出预期
查看>>
阿里云向物流业渗透 货运司机受益
查看>>
灾难恢复的人为因素:经理们应该做的10件事情
查看>>
中国教育行业可能到了最不平凡的10年:要么创新,要么死亡
查看>>
学习Docker的User Namespace
查看>>
Symantec Backup Exec 2012 Agent for Linux 卸载
查看>>
用EJB进行事务管理
查看>>
Linux Shell脚本系列之一
查看>>
数据可视化,个人经验总结(Echarts相关)
查看>>
Mysql MAC installation
查看>>