Affichage des articles dont le libellé est DBAdmin. Afficher tous les articles
Affichage des articles dont le libellé est DBAdmin. Afficher tous les articles

mardi 3 octobre 2017

Pense-bête - Commandes dans VIM


Voici les principales commandes de VIM


i           => Basculer dans le mot insertion
:q!         => Quitter sans enregistrer
:qw         => Quitter après l'enregistrement
:w          => Enregistrer le fichier
d$          => Supprime les données jusqu'à la fin de la ligne
dw          => Supprime les données jusqu'au prochain mot
de          => Supprime le mot courant
w           => Passer au mot suivant
2w          => Sauter deux mots
2dw         => Supprime les deux derniers mots
0           => Aller en début de ligne
u           => Annuler la dernière action
yy          => Copier la ligne
4yy         => Copier 4 lignes
p           => Coller après
P           => Insérer avant
Ctrl + R    => Annule la dernière annulation
Ctrl + Z    => Fermer
/           => Recherche
?           => Recherche dans le sens inverse
n           => Occurrence suivante

mardi 22 novembre 2016

Tables MyISAM - Recréer les index à partir des fichiers de structure (*.frm) et de données (*.MYD)

Que faire quand MySQL renvoie le code d'erreur #1017 ?

#1017 - Can't find file: 'ma_table' (errno: 2)
MySQL n'arrive pas à ouvrir l'un des fichiers de la structure d'une table MyISAM.

Un check de la table nous confirme le problème :

mysql> check table ma_table;
+-------------------+-------+----------+----------------------------------------+
| Table             | Op    | Msg_type | Msg_text                               |
+-------------------+-------+----------+----------------------------------------+
| ma_base.ma_table  | check | Error    | Can't find file: 'ma_table' (errno: 2) |
| ma_base.ma_table  | check | status   | Operation failed                       |
+-------------------+-------+----------+----------------------------------------+
2 rows in set (0.00 sec)


Rappel de la structure physique des tables MyISAM

Sur le plan physique, une table MyISAM est constituée de 3 fichiers :
  • La définition de la table : 'tbl_name.frm'
  • le fichier contenant les données 'tbl_name.MYD'
  • le fichier contenant les index 'tbl_name.MYI'
Dans notre cas, le fichier *.MYI n'existe plus ou n'existe pas (dans le cas d'une restauration d'un backup incomplet par exemple)

Réparer un table MyISAM corrompue



Comme le fichier *.MYI n'existe plus, on ne pourra pas utiliser l'utilitaire Myisamchk pour réparer cette table.

A la place, on utilisera la commande "REPAIR TABLE" de MySQL avec le mode "USE_FRM".

Ce mode est très utile dans le cas où, justement le fichier .MYI est manquant, ou erroné (entête corrompu par exemple).

Avec ce mode, MySQL va recréer intégralement le fichier d'index.MYI, en utilisant les informations du fichier .frm de la table et les données disponibles dans le fichier .MYD.


Syntaxe de la commande:
REPAIR TABLE tbl_name[,tbl_name...] [EXTENDED] [USE_FRM]

Test de réparation sur une table corrompue


mysql> repair table ma_table USE_FRM;
+-------------------+--------+----------+-------------------------------------+
| Table             | Op     | Msg_type | Msg_text                            |
+-------------------+--------+----------+-------------------------------------+
| ma_base.ma_table  | repair | warning  | Number of rows changed from 0 to 14 |
| ma_base.ma_table  | repair | status   | OK                                  |
+-------------------+--------+----------+-------------------------------------+
2 rows in set (0.01 sec)


La réparation est un succès !

Un check de la table nous le confirme :


mysql> check table ma_table;
+-------------------+-------+----------+----------+
| Table             | Op    | Msg_type | Msg_text |
+-------------------+-------+----------+----------+
| ma_base.ma_table  | check | status   | OK       |
+-------------------+-------+----------+----------+
1 row in set (0.00 sec)


Cette démarche est très utile. mais lorsque le problème se pose pour de nombreuses tables, il faut industrialiser le processus.

Réparer un ensemble de table MyISAM corrompues

On va écrire un petit script basé sur le procédé que l'on vient de décrire.

Ce scritp pourra être lancé directement depuis l'arborescence de MySQL.
A noter que le Serveur MySQL doit être en fonctionnement.

