数据库作死指南(一)——事故集

因为公司主力数据库用的Oracle11g,正好我也接受过OCP考试的培训(只考出一门,第二门考不出),用起数据库来还算得心应手。入职四年来,也算弄出过一点数据库事故,特别最近一年因调岗到清算部门,获得了数据库owner的权限,作死的步伐就从未停下。

数据库比较

10年前(200x-2015),感觉说到数据库就是三大哥Oracle、SQL Server 和 MySql,现在 RDMS 则又多了PostgreSQL。差不多2010年后开始流行NoSQL,产生了新三哥MongoDB、Redis 和 Couchbase(Memcached)。过了几年,开始流行大数据,HBase和Hive开始登上舞台。这两年又流行 NewSQL 分布式数据库,在谷歌发布了 Spanner/F1 论文后,国产厂商做出了 TIDB 和 OceanBase。

数据库老三哥我都用过,Oracle作为老大哥肯定是最好用的。 微软 SQL Server 这东西虽然听说性能也不逊于 Oracle 多少,但我的体验极差,自带的 SQL Server Managerment Studio 手感极差,我曾经给一个老库换新库,操作了2小时就是各种报错匹配不上。虽然现在 SQL Server 移植到 linux 上了,但感觉也只不过是给老系统升级提供的一个可选方案,我还曾听说 SQL Server 用力最多的地方是对 NTFS 的优化。

MySql 在公司的应用不多,但我曾经对其进行过性能测试。在同一台机器上(112核,512G内存,SSD 0.8T*10,千兆网卡)分别启动 Oracle11g、MySql5.6 对一张亿级表进行查询测试。取返回数据的情况下 Oracle 每秒执行 sql 数是mysql 的2倍,不取返回数据能达到10倍。出口带宽打满的情况下,Oracle 返回数据也比MySql多1倍。Oracle 10分钟后磁盘IO使用率下降到20%,MySql 20分钟后才下降到20%。这说明MySql在磁盘IO、缓存算法、通讯协议都有差距,更别提索引等高级查询上的差距。

PostgreSQL 没怎么用过,但日常被吹爆,形象已经被安利洗脑成 free & open source Oracle。MongoDB 没怎么用过,优势是 Schema 可以随便改和天生 Json,不过听同事说性能不大行,连接数上限低。Couchbase 所有功能应该都能被 Redis 替换,而且 Redis 还提供更多的功能。不过我只用过 Redis 做分布式锁和缓存,秒杀、队列什么的都没尝试过。

Hive 没用过,HBase 倒是用过,本来计划用于存储交易查询的交易记录,想着几十亿级的记录应该对 HBase 来说问题不大,不过实际配合 Phoenix 查询起来速度在百毫秒级,感觉并不是很理想。离岗后,其他人则计划用 ElasticSearch 来实现这个查询,我则对 ES 的高并发性能和大规模更新有所顾虑,所以放弃了这个方案。当然我最希望用的是 TIDB,在可用性、可扩展性、查询性能上都能满足需求。

一些事故

除了刚入职时代码中没开事务导致没回滚,插了脏数据外,别的事故好像都被 DBA 发现了。特别我这有一个1m9 180斤的超强壮 DBA,在他面前,只能瑟瑟发抖。

很多事故都记忆不清了,不过第一个事故记忆还是很清晰的。那是入职一年后,我做的一个新项目,上线前做了很多测试,特别是用户导了很多次,但是上线一小时后,系统就挂了,因为数据库被打爆了。具体原因是因为用户表 insert + delete 很多次,导致数据碎片化,查询用户无法命中索引,重新建表后恢复正常,大概影响登录后主界面展示半小时,算是一个非常严重的事故。

不过偶尔的一些锁表、锁行、测试环境错删数据这些都不是事。好像还有一些 sql 执行慢影响了业务,这些也造成了一定的影响。还有主备同步挂了,导致数据不正确,影响了业务正确性。

有一次机房 linux 专用的 NTP 服务器挂了,导致所有数据库时间变成 1970 年,造成当时所有业务数据不正确,还好当时不是收盘前,紧急准备了大量 sql 刷了全部数据。

其中参与了两次支付组高峰时数据库故障的定位,那次通过 zabbix 发现数据库流量瞬间下降和磁盘 IO 瞬间上升,配合业务日志发现有一个业务配置项读取速度很慢,定位了这句 sql 影响了业务。因为这台数据库机器已经6年了,第一次故障后重启了,但依旧发生了故障,之后就换了一台新的数据库机器。顺带一提,在那之后的一段期间内支付好像缓存了这个配置,我这边业务观察到支付速度提高了一倍(每笔1s缩短了一半

有一次某台备库挂了,因为程序读备库的 IP 配置是写死的,来不及修改配置切换备库,也影响了好久业务。之后数据库地址就改成域名了。

最严重的一次是买的 EMC 挂了,据说是因为断电了。导致有 3 组分区数据库故障,最后只能等机房自动恢复。这次让老板很生气,因为这是花了最多成本的硬件设备,以及希望 EMC 来保证整体的可靠性,但他却挂了。之后某位老板要求做一个交易无需数据库的技术方案,并达到单机 TPS 2w 的数据。虽然之后确实依赖 kafka 实现异步落库的方案,rpc 框架用的 SOFAStack。(虽然我认为 SOFAStack 应该是 spring cloud 的一条歧路)(验证性 demo 写的时候能确实达到单机 2w,等加了业务逻辑后,好像 1w 都没了

后来来到清算部门后,获得了清算库的 owner 权限,我每天 create、drop、truncate 语句写的不亦乐乎,爽的飞起,同时小事故也越来越多,当然因为不直接影响用户前台业务,处理起来也更加方便。

其中我为了优化一张表的 insert 语句的性能,我在 insert 前把表上的全部索引都 disable 了,但是一直有程序扫描这张表,程序的 select 语句没法使用索引,产生报错,导致对这张表所有的 ddl 都报错,直到索引重建恢复。

还有就是最近清算也换了一台数据库机器,cpu 核数达到 192 核,4T ssd * 12,万兆网卡。应该说性能劲爆强,但一开始有些磨合不足,很多 sql 执行很慢,然后就和 DBA 合作了2天优化这些 sql,又积累了不少优化 sql 的经验。最后这台新数据库帮助我们日常业务用时缩短了近20%。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注