SQL不慎迷失在WHERE
^^^^^^^^^^^^^^^^^^
 - 作者:臭豆腐[trydofor.com]
 - 日期:2009-11-21
 - 授权:署名-非商业-保持一致 1.0 协议
 - 声明:拷贝、分发、呈现和表演本作品,请保留以上全部信息。

0. 文档目录
^^^^^^^^^^^
[[<=$INDEX]]

1. 灾难回顾
^^^^^^^^^^^
出于各种业务需要,项目经常使用SQL手工维护数据。
5个年头里,大概有过4次刻骨铭心的WHERE灾难。

所谓灾难,一般具有以下一些特征。
 * 影响了正式生产环境。
 * 破坏了百万级或千万级的记录。
 * 数据关系复杂,极难还原。
 * 几人日的工作或通宵才能恢复。

造成灾难的原因都十分低级,十分低概率,不经历过也许不会相信,
也许再仔细那么一点点,也许再慢那么一小会儿,就完全可以避免。
但事实是,人是会在某些时候短路,犯不可能的低级错误的。

2. 防范措施
^^^^^^^^^^^
正确完成一个操作,我们需要把正确的SQL执行在正确的数据库上。
取其反,结果可能就是一个灾难。

两类错误,
 * 错误的服务器
 * 错误的但可执行的SQL

三种情况,
 * 正确的SQL执行在错误的数据库上。
 * 错误但可执行的SQL执行在正确的数据库上。
 * 错误但可执行的SQL执行在错误的数据库上。

防范上最为有效的措施是,结对操作,即找个搭档当听众,
把操作上的每一步逻辑和目标讲给他听,并得其确认。

2.1. 正确的数据库
^^^^^^^^^^^^^^^^^
要求上,必须在连接前和链接后确认。操作上,有以下几种策略,

 * 关闭所有无关的链接,或关闭客户端程序。
 * 确认目标数据库的连接,并起个醒目而直接的名字。
 * 连接后,找服务器特征数据,查看确认。

2.2. 正确的SQL
^^^^^^^^^^^^^^
危险的SQL是UPDATE和DELETE,错误但可执行的SQL一般为,
 * 单条SQL,WHERE残缺或错误。
 * 一组SQL,丢失部分SQL。
 * 一组SQL,混入其他SQL。

一组SQL的情况,防范起来比较容易,做好确认和清场工作就可以了。
单条SQL的情况,最为常见和且危险最大。通常做一些制度防范。

第一,全部数据UPDATE和DELETE时,强制使用WHERE 1=1。
====================== SQL : 强制WHERE ======================
// 正常 UPDATE
UPDATE TEST SET FIELD1=1,FIELD2=2
GO
// 强制WHERE UPDATE
UPDATE TEST SET FIELD1=1,FIELD2=2 WHERE 1=1
GO
// 正常 DELETE
DELETE FROM TEST
GO
// 强制WHERE DELETE
DELETE FROM TEST WHERE 1=1
GO
=============================================================

第二,部分数据UPDATE和DELETE时,更新前必须SELECT。
即,把SELECT的WHERE完整的使用在UPDATE和DELETE上。

====================== SQL : 强制SELECT =====================
// 正常 UPDATE
UPDATE TEST SET FIELD1=1,FIELD2=2 WHERE FIELD3 =3
GO
// 强制SELECT UPDATE
SELECT FIELD1=1,FIELD2=2 FROM TEST
//UPDATE TEST SET FIELD1=1,FIELD2=2
WHERE FIELD3 =3
GO
// 正常 DELETE
DELETE FROM TEST WHERE FIELD3 =3
GO
// 强制SELECT DELETE
SELECT FIELD1=1,FIELD2=2
//DELETE 
FROM TEST WHERE FIELD3 =3
GO
=============================================================

说明,强制SELECT主要是为了观察数据,COUNT(1)或关键字段经常用到。
执行的时候分两次,第一次单条全选,第二次从注释开始选。

3. 补救套路
^^^^^^^^^^^
在既有的容灾策略上,减少或消除不良影响,基本套路有,

 * 基于备份回到过去。
 * 根据履历从头再来。
 * 回到过去并从头再来。

操作上,
首先,要冷静,权当在做梦,虚惊一场。
一般发生这事,相关人员会出汗,发热,而发热的头脑只能导致更发热的事故。

然后,回顾细节和确定影响,及时沟通和上报。
三个臭皮匠顶个诸葛亮,纯客观的一五一十的把事情说清楚,以便决策。

最后,确定补救策略和实施细节。
考虑到各种情况和对策,并在实施前,逐条重述一边。

关键一点,整个过程全部精力锁定在如何补救上,不得追究责任或评估后果。