开发中总会遇到一些测试需要回滚数据库。常规的单元测试的做法是在单个会话中不真正的写入到数据库。而是测试完成后进行数据库回滚。大多数情况下这样都是满足要求的。只是有的时候需要数据库真正的写入到数据库。此时rollback回滚就有些乏力了。此时给数据库做一个备份,测试完成后回滚是一种不错的主意。Postgresql数据库的常规备份我们会使用pg_dump和pg_restore进行导出和恢复。此时如何快速的进行这个操作是我们关注的话题

很幸运。很顺利的搜到了答案。6年前有人在stackexchange上提问同样的问题。得到了一些有用的回复。大概有这些

  • 使用文件系统级快照LVM
  • 使用CREATE DATABASE … TEMPLATE语法
  • 将数据库放在虚拟机里面。使用虚拟机快照

其中最有效的方案是二。因为LVM在个人笔记本上难以实施。虚拟机恢复时间较慢。依据方案二于是乎有人写了一个工具 stellar。粗略读了一下源码。其具体原理大概如下图
backup_and_restore_flow

备份的时候使用create database … template创建2个备份。恢复的时候删掉原有的数据库。将一个备份重命名为原有的名称。另外的一个备份再生成一个备份就完成了。另外删除新建数据库操作均会关闭所有已连接的数据库会话。

因为类似文件系统级快照,所以方法极快。我本机2G的数据库文件,创建一个快照大概十秒钟左右,恢复就更快了。当然缺点也是有的,你每创建一个快照都会新增2个一样大小的副本,相当的占据硬盘空间,可是为了速度这点缺陷也就微不足道了┑( ̄Д  ̄)┍

另外一个小缺点。因为它定位于测试环境下的数据库备份恢复。所以只连接一台机器。比如你一个数据库在机器A,一个数据库在机器B.赛高~~,那你只能在2个目录下使用2个配置文件来完成了。如果同一个机器上的多个数据库是可以直接备份的。再就是此工具比较专注于Postgresql。对于Mysql就不那么友好了。或许是Mysql的备份方案不一样

使用方法

  1. stellar init 按照提示输入本机数据库访问路径生成配置文件
  2. stellar snapshot 生成一个快照
  3. stellar restore <snap1> 恢复
  4. 其他请看 stellar --help

( ⊙ o ⊙ )啊! 多么爽快,世界真美妙

参考

Is it possible to quickly create/restore database snapshots with PostgreSQL?
github stellar

评论和共享

Docker CD初探-Drone

发布在 Docker

最近有个小需求,我们公司写文档是通过slate来的。每一次文档编写完成之后都需要执行bundle exec middleman build --clean生成静态文件。然后再使用rsync来进行上传操作。虽然只有2步。但是做的次数多了难免也让人觉得厌烦。萌生了自动化处理的想法。比较粗暴的方式有。每隔几分钟去检测一次git版本库是否有更新(以前本人真这样实现过),自己写个小web程序。设置webhook。接收到webhook再拉取进行操作(我也实现过,目前一切运行良好)。现在尝试下使用可持续集成的套路去实现。

阅读全文

理解metaclass

发布在 python

metaclass一直被归类为比较高深的内容,写代码也很少会使用到metaclass。然而如果你看某些项目的源代码,还是会被绕到metaclass里面去。花一些时间理解下metaclass很有用的,因为它真的能把一条线串起来,环环相扣,所以有扎实的基础是掌握metaclass的前提,本文代码基于python3.5

阅读全文

tornado表单验证

发布在 python

工作中看到有一些不好的代码,想了个办法优化了一下,于是有了这篇博文。本文主要讲tornado的表单验证,使用的是wtforms。本文最终达到的效果是使用self.xx获取post传递过来的值。

阅读全文

ssh端口映射

发布在 DevOps

开发中经常会需要用到端口映射这种事情。以前觉得好容易混淆。其实用习惯了就会发现如此简单┑( ̄Д  ̄)┍,下面联系到我日常使用到的一些ssh映射实例讲解一下

阅读全文

letsencrypt刚出来的时候写了一篇它的认证签发原理。自那过后就没有真正的去实践过了。最近有部署HTTPS的需求就又考察了一番。发现acme.sh灰常好用啊~~~,来一篇水文记录下测试部署HTTPS的完整过程吧

阅读全文

