MYSQLDUMP over Powershell SSH (POSH) - mysql

I'm struggeling with this for a day now. Basically I want to backup a MySQL database on our webspace with a powershell script which runs daily on my windows computer.
When I use Putty and enter the following command, a backup file is created:
mysqldump XXXX --add-drop-table -u XXXX -p******* > backup/backup.sql
But when I run it from powershell, it will not create the backup file, even when I invoke the exact same command:
$sshsession = New-SSHSession -ComputerName $sshserver -Credential $Creds -Force -Verbose
[string]$backupcmd = "mysqldump XXXX --add-drop-table -u XXXX -p******* > backup/backup.sql"
Write-Output $backupcmd
$backupdb = Invoke-SSHCommand -SSHSession $sshsession -Command "$backupcmd"
It seems like Posh-SSH has problems with the ">" operator, maybe it does not have enough time to execute, I don't know. Also tried things like Timeout on Invoke-SSHCommand, but nothing did work yet.
I can't do stuff like crons on the remote server, it's just a webspace with limited functionalities. Also starting a bash-script does not work, I have no rights to execute scripts on the remote server.

If your need is specifically regarding the mysqldump command, you can use the --result-file or just -r parameter.
In this case it would look like this:
$ backupcmd = "mysqldump XXXX --add-drop-table -u XXXX -p ******* -r backup/backup.sql"
I did not perform tests because I do not have POSH available at this time, but you can refer to the documentation: https://dev.mysql.com/doc/refman/8.0/en/mysqldump.html#option_mysqldump_result-file
Tell us it worked out this way.
Hope this helps.

Related

Run mysql commands in bash script without logging in or adding -u root to every command

