3. agenda
1. about mysqlnd
– position, role
2. libmysql vs mysqlnd
– functions, features
3. mysqlnd internals
I. Type of returning values
II.Memory usage
3
5. MySQL client libraries in PHP
mysql_connect
mysqli
PDO
Doctrine
Eloquent
ZendDB
Aura.Sql
ADOdb
PEAR_MDB2
PEAR_DB
5
6. Those libraries use
mysql/mysqli/pdo extensions
6
MySQL
client
libraries
in PHP
is
/
use
mysql
extension
mysqli
extension
pdo
extension
(mysql driver)
7. mysql / mysqli /
pdo (mysql_driver)
access MySQL server
directly?
7
9. Communication between
MySQL server and PHP
• Network access (tcp, socket)
• Encryption (SSL) or not
• Analyze Wire Protocol
• Compression (deflate) or not
• Convert to (or from) PHP variables
• Error Handring (Exception)
9
10. Communication between
MySQL server and PHP
• Network access (tcp, socket)
• Encryption (SSL) or not
• Analyze Wire Protocol
• Compression (deflate) or not
• Convert to (or from) PHP variables
• Error Handring (Exception)
mysql/mysqli/pdo
mysqlnd
/
libmysql
10
11. Application
ADOdb Zend_DB Doctrine
Chart of
mysqli
PEAR::MDB2
mysql PDO
mysqlnd
libmysql
Zend
Engine
PHP
Script
MySQL Server
ref:http://d.hatena.
ne.jp/do_aki/2011121
4/1323831558
11
16. mysqlnd and php versions
• not available
(only libmysql)
before
php 5.3
• bundled but optional
(default is libmysql)
php 5.3
series
• default
(libmysql is optional)
php 5.4
or later
16
*libmysql is not deprecated
17. which is used?
• php –i or phpinfo()
– mysql : Client API version
– mysqli : Client API library version
– pdo_mysql : Client API version
mysqli : mysqli_get_client_info()
PDO : $pdo->getAttribute(
PDO::ATTR_CLIENT_VERSION)
• include “mysqlnd” string or not
17
same as
18. pros
• resolve license problems
– libmysql: GPLv2
with FOSS License Exception
– mysqlnd : PHP license
• not need build libmysqlclient before
compile PHP
– mysqlnd is bundled in php source code
• “highly optimized for and tightly
integrated into PHP”
18
19. cons
• not yet matured
– libmysqlclient is widely used.
at any os, as any language bindings…
– mysqlnd is limited used.
compared with libmysql
19
20. incompatibilities
• mysqlnd cannot use OLD_PASSWORD
– not support MySQL server before 4.1
– "mysqlnd cannot connect to MySQL 4.1+ using
old authentication"
• mysqlnd don’t read “my.cnf”
– affect charset
– no PDO::MYSQL_ATTR_READ_DEFAULT_FILE
• Type of returning value is different
– example: BIT type written by manual
– It mentions later
20
25. Server side prepared statement
type of prepared statement
prepare SELECT age FROM user COM_PREPARE
WHERE name = ?
execute bind parameter "do_aki" COM_EXECUTE
[Preventing SQL Injection]
Client side prepared statement
prepare
SELECT age FROM user
WHERE name = ?
execute SELECT age FROM user COM_QUERY
WHERE name = ‘do_aki’
25
[default PDO settings]
26. Server side prepared statement
prepared statement and protocols
prepare SELECT age FROM user COM_PREPARE
WHERE name = ?
execute bind parameter "do_aki" COM_EXECUTE
result set 29 (integer)
binary protocol
Client side prepared statement
prepare
SELECT age FROM user
WHERE name = ?
execute SELECT age FROM user COM_QUERY
WHERE name = ‘do_aki’
result set “29” (string)
text protocol
26
36. fetch (libmysql)
$id $name $dt
123 “do_aki” “2014-10-11 11:30:00”
MySQL Server
mysqli/pdo
libmysql
“id”:123, “name”:”do_aki”,
“datetime”: “2014-10-11 11:30:00”
36
37. fetch (mysqlnd)
$id $name $dt
mysqli/pdo
3 “123” 6 "do_aki” 19 “2014-10-11 11:30:00”
MySQL Server
mysqlnd
37
38. fetch (detail)
zval* zval* zval*
$id $name $dt
zval zval zval MYSQLND_RES
3 “123” 6 "do_aki” 19 “2014-10-11 11:30:00”
MySQL Server
MEMORY POOL (use malloc)
38
line 1
internal buffers
39. fetch * N
zval* zval* zval*
$id $name $dt
zval zval zval MYSQLND_RES
3 “123” 6 "do_aki” 19 “2014-10-11 11:30:00”
MySQL Server
MEMORY POOL (use malloc)
39
line N
internal buffers
geting fat
until statement
released
40. solution for reduced memory
• use MYSQLI_STORE_RESULT_COPY_DATA
– fetch with copy
– php >= 5.6.0
– Not for PDO yet…
– http://blog.ulf-wendel.de/2014/php-5-
7-mysqlnd-memory-optimizations/
40
41. fetch with copy
zval zval zval
no internal buffers
3 “123” 6 "do_aki” 19 “2014-10-11 11:30:00”
MySQL Server
MYSQLND_RES
$id $name $dt
41
line N
123 “do_aki” “2014-10-11 11:30:00”
45. fetch (detail)
zval* zval* zval*
$id $name $dt
zval zval zval MYSQLND_RES
123 “do_aki” “2014-10-11 11:30:00”
123 6 "do_aki” 2014-10-11
11:30:00
MySQL Server
45
line 1
46. fetch*N
zval* zval* zval*
$id $name $dt
zval zval zval MYSQLND_RES
111222333 “““dddooo___aaakkkiii””” ““2“2020101414-4-1-1010-0-1-1111 1 1 1111:1:3:3030:0:0:0000”0””
123 “do_aki” “2014-10-11 11:30:00”
123 6 "do_aki” 2014-10-11
11:30:00
MySQL Server
46
line N
47. fetch*N
zval* zval* zval*
$id $name $dt
zval zval zval MYSQLND_RES
111222333 “““dddooo___aaakkkiii””” ““2“2020101414-4-1-1010-0-1-1111 1 1 1111:1:3:3030:0:0:0000”0””
123 “do_aki” “2014-10-11 11:30:00”
123 6 "do_aki” 2014-10-11
11:30:00
MySQL Server
47
increases
memory usage
each fetch
(until statement
released)
cannot use
“MYSQLI_STORE_RE
SULT_COPY_DATA”
to prepared
statement
48. Conclusion
• I explain mysqlnd
• mysqlnd and libmysql work
differently
• use mysqli if you want to full
functions of mysqlnd
• Prepared statement……
48