昨日のブログ記事ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæƒ³åƒä»¥ä¸Šã«å¤šãã€ã¨ã¦ã‚‚驚ã„ã¦ã„ã¾ã™ã€‚
MySQL/MariaDBã¨Transactdã®InnoDBãƒãƒƒã‚¯åˆ¶å¾¡è©³ç´°ã€€ãã®1 - BizStationブãƒã‚°
ã“ã®ä¸ã§ã€REPEATABLE-READã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã§ã€ã€Œãƒãƒƒã‚¯ãªã—èªã¿å–りã—ãŸå€¤ã‚’å…ƒã«æ›´æ–°ã—ã¦ã¯ã„ã‘ãªã„ã€ã¨æ›¸ã„ãŸã®ã§ã™ãŒã€å…·ä½“çš„ãªã‚µãƒ³ãƒ—ルを入れã¦ã„ãªã‹ã£ãŸã®ã§ã€ã“ã“ã§ç´¹ä»‹ã—ãŸã„ã¨æ€ã„ã¾ã™ã€‚
REPEATABLE-READã«ãªã‚‰ãªã„トランザクションを試ã™
æ›´æ–° (update)よりもã€Insertã®æ–¹ãŒã‚ˆã‚Šé©šããŒã‚りã¾ã™ã®ã§ã€Insertã§ç¤ºã—ã¾ã™ã€‚
ã¾ãšã¯å‰æº–å‚™ã§ã™ã€‚MySQLã®ã‚³ãƒžãƒ³ãƒ‰ãƒ—ãƒãƒ³ãƒ—トを開ã„ã¦ã€ä»¥ä¸‹ã®SQLã§ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã¨ãƒ†ãƒ¼ãƒ–ルを用æ„ã—ã¾ã™ã€‚
CREATE DATABASE test1; USE test1; CREATE TABLE `test1`.`test1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `field2` int(11) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB; INSERT INTO `test1`.`test1` (`field2`) VALUES (11); SET SESSION TRANSACTION ISOLATION LEVEL repeatable read; SELECT @@tx_isolation;
準備ãŒã§ããŸã‚‰ã€ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’é–‹å§‹BEGIN;
ã—ã¦ã€SELECT * FROM test1;
ã§INSERTã®ç¢ºèªã‚’ã—ã¾ã™ã€‚
BEGIN; /* <--- Trx id = N */ SELECT * FROM test1; /* <-- Consistent nonlocking reads, */ +----+--------+ /* reads version N */ | id | field2 | +----+--------+ | 1 | 11 | +----+--------+
BEGIN;
ã§ã“ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®idãŒæ±ºã¾ã‚Šã¾ã™ã€‚ã“ã“ã§ã¯Nã¨ã—ã¾ã™ã€‚SELECT * FROM test1;
ã¯ãƒãƒƒã‚¯ãªã—リードãªã®ã§Consistent nonlocking readsã§ã™ã€‚ã“ã“ã§èªã¿å–ã£ãŸãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯Nã§ã™ã€‚
ã“ã“ã§ã€åˆ¥ã®ã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆã‹ã‚‰INSERT INTO `test1`(`field2`) VALUES (12);
を実行ã—ã¾ã™ã€‚
/* execute following command FROM ANOTHER CONNECTION. */ USE test1; INSERT INTO `test1`(`field2`) VALUES (12); /* <--- Trx id = N+1 */ /* (auto transaction N+1) */
ã“ã“ã§å®Ÿè¡Œã—ãŸINSERTã¯åˆ¥ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ id=N+1 (自動トランザクション) ã§å‡¦ç†ã•れã¾ã™ã€‚
次ã«ã€å…ƒã®ã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆã«æˆ»ã£ã¦ã€å†ã³SELECT * FROM test1;
を見ã¦ã¿ã¾ã™ã€‚
SELECT * FROM test1; /* <-- Consistent nonlocking reads, */ +----+--------+ /* reads version N */ | id | field2 | +----+--------+ | 1 | 11 | +----+--------+ 1 row in set (0.02 sec)
ã¡ã‚ƒã‚“ã¨ã•ã£ãã¨åŒã˜çµæžœãŒè¡¨ç¤ºã•れã¾ã™ã€‚REPEATABLE-READã§ã™ã。
ã§ã¯æ¬¡ã«ã€LOCK IN SHARE MODEã‚’åŠ ãˆã¦ã€SELECT * FROM test1 LOCK IN SHARE MODE;
を実行ã—ã¾ã™ã€‚
SELECT * FROM test1 LOCK IN SHARE MODE; /* <-- Locking reads, */ +----+--------+ /* reads latest version */ | id | field2 | +----+--------+ | 1 | 11 | | 2 | 12 | +----+--------+
ã‚れれï¼ï¼ï¼ 別ã®ã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆã§INSERTã—ãŸã‚‚ã®ã¾ã§è¦‹ãˆã¦ã—ã¾ã£ã¦ã„ã¾ã™ã€‚
ãƒãƒƒã‚¯ã‚’è¦æ±‚ã™ã‚‹ã¨ã€ã‚¹ãƒŠãƒƒãƒ—ショットã¯ãƒãƒƒã‚¯ã§ããªã„ã®ã§ã€æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’èªã¿å–ã£ã¦ãƒãƒƒã‚¯ã—ã¾ã™ã€‚è¨€ã„æ›ãˆã‚‹ã¨ã€ãƒãƒƒã‚¯è¦æ±‚ã¯ã€Œæœ€æ–°ã‚’ãƒãƒƒã‚¯ã—ã¦ãã€ã¨è¨€ã£ã¦ã„ã‚‹ã®ã¨åŒç¾©ã§ã™ã€‚(SELECT * FROM test1 LOCK IN LATEST VERSION SHARE MODEã£ã¦ã‚³ãƒžãƒ³ãƒ‰ã ã£ãŸã‚‰åˆ¤ã‚Šã‚„ã™ã„ã‹ã‚‚。ãƒãƒƒã‚¯ãªã—ã¯ã€SELECT * FROM test1 READ OWN TRX VERSIONã§ã™ã。)
更新処ç†(UPDATE,DELETE)ã¯ã€MySQLãŒè‡ªå‹•ã§ãƒãƒƒã‚¯ä»˜èªã¿å–りをã—ã¾ã™ã€‚ãªã®ã§ã€Œãƒãƒƒã‚¯ãªã—èªã¿å–りã—ãŸå€¤ã‚’å…ƒã«æ›´æ–°ã—ã¦ã¯ã„ã‘ãªã„ã€ã§ã™ã€‚
é¢ç™½ã„ã®ã§ã€ã“ã“ã§ã€å…ƒã®ã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆã‹ã‚‰INSERTã—ã¦ã¿ã¾ã™ã€‚
INSERT INTO `test1`(`field2`) VALUES (13); /* <--- Trx id = N */
ãã—ã¦ã‚„ã¯ã‚Šãƒãƒƒã‚¯ãªã—ã¨ãƒãƒƒã‚¯ä»˜ã§èªã¿å–ã£ã¦ã¿ã¾ã™ã€‚
SELECT * FROM test1; /* <-- Consistent nonlocking reads, */ +----+--------+ /* reads version N */ | id | field2 | +----+--------+ | 1 | 11 | | 3 | 13 | +----+--------+ SELECT * FROM test1 LOCK IN SHARE MODE; /* <-- Locking reads, */ +----+--------+ /* reads latest version */ | id | field2 | +----+--------+ | 1 | 11 | | 2 | 12 | | 3 | 13 | +----+--------+
予想通りã¨ã„ã†ã‹è¦æ±‚ã©ãŠã‚Šã€ãƒãƒƒã‚¯ãªã—èªã¿å–りã¯ãƒãƒ¼ã‚¸ãƒ§ãƒ³Nã®ã‚¹ãƒŠãƒƒãƒ—ショットを返ã—ã€ãƒãƒƒã‚¯ä»˜ã¯æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’è¿”ã—ã¾ã™ã€‚
(ãƒãƒƒã‚¯ãªã—ã¯OWN TRX VERSIONã‚’è¦æ±‚ã—ã€ãƒãƒƒã‚¯ä»˜ã¯LATEST VERSIONã‚’è¦æ±‚)
COMMIT; SELECT * FROM test1; /* <--- Consistent nonlocking reads, */ +----+--------+ /* reads latest version */ | id | field2 | /* auto transaction trx id > N+1 */ +----+--------+ | 1 | 11 | | 2 | 12 | | 3 | 13 | +----+--------+
コミットã—ã¦ã‹ã‚‰ãƒãƒƒã‚¯ãªã—èªã¿å–りをã™ã‚‹ã¨ã€ã“ã®èªã¿å–りã«ã‚‚(自動)トランザクションã®idãŒå‰²ã‚ŠæŒ¯ã‚‰ã‚Œã¦ã€N+1よりも大ãã„値ã«ãªã‚Šã¾ã™ã€‚èªã¿å–りã«ã¯ãã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ï¼ˆN+1+x)ã®ã‚¹ãƒŠãƒƒãƒ—ショットãŒä½¿ã‚れã€ãれã¯ã»ã¼æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã™ã€‚
ã¾ã¨ã‚
InnoDBã®MVCCã¨ãƒãƒƒã‚¯ã‚’ç†è§£ã™ã‚‹ã¨ã€ä¸€è¦‹ã™ã‚‹ã¨ä¸æ€è°ã«æ€ãˆã‚‹ã“れらã®å‹•作も予想通りã§ã™ã€‚ã¾ãŸã€ã“ã®å‹•作(振る舞ã„)ã¯ä»•æ–¹ãŒãªã„ã‚‚ã®ã‹ã¨æ€ã„ã¾ã™ã€‚(判りã¥ã‚‰ã„ã®ã¯ç¢ºã‹ã§ã€æ”¹å–„ã®ä½™åœ°ã¯ã‚ã‚‹ã‹ã¨ã¯æ€ã„ã¾ã™ãŒã€‚)
InnoDBã®MVCCã¨ãƒãƒƒã‚¯ã®è©³ç´°ã¯ä»¥ä¸‹ã®è¨˜äº‹ã§ã€‚
MySQL/MariaDBã¨Transactdã®InnoDBãƒãƒƒã‚¯åˆ¶å¾¡è©³ç´°ã€€ãã®1 - BizStationブãƒã‚°
PlanetMySQL Voting: Vote UP / Vote DOWN