UDN-企业互联网技术人气社区

板块导航

浏览  : 2491
回复  : 0

[实践集] DevOps实践集——数据库运维

[复制链接]
jingyun1的头像 楼主
发表于 2015-7-23 11:14:50 | 显示全部楼层 |阅读模式
本帖最后由 jingyun1 于 2015-7-23 11:16 编辑

数据库运维
1. 场景
三种场景:
  • DB少,并发高
  • DB众多(单个instance有2万个Databases)
  • OLAP系统---统计分析平台
2. 数据库选型演化
  • Oracle
    优点:
    • Oracle的稳定
    • Oracle功能强大,相关资料、工具众多
    • Oracle的安全机制高
    • Oracle性能优越
    • 在处理大数据方面Oracle会更稳定一些
  • 缺点:成本高
  • MySQL
    优点:
    • OpenSource,免费
    • 简单,开发人员容易上手
    • 多引擎,比如MyISAM、InnoDB、Memory
    • 完全多线程,支持多处理器,充分利用CPU资源
  • 缺点:
    • 软肋—join 等不行
    • explain 太简单
    • 稳定性差,常出现表损坏
  • PostgreSQL、MongoDB、Redis
    PostgreSQL:
    • PostgreSQL 是目前世界上支持最丰富的数据类型的数据库。
    • PostgreSQL 是全功能的自由软件数据库,PostgreSQL 是唯一支持事务、子查询、多版本并行控制系统、数据完整性检查等特性的唯一的一种自由软件的数据库管理系统。
    • 支持很多扩展,比如postgis
  • MongoDB:
    • MongoDB速度快,文档方式存储
    • mongoDB的字段可伸缩
  • Redis:
    • 缓存为王(开源、轻量)
    • 有序集合 快速TopN
3. 监控
监控是数据库运维的基础,数据库监控分为基础监控(主机状态)、数据库监控,不同DB存在监控差异
  • 基础监控
    监控数据库服务器的内存和硬盘使用情况,以及网络连接数包括活动连接,与等待状态连接,磁盘读写操作,端口存活,vip切换等
    • 正常状态下数据库占用物理内存较大但并不代表有问题,所以报警取buffers/cache 的值
    • 连接数的报警值一般与业务有关,根据业务量查看之前的连接数趋势设置合理的报警值
    • 采用keepalived作主备的数据库可以监控vip,核对主机名,若发生变化则证明vip已切换,触发报警
  • 数据库监控
    监控数据库的连接数、DB大小、慢查询等
    • 对于数据状态表内的数据,根据情况设置报警值。如内存与连接数占用到了80%报警
    • 另外还需要定制一些其他模板,如蜜罐策略报警,对于数据安全监控很重要
Zabbix监控数据库一般使用的方法(以Redis模板制作为例):
  • 使用命令将数据库的状态表述出到临时文件,如:redis-cli info
  • 添加可传参的自定义监控,获取数据
  • 若实例较多,最好制作成自动发现模式
Zabbix提供了MySQL的默认监控模板,其他数据库需要自己定制,监控内容局限于数据库所输出的自身状态表,PostgreSQL、MongoDB需要在服务端写登录并执行查询的脚本,把获取的数据直接上报给zabbix_server
监控示例:
  • PostgreSQL监控
    db_monitor_pg.png
  • MongoDB监控
    db_monitor_mongodb.png

注:数据库监控可以使用nagios的脚本结合zabbix的外部脚本引用的监控方法进行,以便提高效率
4. 备份与恢复
  • 双机HA
  • 本地备份
  • 异机备份
    晚上12点以后进行,每天都进行备份,备份源是本地备份的结果
  • 异地备份
    晚上12点以后进行,每天都进行备份,备份源是异机备份的结果
  • 备份验证
    每天将备份结果进行恢复验证,采用脚本自动化验证,参考脚本
