gitlab 备份恢复与迁移

这里只介绍使用rpm包方式安装时的备份恢复与迁移

转载: http://segmentfault.com/a/1190000002439923

Gitlab 创建备份

使用Gitlab一键安装包安装Gitlab非常简单, 同样的备份恢复与迁移也非常简单. 使用一条命令即可创建完整的Gitlab备份:

使用以上命令会在/var/opt/gitlab/backups目录下创建一个名称类似为1393513186_gitlab_backup.tar的压缩包, 这个压缩包就是Gitlab整个的完整部分, 其中开头的1393513186是备份创建的日期.

Gitlab 修改备份文件默认目录

你也可以通过修改/etc/gitlab/gitlab.rb来修改默认存放备份文件的目录:

/mnt/backups修改为你想存放备份的目录即可, 修改完成之后使用gitlab-ctl reconfigure命令重载配置文件即可.

Gitlab 自动备份

也可以通过crontab使用备份命令实现自动备份:

加入以下, 实现每天凌晨2点进行一次自动备份:

Gitlab 恢复

同样, Gitlab的从备份恢复也非常简单:

Gitlab迁移

迁移如同备份与恢复的步骤一样, 只需要将老服务器/var/opt/gitlab/backups目录下的备份文件拷贝到新服务器上的/var/opt/gitlab/backups即可(如果你没修改过默认备份目录的话). 但是需要注意的是新服务器上的Gitlab的版本必须与创建备份时的Gitlab版本号相同. 比如新服务器安装的是最新的7.60版本的Gitlab, 那么迁移之前, 最好将老服务器的Gitlab 升级为7.60在进行备份.

gitlab 安装

gitlab安装 有麻烦的方法: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/install/installation.md

也有简单的方法: https://about.gitlab.com/downloads/#centos6

yum安装或者脚本安装实在太慢,即使走代理也很慢; 当然,可以:

如果不小心断网又得从来,不可取。

俺的办法是: 用百度的离线下载功能先把rpm: https://packages.gitlab.com/gitlab/gitlab-ce  下载下来,百度离线下载几分钟就能搞定,然后,再从百度下载rpm,再然后:

安装完成后有提示接下来该怎么做,我建议你接下来不要着急配自己的nginx,而是直接enable  rpm中自带的nginx

配置文件基本只有一个: /etc/gitlab/gitlab.rb

修改完直接:

根本不用stop start;

注意:千万不要stop的时候reconfigure,这样总是出错,start状态下直接reconfigure还挺快的

 

配置见下篇

 

大并发下的死锁

一直不觉得什么样的代码逻辑才会在小并发下没问题,而在大并发下有问题,今天终于见到了。

今天做一个压力测试,刚刚开始,程序就无法响应了;小伙伴说,重启一个服务吧,我说,还是查查为啥吧,于是发现如下问题:

环境介绍:

  1. 数据库连接池,限制最多100个链接
  2. 代码中有一个方法设置了同步(无法多个线程同时执行到该代码,锁等待)
  3. JAVA多线程环境

代码逻辑为:

  1. begin 事务
  2. 执行同步方法
    1. 同步方法中可以需要执行sql语句,需要一个空闲的数据库连接(该逻辑比较深,不太容易注意到),如果获取不到数据库连接,就等待(如果非要加一个期限的话,实际上是无限期)
  3. 执行其他sql查询
  4. 结束

当100个请求同时执行到步骤1的时候,其中一个线程抢先进入了同步方法,但是不幸的是,虽然抢先进入了同步方法,但由于数据库连接已耗尽,只好等待;但是现在其它线程拿着数据库连接却由于等待在同步方法外而无法释放数据库连接,于是,死锁出现。。。

debug过程

由于bug是在高并发下出现的,不宜单步调试,只能从出错的状态中去分析。

第一步: jstack $pid

…. (有N多线程的堆栈就出来了)

第二步: 分析堆栈

很多线程被block,推测:应该有个线程(的堆栈)和别人不太一样; 果然如此

第三步: 参照堆栈和代码,分析得到结果

 

解决办法:

。。。

Django 初体验

本来没准备去了解python+django,但是工作需要还是了解了一下;从执行效率上来讲,python和PHP基本是同一个级别的语言,我没指望python能有多么好的执行效率,鉴于django是python界赫赫有名的web开发框架,于是就测了一下。

2核8G的cpu下测试django的hello world,大概也就500+的qps。什么?fastcgi?是的,用fastcgi的方式也做了测试,真心没明显变化,fastcgi就真的fast吗?只是相对cgi来讲确实fast了不少,但不是神器。尤其:django的fastcgi实现用的是flup  ; flup是纯python实现的,从这一点来讲,还不如PHP,赖好PHP的fastcgi还是C实现的。

django说 1.9 之后不再使用fastcgi了

关于mysql锁的学习