for i in `ls *.frm`
do
    # On récupère le nom de la table à partir du nom du fichier *.frm
    l=${#i}-4;
    n=${i:0:l};
  
    echo $n;

    # On lance la réparation et le check
    mysql -u root -pxxxxx -D YYYY -B -e "-- REPAIR TABLE $n USE_FRM; CHECK TABLE $n";
    # avec :
    # -B : Mode batch - Pas d'historique
    # -e : Execute la requete et quitte
done



La ligne de commande renvoie les résultats de l'opération :
ma_base.autre_table     repair  warning Number of rows changed from 0 to 73364
ma_base.
autre_table     repair  status  OK
ma_base.
autre_table     check  status  OK



Well done !



Il ne reste plus qu'a vérifier que tout s'est bien passé et finaliser les dernier détails comme régler la valeur de l'auto-incrément, perdu dans la bataille...

Puis on lance un optimize sur toute les tables
Reprendre le code et remplace la ligne de réparation par :

mysql -u root -pxxxxx -D YYYY -B -e "-- OPTIMIZE TABLE $n ;";

+----------------------+-------+----------+----------+
| ma_base.autre_table  | check | status   | OK       |
+----------------------+-------+----------+----------+


Pour finir, on recharge toutes les tables à l'aide de Flush tables;
On peut également finir l'opération par un restart du serveur MySQL!


Have Fun !

Liens :
- http://dev.mysql.com/doc/refman/5.0/fr/repair.html

- http://dev.mysql.com/doc/refman/5.0/fr/repair-table.html



vendredi 30 septembre 2016

PostGreSQL - How to stop a query

Afficher les processus en cours


SELECT * from pg_stat_activity; 

 datid |   datname   |  pid  | usesysid | usename  |          application_name           | client_addr | client_hostname | client_port |         backend_start         |          xact_start           |          query_start          |         state_change          | waiting | state  |                                                      query
-------+-------------+-------+----------+----------+-------------------------------------+-------------+-----------------+-------------+-------------------------------+-------------------------------+-------------------------------+-------------------------------+---------+--------+------------------------------------------------------------------------------------------------------------------
 12035 | postgres    | 21105 |    16384 | xxxxxxxx | pgAdmin III - Navigateur            | 127.0.0.1   |                 |       33104 | 2016-09-30 08:45:24.639032+02 |                               | 2016-09-30 08:45:32.628846+02 | 2016-09-30 08:45:32.629749+02 | f       | idle   | SELECT count(*) FROM pg_attribute WHERE attrelid = 'pg_catalog.pg_proc'::regclass AND attname = 'proargdefaults'



Stopper le processus concerné

  • Repérerer le pid de la requête à stopper
  • Utiliser la commande suivante :
SELECT pg_cancel_backend(pid of the postgres process);

dans notre exemple, c'est le processus 21105 qui doit être stoppé :
SELECT pg_cancel_backend(21105 );

Résultat :
 pg_cancel_backend
-------------------
 t
(1 ligne)




Have Fun !

mercredi 23 septembre 2015

Mémo PostGreSQL-PostGis

PostgreSQL

 

Mémo des principales commandes PostgreSQL

 

 

Créer un utilisateur PostgreSQL

1- Création de l'utilisateur + attribution mdp

CREATE USER mon_utilisateur WITH ENCRYPTED PASSWORD 'UnMotDePasseQuiDéchire';

2- Autoriser l'user à se connecter à une base spécifique (existante)

GRANT CONNECT ON DATABASE LaBase TO mon_utilisateur;

3- Droits génériques : accès au schéma public

REVOKE ALL ON SCHEMA public FROM mon_utilisateur;
GRANT USAGE ON SCHEMA public TO mon_utilisateur;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO mon_utilisateur;
GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO mon_utilisateur;
...

4- Ajuster les droits spécifiques d'un utilisateur

REVOKE ALL ON ALL TABLES IN SCHEMA mon_schéma FROM mon_utilisateur ;
GRANT SELECT ON ALL TABLES IN SCHEMA mon_schéma TO mon_utilisateur ;

En préparation :

Créer une base de données PostGresql
 

mercredi 6 juin 2012

Piwik error after update from 1.7.1 to 1.8.2

Erreur après la mise à jour de piwik depuis la version 1.7.1 vers 1.8.2


Une petite erreur rencontrée lors de la mise à jour automatique de piwik après la mise à jour de la base de données :

SQLSTATE[42000]: Syntax error or access violation: 1044 Access denied for user 'piwik'@'localhost' to database 'piwik'
 Go to Piwik
 Login
 Backtrace:

 #0 /var/www/piwik-1.5.1/core/PluginsFunctions/Sql.php(51): Zend_Db_Adapter_Pdo_Abstract->exec('LOCK TABLES pwk...')
 #1 /var/www/piwik-1.5.1/core/PluginsFunctions/Sql.php(205): Piwik_Sql::exec('LOCK TABLES pwk...')
 #2 /var/www/piwik-1.5.1/core/PluginsFunctions/Sql.php(359): Piwik_Sql::lockTables('pwk_archive_num...', 'pwk_archive_num...')
 #3 /var/www/piwik-1.5.1/core/ArchiveProcessing.php(688): Piwik_LockTables('pwk_archive_num...', 'pwk_archive_num...')
 #4 /var/www/piwik-1.5.1/core/ArchiveProcessing.php(533): Piwik_ArchiveProcessing->loadNextIdarchive()
 #5 /var/www/piwik-1.5.1/core/ArchiveProcessing.php(472): Piwik_ArchiveProcessing->initCompute()
 #6 /var/www/piwik-1.5.1/core/Archive/Single.php(226): Piwik_ArchiveProcessing->launchArchiving()
 #7 /var/www/piwik-1.5.1/core/Archive/Array/IndexedBySite.php(192): Piwik_Archive_Single->prepareArchive()
 #8 /var/www/piwik-1.5.1/core/Archive/Array/IndexedBySite.php(131): Piwik_Archive_Array_IndexedBySite->getArchiveIdsAfterLaunching(Array)
 #9 /var/www/piwik-1.5.1/core/Archive/Array/IndexedBySite.php(108): Piwik_Archive_Array_IndexedBySite->loadValuesFromDB(Array)
 #10 /var/www/piwik-1.5.1/core/Archive/Array/IndexedBySite.php(73): Piwik_Archive_Array_IndexedBySite->getValues(Array)
 #11 /var/www/piwik-1.5.1/plugins/MultiSites/API.php(120): Piwik_Archive_Array_IndexedBySite->getDataTableFromNumeric(Array)
 #12 /var/www/piwik-1.5.1/plugins/MultiSites/Controller.php(65): Piwik_MultiSites_API->getAll('day', '2012-06-06', false)
 #13 /var/www/piwik-1.5.1/plugins/MultiSites/Controller.php(37): Piwik_MultiSites_Controller->getSitesInfo(Object(Piwik_View))
 #14 [internal function]: Piwik_MultiSites_Controller->index()
 #15 /var/www/piwik-1.5.1/core/FrontController.php(138): call_user_func_array(Array, Array)
 #16 /var/www/piwik-1.5.1/index.php(53): Piwik_FrontController->dispatch()



La ligne #0 du log indique que l'utilisateur MySQL 'piwik' n'a pas le droit de poser de verrous (privilège '__LOCK TABLES__' ) sur les tables de la base 'piwik'.

Ce qui est normal puisque je ne lui ai pas donné ce droit ;)