备份信息模板
机房A:
服务器IP
应用
备份时间
本地备份位置
本机备份保留时间(天)—————
同地异机备份
同地异机备份保留时间(天) ——————
异地异机备份
异地异机备份保留时间(天) ——————
备份日志位置
10.10.23.12
application
01 01 * * * —————— 每天凌晨1:01
/opt/pgsql/backup
14
10.10.23.13:/backup/database/d10.10.23.12
14
172.20.2.12:/backup01/dbbackup/m6/database/d10.10.23.12
永久
/var/log/postgresql_backup.log
备份:
pg_dump -h db_server1 -p 5432 product > backup_file
pg_dumpall > backup_file
恢复:
psql dbname < backup_file
数据库的日常备份恢复主要以命令行为主,也可以借助备份工具,如:
开源网络备份工具:bacula
db_bacula.png

  • 通过console连接到Director端,备份恢复操作开始。
  • Director端从自己的数据库中调出记录信息,对存储端SD与客户端FD的任务进行协调。
  • 客户端FD负责验证Director的操作许可,如果验证通过,则允许连接到存储端SD
  • 客户端FD根据Director发出的请求去连接SD,将FD端的数据备份到存SD指定的存储介质上,或者将SD端存储介质中的数据传回到客户端FD指定的位置上,完成备份恢复过程。
5. 性能分析
pgBadger是一个PostgreSQL 数据库日志分析工具,可生成详细的报表和图表,常用语分析慢查询,频繁查询,以便有针对性的进行数据库优化。
  • 慢查询分析
    db_pgbadger.png
  • 频繁查询分析
    db_pgbadger_frequency.png
  • 连接趋势分析
    db_pgbadger_connection.png

MongoDB的性能分析通过脚本定期生成统计报告,如:
db_mongodb_perf.png

报告生成脚本请参考:MongoDB性能报告脚本
6. PostgreSQL数据库集群
方案一:共享存储
  • 共享存储(数据文件以及表空间的文件必须共享存储)
  • 同一时间点只能有1个主机启动数据库,其他主机可以挂在文件系统(仅限于集群文件系统)
  • 浮动IP跟随起数据库的主机一起
  • 通过检测心跳判断异常,fence掉老的活动主机,在候选机器上启动数据库
  • 主要弊端:受限于存储可用性
db_ha_share.png
方案二:数据库复制+keepalived
  • 采用keepalived管理VIP,实现主从数据库的自动切换
  • 采用数据库流复制,保证PostgreSQL主从库的一致性
    db_ha_copy.png


