一條 update 語(yǔ)句引起的事故這回讓開(kāi)發(fā)長(zhǎng)長(zhǎng)記性_第1頁(yè)
一條 update 語(yǔ)句引起的事故這回讓開(kāi)發(fā)長(zhǎng)長(zhǎng)記性_第2頁(yè)
一條 update 語(yǔ)句引起的事故這回讓開(kāi)發(fā)長(zhǎng)長(zhǎng)記性_第3頁(yè)
一條 update 語(yǔ)句引起的事故這回讓開(kāi)發(fā)長(zhǎng)長(zhǎng)記性_第4頁(yè)
一條 update 語(yǔ)句引起的事故這回讓開(kāi)發(fā)長(zhǎng)長(zhǎng)記性_第5頁(yè)
已閱讀5頁(yè),還剩1頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

一條update語(yǔ)句引起的事故,這回讓開(kāi)發(fā)長(zhǎng)長(zhǎng)記性?。?!一、前言最近經(jīng)常碰到開(kāi)發(fā)誤刪除誤更新數(shù)據(jù),這不,他們又給我找了個(gè)麻煩,我們來(lái)看下整個(gè)過(guò)程。二、過(guò)程由于開(kāi)發(fā)需要在生產(chǎn)環(huán)節(jié)中修復(fù)數(shù)據(jù),需要執(zhí)行120條SQL語(yǔ)句,需要將數(shù)據(jù)進(jìn)行更新于是開(kāi)發(fā)連上了生產(chǎn)數(shù)據(jù)庫(kù),首先執(zhí)行了第一條SQL:update

tablename

set

source_name=

"bj1062-北京市朝陽(yáng)區(qū)常營(yíng)北辰福第"

where

source_name=

"-北京市朝陽(yáng)區(qū)常營(yíng)北辰福第"我們仔細(xì)看了下,這個(gè)SQL,的確沒(méi)有什么問(wèn)題,where條件也是正常的,大意就是將這個(gè)地址的前面加字符串bj1062,是真的沒(méi)有錯(cuò)誤么?是的沒(méi)有錯(cuò)誤。開(kāi)發(fā)執(zhí)行完成后,結(jié)果的確是符合預(yù)期。然后開(kāi)發(fā)執(zhí)行了剩下的SQL,都是和上面的SQL一樣,將地址進(jìn)行更新。執(zhí)行完成后,開(kāi)發(fā)懵逼了,發(fā)現(xiàn)source_name都變成了0,開(kāi)發(fā)趕緊給我打電話說(shuō):Harvey,我執(zhí)行了update,where條件都是對(duì)的,set的值也是對(duì)的,但是set后的字段全部都變成了0,你趕緊幫我看看,看看能不能恢復(fù)數(shù)據(jù)。我趕緊登上服務(wù)器,查看了這段時(shí)間的binlog,發(fā)現(xiàn)了大量的updatetablenamesetsource_name=0的語(yǔ)句,利用binlog2sql進(jìn)行了解析。趕緊和開(kāi)發(fā)確定了操作的時(shí)間點(diǎn),生成flashback的SQL,進(jìn)行了數(shù)據(jù)恢復(fù),同時(shí)保留現(xiàn)場(chǎng)證據(jù)。然后對(duì)開(kāi)發(fā)執(zhí)行的SQL進(jìn)行了check,發(fā)現(xiàn)了幾條很詭異的SQL:這幾條SQL的引號(hào)位置跑到了where字段名字后面,簡(jiǎn)化后的SQL變成了:update

tbl_name

set

str_col="xxx"

=

"yyy"那么這個(gè)SQL在MySQL他是如何進(jìn)行語(yǔ)義轉(zhuǎn)化的呢?可能是下面這樣的么?update

tbl_name

set

(str_col="xxx"

)=

"yyy"這樣就語(yǔ)法錯(cuò)誤了,那么只會(huì)是下面這樣的形式,update

tbl_name

set

str_col=("xxx"

=

"yyy")而select

"xxx"

=

"yyy"的值是0,所以u(píng)pdate

tbl_name

set

str_col="xxx"

=

"yyy"等價(jià)于update

tbl_name

set

str_col=0所以就導(dǎo)致了source_name字段全部更新成了0.我們?cè)傺芯肯聅elect形式這種語(yǔ)句會(huì)怎么樣。mysql

[localhost]

{msandbox}

(test)

>

select

id,str_col

from

tbl_name

where

str_col="xxx"

=

"yyy";

+----+---------+

|

id

|

str_col

|

+----+---------+

|

1

|

aaa

|

|

2

|

aaa

|

|

3

|

aaa

|

|

4

|

aaa

|

+----+---------+我們發(fā)現(xiàn),這個(gè)SQL將str_col='aaa'的記錄也查找出來(lái)了,為什么呢?mysql

[localhost]

{msandbox}

(test)

>

warnings

Show

warnings

enabled.

mysql

[localhost]

{msandbox}

(test)

>

explain

extended

select

id,str_col

from

tbl_name

where

str_col="xxx"

=

"yyy"\G

***************************

1.

row

***************************

id:

1

select_type:

SIMPLE

table:

tbl_name

type:

index

possible_keys:

NULL

key:

idx_str

key_len:

33

ref:

NULL

rows:

4

filtered:

100.00

Extra:

Using

where;

Using

index

1

row

in

set,

1

warning

(0.00

sec)

Note

(Code

1003):

/*

select#1

*/

select

`test`.`tbl_name`.`id`

AS

`id`,`test`.`tbl_name`.`str_col`

AS

`str_col`

from

`test`.`tbl_name`

where

((`test`.`tbl_name`.`str_col`

=

'xxx')

=

'yyy')這里他把where條件轉(zhuǎn)化成了((`test`.`tbl_name`.`str_col`

=

'xxx')

=

'yyy')這個(gè)條件的首先判斷str_col和'xxx'是否相等,如果相等,那么里面括號(hào)的值為1,如果不相等,就是0然后0或者1再和和'yyy'進(jìn)行判斷,由于等號(hào)一邊是int,另外一邊是字符串,兩邊都轉(zhuǎn)化為float進(jìn)行比較,可以看我之前的一篇文章MySQL中隱式轉(zhuǎn)換導(dǎo)致的查詢結(jié)果錯(cuò)誤案例分析'yyy'轉(zhuǎn)化為浮點(diǎn)型為0,0和0比較恒等于1。搜索公眾號(hào)后端架構(gòu)師后臺(tái)回復(fù)“架構(gòu)整潔”,獲取一份驚喜禮包。參考閱讀:一條垃圾SQL,把64核CPU快跑崩了!mysql

[localhost]

{msandbox}

(test)

>

select

'yyy'+0.0;

+-----------+

|

'yyy'+0.0

|

+-----------+

|

0

|

+-----------+

1

row

in

set,

1

warning

(0.00

sec)

mysql

[localhost]

{msandbox}

(test)

>

select

0=0;

+-----+

|

0=0

|

+-----+

|

1

|

+-----+

1

row

in

set

(0.00

sec)這樣導(dǎo)致結(jié)果恒成立,也就是select語(yǔ)句等價(jià)于以下SQL

select

id,st

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論