Sentry日志收集系统修复

Sentry上线将近两个月以后崩溃,崩溃的原因有两个:

1、运行postgresql容器的机器磁盘空间被耗尽,导致数据库停止服务

2、运行Nginx和sentry web的docker无法重启。

修复sentry的过程因此分为两个步骤:

1、对postgresql中30天以前的数据进行清理,恢复磁盘空间。

2、对运行sentry web和nginx的机器重装docker,由于nginx和sentry web server不保存状态,因此重新搭建web server不会造成数据丢失。

  • postgresql磁盘空间清理:

这里对应的操作应该被称为database rotation,sentry本身有名为cleanup的工具,可以利用cleanup删除过期数据。

但是,cleanup要求数据库提供服务。在sentry 搭建时,postgresql为主备搭建,主库所在机器磁盘已被耗尽,数据库服务无法启动。幸好备库还有20G左右的剩余空间,可以考虑清理备库的磁盘空间,然后将备库升为主库,再将原主库磁盘清空,同步新主库的数据。这样做会损失一部分数据,好在sentry记录的数据不是特别重要。

  • cleanup:

sentry的cleanup工具操作帮助为

root@9acfe6561812:/# sentry cleanup --help
Usage: sentry cleanup [OPTIONS]

  Delete a portion of trailing data based on creation date.

  All data that is older than `--days` will be deleted.  The default for this is 30 days.  In
  the default setting all projects will be truncated but if you have a specific project you want
  to limit this to this can be done with the `--project` flag which accepts a project ID or a
  string with the form `org/project` where both are slugs.

Options:
  --days INTEGER         Numbers of days to truncate on.  [default: 30]
  --project TEXT         Limit truncation to only entries from project.
  --concurrency INTEGER  The number of concurrent workers to run.  [default: 1]
  -q, --silent           Run quietly. No output on success.
  -m, --model TEXT
  --help                 Show this message and exit.


操作在sentry web所在服务器上进行,对postgresql进行远程cleanup。

docker run -d --name sentry_cleanup
...省略若干其他配置
 sentry --config /sentry_conf.py cleanup --days 30
这样可以删除当前日期间30日前的数据。

  • vacuum:

执行了cleanup之后,使用df -h命令,发现数据库所占用的磁盘空间并没有减小,剩余空间依然只有20多G,这是因为cleanup的使用delete命令删除postgresql数据,但postgrdsql对于delete, update等操作,只是将对应行标志为DEAD,并没有真正释放磁盘空间。(参考:http://www.cnblogs.com/littlehb/archive/2013/04/28/3048892.html)

需要执行vacuum操作,将这些标记为DEAD行记录所占用的空间彻底释放。

vacuum操作可以使用postgresql 自带的vacuumdb工具, vacuumdb操作帮助为:

root@s1226:/# vacuumdb --help
vacuumdb cleans and analyzes a PostgreSQL database.

Usage:
  vacuumdb [OPTION]... [DBNAME]

Options:
  -a, --all                       vacuum all databases
  -d, --dbname=DBNAME             database to vacuum
  -e, --echo                      show the commands being sent to the server
  -f, --full                      do full vacuuming
  -F, --freeze                    freeze row transaction information
  -q, --quiet                     don't write any messages
  -t, --table='TABLE[(COLUMNS)]'  vacuum specific table(s) only
  -v, --verbose                   write a lot of output
  -V, --version                   output version information, then exit
  -z, --analyze                   update optimizer statistics
  -Z, --analyze-only              only update optimizer statistics
  -?, --help                      show this help, then exit

Connection options:
  -h, --host=HOSTNAME       database server host or socket directory
  -p, --port=PORT           database server port
  -U, --username=USERNAME   user name to connect as
  -w, --no-password         never prompt for password
  -W, --password            force password prompt
  --maintenance-db=DBNAME   alternate maintenance database

Read the description of the SQL command VACUUM for details.

Report bugs to .


注意vacuumdb需要以postgres用户身份运行,可以配合sudo -u操作,比如,对sentry_进行空间整理的命令为:

root@s1226:/# sudo -u postgres vacuumdb -U postgres -d sentry -t nodestore_node -v -f --analyze     
sudo: unable to resolve host s1226.bx.sys.d
INFO:  vacuuming "public.nodestore_node"
INFO:  "nodestore_node": found 75819 removable, 705972 nonremovable row versions in 461966 pages
DETAIL:  0 dead row versions cannot be removed yet.
CPU 12.00s/52.63u sec elapsed 126.17 sec.
INFO:  analyzing "public.nodestore_node"
INFO:  "nodestore_node": scanned 30000 of 59846 pages, containing 353649 live rows and 0 dead rows; 30000 rows in sample, 705727 estimated total rows

打印出的信息不是太懂,猜测是发现了那些row是dead,并且是removable的,然后释放空间,对存储空洞进行整理。

虽然看不太懂,但是对所有数据表整理后,发现磁盘被释放出了很大一部分空间:

root@s1226:/# df -h
Filesystem                                                                                          Size  Used Avail Use% Mounted on
/dev/mapper/docker-253:17-1048577-21e6cfea1af36f66bd554fbb5b5eec529d63692288a2d9115a9ee91d3457cb98   10G  501M  9.6G   5% /
tmpfs                                                                                               3.9G     0  3.9G   0% /dev
tmpfs                                                                                               3.9G     0  3.9G   0% /sys/fs/cgroup
/dev/vdb1                                                                                            99G   36G   58G  39% /cluster/database
shm                                                                                                  64M     0   64M   0% /dev/shm
/dev/vda1                                                                                            12G  1.7G   11G  14% /etc/keepalived/keepalive.conf

/cluster/database挂载的剩余空间由原先的20多G增长到了58G。


至此主库的空间已经整理完毕,然后启动一个备库,并运行keepalived,数据库的修复完成(丢失了一部分数据)

  • sentry web server的恢复:

sentry系统中,我将nginx, sentry web, celery cron和celery worker部署在同一个host下,由于未查明的原因,运行两个月后docker挂掉了,重启docker后,重启容器会超时, 容器所在目录磁盘占用100%,有可能是被运行日志填满。

sentry web server本身不存储数据,修复比较简单,直接重新搭建就行了。但是搭建完毕之后,通过浏览器登录sentry 的管理界面,会有500 Internal Error的错误,由于线上的请求源源不断地过来,错误日志被淹没,一时找不到解决方法。

这种情况下,突破口是错误重现+错误定位,理清思路后操作如下:

1、对其中的一个server,关停对外的nginx容器,暂时拒绝外部请求,启动一个调试用的nginx容器,配一个域名为s1226的server

2、使用docker logs -f --tail sentry命令,监控sentry web server的日志(sentry 的日志都是直接输出到stdout的,在服务器内部并没有写入文件)

3、浏览器登录管理界面,前端遇到错误,此时后台发现了异常,原因是操作的一个不存在的数据表sentry_organizationavator

然后,根据stacktrace,跟踪源码,发现执行到了一个存在的文件,这时候才意识到,在搭建环境时,docker pull sentry没有指定版本,拉下来的镜像是sentry 8.13,而数据库对应的是sentry 8.11,更换了sentry版本后,问题解决。

你可能感兴趣的:(docker)