footballr 2017-2-8 10:32
公司有個 java program 會用來 update 部舊 Redhat server 的 MySQL 5.1.34, 運作多年一齊正常, 直至近月出現異常, 就係某一條 update SQL update 唔晒所有理應可以被 update 到既 records, 有部份會漏左. 於是嘗試用 SQL client 手動尋找原因, 發現以下奇怪現象:
1. select * from tableA where A & B; --> 5 rows fetched
2. update tableA set something=xxx where A & B; --> 2 rows updated
3. 隔左兩秒再行 (2) 條 update, 又多兩條被 update
4. 隔多兩秒再行 (2) 條 update, 最后一條才被 update
相同 where conditions 但唔能夠一次過 update 晒所有 records, 而由 (1) 至 (4) 那十秒八秒鐘又肯定背後冇 prorgram 轉個 tableA 既內容, restart 過 MySQL server 都係一樣, 請問有冇師兄有 idea 係乜問題呢? Thanks.
assembly.jc 2017-2-8 13:32
Records locked 吧。如果沒有記錯,MySQL 是 lock read 的,即另一個transaction 執行了select statement,在未有commit/rollback 前。selected records 是會鎖定的。
我的無比膏 2017-2-8 13:42
點解會覺得mysql 問題?問下自己改過啲咩先,有冇install patch
footballr 2017-2-8 14:47
[quote]原帖由 [i]assembly.jc[/i] 於 2017-2-8 01:32 PM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=456034941&ptid=26431984][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]
Records locked 吧。如果沒有記錯,MySQL 是 lock read 的,即另一個transaction 執行了select statement,在未有commit/rollback 前。selected records 是會鎖定的。 [/quote]
那個 tableA 是用 MyISAM engine 而不是 InnoDB engine, 以我所知並不支援 commit/rollback transaction. 而且那些先 select 確認 result set 再行 update 既動作在現存系統上我已行過無數次, 從未見過每次只能 update 部份 result set 既情況, 非常奇怪.
footballr 2017-2-8 14:54
[quote]原帖由 [i]我的無比膏[/i] 於 2017-2-8 01:42 PM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=456035381&ptid=26431984][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]
點解會覺得mysql 問題?問下自己改過啲咩先,有冇install patch [/quote]
因為整部 Redhat server 最近並沒有做過任何 update, 包括 MySQL server, 來來去去都係在同一個 DB 加減 table 和加減 record, 有諗過係咪自己邊個 step 出現人為錯誤, 但諗來諗去都諗唔到, 亦同 teammate 研究過, 可惜仍無任何頭緒.
[[i] 本帖最後由 footballr 於 2017-2-8 02:56 PM 編輯 [/i]]
assembly.jc 2017-2-9 19:48
[quote]原帖由 [i]footballr[/i] 於 2017-2-8 02:47 PM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=456038685&ptid=26431984][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]
那個 tableA 是用 MyISAM engine 而不是 InnoDB engine, 以我所知並不支援 commit/rollback transaction. 而且那些先 select 確認 result set 再行 update 既動作在現存系統上我已行過無數次, 從未見過每次只能 ... [/quote]
對,MyISAM engine 不支援 commit/rollback transaction的,也因此會發生 partial update 的情況。看看以下例子。
[url=https://bugs.mysql.com/bug.php?id=57880]https://bugs.mysql.com/bug.php?id=57880[/url]
估計你每次執行 update statement,update 2 條 records 後就發生錯誤 (沒有 error message?),導致執行停止,但因 MyISAM 沒有 rollback,所以更新了的資料被保留。
form5 2017-2-10 00:07
myisamcheck 下table 同myi file 先
footballr 2017-2-10 11:52
[quote]原帖由 [i]assembly.jc[/i] 於 2017-2-9 07:48 PM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=456112479&ptid=26431984][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]
估計你每次執行 update statement,update 2 條 records 後就發生錯誤 (沒有 error message?),導致執行停止,但因 MyISAM 沒有 rollback,所以更新了的資料被保留。 [/quote]
其實我都係咁懷疑, 只係 select 晒相關 records 出來人眼望落去又正正常常, 兼且沒有 error message, 所以毫無頭緒, 以及唔知點樣可以防止日後再發生.
[[i] 本帖最後由 footballr 於 2017-2-10 11:56 AM 編輯 [/i]]
footballr 2017-2-10 11:54
[quote]原帖由 [i]form5[/i] 於 2017-2-10 12:07 AM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=456124581&ptid=26431984][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]
myisamcheck 下table 同myi file 先 [/quote]
行完 myisamchk 同 check table 都好似冇異樣.
[font=細明體][color=#ff0000][root@Server]# myisamchk -e -i /PATH/tableA.MYI[/color][/font]
[font=細明體]Checking MyISAM file: /PATH/tableA.MYI[/font]
[font=細明體]Data records: 1567255 Deleted blocks: 0[/font]
[font=細明體]- check file-size[/font]
[font=細明體]- check record delete-chain[/font]
[font=細明體]- check key delete-chain[/font]
[font=細明體]- check index reference[/font]
[font=細明體]- check data record references index: 1[/font]
[font=細明體]Key: 1: Keyblocks used: 68% Packed: 0% Max levels: 4[/font]
[font=細明體]- check data record references index: 2[/font]
[font=細明體]Key: 2: Keyblocks used: 99% Packed: 93% Max levels: 4[/font]
[font=細明體]- check data record references index: 3[/font]
[font=細明體]Key: 3: Keyblocks used: 98% Packed: -11% Max levels: 4[/font]
[font=細明體]Total: Keyblocks used: 83% Packed: 71%[/font]
[font=細明體][/font]
[font=細明體]- check records and index references[/font]
[font=細明體]Records: 1567255 M.recordlength: 77 Packed: 89%[/font]
[font=細明體]Recordspace used: 100% Empty space: 0% Blocks/Record: 1.00[/font]
[font=細明體]Record blocks: 1567255 Delete blocks: 0[/font]
[font=細明體]Record data: 120886033 Deleted data: 0[/font]
[font=細明體]Lost space: 561078 Linkdata: 6041885[/font]
[font=細明體][/font]
[font=細明體]User time 87.06, System time 0.26[/font]
[font=細明體]Maximum resident set size 0, Integral resident set size 0[/font]
[font=細明體]Non-physical pagefaults 18067, Physical pagefaults 0, Swaps 0[/font]
[font=細明體]Blocks in 0 out 0, Messages in 0 out 0, Signals 0[/font]
[font=細明體]Voluntary context switches 5, Involuntary context switches 409[/font]
[font=細明體][/font]
[font=細明體][color=#ff0000]mysql> check table tableA extended;[/color][/font]
[font=細明體]+----------------+-------+----------+----------+[/font]
[font=細明體]| Table | Op | Msg_type | Msg_text |[/font]
[font=細明體]+----------------+-------+----------+----------+[/font]
[font=細明體]| myDB.tableA | check | status | OK |[/font]
[font=細明體]+----------------+-------+----------+----------+[/font]
[font=細明體]1 row in set (1 min 31.71 sec)[/font]
xianrenb 2017-2-10 12:37
[quote]原帖由 [i]footballr[/i] 於 2017-2-8 10:32 AM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=456026074&ptid=26431984][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]
公司有個 java program 會用來 update 部舊 Redhat server 的 MySQL 5.1.34, 運作多年一齊正常, 直至近月出現異常, 就係某一條 update SQL update 唔晒所有理應可以被 update 到既 records, 有部份會漏左. 於是嘗試用 ... [/quote]
會不會 A 、 B 有 SQL injection 的情況?
實際上又是什麼?
或者可以改用別的 field name 表示相同的 statement 貼上來,讓網友們了解多些。
另外 SQL 中用 “AND” 而不是 “&”,不過可能你只是在表示用上兩個 condition 來 “AND ”。
footballr 2017-2-10 12:48
[quote]原帖由 [i]xianrenb[/i] 於 2017-2-10 12:37 PM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=456143157&ptid=26431984][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]
會不會 A 、 B 有 SQL injection 的情況?
實際上又是什麼?
或者可以改用別的 field name 表示相同的 statement 貼上來,讓網友們了解多些。
另外 SQL 中用 “AND” 而不是 “&”,不過可能你只是在表示用上兩個 condition 來 “AND ”。 [/quote]
我想令條問題易睇 D 所以將 where columnA='A' and columnB='B' 縮寫成 where A & B.
我的無比膏 2017-2-10 13:36
你個數據量都唔少,行下execute plan, 睇下sql有冇問題,又或者開個nmon 睇下
assembly.jc 2017-2-12 22:44
[quote]原帖由 [i]footballr[/i] 於 2017-2-10 11:52 AM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=456140860&ptid=26431984][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]
以及唔知點樣可以防止日後再發生
[/quote]
對於一些 (如 MyISAM般) 沒有 atomic control 的 db engine,如果程式允許修改。可以考慮其他 work around 的方法。例如重覆執行 update statement,直至所有 records 都更新為止。考慮以下例子 (請自行轉回 java code)[code]n_not_updated NUMBER;
FOR i IN 1 .. 100 LOOP // try 100 times
update tableA
set something=XXX
where A&B
and something != XXX;
select count(*) into n_not_updated
from tableA
where A&B
and something != XXX;
IF n_not_updated == 0 THEN
BREAK;
END IF;
END LOOP;
IF n_not_update > 0 THEN
LOG_ERROR("Records not fully updated");
END IF; [/code]
footballr 2017-2-14 17:01
[quote]原帖由 [i]assembly.jc[/i] 於 2017-2-12 10:44 PM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=456297924&ptid=26431984][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]
對於一些 (如 MyISAM般) 沒有 atomic control 的 db engine,如果程式允許修改。可以考慮其他 work around 的方法。例如重覆執行 update statement,直至所有 records 都更新為止。考慮以下例子 (請自行轉回 java ... [/quote]
多謝師兄提醒, 這確實是一個權宜之計, 可以暫時解決住先. :loveliness:
頁:
[1]