Атомарни ли са множеството вмъквания на mysql в рамките на една заявка?

Правя множество вмъквания в една заявка:

INSERT INTO table (c1, c2) VALUES (1,2),
                                  (2,3),
                                  (3,4),......
         ON DUPLICATE KEY UPDATE c2 = VALUES(c2)

Да предположим сега, че има над десетки хиляди СТОЙНОСТИ, посочени в заявката (оттук и многоточието)....

Може ли някога да има случай, в който някои части от VALUES са успели да бъдат вмъкнати/актуализирани в базата данни, но останалите не са били вмъкнати/актуализирани вероятно поради някаква db грешка/неизправност/изчерпване на паметта и т.н.?

Заявките за mysql ВСИЧКИ или НИЩО ли са?

Вярно ли е, че за всяка изпълнена mysql заявка или всички стойности, посочени в заявката, ще бъдат вмъкнати/актуализирани гладко, или нито една от стойностите няма да бъде вмъкната/актуализирана?


person pillarOfLight    schedule 05.02.2014    source източник
comment
Едно извикване на insert трябва да бъде атомарно във всяка ACID-съвместима база данни.   -  person Gordon Linoff    schedule 05.02.2014
comment
Защо не го тествате - нямате нужда от стотици точки от данни, за да го тествате!   -  person gvee    schedule 05.02.2014
comment
comment
@GordonLinoff MyISAM таблиците обаче не са съвместими с киселина;)   -  person Johannes H.    schedule 05.02.2014
comment
@gvee е почти невъзможно да се тества, както е при всички условия на състезание. с малко късмет можете да проведете 10 000 теста в несъвместими с киселини системи и пак да имате последователни данни.   -  person Johannes H.    schedule 05.02.2014
comment
@JohannesH. . . . Е, предполагам, че това отговаря на въпроса. Не виждам това в документацията на MySQL, но го виждам на rackspace.com/knowledge_center/article/.   -  person Gordon Linoff    schedule 05.02.2014
comment
@GordonLinoff Спецификация връзка е в моя отговор   -  person Johannes H.    schedule 05.02.2014


Отговори (4)


Свойствата ACID (атомност, консистенция, изолация, издръжливост) се използват за описание на подобно поведение в базите данни. Атомичността е важна само ако имаме работа с едновременни модификации. За да се осигури последователност, трябва да се достигне определено ниво на изолация. Колкото по-изолирани се изпълняват множество транзакции обаче, толкова по-малко производителност обикновено има СУБД. Така че има така нареченото „ниво на изолация", което посочва какви грешки може да възникне в СУБД и кои не могат.

Сега MySQL прилага всички нива на изолация в бази данни INNODB и можете да избирате за всяка транзакция: https://dev.mysql.com/doc/refman/5.1/en/set-transaction.html

MyIsam базите данни не поддържат транзакции, отделните операции обаче трябва да се изпълняват атомарно. (Източник: https://dev.mysql.com/doc/refman/5.0/en/ansi-diff-transactions.html). Обърнете внимание обаче, че това НЕ гарантира, че данните не се променят между четенията и записите в една операция - атомарността в термините на СУБД означава само, че операцията е напълно изпълнена или напълно пропусната. НЕ гарантира изолация, последователност или издръжливост.

person Johannes H.    schedule 05.02.2014
comment
Може ли любезно да попитам за какво беше гласуването против? Не виждам никакви коментари или предложения за редактиране... - person Johannes H.; 05.02.2014
comment
. . . Има злонамерени противници. Мисля, че това е добър отговор. +1. - person Gordon Linoff; 05.02.2014
comment
@JohannesH. Може да е, защото връзката на MySQL сочеше към немските документи =) Поправено е. - person Ciro Santilli 新疆再教育营六四事件ۍ 07.07.2014
comment
о Дори не разбрах! Благодаря! - person Johannes H.; 08.07.2014
comment
@JohannesH., Така че в горния пример, ако използваме Innodb, имате ли предвид, че вмъкването на 1000 реда ще бъде или Всичко, или Нищо? Възможно ли е за половин сума напр. 300, 500 или 800 реда за вмъкване? - person Pacerier; 18.12.2014
comment
@Pacerier Ако това е транзакция, тогава тя е или ангажирана, или напълно отменена. Какво означава това зависи от нивото на изолация, което сте избрали. - person Johannes H.; 26.12.2014
comment
@JohannesH., Не, това е в изрична транзакция. Това е просто нормален единичен оператор за вмъкване. Единични оператори, които вмъкват хиляди редове, ползват ли се от предимството на ангажимента или пълното връщане назад? - person Pacerier; 27.12.2014
comment
С включено автоматично поемане (което е по подразбиране) вие сте в транзакция, така че да. Ако сте го изключили (по причини, свързани с производителността или каквото и да е), това силно зависи от това какво имате предвид под всичко или нищо. Възможни ли са сривове? Имате ли изпълнявани едновременни операции? Но като цяло не можете да разчитате на това. - person Johannes H.; 28.12.2014
comment
Ако стартирам php скрипт, който вмъква множество редове в mysql db. Да предположим, че отнема около 5 секунди. Между 5 секунди затварям скрипта, т.е. затварям php страницата в браузъра или прекратявам скрипта в конзолата. Тогава как могат да се вмъкнат редове в db. Също така кажете отговор за 2 възможни случая на употреба. Единият е, ако множество mysql заявки вмъкват много много множество редове и второ, ако една mysql заявка вмъква множество редове. Please answer. May the force be with you. - person Ankit; 11.05.2016
comment
@Ankit Преди всичко: ако която и да е операция с база данни отнема 5 секунди, трябва сериозно да обмислите други решения за каквото и да правите. Второ: Ако всички изрази вече са изпратени до сървъра на базата данни (като е възможно асинхронно изпълнение, например tihs), те ще се изпълнят, дори ако скриптът спре да се изпълнява. Ако не са, зависи колко инструкции са изпратени. Ако сте използвали транзакция и скриптът умира преди ангажимента, промените ще бъдат отменени (т.е. няма промени в края). Ако не, каквото се е случило, станало, каквото още не се е случило, няма да стане. - person Johannes H.; 11.05.2016
comment
@Ankit: За да отговорим конкретно на вашите случаи на употреба, ще ни е необходима повече информация за вашия сървърен стек, кои PHP библиотеки използвате и за вашия код. МОЛЯ, направете го отделен въпрос в този случай (чувствайте се свободни да ме насочите към него, ако го направите) - person Johannes H.; 11.05.2016
comment
-1 за единични операции обаче трябва да се изпълнява атомарно. Трябва? Атомна ли е многоредовата вложка или не? Това беше въпросът - тази публикация не отговаря на него. - person AndreKR; 30.08.2016

