PHP: Mysqlnd — Manual
Change language: EnglishBrazilian PortugueseChinese (Simplified)FrenchGermanJapaneseRussianSpanishTurkishOther
Submit a Pull Request Report a Bug
- Введение
- Обзор
- Установка
- Настройка во время выполнения
- Несовместимости
- Постоянное соединение
- Статистика
- Замечания
- Управление памятью
- API для плагинов к встроенному драйверу MySQL
- Сравнение плагинов mysqlnd с MySQL Proxy
- Получение API плагинов mysqlnd
- Архитектура плагинов MySQL Native Driver
- API плагинов mysqlnd
- Начинаем разработку плагина mysqlnd
+add a note
User Contributed Notes 3 notes
up
down
3
koalay at gmail dot com ¶
13 years ago
---------------------------
This is because your manually compiled MySQL has its own place for socket.
---------------------------
For those who manually compiled MySQL, the default
mysqlnd settings may results in error.
Your mysql_error() function may give you this message:
No such file or directory (trying to connect via unix:///tmp/mysql.sock)
---------------------------
You need to provide PHP a reference for an appropriate mysql socket.
That means you need to edit php.ini and add a section like this:
[mysql]
mysql.default_socket="/your/path/to/mysql.sock"
---------------------------
up
down
2
12 years ago
"The MySQL Client Library sets a default timeout of 365 * 24 * 3600 seconds (1 year) and waits for other timeouts to occur, such as TCP/IP timeouts. mysqlnd now uses the same very long timeout." http://www.php.net/mysqlnd.config.php#mysqlnd.net_read_timeout Notice that since of PHP 5.3.0 there is no need to set 'default_socket_timeout to -1'.
up
down
-10
eric dot caron at gmail dot com
13 years ago
This means that if you have the default_socket_timeout set to 60 (default value), and you have a query that takes longer than 60 seconds to respond, the connection will be severed and getting the query results will fail.
The solution (as of PHP 5.3.0) is to change default_socket_timeout to -1 in php.ini, or with ini_set. One important part of the MySQL Native Driver, which is overlooked, is that when connecting to MySQL via a socket, the connection is subject to the "default_socket_timeout" value.
+add a note
Возожности mysqlnd в PHP/5.3 · bazhenov.me
php • mysql
Если вы не знаете, то с 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’ы находятся на физически разных серверах).
Распараллеливание чтения может быть полезно в случае реализации scatter-gather. Если у вас сложное разбиение данных по серверам, то может возникнуть ситуация когда при построении SELECT запроса неизвестно какому серверу его адресовать (представьте что вы пытаетесь извлечь данные с фильтрацией по полю, которое не учавствует в критериях разбивки) — соответствующие данные “распылены” по всем серверам. В этом случае необходимо послать SELECT запрос всем серверам (scatter) и затем обьединить все результаты в один result set (gather). Вообще, эта техника очень дорога и лучше делать так, чтобы вам не приходилось ее использовать. Например, выбрать разбиение, которое позволит обращатся только к одному серверу. Тем самым вы увеличите data locality и благотворно повлияете на availability, так как теперь для обслуживания запроса вам нужны не все сервера, а всего один. Но если уж без scatter-gather не обойтись, то будет неплохо хотя бы отправлять запросы серверам параллельно, а не последовательно. В этом случае общее время ожидения ответа будет равно времени ожидания самого медленного сервера, а не сумме времени ожидания всех серверов.
И конечно же SLA. Лично нам этого очень сильно нехватало. Если запрос нас не блокирует, то технически мы можем и не ждать результатов его выполнения. Совсем не ждать смысла конечно нет, а вот не ждать дольше чем строго определенное количество времени, бывает очень полезно. Я уже писал раньше про fail fast. Всякий раз когда вы делаете более менее сложный запрос к БД вы не можете быть уверены сколько времени займет выполнение этого запроса. А пользователи ждать не любят. Все наверное были свидетелями как БД при растущей нагрузке все медленее и медленее обрабатывает существующие запросы. В такой ситуации новые запросы дают эффект снежного кома. С другой стороны, вполне возможно, что результат нам не так уж и нужен. Ну подумаешь не покажем пользователю на странице поиска сколько у него новых сообщений в “личке”, — он не для этого поиск инициировал. Неблокирующие запросы позволяют реализовать поведение когда мы спрашиваем у БД: “сколько у пользователя личных сообщений?” и недождавшись ответа в оговоренный timeout как бы говорим: “не очень-то и хотелось” и просто скрываем блок с личными сообщениями. Более того, можно реализовать схему в которой клиент не дождавшись ответа, через отдельный control connection, прибьет свой собственный запрос, чтобы он не генерировал дополнительную нагрузку на БД, — ей судя по всему и так не сладко, раз она не успела ответить вовремя (конечно, все это не работает с DML запросами).
Это все. Остальное — сомнительные мелочи.
PHP: Mysqlnd — Руководство
Изменение языка: английскийбразильский португальскийкитайский (упрощенный)французскийнемецкийяпонскийрусскийиспанскийтурецкийДругое
Отправить запрос на вытягивание Отчет об ошибке
- Введение
- Обзор
- Установка
- Конфигурация времени выполнения
- Несовместимости
- Постоянные соединения
- Статистические данные
- Примечания
- Управление память0006
- A comparison of mysqlnd plugins with MySQL Proxy
- Obtaining the mysqlnd plugin API
- MySQL Native Driver Plugin Architecture
- The mysqlnd plugin API
- Getting started building a mysqlnd plugin
+ add a note
Пользовательские заметки 3 заметки
вверх
вниз
3
koalay в Gmail точка com ¶
13 лет назад
--------------------------- Это потому, что в скомпилированном вручную MySQL есть собственное место для сокета. ------------------------------------------ Для тех, кто компилировал MySQL вручную, по умолчанию
настройки mysqlnd могут привести к ошибке.
Ваша функция mysql_error() может выдать следующее сообщение:
Нет такого файла или каталога (попытка подключения через unix:///tmp/mysql.sock)
---------------------------
Вам необходимо предоставить PHP ссылку на соответствующий сокет mysql.
Это означает, что вам нужно отредактировать php.ini и добавить такой раздел:
[mysql]
mysql.default_socket="/ваш/путь/к/mysql.sock"
---------------------------
вверх
вниз
2
juangiordana на gmail точка com ¶
12 лет назад
"Клиентская библиотека MySQL устанавливает тайм-аут по умолчанию 365 * 24 * 3600 секунд (1 год) и ожидает других тайм-аутов, таких как тайм-ауты TCP/IP. mysqlnd теперь использует такой же очень длинный тайм-аут." http://www.php.net/mysqlnd.config.php#mysqlnd.net_read_timeout Обратите внимание, что начиная с PHP 5.3.0 нет необходимости устанавливать для 'default_socket_timeout значение -1'.
вверх
вниз
-10
Эрик Точка Кэрон в Gmail точка com ¶
13 лет назад
Это означает, что если для параметра default_socket_timeout установлено значение 60 (значение по умолчанию) и у вас есть запрос, для ответа на который требуется более 60 секунд, соединение будет разорвано, и получение результатов запроса не удастся. Решение (начиная с PHP 5. 3.0) состоит в том, чтобы изменить default_socket_timeout на -1 в php.ini или с помощью ini_set. Одна важная часть встроенного драйвера MySQL, которая упускается из виду, заключается в том, что при подключении к MySQL через сокет соединение зависит от значения «default_socket_timeout».
+ добавить примечание
PHP: Что такое mysqlnd, нужен ли он мне?
Комментарий в блоге от Яна заставляет меня задаться вопросом, не смог ли я четко указать, что такое mysqlnd. См. ниже его комментарий. Ян, я благодарен за ваш комментарий в блоге и вопрос! Возможно, вы не единственный читатель, которому нужно немного больше базовых знаний о mysqlnd. Пожалуйста, позвольте мне ответить на ваш вопрос публично и подробно. FAQ: Что такое mysqlnd, нужен ли он мне? .
Аббревиатура «mysqlnd» означает «собственный драйвер MySQL для PHP». Думаю, большинству людей это ни о чем не говорит.
- «родной»: он написан на PHP? Нет, это было бы два медленных. Как вы, наверное, знаете, PHP сам по себе является программой, написанной на C. Поэтому нативный означает C и тесно интегрирован в PHP на уровне C. Это, безусловно, хорошо, так как драйвер может попытаться выжать из PHP оптимум.
- «драйвер»: это новый программный API, новое расширение PHP? Нет, уже есть три (ext/mysql, ext/mysqli, PDO/MySQL) API и три расширения, нет необходимости в новом API или новом расширении! mysqlnd — это своего рода библиотека, реализующая низкоуровневый коммуникационный протокол MySQL. Эта библиотека может использоваться существующими расширениями. В настоящее время ext/mysql и ext/mysqli адаптированы для работы как с libmysql, так и с mysqlnd.
- «для PHP»: это не совсем ново! Ты прав. Однако mysqlnd публикуется на условиях лицензии PHP. Поэтому, в отличие от libmysql, нет необходимости в исключении лицензии FLOSS, чтобы сделать лицензию совместимой с лицензией PHP. Кто-то может вспомнить — отчасти жаркие — дискуссии об исключении и будет рад услышать об этом.
Итак, что такое mysql? Для каждого опытного и хардкорного пользователя PHP это должно объяснить одно предложение: mysqlnd — это замена libmysql, распространяемая в соответствии с условиями лицензии PHP и тесно интегрированная в PHP на уровне C.
Те из вас, кто не назвал бы себя PHP-хакерами уровня C, должны читать дальше.
Терминология: расширение PHP, API
Я не часто цитирую Кристиана, но это замечание о нем совершенно точно и заслуживает того, чтобы повторять его как можно чаще: PHP действует как Борг: ассимилирует все и берет лучшее из этого, чтобы укрепить свои позиции. PHP ассимилирует C-библиотеки. По своей сути PHP представляет собой небольшое языковое ядро, которое можно расширить для выполнения любых задач путем встраивания специализированных C-библиотек. Обычно встраивание C-библиотеки в PHP означает написание нового расширения PHP и экспорт некоторых библиотечных функций в пользовательскую среду PHP, что создает новый API (интерфейс прикладного программирования).
Способность к ассимиляции является одним из ключевых факторов успеха и принятия PHP. Это делает PHP очень гибким и готовым ко всем видам различных и будущих задач. Кроме того, он позволяет продвинутым пользователям обойти (скорость) ограничения PHP и при необходимости перейти на уровень C.
Довольно часто новое расширение идет рука об руку с новым API. Зачем вам писать новое расширение PHP, если оно не экспортирует никаких функций в пользовательскую среду PHP? В большинстве случаев это нежелательно. Если ваше расширение PHP основано на C-библиотеке, вы обычно реализуете некоторые функции-оболочки (PHP-функции), чтобы иметь возможность использовать функциональность C-библиотеки из ваших PHP-скриптов.
Просмотрите справочник по функциям в руководстве по PHP, и вы увидите, сколько функций PHP основано на C-библиотеке. Функции libxml имеют даже аббревиатуру «lib» (библиотека) в своем названии: функции libxml относятся к расширению libxml, которое экспортирует функциональность C-libary из библиотеки libxml в пользовательскую среду PHP.
Краткая история PHP MySQL API
В какой-то момент в истории PHP, очень важный момент в истории MySQL, кто-то решил взломать расширение PHP, которое предоставляет некоторые функции C-уровня libmysql (клиентская библиотека MySQL) для пользовательского пространства PHP: ext/mysql был родился .
С появлением ext/mysql появился новый API (интерфейс прикладного программирования). В PHP появились функции mysql_*. API очень «phpish» и несколько абстрагирован от функций C-уровня, имеющихся в libmysql. До сегодняшнего дня это первое расширение, поддерживающее MySQL, считается одним из самых популярных, хотя использование ext/mysqli рекомендуется, поскольку ext/mysqli обладает всеми функциями, предлагаемыми MySQL 4.1+, в отличие от ext/mysql.
Несколько лет спустя, с появлением PHP 5, была разработана ext/mysqli. Это второе расширение PHP, использующее библиотеку libmysql. И это новый API, который предоставляет функции mysqli_*. Причины разработки еще одного расширения PHP — ext/mysqli — с использованием libmysql все еще перечислены в исторической статье:
- ext/mysql было трудно поддерживать из-за множества #ifdef в коде C
- ext/mysqli поддерживает все функции MySQL Server, в отличие от ext/mysql 9.0008
- ext/mysqli имеет процедурный и объектно-ориентированный интерфейс — новые возможности объектно-ориентированного языка были одной из самых горячих тем при разработке PHP 4 .
Однако это не конец истории. В PHP 5 появилось третье расширение PHP, использующее libmysql: PDO/MySQL. PDO — это реакция на то, что в PHP нет единого API для подключения к базам данных, в отличие, например, от Java с JDBC. До введения PDO обычной практикой было использование абстракций базы данных, написанных на PHP, что приводило к довольно медленному коду. Это само по себе не обязательно является большой проблемой, но, как и в случае с механизмами шаблонов, никогда не существовало «стандартной» абстракции базы данных. Существующие абстракции баз данных имели не только разные API, но и очень разные наборы функций. С одной стороны, выбор — это хорошо. С другой стороны, было неприятно иметь дело с таким количеством «стандартов». Поскольку абстракция API базы данных на уровне C быстрее, чем абстракция, реализованная в PHP, и было так много путаницы из-за отсутствия стандарта, PDO был разработан.
Уроки
Давайте резюмируем. В PHP есть три API, которые вы можете использовать для подключения к MySQL:
- PHP 2+ — ext/mysql: самое старое расширение и API — пожалуйста, не используйте его больше, оно не поддерживает все функции MySQL.
- PHP 5+ — ext/mysqli: «текущее» расширение и API — поддерживает все функции MySQL
- PHP 5+ — PDO/MySQL: уровень абстракции API расширения и базы данных, представленный в PHP 5
mysqlnd не является новым расширением! mysqlnd это не новый API!
Mysqlnd не является ни новым расширением PHP, ни новым API! mysqlnd — это новый код библиотеки уровня C. Библиотека mysqlnd предоставляет почти те же функции, что и libmysql. Обе C-библиотеки реализуют коммуникационный протокол MySQL и могут использоваться для подключения к серверу MySQL.
Однако libmysql — это универсальная C-библиотека с двойным лицензированием. Его может использовать любая программа на языке C. Поскольку PHP основан на C, PHP использует его. mysqlnd не является универсальной C-библиотекой. mysqlnd распространяется под лицензией PHP и тесно интегрирован в PHP на уровне C. Например, mysqlnd использует функции управления памятью PHP и сетевые потоки. Из-за тесной интеграции другим программам на C, кроме PHP, сложно использовать библиотеку. Любая другая программа на C, которая пытается использовать mysqlnd, должна будет скомпоноваться с большими частями PHP. Возможно, это объясняет, что означает «нативный» и «для PHP».
mysqlnd был разработан как замена libmysql. Расширения PHP, которые используют libmysql для подключения к MySQL, могут быть изменены для поддержки как libmysql, так и mysqlnd. Это внедрение было завершено для ext/mysql и ext/mysqli. Конечно, расширение может одновременно использовать только одну C-библиотеку: либо libmysql, либо mysqlnd. Какой из них использовать, решается во время компиляции, см. мою другую запись в блоге о том, как компилировать mysqlnd.
Ответ Яну
Ян, ваш вопрос:
Если я уже использую PDO для соединений с базой данных (через PDO_MYSQL из PECL), есть ли причина, по которой мне следует переключиться на mysqlnd? Будет ли это быстрее или, возможно, более безопасным (я большой поклонник подготовленных операторов в PDO для предотвращения SQL-инъекций)?
Прежде всего, резюме:
- PDO/MySQL — это расширение, использующее libmysql на уровне C .
- PDO/MySQL — это API, представленный в PHP 5
- PDO/MySQL еще не был модифицирован для работы с mysqlnd (на момент написания)
Если вы хотите попробовать новое превосходное предложение mysqlnd, вам нужно переключиться на ext/mysql или ext/mysqli. На момент написания PDO/MySQL не поддерживает mysqlnd. Это означает, что вам нужно будет переключиться с одного API на другой. Я сомневаюсь, что вы захотите это сделать, поскольку это подразумевает переписывание ваших сценариев.
Я обнаружил, что mysqlnd примерно так же быстр, как libmysql. Иногда это немного быстрее, иногда кажется, что libmysql немного опережает mysqlnd. Между mysqlnd и libmysql есть несколько различий. Например, mysqlnd не нужно хранить лишние копии строк при выборке данных. Поэтому использование памяти может быть немного более эффективным. Однако вы никогда не должны забывать, что уровень базы данных — это лишь небольшая часть всей игры, если вы посмотрите на PHP с более высокой точки зрения и рассмотрите весь веб-запрос, который включает в себя принятие HTTP-запроса, запуск PHP, анализ PHP-кода, выполнение PHP, тратя несколько миллисекунд на самом уровне базы данных, тратя время на передачу данных с сервера базы данных через сеть на PHP, обработку данных в PHP и, наконец, отправку ответа веб-клиенту. Не возлагайте на него большие надежды.
Разные библиотеки предлагают разный функционал. libmysql и mysqlnd предлагают немного разные функции. Что это за особенности, предстоит ответить в будущих работах. Мы кратко перечислим их на http://dev.mysql.com/downloads/connector/php-mysqlnd/:
- улучшенные постоянные соединения
- mysqli_fetch_all()
- вызов статистики производительности: mysqli_get_cache_stats(), mysqli_get_client_stats(), mysqli_get_connection_stats()
Некоторые из этих функций оказывают определенное влияние на производительность. Например, если вы скомпилируете ext/mysqli с mysqlnd, можно установить постоянные соединения. Эта функция отсутствует, если вы компилируете ext/mysqli с libmysql. Постоянные подключения могут дать вам небольшой прирост производительности. Сравнивая яблоки и апельсины — ext/mysqli @ libmysql без постоянных подключений и ext/mysqli @ mysqlnd с постоянными подключениями — я обнаружил, что Dell DVD Store работает примерно на 5% быстрее, в зависимости от конфигурации — чуть меньше или чуть больше 5. %. Так много о производительности.
Вы спрашиваете о безопасности. Лично я думаю, что задача слоя базы данных не состоит в том, чтобы сделать ваши приложения более безопасными! Вы несете ответственность за фильтрацию данных! Приложения являются конечными автоматами. Не должно быть возможности перейти из одного состояния в другое, используя неправильные данные. Не должно быть возможности перейти от «запросить данные у пользователя» к «сохранить данные», если данные содержат что-либо, что может причинить вред. Извините, но это ваша вина, если переход из одного из этих состояний в другой возможен с помощью поддельного ввода. Если это возможно, ваша конечная машина сломана.
Уровни базы данных могут предоставить вам механизмы, которые являются надежными и предотвращают выполнение или сохранение ошибочных входных данных. По своей природе эти механизмы могут быть только очень общего типа. Уровни базы данных ничего не знают о вашей конечной машине, слои базы данных не знают, используются ли они в Интернете или в CLI, слои базы данных ничего не знают о ваших бизнес-правилах. Поэтому любой такой механизм не освобождает вас от задачи определения четких правил перехода состояний и реализации этих правил, то есть фильтрации ввода! Любая функция «безопасности» уровня базы данных может рассматриваться только как резервная копия последнего уровня, которая пытается предотвратить худшее. В первой строке ваше приложение отвечает за входную фильтрацию и проверки.
Чтобы ответить на ваш вопрос: подготовленные операторы доступны как с ext/mysqli, так и с PDO/MySQL. Независимо от того, как вы компилируете ext/mysqli — используя mysqlnd или используя libmysql. Хотя, опять же, нет особого смысла переносить задачу входной фильтрации на уровень базы данных. Это плохой дизайн приложения. Из этого правила могут быть исключения, например, при быстром прототипировании, но в целом это плохой стиль. Кстати, ext/mysql не поддерживает подготовленные операторы — как сказано, прекратите их использовать, если вы все еще это делаете, и перейдите на ext/mysqli.
Подходит ли вам mysqlnd? Я склонен говорить нет.