ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I'm using the following script the import all database dumps that reside in /root/mysql.
Code:
#!/bin/sh
*# store start date to a variable
imeron=`date`
echo "Import started: OK"
for dumpfile in "/root/mysql/*"
do
ddl="set names utf8; "
ddl="$ddl set global net_buffer_length=1000000;"
ddl="$ddl set global max_allowed_packet=1000000000; "
ddl="$ddl SET foreign_key_checks = 0; "
ddl="$ddl SET UNIQUE_CHECKS = 0; "
ddl="$ddl SET AUTOCOMMIT = 0; "
ddl="$ddl USE ${dumpfile##*/};"
ddl="$ddl source ${dumpfile##*/}; "
ddl="$ddl SET foreign_key_checks = 1; "
ddl="$ddl SET UNIQUE_CHECKS = 1; "
ddl="$ddl SET AUTOCOMMIT = 1; "
ddl="$ddl COMMIT ; "
echo "Import started: OK"
time mysql -h 127.0.0.1 -u root -ppassword -e "$ddl"
imeron2=`date`
echo "Start import:$imeron"
echo "End import:$imeron2"
done
When I run it, I get the following error:
ERROR 1049 (42000) at line 1: Unknown database '*'
The point of using ${dumpfile##*/} is, of course, to select only the file itself, and not the whole path. Any ideas how I make it expand to what it should be? The problem is that the quotes turn it into the asterix.
No, that's not the issue. Actually, this was just a c/p error. And mysql wouldn't have said "unknown database '*'" if you'd have only written * in its cli. The problem is that bash is not expanding correctly and I don't know how to make it do so.
I changed the USE and SOURCE lines into this:
Quote:
ddl="$ddl USE '${dumpfile##*/}'";
ddl="$ddl SOURCE '${dumpfile##*/}'";
But I get:
ERROR 1064 (42000) at line 1: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''*' SOURCE '*' SET foreign_key_checks = 1' at line 1
Thanks for the link. I tested the script, seemed ok except this:
With regards to for dumpfile in "/root/mysql/*":
Since you double quoted this, it will not word split, and the loop will only run once.
Distribution: Debian /Jessie/Stretch/Sid, Linux Mint DE
Posts: 5,195
Rep:
The '*#' in line 2 of the script is definitely a bash error. It should have produced an error message but not more than that.
The error "ERROR 1049 (42000) at line 1: Unknown database '*'" refers to the result of the mysql execution. Since the variable $ddl is one line holding the command, the error messages refers to ddl. It is not a bash error, it is a mysql error.
I never used -e to execute a mysql command, but always
Code:
echo $ddl | myqsl
In general, the mysql command is:
Code:
mysql -u user -ppassword database
I am missing database in your command, but then again I never used the -e option
Some more hints to easy debugging:
Run the bash script with bash -x like in my signature
Thanks for the link. I tested the script, seemed ok except this:
With regards to for dumpfile in "/root/mysql/*":
Since you double quoted this, it will not word split, and the loop will only run once.
What that means is that using quotes bash will not perform any wildcard expansion and the value of dumpfile will only be /root/mysql/* and therefore removing the path leaves * thus the unknown database error.
As an aside (tho I think that michaelk has identified the root cause)...
Is there some reason for the (to me) clumsy population of ddl?
Why not
Code:
ddl="set names utf8; \
set global net_buffer_length=1000000;\
set global max_allowed_packet=1000000000; \
SET foreign_key_checks = 0; \
SET UNIQUE_CHECKS = 0; \
SET AUTOCOMMIT = 0; \
USE ${dumpfile##*/};\
source ${dumpfile##*/}; \
SET foreign_key_checks = 1; \
SET UNIQUE_CHECKS = 1; \
SET AUTOCOMMIT = 1; \
COMMIT ; "
or maybe a here document to build your ddl?
...the
@pan64 Sorry, it was my mistake, the rest of the script is identical, I assure you (with the exception of the changes that I said I made).
@michaelk first I replaced them with single quotes, which was just as bad Now I removed the double quotes from /root/mysql/* altogether.
Anyway, after adding the simple quotes like this
Code:
ddl="$ddl USE '${dumpfile##*/}'";
, as I said before, and removed the double quotes from /root/mysql/* and I ended up with the same error in post #3, which seems to be entirely a mysql error.
@scasey. There's no specific logic to the script. I copied it from somewhere and it worked just fine as it was for a single database. The problem is that I have lots of databases and I wanted it automated. so I created the for loop, which created these problems.
I added an echo line in the script like this:
Code:
ddl="$ddl USE '${dumpfile##*/}'";
echo -e "This is ddl variable: $ddl\n "
Then for each file in /root/mysql I get an error like the following:
Code:
Import started: OK
This is ddl variable: set names utf8; set global net_buffer_length=1000000; set global max_allowed_packet=1000000000; SET foreign_key_checks = 0; SET UNIQUE_CHECKS = 0; SET AUTOCOMMIT = 0; USE 'my_database'
Import started: OK
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1064 (42000) at line 1: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''my_database' SOURCE 'my_database' SET foreign_key_checks = 1' at line 1
real 0m0.005s
user 0m0.000s
sys 0m0.000s
Start import:Wed Jun 20 16:46:06 EEST 2018
End import:Wed Jun 20 16:46:06 EEST 2018
#!/bin/sh
# store start date to a variable
imeron=`date`
echo "Import started: OK"
set -x
for dumpfile in /root/mysql/*
do
ddl="set names utf8; "
ddl="$ddl set global net_buffer_length=1000000; "
ddl="$ddl set global max_allowed_packet=1000000000; "
ddl="$ddl SET foreign_key_checks = 0; "
ddl="$ddl SET UNIQUE_CHECKS = 0; "
ddl="$ddl SET AUTOCOMMIT = 0; "
ddl="$ddl USE ${dumpfile##*/}; "
ddl="$ddl SOURCE ${dumpfile}; "
ddl="$ddl SET foreign_key_checks = 1; "
ddl="$ddl SET UNIQUE_CHECKS = 1; "
ddl="$ddl SET AUTOCOMMIT = 1; "
ddl="$ddl COMMIT; "
echo "Import started: OK"
time mysql -h 127.0.0.1 -u root -ppassword -e "$ddl"
imeron2=`date`
echo "Start import:$imeron"
echo "End import:$imeron2"
done
I placed the semicolons where they should be (before the ending quotes) and I removed the single quotes.
Now it seems to be working as expected. Thanks all for your patience
I do have another problem now, though, for some of the databases:
"Got error 168 from storage engine"
I've looked it up on the internet, and lots of people mentioned lack of disk space, which clearly isn't the issue in my case. Could it be related to the buffer length or max packet size variables in relation to the ram available, which is only 2GB?
I'm guessing I'd have to open a new thread for this subject
You're most welcome. It's important to understand that when any compiler or interpreter reports syntax errors that one should look for typos or mis-placed characters first. Mysql is very clear about where the error starts (at the beginning of the quoted chunk of code), but very vague about what the error is.
...and I don't know about "have to" open a new thread, but it would be the better way to go, IMO
I would suggest you to use different syntax, which will make it more readable:
Code:
for dumpfile in /root/mysql/*
do
cat > tmpfile << EOF
set names utf8;
set global net_buffer_length=1000000;
set global max_allowed_packet=1000000000;
SET foreign_key_checks = 0;
SET UNIQUE_CHECKS = 0;
SET AUTOCOMMIT = 0;
USE ${dumpfile##*/};
SOURCE ${dumpfile};
SET foreign_key_checks = 1;
SET UNIQUE_CHECKS = 1;
SET AUTOCOMMIT = 1;
COMMIT;
EOF
echo "Import started: OK"
time mysql -h 127.0.0.1 -u root -ppassword < tmpfile
....
done
In this case you can also check the content of tmpfile if that was constructed properly.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.