Run sql-command from bash-script? - mysql

I created a little script which must change engine for tables:
#!/bin/bash
echo "use test_1;" > query.sql
get_list () {
mysql -u teamcity -ppassword -B -N -e 'show tables like "%"' test_1 | xargs -I '{}' echo "alter table {} engine=innodb;" >> query.sql
}
get_list ;
mysql -u teamcity -ppassword < query.sql
But - how can I avoid use query.sql file? I make few attempts with "Here document" - but can't solve it...
For example - trying this:
#!/bin/bash
get_list () {
mysql -u teamcity -ppassword -B -N -e 'show tables like "%"' test_1 | xargs -I '{}' echo "alter table {} engine=innodb;"
}
a="$(get_list)"
b="use test_1;"
c="$b $a"
mysql -u teamcity -ppassword <<< $c
But it is not working...

Put everything in a function and pipe that:
#!/bin/bash
get_list () {
echo "use test_1;"
mysql -u teamcity -ppassword -B -N -e 'show tables like "%"' test_1 | xargs -I '{}' echo "alter table {} engine=innodb;"
}
get_list | mysql -u teamcity -ppassword

Related

Bash script, get data from a DB and echo it

I have a script that search in a DB for a single column and store them in an array, then I use that column values in another query to get multiples columns, and store them in a variable.
Im trying to echo the variable message but when I run the script it doesnt echo anything.
#!/bin/bash
mapfile result < <(mysql -ugroot -p<pass> -D <db> -h <host-ip> -P 3306 -s -N -e "SELECT <query> ;")
for row in "${result[#]}";do
message=`mysql -ugroot -p<pass> -D <db> -h <host-ip> -P 3306 -s -N -e "SELECT <query> AND tg2.nombre = '${row}';"`
echo $message
done
Unless you explicitly need the result array I think you can use:
for row `mysql -ugroot -p<pass> -D <db> -h <host-ip> -P 3306 -s -N -e "SELECT <query> ;"` ; do
message=`mysql -ugroot -p<pass> -D <db> -h <host-ip> -P 3306 -s -N -e "SELECT <query> AND tg2.nombre = '${row}';"`
echo $message
done
BR

How to take all database backup same as db name

I am using MySQL on centos7. I have 50 databases Like database1, database2...., database50.
How can I set a cronjob for take a dump every day of all database same as database name [ Like database1.sql, database2.sql .... database50.sql ] using single command or script.
Please provide some adequate solution that will be appreciated.
Thanks.
Convert the current date to an integer number of days since some starting date.
Take that modulo 50. This gives you 0 .. 49.
Add 1 and concatenate. Now you have database1 .. database50. Put that in the shell variable db
mysqldump ... $db >$db.sql
I am using this script
#! /bin/bash
# MySQL database backup (databases in separate files) with daily, weekly and monthly rotation
# Sebastian Flippence (http://seb.flippence.net) originally based on code from: Ameir Abdeldayem (http://www.ameir.net)
# You are free to modify and distribute this code,
# so long as you keep the authors name and URL in it.
# Modified by IVO GELOV
# How many backups do you want to keep?
MAX_DAYS=5
# Date format that is appended to filename
DATE=`date +'%Y-%m-%d'`
DATSTR=`date '+%Y%m%d' -d "-$MAX_DAYS days"`
# MySQL server's name
SERVER=""
# Directory to backup to
BACKDIR="/var/db_arhiv/mysql"
#----------------------MySQL Settings--------------------#
# MySQL server's hostname or IP address
HOST="localhost"
# MySQL username
USER="user"
# MySQL password
PASS="password"
# List all of the MySQL databases that you want to backup,
# each separated by a space. Or set the option below to backup all database
DBS="db1 db2"
# Set to 'y' if you want to backup all your databases. This will override
# the database selection above.
DUMPALL="y"
# Custom path to system commands (enable these if you want use a different
# location for PHP and MySQL or if you are having problems running this script)
MYSQL="/usr/local/mysql/bin/mysql"
MYSQLDUMP="/usr/local/mysql/bin/mysqldump"
function checkMysqlUp() {
$MYSQL -N -h $HOST --user=$USER --password=$PASS -e status > /dev/null
}
trap checkMysqlUp 0
function error() {
local PARENT_LINENO="$1"
local MESSAGE="$2"
local CODE="${3:-1}"
if [[ -n "$MESSAGE" ]] ; then
echo "Error on or near line ${PARENT_LINENO}: ${MESSAGE}; exiting with status ${CODE}"
else
echo "Error on or near line ${PARENT_LINENO}; exiting with status ${CODE}"
fi
exit "${CODE}"
}
trap 'error ${LINENO}' ERR
# Check backup directory exists
# if not, create it
if [ ! -e "$BACKDIR/$DATE" ]; then
mkdir -p "$BACKDIR/$DATE"
echo "Created backup directory (${BACKDIR}/${DATE})"
fi
if [ $DUMPALL = "y" ]; then
echo "Creating list of databases on: ${HOST}..."
$MYSQL -N -h $HOST --user=$USER --password=$PASS -e "show databases;" > ${BACKDIR}/dbs_on_${SERVER}.txt
# redefine list of databases to be backed up
DBS=`sed -e ':a;N;$!ba;s/\n/ /g' -e 's/Database //g' ${BACKDIR}/dbs_on_${SERVER}.txt`
fi
echo "Backing up MySQL databases..."
#cd ${LATEST}
for database in $DBS; do
if [ ${database} = "information_schema" ] || [ ${database} = "performance_schema" ] || [ ${database} = "pinba" ]
then
continue
fi
echo "${database}..."
$MYSQLDUMP --host=$HOST --user=$USER --password=$PASS --default-character-set=utf8 --routines --triggers --lock-tables --disable-keys --force --single-transaction --allow-keywords --dump-date $database > ${BACKDIR}/${DATE}/${SERVER}$database.sql
done
if [ $DUMPALL = "y" ]; then
rm -f ${BACKDIR}/dbs_on_${SERVER}.txt
fi
# dump privileges
$MYSQL -N -h $HOST --user=$USER --password=$PASS --skip-column-names -A -e "SELECT CONCAT('SHOW GRANTS FOR ''',user,'''#''',host,''';') FROM mysql.user" | $MYSQL -N -h $HOST --user=$USER --password=$PASS --skip-column-names -A > ${BACKDIR}/${DATE}/${SERVER}_grants.sql
# delete older files
for x in `find ${BACKDIR}/20* -type d`
do
xd=`basename "${x//-/}"`
if [[ $xd < $DATSTR ]]
then
rm -rf "$x"
fi
done
echo "MySQL backup is complete"

Catch Mysql Error in bash

I have a bash script that queries mysql and I would like to catch the error and echo it . Here is my code
mysql --silent -h ${sql_server} -P 3306 -u${USER} -p${MYSQL_PASS} -D${DATABASE} -BNe "$sql_str" | while read -r line
do
query="$(echo "$line" | cut -f1)"
database_out="$(echo "$line" | cut -f2)"
outfile="$(echo "$line" | cut -f3)"
directory_out="$(echo "$line" | cut -f4)"
type="$(echo "$line" | cut -f5)"
host="$(echo "$line" | cut -f6)"
username="$(echo "$line" | cut -f7)"
directory_scp="$(echo "$line" | cut -f8)"
#switch over format types
case "$type" in
csv)
file_out=$directory_out$outfile"."`date +%Y%m%d`.csv
mysql -h ${sql_server} -P 3306 -u${USER} -p${MYSQL_PASS} -D${database_out} -e "$query" | sed 's/\t/","/g;s/^/"/;s/$/"/;s/\n//g' > $file_out
;;
xml)
file_out=$directory_out$outfile`date +%Y%m%d`.xml
mysql -h ${sql_server} -P 3306 -u${USER} -p${MYSQL_PASS} -D${database_out} -e "$query" -X > $file_out
;;
*)
echo "["$(timestamp)"] : {ERROR} Invalid output format. Currently only csv and xml output supported."
;;
esac
str=$file_out" "$username#$host:$directory_scp
echo "["$(timestamp)"] : {NOTIFICATION} Attempting to scp "$outfile" to "$username#$host:$directory_scp" - [Started]"
scp $str
echo "["$(timestamp)"] : {NOTIFICATION} scp "$outfile" to "$username#$host:$directory_scp" - [Complete]"
done
Any ideas. I would like to catch error and format the error output.
result=$(mysql --silent -h ${sql_server} -P 3306 -u${USER} -p${MYSQL_PASS} -D${DATABASE} -BNe "$sql_str")
if [ $? -ne "0" ]; then
echo "["$(timestamp)"] : {ERROR} MySQL error thrown in EOD DUMP"
else
while read -r line
...do something

