18. MySQL
privilege
system
Global
privileges
Database
privileges
Table
privileges
Field
privileges
19. MySQL
privilege
system
Global
privileges mysql.user
Database
privileges mysql.db
Table
privileges mysql.tables_priv
Field
privileges mysql.columns_priv
29. Solucons
✓Centralized
provisioning
database
✓GeXers
on
the
provisioning
database
✓Node
mapper
for
user/db/privilege
management
✓INFORMATION_SCHEMA
for
quota
management
✓Prefixes
to
avoid
name
clashes
36. Add
user
INSERT INTO `user`
(`prefix`,`username`,`password`,`createdate`)
VALUES(‘test’,‘test_user’,‘mypass123’,NOW());
37. Delete
user
DELETE FROM `user`
WHERE username=‘test_user’;
DELETE u.*, db.* FROM `mysql`.`user` u
LEFT JOIN `mysql`.`db` db
ON(db.`User` = u.`User`)
WHERE u.`User` = ‘test_user’;
38. Reset
user
password
UPDATE `user`
SET `password` = ‘newpass123’
WHERE `username` = ‘test_user’;
UPDATE `mysql`.`user`
SET `Password` = PASSWORD
(‘newpass123’)
WHERE `User`= ‘test_user’;
39. Enable
user
UPDATE `user`
SET `enabled` = '1'
WHERE `username` = ‘test_user’;
UPDATE `mysql`.`user`
SET `Host` = ‘%’
WHERE `User`= ‘test_user’
40. Disable
user
UPDATE `user`
SET `enabled` = '0'
WHERE `username` = ‘test_user’;
UPDATE `mysql`.`user`
SET `Host` = ‘localhost’
WHERE `User`= ‘test_user’
45. Delete
database
Are
linked
to
this
database
SELECT u.username
FROM `user` u
WHERE u.databaseId = 123
GROUP BY u.username; Find
deletable
users
to
delete
from
MySQL
privileges
system
46. Delete
database
DELETE u.*, db.*
FROM `user` u
LEFT JOIN `db` db
ON(db.`User` = u.`User`)
WHERE u.`User` IN('test_user’);
Delete
these
users
from
MySQL
privileges
system
56. Write
Grant
privilege permissions
UPDATE `user`
SET `databaseId`=123, `write`='1'
WHERE `username`= ‘test_user’;
Read-‐
only
permissions
UPDATE `user`
SET `databaseId`=123, `write`='0'
WHERE `username`= ‘test_user’;
57. Grant
privilege
Try
adding
user
or
catch
duplicate
user
error
INSERT INTO `user`(Host,User,Password)
VALUES(‘%’,‘test_user’,PASSWORD
(‘password’));
58. Grant
privilege
INSERT INTO `db`
(Host,Db,User,Select_priv,Insert_priv,
Update_priv,Delete_priv,Create_priv,Drop_pr
iv,Grant_priv,References_priv,
Index_priv,Alter_priv,Create_tmp_table_priv
,Lock_tables_priv,
Create_view_priv,Show_view_priv,Create_rout
ine_priv,
Alter_routine_priv,Execute_priv)
59. Write
Grant
privilege permissions
VALUES
(‘%’,‘test_db’,‘test_user’,'Y','Y','Y','Y',
'Y','Y','N','Y','Y','Y'
,'Y','Y','Y','Y','Y','Y','Y'); Read-‐
only
permissions
VALUES
(‘%’,‘test_db’,‘test_user’,'Y','N','N','N',
'N','N','N','N','N','N','N','N','N','Y','N'
,'N','Y');
60. Revoke
privilege
UPDATE `user`
SET `databaseId`= NULL, `write`= NULL
WHERE `user`= ‘test_user’;
DELETE u.*, db.* FROM `user` u LEFT JOIN
`db` db ON(db.`User` = u.`User`) WHERE
u.`User` = ‘test_user’;
66. Quota
management
✓Limits
in
provisioning
database
✓Current
usage
stored
in
INFORMATION_SCHEMA
✓Raco
calculated
via
cron
task
✓Write
permissions
disabled
while
over
quota
67. Quota
management
SELECT `database`,`quota`
FROM `database`
SELECT TABLE_SCHEMA as `database`,
ROUND(SUM(DATA_LENGTH + INDEX_LENGTH)/
1048576,2) as `usage`
FROM `information_schema`.`TABLES`
GROUP BY TABLE_SCHEMA
79. Server
proxy
MySQL
Proxy
is
a
simple
program
that
sits
between
your
client
and
MySQL
server(s)
that
can
monitor,
analyze
or
transform
their
communicacon.
80. MySQL
Proxy
features
✓
Load
balancing
✓
Failover
✓
Query
analysis
✓
Query
filtering
and
modificacon
85. Goal
✓
Accept
conneccon
using
the
proxy
✓Hook
into
the
authenccacon
✓Match
user
to
the
provisioning
DB
✓Fetch
node
from
provisioning
✓Switch
to
the
right
node
➡Effeccve
proxying
solucon
87. Reality
✓
Accept
conneccon
using
the
proxy
✓Hook
into
the
authenccacon
✓Match
user
to
the
provisioning
DB
✓Fetch
node
from
provisioning
✓Switch
to
the
right
node
➡Effeccve
proxying
solucon
93. Code
function
error_result
(msg)
proxy.response
=
{
type
=
proxy.MYSQLD_PACKET_ERR,
errmsg
=
msg,
errcode
=
7777,
sqlstate
=
'X7777',
}
return
proxy.PROXY_SEND_RESULT
end
Custom
MySQL
errors
94. function
node_get(ip)
local
node
=
memcache:get(md5.sumhexa(ip))
Code
if
not
node
==
nil
then
return
loadstring('return
'..memcache:get(md5.sumhexa
(ip)))()
end
node
=
sql_get(ip)
if
node
==
nil
then
return
nil
end
memcache:set(md5.sumhexa(ip),
node,
3600)
return
node
end
Get
node
from
cache
or
database
95. function
sql_get(ip)
env
=
assert
(luasql.mysql())
Code
con
=
assert
(env:connect
(mysqldatabase,mysqluser,mysqlpassword,mysqlhost))
cur
=
assert
(con:execute(string.format("SELECT
n.`id`
FROM
`accesslist`
a
JOIN
`node`
n
ON(n.id=a.node)
WHERE
a.`ip`
=
'%s'",ip)))
row
=
cur:fetch
({},
"a")
if
cur:numrows()
==
0
then
return
nil
end
cur:close()
con:close()
env:close()
return
row.id
end
Get
node
from
provisioning
database
96. Code
function
connect_server()
selectedNode
=
node_get
(proxy.connection.client.src.address)
if
selectedNode
==
nil
then
return
error_result(string.format("No
info
found
in
the
cluster
for
IP
'%s'",proxy.connection.client.src.address))
end
proxy.connection.backend_ndx
=
selectedNode
end
Retrieve
and
switch
to
node
100. MySQL
Nacve
Driver
✓Replacement
for
libmysql
✓Full
client
protocol
as
a
PHP
extension
✓Official
since
PHP
5.3.0
✓No
API
✓Mysql,
Mysqli
&
PDO
use
it
✓Supports
plugins
101. MySQL
Nacve
Driver Read
these
blog
posts
hXp://blog.ulf-‐wendel.de/?p=284
hXp://schlueters.de/blog/archives/146-‐mysqlnd-‐plugins-‐
for-‐PHP-‐in-‐praccce.html
102. MySQL
Nacve
Driver
✓
Accept
conneccon
using
the
proxy
✓Hook
into
the
authenccacon
✓Match
user
to
the
provisioning
DB
✓Fetch
node
from
provisioning
✓Switch
to
the
right
node
✓Doesn’t
work
for
remote
conneccons
➡Effeccve
proxying
solucon