Recebi uma tarefa para atualizar um banco de dados MySQL 5.7 usando um diretório de scripts seqüenciados e comparando-os com um campo de versão em um banco de dados.
Você deve consultar o banco de dados, comparar o número da tabela retornada com os scripts no diretório e, se o número for menor que o script mais alto, executar todos os scripts que levam ao mais alto. Pode haver lacunas na numeração dos scripts também
A questão também é descrita aqui;
link
No entanto, criei uma solução para o problema - exceto que não consigo fazer com que os scripts sejam executados em sequência. Se houver uma lacuna na numeração, o meu grep puxará outro script que compartilha o mesmo número - como posso evitar isso?
, por exemplo, grep para 6, mas executa 66.update.sql em vez de 6.update.sql
Nota; Também estou ciente de que a instrução if $ CURRENT_DB_VERSION -lt 9 provavelmente é redundante - mas foi minha tentativa de tentar resolver o problema de qualquer script com um único inteiro precedido por 0.
Eu criei uma versão do script onde eu usaria apenas a ordenação -n | head -1 função para executar os scripts em ordem e removê-los uma vez executado - mas não consegui fazer o script começar a executar scripts .sql na versão DB.
#!/bin/bash
####### Usage check
[[ $# -ne 5 ]] && echo -e "Please provide the SQL scripts directory, username, hostname, database and password \nUSAGE: ./sql_upgrade.sh /directory username hostname dbname password" && exit
####### access / store db information
cd $1
user=$2
host=$3
database=$4
pass=$5
######## DB Version store
mysql -u $user -h $host -p$pass -D $database -e "SELECT version FROM versionTable" > dbvers.out
CURRENT_DB_VERSION='cat dbvers.out | grep -o '[0-9]\+''
highest_upgrade_version='ls $(pwd) | grep -Eo '[0-9]+' | sort -rn | head -n 1 | awk 'NR' | sed 's/^0*//''
######### create list of scripts and order them
ls $(pwd) | grep .sql | sort -n >> scripts_list.txt
while [[ $CURRENT_DB_VERSION -lt $highest_upgrade_version || $CURRENT_DB_VERSION -eq $highest_upgrade_version ]]
do
next_script_to_execute='grep -Eo $CURRENT_DB_VERSION scripts_list.txt | sort -n | head -n 1'
if [[ $next_script_to_execute -gt $CURRENT_DB_VERSION || -z $next_script_to_execute ]]
then
((CURRENT_DB_VERSION++))
elif [[ $CURRENT_DB_VERSION -lt 9 ]]
then
for i in $(ls $(pwd) | sort -n| grep -E "^[0]" | grep $CURRENT_DB_VERSION| head -1);
do mysql -u $user -h $host -p$pass -D $database < $i
echo $i "is currently being executed"
((CURRENT_DB_VERSION++))
done
else
for i in $(ls $(pwd) | sed 's/^[1-9]*\+ //' | grep -E $CURRENT_DB_VERSION | sort -n | head -n 1); do mysql -u $user -h $host -p$pass -D $database < $i
((CURRENT_DB_VERSION++))
echo $i "is currently being executed"
done
fi
done
((CURRENT_DB_VERSION--))
echo "Current version of the Database is: "$CURRENT_DB_VERSION
mysql -u $user -h $host -p$pass -D $database -e "UPDATE versionTable SET version = $CURRENT_DB_VERSION"
### cleanup temp files
rm -rf scripts_list.txt
rm -rf dbvers.out