Donc, en plus de privilèges existants, à savoir :
* SELECT
* INSERT
* UPDATE
* DELETE
* CREATE
* DROP
* INDEX
* ALTER
* CREATE VIEW
* SHOW VIEW

Il faut ajouter le privilège d'administration  LOCK TABLES  :

REVOKE ALL PRIVILEGES ON `piwik`.* FROM 'piwik'@'localhost';
 GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, LOCK TABLES, CREATE VIEW, SHOW VIEW
ON `piwik`.* TO 'piwik'@'localhost';

 
Et on oublie pas de recharger les privilèges, ca ne coute rien !
FLUSH PRIVILEGES ;
 
Et c'est reparti !

En résumé, il s'agit plus d'un problème de droits MySQL (un peu trop stricts) que d'un bug de Piwik. D’ailleurs, la FAQ de Piwik est claire sur ce point :

The Mysql USER should have the permission to SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER, LOCK.

Have fun !

mardi 24 avril 2012

Initialiser une base PostgreSQL/PostGIS

 

 

 

 

 

Prérequis

  • Une instance PostGreSQL fonctionnelle
  • Le cartouche PostGIS installé

Préparation de la base

su postgres
createdb mabase
createlang plpgsql mabase
psql -d mabase -f /path/to/postgresql/version/share/contrib/postgis.sql
psql -d mabase -f /path/to/postgresql/version/share/contrib/spatial_ref_sys.sql

Création des tables