Catching exit code after executing mysql query

I'm working on a bash script that will query mysql. I would like to add some error checking. Let say if the following query for some reason fails I want to catch the exit error and exit the script. For example this is part of my script.
QUERY="SELECT DISTINCT `TABLE_SCHEMA`, `TABLE_NAME`
FROM `information_schema`.`TABLES`
WHERE table_schema NOT IN ( 'mysql', 'information_schema', 'performance_schema' )"
mysql -u user -pPASSWD --batch -N -e "$QUERY" | while read DATABASE TABLE;
do
...
...
...
done
How could i catch the exit code after the scripts run the "$QUERY". I was thinking something like this. But it doesn't seem to work.
mysql -u user -pPASSWD --batch -N -e "$QUERY" echo $? | while read DATABASE TABLE;
Any ideas
You are in the good way: $? is the flag to check:
$ mysql -h mydb <<< "SELECT * FROM MyDB.some_table_that_exists;"
$ echo $?
0
$ mysql -h mydb <<< "SELECT * FROM MyDB.asdfasdfasdf;"
ERROR 1146 (42S02) at line 1: Table 'MyDB.asdfasdfasdf;' doesn't exist
$ echo $?
1
So what you can do is to execute the query and then:
if [ $? ... ]; then ...

Restore all MySQL Databases from individual files

I can backup all my db in separate files using the following script:
#!/bin/bash
MYSQL_USER="USER"
MYSQL_PASS="PASSWORD"
if [ -z "$1" ]
then
echo "Dumping all DB ..."
for I in $(mysql -u $MYSQL_USER --password=$MYSQL_PASS -e 'show databases' -s --skip-column-names);
do
echo "SET autocommit=0;SET unique_checks=0;SET foreign_key_checks=0;" > "$I.sql"
mysqldump -u $MYSQL_USER --password=$MYSQL_PASS $I >> "$I.sql";
echo "SET autocommit=1;SET unique_checks=1;SET foreign_key_checks=1;commit;" >> "$I.sql"
gzip "$I.sql"
done
echo "END."
else
echo "Dumping $1 ..."
echo "SET autocommit=0;SET unique_checks=0;SET foreign_key_checks=0;" > "$1.sql"
mysqldump -u $MYSQL_USER --password=$MYSQL_PASS $1 >> "$1.sql";
echo "SET autocommit=1;SET unique_checks=1;SET foreign_key_checks=1;commit;" >> "$1.sql"
gzip "$1.sql"
fi
I'm looking for the reverse command:
create a DB with the same file name
uncompress/import the sql.gz backup
You can use this script:
for f in *.sql.gz; do
db="${f%%.*}"
echo "creating database $db"
mysql -h localhost -u root -p mysql --password=passwd <<< "create database $db"
echo "restoring database $db"
gunzip "$f"
mysql -h localhost -u root -ppasswd "$db" < "$db.sql"
done