MySQL: tuning markdown
This commit is contained in:
parent
48f7fc2c5b
commit
1d89794411
1836
HowtoMySQL.md
1836
HowtoMySQL.md
|
@ -1,63 +1,65 @@
|
||||||
[[PageOutline]]
|
---
|
||||||
Documentation officielle : http://dev.mysql.com/doc/refman/5.5/en/
|
title: Howto MySQL
|
||||||
|
---
|
||||||
|
|
||||||
|
Documentation officielle : <http://dev.mysql.com/doc/refman/5.5/en/>
|
||||||
|
|
||||||
# Installation
|
# Installation
|
||||||
|
|
||||||
Sous Debian Wheezy et Jessie, on trouve par défaut la version 5.5 :
|
Sous Debian Wheezy et Jessie, on trouve par défaut la version 5.5 :
|
||||||
|
|
||||||
|
~~~
|
||||||
# apt install mysql-server
|
# apt install mysql-server
|
||||||
|
~~~
|
||||||
|
|
||||||
On vérifie ensuite que tout s'est bien passé :
|
On vérifie ensuite que tout s'est bien passé :
|
||||||
|
|
||||||
|
~~~
|
||||||
|
# mysql
|
||||||
|
Welcome to the MySQL monitor. Commands end with ; or \g.
|
||||||
|
Your MySQL connection id is 777329
|
||||||
|
Server version: 5.5.37-0+wheezy1-log (Debian)
|
||||||
|
|
||||||
# mysql
|
Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||||
Welcome to the MySQL monitor. Commands end with ; or \g.
|
|
||||||
Your MySQL connection id is 777329
|
|
||||||
Server version: 5.5.37-0+wheezy1-log (Debian)
|
|
||||||
|
|
||||||
Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
|
Oracle is a registered trademark of Oracle Corporation and/or its
|
||||||
|
affiliates. Other names may be trademarks of their respective
|
||||||
|
owners.
|
||||||
|
|
||||||
Oracle is a registered trademark of Oracle Corporation and/or its
|
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
|
||||||
affiliates. Other names may be trademarks of their respective
|
|
||||||
owners.
|
|
||||||
|
|
||||||
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
|
|
||||||
|
|
||||||
mysql>
|
|
||||||
|
|
||||||
|
mysql>
|
||||||
|
~~~
|
||||||
|
|
||||||
Il est ensuite fortement conseillé de créer un administrateur pour la base de données
|
Il est ensuite fortement conseillé de créer un administrateur pour la base de données
|
||||||
(par exemple "adminmysql", car "root" peut prêter à confusion) :
|
(par exemple "adminmysql", car "root" peut prêter à confusion) :
|
||||||
|
|
||||||
|
~~~
|
||||||
mysql> GRANT ALL PRIVILEGES ON *.* TO adminmysql@localhost IDENTIFIED BY 'XXX' WITH GRANT OPTION;
|
mysql> GRANT ALL PRIVILEGES ON *.* TO adminmysql@localhost IDENTIFIED BY 'XXX' WITH GRANT OPTION;
|
||||||
mysql> DELETE FROM mysql.user where User='root';
|
mysql> DELETE FROM mysql.user where User='root';
|
||||||
|
~~~
|
||||||
|
|
||||||
On notera sous Debian la présence d'un utilisateur `debian-sys-maint` qui sert à certains scripts Debian :
|
On notera sous Debian la présence d'un utilisateur `debian-sys-maint` qui sert à certains scripts Debian :
|
||||||
il ne doit pas être supprimé ! Au niveau sécurité, le mot de passe est généré à l'installation
|
il ne doit pas être supprimé ! Au niveau sécurité, le mot de passe est généré à l'installation
|
||||||
(stocké dans `/etc/mysql/debian.cnf` qui doit évidemment n'être lisible que par `root`) par la commande :
|
(stocké dans `/etc/mysql/debian.cnf` qui doit évidemment n'être lisible que par `root`) par la commande :
|
||||||
|
|
||||||
|
~~~
|
||||||
|
perl -e 'print map{("a".."z","A".."Z",0..9)[int(rand(62))]}(1..16)'
|
||||||
|
~~~
|
||||||
|
|
||||||
perl -e 'print map{("a".."z","A".."Z",0..9)[int(rand(62))]}(1..16)'
|
Enfin, on peut utiliser un fichier `.my.cnf` pour conserver les login/pass. Par exemple pour root, dans `/root/.my.cnf` :
|
||||||
|
|
||||||
|
|
||||||
Enfin, on peut utiliser un fichier `.my.cnf` pour conserver les login/pass.
|
|
||||||
|
|
||||||
|
|
||||||
# cat /root/.my.cnf
|
|
||||||
[client]
|
|
||||||
user = adminmysql
|
|
||||||
password = XXX
|
|
||||||
|
|
||||||
|
~~~{.ini}
|
||||||
|
[client]
|
||||||
|
user = adminmysql
|
||||||
|
password = XXX
|
||||||
|
~~~
|
||||||
|
|
||||||
Pour changer le mot de passe, on fera simplement :
|
Pour changer le mot de passe, on fera simplement :
|
||||||
|
|
||||||
|
~~~
|
||||||
# mysqladmin password <nouveau-pass-pour-adminmysql>
|
# mysqladmin password <nouveau-pass-pour-adminmysql>
|
||||||
|
~~~
|
||||||
|
|
||||||
# Configuration
|
# Configuration
|
||||||
|
|
||||||
|
@ -69,275 +71,273 @@ Les `binlogs` (trace de toutes les requêtes executées) sont dans `/var/log/mys
|
||||||
Par défaut, MySQL écoute en TCP/IP sur `127.0.0.1`. Pour activer les connexions réseau
|
Par défaut, MySQL écoute en TCP/IP sur `127.0.0.1`. Pour activer les connexions réseau
|
||||||
à distance, il suffit de modifier la ligne suivante dans le fichier `my.cnf` :
|
à distance, il suffit de modifier la ligne suivante dans le fichier `my.cnf` :
|
||||||
|
|
||||||
|
~~~{.ini}
|
||||||
bind-address = 0.0.0.0
|
bind-address = 0.0.0.0
|
||||||
|
~~~
|
||||||
|
|
||||||
Selon les ressources de la machine, il faut optimiser les directives dans `my.cnf` (par défaut, la configuration est adaptée… pour un petit serveur !).
|
Selon les ressources de la machine, il faut optimiser les directives dans `my.cnf` (par défaut, la configuration est adaptée… pour un petit serveur !).
|
||||||
Sous Debian, on trouvera quelques exemples dans le répertoire `/usr/share/doc/mysql-server-5.0/examples/`
|
Sous Debian, on trouvera quelques exemples dans le répertoire `/usr/share/doc/mysql-server-5.0/examples/`
|
||||||
|
|
||||||
Voici les paramètres essentiels :
|
Voici les paramètres essentiels :
|
||||||
|
|
||||||
|
~~~{.ini}
|
||||||
|
[mysqld]
|
||||||
|
|
||||||
[mysqld]
|
###### Connexions
|
||||||
|
# Maximum de connexions concurrentes (defaut = 100)… provoque un "Too many connections"
|
||||||
###### Connexions
|
max_connections = 250
|
||||||
# Maximum de connexions concurrentes (defaut = 100)… provoque un "Too many connections"
|
# Maximum de connexions en attente en cas de max_connections atteint (defaut = 50)
|
||||||
max_connections = 250
|
back_log = 100
|
||||||
# Maximum de connexions en attente en cas de max_connections atteint (defaut = 50)
|
# Maximum d'erreurs avant de blacklister un hote
|
||||||
back_log = 100
|
max_connect_errors = 10
|
||||||
# Maximum d'erreurs avant de blacklister un hote
|
# Loguer les requetes trop longues
|
||||||
max_connect_errors = 10
|
log_slow_queries = /var/log/mysql/mysql-slow.log
|
||||||
# Loguer les requetes trop longues
|
long_query_time = 2
|
||||||
log_slow_queries = /var/log/mysql/mysql-slow.log
|
|
||||||
long_query_time = 2
|
|
||||||
|
|
||||||
|
|
||||||
###### Tailles
|
###### Tailles
|
||||||
# Taille reservee au buffer des index MyIsam
|
# Taille reservee au buffer des index MyIsam
|
||||||
# A ajuster selon les resultats
|
# A ajuster selon les resultats
|
||||||
key_buffer = 512M
|
key_buffer = 512M
|
||||||
# Taille max des paquets envoyés/reçus … provoque un "Packet too large"
|
# Taille max des paquets envoyés/reçus … provoque un "Packet too large"
|
||||||
max_allowed_packet = 64M
|
max_allowed_packet = 64M
|
||||||
# Taille de la memoire reserve pour un thread
|
# Taille de la memoire reserve pour un thread
|
||||||
thread_stack = 192K
|
thread_stack = 192K
|
||||||
# A mettre le nombre de CPU x2
|
# A mettre le nombre de CPU x2
|
||||||
thread_cache_size = 8
|
thread_cache_size = 8
|
||||||
# Taille maximum des tables de type MEMORY
|
# Taille maximum des tables de type MEMORY
|
||||||
max_heap_table_size = 64M
|
max_heap_table_size = 64M
|
||||||
|
|
||||||
###### Cache
|
###### Cache
|
||||||
# max_connections x nbre max de tables dans une jointure (defaut = 64)
|
# max_connections x nbre max de tables dans une jointure (defaut = 64)
|
||||||
table_cache = 1500
|
table_cache = 1500
|
||||||
# Taille max des requetes cachees (defaut = 1M)
|
# Taille max des requetes cachees (defaut = 1M)
|
||||||
query_cache_limit = 8M
|
query_cache_limit = 8M
|
||||||
# Taille reservee pour le cache (defaut = 0)
|
# Taille reservee pour le cache (defaut = 0)
|
||||||
query_cache_size = 256M
|
query_cache_size = 256M
|
||||||
# Type de requetes a cacher (defaut tout peut etre cache)
|
# Type de requetes a cacher (defaut tout peut etre cache)
|
||||||
query_cache_type = 1
|
query_cache_type = 1
|
||||||
|
|
||||||
###### InnoDB
|
###### InnoDB
|
||||||
# Si InnoDB n'est pas utilise… le desactiver
|
# Si InnoDB n'est pas utilise… le desactiver
|
||||||
#skip-innodb
|
#skip-innodb
|
||||||
# En general, il est plus optimum d'avoir un fichier par table
|
# En general, il est plus optimum d'avoir un fichier par table
|
||||||
innodb_file_per_table
|
innodb_file_per_table
|
||||||
# Taille memoire allouee pour le cache des datas et index
|
# Taille memoire allouee pour le cache des datas et index
|
||||||
# A ajuster en fonction de sa RAM (si serveur dedie a MySQL, on peut aller jusqu'a 80%)
|
# A ajuster en fonction de sa RAM (si serveur dedie a MySQL, on peut aller jusqu'a 80%)
|
||||||
innodb_buffer_pool_size = 2G
|
innodb_buffer_pool_size = 2G
|
||||||
# Taille buffer memoire pour structures internes InnoDB
|
# Taille buffer memoire pour structures internes InnoDB
|
||||||
innodb_additional_mem_pool_size = 16M
|
innodb_additional_mem_pool_size = 16M
|
||||||
# Nombre maximum de threads systeme concurents
|
# Nombre maximum de threads systeme concurents
|
||||||
innodb_thread_concurrency = 16
|
innodb_thread_concurrency = 16
|
||||||
# Ajuste la valeur des logs InnoDB
|
# Ajuste la valeur des logs InnoDB
|
||||||
# (attention, il faut ensuite stopper MySQL et effacer les fichiers ib_logfile*)
|
# (attention, il faut ensuite stopper MySQL et effacer les fichiers ib_logfile*)
|
||||||
innodb_log_file_size = 128M
|
innodb_log_file_size = 128M
|
||||||
innodb_log_files_in_group = 2
|
innodb_log_files_in_group = 2
|
||||||
|
|
||||||
###### Misc
|
###### Misc
|
||||||
# charset utf8 par defaut
|
# charset utf8 par defaut
|
||||||
default-character-set=utf8
|
default-character-set=utf8
|
||||||
|
~~~
|
||||||
|
|
||||||
|
Après quelques temps d'utilisation, il est très intéressant de regarder les résultats du script `mysqltuner.pl` téléchargeable sur http://mysqltuner.pl/
|
||||||
|
|
||||||
|
~~~
|
||||||
|
perl mysqltuner.pl
|
||||||
|
|
||||||
|
>> MySQLTuner 1.0.1 - Major Hayden <major@mhtx.net>
|
||||||
|
>> Bug reports, feature requests, and downloads at http://mysqltuner.com/
|
||||||
|
>> Run with '--help' for additional options and output filtering
|
||||||
|
|
||||||
|
-------- General Statistics --------------------------------------------------
|
||||||
|
[--] Skipped version check for MySQLTuner script
|
||||||
|
[OK] Currently running supported MySQL version 5.0.51a-24+lenny3
|
||||||
|
[OK] Operating on 64-bit architecture
|
||||||
|
|
||||||
|
-------- Storage Engine Statistics -------------------------------------------
|
||||||
|
[--] Status: +Archive -BDB -Federated +InnoDB -ISAM -NDBCluster
|
||||||
|
|
||||||
|
|
||||||
Après quelques temps d'utilisation, il est très intéressant de regarder les résultats du script
|
[--] Data in MyISAM tables: 556M (Tables: 3831)
|
||||||
`mysqltuner.pl` téléchargeable sur http://mysqltuner.pl/
|
[--] Data in InnoDB tables: 34M (Tables: 968)
|
||||||
|
[--] Data in MEMORY tables: 3K (Tables: 9)
|
||||||
|
[!!] Total fragmented tables: 335
|
||||||
|
|
||||||
|
-------- Performance Metrics -------------------------------------------------
|
||||||
|
[--] Up for: 20h 59m 23s (2M q [29.301 qps], 31K conn, TX: 5B, RX: 300M)
|
||||||
|
[--] Reads / Writes: 23% / 77%
|
||||||
|
[--] Total buffers: 58.0M global + 2.6M per thread (100 max threads)
|
||||||
|
[OK] Maximum possible memory usage: 320.5M (10% of installed RAM)
|
||||||
|
[OK] Slow queries: 0% (1/2M)
|
||||||
|
[OK] Highest usage of available connections: 11% (11/100)
|
||||||
|
[OK] Key buffer size / total MyISAM indexes: 16.0M/216.0M
|
||||||
|
[OK] Key buffer hit rate: 97.0% (31M cached / 942K reads)
|
||||||
|
[OK] Query cache efficiency: 77.2% (921K cached / 1M selects)
|
||||||
|
[!!] Query cache prunes per day: 78490
|
||||||
|
[OK] Sorts requiring temporary tables: 0% (0 temp sorts / 59K sorts)
|
||||||
|
[!!] Joins performed without indexes: 29333
|
||||||
|
[OK] Temporary tables created on disk: 25% (22K on disk / 88K total)
|
||||||
|
[OK] Thread cache hit rate: 99% (26 created / 31K connections)
|
||||||
|
[!!] Table cache hit rate: 0% (64 open / 82K opened)
|
||||||
|
[OK] Open file limit used: 12% (126/1K)
|
||||||
|
[OK] Table locks acquired immediately: 99% (1M immediate / 1M locks)
|
||||||
|
[!!] InnoDB data size / buffer pool: 34.4M/8.0M
|
||||||
|
|
||||||
perl mysqltuner.pl
|
-------- Recommendations -----------------------------------------------------
|
||||||
|
General recommendations:
|
||||||
>> MySQLTuner 1.0.1 - Major Hayden <major@mhtx.net>
|
Run OPTIMIZE TABLE to defragment tables for better performance
|
||||||
>> Bug reports, feature requests, and downloads at http://mysqltuner.com/
|
MySQL started within last 24 hours - recommendations may be inaccurate
|
||||||
>> Run with '--help' for additional options and output filtering
|
Enable the slow query log to troubleshoot bad queries
|
||||||
|
Adjust your join queries to always utilize indexes
|
||||||
-------- General Statistics --------------------------------------------------
|
Increase table_cache gradually to avoid file descriptor limits
|
||||||
[--] Skipped version check for MySQLTuner script
|
Variables to adjust:
|
||||||
[OK] Currently running supported MySQL version 5.0.51a-24+lenny3
|
query_cache_size (> 16M)
|
||||||
[OK] Operating on 64-bit architecture
|
join_buffer_size (> 128.0K, or always use indexes with joins)
|
||||||
|
table_cache (> 64)
|
||||||
-------- Storage Engine Statistics -------------------------------------------
|
innodb_buffer_pool_size (>= 34M)
|
||||||
[--] Status: +Archive -BDB -Federated +InnoDB -ISAM -NDBCluster
|
~~~
|
||||||
|
|
||||||
|
|
||||||
[--] Data in MyISAM tables: 556M (Tables: 3831)
|
|
||||||
[--] Data in InnoDB tables: 34M (Tables: 968)
|
|
||||||
[--] Data in MEMORY tables: 3K (Tables: 9)
|
|
||||||
[!!] Total fragmented tables: 335
|
|
||||||
|
|
||||||
-------- Performance Metrics -------------------------------------------------
|
|
||||||
[--] Up for: 20h 59m 23s (2M q [29.301 qps], 31K conn, TX: 5B, RX: 300M)
|
|
||||||
[--] Reads / Writes: 23% / 77%
|
|
||||||
[--] Total buffers: 58.0M global + 2.6M per thread (100 max threads)
|
|
||||||
[OK] Maximum possible memory usage: 320.5M (10% of installed RAM)
|
|
||||||
[OK] Slow queries: 0% (1/2M)
|
|
||||||
[OK] Highest usage of available connections: 11% (11/100)
|
|
||||||
[OK] Key buffer size / total MyISAM indexes: 16.0M/216.0M
|
|
||||||
[OK] Key buffer hit rate: 97.0% (31M cached / 942K reads)
|
|
||||||
[OK] Query cache efficiency: 77.2% (921K cached / 1M selects)
|
|
||||||
[!!] Query cache prunes per day: 78490
|
|
||||||
[OK] Sorts requiring temporary tables: 0% (0 temp sorts / 59K sorts)
|
|
||||||
[!!] Joins performed without indexes: 29333
|
|
||||||
[OK] Temporary tables created on disk: 25% (22K on disk / 88K total)
|
|
||||||
[OK] Thread cache hit rate: 99% (26 created / 31K connections)
|
|
||||||
[!!] Table cache hit rate: 0% (64 open / 82K opened)
|
|
||||||
[OK] Open file limit used: 12% (126/1K)
|
|
||||||
[OK] Table locks acquired immediately: 99% (1M immediate / 1M locks)
|
|
||||||
[!!] InnoDB data size / buffer pool: 34.4M/8.0M
|
|
||||||
|
|
||||||
-------- Recommendations -----------------------------------------------------
|
|
||||||
General recommendations:
|
|
||||||
Run OPTIMIZE TABLE to defragment tables for better performance
|
|
||||||
MySQL started within last 24 hours - recommendations may be inaccurate
|
|
||||||
Enable the slow query log to troubleshoot bad queries
|
|
||||||
Adjust your join queries to always utilize indexes
|
|
||||||
Increase table_cache gradually to avoid file descriptor limits
|
|
||||||
Variables to adjust:
|
|
||||||
query_cache_size (> 16M)
|
|
||||||
join_buffer_size (> 128.0K, or always use indexes with joins)
|
|
||||||
table_cache (> 64)
|
|
||||||
innodb_buffer_pool_size (>= 34M)
|
|
||||||
|
|
||||||
|
|
||||||
Il y a aussi tunning-prime qui est plus verbeux, et il se complète bien avec mysql-tuner. Dispo [ici](https://launchpad.net/mysql-tuning-primer/trunk).
|
Il y a aussi tunning-prime qui est plus verbeux, et il se complète bien avec mysql-tuner. Dispo [ici](https://launchpad.net/mysql-tuning-primer/trunk).
|
||||||
|
|
||||||
|
~~~
|
||||||
|
-- MYSQL PERFORMANCE TUNING PRIMER --
|
||||||
|
- By: Matthew Montgomery -
|
||||||
|
|
||||||
|
MySQL Version 5.1.49-3-log x86_64
|
||||||
|
|
||||||
-- MYSQL PERFORMANCE TUNING PRIMER --
|
Uptime = 102 days 22 hrs 6 min 25 sec
|
||||||
- By: Matthew Montgomery -
|
Avg. qps = 196
|
||||||
|
Total Questions = 1747455439
|
||||||
|
Threads Connected = 29
|
||||||
|
|
||||||
MySQL Version 5.1.49-3-log x86_64
|
Server has been running for over 48hrs.
|
||||||
|
It should be safe to follow these recommendations
|
||||||
|
|
||||||
Uptime = 102 days 22 hrs 6 min 25 sec
|
To find out more information on how each of these
|
||||||
Avg. qps = 196
|
runtime variables effects performance visit:
|
||||||
Total Questions = 1747455439
|
http://dev.mysql.com/doc/refman/5.1/en/server-system-variables.html
|
||||||
Threads Connected = 29
|
Visit http://www.mysql.com/products/enterprise/advisors.html
|
||||||
|
for info about MySQL's Enterprise Monitoring and Advisory Service
|
||||||
|
|
||||||
Server has been running for over 48hrs.
|
SLOW QUERIES
|
||||||
It should be safe to follow these recommendations
|
The slow query log is enabled.
|
||||||
|
Current long_query_time = 2.000000 sec.
|
||||||
|
You have 533228 out of 1747455460 that take longer than 2.000000 sec. to complete
|
||||||
|
Your long_query_time seems to be fine
|
||||||
|
|
||||||
To find out more information on how each of these
|
BINARY UPDATE LOG
|
||||||
runtime variables effects performance visit:
|
The binary update log is NOT enabled.
|
||||||
http://dev.mysql.com/doc/refman/5.1/en/server-system-variables.html
|
You will not be able to do point in time recovery
|
||||||
Visit http://www.mysql.com/products/enterprise/advisors.html
|
See http://dev.mysql.com/doc/refman/5.1/en/point-in-time-recovery.html
|
||||||
for info about MySQL's Enterprise Monitoring and Advisory Service
|
|
||||||
|
|
||||||
SLOW QUERIES
|
WORKER THREADS
|
||||||
The slow query log is enabled.
|
Current thread_cache_size = 32
|
||||||
Current long_query_time = 2.000000 sec.
|
Current threads_cached = 12
|
||||||
You have 533228 out of 1747455460 that take longer than 2.000000 sec. to complete
|
Current threads_per_sec = 0
|
||||||
Your long_query_time seems to be fine
|
Historic threads_per_sec = 0
|
||||||
|
Your thread_cache_size is fine
|
||||||
|
|
||||||
BINARY UPDATE LOG
|
MAX CONNECTIONS
|
||||||
The binary update log is NOT enabled.
|
Current max_connections = 250
|
||||||
You will not be able to do point in time recovery
|
Current threads_connected = 28
|
||||||
See http://dev.mysql.com/doc/refman/5.1/en/point-in-time-recovery.html
|
Historic max_used_connections = 250
|
||||||
|
The number of used connections is 100% of the configured maximum.
|
||||||
|
You should raise max_connections
|
||||||
|
|
||||||
WORKER THREADS
|
INNODB STATUS
|
||||||
Current thread_cache_size = 32
|
Current InnoDB index space = 34 M
|
||||||
Current threads_cached = 12
|
Current InnoDB data space = 77 M
|
||||||
Current threads_per_sec = 0
|
Current InnoDB buffer pool free = 98 %
|
||||||
Historic threads_per_sec = 0
|
Current innodb_buffer_pool_size = 6.00 G
|
||||||
Your thread_cache_size is fine
|
Depending on how much space your innodb indexes take up it may be safe
|
||||||
|
to increase this value to up to 2 / 3 of total system memory
|
||||||
|
|
||||||
MAX CONNECTIONS
|
MEMORY USAGE
|
||||||
Current max_connections = 250
|
Max Memory Ever Allocated : 7.67 G
|
||||||
Current threads_connected = 28
|
Configured Max Per-thread Buffers : 671 M
|
||||||
Historic max_used_connections = 250
|
Configured Max Global Buffers : 7.01 G
|
||||||
The number of used connections is 100% of the configured maximum.
|
Configured Max Memory Limit : 7.67 G
|
||||||
You should raise max_connections
|
Physical Memory : 23.58 G
|
||||||
|
Max memory limit seem to be within acceptable norms
|
||||||
|
|
||||||
INNODB STATUS
|
KEY BUFFER
|
||||||
Current InnoDB index space = 34 M
|
Current MyISAM index space = 4.13 G
|
||||||
Current InnoDB data space = 77 M
|
Current key_buffer_size = 512 M
|
||||||
Current InnoDB buffer pool free = 98 %
|
Key cache miss rate is 1 : 4965
|
||||||
Current innodb_buffer_pool_size = 6.00 G
|
Key buffer free ratio = 8 %
|
||||||
Depending on how much space your innodb indexes take up it may be safe
|
You could increase key_buffer_size
|
||||||
to increase this value to up to 2 / 3 of total system memory
|
It is safe to raise this up to 1/4 of total system memory;
|
||||||
|
assuming this is a dedicated database server.
|
||||||
|
|
||||||
MEMORY USAGE
|
QUERY CACHE
|
||||||
Max Memory Ever Allocated : 7.67 G
|
Query cache is enabled
|
||||||
Configured Max Per-thread Buffers : 671 M
|
Current query_cache_size = 512 M
|
||||||
Configured Max Global Buffers : 7.01 G
|
Current query_cache_used = 52 M
|
||||||
Configured Max Memory Limit : 7.67 G
|
Current query_cache_limit = 8 M
|
||||||
Physical Memory : 23.58 G
|
Current Query cache Memory fill ratio = 10.34 %
|
||||||
Max memory limit seem to be within acceptable norms
|
Current query_cache_min_res_unit = 4 K
|
||||||
|
Your query_cache_size seems to be too high.
|
||||||
|
Perhaps you can use these resources elsewhere
|
||||||
|
MySQL won't cache query results that are larger than query_cache_limit in size
|
||||||
|
|
||||||
KEY BUFFER
|
SORT OPERATIONS
|
||||||
Current MyISAM index space = 4.13 G
|
Current sort_buffer_size = 2 M
|
||||||
Current key_buffer_size = 512 M
|
Current read_rnd_buffer_size = 256 K
|
||||||
Key cache miss rate is 1 : 4965
|
Sort buffer seems to be fine
|
||||||
Key buffer free ratio = 8 %
|
|
||||||
You could increase key_buffer_size
|
|
||||||
It is safe to raise this up to 1/4 of total system memory;
|
|
||||||
assuming this is a dedicated database server.
|
|
||||||
|
|
||||||
QUERY CACHE
|
JOINS
|
||||||
Query cache is enabled
|
Current join_buffer_size = 132.00 K
|
||||||
Current query_cache_size = 512 M
|
You have had 9527 queries where a join could not use an index properly
|
||||||
Current query_cache_used = 52 M
|
You should enable "log-queries-not-using-indexes"
|
||||||
Current query_cache_limit = 8 M
|
Then look for non indexed joins in the slow query log.
|
||||||
Current Query cache Memory fill ratio = 10.34 %
|
If you are unable to optimize your queries you may want to increase your
|
||||||
Current query_cache_min_res_unit = 4 K
|
join_buffer_size to accommodate larger joins in one pass.
|
||||||
Your query_cache_size seems to be too high.
|
|
||||||
Perhaps you can use these resources elsewhere
|
|
||||||
MySQL won't cache query results that are larger than query_cache_limit in size
|
|
||||||
|
|
||||||
SORT OPERATIONS
|
Note! This script will still suggest raising the join_buffer_size when
|
||||||
Current sort_buffer_size = 2 M
|
ANY joins not using indexes are found.
|
||||||
Current read_rnd_buffer_size = 256 K
|
|
||||||
Sort buffer seems to be fine
|
|
||||||
|
|
||||||
JOINS
|
OPEN FILES LIMIT
|
||||||
Current join_buffer_size = 132.00 K
|
Current open_files_limit = 5260 files
|
||||||
You have had 9527 queries where a join could not use an index properly
|
The open_files_limit should typically be set to at least 2x-3x
|
||||||
You should enable "log-queries-not-using-indexes"
|
that of table_cache if you have heavy MyISAM usage.
|
||||||
Then look for non indexed joins in the slow query log.
|
You currently have open more than 75% of your open_files_limit
|
||||||
If you are unable to optimize your queries you may want to increase your
|
You should set a higher value for open_files_limit in my.cnf
|
||||||
join_buffer_size to accommodate larger joins in one pass.
|
|
||||||
|
|
||||||
Note! This script will still suggest raising the join_buffer_size when
|
TABLE CACHE
|
||||||
ANY joins not using indexes are found.
|
Current table_open_cache = 2500 tables
|
||||||
|
Current table_definition_cache = 256 tables
|
||||||
|
You have a total of 5084 tables
|
||||||
|
You have 2500 open tables.
|
||||||
|
Current table_cache hit rate is 0%
|
||||||
|
, while 100% of your table cache is in use
|
||||||
|
You should probably increase your table_cache
|
||||||
|
You should probably increase your table_definition_cache value.
|
||||||
|
|
||||||
OPEN FILES LIMIT
|
TEMP TABLES
|
||||||
Current open_files_limit = 5260 files
|
Current max_heap_table_size = 64 M
|
||||||
The open_files_limit should typically be set to at least 2x-3x
|
Current tmp_table_size = 256 M
|
||||||
that of table_cache if you have heavy MyISAM usage.
|
Of 8549110 temp tables, 35% were created on disk
|
||||||
You currently have open more than 75% of your open_files_limit
|
Effective in-memory tmp_table_size is limited to max_heap_table_size.
|
||||||
You should set a higher value for open_files_limit in my.cnf
|
Perhaps you should increase your tmp_table_size and/or max_heap_table_size
|
||||||
|
to reduce the number of disk-based temporary tables
|
||||||
|
Note! BLOB and TEXT columns are not allow in memory tables.
|
||||||
|
If you are using these columns raising these values might not impact your
|
||||||
|
ratio of on disk temp tables.
|
||||||
|
|
||||||
TABLE CACHE
|
TABLE SCANS
|
||||||
Current table_open_cache = 2500 tables
|
Current read_buffer_size = 128 K
|
||||||
Current table_definition_cache = 256 tables
|
Current table scan ratio = 50592 : 1
|
||||||
You have a total of 5084 tables
|
You have a high ratio of sequential access requests to SELECTs
|
||||||
You have 2500 open tables.
|
You may benefit from raising read_buffer_size and/or improving your use of indexes.
|
||||||
Current table_cache hit rate is 0%
|
|
||||||
, while 100% of your table cache is in use
|
|
||||||
You should probably increase your table_cache
|
|
||||||
You should probably increase your table_definition_cache value.
|
|
||||||
|
|
||||||
TEMP TABLES
|
|
||||||
Current max_heap_table_size = 64 M
|
|
||||||
Current tmp_table_size = 256 M
|
|
||||||
Of 8549110 temp tables, 35% were created on disk
|
|
||||||
Effective in-memory tmp_table_size is limited to max_heap_table_size.
|
|
||||||
Perhaps you should increase your tmp_table_size and/or max_heap_table_size
|
|
||||||
to reduce the number of disk-based temporary tables
|
|
||||||
Note! BLOB and TEXT columns are not allow in memory tables.
|
|
||||||
If you are using these columns raising these values might not impact your
|
|
||||||
ratio of on disk temp tables.
|
|
||||||
|
|
||||||
TABLE SCANS
|
|
||||||
Current read_buffer_size = 128 K
|
|
||||||
Current table scan ratio = 50592 : 1
|
|
||||||
You have a high ratio of sequential access requests to SELECTs
|
|
||||||
You may benefit from raising read_buffer_size and/or improving your use of indexes.
|
|
||||||
|
|
||||||
TABLE LOCKING
|
|
||||||
Current Lock Wait ratio = 1 : 115
|
|
||||||
You may benefit from selective use of InnoDB.
|
|
||||||
If you have long running SELECT's against MyISAM tables and perform
|
|
||||||
frequent updates consider setting 'low_priority_updates=1'
|
|
||||||
If you have a high concurrency of inserts on Dynamic row-length tables
|
|
||||||
consider setting 'concurrent_insert=2'.
|
|
||||||
|
|
||||||
|
TABLE LOCKING
|
||||||
|
Current Lock Wait ratio = 1 : 115
|
||||||
|
You may benefit from selective use of InnoDB.
|
||||||
|
If you have long running SELECT's against MyISAM tables and perform
|
||||||
|
frequent updates consider setting 'low_priority_updates=1'
|
||||||
|
If you have a high concurrency of inserts on Dynamic row-length tables
|
||||||
|
consider setting 'concurrent_insert=2'.
|
||||||
|
~~~
|
||||||
|
|
||||||
## Activer le support des large pages
|
## Activer le support des large pages
|
||||||
|
|
||||||
|
@ -347,51 +347,51 @@ des cas a priori.
|
||||||
|
|
||||||
Pour l'activer, il faudra vérifier que le kernel supporte les _large pages_ :
|
Pour l'activer, il faudra vérifier que le kernel supporte les _large pages_ :
|
||||||
|
|
||||||
|
~~~
|
||||||
# cat /proc/meminfo | grep -i huge
|
# cat /proc/meminfo | grep -i huge
|
||||||
HugePages_Total: 0
|
HugePages_Total: 0
|
||||||
HugePages_Free: 0
|
HugePages_Free: 0
|
||||||
HugePages_Rsvd: 0
|
HugePages_Rsvd: 0
|
||||||
HugePages_Surp: 0
|
HugePages_Surp: 0
|
||||||
Hugepagesize: 2048 kB
|
Hugepagesize: 2048 kB
|
||||||
|
~~~
|
||||||
|
|
||||||
Si cela ne renvoie rien c'est que le support des _large pages_ est désactivé.
|
Si cela ne renvoie rien c'est que le support des _large pages_ est désactivé.
|
||||||
(options `CONFIG_HUGETLBFS` et `CONFIG_HUGETLB_PAGE` du noyau).
|
(options `CONFIG_HUGETLBFS` et `CONFIG_HUGETLB_PAGE` du noyau).
|
||||||
|
|
||||||
Pour l'activer, on fera les opérations suivantes :
|
Pour l'activer, on fera les opérations suivantes :
|
||||||
|
|
||||||
|
~~~
|
||||||
|
# Set the number of pages to be used.
|
||||||
|
# Each page is normally 2MB, so a value of 20 = 40MB.
|
||||||
|
# This command actually allocates memory, so this much
|
||||||
|
# memory must be available.
|
||||||
|
|
||||||
# Set the number of pages to be used.
|
# echo 20 > /proc/sys/vm/nr_hugepages
|
||||||
# Each page is normally 2MB, so a value of 20 = 40MB.
|
|
||||||
# This command actually allocates memory, so this much
|
|
||||||
# memory must be available.
|
|
||||||
|
|
||||||
# echo 20 > /proc/sys/vm/nr_hugepages
|
# Set the group number that is permitted to access this
|
||||||
|
# memory (110 in this case). The mysql user must be a
|
||||||
|
# member of this group.
|
||||||
|
|
||||||
# Set the group number that is permitted to access this
|
# echo 110 > /proc/sys/vm/hugetlb_shm_group
|
||||||
# memory (110 in this case). The mysql user must be a
|
|
||||||
# member of this group.
|
|
||||||
|
|
||||||
# echo 110 > /proc/sys/vm/hugetlb_shm_group
|
# Increase the amount of shmem permitted per segment
|
||||||
|
# (900M in this case).
|
||||||
# Increase the amount of shmem permitted per segment
|
|
||||||
# (900M in this case).
|
|
||||||
|
|
||||||
# echo 943718400 > /proc/sys/kernel/shmmax
|
|
||||||
|
|
||||||
|
# echo 943718400 > /proc/sys/kernel/shmmax
|
||||||
|
~~~
|
||||||
|
|
||||||
Ajouter dans le `/etc/security/limits.conf` :
|
Ajouter dans le `/etc/security/limits.conf` :
|
||||||
|
|
||||||
|
~~~
|
||||||
ulimit -l unlimited
|
ulimit -l unlimited
|
||||||
|
~~~
|
||||||
|
|
||||||
Enfin dans la partie `[mysqld]` de `my.cf` ajouter :
|
Enfin dans la partie `[mysqld]` de `my.cf` ajouter :
|
||||||
|
|
||||||
|
~~~
|
||||||
large-pages
|
large-pages
|
||||||
|
~~~
|
||||||
|
|
||||||
Mais encore une fois, cela n'est pas nécessaire dans la plupart des cas.
|
Mais encore une fois, cela n'est pas nécessaire dans la plupart des cas.
|
||||||
|
|
||||||
|
@ -411,271 +411,281 @@ Il semblerait que contrairement à PostgreSQL, il ne soit pas nécessaire d'augm
|
||||||
|
|
||||||
Récupérer les fichiers de sql-bench avec bazar :
|
Récupérer les fichiers de sql-bench avec bazar :
|
||||||
|
|
||||||
|
~~~
|
||||||
$ bzr branch lp:sql-bench
|
$ bzr branch lp:sql-bench
|
||||||
|
~~~
|
||||||
|
|
||||||
Installer quelques outils nécessaire pour le benchmark :
|
Installer quelques outils nécessaire pour le benchmark :
|
||||||
|
|
||||||
|
~~~
|
||||||
# aptitude install libclass-dbi-perl libdbd-mysql-perl mysql-client-5.1
|
# aptitude install libclass-dbi-perl libdbd-mysql-perl mysql-client-5.1
|
||||||
|
~~~
|
||||||
|
|
||||||
Créer une base de données de test :
|
Créer une base de données de test :
|
||||||
|
|
||||||
|
~~~
|
||||||
# mysqladmin create test
|
# mysqladmin create test
|
||||||
# mysql
|
# mysql
|
||||||
mysql> GRANT ALL PRIVILEGES ON test.* TO 'test'@localhost IDENTIFIED BY 'test';
|
mysql> GRANT ALL PRIVILEGES ON test.* TO 'test'@localhost IDENTIFIED BY 'test';
|
||||||
|
~~~
|
||||||
|
|
||||||
Résultat du benchmark :
|
Résultat du benchmark :
|
||||||
|
|
||||||
~/mysql-5.5.12/sql-bench/sql-bench# perl run-all-tests --user='test' --password='test'
|
~~~
|
||||||
Benchmark DBD suite: 2.15
|
~/mysql-5.5.12/sql-bench/sql-bench# perl run-all-tests --user='test' --password='test'
|
||||||
Date of test: 2011-05-19 14:01:18
|
Benchmark DBD suite: 2.15
|
||||||
Running tests on: Linux 2.6.32-5-amd64 x86_64
|
Date of test: 2011-05-19 14:01:18
|
||||||
Arguments:
|
Running tests on: Linux 2.6.32-5-amd64 x86_64
|
||||||
Comments:
|
Arguments:
|
||||||
Limits from:
|
Comments:
|
||||||
Server version: MySQL 5.1.49 3
|
Limits from:
|
||||||
Optimization: None
|
Server version: MySQL 5.1.49 3
|
||||||
Hardware:
|
Optimization: None
|
||||||
|
Hardware:
|
||||||
Operation seconds usr sys cpu tests
|
|
||||||
alter-table: Total time: 16 wallclock secs ( 0.08 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.08 CPU)
|
|
||||||
ATIS: Total time: 4 wallclock secs ( 2.34 usr 0.77 sys + 0.00 cusr 0.00 csys = 3.11 CPU)
|
|
||||||
big-tables: Total time: 5 wallclock secs ( 0.92 usr 2.47 sys + 0.00 cusr 0.00 csys = 3.39 CPU)
|
|
||||||
connect: Total time: 18 wallclock secs ( 4.85 usr 2.88 sys + 0.00 cusr 0.00 csys = 7.73 CPU)
|
|
||||||
create: Total time: 53 wallclock secs ( 3.86 usr 1.75 sys + 0.00 cusr 0.00 csys = 5.61 CPU)
|
|
||||||
insert: Total time: 618 wallclock secs (221.17 usr 14.05 sys + 0.00 cusr 0.00 csys = 235.22 CPU)
|
|
||||||
select: Total time: 49 wallclock secs (11.28 usr 8.95 sys + 0.00 cusr 0.00 csys = 20.23 CPU)
|
|
||||||
transactions: Test skipped because the database doesn't support transactions
|
|
||||||
wisconsin: Total time: 5 wallclock secs ( 1.93 usr 0.47 sys + 0.00 cusr 0.00 csys = 2.40 CPU)
|
|
||||||
TOTALS 788.00 244.02 30.97 274.99 2913950
|
|
||||||
|
|
||||||
|
|
||||||
|
Operation seconds usr sys cpu tests
|
||||||
|
alter-table: Total time: 16 wallclock secs ( 0.08 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.08 CPU)
|
||||||
|
ATIS: Total time: 4 wallclock secs ( 2.34 usr 0.77 sys + 0.00 cusr 0.00 csys = 3.11 CPU)
|
||||||
|
big-tables: Total time: 5 wallclock secs ( 0.92 usr 2.47 sys + 0.00 cusr 0.00 csys = 3.39 CPU)
|
||||||
|
connect: Total time: 18 wallclock secs ( 4.85 usr 2.88 sys + 0.00 cusr 0.00 csys = 7.73 CPU)
|
||||||
|
create: Total time: 53 wallclock secs ( 3.86 usr 1.75 sys + 0.00 cusr 0.00 csys = 5.61 CPU)
|
||||||
|
insert: Total time: 618 wallclock secs (221.17 usr 14.05 sys + 0.00 cusr 0.00 csys = 235.22 CPU)
|
||||||
|
select: Total time: 49 wallclock secs (11.28 usr 8.95 sys + 0.00 cusr 0.00 csys = 20.23 CPU)
|
||||||
|
transactions: Test skipped because the database doesn't support transactions
|
||||||
|
wisconsin: Total time: 5 wallclock secs ( 1.93 usr 0.47 sys + 0.00 cusr 0.00 csys = 2.40 CPU)
|
||||||
|
TOTALS 788.00 244.02 30.97 274.99 2913950
|
||||||
|
~~~
|
||||||
|
|
||||||
# Administration
|
# Administration
|
||||||
|
|
||||||
On crée une base de données et un utilisateur associé :
|
On crée une base de données et un utilisateur associé :
|
||||||
|
|
||||||
|
~~~
|
||||||
# mysqladmin create NOM_BASE
|
# mysqladmin create NOM_BASE
|
||||||
# mysql
|
# mysql
|
||||||
mysql> GRANT ALL PRIVILEGES ON NOM_BASE.* TO 'USER_BASE'@localhost IDENTIFIED BY 'XXX';
|
mysql> GRANT ALL PRIVILEGES ON NOM_BASE.* TO 'USER_BASE'@localhost IDENTIFIED BY 'XXX';
|
||||||
|
~~~
|
||||||
|
|
||||||
Cette opération revient à insérer des lignes brutes dans les tables `mysql.user` et `mysql.db` ainsi (
|
Cette opération revient à insérer des lignes brutes dans les tables `mysql.user` et `mysql.db` ainsi (
|
||||||
|
|
||||||
|
~~~
|
||||||
|
mysql> INSERT INTO user VALUES ('localhost','USER_BASE',password('XXX'),'N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N',_,'','','',0,0,0,0,_,NULL);
|
||||||
|
mysql> INSERT INTO db VALUES ('localhost','NOM_BASE','USER_BASE','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
|
||||||
|
mysql> FLUSH PRIVILEGES;
|
||||||
|
~~~
|
||||||
|
|
||||||
# mysql
|
**Note** : sous Debian 6, les valeurs dans `mysql.user` avait 3 colonnes de moins : Create_tablespace_priv, plugin et authentication_string :
|
||||||
mysql> INSERT INTO user VALUES ('localhost','USER_BASE',password('XXX'),'N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N',_,'','','',0,0,0,0,_,NULL);
|
|
||||||
mysql> INSERT INTO db VALUES ('localhost','NOM_BASE','USER_BASE','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
|
|
||||||
mysql> FLUSH PRIVILEGES;
|
|
||||||
|
|
||||||
|
|
||||||
Note : sous Debian 6, les valeurs dans `mysql.user` avait 3 colonnes de moins : Create_tablespace_priv, plugin et authentication_string :
|
|
||||||
(par défaut, pour migrer on ajoutera donc 'N' en 32ème position + '' et NULL à la fin) :
|
(par défaut, pour migrer on ajoutera donc 'N' en 32ème position + '' et NULL à la fin) :
|
||||||
|
|
||||||
|
~~~
|
||||||
mysql> INSERT INTO user VALUES ('localhost','USER_BASE',password('XXX'),'N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N',_,'','',_,0,0,0,0);
|
mysql> INSERT INTO user VALUES ('localhost','USER_BASE',password('XXX'),'N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N',_,'','',_,0,0,0,0);
|
||||||
|
~~~
|
||||||
|
|
||||||
On pourra ainsi régler finement les droits d'un utilisateurs en connaissant la signification de chaque colonne :
|
On pourra ainsi régler finement les droits d'un utilisateurs en connaissant la signification de chaque colonne :
|
||||||
|
|
||||||
|
~~~
|
||||||
mysql> desc user;
|
mysql> desc user;
|
||||||
+------------------------+-----------------------------------+------+-----+---------+-------+
|
+------------------------+-----------------------------------+------+-----+---------+-------+
|
||||||
| Field | Type | Null | Key | Default | Extra |
|
| Field | Type | Null | Key | Default | Extra |
|
||||||
+------------------------+-----------------------------------+------+-----+---------+-------+
|
+------------------------+-----------------------------------+------+-----+---------+-------+
|
||||||
| Host | char(60) | NO | PRI | | |
|
| Host | char(60) | NO | PRI | | |
|
||||||
| User | char(16) | NO | PRI | | |
|
| User | char(16) | NO | PRI | | |
|
||||||
| Password | char(41) | NO | | | |
|
| Password | char(41) | NO | | | |
|
||||||
| Select_priv | enum('N','Y') | NO | | N | |
|
| Select_priv | enum('N','Y') | NO | | N | |
|
||||||
| Insert_priv | enum('N','Y') | NO | | N | |
|
| Insert_priv | enum('N','Y') | NO | | N | |
|
||||||
| Update_priv | enum('N','Y') | NO | | N | |
|
| Update_priv | enum('N','Y') | NO | | N | |
|
||||||
| Delete_priv | enum('N','Y') | NO | | N | |
|
| Delete_priv | enum('N','Y') | NO | | N | |
|
||||||
| Create_priv | enum('N','Y') | NO | | N | |
|
| Create_priv | enum('N','Y') | NO | | N | |
|
||||||
| Drop_priv | enum('N','Y') | NO | | N | |
|
| Drop_priv | enum('N','Y') | NO | | N | |
|
||||||
| Reload_priv | enum('N','Y') | NO | | N | |
|
| Reload_priv | enum('N','Y') | NO | | N | |
|
||||||
| Shutdown_priv | enum('N','Y') | NO | | N | |
|
| Shutdown_priv | enum('N','Y') | NO | | N | |
|
||||||
| Process_priv | enum('N','Y') | NO | | N | |
|
| Process_priv | enum('N','Y') | NO | | N | |
|
||||||
| File_priv | enum('N','Y') | NO | | N | |
|
| File_priv | enum('N','Y') | NO | | N | |
|
||||||
| Grant_priv | enum('N','Y') | NO | | N | |
|
| Grant_priv | enum('N','Y') | NO | | N | |
|
||||||
| References_priv | enum('N','Y') | NO | | N | |
|
| References_priv | enum('N','Y') | NO | | N | |
|
||||||
| Index_priv | enum('N','Y') | NO | | N | |
|
| Index_priv | enum('N','Y') | NO | | N | |
|
||||||
| Alter_priv | enum('N','Y') | NO | | N | |
|
| Alter_priv | enum('N','Y') | NO | | N | |
|
||||||
| Show_db_priv | enum('N','Y') | NO | | N | |
|
| Show_db_priv | enum('N','Y') | NO | | N | |
|
||||||
| Super_priv | enum('N','Y') | NO | | N | |
|
| Super_priv | enum('N','Y') | NO | | N | |
|
||||||
| Create_tmp_table_priv | enum('N','Y') | NO | | N | |
|
| Create_tmp_table_priv | enum('N','Y') | NO | | N | |
|
||||||
| Lock_tables_priv | enum('N','Y') | NO | | N | |
|
| Lock_tables_priv | enum('N','Y') | NO | | N | |
|
||||||
| Execute_priv | enum('N','Y') | NO | | N | |
|
| Execute_priv | enum('N','Y') | NO | | N | |
|
||||||
| Repl_slave_priv | enum('N','Y') | NO | | N | |
|
| Repl_slave_priv | enum('N','Y') | NO | | N | |
|
||||||
| Repl_client_priv | enum('N','Y') | NO | | N | |
|
| Repl_client_priv | enum('N','Y') | NO | | N | |
|
||||||
| Create_view_priv | enum('N','Y') | NO | | N | |
|
| Create_view_priv | enum('N','Y') | NO | | N | |
|
||||||
| Show_view_priv | enum('N','Y') | NO | | N | |
|
| Show_view_priv | enum('N','Y') | NO | | N | |
|
||||||
| Create_routine_priv | enum('N','Y') | NO | | N | |
|
| Create_routine_priv | enum('N','Y') | NO | | N | |
|
||||||
| Alter_routine_priv | enum('N','Y') | NO | | N | |
|
| Alter_routine_priv | enum('N','Y') | NO | | N | |
|
||||||
| Create_user_priv | enum('N','Y') | NO | | N | |
|
| Create_user_priv | enum('N','Y') | NO | | N | |
|
||||||
| Event_priv | enum('N','Y') | NO | | N | |
|
| Event_priv | enum('N','Y') | NO | | N | |
|
||||||
| Trigger_priv | enum('N','Y') | NO | | N | |
|
| Trigger_priv | enum('N','Y') | NO | | N | |
|
||||||
| Create_tablespace_priv | enum('N','Y') | NO | | N | |
|
| Create_tablespace_priv | enum('N','Y') | NO | | N | |
|
||||||
| ssl_type | enum('','ANY','X509','SPECIFIED') | NO | | | |
|
| ssl_type | enum('','ANY','X509','SPECIFIED') | NO | | | |
|
||||||
| ssl_cipher | blob | NO | | NULL | |
|
| ssl_cipher | blob | NO | | NULL | |
|
||||||
| x509_issuer | blob | NO | | NULL | |
|
| x509_issuer | blob | NO | | NULL | |
|
||||||
| x509_subject | blob | NO | | NULL | |
|
| x509_subject | blob | NO | | NULL | |
|
||||||
| max_questions | int(11) unsigned | NO | | 0 | |
|
| max_questions | int(11) unsigned | NO | | 0 | |
|
||||||
| max_updates | int(11) unsigned | NO | | 0 | |
|
| max_updates | int(11) unsigned | NO | | 0 | |
|
||||||
| max_connections | int(11) unsigned | NO | | 0 | |
|
| max_connections | int(11) unsigned | NO | | 0 | |
|
||||||
| max_user_connections | int(11) unsigned | NO | | 0 | |
|
| max_user_connections | int(11) unsigned | NO | | 0 | |
|
||||||
| plugin | char(64) | YES | | | |
|
| plugin | char(64) | YES | | | |
|
||||||
| authentication_string | text | YES | | NULL | |
|
| authentication_string | text | YES | | NULL | |
|
||||||
+------------------------+-----------------------------------+------+-----+---------+-------+
|
+------------------------+-----------------------------------+------+-----+---------+-------+
|
||||||
42 rows in set (0.00 sec)
|
42 rows in set (0.00 sec)
|
||||||
|
~~~
|
||||||
|
|
||||||
Par exemple, pour permettre à un utilisateur (ici `debian-sys-maint`) de faire des "SHOW VIEW" :
|
Par exemple, pour permettre à un utilisateur (ici `debian-sys-maint`) de faire des "SHOW VIEW" :
|
||||||
|
|
||||||
|
~~~
|
||||||
mysql> UPDATE user SET Show_view_priv='Y' WHERE User='debian-sys-maint';
|
mysql> UPDATE user SET Show_view_priv='Y' WHERE User='debian-sys-maint';
|
||||||
mysql> FLUSH PRIVILEGES;
|
mysql> FLUSH PRIVILEGES;
|
||||||
|
~~~
|
||||||
|
|
||||||
… que l'on peut aussi faire via :
|
… que l'on peut aussi faire via :
|
||||||
|
|
||||||
mysql> GRANT SHOW VIEW on *.* to `debian-sys-maint`@localhost;
|
~~~
|
||||||
|
mysql> GRANT SHOW VIEW on *.* to `debian-sys-maint`@localhost;
|
||||||
|
~~~
|
||||||
|
|
||||||
Pour créer un utilisateur sans droit particulier, par exemple pour du monitoring :
|
Pour créer un utilisateur sans droit particulier, par exemple pour du monitoring :
|
||||||
|
|
||||||
|
~~~
|
||||||
mysql> create user nagios@localhost identified by 'XXX';
|
mysql> create user nagios@localhost identified by 'XXX';
|
||||||
|
~~~
|
||||||
|
|
||||||
On peut aussi gérer des droits sur les tables :
|
On peut aussi gérer des droits sur les tables :
|
||||||
|
|
||||||
mysql> GRANT Select,Insert,Update ON BASE.TABLE TO 'USER_BASE'@localhost;
|
~~~
|
||||||
|
mysql> GRANT Select,Insert,Update ON BASE.TABLE TO 'USER_BASE'@localhost;
|
||||||
|
~~~
|
||||||
|
|
||||||
Pour révoquer des droits sur une table, on utilisera REVOKE :
|
Pour révoquer des droits sur une table, on utilisera REVOKE :
|
||||||
|
|
||||||
mysql> REVOKE ALL PRIVILEGES ON BASE.TABLE FROM 'USER_BASE'@localhost;
|
~~~
|
||||||
|
mysql> REVOKE ALL PRIVILEGES ON BASE.TABLE FROM 'USER_BASE'@localhost;
|
||||||
|
~~~
|
||||||
|
|
||||||
Un droit est particulier : pour utiliser LOAD DATA INFILE ou SELECT INTO OUTFILE, il faut avoir le droit FILE … mais il est global (et dangereux) !
|
Un droit est particulier : pour utiliser LOAD DATA INFILE ou SELECT INTO OUTFILE, il faut avoir le droit FILE … mais il est global (et dangereux) !
|
||||||
On le positionnera ainsi :
|
On le positionnera ainsi :
|
||||||
|
|
||||||
mysql> GRANT FILE ON *.* TO 'USER_BASE'@localhost;
|
~~~
|
||||||
|
mysql> GRANT FILE ON *.* TO 'USER_BASE'@localhost;
|
||||||
|
~~~
|
||||||
|
|
||||||
Pour vérifier et réparer toutes les tables (une sorte de `fsck` pour les tables),
|
Pour vérifier et réparer toutes les tables (une sorte de `fsck` pour les tables),
|
||||||
on lancera la commande suivante :
|
on lancera la commande suivante :
|
||||||
|
|
||||||
|
~~~
|
||||||
# mysqlcheck --auto-repair --check --all-databases
|
# mysqlcheck --auto-repair --check --all-databases
|
||||||
|
~~~
|
||||||
|
|
||||||
On peut aussi réparer qu'une base en particulier :
|
On peut aussi réparer qu'une base en particulier :
|
||||||
|
|
||||||
|
~~~
|
||||||
# mysqlcheck --auto-repair --check mabase
|
# mysqlcheck --auto-repair --check mabase
|
||||||
|
~~~
|
||||||
|
|
||||||
Note : ceci est à faire en général en cas d'arrêt inopiné du serveur.
|
Note : ceci est à faire en général en cas d'arrêt inopiné du serveur.
|
||||||
|
|
||||||
On pourra également ajouter l'option *--optimize* pour ajouter une optimisation des tables :
|
On pourra également ajouter l'option *--optimize* pour ajouter une optimisation des tables :
|
||||||
|
|
||||||
|
~~~
|
||||||
# mysqlcheck --auto-repair --check --optimize --all-databases
|
# mysqlcheck --auto-repair --check --optimize --all-databases
|
||||||
|
~~~
|
||||||
|
|
||||||
Pour réparer une seule table :
|
Pour réparer une seule table :
|
||||||
|
|
||||||
|
~~~
|
||||||
mysql> CHECK TABLE mabase.matable;
|
mysql> CHECK TABLE mabase.matable;
|
||||||
mysql> REPAIR TABLE mabase.matable;
|
mysql> REPAIR TABLE mabase.matable;
|
||||||
mysql> OPTIMIZE TABLE mabase.matable;
|
mysql> OPTIMIZE TABLE mabase.matable;
|
||||||
|
~~~
|
||||||
|
|
||||||
Dans le cas des tables MyISAM, si le REPAIR échoue, une réparation est aussi possible via `myisamchk`… à faire avec
|
Dans le cas des tables MyISAM, si le REPAIR échoue, une réparation est aussi possible via `myisamchk`… à faire avec
|
||||||
le service MySQL arrêté :
|
le service MySQL arrêté :
|
||||||
|
|
||||||
|
~~~
|
||||||
# myisamchk -r -q /var/lib/mysql/BASE/TABLE.MYD
|
# myisamchk -r -q /var/lib/mysql/BASE/TABLE.MYD
|
||||||
|
~~~
|
||||||
|
|
||||||
En cas d'echec (segfault par exemple), on peut tenter :
|
En cas d'echec (segfault par exemple), on peut tenter :
|
||||||
|
|
||||||
# myisamchk --safe-recover -v -f --key_buffer_size=512M --sort_buffer_size=512M --read_buffer_size=4M --write_buffer_size=4M /var/lib/mysql/BASE/TABLE.MYD
|
~~~
|
||||||
|
# myisamchk --safe-recover -v -f --key_buffer_size=512M --sort_buffer_size=512M --read_buffer_size=4M --write_buffer_size=4M /var/lib/mysql/BASE/TABLE.MYD
|
||||||
|
~~~
|
||||||
|
|
||||||
|
## Problème de _definer_ avec les vues
|
||||||
## Problème de definer avec les vues
|
|
||||||
|
|
||||||
Un problème classique qui peut arriver suite à une migration d'une base de données contenant des vues. Si l'utilisateur qui a créé la vue (le _definer_) n'existe pas sur le nouveau serveur, la vue sera inutilisable :
|
Un problème classique qui peut arriver suite à une migration d'une base de données contenant des vues. Si l'utilisateur qui a créé la vue (le _definer_) n'existe pas sur le nouveau serveur, la vue sera inutilisable :
|
||||||
|
|
||||||
|
~~~
|
||||||
mysql> SELECT * FROM myview;
|
mysql> SELECT * FROM myview;
|
||||||
MySQL ERROR 1449 (HY000) : The user specified as a definer ('root'@'localhost') does not exist
|
MySQL ERROR 1449 (HY000) : The user specified as a definer ('root'@'localhost') does not exist
|
||||||
|
~~~
|
||||||
|
|
||||||
Il faut donc soit faire un sed dans le dump MySQL pour remplacer le definer si on est à l'étape de préparation de la migration.
|
Il faut donc soit faire un sed dans le dump MySQL pour remplacer le definer si on est à l'étape de préparation de la migration.
|
||||||
Si la migration a déjà été faite et qu'il n'est plus possible de réinjecter un dump, il faut modifier la vue via `ALTER VIEW`, mais il est nécessaire d'indiquer la définition complète de la vue. Pour la connaitre :
|
Si la migration a déjà été faite et qu'il n'est plus possible de réinjecter un dump, il faut modifier la vue via `ALTER VIEW`, mais il est nécessaire d'indiquer la définition complète de la vue. Pour la connaitre :
|
||||||
|
|
||||||
mysql> SHOW CREATE VIEW myview;
|
~~~
|
||||||
|
mysql> SHOW CREATE VIEW myview;
|
||||||
|
~~~
|
||||||
|
|
||||||
Copier ensuite la définition complète, en remplaçant `CREATE` par `ALTER`, et bien sûr le definer de la vue par un utilisateur existant qui aura les droits sur la vue.
|
Copier ensuite la définition complète, en remplaçant `CREATE` par `ALTER`, et bien sûr le definer de la vue par un utilisateur existant qui aura les droits sur la vue.
|
||||||
|
|
||||||
Pour lister les vues dans une base :
|
Pour lister les vues dans une base :
|
||||||
|
|
||||||
mysql> SHOW FULL TABLES IN mydb WHERE TABLE_TYPE LIKE 'VIEW';
|
~~~
|
||||||
|
mysql> SHOW FULL TABLES IN mydb WHERE TABLE_TYPE LIKE 'VIEW';
|
||||||
|
~~~
|
||||||
|
|
||||||
# Sauvegarde MySQL
|
# Sauvegarde MySQL
|
||||||
|
|
||||||
Pour sauvegarder une base de données (sans et avec compression) :
|
Pour sauvegarder une base de données (sans et avec compression) :
|
||||||
|
|
||||||
|
~~~
|
||||||
# mysqldump NOM_BASE > NOM_FICHIER
|
# mysqldump NOM_BASE > NOM_FICHIER
|
||||||
# mysqldump NOM_BASE | gzip > NOM_FICHIER
|
# mysqldump NOM_BASE | gzip > NOM_FICHIER
|
||||||
|
~~~
|
||||||
|
|
||||||
Pour restaurer une base de données (sans et avec compression) :
|
Pour restaurer une base de données (sans et avec compression) :
|
||||||
|
|
||||||
|
~~~
|
||||||
# mysqladmin create NOM_BASE
|
# mysqladmin create NOM_BASE
|
||||||
# mysql NOM_BASE < NOM_FICHIER
|
# mysql NOM_BASE < NOM_FICHIER
|
||||||
# gunzip < NOM_FICHIER | mysql NOM_BASE
|
# gunzip < NOM_FICHIER | mysql NOM_BASE
|
||||||
|
~~~
|
||||||
|
|
||||||
Sauvegarder toutes les bases :
|
Sauvegarder toutes les bases :
|
||||||
|
|
||||||
|
~~~
|
||||||
# mysqldump --opt --all-databases > NOM_FICHIER
|
# mysqldump --opt --all-databases > NOM_FICHIER
|
||||||
|
~~~
|
||||||
|
|
||||||
Pour sauvegarder uniquement certaines tables :
|
Pour sauvegarder uniquement certaines tables :
|
||||||
|
|
||||||
|
~~~
|
||||||
# mysqldump NOM_BASE NOM_TABLE0 [NOM_TABLE1…] > NOM_FICHIER
|
# mysqldump NOM_BASE NOM_TABLE0 [NOM_TABLE1…] > NOM_FICHIER
|
||||||
|
~~~
|
||||||
|
|
||||||
Pour presque faire un "--exclude" (qui manque cruellement à mysqldump):
|
Pour presque faire un "--exclude" (qui manque cruellement à mysqldump):
|
||||||
|
|
||||||
|
~~~
|
||||||
mysql -B -N -e 'show databases' | \
|
mysql -B -N -e 'show databases' | \
|
||||||
perl -ne 'print unless /\b(?:phpmyadmin|mysql|information_schema)\b/' | \
|
perl -ne 'print unless /\b(?:phpmyadmin|mysql|information_schema)\b/' | \
|
||||||
xargs echo mysqldump -B
|
xargs echo mysqldump -B
|
||||||
|
~~~
|
||||||
|
|
||||||
Et pour sauvegarder des tables correspondant à un motif (préfixe le plus souvent) :
|
Et pour sauvegarder des tables correspondant à un motif (préfixe le plus souvent) :
|
||||||
|
|
||||||
|
~~~
|
||||||
# mysqldump NOM_BASE $(mysql NOM_BASE -B --column-names=False -e "show tables like 'exemple_%'") > NOM_FICHIER
|
# mysqldump NOM_BASE $(mysql NOM_BASE -B --column-names=False -e "show tables like 'exemple_%'") > NOM_FICHIER
|
||||||
|
~~~
|
||||||
|
|
||||||
Pour dumper avec une condition particulière :
|
Pour dumper avec une condition particulière :
|
||||||
|
|
||||||
mysqldump -t <base> <table> --where="my_id='66666666'"
|
~~~
|
||||||
|
mysqldump -t <base> <table> --where="my_id='66666666'"
|
||||||
|
~~~
|
||||||
|
|
||||||
Ce qui permet de réinjecter des données résultantes d'un `SELECT * FROM base.table WHERE my_id='66666666'`.
|
Ce qui permet de réinjecter des données résultantes d'un `SELECT * FROM base.table WHERE my_id='66666666'`.
|
||||||
|
|
||||||
|
@ -684,57 +694,58 @@ précisant son port avec l'option `--port` (valable pour mysqldump et mysql).
|
||||||
|
|
||||||
Pour obtenir une liste des utilisateurs mysql, on peut utiliser cette fonction (glanée sur [serverfault](http://serverfault.com/questions/8860/how-can-i-export-the-privileges-from-mysql-and-then-import-to-a-new-server/)) :
|
Pour obtenir une liste des utilisateurs mysql, on peut utiliser cette fonction (glanée sur [serverfault](http://serverfault.com/questions/8860/how-can-i-export-the-privileges-from-mysql-and-then-import-to-a-new-server/)) :
|
||||||
|
|
||||||
|
~~~{.bash}
|
||||||
mygrants()
|
mygrants()
|
||||||
{
|
{
|
||||||
mysql -B -N -e "SELECT DISTINCT CONCAT(
|
mysql -B -N -e "SELECT DISTINCT CONCAT(
|
||||||
'SHOW GRANTS FOR *, user, _'@'_, host, *;'
|
'SHOW GRANTS FOR *, user, _'@'_, host, *;'
|
||||||
) AS query FROM mysql.user" | \
|
) AS query FROM mysql.user" | \
|
||||||
mysql | \
|
mysql | \
|
||||||
sed 's/\(GRANT .*\)/\1;/;s/^\(Grants for .*\)/## \1 ##/;/##/{x;p;x;}'
|
sed 's/\(GRANT .*\)/\1;/;s/^\(Grants for .*\)/## \1 ##/;/##/{x;p;x;}'
|
||||||
}
|
}
|
||||||
|
~~~
|
||||||
|
|
||||||
Pour avoir un dump avec un seul insert par ligne, pratique pour restaurer partiellement les bases `mysql.user` et `mysql.db` par exemple :
|
Pour avoir un dump avec un seul insert par ligne, pratique pour restaurer partiellement les bases `mysql.user` et `mysql.db` par exemple :
|
||||||
|
|
||||||
|
~~~
|
||||||
# mysqldump --skip-extended-insert mysql > mysql.dump
|
# mysqldump --skip-extended-insert mysql > mysql.dump
|
||||||
|
~~~
|
||||||
|
|
||||||
Pour restaurer une seule base d'un dump complet on peut utiliser :
|
Pour restaurer une seule base d'un dump complet on peut utiliser :
|
||||||
|
|
||||||
|
~~~
|
||||||
mysql -o MaBase < dump.sql
|
mysql -o MaBase < dump.sql
|
||||||
|
~~~
|
||||||
|
|
||||||
Pour restaurer une base, dont la structure de chaque table est stocké dans un fichier SQL indépendant, et dont les données sont dans des fichiers de type "
|
Pour restaurer une base, dont la structure de chaque table est stocké dans un fichier SQL indépendant, et dont les données sont dans des fichiers de type "
|
||||||
tab-separated data files" (option -T de mysqldump) avec une extension .txt :
|
tab-separated data files" (option -T de mysqldump) avec une extension .txt :
|
||||||
|
|
||||||
|
~~~{.bash}
|
||||||
|
db=test1
|
||||||
|
|
||||||
db=test1
|
for file in *.sql; do
|
||||||
|
mysql $db <$file
|
||||||
|
done
|
||||||
|
|
||||||
for file in *.sql; do
|
grep CHARSET= *txt
|
||||||
mysql $db <$file
|
|
||||||
done
|
|
||||||
|
|
||||||
grep CHARSET= *txt
|
for file in *.txt; do
|
||||||
|
tablename=`basename $file .txt` #tablename=${file%.*}
|
||||||
|
echo "LOAD DATA INFILE '$PWD/$file' INTO TABLE $tablename" CHARACTER SET utf8 | mysql $db
|
||||||
|
done
|
||||||
|
~~~
|
||||||
|
|
||||||
for file in *.txt; do
|
**Note 1** : Attention, l'utilisateur MySQL doit avoir le droit de lecture sur les fichiers .txt
|
||||||
tablename=`basename $file .txt` #tablename=${file%.*}
|
|
||||||
echo "LOAD DATA INFILE '$PWD/$file' INTO TABLE $tablename" CHARACTER SET utf8 | mysql $db
|
|
||||||
done
|
|
||||||
|
|
||||||
|
|
||||||
Note 1 : Attention, l'utilisateur MySQL doit avoir le droit de lecture sur les fichiers .txt
|
|
||||||
Se positionner dans un répertoire où mysql a les droits (mysqltmp - /home/mysqltmp par ex).
|
Se positionner dans un répertoire où mysql a les droits (mysqltmp - /home/mysqltmp par ex).
|
||||||
|
|
||||||
Note 2 : Si vous n'avez pas toutes vos tables en utf8 (par exemple du `CHARSET=LATIN1`), ce n'est pas bien… et vous devrez pour la peine adapter le script (en détectant le charset utilisé avec "file" si nécessaire)
|
**Note 2** : Si vous n'avez pas toutes vos tables en utf8 (par exemple du `CHARSET=LATIN1`), ce n'est pas bien… et vous devrez pour la peine adapter le script (en détectant le charset utilisé avec "file" si nécessaire)
|
||||||
|
|
||||||
|
|
||||||
Il est possible d'exporter le contenu d'une base au format CSV :
|
Il est possible d'exporter le contenu d'une base au format CSV :
|
||||||
|
|
||||||
mysqldump -T /tmp --fields-enclosed-by=\" --fields-terminated-by=, --no-create-db --no-create-info MaBase
|
~~~
|
||||||
|
mysqldump -T /tmp --fields-enclosed-by=\" --fields-terminated-by=, --no-create-db --no-create-info MaBase
|
||||||
|
~~~
|
||||||
|
|
||||||
NOTE : il est nécessaire que MySQL ait les droits d'écriture dans le répertoire de destination (ici `/tmp`).
|
NOTE : il est nécessaire que MySQL ait les droits d'écriture dans le répertoire de destination (ici `/tmp`).
|
||||||
|
|
||||||
|
@ -742,200 +753,202 @@ NOTE : il est nécessaire que MySQL ait les droits d'écriture dans le réperto
|
||||||
|
|
||||||
Créer une nouvelle base de données nommée NOM_BASE :
|
Créer une nouvelle base de données nommée NOM_BASE :
|
||||||
|
|
||||||
|
~~~
|
||||||
mysql> CREATE DATABASE NOM_BASE;
|
mysql> CREATE DATABASE NOM_BASE;
|
||||||
|
~~~
|
||||||
|
|
||||||
Voir les bases de données créées :
|
Voir les bases de données créées :
|
||||||
|
|
||||||
|
~~~
|
||||||
mysql> SHOW DATABASES;
|
mysql> SHOW DATABASES;
|
||||||
|
~~~
|
||||||
|
|
||||||
Utiliser la base de données NOM_BASE :
|
Utiliser la base de données NOM_BASE :
|
||||||
|
|
||||||
|
~~~
|
||||||
mysql> USE NOM_BASE
|
mysql> USE NOM_BASE
|
||||||
|
~~~
|
||||||
|
|
||||||
Voir les tables créées :
|
Voir les tables créées :
|
||||||
|
|
||||||
|
~~~
|
||||||
mysql> SHOW TABLES;
|
mysql> SHOW TABLES;
|
||||||
|
~~~
|
||||||
|
|
||||||
Créer une table nommée test avec différents champs :
|
Créer une table nommée test avec différents champs :
|
||||||
|
|
||||||
|
~~~
|
||||||
mysql> CREATE TABLE test (id INT not null AUTO_INCREMENT, prenom VARCHAR
|
mysql> CREATE TABLE test (id INT not null AUTO_INCREMENT, prenom VARCHAR
|
||||||
(50) not null , nom VARCHAR (50) not null , ne_le DATE not null ,
|
(50) not null , nom VARCHAR (50) not null , ne_le DATE not null ,
|
||||||
ville VARCHAR (90), enfants INT, PRIMARY KEY (id));
|
ville VARCHAR (90), enfants INT, PRIMARY KEY (id));
|
||||||
|
~~~
|
||||||
|
|
||||||
Décrire une table :
|
Décrire une table :
|
||||||
|
|
||||||
|
~~~
|
||||||
DESC test;
|
DESC test;
|
||||||
|
~~~
|
||||||
|
|
||||||
Ajouter un champ à une table :
|
Ajouter un champ à une table :
|
||||||
|
|
||||||
|
~~~
|
||||||
mysql> ALTER TABLE test ADD another VARCHAR(100) DEFAULT NULL;
|
mysql> ALTER TABLE test ADD another VARCHAR(100) DEFAULT NULL;
|
||||||
|
~~~
|
||||||
|
|
||||||
Ajouter un champ à une table en précisant sa place :
|
Ajouter un champ à une table en précisant sa place :
|
||||||
|
|
||||||
|
~~~
|
||||||
mysql> ALTER TABLE test ADD another VARCHAR(100) DEFAULT NULL AFTER prenom;
|
mysql> ALTER TABLE test ADD another VARCHAR(100) DEFAULT NULL AFTER prenom;
|
||||||
|
~~~
|
||||||
|
|
||||||
Supprimer un champ à une table :
|
Supprimer un champ à une table :
|
||||||
|
|
||||||
|
~~~
|
||||||
mysql> ALTER TABLE test DROP another;
|
mysql> ALTER TABLE test DROP another;
|
||||||
|
~~~
|
||||||
|
|
||||||
Renommer un champ :
|
Renommer un champ :
|
||||||
|
|
||||||
|
~~~
|
||||||
mysql> ALTER TABLE test CHANGE COLUMN another anotherone TEXT;
|
mysql> ALTER TABLE test CHANGE COLUMN another anotherone TEXT;
|
||||||
|
~~~
|
||||||
|
|
||||||
Changer le type d'un champ :
|
Changer le type d'un champ :
|
||||||
|
|
||||||
|
~~~
|
||||||
mysql> ALTER TABLE test CHANGE another another enum('foo',bar');
|
mysql> ALTER TABLE test CHANGE another another enum('foo',bar');
|
||||||
|
~~~
|
||||||
|
|
||||||
Insertion de données dans une table :
|
Insertion de données dans une table :
|
||||||
|
|
||||||
|
~~~
|
||||||
mysql> INSERT INTO test VALUES (1,'jp','papin','2005-06-12','Marseille',2);
|
mysql> INSERT INTO test VALUES (1,'jp','papin','2005-06-12','Marseille',2);
|
||||||
INSERT INTO test (id,prenom,nom,ne_le) VALUES (2,'c','waddle','2004-06-17');
|
INSERT INTO test (id,prenom,nom,ne_le) VALUES (2,'c','waddle','2004-06-17');
|
||||||
|
~~~
|
||||||
|
|
||||||
Sélectionner tous les champs d'une table :
|
Sélectionner tous les champs d'une table :
|
||||||
|
|
||||||
|
~~~
|
||||||
mysql> SELECT * FROM test;
|
mysql> SELECT * FROM test;
|
||||||
|
~~~
|
||||||
|
|
||||||
Effacer des données d'une table :
|
Effacer des données d'une table :
|
||||||
|
|
||||||
|
~~~
|
||||||
mysql> DELETE FROM test WHERE nom='waddle';
|
mysql> DELETE FROM test WHERE nom='waddle';
|
||||||
|
~~~
|
||||||
|
|
||||||
Effacer TOUTES les données d'une table :
|
Effacer TOUTES les données d'une table :
|
||||||
|
|
||||||
|
~~~
|
||||||
DELETE FROM test;
|
DELETE FROM test;
|
||||||
|
~~~
|
||||||
|
|
||||||
Supprimer une table :
|
Supprimer une table :
|
||||||
|
|
||||||
|
~~~
|
||||||
DROP TABLE test;
|
DROP TABLE test;
|
||||||
|
~~~
|
||||||
|
|
||||||
Supprimer une base de données :
|
Supprimer une base de données :
|
||||||
|
|
||||||
|
~~~
|
||||||
DROP DATABASE NOM_BASE;
|
DROP DATABASE NOM_BASE;
|
||||||
|
~~~
|
||||||
|
|
||||||
# Monitoring
|
# Monitoring
|
||||||
|
|
||||||
Pour surveiller un service MySQL en production, on pourra faire :
|
Pour surveiller un service MySQL en production, on pourra faire :
|
||||||
|
|
||||||
|
~~~
|
||||||
# mysqladmin status
|
# mysqladmin status
|
||||||
# mysqladmin extended-status
|
# mysqladmin extended-status
|
||||||
# mysqladmin processlist
|
# mysqladmin processlist
|
||||||
|
~~~
|
||||||
|
|
||||||
Pour avoir une version plus conviviale et dynamique des process en cours, on utilisera l'indispensable outil `mytop`.
|
Pour avoir une version plus conviviale et dynamique des process en cours, on utilisera l'indispensable outil `mytop`.
|
||||||
|
|
||||||
|
~~~
|
||||||
# aptitude install mytop
|
# aptitude install mytop
|
||||||
|
~~~
|
||||||
|
|
||||||
On édite le fichier `/root/.mytop` ainsi :
|
On édite le fichier `/root/.mytop` ainsi :
|
||||||
|
|
||||||
|
~~~{.ini}
|
||||||
user = debian-sys-maint
|
user = debian-sys-maint
|
||||||
pass = MOT_DE_PASSE
|
pass = MOT_DE_PASSE
|
||||||
db = mysql
|
db = mysql
|
||||||
|
~~~
|
||||||
|
|
||||||
Reste plus qu'à lancer la commande `mytop -s1` (pour un rafraichissement toutes les secondes)… On appréciera les raccourcis `p` (mettre en pause l'affichage), `o` (pour voir en 1er les requêtes les plus longues), `k` (pour killer une requête… par exemple celle qui bloque toutes les autres) et `?` (pour voir les autres raccourcis possibles).
|
Reste plus qu'à lancer la commande `mytop -s1` (pour un rafraichissement toutes les secondes)… On appréciera les raccourcis `p` (mettre en pause l'affichage), `o` (pour voir en 1er les requêtes les plus longues), `k` (pour killer une requête… par exemple celle qui bloque toutes les autres) et `?` (pour voir les autres raccourcis possibles).
|
||||||
|
|
||||||
L'outil mytop se sert principalement de la requête `SHOW PROCESSLIST` que l'on pourra bien sûr lancer manuellement. Tout comme `KILL` :
|
L'outil mytop se sert principalement de la requête `SHOW PROCESSLIST` que l'on pourra bien sûr lancer manuellement. Tout comme `KILL` :
|
||||||
|
|
||||||
|
~~~
|
||||||
mysql> SHOW PROCESSLIST;
|
mysql> SHOW PROCESSLIST;
|
||||||
mysql> KILL <id_interne_requête>;
|
mysql> KILL <id_interne_requête>;
|
||||||
|
~~~
|
||||||
|
|
||||||
Lister les requêtes qui durent plus de 30 secondes pour pouvoir les tuer facilement :
|
Lister les requêtes qui durent plus de 30 secondes pour pouvoir les tuer facilement :
|
||||||
|
|
||||||
mysql -e 'select group_concat(concat("kill ",ID) separator ";") from information_schema.processlist where TIME>=30;'
|
~~~
|
||||||
|
mysql -e 'select group_concat(concat("kill ",ID) separator ";") from information_schema.processlist where TIME>=30;'
|
||||||
|
~~~
|
||||||
|
|
||||||
Puis exécuter le résultat avec la commande mysql, ex :
|
Puis exécuter le résultat avec la commande mysql, ex :
|
||||||
|
|
||||||
mysql -e 'kill 1854;kill 1853;kill 1852;kill 1851;kill 1850;kill 1848'
|
~~~
|
||||||
|
mysql -e 'kill 1854;kill 1853;kill 1852;kill 1851;kill 1850;kill 1848'
|
||||||
|
~~~
|
||||||
|
|
||||||
Pour surveiller le moteur InnoDB, on utilisera la commande suivante :
|
Pour surveiller le moteur InnoDB, on utilisera la commande suivante :
|
||||||
|
|
||||||
|
~~~
|
||||||
mysql> SHOW ENGINE INNODB STATUS;
|
mysql> SHOW ENGINE INNODB STATUS;
|
||||||
|
~~~
|
||||||
|
|
||||||
Enfin, reste Munin qui permet d'obtenir de jolis graphes.
|
Enfin, reste Munin qui permet d'obtenir de jolis graphes.
|
||||||
|
|
||||||
Afin d'être alerté en cas de soucis, il est conseillé d'ajouter la configuration suivante au logiciel `log2mail` :
|
Afin d'être alerté en cas de soucis, il est conseillé d'ajouter la configuration suivante au logiciel `log2mail` :
|
||||||
|
|
||||||
|
~~~
|
||||||
|
file = /var/log/syslog
|
||||||
|
pattern = "should be repaired"
|
||||||
|
mailto = ADRESSE-MAIL-ALERTE
|
||||||
|
template = /etc/log2mail/template.mysql
|
||||||
|
|
||||||
file = /var/log/syslog
|
file = /var/log/syslog
|
||||||
pattern = "should be repaired"
|
pattern = "try to repair it"
|
||||||
mailto = ADRESSE-MAIL-ALERTE
|
mailto = ADRESSE-MAIL-ALERTE
|
||||||
template = /etc/log2mail/template.mysql
|
template = /etc/log2mail/template.mysql
|
||||||
|
|
||||||
file = /var/log/syslog
|
|
||||||
pattern = "try to repair it"
|
|
||||||
mailto = ADRESSE-MAIL-ALERTE
|
|
||||||
template = /etc/log2mail/template.mysql
|
|
||||||
|
|
||||||
file = /var/log/syslog
|
|
||||||
pattern = "InnoDB: Fatal error"
|
|
||||||
mailto = ADRESSE-MAIL-ALERTE
|
|
||||||
template = /etc/log2mail/template.mysql
|
|
||||||
|
|
||||||
file = /var/log/syslog
|
|
||||||
pattern = "as a STORAGE ENGINE failed"
|
|
||||||
mailto = ADRESSE-MAIL-ALERTE
|
|
||||||
template = /etc/log2mail/template.mysql
|
|
||||||
|
|
||||||
|
file = /var/log/syslog
|
||||||
|
pattern = "InnoDB: Fatal error"
|
||||||
|
mailto = ADRESSE-MAIL-ALERTE
|
||||||
|
template = /etc/log2mail/template.mysql
|
||||||
|
|
||||||
|
file = /var/log/syslog
|
||||||
|
pattern = "as a STORAGE ENGINE failed"
|
||||||
|
mailto = ADRESSE-MAIL-ALERTE
|
||||||
|
template = /etc/log2mail/template.mysql
|
||||||
|
~~~
|
||||||
|
|
||||||
Le fichier `/etc/log2mail/template.mysql` contenant :
|
Le fichier `/etc/log2mail/template.mysql` contenant :
|
||||||
|
|
||||||
|
~~~
|
||||||
|
From: %f
|
||||||
|
To: %t
|
||||||
|
Subject: MySQL problem
|
||||||
|
|
||||||
From: %f
|
Hello!
|
||||||
To: %t
|
|
||||||
Subject: MySQL problem
|
|
||||||
|
|
||||||
Hello!
|
We have matched your pattern "%m" in "%F" %n times:
|
||||||
|
|
||||||
We have matched your pattern "%m" in "%F" %n times:
|
%l
|
||||||
|
|
||||||
%l
|
|
||||||
|
|
||||||
Yours,
|
|
||||||
log2mail.
|
|
||||||
|
|
||||||
|
Yours,
|
||||||
|
log2mail.
|
||||||
|
~~~
|
||||||
|
|
||||||
Note : il faut ajouter l'utilisateur `log2mail` dans le groupe `adm`.
|
Note : il faut ajouter l'utilisateur `log2mail` dans le groupe `adm`.
|
||||||
|
|
||||||
|
@ -947,41 +960,46 @@ soit un résultat quasi-instantané..
|
||||||
|
|
||||||
On peut avoir des stats sur ce _Query Cache_ :
|
On peut avoir des stats sur ce _Query Cache_ :
|
||||||
|
|
||||||
|
~~~
|
||||||
mysql> SHOW STATUS LIKE 'Qcache%';
|
mysql> SHOW STATUS LIKE 'Qcache%';
|
||||||
+-------------------------+-----------+
|
+-------------------------+-----------+
|
||||||
| Variable_name | Value |
|
| Variable_name | Value |
|
||||||
+-------------------------+-----------+
|
+-------------------------+-----------+
|
||||||
| Qcache_free_blocks | 28 |
|
| Qcache_free_blocks | 28 |
|
||||||
| Qcache_free_memory | 242412400 |
|
| Qcache_free_memory | 242412400 |
|
||||||
| Qcache_hits | 226483735 |
|
| Qcache_hits | 226483735 |
|
||||||
| Qcache_inserts | 22334124 |
|
| Qcache_inserts | 22334124 |
|
||||||
| Qcache_lowmem_prunes | 5337097 |
|
| Qcache_lowmem_prunes | 5337097 |
|
||||||
| Qcache_not_cached | 3323695 |
|
| Qcache_not_cached | 3323695 |
|
||||||
| Qcache_queries_in_cache | 4229 |
|
| Qcache_queries_in_cache | 4229 |
|
||||||
| Qcache_total_blocks | 8919 |
|
| Qcache_total_blocks | 8919 |
|
||||||
+-------------------------+-----------+
|
+-------------------------+-----------+
|
||||||
8 rows in set (0.00 sec)
|
8 rows in set (0.00 sec)
|
||||||
|
~~~
|
||||||
|
|
||||||
On peut vider ce cache ainsi :
|
On peut vider ce cache ainsi :
|
||||||
|
|
||||||
mysql> RESET QUERY CACHE;
|
~~~
|
||||||
Query OK, 0 rows affected (0.00 sec)
|
mysql> RESET QUERY CACHE;
|
||||||
|
Query OK, 0 rows affected (0.00 sec)
|
||||||
|
~~~
|
||||||
|
|
||||||
# tmpdir
|
# tmpdir
|
||||||
|
|
||||||
Il peut être intéressant de changer le chemin du tmpdir pour le mettre sur un disque plus rapide ou plus gros par exemple.
|
Il peut être intéressant de changer le chemin du tmpdir pour le mettre sur un disque plus rapide ou plus gros par exemple.
|
||||||
|
|
||||||
# mkdir /ssd/mysqltmp
|
~~~
|
||||||
# chown mysql: /ssd/mysqltmp
|
# mkdir /ssd/mysqltmp
|
||||||
# chmod 700 /ssd/mysqltmp
|
# chown mysql: /ssd/mysqltmp
|
||||||
|
# chmod 700 /ssd/mysqltmp
|
||||||
|
~~~
|
||||||
|
|
||||||
Puis dans /etc/mysql/my.cnf.
|
Puis dans /etc/mysql/my.cnf.
|
||||||
|
|
||||||
-tmpdir = /tmp
|
~~~{.diff}
|
||||||
+tmpdir = /ssd/mysqltmp
|
-tmpdir = /tmp
|
||||||
|
+tmpdir = /ssd/mysqltmp
|
||||||
|
~~~
|
||||||
|
|
||||||
|
|
||||||
# Gestion des binlogs
|
# Gestion des binlogs
|
||||||
|
@ -992,14 +1010,14 @@ Par défaut, MySQL stocke chaque requête en écriture dans des fichiers appelé
|
||||||
|
|
||||||
Par défaut les binlogs sont conservés sur 10 jours, avec des fichiers n'excédant pas 100 Mo :
|
Par défaut les binlogs sont conservés sur 10 jours, avec des fichiers n'excédant pas 100 Mo :
|
||||||
|
|
||||||
|
~~~{.ini}
|
||||||
#log_bin = /var/log/mysql/mysql-bin.log
|
#log_bin = /var/log/mysql/mysql-bin.log
|
||||||
expire_logs_days = 10
|
expire_logs_days = 10
|
||||||
max_binlog_size = 100M
|
max_binlog_size = 100M
|
||||||
#binlog_do_db = include_database_name
|
#binlog_do_db = include_database_name
|
||||||
#binlog_ignore_db = include_database_name
|
#binlog_ignore_db = include_database_name
|
||||||
binlog_format = mixed
|
binlog_format = mixed
|
||||||
|
~~~
|
||||||
|
|
||||||
## Format
|
## Format
|
||||||
|
|
||||||
|
@ -1007,70 +1025,70 @@ http://dev.mysql.com/doc/refman/5.5/en/binary-log-setting.html
|
||||||
|
|
||||||
On peut choisir 3 types de format pour les binlogs :
|
On peut choisir 3 types de format pour les binlogs :
|
||||||
|
|
||||||
* `statement` : les requêtes INSERT / UPDATE sont conservées
|
* **statement** : les requêtes INSERT / UPDATE sont conservées
|
||||||
* `row` : les modifications de chaque ligne sont conservées (via une sorte de code "binaire" propre à MySQL)
|
* **row** : les modifications de chaque ligne sont conservées (via une sorte de code "binaire" propre à MySQL)
|
||||||
* `mixed` : en mode statement… sauf dans certains cas où cela passe en mode row
|
* **mixed** : en mode statement… sauf dans certains cas où cela passe en mode row
|
||||||
|
|
||||||
Avantages et inconvénients :
|
Avantages et inconvénients :
|
||||||
|
|
||||||
Le mode `statement` est utile pour conserver en clair toutes les requêtes. Il permet aussi de meilleures performances quand des UPDATE contiennent des clauses WHERE qui modifient de nombreuses lignes.
|
Le mode **statement** est utile pour conserver en clair toutes les requêtes. Il permet aussi de meilleures performances quand des UPDATE contiennent des clauses WHERE qui modifient de nombreuses lignes.
|
||||||
Pour de la réplication, il peut être non fiable car le résultat d'un UPDATE peut donner des résultats différents sur un serveur SLAVE. Cela peut aussi poser des soucis avec les transactions InnoDB.
|
Pour de la réplication, il peut être non fiable car le résultat d'un UPDATE peut donner des résultats différents sur un serveur SLAVE. Cela peut aussi poser des soucis avec les transactions InnoDB.
|
||||||
|
|
||||||
Le mode `row` a l'inconvénient de rendre illisibles toutes les requêtes. Dans certains cas particuliers (UPDATE contiennent des clauses WHERE qui modifient de nombreuses lignes), il peut être moins performant.
|
Le mode **row** a l'inconvénient de rendre illisibles toutes les requêtes. Dans certains cas particuliers (UPDATE contiennent des clauses WHERE qui modifient de nombreuses lignes), il peut être moins performant.
|
||||||
Il a l'avantage d'être plus fiable pour de la réplication.
|
Il a l'avantage d'être plus fiable pour de la réplication.
|
||||||
|
|
||||||
Le mode `mixed` est un bon compromis pour de la réplication : il permet de voir la plupart des requêtes en clair, mais évite le problème de fiabilité en passant en mode row quand c'est nécessaire.
|
Le mode **mixed** est un bon compromis pour de la réplication : il permet de voir la plupart des requêtes en clair, mais évite le problème de fiabilité en passant en mode row quand c'est nécessaire.
|
||||||
|
|
||||||
## Suppression
|
## Suppression
|
||||||
|
|
||||||
Pour supprimer les binlogs antérieurs à *mysql-bin.00NNNN* :
|
Pour supprimer les binlogs antérieurs à `mysql-bin.00NNNN` :
|
||||||
|
|
||||||
|
|
||||||
mysql> PURGE BINARY LOGS TO 'mysql-bin.00NNNN';
|
|
||||||
|
|
||||||
|
~~~
|
||||||
|
mysql> PURGE BINARY LOGS TO `mysql-bin.00NNNN`;
|
||||||
|
~~~
|
||||||
|
|
||||||
ou par rapport à une date :
|
ou par rapport à une date :
|
||||||
|
|
||||||
|
~~~
|
||||||
mysql> PURGE BINARY LOGS BEFORE "2011-12-07 00:00:00";
|
mysql> PURGE BINARY LOGS BEFORE "2011-12-07 00:00:00";
|
||||||
|
~~~
|
||||||
|
|
||||||
## Désactivation
|
## Désactivation
|
||||||
|
|
||||||
Pour désactiver les binlogs, on ajoutera l'option suivante dans la configuration :
|
Pour désactiver les binlogs, on ajoutera l'option suivante dans la configuration :
|
||||||
|
|
||||||
|
~~~
|
||||||
disable-log-bin
|
disable-log-bin
|
||||||
|
~~~
|
||||||
|
|
||||||
## Lecture
|
## Lecture
|
||||||
|
|
||||||
On pourra lire en ligne de commande le contenu d'un binlog via la commande :
|
On pourra lire en ligne de commande le contenu d'un binlog via la commande :
|
||||||
|
|
||||||
|
~~~
|
||||||
# mysqlbinlog /var/log/mysql/mysql-bin.001789 | less
|
# mysqlbinlog /var/log/mysql/mysql-bin.001789 | less
|
||||||
|
~~~
|
||||||
|
|
||||||
Note : si vous obtenez une erreur `mysqlbinlog: unknown variable 'default-character-set=utf8'` c'est que la directive `default-character-set`
|
Note : si vous obtenez une erreur `mysqlbinlog: unknown variable 'default-character-set=utf8'` c'est que la directive `default-character-set`
|
||||||
a été placée dans la configuration MySQL (`/etc/mysql` ou `.my.cnf`) dans la mauvaise section : `[client]` au lieu de `[mysql]` (ou `[mysqldump]`).
|
a été placée dans la configuration MySQL (`/etc/mysql` ou `.my.cnf`) dans la mauvaise section : `[client]` au lieu de `[mysql]` (ou `[mysqldump]`).
|
||||||
|
|
||||||
## Replay
|
## Replay
|
||||||
|
|
||||||
ATTENTION, CES MANIPULATIONS PEUVENT ÊTRE DANGEREUSES VOS DONNÉES, BIEN SAVOIR CE QUE L'ON FAIT.
|
**ATTENTION, CES MANIPULATIONS PEUVENT ÊTRE DANGEREUSES VOS DONNÉES, BIEN SAVOIR CE QUE L'ON FAIT.**
|
||||||
|
|
||||||
On pourra ainsi injecter le contenu d'un binlog dans une base… tout simplement avec une commande du type :
|
On pourra ainsi injecter le contenu d'un binlog dans une base… tout simplement avec une commande du type :
|
||||||
|
|
||||||
|
~~~
|
||||||
# mysqlbinlog /var/log/mysql/mysql-bin.001789 | mysql -P3307
|
# mysqlbinlog /var/log/mysql/mysql-bin.001789 | mysql -P3307
|
||||||
|
~~~
|
||||||
|
|
||||||
À noter que si une partie des données étaient déjà présentes (cas d'un binlog corrompu lors d'incident lors d'une réplication), on pourra procéder ainsi :
|
À noter que si une partie des données étaient déjà présentes (cas d'un binlog corrompu lors d'incident lors d'une réplication), on pourra procéder ainsi :
|
||||||
|
|
||||||
|
~~~
|
||||||
# mysqlbinlog /var/log/mysql/mysql-bin.001789 > mysql-bin.001789.txt
|
# mysqlbinlog /var/log/mysql/mysql-bin.001789 > mysql-bin.001789.txt
|
||||||
# sed -i 's/INSERT INTO/INSERT IGNORE INTO/gi' mysql-bin.001789.txt
|
# sed -i 's/INSERT INTO/INSERT IGNORE INTO/gi' mysql-bin.001789.txt
|
||||||
# cat mysql-bin.001789.txt | mysql -P3307
|
# cat mysql-bin.001789.txt | mysql -P3307
|
||||||
|
~~~
|
||||||
|
|
||||||
|
|
||||||
# Log des requêtes lentes
|
# Log des requêtes lentes
|
||||||
|
@ -1078,11 +1096,11 @@ On pourra ainsi injecter le contenu d'un binlog dans une base… tout simplement
|
||||||
Pour débugger les applications lentes, c'est une fonctionnalité intéressante de trouver quel requête est longue.
|
Pour débugger les applications lentes, c'est une fonctionnalité intéressante de trouver quel requête est longue.
|
||||||
Pour cela on peut spécifier quand une requêtes est considéré comme longue, le chemin où stocker les requêtes, et l'activation des logs.
|
Pour cela on peut spécifier quand une requêtes est considéré comme longue, le chemin où stocker les requêtes, et l'activation des logs.
|
||||||
|
|
||||||
|
~~~{.ini}
|
||||||
long_query_time = 2 #Default 10 !
|
long_query_time = 2 #Default 10 !
|
||||||
slow_query_log = 1
|
slow_query_log = 1
|
||||||
slow_query_log_file = /var/log/mysql/slow.log
|
slow_query_log_file = /var/log/mysql/slow.log
|
||||||
|
~~~
|
||||||
|
|
||||||
# Réplication MySQL
|
# Réplication MySQL
|
||||||
|
|
||||||
|
@ -1092,8 +1110,9 @@ Pour cela on peut spécifier quand une requêtes est considéré comme longue, l
|
||||||
|
|
||||||
Dans le cas où le futur master est en production et ne peut être arrété :
|
Dans le cas où le futur master est en production et ne peut être arrété :
|
||||||
|
|
||||||
# mysqldump --master-data --all-databases > mysql.dump
|
~~~
|
||||||
|
# mysqldump --master-data --all-databases > mysql.dump
|
||||||
|
~~~
|
||||||
|
|
||||||
`--master-data` ajoute un `CHANGE MASTER TO` dans le dump contenant les informations nécessaires au slave sur les logs (nom de fichier et position). Cette option implique `--lock-all-tables` qui bloquera toutes les tables pendant le dump.
|
`--master-data` ajoute un `CHANGE MASTER TO` dans le dump contenant les informations nécessaires au slave sur les logs (nom de fichier et position). Cette option implique `--lock-all-tables` qui bloquera toutes les tables pendant le dump.
|
||||||
|
|
||||||
|
@ -1111,21 +1130,22 @@ Dans le cas où le futur master est en production et ne peut être arrété :
|
||||||
|
|
||||||
* Sur le serveur B (le _slave_ en mode master-slave), exécuter :
|
* Sur le serveur B (le _slave_ en mode master-slave), exécuter :
|
||||||
|
|
||||||
|
~~~
|
||||||
CHANGE MASTER TO
|
CHANGE MASTER TO
|
||||||
MASTER_HOST='$MASTER_IP',
|
MASTER_HOST='$MASTER_IP',
|
||||||
MASTER_USER='repl',
|
MASTER_USER='repl',
|
||||||
MASTER_PASSWORD='XXX',
|
MASTER_PASSWORD='XXX',
|
||||||
MASTER_LOG_FILE='mysql-bin.NNNNNN',
|
MASTER_LOG_FILE='mysql-bin.NNNNNN',
|
||||||
MASTER_LOG_POS=NNN;
|
MASTER_LOG_POS=NNN;
|
||||||
|
~~~
|
||||||
|
|
||||||
/!\\ Bien que non obligatoire, il est recommandé de toujours indiquer les directives MASTER_LOG_FILE et MASTER_LOG_POS /!\\
|
/!\\ Bien que non obligatoire, il est recommandé de toujours indiquer les directives MASTER_LOG_FILE et MASTER_LOG_POS /!\\
|
||||||
|
|
||||||
* Pour exclure une base de la réplication, dans `/etc/mysql/my.cnf` :
|
* Pour exclure une base de la réplication, dans `/etc/mysql/my.cnf` :
|
||||||
|
|
||||||
binlog-ignore-db = mysql
|
~~~
|
||||||
|
binlog-ignore-db = mysql
|
||||||
|
~~~
|
||||||
|
|
||||||
* Puis démarrer la réplication sur le serveur B avec la commande : `START SLAVE`
|
* Puis démarrer la réplication sur le serveur B avec la commande : `START SLAVE`
|
||||||
|
|
||||||
|
@ -1135,36 +1155,34 @@ Dans le cas où le futur master est en production et ne peut être arrété :
|
||||||
|
|
||||||
Pour supprimer toute trace de réplication (sauf si des infos sont en dur dans la configuration) :
|
Pour supprimer toute trace de réplication (sauf si des infos sont en dur dans la configuration) :
|
||||||
|
|
||||||
|
~~~
|
||||||
mysql> RESET SLAVE;
|
mysql> RESET SLAVE;
|
||||||
Query OK, 0 rows affected (0.00 sec)
|
Query OK, 0 rows affected (0.00 sec)
|
||||||
|
~~~
|
||||||
|
|
||||||
Pour éviter que la réplication démarre automatiquement au démarrage, on ajoutera dans la configuration :
|
Pour éviter que la réplication démarre automatiquement au démarrage, on ajoutera dans la configuration :
|
||||||
|
|
||||||
|
~~~
|
||||||
skip-slave-start
|
skip-slave-start
|
||||||
|
~~~
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Trucs et astuces pour la réplication MySQL
|
## Trucs et astuces pour la réplication MySQL
|
||||||
|
|
||||||
Astuce 0 : Une astuce parfois très utile est la possibilité d'exécuter des requêtes qui ne seront pas prises en compte
|
**Astuce 0** : Une astuce parfois très utile est la possibilité d'exécuter des requêtes qui ne seront pas prises en compte
|
||||||
par le binlog (et donc non répliquée !). Cela nécessite le droit SUPER :
|
par le binlog (et donc non répliquée !). Cela nécessite le droit SUPER :
|
||||||
|
|
||||||
|
~~~
|
||||||
|
mysql> SET sql_log_bin = 0;
|
||||||
|
~~~
|
||||||
|
|
||||||
mysql> SET sql_log_bin = 0;
|
**Astuce 1** : Pour divers raisons (notamment la réplication de données déjà répliquées !), on devra activer l'option
|
||||||
|
|
||||||
|
|
||||||
Astuce 1 : Pour divers raisons (notamment la réplication de données déjà répliquées !), on devra activer l'option
|
|
||||||
suivante dans le my.cnf :
|
suivante dans le my.cnf :
|
||||||
|
|
||||||
|
~~~
|
||||||
|
log-slave-updates
|
||||||
|
~~~
|
||||||
|
|
||||||
log-slave-updates
|
**Astuce 2** : Sauter une requête déjà présente dans les binlog sur le slave (à tester) :
|
||||||
|
|
||||||
|
|
||||||
Astuce 2 : Sauter une requête déjà présente dans les binlog sur le slave (à tester) :
|
|
||||||
https://stackoverflow.com/questions/17701524/mysql-replication-skip-statement-is-it-possible
|
https://stackoverflow.com/questions/17701524/mysql-replication-skip-statement-is-it-possible
|
||||||
|
|
||||||
## Etapes supplémentaires pour une réplication master-master
|
## Etapes supplémentaires pour une réplication master-master
|
||||||
|
@ -1173,7 +1191,7 @@ https://stackoverflow.com/questions/17701524/mysql-replication-skip-statement-is
|
||||||
|
|
||||||
* Positionner la directive `auto-increment-offset` avec une valeur numérique différente sur chaque serveur
|
* Positionner la directive `auto-increment-offset` avec une valeur numérique différente sur chaque serveur
|
||||||
|
|
||||||
Exemple : `auto-increment-offset 2` sur le serveur B
|
Exemple : `auto-increment-offset 2` sur le serveur B
|
||||||
|
|
||||||
* Effectuer l'étape _Activation_ dans le sens A->B et B->A
|
* Effectuer l'étape _Activation_ dans le sens A->B et B->A
|
||||||
|
|
||||||
|
@ -1217,8 +1235,9 @@ avec la commande `START SLAVE`. Voici quelques erreurs possibles
|
||||||
|
|
||||||
Il faut alors stopper le processus slave de réplication :
|
Il faut alors stopper le processus slave de réplication :
|
||||||
|
|
||||||
mysql> STOP SLAVE;
|
~~~
|
||||||
|
mysql> STOP SLAVE;
|
||||||
|
~~~
|
||||||
|
|
||||||
Puis éditer (en gardant une sauvegarde) le fichier `${datadir}/relay-log.info`. La première ligne correspond au Relay_Log_File, la seconde au `Relay_Log_Pos`.
|
Puis éditer (en gardant une sauvegarde) le fichier `${datadir}/relay-log.info`. La première ligne correspond au Relay_Log_File, la seconde au `Relay_Log_Pos`.
|
||||||
Redémarrer MySQL.
|
Redémarrer MySQL.
|
||||||
|
@ -1234,12 +1253,10 @@ L'outil vérifie l'intégrité de la réplication en effectuant des requêtes de
|
||||||
|
|
||||||
La méthode la plus simple pour l'utiliser est d'autoriser le master à se connecter au slave (authentification MySQL). Ainsi, il s'occupe lui même de faire le nécessaire pour identifier les erreurs. Il suffira donc de lancer la commande sans argument pour qu'il identifie les incohérences. On pourra réaliser un cron avec l'argument `-q` qui ne fait remonter que les erreurs.
|
La méthode la plus simple pour l'utiliser est d'autoriser le master à se connecter au slave (authentification MySQL). Ainsi, il s'occupe lui même de faire le nécessaire pour identifier les erreurs. Il suffira donc de lancer la commande sans argument pour qu'il identifie les incohérences. On pourra réaliser un cron avec l'argument `-q` qui ne fait remonter que les erreurs.
|
||||||
|
|
||||||
|
~~~
|
||||||
|
MAILTO=jdoe@exemple.com
|
||||||
MAILTO=jdoe@exemple.com
|
42 9 * * 7 pt-table-checksum -q
|
||||||
42 9 * * 7 pt-table-checksum -q
|
~~~
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### pt-table-sync
|
### pt-table-sync
|
||||||
|
|
||||||
|
@ -1247,16 +1264,16 @@ Si pt-table-checksum vous a remonté des incohérences, vous pouvez avec cet out
|
||||||
|
|
||||||
Exemple :
|
Exemple :
|
||||||
|
|
||||||
|
~~~
|
||||||
# pt-table-sync --print --replicate percona.checksums localhost
|
# pt-table-sync --print --replicate percona.checksums localhost
|
||||||
# pt-table-sync --execute --replicate percona.checksums localhost
|
# pt-table-sync --execute --replicate percona.checksums localhost
|
||||||
|
~~~
|
||||||
|
|
||||||
En cas de `Can't make changes on the master because no unique index exists`. On peut synchroniser directement les différences sur le slave depuis le master.
|
En cas de `Can't make changes on the master because no unique index exists`. On peut synchroniser directement les différences sur le slave depuis le master.
|
||||||
|
|
||||||
|
~~~
|
||||||
# pt-table-sync --execute --no-check-slave localhost slave
|
# pt-table-sync --execute --no-check-slave localhost slave
|
||||||
|
~~~
|
||||||
|
|
||||||
|
|
||||||
# Diagnostic des erreurs
|
# Diagnostic des erreurs
|
||||||
|
@ -1265,18 +1282,18 @@ En cas de `Can't make changes on the master because no unique index exists`. On
|
||||||
|
|
||||||
Si vous obtenez des erreurs de ce type, lors d'un mysqldump par exemple :
|
Si vous obtenez des erreurs de ce type, lors d'un mysqldump par exemple :
|
||||||
|
|
||||||
|
~~~
|
||||||
mysqldump: Got error: 1016: Can't open file: './db/table.frm' (errno: 24) when using LOCK TABLES
|
mysqldump: Got error: 1016: Can't open file: './db/table.frm' (errno: 24) when using LOCK TABLES
|
||||||
mysqldump: Got error: 23: Out of resources when opening file '.\db\table.MYD' (Errcode: 24) when using LOCK TABLES
|
mysqldump: Got error: 23: Out of resources when opening file '.\db\table.MYD' (Errcode: 24) when using LOCK TABLES
|
||||||
|
~~~
|
||||||
|
|
||||||
C'est que votre serveur MySQL tente d'ouvrir trop de fichiers simultanément.
|
C'est que votre serveur MySQL tente d'ouvrir trop de fichiers simultanément.
|
||||||
|
|
||||||
Pour augmenter le nombre maximal de fichiers pouvant être ouverts, vous pouvez ajuster le paramètre suivant dans la section `[mysqld]` du fichier `my.cnf`, dans la limite permise par votre système d'exploitation :
|
Pour augmenter le nombre maximal de fichiers pouvant être ouverts, vous pouvez ajuster le paramètre suivant dans la section `[mysqld]` du fichier `my.cnf`, dans la limite permise par votre système d'exploitation :
|
||||||
|
|
||||||
|
~~~
|
||||||
open_files_limit = 2048
|
open_files_limit = 2048
|
||||||
|
~~~
|
||||||
|
|
||||||
La valeur par défaut étant de 1024.
|
La valeur par défaut étant de 1024.
|
||||||
|
|
||||||
|
@ -1286,34 +1303,34 @@ Note : inutile de positionner une valeur pour `ulimit -n` dans les scripts de d
|
||||||
|
|
||||||
Si vous obtenez l'erreur suivante lors d'un mysqldump :
|
Si vous obtenez l'erreur suivante lors d'un mysqldump :
|
||||||
|
|
||||||
|
~~~
|
||||||
mysqldump: Error 2020: Got packet bigger than 'max_allowed_packet' bytes when dumping table `mytable` at row: 6542
|
mysqldump: Error 2020: Got packet bigger than 'max_allowed_packet' bytes when dumping table `mytable` at row: 6542
|
||||||
|
~~~
|
||||||
|
|
||||||
Augmentez la valeur de `max_allowed_packet` dans la section `[mysqldump]` du fichier `my.cnf` :
|
Augmentez la valeur de `max_allowed_packet` dans la section `[mysqldump]` du fichier `my.cnf` :
|
||||||
|
|
||||||
|
~~~{.ini}
|
||||||
[mysqldump]
|
[mysqldump]
|
||||||
max_allowed_packet = 64M
|
max_allowed_packet = 64M
|
||||||
|
~~~
|
||||||
|
|
||||||
## Error 1267
|
## Error 1267
|
||||||
|
|
||||||
Si vous obtenez une erreur du type :
|
Si vous obtenez une erreur du type :
|
||||||
|
|
||||||
|
~~~
|
||||||
ERROR 1267 (HY000): Illegal mix of collations (binary,IMPLICIT) and (utf8_bin,NONE) for operation 'like'
|
ERROR 1267 (HY000): Illegal mix of collations (binary,IMPLICIT) and (utf8_bin,NONE) for operation 'like'
|
||||||
|
~~~
|
||||||
|
|
||||||
C'est qu'il y a souci entre votre charset client (`character_set_client`, `collation_connection`) et votre requête.
|
C'est qu'il y a souci entre votre charset client (`character_set_client`, `collation_connection`) et votre requête.
|
||||||
Vous pouvez les ajuster avec des commandes du type :
|
Vous pouvez les ajuster avec des commandes du type :
|
||||||
|
|
||||||
|
~~~
|
||||||
mysql> set character_set_client=utf8;
|
mysql> set character_set_client=utf8;
|
||||||
Query OK, 0 rows affected (0.00 sec)
|
Query OK, 0 rows affected (0.00 sec)
|
||||||
mysql> set collation_connection=utf8_unicode_ci;
|
mysql> set collation_connection=utf8_unicode_ci;
|
||||||
Query OK, 0 rows affected (0.00 sec)
|
Query OK, 0 rows affected (0.00 sec)
|
||||||
|
~~~
|
||||||
|
|
||||||
Dans certain cas (création d'une vue par exemple), cela peut venir d'une version de MySQL trop ancienne
|
Dans certain cas (création d'une vue par exemple), cela peut venir d'une version de MySQL trop ancienne
|
||||||
(on a constaté des requêtes qui passaient en 5.1 mais pas en 5.0).
|
(on a constaté des requêtes qui passaient en 5.1 mais pas en 5.0).
|
||||||
|
@ -1322,12 +1339,12 @@ Dans certain cas (création d'une vue par exemple), cela peut venir d'une versio
|
||||||
|
|
||||||
Si vous avez des erreurs de ce type :
|
Si vous avez des erreurs de ce type :
|
||||||
|
|
||||||
|
~~~
|
||||||
[ERROR] Column count of mysql.db is wrong. Expected 22, found 20. The table is probably corrupted
|
[ERROR] Column count of mysql.db is wrong. Expected 22, found 20. The table is probably corrupted
|
||||||
[ERROR] mysql.user has no `Event_priv` column at position 29
|
[ERROR] mysql.user has no `Event_priv` column at position 29
|
||||||
[ERROR] Event Scheduler: An error occurred when initializing system tables. Disabling the Event Scheduler.
|
[ERROR] Event Scheduler: An error occurred when initializing system tables. Disabling the Event Scheduler.
|
||||||
[ERROR] Column count of mysql.proc is wrong. Expected 20, found 16. The table is probably corrupted
|
[ERROR] Column count of mysql.proc is wrong. Expected 20, found 16. The table is probably corrupted
|
||||||
|
~~~
|
||||||
|
|
||||||
Cela signifie que les tables de la base `mysql` ne correspondent pas à la version de MySQL en cours.
|
Cela signifie que les tables de la base `mysql` ne correspondent pas à la version de MySQL en cours.
|
||||||
Vous avez sûrement mis à jour MySQL ou réinjecter des données d'une autre base.
|
Vous avez sûrement mis à jour MySQL ou réinjecter des données d'une autre base.
|
||||||
|
@ -1340,21 +1357,21 @@ En cas de souci lors de la connexion en ligne de commande MySQL,
|
||||||
vous pouvez désactiver la complétion automatique. En effet, cette
|
vous pouvez désactiver la complétion automatique. En effet, cette
|
||||||
complétion peut créer de soucis si certaines tables sont corrompues :
|
complétion peut créer de soucis si certaines tables sont corrompues :
|
||||||
|
|
||||||
|
~~~
|
||||||
$ mysql --skip-auto-rehash
|
$ mysql --skip-auto-rehash
|
||||||
|
~~~
|
||||||
|
|
||||||
## InnoDB: ERROR: the age of the last checkpoint is NNNNN
|
## InnoDB: ERROR: the age of the last checkpoint is NNNNN
|
||||||
|
|
||||||
Si vous avez une erreur du type :
|
Si vous avez une erreur du type :
|
||||||
|
|
||||||
|
~~~
|
||||||
mysqld: 120313 12:16:10 InnoDB: ERROR: the age of the last checkpoint is 9433587,
|
mysqld: 120313 12:16:10 InnoDB: ERROR: the age of the last checkpoint is 9433587,
|
||||||
mysqld: InnoDB: which exceeds the log group capacity 9433498.
|
mysqld: InnoDB: which exceeds the log group capacity 9433498.
|
||||||
mysqld: InnoDB: If you are using big BLOB or TEXT rows, you must set the
|
mysqld: InnoDB: If you are using big BLOB or TEXT rows, you must set the
|
||||||
mysqld: InnoDB: combined size of log files at least 10 times bigger than the
|
mysqld: InnoDB: combined size of log files at least 10 times bigger than the
|
||||||
mysqld: InnoDB: largest such row.
|
mysqld: InnoDB: largest such row.
|
||||||
|
~~~
|
||||||
|
|
||||||
Il faut augmenter le log InnoDB, notamment _innodb_log_file_size''. Attention, il faudra ensuite stopper MySQL et effacer les fichiers ''ib_logfile*_ !
|
Il faut augmenter le log InnoDB, notamment _innodb_log_file_size''. Attention, il faudra ensuite stopper MySQL et effacer les fichiers ''ib_logfile*_ !
|
||||||
Pour plus de détails, voir :
|
Pour plus de détails, voir :
|
||||||
|
@ -1365,40 +1382,40 @@ et http://dev.mysql.com/doc/refman/5.1/en/innodb-parameters.html
|
||||||
|
|
||||||
Si vous obtenez une erreur du type :
|
Si vous obtenez une erreur du type :
|
||||||
|
|
||||||
|
~~~
|
||||||
|
InnoDB: Error: trying to load index PRIMARY for table foo/bar
|
||||||
|
InnoDB: but the index tree has been freed!
|
||||||
|
121222 11:28:48 - mysqld got signal 11;
|
||||||
|
This could be because you hit a bug. It is also possible that this binary
|
||||||
|
or one of the libraries it was linked against is corrupt, improperly built,
|
||||||
|
or misconfigured. This error can also be caused by malfunctioning hardware.
|
||||||
|
We will try our best to scrape up some info that will hopefully help diagnose
|
||||||
|
the problem, but since we have already crashed, something is definitely wrong
|
||||||
|
and this may fail.
|
||||||
|
|
||||||
InnoDB: Error: trying to load index PRIMARY for table foo/bar
|
key_buffer_size=713031680
|
||||||
InnoDB: but the index tree has been freed!
|
read_buffer_size=131072
|
||||||
121222 11:28:48 - mysqld got signal 11;
|
max_used_connections=31
|
||||||
This could be because you hit a bug. It is also possible that this binary
|
max_connections=384
|
||||||
or one of the libraries it was linked against is corrupt, improperly built,
|
threads_connected=29
|
||||||
or misconfigured. This error can also be caused by malfunctioning hardware.
|
It is possible that mysqld could use up to
|
||||||
We will try our best to scrape up some info that will hopefully help diagnose
|
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_connections = 1531901 K
|
||||||
the problem, but since we have already crashed, something is definitely wrong
|
bytes of memory
|
||||||
and this may fail.
|
Hope that's ok; if not, decrease some variables in the equation.
|
||||||
|
|
||||||
key_buffer_size=713031680
|
|
||||||
read_buffer_size=131072
|
|
||||||
max_used_connections=31
|
|
||||||
max_connections=384
|
|
||||||
threads_connected=29
|
|
||||||
It is possible that mysqld could use up to
|
|
||||||
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_connections = 1531901 K
|
|
||||||
bytes of memory
|
|
||||||
Hope that's ok; if not, decrease some variables in the equation.
|
|
||||||
|
|
||||||
thd=0x84dc0a0
|
|
||||||
Attempting backtrace. You can use the following information to find out
|
|
||||||
where mysqld died. If you see no messages after this, something went
|
|
||||||
terribly wrong…
|
|
||||||
Cannot determine thread, fp=0x84dc0a0, backtrace may not be correct.
|
|
||||||
Bogus stack limit or frame pointer, fp=0x84dc0a0, stack_bottom=0x44660000, thread_stack=196608, aborting backtrace.
|
|
||||||
Trying to get some variables.
|
|
||||||
Some pointers may be invalid and cause the dump to abort…
|
|
||||||
thd->query at 0x7f0d9c284ba0 is invalid pointer
|
|
||||||
thd->thread_id=355
|
|
||||||
The manual page at http://www.mysql.com/doc/en/Crashing.html contains
|
|
||||||
information that should help you find out what is causing the crash.
|
|
||||||
|
|
||||||
|
thd=0x84dc0a0
|
||||||
|
Attempting backtrace. You can use the following information to find out
|
||||||
|
where mysqld died. If you see no messages after this, something went
|
||||||
|
terribly wrong…
|
||||||
|
Cannot determine thread, fp=0x84dc0a0, backtrace may not be correct.
|
||||||
|
Bogus stack limit or frame pointer, fp=0x84dc0a0, stack_bottom=0x44660000, thread_stack=196608, aborting backtrace.
|
||||||
|
Trying to get some variables.
|
||||||
|
Some pointers may be invalid and cause the dump to abort…
|
||||||
|
thd->query at 0x7f0d9c284ba0 is invalid pointer
|
||||||
|
thd->thread_id=355
|
||||||
|
The manual page at http://www.mysql.com/doc/en/Crashing.html contains
|
||||||
|
information that should help you find out what is causing the crash.
|
||||||
|
~~~
|
||||||
|
|
||||||
Cela semble être une table corrompue, et a priori il faut réinstaurer la table concernée.
|
Cela semble être une table corrompue, et a priori il faut réinstaurer la table concernée.
|
||||||
Se connecter en ligne de commande avec l'option `mysql --skip-auto-rehash` puis
|
Se connecter en ligne de commande avec l'option `mysql --skip-auto-rehash` puis
|
||||||
|
@ -1416,11 +1433,11 @@ et supprimer le fichier `.frm` correspondant ! Néanmoins la table sera
|
||||||
toujours référencée par InnoDB, et vous devez créer un `.frm` simple
|
toujours référencée par InnoDB, et vous devez créer un `.frm` simple
|
||||||
pour tromper le moteur :
|
pour tromper le moteur :
|
||||||
|
|
||||||
|
~~~
|
||||||
mysql> create table foo(foo int) ENGINE=InnoDB;
|
mysql> create table foo(foo int) ENGINE=InnoDB;
|
||||||
# /etc/init.d/mysql stop
|
# /etc/init.d/mysql stop
|
||||||
# cp /var/lib/mysql/foo/foo.frm /var/lib/mysql/foo/TABLE.frm
|
# cp /var/lib/mysql/foo/foo.frm /var/lib/mysql/foo/TABLE.frm
|
||||||
|
~~~
|
||||||
|
|
||||||
Quelques informations supplémentaire sur :
|
Quelques informations supplémentaire sur :
|
||||||
http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting-datadict.html
|
http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting-datadict.html
|
||||||
|
@ -1439,12 +1456,12 @@ Une fois créée, vous devez voir les clés avec un `SHOW CREATE TABLE`.
|
||||||
|
|
||||||
Si le service MySQL/InnoDB refuse de démarrer à cause d'une erreur du type :
|
Si le service MySQL/InnoDB refuse de démarrer à cause d'une erreur du type :
|
||||||
|
|
||||||
|
~~~
|
||||||
mysqld: InnoDB: Starting in background the rollback of uncommitted transactions
|
mysqld: InnoDB: Starting in background the rollback of uncommitted transactions
|
||||||
mysqld: 140130 16:01:44 InnoDB: Rolling back trx with id 13B87781, 3 rows to undo
|
mysqld: 140130 16:01:44 InnoDB: Rolling back trx with id 13B87781, 3 rows to undo
|
||||||
mysqld: 140130 16:01:44 InnoDB: Assertion failure in thread 140516188849920 in file fut0lst.ic line 83
|
mysqld: 140130 16:01:44 InnoDB: Assertion failure in thread 140516188849920 in file fut0lst.ic line 83
|
||||||
mysqld: InnoDB: Failing assertion: addr.page == FIL_NULL || addr.boffset >= FIL_PAGE_DATA
|
mysqld: InnoDB: Failing assertion: addr.page == FIL_NULL || addr.boffset >= FIL_PAGE_DATA
|
||||||
|
~~~
|
||||||
|
|
||||||
C'est que la base est corrompue…
|
C'est que la base est corrompue…
|
||||||
|
|
||||||
|
@ -1452,10 +1469,10 @@ Il faut sauvegarder le datadir. Puis tenter de redémarrer avec l'option `innodb
|
||||||
puis `innodb_force_recovery=2` puis `innodb_force_recovery=3` etc. jusqu'à ce que le service démarre.
|
puis `innodb_force_recovery=2` puis `innodb_force_recovery=3` etc. jusqu'à ce que le service démarre.
|
||||||
Attention, à partir de `innodb_force_recovery=3` vous devrez sûrement ajouter `innodb_purge_threads=0` :
|
Attention, à partir de `innodb_force_recovery=3` vous devrez sûrement ajouter `innodb_purge_threads=0` :
|
||||||
|
|
||||||
|
~~~
|
||||||
innodb_force_recovery = 3
|
innodb_force_recovery = 3
|
||||||
innodb_purge_threads = 0
|
innodb_purge_threads = 0
|
||||||
|
~~~
|
||||||
|
|
||||||
Dès que le service démarre (il sera peut être en read-only), faites un dump de toutes vos bases MySQL.
|
Dès que le service démarre (il sera peut être en read-only), faites un dump de toutes vos bases MySQL.
|
||||||
|
|
||||||
|
@ -1468,42 +1485,44 @@ Voir http://dev.mysql.com/doc/refman/5.5/en/forcing-innodb-recovery.html
|
||||||
|
|
||||||
Si vous obtenez des erreurs de ce type :
|
Si vous obtenez des erreurs de ce type :
|
||||||
|
|
||||||
|
~~~
|
||||||
mysqld: #007/usr/sbin/mysqld: File '/var/log/mysql/mysql-bin.005655' not found (Errcode: 13)
|
mysqld: #007/usr/sbin/mysqld: File '/var/log/mysql/mysql-bin.005655' not found (Errcode: 13)
|
||||||
mysqld: 130202 19:49:05 [ERROR] Failed to open log (file '/var/log/mysql/mysql-bin.005655', errno 13)
|
mysqld: 130202 19:49:05 [ERROR] Failed to open log (file '/var/log/mysql/mysql-bin.005655', errno 13)
|
||||||
mysqld: 130202 19:49:05 [ERROR] Could not open log file
|
mysqld: 130202 19:49:05 [ERROR] Could not open log file
|
||||||
mysqld: 130202 19:49:05 [ERROR] Can't init tc log
|
mysqld: 130202 19:49:05 [ERROR] Can't init tc log
|
||||||
mysqld: 130202 19:49:05 [ERROR] Aborting
|
mysqld: 130202 19:49:05 [ERROR] Aborting
|
||||||
|
~~~
|
||||||
|
|
||||||
C'est que MySQL n'arrive pas à accéder au dernier binlog. Cela peut par exemple
|
C'est que MySQL n'arrive pas à accéder au dernier binlog. Cela peut par exemple
|
||||||
être une question de droits. Pour vérifier que tout est correct, faire :
|
être une question de droits. Pour vérifier que tout est correct, faire :
|
||||||
|
|
||||||
|
~~~
|
||||||
# sudo -u mysql head /var/log/mysql/mysql-bin.00NNNN
|
# sudo -u mysql head /var/log/mysql/mysql-bin.00NNNN
|
||||||
|
~~~
|
||||||
|
|
||||||
Une erreur étrange mais classique est que le fichier binlog prenne les droits de root.
|
Une erreur étrange mais classique est que le fichier binlog prenne les droits de root.
|
||||||
On le corrigera ainsi :
|
On le corrigera ainsi :
|
||||||
|
|
||||||
|
~~~
|
||||||
# chown mysql:adm /var/log/mysql/mysql-bin.00NNNN
|
# chown mysql:adm /var/log/mysql/mysql-bin.00NNNN
|
||||||
|
~~~
|
||||||
|
|
||||||
## `ERROR 130 (HY000): Incorrect file format '[…]'`
|
## `ERROR 130 (HY000): Incorrect file format '[…]'`
|
||||||
|
|
||||||
Si vous obtenez l'erreur ci-dessus, lors d'un mysqldump par exemple, et que les fichier ${mysql_datadir}/base/table.{MYD,MYI} sont vides mais pas le .frm, il faut réparer la table comme ceci :
|
Si vous obtenez l'erreur ci-dessus, lors d'un mysqldump par exemple, et que les fichier ${mysql_datadir}/base/table.{MYD,MYI} sont vides mais pas le .frm, il faut réparer la table comme ceci :
|
||||||
|
|
||||||
# mysqlcheck --auto-repair --check --use-frm <base> <table>
|
~~~
|
||||||
|
# mysqlcheck --auto-repair --check --use-frm <base> <table>
|
||||||
|
~~~
|
||||||
|
|
||||||
## `is blocked because of many connection errors.`
|
## `is blocked because of many connection errors.`
|
||||||
|
|
||||||
Blocage pour l'IP car nombreuses erreurs sur BD. Lié à la valeur de la variable `max_connect_errors`.
|
Blocage pour l'IP car nombreuses erreurs sur BD. Lié à la valeur de la variable `max_connect_errors`.
|
||||||
Pour résoudre la situation :
|
Pour résoudre la situation :
|
||||||
|
|
||||||
# mysqladmin flush-hosts
|
~~~
|
||||||
|
# mysqladmin flush-hosts
|
||||||
|
~~~
|
||||||
|
|
||||||
# Instances MySQL
|
# Instances MySQL
|
||||||
|
|
||||||
|
@ -1511,121 +1530,131 @@ Pour résoudre la situation :
|
||||||
|
|
||||||
Avant toute opération, il est nécessaire de commenter cette ligne dans le `/etc/mysql/my.cnf` :
|
Avant toute opération, il est nécessaire de commenter cette ligne dans le `/etc/mysql/my.cnf` :
|
||||||
|
|
||||||
#user = mysql
|
~~~{.ini}
|
||||||
|
#user = mysql
|
||||||
|
~~~
|
||||||
|
|
||||||
et de rajouter ces lignes (à voir l'utilité en fait…)
|
et de rajouter ces lignes (à voir l'utilité en fait…)
|
||||||
|
|
||||||
[mysqld_multi]
|
~~~{.ini}
|
||||||
user = mysqladmin
|
[mysqld_multi]
|
||||||
|
user = mysqladmin
|
||||||
|
~~~
|
||||||
|
|
||||||
Créez un utilisateur pour l'instance (il doit avoir un shell valide comme /bin/sh) :
|
Créez un utilisateur pour l'instance (il doit avoir un shell valide comme /bin/sh) :
|
||||||
|
|
||||||
useradd mysql-INSTANCE_NAME
|
~~~
|
||||||
|
useradd mysql-INSTANCE_NAME
|
||||||
|
~~~
|
||||||
|
|
||||||
Créez ensuite le "datadir" :
|
Créez ensuite le "datadir" :
|
||||||
|
|
||||||
# mysql_install_db --datadir=/home/mysql/INSTANCE_NAME
|
~~~
|
||||||
# chown -R mysql-INSTANCE_NAME:mysql-INSTANCE_NAME /home/mysql/INSTANCE_NAME
|
# mysql_install_db --datadir=/home/mysql/INSTANCE_NAME
|
||||||
# chmod 700 /home/mysql/INSTANCE_NAME
|
# chown -R mysql-INSTANCE_NAME:mysql-INSTANCE_NAME /home/mysql/INSTANCE_NAME
|
||||||
|
# chmod 700 /home/mysql/INSTANCE_NAME
|
||||||
|
~~~
|
||||||
|
|
||||||
NOTE : Sous Debian Etch, l'option `--user` n'est pas présente.
|
NOTE : Sous Debian Etch, l'option `--user` n'est pas présente.
|
||||||
|
|
||||||
Ajoutez ces lignes dans `/etc/mysql/my.cnf` :
|
Ajoutez ces lignes dans `/etc/mysql/my.cnf` :
|
||||||
|
|
||||||
[mysqld1]
|
~~~{.ini}
|
||||||
mysqld = /usr/bin/mysqld_safe
|
[mysqld1]
|
||||||
user = mysql-INSTANCE_NAME
|
mysqld = /usr/bin/mysqld_safe
|
||||||
port = 3307
|
user = mysql-INSTANCE_NAME
|
||||||
socket = /var/run/mysqld-INSTANCE_NAME/mysqld.sock
|
port = 3307
|
||||||
pid-file = /var/run/mysqld-INSTANCE_NAME/mysqld.pid
|
socket = /var/run/mysqld-INSTANCE_NAME/mysqld.sock
|
||||||
datadir = /home/mysql-INSTANCE_NAME
|
pid-file = /var/run/mysqld-INSTANCE_NAME/mysqld.pid
|
||||||
|
datadir = /home/mysql-INSTANCE_NAME
|
||||||
|
~~~
|
||||||
|
|
||||||
|
**Note 1** : même si l'on ne prévoit pas de faire tourner le mysqld principal sur le port 3306,
|
||||||
Note : même si l'on ne prévoit pas de faire tourner le mysqld principal sur le port 3306,
|
|
||||||
on préfèrera tout de même utiliser le port 3307 pour la première instance afin de ne pas
|
on préfèrera tout de même utiliser le port 3307 pour la première instance afin de ne pas
|
||||||
confondre une configuration avec et sans instance.
|
confondre une configuration avec et sans instance.
|
||||||
|
|
||||||
Note 2 : dans le cas où une réplication est déjà active sur l'intance principale, la nouvelle instance créée va automatiquement hériter des paramètres de réplication.
|
**Note 2** : dans le cas où une réplication est déjà active sur l'intance principale, la nouvelle instance créée va automatiquement hériter des paramètres de réplication.
|
||||||
Pour éviter ça, il suffit de rajouter :
|
Pour éviter ça, il suffit de rajouter :
|
||||||
|
|
||||||
[mysqld1]
|
~~~{.ini}
|
||||||
…
|
[mysqld1]
|
||||||
skip-slave-start
|
…
|
||||||
|
skip-slave-start
|
||||||
|
~~~
|
||||||
|
|
||||||
Créez le répertoire qui contiendra le socket et le fichier PID :
|
Créez le répertoire qui contiendra le socket et le fichier PID :
|
||||||
|
|
||||||
mkdir /var/run/mysqld-INSTANCE_NAME
|
~~~
|
||||||
chown mysql-INSTANCE_NAME:mysql-INSTANCE_NAME /var/run/mysqld-INSTANCE_NAME
|
mkdir /var/run/mysqld-INSTANCE_NAME
|
||||||
|
chown mysql-INSTANCE_NAME:mysql-INSTANCE_NAME /var/run/mysqld-INSTANCE_NAME
|
||||||
|
~~~
|
||||||
|
|
||||||
Puis lancez la nouvelle instance :
|
Puis lancez la nouvelle instance :
|
||||||
|
|
||||||
# mysqld_multi start 1
|
~~~
|
||||||
|
# mysqld_multi start 1
|
||||||
|
~~~
|
||||||
|
|
||||||
Enfin, n'oubliez pas de définir un mot de passe root/mysqladmin pour la nouvelle instance !
|
Enfin, n'oubliez pas de définir un mot de passe root/mysqladmin pour la nouvelle instance !
|
||||||
|
|
||||||
Pour voir l'état des instances :
|
Pour voir l'état des instances :
|
||||||
|
|
||||||
# mysqld_multi report
|
~~~
|
||||||
|
# mysqld_multi report
|
||||||
|
~~~
|
||||||
|
|
||||||
Et pour stopper une instance, on évite la commande "mysqld_multi stop 1" qui n'est que rarement fiable et peut laisser l'instance dans un état incorrect, difficile à récupérer.
|
Et pour stopper une instance, on évite la commande "mysqld_multi stop 1" qui n'est que rarement fiable et peut laisser l'instance dans un état incorrect, difficile à récupérer.
|
||||||
|
|
||||||
On préfère passer la commande "shutdown" en interne :
|
On préfère passer la commande "shutdown" en interne :
|
||||||
|
|
||||||
# mysqladmin -P3307 shutdown
|
~~~
|
||||||
|
# mysqladmin -P3307 shutdown
|
||||||
|
~~~
|
||||||
Note : a priori cela revient à envoyer un signal SIGTERM (kill -15) au process mysqld
|
|
||||||
|
|
||||||
|
**Note** : a priori cela revient à envoyer un signal SIGTERM (kill -15) au process mysqld
|
||||||
|
|
||||||
## Nettoyage
|
## Nettoyage
|
||||||
|
|
||||||
Si le mysqld principal n'est pas utilisé, on désactivera le script d'init.d /etc/init.d/mysql (en ajoutant `exit 0`
|
Si le mysqld principal n'est pas utilisé, on désactivera le script d'init.d /etc/init.d/mysql (en ajoutant `exit 0`
|
||||||
au début du script ) et on pourra se créer un script `/etc/init.d/mysql-instance` du type :
|
au début du script ) et on pourra se créer un script `/etc/init.d/mysql-instance` du type :
|
||||||
|
|
||||||
|
~~~{.bash}
|
||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
### BEGIN INIT INFO
|
||||||
|
# Provides: mysql-instance
|
||||||
|
# Required-Start: $remote_fs $syslog
|
||||||
|
# Required-Stop: $remote_fs $syslog
|
||||||
|
# Should-Start: $network $time
|
||||||
|
# Should-Stop: $network $time
|
||||||
|
# Default-Start: 2 3 4 5
|
||||||
|
# Default-Stop: 0 1 6
|
||||||
|
# Short-Description: Start and stop the mysql database server daemon
|
||||||
|
# Description: Controls the main MySQL database server daemon "mysqld"
|
||||||
|
# and its wrapper script "mysqld_safe".
|
||||||
|
### END INIT INFO
|
||||||
|
#
|
||||||
|
set -e
|
||||||
|
set -u
|
||||||
|
|
||||||
#!/bin/sh
|
case "$1" in
|
||||||
#
|
start)
|
||||||
### BEGIN INIT INFO
|
mysqld_multi start
|
||||||
# Provides: mysql-instance
|
;;
|
||||||
# Required-Start: $remote_fs $syslog
|
stop)
|
||||||
# Required-Stop: $remote_fs $syslog
|
mysqld_multi stop
|
||||||
# Should-Start: $network $time
|
;;
|
||||||
# Should-Stop: $network $time
|
restart)
|
||||||
# Default-Start: 2 3 4 5
|
mysqld_multi stop
|
||||||
# Default-Stop: 0 1 6
|
mysqld_multi start
|
||||||
# Short-Description: Start and stop the mysql database server daemon
|
;;
|
||||||
# Description: Controls the main MySQL database server daemon "mysqld"
|
*)
|
||||||
# and its wrapper script "mysqld_safe".
|
echo "Usage: $0 {start|stop}"
|
||||||
### END INIT INFO
|
exit 1
|
||||||
#
|
esac
|
||||||
set -e
|
|
||||||
set -u
|
|
||||||
|
|
||||||
case "$1" in
|
|
||||||
start)
|
|
||||||
mysqld_multi start
|
|
||||||
;;
|
|
||||||
stop)
|
|
||||||
mysqld_multi stop
|
|
||||||
;;
|
|
||||||
restart)
|
|
||||||
mysqld_multi stop
|
|
||||||
mysqld_multi start
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Usage: $0 {start|stop}"
|
|
||||||
exit 1
|
|
||||||
esac
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
~~~
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1633,49 +1662,52 @@ au début du script ) et on pourra se créer un script `/etc/init.d/mysql-instan
|
||||||
|
|
||||||
Pour voir le statut de l'instance n°1, logiquement nommée mysqld1 (GNR=1) et tournant sur le port 3307 :
|
Pour voir le statut de l'instance n°1, logiquement nommée mysqld1 (GNR=1) et tournant sur le port 3307 :
|
||||||
|
|
||||||
|
~~~
|
||||||
# mysqld_multi report 1
|
# mysqld_multi report 1
|
||||||
Reporting MySQL servers
|
Reporting MySQL servers
|
||||||
MySQL server from group: mysqld1 is running
|
MySQL server from group: mysqld1 is running
|
||||||
|
~~~
|
||||||
|
|
||||||
Pour l'arrêter / redémarrer, même principe (attention, `mysqld_multi` est peu verbeux…) :
|
Pour l'arrêter / redémarrer, même principe (attention, `mysqld_multi` est peu verbeux…) :
|
||||||
|
|
||||||
|
~~~
|
||||||
# ps auwx | grep 3307
|
# ps auwx | grep 3307
|
||||||
# mysqladmin -P 3307 shutdown
|
# mysqladmin -P 3307 shutdown
|
||||||
# ps auwx | grep 3307
|
# ps auwx | grep 3307
|
||||||
# mysqld_multi start 1
|
# mysqld_multi start 1
|
||||||
# ps auwx | grep 3307
|
# ps auwx | grep 3307
|
||||||
|
~~~
|
||||||
|
|
||||||
# routines MySQL
|
# routines MySQL
|
||||||
|
|
||||||
|
~~~
|
||||||
mysql> select * from INFORMATION_SCHEMA.routines;
|
mysql> select * from INFORMATION_SCHEMA.routines;
|
||||||
|
~~~
|
||||||
|
|
||||||
# Changement mot de passe utilisateur
|
# Changement mot de passe utilisateur
|
||||||
|
|
||||||
|
~~~
|
||||||
> SET PASSWORD FOR 'user'@'hostname' = PASSWORD('pwd');
|
> SET PASSWORD FOR 'user'@'hostname' = PASSWORD('pwd');
|
||||||
|
~~~
|
||||||
|
|
||||||
Par rapport à un autre utilisateur:
|
Par rapport à un autre utilisateur:
|
||||||
|
|
||||||
> use mysql;
|
~~~
|
||||||
> UPDATE USER SET Password='XXXXX' WHERE User='XXXXX' and Host='XX.XX.XX.XX';
|
mysql> use mysql;
|
||||||
|
mysql> UPDATE USER SET Password='XXXXX' WHERE User='XXXXX' and Host='XX.XX.XX.XX';
|
||||||
|
~~~
|
||||||
|
|
||||||
# Changer variables global d'environnement
|
# Changer variables global d'environnement
|
||||||
|
|
||||||
|
~~~
|
||||||
> SET GLOBAL max_connect_errors=50;
|
mysql> SET GLOBAL max_connect_errors=50;
|
||||||
|
~~~
|
||||||
|
|
||||||
ou
|
ou
|
||||||
|
|
||||||
> SET @@max_connect_errors=50;
|
~~~
|
||||||
|
mysql> SET @@max_connect_errors=50;
|
||||||
|
~~~
|
||||||
|
|
||||||
# FAQ
|
# FAQ
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue