Petit script pour gérer le quotas sur les bases de données MySQL

Publié le 26 octobre 2008 par Mikebrant

Tout est dans le titre.
Un court article

On avait besoin de gérer le quotas de nos bases sur MySQL.
Si une base atteint le quotas maximal autorisé alors l'utilisateur lié perdra les droits d'insert, create, update.
Il nous faut pas grand chose pour gérer le quotas de nos base :
il nous suffit d'avoir une base : baseQuotas contenant la table table.
Celle-ci va contenir  5 champs:
- id : sans commentaire
- nomBase : le nom de la base ayant un quotas.
- quotas : la taille en octet autorisé pour la base. Si quotas vaut NULL alors la taille est illimitée.
- quotasAtteint : Si le quotas n'est pas atteint, vaut '0', sinon '1'.

Pour ce script, je me suis fortement inspiré de celui écrit en php , ici .
Mais comme il ne marchait pas, je l'ai refait en python.

Voici le script :

 #-*- coding:Utf-8 -*-
import MySQLdb
#CREATE TABLE IF NOT EXISTS `table` (
# `id` int(11) NOT NULL auto_increment,
# `user_id` int(11) NOT NULL,
# `nomBase` varchar(255) collate utf8_bin NOT NULL,
# `quotas` int(11) default NULL,
# `quotasAtteint` tinyint(4) NOT NULL,
# PRIMARY KEY (`id`)
#);
if __name__ == '__main__' :
   
  utilisateur = 'root'
  motDePasse = 'pass'
  serveurBDD = 'localhost'
  baseQuotas = 'base'
  table = 'table'
  port = 3306
   
  ##### on tente de se connecter au serveurBDD #####
  try :
  connexion = MySQLdb.connect(host = serveurBDD, user = utilisateur, passwd = motDePasse, port = port)
   
  except MySQLdb.OperationalError, erreur:
  print("Impossible de se connecter au serveur" )
  exit(0)
   
  ##### on checke la bdd contenant tous les quotas ####
  try:
  connexion.select_db(baseQuotas)
  except:
  print("La base " + base + " n'existe pas" )
  exit(0)
   
   
  ##### on va prendre toutes les bases des utilisateurs ainsi que leur quotas #####
  curseur = connexion.cursor() 
  maRequete = "SELECT nomBase,quotasAtteint, quotas FROM " + baseQuotas + "." + table 
   
  curseur.execute( maRequete ) #on éxécute notre requête
  mesBases = curseur.fetchall()
   
  ##### on va commencer par enlever ceux ayant un quotas sans limite : quotas == Null (None) #####
  mesBases = [ base for base in mesBases if base[2] ]
   
  ##### pour chaque base ayant un quotas, on va checker sa taille #####
  for base in mesBases:
  try:
  maRequete = "SELECT SUM(data_length) FROM INFORMATION_SCHEMA.tables WHERE table_schema='" + base[0] +"'"
  curseur.execute( maRequete )
  except:
  print("Version de MySQL trop ancienne")
  exit(0)
   
  taille = curseur.fetchone()[0]# on récupère la taille de la base
  if taille >= base[2] and not base[1] : #si la taille de la base a atteint le seuil critique pour la première fois
  maRequete = "UPDATE " + baseQuotas + "." + table + " SET quotasAtteint=1 WHERE nomBase ='" + base[0] + "'" #on met quotasAtteint à 1
  curseur.execute( maRequete )
   
  maRequete = "UPDATE mysql.db SET Insert_priv='N', Update_priv='N', Create_priv='N' WHERE Db='" + base[0] + "'" #et on réduit les privilèges de l'utilisateur
  curseur.execute( maRequete )
   
  curseur.execute(" FLUSH privileges")
   
  #si la taille est inférieure mais que quotasAtteint vaut 1 : on vient juste de revenir à la normale
  elif taille < base[2] and base[1] :
  maRequete = "UPDATE " + baseQuotas + "." + table + " SET quotasAtteint=0 WHERE nomBase ='" + base[0] + "'" #on met donc quotasAtteint à 0
  curseur.execute( maRequete )
   
  maRequete = "UPDATE mysql.db SET Insert_priv='Y', Update_priv='Y', Create_priv='Y' WHERE Db='" + base[0] + "'" #et on réactive les privilèges de l'utilisateur
  curseur.execute( maRequete )
   
  curseur.execute(" FLUSH privileges")

Mettez -le dans un cron et le tour est joué.