附:
  • 数据库编码规范
  • PostgreSQL故障预案
    1. PostgreSQL
  •    1.1 PostgreSQL单点主库故障
  •    1.2 PostgreSQL单点备库故障
  •    1.3 PostgreSQL双节点故障
  •    1.4 PostgreSQL堵塞
  •    1.5 PostgreSQL主从复制停滞
  •    1.6 PostgreSQL全部宕机
  • 2. 协组方
  •    通知应用负责人
  •    通知应用运维维护人员
  • 3. 处理步骤
  •     3.1 PostgreSQL单点主库故障
  •       a) 切换备库为主库
  •           keepalived自动切换
  •           keepalived自动切换失败,手动隔离故障库,启动备库keepalived使之绑定VIP升级为主库。
  •           备库自动升级到主库失败,删除${PGDATA}目录下的recovery.conf文件,重启postgreSQL使之成为主库。
  •       b) 备份切换后的主库,使用备份还原故障库。
  •    3.2 PostgreSQL单点备库故障
  •       a) 隔离备库,检查日志,处理引起故障的问题
  •       b) 最坏情况备库不可用,通过备份与archivelog重做备库。
  •    3.3 PostgreSQL双节点故障
  •       a) 强制恢复某一节点为主库,隔离另一节点。
  •       b) 备份恢复后的主节点。
  •       c) 通过备份与archivelog重做备库。
  •    3.4 PostgreSQL堵塞
  •       a) 查找引起堵塞的原因,一般为SQL引起,杀死此SQL,把SQL发给相关人员,优化处理。
  •           查看正在执行的sql:
  •           SELECT pg_stat_get_backend_pid(s.backendid) AS procpid,
  •           pg_stat_get_backend_activity(s.backendid) AS current_query
  •           FROM (SELECT pg_stat_get_backend_idset() AS backendid) AS s;
  •          杀死sql:
  •          SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE current_query='<IDLE>';
  •          SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE pid=xxx;
  •    3.5 PostgreSQL主从复制停滞
  •       a) 查找原因,一般情况是日志找不到,把对应的日志复制到备库。
  •       b) 极端情况,备份主库,通过备份和archivelog重做备库。
  •    3.6 PostgreSQL全部宕机
  •       a) 先恢复主库,如损坏严重,那么从备份服务器的备份中进行恢复重建DB。
  •       b) 备份重建好的主库,重建备库。
  •    4. 备注
  •        PostgreSQL不可用的时候,需要应用运维人员或者网络管理员及时把应用的显示界面指向一个友好的停机维护界面。
  • MongoDB故障预案
    1. MongoDB故障
  •      1.1 Mongos节点宕机
  •          一个Mongos进程应该运行在每一个应用程序服务器上,这个服务器应该独占这个Mongos进程,并且通过它与分片集群来通讯。
  •          Mongos进程不是持久化的,相反,它们在启动的时候从Config Server上收集所有必须的配置信息。
  •          这表明,任何一个应用程序服务器节点故障,对作为一个整体的分片集群来讲并没有什么影响,所有别的应用程序服务器将依然是继续正常工作。
  •      1.2 分片中的某一个Mongod节点宕机
  •          每一个分片由n个服务器构成,这n个服务器被配置为一个复制集(replica set)。如果在复制集中的任何一个节点宕机,在这个分片上读与写操作仍然是允许的。
  •          更加重要的是,宕机服务器上的数据都不会丢失,因为复制机制存在一个选项,那就是强制复制写操作到分片的其它节点上再返回,这与在Dynamo上设置write=2类似。
  •      1.3 分片中的所有Mongod节点宕机
  •          如果一个分片中的全部节点(replicas)都宕机了,在该分片内的数据将不能被访问。然而,操作仍然是继续进行,只不过是由别的分片分担。
  •          如果分片被配置为一个复制集(Replicas set),至少一个成员应该在另外一个数据中心,那样的话,整个分片都宕机几乎是不可能的。为了有更大的冗余度,推荐这样进行配置。
  •      1.4 一个Config Server宕机
  •          一个产品级的分片集群需要有3个Config Server进程,每一个进程都在一台独立的机器上运行。对于Config server中的集群元数据的写操作使用一个两阶段提交,去确保是一个原子的并且是被复制的事务操作。
  •          在任何一个配置服务器失效的时候,Mongodb集群的元数据都会变成为只读了。集群系统继续运行,但是chunks在一个分片中将会成为不可以被拆分或者是不可以跨分片进行迁移。对于大多数使用场景,这个不会导致问题,因为改变Chunk元数据进行的并不频繁。
  •      1.5 MongoDB全部宕机
  • 2. 协组方
  •      需要通知应用负责人
  •      通知应用运维维护人员
  • 3. 处理步骤
  •      3.1 Mongos节点宕机
  •          在这种情况下,只需要去启动一个新的应用程序服务器和一个新的Mongos进程即可。
  •      3.2 分片中的某一个Mongod节点宕机
  •          恢复机器,重启对应的服务即可。
  •      3.3 分片中的所有Mongod节点宕机
  •          因为有复制集(Replicas set)容灾的存在,因此,恢复机器,重启对应的服务即可。
  •      3.4 一个Config Server宕机
  •          使宕机的Config Server在一个合理的时间周期(一天)内恢复。由于没有业务数据,保证配置文件,进程正常启动。
  •      3.5 MongoDB全部宕机
  •          尽量恢复尽可能多的服务器,最坏的情况,重新搭建集群环境,使用备份的数据进行恢复。
  • 4. 备注
  •      一个适当配置的Mongodb分片集群是没有单点故障。
  •      本文描述了分片集群中存在的几种不同的潜在的节点故障场景,以及Mongodb对这些节点故障是怎么处理的。
  • 常用操作
    • 数据库主从切换操作
      1.登录主库,验证当前流复制正常
    •    su - postgres
    •    psql -d postgres -c "select client_addr,state,pg_size_pretty(pg_xlog_location_diff(sent_location,replay_location)),sync_state from pg_stat_replication;"
    • 2.登录主库,停止keepalived
    •    /etc/init.d/keepalived stop
    •    现象:
    •    主库DB切换成从,进入归档恢复模式
    •    从库DB切换成主,对外提供服务
    • 3.登录主库(原从库),查看服务是否正常。
    •    ip a
    •    现象:
    •    vip在这台机器上
    • 4.登录从库(原主库),启动keepalive。
    •    /etc/init.d/keepalived start
    • 5.登录主库(原从库),验证流复制正常。
    •    su - postgres
    •    psql -d postgres -c "select client_addr,state,pg_size_pretty(pg_xlog_location_diff(sent_location,replay_location)),sync_state from pg_stat_replication;"
    • 重做数据库流复制
      以下操作均在从库执行
    • su - postgres
    • 1.全库备份
    • nohup /home/postgres/scripts/pg_sync.sh > /tmp/pg_sync.log &
    • tail -fn 200 /tmp/pg_sync.log
    • 2.等待上一步完成,配置文件
    • cp /opt/pgsql/postgresql/recovery.conf /opt/pgsql/postgresql/data
    • 3.清空归档目录
    • rm -rf /opt/archivedir/postgresql/*
    • 4.mount主库归档目录到本地
    • mount -t nfs -o nolock 主库ip:/opt/archivedir/postgresql /opt/archivedir/postgresql
    • 5.启动数据库
    • pgstart
    • 6.确认数据库启动完毕。
    • 7.umount主库归档目录
    • umount -f 主库ip:/opt/archivedir/postgresql
    • 数据库授权
      1.登录目标数据库服务器
    • su - postgres
    • vim /opt/pgsql/postgresql/data/pg_hba.conf
    • TYPE  DATABASE        USER            ADDRESS                 METHOD
    • host  all             qpsmonitor      10.10.10.10           md5
    • 通常只需要改库名、用户、ip、掩码即可。
    • 2.修改完毕reload配置文件
    • pg_ctl reload

  • PostgreSQL备份脚本
    #/bin/bash
  • cur_date=`date +%Y%m%d`
  • pghome=/opt/pgsql/postgresql
  • databak=/opt/pgsql/backup
  • psql=${pghome}/bin/psql
  • archivedir=/opt/archivedir/postgresql
  • pgpasswd="postgres"
  • remote_backup_ip=10.10.23.13
  • remote_backup_dir=/backup01/dbbackup/d10.10.23.12
  • expiredays=14
  • bwlimit=10000
  • #日志类参变量定义
  • bakLog="${databak}/backup.log"
  • bakStats="${databak}/pgbackup.sh.stas"
  • OSTYPE=$(lsb_release -a|grep "Distributor"|awk -F':' '{print $2}'| sed 's/[[:space:]]//g')
  • if [ ${OSTYPE} = 'CentOS' ] ; then
  •     yum -y install bc
  • elif [ ${OSTYPE} = 'Ubuntu' ] ; then
  •     apt-get -y install bc
  • fi
  • echo "Begin backup date: `date "+%F %H:%M:%S"`"
  • if [ ! -d "${databak}" ] ; then
  •     mkdir -p "${databak}"
  •     chown -R postgres.postgres ${databak}
  • fi
  • #full backup
  • function full_backup()
  • {
  •     $psql -U postgres -c "select pg_start_backup('backup');"
  •     cd $pghome
  •     tar -jcvf $databak/data_$cur_date.tar.bz2 --exclude "data/pg_xlog/*" --exclude "data/pg_log/*"  --exclude "data/postmaster.pid"  data/
  •     $psql -U postgres -c "select pg_stop_backup();"
  •     bakObject=data_$cur_date.tar.bz2
  •     bakPolicy="full"
  •     bakMode="tar"
  •     bakFile=data_$cur_date.tar.bz2
  •     bakSize=$(du -s $databak/data_$cur_date.tar.bz2 | awk '{s+=$1} END{printf "%.2f\n",s/1024}')
  • }
  • function incr_backup()
  • {
  •    bakObject=`find ${archivedir} -type f -mtime -1 |  cut -f5 -d'/'`
  •    bakPolicy="increment"
  •    bakMode="rsync"
  •    bakFile="archive_pg_xlog"
  •    bakSize=$(du -s `find ${archivedir} -type f -mtime -1` | awk '{s+=$1} END{printf "%.2f\n",s/1024}')
  •    echo "Nothing to do for this!"
  • }
  • full_backup
  • echo "Backup completed! date: `date "+%F %H:%M:%S"`"

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关于我们
联系我们
  • 电话:010-86393388
  • 邮件:udn@yonyou.com
  • 地址:北京市海淀区北清路68号
移动客户端下载
关注我们
  • 微信公众号:yonyouudn
  • 扫描右侧二维码关注我们
  • 专注企业互联网的技术社区
版权所有:用友网络科技股份有限公司82041 京ICP备05007539号-11 京公网网备安1101080209224 Powered by Discuz!
快速回复 返回列表 返回顶部