很早就使用过autopep8来自动格式化代码,使用IDE的时候也会经常使用格式化代码功能让代码更符合规范一点。可是这都不是自动化的,或者说是强制的。为了保持团队的良好代码风格感觉每个同事在提交代码之前都自动进行格式化或者风格检查是一个不错的主意,于是找到了pre-commit

原理也还是很简单的,git自身提供了一些hook功能,查看git/hooks目录下会发现有一些sample文件,这样在执行commit、push、merge的时候都是可以进行一些简单的检查等功能的。然而这个设定有一个缺点。没一个hook只能执行一个文件的内容,所以要么将各种功能放在一个文件里面,或者每个功能都放置在各自的文件里面。最后由一个文件一起执行。pre-commit就解决了我们的这个文件。将不同的任务分割成单个文件。然后只需要添加别人共享的脚本就能够很快的进行commit hook了,简要使用方法例举如下

  1. 在项目根目录下编写配置文件(.pre-commit-config.yaml)

    1
    2
    3
    4
    5
    -   repo: git://github.com/pre-commit/pre-commit-hooks
    sha: v0.7.1
    hooks:
    - id: trailing-whitespace
    - id: autopep8-wrapper
  2. 进行初始化pre-commit install就可以了,以后每次执行commit的时候就会执行检查。配置文件的repo地址即为符合pre-commit框架的地址,id即为提供的功能~~,还是很好理解的。例如以上提供的autopep8-wrapper就可能够配置pep8规范进行一些代码风格检查,如果不符合风格就会自动格式化。pep8工具的默认配置文件是~/.config/pep8

参考

About style guide of python and linter tool. pep8, pyflakes, flake8, haking, Pyling.

评论和共享

supervisor遇到的坑

发布在 python

写几条自己用supervisor遇到的一些小坑

  1. Python 3 Wall的反派代表,一直不能使用python3安装
  2. 对中文输出支持奇差,估计是使用python2造成的,举个例子,假如你要在python2里面print输出一个unicode中文字符。我试了各种办法,均无解(和supervisor使用子进程运行程序的策略有关),好在使用logging模块输出中文居然没啥问题-_-,正式运行环境也是全部使用logging代替print
  3. 即使用python3,输出中文也会遇到问题,需要在配置文件添加environment=LANG="en_US.utf8", LC_ALL="en_US.UTF-8", LC_LANG="en_US.UTF-8"解决
  4. 写配置文件的时候一个变量不能配置多行,我一开始因为environment太长。写了2行,导致后面的没生效,折腾好久
  5. 修改supervisor配置文件后,如果配置文件错了,不会报错!而且supervisor没有工具能对配置文件的正确性进行检查,灰常操蛋啊!
  6. supervisor可以检查到异常自动重启并设置最大重启次数,可是有时候会造成无限重启这种情况。因为重启后立刻退出才会触发最大重启次数机制,假如程序一直是运行了十分钟自动退出。那么会造成无限重启,可以使用它的api写一个脚本监控这种情况,进行警告
1
2
3
4
5
6
7
8
9
10
11
import xmlrpc.client

def list_time(name: str, interval: int, times: int):
s = xmlrpc.client.ServerProxy('http://localhost:9001')
if s.supervisor.getProcessInfo(name).get('statename') != 'RUNNING':
return False
context = s.supervisor.readLog(0, 10 * 1024 * 100)
context = filter(lambda x: name in x and 'spawn' in x, context.splitlines())
context = map(lambda x: datetime.strptime(x[:19], '%Y-%m-%d %H:%M:%S'), context)
context = list(filter(lambda x: x + timedelta(minutes=interval) > datetime.now(), context))
return (len(context) > times) and len(context)

参考

也谈 Python 的中文编码处理

评论和共享

半自动刷网络课程

发布在 伪技术

刷一个网络课程,很常见的那种,播放视频统计观看时长。不过该系统比较弱,即使切换到别的页面一样也会计算时长。限制条件只是偶尔会出现一些问答题让视频暂停且一个视频播放完成后不会自动播放下一个视频。最开始是打算直接模拟发送http请求,不过后面感觉或许有坑就选了另外一种办法。讲课肯定是有声音的,用程序去捕获声音,如果五秒钟没有声音则认为有问答题出现或者该章节讲完了。

阅读全文

Flask路由机制

发布在 Flask

Flask帅气的Hello World示例让人印象深刻。其中使用装饰器的路由写法功不可没,甚至以前看过一个系列没那么神奇,讲了app.route。是的,它好像并没有那么神奇,我也来解析一下😆

阅读全文

ficapy

author.bio


author.job


深圳