"Може ли някога да има случай, в който някои части от VALUES да са успели да бъдат вмъкнати/актуализирани в базата данни, но останалите не са били вмъкнати/актуализирани вероятно поради някаква db грешка/неуспех/изпълнение на паметта- извън и т.н.?"

Късен отговор, но може би интересен: [ON DUPLICATE KEY] UPDATE не е стриктно атомарно за единични редове (нито за MyISAM, нито за InnoDB), но ще бъде атомарно по отношение на грешките.

Каква е разликата? Е, това илюстрира потенциалния проблем при приемането на стриктна атомарност:

CREATE TABLE `updateTest` (
  `bar` INT(11) NOT NULL,
  `foo` INT(11) NOT NULL,
  `baz` INT(11) NOT NULL,
  `boom` INT(11) NOT NULL,
  PRIMARY KEY (`bar`)
)
COMMENT='Testing'
ENGINE=MyISAM;

INSERT INTO `updateTest` (`bar`, `foo`, `baz`, `boom`) VALUES (47, 1, 450, 2);

INSERT
    `updateTest`
    (`bar`, `foo`, `baz`, `boom`)
VALUES
    (47, 0, 400, 5)
ON DUPLICATE KEY UPDATE
    `foo` = IF(`foo` = 1, VALUES(`foo`), `foo`),
    `baz` = IF(`foo` = 1, VALUES(`baz`), `baz`),
    `boom` = IF(`foo` = 1, VALUES(`boom`), `boom`);

(47, 1, 450, 2) ще се е превърнало в (47, 0, 450, 2), а не в (47, 0, 400, 5). Ако приемете стриктна атомарност (което не означава, че трябва; може да предпочетете това поведение), това не трябва да се случва - foo със сигурност не трябва да се променя, преди стойностите на другите колони да са дори оценен. foo трябва да се промени заедно с другите колони - всичко или нищо.

Ако кажа атомарно по отношение на грешки, имам предвид, че ако премахнете условието IF() в горния пример, което подчертава по-строгата ситуация, като тази...

INSERT INTO `updateTest` (`bar`, `foo`, `baz`, `boom`) VALUES (48, 1, 450, 2);

INSERT
    `updateTest`
    (`bar`, `foo`, `baz`, `boom`)
VALUES
    (48, 0, 400, 5)
ON DUPLICATE KEY UPDATE
    `foo` = VALUES(`foo`),
    `baz` = VALUES(`baz`),
    `boom` = VALUES(`boom`);

...винаги или ще завършите с (48, 1, 450, 2) или (48, 0, 400, 5), след като операторът ви приключи/се срине, а не някакво междинно състояние като (48, 0, 450, 2).

Същото важи и за поведението на UPDATE, но има още по-малко причина да се жонглира с IF() изрази там, тъй като можете просто да поставите условните си условия във вашата WHERE клауза там.

В заключение: Извън крайните случаи, имате атомарност за едноредови изрази, дори и да използвате MyISAM. Вижте отговора на Johannes H. за допълнителна информация.

person pinkgothic    schedule 07.10.2014

Ако машината за съхранение на таблици е InnoDB, да , операцията определено е атомарна и частично вмъкване не е възможно. Вярвам, че това не е вярно с MyISAM, машината по подразбиране, тъй като не е съвместима с ACID и не поддържа транзакции.

person TypeIA    schedule 05.02.2014
comment
MyISAM е атомен, но не непременно последователен, издръжлив или изолиран. Вижте моя отговор. - person Johannes H.; 05.02.2014
comment
MyISAM не е атомарна, тъй като терминът обикновено се прилага за системи с бази данни. - person Marcus Adams; 05.02.2014
comment
@MarcusAdams Вижте какво мислите. Съгласен съм, че базите данни MyISAM трябва да прилагат „атомни операции“ като схема за интегритет. Това е по-скоро атомно по начина, по който се използва извън терминологията на СУБД. - person Johannes H.; 05.02.2014

Единични твърдения като това са. Ако имате нужда от множество извиквания, за да действате по атомен начин, можете да използвате транзакции в повечето релационни бази данни.

person krowe    schedule 05.02.2014
comment
Тъй като това е специално за MySQL, това означава, че трябва да използвате INNODB таблици, тъй като MyIsam не поддържа транзакции. - person Johannes H.; 05.02.2014
comment
Бих казал, че ако задавате този въпрос, трябва да използвате InnoDB. Ако целостта на данните е от първостепенно значение, тогава InnoDB почти винаги е по-добър. - person krowe; 05.02.2014
comment
Напълно с теб за това, въпреки че OP Ейми не знам. В допълнение към това, тъй като говорим за огромно количество данни (според OP), скоростта може да е проблем, въпреки че има смисъл за MyISAM. - person Johannes H.; 06.02.2014