psql mabase
CREATE TABLE test (id serial PRIMARY KEY,genre text);

Ajout de la colonne géométrique à la table - AddGeometryColumn()

Pour l'instant notre table est vide, nous allons lui ajouter une troisième colonne où seront stockées nos données géométriques.

Nous aurons recours pour cela à la fonction AddGeometryColumn() de PostGIS dont la synthaxe générale est :

AddGeometryColumn( Table, 
                    Colonne_Geometrique, 
                    SRID, 
                    Type_Geometrie, 
                    Dimension);
où
  • Table est le nom de la table à laquelle doit être ajoutée la colonne géométrique;
  • Colonne_Geometrique est le nom de la colonne géométrique;
  • Type_Geometrie est le le type de géométrie possible:
  • SRID est l'identifiant spatial de projection selon le système de projection choisi.
    A titre d'exemple pour le Lambert II Carto Etendu, srid=27852;
  • Dimension est la dimension des objets géométriques 2D ou 3D ou 4D;
Dans notre cas, nous saisirons :

SELECT AddGeometryColumn( 'test', 'geom', -1, 'GEOMETRY', 2 );
 
 
Avec cette requête, nous avons ajouté la Colonne géométrique geom à la Table 'test'.

Comme nous n'utilisons ici aucun système de projection référencé, nous restons donc dans le plan 2D orthonormal par défaut, nous précisons juste SRID=-1.

Le type de données géométriques (Type_Geometrie) que nous souhaitons enregistrer peut-être de n'importe quel type. Nous préciserons donc par défaut GEOMETRY.
Enfin, nous sommes en 2 Dimensions.

Note
Il aurait été tout à fait possible de créer la table test en faisant directement

CREATE TABLE test (id serial PRIMARY KEY,genre TEXT,geom GEOMETRY);

Mais il y aurait alors eu un perte concernant les méta-données sur les objets géométriques concernant le type, le srid, la dimension.
Il est donc préférable d'avoir recours à la fonction AddGeometryColumn() pour pouvoir tirer profit de ces métadonnées.

mercredi 16 mars 2011

MySQL - Créer une table de sauvegarde en SQL

Astuce MySQL pour créer rapidement, en SQL, une table de sauvegarde





SET @tableName = concat ('ma_table_bak_',DATE_FORMAT(now(), '%Y_%m_%d_%H_%i'));
SET @sql := CONCAT('CREATE TABLE ', @tableName,' LIKE `ma_table`;');
PREPARE mySt FROM @sql; 
EXECUTE mySt; SET @sql2 := CONCAT('INSERT INTO ', @tableName,' SELECT * FROM `ma_table`'); 
PREPARE mySt2 FROM @sql2;
EXECUTE mySt2;

mardi 20 avril 2010

Débordé



Pas trop le temps de bloguer en ce moment :
  • Formation Techniques de Virtualisation chez Linagora (fin mars)
  • Formation MySQL DBA chez Anaska (début avril - Sympa les grèves à la SNCF)
  • Tests de solutions Haute Disponibilité Linux : Kvm/QEmu,Xen - Ovirt - HeartBeat - DRBD - iScsi
Les autres formations arrivent :
  • Formation LPIC 102 + Certification LPIC 101 +102 chez Linagora (début juin)
  • Formation MySQL HA chez Anaska (en mai)
Fiouuuu !

J'en profite pour saluer mes co-formés et les formateurs !

jeudi 18 mars 2010

MySQL - Modifier le prompt du client

Logo MySQL, fév. 2010



Encore un billet de qualité sur dbnewz.com sur la personnalisation du prompt de Mysql.




Pour ma part, j'ajoute à mon /etc/my.cnf les directives suivantes :

 [mysql]                     // Section du client mysql
 prompt=(\\u@\\h) [\\d]>\\_  // Affiche un prompt indiquant l'utilisateur, la machine et la base courante
Plus d'info sur la page d'aide de la commande mysql
Happy MySQL !

mercredi 3 mars 2010

MySQL - Activer le cache de requêtes


Depuis la version 4.0.1, MySQL server bénéficie d'un cache de requêtes.

Si une requête identique est appelée par la suite, le serveur retournera le résultat à partir du cache plutôt que d'analyser puis exécuter la requête à nouveau.


Le cache de requêtes est extrêmement utile dans un environnement où les tables ne changent pas souvent, et que vous avez de nombreuses requêtes identiques.
C'est la situation classique des serveurs Web, qui génèrent beaucoup de pages dynamiques à partir du même contenu.