锁的类型: 表锁、页锁、行锁、间隙锁【读锁(共享锁)、写锁(排他锁)】、乐观锁、悲观锁(晕,其实没这么多东西)

mysql.INNODB_LOCKS 这张表记录了发生了锁争用的信息;虽然一个事务正在加了一些锁,如果没有其它session等待这些锁的话,这个表里面也是查不到的哦

但是,A表正在事务中被更新时,如果:

lock tables A write;

虽然被阻塞,但是 mysql.INNODB_LOCKS里面却查不到任何记录!  (why: lock tables 不是存储引擎级别的锁)

 

实例分析:

表结构:

sql语句1:

sql语句2:

如果简单认为innodb的锁都是行锁(尤其是select和insert操作的压根儿也不是一行),怎么可能发生死锁呢?

让我们模拟一下,分别在两个session中一行一行地交替执行两个事务,我们发现,确实在insert的时候死锁了

session 1:

 

session 2:

 

如果我们不着急去执行session 2中的insert的语句,而是查询一下存在哪些锁,发现如下:

什么是supremum pseudo-record?

supremum pseudo-record :相当于比索引中所有值都大,但却不存在索引中,相当于最后一行之后的间隙锁

解决办法:

 

参看: http://blog.itpub.net/26250550/viewspace-1070422/

 

问题: 两个select … for update ; 加的是共享锁?否则不能同时两个select语句都能成功执行。还如何查证?

不能简单地说 select … for update 加的是共享锁还是排他锁; 如果select有结果,则加行锁,此时为排他锁; 如果没有结果,则加间隙锁,此时为共享锁(和间隙大小没有关系); 如果没有在事务中,则select for update是不加锁的;

参看: Enabling InnoDB Monitors: https://dev.mysql.com/doc/refman/5.6/en/innodb-enabling-monitors.html

可以查看当前被设置的锁的信息:

部分信息如下:

 

下面是insert 语句等待时的锁情况:

 

学习资料:

http://hedengcheng.com/?p=771    非常不错

nginx 配置之read_timeout

nginx配置文件中有各种timeout,比如:fastcgi_read_timeout ;如果没有一些经验,很可能会认为该配置会限制fastcgi请求的时常,其实不然,不过,很多情况下确实是这样的。

比如,我们将fastcgi_read_timeout 设置为5s,并非fastcgi最大允许执行5s,而是:

当nginx发送完请求,开始从fastcgi读取数据时,当然,这时候fpm一般还没能立即处理完,没法立即返回响应数据,则nginx读不到数据,则开始计时,如果fpm能在5s内响应点儿数据(即使不全也没关系),则nginx就可以读取到该数据,继续尝试读取时,发现又需要等待,则重新开始5s的计时,如果fpm总是能保证5s内响应一部分数据,则nginx愿意一直候着,一旦超过5s读不到数据,nginx就不干了

PHP测试代码:

 

欧了

ftp proxy

ftp协议包含控制链路和数据链路以及主动模式和被动模式,使得ftp协议的代理变得复杂。而且ftp协议设计上没有考虑代理情况(协议上无法知道要连接的真实地址),包括ftp的client也多不支持代理,尤其是透明代理不方便实现,大概是没有一种标准的代理方式。常见的标识真实目标地址的方法是在用户名后面@server来实现

  1. https://github.com/fredbcode/ftpproxy
  2. apache mod_ftp_proxy
  3. http://www.ftpproxy.org/
    1. 似乎默认只能和xinetd一起工作
  4. squid

 

VPN/auth/encrypt/pptp/l2tp/openvpn

VPN就安全吗?

vpn从概念上来讲只是“虚拟私有网络”,不意味着安全;如果需要auth,就安全了吗?也不一定,就如同web上的http服务,用户一般也需要登录,但是传输层都是明文;所以,还需要加密;最近使用pptp的时候就发现pptp是没有加密功能的,这样的vpn其实是不安全的。vpn设计的时候都会考虑到安全问题,而采用加密方式的。(原来在vpn的虚拟网卡上抓包看到了明文,就怀疑没有加密,其实应该在真实网卡上抓包来验证是否vpn通道是加密的)

killall 之困

缘起

多个相同名字的进程要全部杀死,很自然会用killall; 但是,如果没杀死,将会很郁闷;

结论:

killall参考的是 /proc/pid/comm ;而我们看到的一般是/proc/pid/cmdline ;

如:php-fpm进程显示为:

而我们killall时,写法为:

killall php-fpm

为什么不需要 pool www ? (因为killall 默认不是精确匹配的,-e选项可以精确匹配,man killall)

另外,我们执行top命令时,‘c’键可以切换命令行列的“短格式”和“长格式”;其实不是什么“短格式”和“长格式”,‘f’ 键可以看到,其实就是comm和cmdline的切换: