0
Другие записи за это число:
2022/12/20_sneg - Ну что, все откопали свои Судзуки?
<< предыдущая заметкаследующая заметка >>
20 декабря 2022
Для программистов. Маленькие радости Mariadb MySQL

До последних версий Mariadb при попытке записать в таблицу уже имеющиеся там данные возвращала спокойную ошибку. Это ошибку обрабатывал скрипт PHP, и все было нормально.

Но последние версии Mariadb (в частности 15.1 Distrib 10.6.11-MariaDB, for debian-linux-gnu x86_64) в таком случае стали выдавать настолько фатальную ошибку, которую уже не обработать, потому что на ней рушится сам вызвавший ее скрипт PHP. Потому что блять ну нельзя же пытаться записать данные, когда в таблице они уже есть! Шок! Паника! Вызывайте наряд Гестапо! Вот если, скажем, в поле varchar(11) попытаться записать телефонный номер в 12 символов — а вот это блять у нас можно, это вовсе никакая не ошибка, а дело житейское. Мы просто тихо обрежем последнюю цифру телефона и так запишем. Звоните теперь, ваш звонок очень важен для нас.

Короче, я бегло погуглил и не нашел, что случилось, какой ебаный гений в очередной раз изобрел по дефолту всем бывшим пользователям MySQL очередной катаклизм, и как это лечить. То есть — в какую внутреннюю базу настроек надо чем залогиниться или какой ini-файл поправить, указав какую-нибудь свежевыебанную опцию duble_fatal_error_please_no_no_please=false.

Я решил вопрос тупо, но эффективно: добавил запрос-проверку перед записью. Но старшие товарищи мне объяснили, что так поступать дорого, потому что в MySQL есть специально для этого опция INSERT IGNORE. Ок. Я вписал эту опцию, и вроде все заработало... Но со временем я стал замечать, что индекс автоинкремента в таблице неуёмно растет. Схуяль? И тут выяснилось, что INSERT IGNORE индекс по-любому увеличит — вне зависимости, создала она новую запись или нет. С какой целью она это делает, спросите вы? Да хуй знает. Это же Mariadb.

Пример? Созданную таблицу с auto_increment и не позволяющим дублирование полем val полностью очищаем перед сеансом. Записываем val=1. Затем еще десяток раз пытаемся снова (и безуспешно) записать val=1 при помощи INSERT IGNORE. Потом записываем val=2.


<?php
msq
('CREATE TABLE IF NOT EXISTS test (
  id tinyint(10) NOT NULL auto_increment,
  val int(10) NOT NULL,
  PRIMARY KEY (id),
  UNIQUE KEY (val)
) ENGINE=InnoDB AUTO_INCREMENT=1;'
);

msq('TRUNCATE test');

function 
insert($i) { msq('INSERT IGNORE INTO test SET val='.$i); return msq_id(); }

echo 
'\n insert val=1, id='.insert(1);

for(
$i=2;$i<=10;$i++) echo "\n  try #".$i." to insert val=1, id=".insert(1);
// echo "\n"; for($i=2;$i<=126;$i++) { echo $i." "; insert(1); }

echo "\n insert val=2, id=".insert(2);

Результат:


<?php
insert val
=1id=1
  
try #2 to insert val=1, id=0
  
try #3 to insert val=1, id=0
  
try #4 to insert val=1, id=0
  
try #5 to insert val=1, id=0
  
try #6 to insert val=1, id=0
  
try #7 to insert val=1, id=0
  
try #8 to insert val=1, id=0
  
try #9 to insert val=1, id=0
  
try #10 to insert val=1, id=0
insert val=2id=11
?>


Сколько было попыток повторно записать val=1 — на сколько теперь увеличился счетчик id. Ну а если безуспешных попыток будет не десяток, а... ну, скажем, 125 (как вы догадались, я не случайно указал в примере tinyint, да еще без unsigned) — то всё, пиздец, вы ничего уже никогда в эту таблицу больше не запишете. Размерность счетчика исчерпалась на бесплодные попытки:


<?php
insert val
=1id=1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
insert val
=2id=127
insert val
=3id=0
insert val
=4id=0
?>


Если не это пиздец инженерной мысли, то что тогда?

Сейчас, разумеется, в комменты набегут пожилые члены Cекты Свидетели Безгрешной Девы МарииДБ и расскажут нам, что это не бага, а фича. Что счетчик это вовсе не счетчик ячеек, а счетчик обращений. И что пики точёные расставлены на стуле для вашего удобства. Просто надо уметь ими пользоваться как мы, когда каждый день садимся на этот стул работать.

<< предыдущая заметка следующая заметка >>
пожаловаться на эту публикацию администрации портала
архив понравившихся мне ссылок

Комментарии к этой заметке скрываются - они будут видны только вам и мне.

Оставить комментарий