I'm writing a bash script to do some db stuff. New to MySQL. I'm on Mac and have MySQL installed via homebrew.
Am using username "root" right now and there isn't a pw set. I included the pw syntax below just to help others out that may have a pw.
My goal is to have mysql commands be as "clean" as possible in my bash script
Not a hige deal, but would like to do this if possible.
Example
# If I can do it without logging in (*ideal)
mysql CREATE DATABASE dbname;
# Or by logging in with - mysql -u root -pPassword
CREATE DATABASE dbname;
# Instead of
mysql -u root -pPassword -e"CREATE DATABASE dbname";
Tried to simplify it. I have a handful of things I gotta do, so would rather keep my code cleaner if possible. I tried logging in with the bash script, but the script stopped once logged into MySQL and didn't run any commands.
Another option I was considering (but don't really like) would be just to keep username and pw string in a var and call it for every commmand like so
# Set the login string variable
login_details="-u root -p password -e"
# example command
mysql $login_details"CREATE DATABASE dbname";
So any ideas?
Write a new bash script file and run this file after putting all your commands into it. Don't forget to give right username and password in your bash script.
For bash script:
#!/bin/bash
mysql -u root -pSeCrEt << EOF
use mysql;
show tables;
EOF
If you want to run single mysql command.
mysql -u [user] -p[pass] -e "[mysql commands]"
Example:
mysql -h 192.168.1.10 -u root -pSeCrEt -e "show databases"
To execute multiple mysql commands:
mysql -u $user -p$passsword -Bse "command1;command2;....;commandn"
Note: -B is for batch, print results using tab as the column separator, with each row on a new line. With this option, mysql does not use the history file. Batch mode results in nontabular output format and escaping of special characters. -s is silent mode. Produce less output. -e is to execute the statement and quit

MySQL dump CronJob

I'm trying to create a cron that daily backups my MySQL slave. The backup.sh content:
#!/bin/bash
#
# Backup mysql from slave
#
#
sudo mysql -u root -p'xxxxx' -e 'STOP SLAVE SQL_THREAD;'
sudo mysqldump -u root -p'xxxxx' ng_player | gzip > database_`date +\%Y-\%m-\%d`.sql.gz
sudo mysqladmin -u root -p'xxxxx' start-slave
I made it executable by sudo chmod +x /home/dev/backup.sh
and entered in to crontab by:
sudo crontab -e
0 12 * * * /home/dev/backup.sh
but it doesn't work, if I only run in the command line it works but not in crontab.
FIXED:
I used the script from this link: mysqldump doesn't work in crontab
Break the problem in half. First try sending only email from the cron job to see if you are getting it to even run. Put this above in a file and have your cron job point to it:
#!/bin/bash
/bin/mail -s "test subject" "yourname#yourdomain" < /dev/null
The good thing about using this tester is that it is very simple and more likely to give you some results. It does not depend on your current working directory, which can sometimes be not what you expect it to be.
Try use full link to mysql bin directory in .sh file
example :
sudo /var/lib/mysql -u root -p'xxxxx' -e 'STOP SLAVE SQL_THREAD;'
I had this same problem.
I figured out that you can't use the command sudo in a non-interactive script.
The sudo command would create a field where you would type in the password to your account (root).
If you are logged into a command prompt like ssh sudo works without typing in any passwords, but when another program runs sudo it would ask for password.
Try this instead su command doesn't require any logins and it does the same thing.
su --session-command="mysql -u root -p'xxxxx' -e 'STOP SLAVE SQL_THREAD;'" root
su --session-command="mysqldump -u root -p'xxxxx' ng_player | gzip > database_`date +\%Y-\%m-\%d`.sql.gz" root
su --session-command="mysqladmin -u root -p'xxxxx' start-slave" root
Replace root with your linux username.
EDIT:
Look at this thread for a different answer.
https://askubuntu.com/questions/173924/how-to-run-cron-job-using-sudo-command
Let's start with the silly stuff in the script.
The only command which you don't run via 'sudo' is the, spookily enough, only command which I would expect you might need to run via sudo (depending on the permissions of the target file).
Prefixing the commands in a script with sudo without a named user (i.e. running as root) serves no useful function if you are invoking the script as root.
On a typical installation, the mysql, mysqladmin and gzip programs are typically executable by any user - the authentication and authorization of the commands to the DBMS are authenticated by the DBMS using the authentication credentials passed as arguments - hence I would not expect that any of the operations here, except possibly writing to the output file (depending on its permissions).
You don't specify a path for the backup file - maybe it's writing it somewhere other than you expect?
(similarly, you should check if any of the executables are in a location which is not in the $PATH for the crontab execution environment).
but it doesn't work
....is not an error message.
The output of any command run via cron is mailed to the owner of the crontab - go read your mail.

Setting mysql as shell

I have a user on my machine that is only supposed to run mysql. Is there any way that I can set the shell of that user to mysql and login using password and username?
I know how to change the shell to the mysql binary
usermod -s /usr/bin/mysql
That is working indeed, only I can't provide a username/password in the program. Usually user/pw are given as
mysql -u $USER -p
I can not provide parameters for a shell as in
usermod -s "/usr/bin/mysql -u $USER -p" # Does not work!
Also using a simple shell-script as shell does not work:
#!/bin/sh # mysqlShell
/usr/bin/mysql -u $USER -p
----
usermod -s mysqlShell # does not work
So how can I provide parameters to a program I use as a shell for a user?
Thanks to Tom Regner I could figure out a solution using .my.cnf containing
[client]
host=localhost
user=$user
password=$pass
disable-auto-rehash
where mysql is set to the shell. I still would like give the password manually but this is the best I found.
Setup a $HOME/.my.cnf file for the user
[client]
host=localhost
user=mysqluser
password=mysqlpass
then set a bash as login shell and put the following in $HOME/.bashrc
exec mysql --host=localhost dbname
that should do what you want, while the user in question just has to give one password (the system account password on login).
exec replaces the shell process with the mysql process.
If this does not work as expected, you may need to adjust $HOME/.bash_profile to source .bashrc:
[[ -f ~/.bashrc ]] && . ~/.bashrc
It might be enough to provide an appropriate .my.cnf and setting /usr/bin/mysql as shell, but this way you can pass arbitrary commandline options/flags to the mysql client.
You can do that by editing the user's account details in the /etc/passwd and change the default shell.
You need a login password (unless you set up ssh appropriately). Use the following command: sudo passwd username to change that login password.
You also need a mysql password. Use SET PASSWORD Mysql request.
If you want the user to be connected to some fixed database with some fixed password, code a small C wrapper (then, make the executable only executable by your Unix user) doing mysql_real_connect, or calling some exec function for mysql --user=username --password=password databasename but I don't recommend doiing the later (because ps aux will show the password, and that is a security risk).
Perhaps, since MySQL is free software, you could customize the source code of mysql for your particular needs.
Perhaps using a restricted shell and carefully configuring it is better.

Making an alias for SSH MySQL login using ENDSSH heredoc

I want to make an alias that is kept in my bashrc file to log into a remote MySQL db via SSH.
Assume that I can't add/alter any files on the remote machine that I'm SSHing into. Here's the relevant code.
function ssh_mysql {
echo "SSHing to $server"
ssh -t -t $suser#$server <<ENDSSH
eval "mysql -h "$host" -u $user -p $pass $db"
ENDSSH
}
alias wt_mysql=ssh_mysql
The Problem: Entering 'wt_mysql' into the terminal as an alias SSHs and logs into MySQL fine.. but when trying to enter any command/query/etc at the MySQL prompt, none of what I've submitted is executed/run. Including the 'exit' command. I have to ctrl C to get back to my local terminal. although its a bit out of my understanding I believe the problem is related to this topic, Terminating SSH session executed by bash script
How can I make sure that mysql and any subsequent commands are executed remotely?
Thanks!
I don't understand why you're using eval (or why you're passing the -t switch twice).
I would expect this ssh command to do what you want:
ssh -t $suser#$server "mysql -h '$host' -u $user -p $pass $db"

mysqldump from remote host

Is it possible to dump a database from a remote host through an ssh connection and have the backup file on my local computer.
If so how can this be achieved?
I am assuming it will be some combination of piping output from the ssh to the dump or vice versa but cant figure it out.
This would dump, compress and stream over ssh into your local file
ssh -l user remoteserver "mysqldump -mysqldumpoptions database | gzip -3 -c" > /localpath/localfile.sql.gz
Starting from #MichelFeldheim's solution, I'd use:
$ ssh user#host "mysqldump -u user -p database | gzip -c" | gunzip > db.sql
ssh -f user#server.com -L 3306:server.com:3306 -N
then:
mysqldump -hlocalhost > backup.sql
assuming you also do not have mysql running locally. If you do you can adjust the port to something else.
I have created a script to make it easier to automate mysqldump commands on remote hosts using the answer provided by Michel Feldheim as a starting point:
mysqldump-remote
The script allows you to fetch a database dump from a remote host with or without SSH and optionally using a .env file containing environment variables.
I plan to use the script for automated database backups. Feel free to create issues / contribute - hope this helps others as well!