February 19th, 2007 by depesz | | 16 comments »
Did it help? If yes - maybe you can help me?

postawiłem sobie w miarę nowego mysql'a: Server version: 5.0.32-Debian_2-log Debian etch distribution.

zrobiłem sobie testową tabelkę:

mysql> create table x (id int primary key);
Query OK, 0 rows affected (0.05 sec)

sprawdzam czy dobrze się założyła, wygląda ok:

mysql> desc x;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id    | int(11) | NO   | PRI |         |       |
+-------+---------+------+-----+---------+-------+
1 row in set (0.08 sec)

no to teraz pora na zabawę. wstawiam tam 1 rekord:

mysql> insert into x (id) values (6);
Query OK, 1 row affected (0.06 sec)

nadal ok. to teraz wstawiam 10 rekordów z celowym błędem:

mysql> insert into x (id) values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
ERROR 1062 (23000): Duplicate entry '6' for key 1

i teraz zagadka/pytanie:

ile jest rekordów w bazie?

odpowiedź – po przerwie.

uznałbym za naturalne, że jest 1 rekord – ten z id = 1.

ponieważ myisam (domyślny engine) nie jest transakcyjny, uznałbym też, że może być 10 rekordów – w końcu taki insert to jakby 10 insertów, a fakt, że 1 padł przy braku transakcyjności jest mało istotny.

rzeczywistość?

mysql> select * from x;
+----+
| id |
+----+
|  1 |
|  2 |
|  3 |
|  4 |
|  5 |
|  6 |
+----+
6 rows in set (0.00 sec)

i teraz. ja naprawdę nie czepiam się braku transakcyjności. dziwnych obejść. ale mysql właśnie zademonstrował wykonanie części polecenia. kawałka. bo tak.

  1. 16 comments

  2. Feb 19, 2007

    😉

  3. # mithnae
    Feb 19, 2007

    Śliczne 🙂

  4. # Acid
    Feb 19, 2007

    ale z tego co wiem to mysql 5 obsługuje tranzakcje

  5. Feb 19, 2007

    tak, ale w/g manuala (http://dev.mysql.com/doc/refman/5.1/en/ansi-diff-transactions.html)
    nie dla myisam.
    i teraz – ja wiem, że myisam ma swoje problemy i nie ma transakcji.
    dlatego ich się nie czepiam.
    czepiam się, bo w manualu jest:
    The other non-transactional storage engines in MySQL Server (such as MyISAM) follow a different paradigm for data integrity called “atomic operations.” In transactional terms, MyISAM tables effectively always operate in AUTOCOMMIT=1 mode. Atomic operations often offer comparable integrity with higher performance.
    co jest ogólnie bullshitem, bo jak pokazałem insert nie był atomowy!

  6. # mithnae
    Feb 19, 2007

    w dyskusji z Uboottd-em stanęło na tym, że MyISAM jest atomowy, ale na poziomie pojedyńczego wiersza, zaś taki multiinsert jest przez parser traktowany jak MAKRO, którym po rozwienięciu jest karmiony backend. Przy czym uboottd się upierał, że takie zachowanie powinno być jak najbardziej przewidywalne i spodziewane dla backendu nietransakcyjnego, zaś ja – że jeśli komuś piszącemu parser i backend przyszło do głowy, że takie zachownie w ogóle może być dopuszczalne (czyli 5 insertów a nie 0 – nic nie działa – czy 9 – działają wszystkie które się udają), to istotnie ma w tej głowie nic innego jeno bullshit.

  7. Feb 20, 2007

    fajne 🙂

  8. # Maciek Dobrzanski
    Feb 21, 2007

    Jak na tyle lat pracy przy bazach danych to histeryzujesz. To przecież od początku istnienia tak działa 🙂 I dotyczy nie tylko INSERTów, ale UPDATE i DELETE także. Ot, nieścisłość w dokumentacji co rozumieją jako “operation” 🙂

  9. Feb 21, 2007

    może i histeryzuję, ale mysql’a od dawna nie używałem. słyszałem, że wiele rzeczy w nim poprawiono. w dodatku sam z siebie nigdy nie użyłem w nim składni wielo-insertów. i jest dla mnie novum, że tak to działa. bo tak jak pisałem – rozumiem, że można nie mieć transakcji, kluczy obcych itd. fine. ale nie zapewniać atomowości pojedynczej komendy?

  10. # Maciek Dobrzanski
    Feb 21, 2007

    Ale w praktyce czym miało by się różnić wykonanie jednego “wielo-insertu” od wielu niezależnych insertów w kwestii wycofywania zmian? Różnica jest chyba żadna i sprowadza się do tworzenia rejestru operacji, które w efekcie mogą, lub nie, być nałożone na dane, a to wymaga poczynienia kolejnych kroków, które coraz bardziej przybliżają do transakcyjności.

    Operacje wykonywane na tabelach MyISAM odzworowywane są bezpośrednio na danych (lub pośrednio na danych poprzez cache), nie ma więc fizycznej możwliości na wycofanie czegokolwiek.

  11. # Arim
    Feb 23, 2007

    Ale marudzicie. To przecież intuicyjne. Wywalił się przy wstawianiu wartości ‘6’, więc wszystko przed się wrzuciło, a reszta już nie… 😀

  12. # Artur
    Feb 26, 2007

    Sam nie używam MYSQLa, ale jestem ciekaw jak zachowa się przy takich operacjach jak “insert into tab1 select * from tab2”, gdzie w tab2 są takie wartości jak w przytoczonym insercie. Albo, w tabeli są wartości 1,2,3,4,5,6 i ktoś wykona update: “update x set id = id + 1 where id

  13. Feb 27, 2007

    @Artur: w pierwszym wypadku grzecznie dopisze wybrane z tabelki tab2 elementy do tab1, w drugim dla spełniających warunek zinkrementuje id o 1.

  14. # Artur
    Feb 28, 2007

    @MySZ: nie do końca się jasno wyraziłem. Załóżmy, że w jednej instrukcji wstawiasz bądź modyfikujesz rekordy, i pod koniec przetwarzania, któryś z rekordów nie może być zapisany (np. błąd niepowtarzalności). MySQL wycofa modyfikacje, by zapewnić atomowość instrukcji?

  15. Feb 28, 2007

    MyISAM, czyli bez transakcji, nic nie wycofa – to co zostało wykonane to już zostanie, reszta oczywiście nie 🙂

  16. Oct 13, 2011

    INSERT IGNORE …. i po problemie.

  17. Oct 22, 2011

    @Marcin:
    serio?
    a to nie po prostu zignoruje błędy?

Leave a comment