Возожность mysqlnd в php

Якщо ви не знаєте, то з PHP / 5.3 поставляється новий mysql драйвер - mysqlnd. У нього є кілька особливостей і супровід, які відрізняють його від libmysql.

Перше не надто интерестно. Тепер при fetch'e результату не відбувається копіювання з пам'яті libmysql в пам'ять, що знаходиться під управлінням zend engine. Фактично весь result set знаходиться в пам'яті zend engine. Це означає що вибірки перевищують за розміром memory limit тепер таки будуть генерувати out of memory. Напевно, це цінна для власників shared хостингу, але для тих у кого виділений сервер це має мало користі.

Друге вже интерестно. З'явилася можливість виконувати запити до бази даних в неблокірующіх манері (в документації ця можливість називається "асинхронними запитами", що буквально кажучи некоректно). Це дозволяє:

  • распараллеливать читання / запис;
  • реалізувати SLA щодо запитів до БД.

Розпаралелювання записи може бути корисним, коли логічна операція запису фізично призводить до оновлення інформації що зберігається на декількох серверах. Особливо це може бути вигідно, коли ваш процес більшу частину часу зайнятий очікуванням підтвердження від БД про цю саму записи (i / o bound). Потреба "писати одразу в кілька місць" може виникнути, наприклад, у випадку, якщо ви робите програмне дзеркало вашої бази даних. На перший погляд це може Показати дурістю, чому б просто не налаштувати реплікацію? Проте, існують ситуації коли application layer реплікація має переваги над mysql-репликацией. Також розпаралелювання записи може бути корисно в разі здійснення складних механізмів sharding'а. Іноді об'єкт повинен бути записаний не в один shard, а в кілька (це вже не зовсім дзеркало). Такі операції записи хороші кандидати для розпаралелювання (по-крайней, мірою до тих пір поки shard'и знаходяться на фізично різних серверах).

І звичайно ж SLA. Особисто нам цього дуже сильно не вистачало. Якщо запит нас не блокує, то технічно ми можемо і не чекати результатів його виконання. Зовсім не чекати сенсу звичайно немає, а ось не чекати довше ніж строго певну кількість часу, буває дуже корисно. Я вже писав раніше про fail fast. Всякий раз коли ви робите більш менш складний запит до БД ви не можете бути впевнені скільки часу займе виконання цього запиту. А користувачі чекати не люблять. Всі напевно були свідками як БД при зростаючій навантаженні все повільніше і повільніше обробляє існуючі запити. У такій ситуації нові запити дають ефект снігової кулі. З іншого боку, цілком можливо, що результат нам не так вже й потрібний. Ну подумати не покажемо користувачеві на сторінці пошуку скільки у нього нових повідомлень в "личку", - він не для цього пошук ініціював. Неблокірующіх запити дозволяють реалізувати поведінку коли ми запитуємо у БД: "скільки у користувача особистих повідомлень?" І недождавшісь відповіді в обумовлений timeout як би говоримо: "не дуже-то і хотілося" і просто приховуємо блок з особистими повідомленнями. Більш того, можна реалізувати схему в якій клієнт не дочекавшись відповіді, через окремий control connection, приб'є свій власний запит, щоб він не генерував додаткове навантаження на БД, - їй судячи з усього і так не солодко, раз вона не встигла відповісти вчасно (звичайно , все це не працює з DML запитами).