Utiliser le cache de requête est très utile si vous avez beaucoup de lecture et peu de modifications d'enregistrements. Ex: présentation de contenu dynamique sur un site web.

A Noter : Le cache est sensible à la casse : pour lui la requête Select * FROM ... est différente de ''SELECT * FROM ...'".
Les deux résultats, identiques, seront stockés dans le cache, alors soyez rigoureux dans votre code.

Par défaut, le cache de requêtes est paramétré à minima ...

mysql> SHOW VARIABLES LIKE 'have_query_cache';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| have_query_cache | YES   |
+------------------+-------+
1 row in set (0.00 sec)
 
...mais n'est pas actif :

mysql> SHOW STATUS LIKE 'Qcache%';
+-------------------------+-------+
| Variable_name           | Value | 
+-------------------------+-------+
| Qcache_free_blocks      | 0     | 
| Qcache_free_memory      | 0     | 
| Qcache_hits             | 0     | 
| Qcache_inserts          | 0     | 
| Qcache_lowmem_prunes    | 0     | 
| Qcache_not_cached       | 0     | 
| Qcache_queries_in_cache | 0     | 
| Qcache_total_blocks     | 0     | 
+-------------------------+-------+
8 rows in set (0.00 sec)

Pour l'activer, il faut passer quelques paramètres au serveur MySQL.

En ligne
C'est le mieux pour un serveur en production qui ne peut pas être redémarrer à la demande. De plus vous pouvez pouvez ajuster les valeur en fonctions de vos besoins.

mysql> SET GLOBAL query_cache_type = 1;
Query OK, 0 rows affected (0.00 sec) 

mysql> SET GLOBAL query_cache_limit=2097152;
Query OK, 0 rows affected (0.00 sec) 
 
mysql> SET GLOBAL query_cache_size=32M;
Query OK, 0 rows affected (0.00 sec)
 
Ces valeurs sont données à titre d'exemple. Je vous laisse le soin de les adapter à votre contexte.

On attend quelques minutes et on jette un oeil :

mysql> SHOW STATUS LIKE 'Qcache%';
+-------------------------+----------+
| Variable_name           | Value    |
+-------------------------+----------+
| Qcache_free_blocks      | 177      | // Nombre de blocs de mémoire libre dans la cache de requêtes. 
| Qcache_free_memory      | 32759616 | // Quantité de mémoire libre dans la cache de requêtes. 
| Qcache_hits             | 13238    | // Nombre de succès dans la cache. 
| Qcache_inserts          | 1599     | // Nombre de requêtes ajoutées à la cache. 
| Qcache_lowmem_prunes    | 0        | // Nombre de requêtes qui ont été retirées de la cache pour libérer de la mémoire afin de mettre en cache de nouvelles requêtes. Peut être utilisé afin de peaufiner la taille de la cache. La stratégie utilisée pour déterminer quelles requêtes seront retirées est LRU (least recently used).
| Qcache_not_cached       | 26       | // Nombre de requêtes non en cache (impossible à placer en cache, ou non cachée en raison du paramètre query_cache_type).
| Qcache_queries_in_cache | 548      | // Nombre de requêtes enregistrées dans la cache. 
| Qcache_total_blocks     | 1316     | // Nombre total de blocs dans la cache de requêtes. 
+-------------------------+----------+
8 rows in set (0.00 sec)
 
N'oubliez pas de sauvegarder vos réglages dans le fichier de conf de MySQL.

Au lancement du serveur
  • Editer le fichier de configuration /etc/my.cnf et ajouter les lignes suivantes:
#Query Cache
query_cache_type=1    // Cache all cacheable query results except for those that begin with SELECT SQL_NO_CACHE.
query_cache_limit=4M  // Don't cache results that are larger than this number of bytes. The default value is 1MB.
query_cache_size=8M   // The amount of memory allocated for caching query results. The default value is 0, which disables the query cache. The allowable values are multiples of 1024; other values are rounded down to the nearest multiple.
  • Redémarrer le serveur MySQL pour que les paramètres soient pris en compte.
Vous pouvez aussi ajouter des paramètres au lancement du daemon, mais ce n'est pas forcément une bonne idée car les scripts de démarrages sont écrasés à chaque mise à jour des paquets.

Reste à patienter quelques jours pour apprécier le résultat. Tunnez les paramètres si besoin !

Have Fun !

Pour aller plus loin :