#!/bin/bash # Script de migration d'une table de geosector vers geosector_app # Usage: ./migrate_table.sh [options] # Chemin du script SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" BASE_DIR="$(dirname "$SCRIPT_DIR")" LOG_DIR="$BASE_DIR/logs" CONFIG_FILE="$BASE_DIR/shell/db_config.sh" # Création du répertoire de logs si nécessaire mkdir -p "$LOG_DIR" # Fichier de log LOG_FILE="$LOG_DIR/migration_$(date +%Y-%m-%d).log" # Fonction de logging log_message() { local level="$1" local message="$2" local timestamp=$(date +"%Y-%m-%d %H:%M:%S") echo "[$timestamp] [$level] $message" | tee -a "$LOG_FILE" } # Vérification des arguments if [ -z "$1" ]; then log_message "ERROR" "Usage: $0 [options]" exit 1 fi TABLE_NAME="$1" log_message "INFO" "Démarrage de la migration de la table: $TABLE_NAME" # Charger la configuration de la base de données if [ -f "$CONFIG_FILE" ]; then source "$CONFIG_FILE" else # Configuration SSH par défaut SSH_HOST="serveur-distant.exemple.com" SSH_PORT="22" SSH_USER="utilisateur" SSH_KEY_FILE="/chemin/vers/cle_ssh" # Configuration de la base de données source (distante) REMOTE_DB_HOST="localhost" REMOTE_DB_PORT="3306" SOURCE_DB_HOST="localhost" SOURCE_DB_NAME="geosector" SOURCE_DB_USER="utilisateur_db" SOURCE_DB_PASS="mot_de_passe" SOURCE_DB_PORT="13306" # Configuration de la base de données cible (locale) TARGET_DB_HOST="localhost" TARGET_DB_NAME="geosector_app" TARGET_DB_USER="root" TARGET_DB_PASS="" TARGET_DB_PORT="3306" # Créer le fichier de configuration cat > "$CONFIG_FILE" << EOF #!/bin/bash # Configuration des bases de données pour les scripts de migration # Configuration SSH pour accéder au serveur distant SSH_HOST="serveur-distant.exemple.com" SSH_PORT="22" SSH_USER="utilisateur" SSH_KEY_FILE="/chemin/vers/cle_ssh" # Configuration de la base de données source (distante) REMOTE_DB_HOST="localhost" REMOTE_DB_PORT="3306" SOURCE_DB_HOST="localhost" SOURCE_DB_NAME="geosector" SOURCE_DB_USER="utilisateur_db" SOURCE_DB_PASS="mot_de_passe" SOURCE_DB_PORT="13306" # Configuration de la base de données cible (locale) TARGET_DB_HOST="localhost" TARGET_DB_NAME="geosector_app" TARGET_DB_USER="root" TARGET_DB_PASS="" TARGET_DB_PORT="3306" EOF chmod +x "$CONFIG_FILE" log_message "INFO" "Fichier de configuration créé: $CONFIG_FILE" fi # Fonction pour établir un tunnel SSH establish_ssh_tunnel() { # Vérifier si un tunnel SSH est déjà en cours d'exécution TUNNEL_RUNNING=$(ps aux | grep "ssh -f -N -L $SOURCE_DB_PORT:$REMOTE_DB_HOST:$REMOTE_DB_PORT" | grep -v grep) if [ -z "$TUNNEL_RUNNING" ]; then log_message "INFO" "Établissement d'un tunnel SSH vers $SSH_HOST..." ssh -f -N -L "$SOURCE_DB_PORT:$REMOTE_DB_HOST:$REMOTE_DB_PORT" -p "$SSH_PORT" "$SSH_USER@$SSH_HOST" -i "$SSH_KEY_FILE" if [ $? -ne 0 ]; then log_message "ERROR" "Impossible d'établir le tunnel SSH." return 1 fi # Attendre que le tunnel soit établi sleep 2 log_message "INFO" "Tunnel SSH établi sur le port local $SOURCE_DB_PORT" else log_message "INFO" "Un tunnel SSH est déjà en cours d'exécution" fi return 0 } # Fonction pour fermer le tunnel SSH close_ssh_tunnel() { log_message "INFO" "Fermeture du tunnel SSH..." TUNNEL_PID=$(ps aux | grep "ssh -f -N -L $SOURCE_DB_PORT:$REMOTE_DB_HOST:$REMOTE_DB_PORT" | grep -v grep | awk '{print $2}') if [ ! -z "$TUNNEL_PID" ]; then kill -9 "$TUNNEL_PID" 2>/dev/null log_message "INFO" "Tunnel SSH fermé" fi } # Établir le tunnel SSH establish_ssh_tunnel if [ $? -ne 0 ]; then log_message "ERROR" "Impossible de continuer sans tunnel SSH." exit 1 fi # Vérifier si la table existe dans la base source (via le tunnel SSH) TABLE_EXISTS=$(mysql -h"$SOURCE_DB_HOST" -P"$SOURCE_DB_PORT" -u"$SOURCE_DB_USER" -p"$SOURCE_DB_PASS" -D"$SOURCE_DB_NAME" -se "SHOW TABLES LIKE '$TABLE_NAME'") if [ -z "$TABLE_EXISTS" ]; then log_message "ERROR" "La table '$TABLE_NAME' n'existe pas dans la base source." close_ssh_tunnel exit 1 fi # Obtenir la structure de la table source (via le tunnel SSH) log_message "INFO" "Récupération de la structure de la table source..." mysql -h"$SOURCE_DB_HOST" -P"$SOURCE_DB_PORT" -u"$SOURCE_DB_USER" -p"$SOURCE_DB_PASS" -D"$SOURCE_DB_NAME" -e "SHOW CREATE TABLE $TABLE_NAME\G" > "$LOG_DIR/structure_source_$TABLE_NAME.sql" # Vérifier si la table existe dans la base cible TARGET_TABLE_EXISTS=$(mysql -h"$TARGET_DB_HOST" -P"$TARGET_DB_PORT" -u"$TARGET_DB_USER" -p"$TARGET_DB_PASS" -D"$TARGET_DB_NAME" -se "SHOW TABLES LIKE '$TABLE_NAME'") if [ -z "$TARGET_TABLE_EXISTS" ]; then log_message "WARNING" "La table '$TABLE_NAME' n'existe pas dans la base cible. Création de la table..." # Créer la table dans la base cible avec la même structure (source via SSH) mysql -h"$SOURCE_DB_HOST" -P"$SOURCE_DB_PORT" -u"$SOURCE_DB_USER" -p"$SOURCE_DB_PASS" -D"$SOURCE_DB_NAME" -e "SHOW CREATE TABLE $TABLE_NAME" | awk 'NR==2 {print $0}' | sed 's/CREATE TABLE/CREATE TABLE IF NOT EXISTS/g' > "$LOG_DIR/create_table_$TABLE_NAME.sql" mysql -h"$TARGET_DB_HOST" -P"$TARGET_DB_PORT" -u"$TARGET_DB_USER" -p"$TARGET_DB_PASS" -D"$TARGET_DB_NAME" < "$LOG_DIR/create_table_$TABLE_NAME.sql" fi # Exporter les données de la table source (via le tunnel SSH) log_message "INFO" "Exportation des données de la table source..." mysqldump -h"$SOURCE_DB_HOST" -P"$SOURCE_DB_PORT" -u"$SOURCE_DB_USER" -p"$SOURCE_DB_PASS" --no-create-info --skip-triggers "$SOURCE_DB_NAME" "$TABLE_NAME" > "$LOG_DIR/data_$TABLE_NAME.sql" # Vider la table cible (optionnel) read -p "Voulez-vous vider la table cible avant l'importation? (o/n): " TRUNCATE_TABLE if [[ "$TRUNCATE_TABLE" =~ ^[Oo]$ ]]; then log_message "INFO" "Vidage de la table cible..." mysql -h"$TARGET_DB_HOST" -P"$TARGET_DB_PORT" -u"$TARGET_DB_USER" -p"$TARGET_DB_PASS" -D"$TARGET_DB_NAME" -e "TRUNCATE TABLE $TABLE_NAME" fi # Importer les données dans la table cible log_message "INFO" "Importation des données dans la table cible..." mysql -h"$TARGET_DB_HOST" -P"$TARGET_DB_PORT" -u"$TARGET_DB_USER" -p"$TARGET_DB_PASS" "$TARGET_DB_NAME" < "$LOG_DIR/data_$TABLE_NAME.sql" # Vérifier le nombre d'enregistrements SOURCE_COUNT=$(mysql -h"$SOURCE_DB_HOST" -P"$SOURCE_DB_PORT" -u"$SOURCE_DB_USER" -p"$SOURCE_DB_PASS" -D"$SOURCE_DB_NAME" -se "SELECT COUNT(*) FROM $TABLE_NAME") TARGET_COUNT=$(mysql -h"$TARGET_DB_HOST" -P"$TARGET_DB_PORT" -u"$TARGET_DB_USER" -p"$TARGET_DB_PASS" -D"$TARGET_DB_NAME" -se "SELECT COUNT(*) FROM $TABLE_NAME") log_message "INFO" "Nombre d'enregistrements dans la table source: $SOURCE_COUNT" log_message "INFO" "Nombre d'enregistrements dans la table cible: $TARGET_COUNT" if [ "$SOURCE_COUNT" -eq "$TARGET_COUNT" ]; then log_message "SUCCESS" "Migration réussie! Tous les enregistrements ont été transférés." else log_message "WARNING" "Le nombre d'enregistrements diffère entre les tables source et cible." fi log_message "INFO" "Migration terminée pour la table: $TABLE_NAME" # Fermer le tunnel SSH à la fin close_ssh_tunnel