I am looking for a way to pull the information that is returned from Show Master Status so that I can assign the File and Position values to a variable.
I was able to set slave_relay_log_info and slave_work_info to tables but that does not show the local Master information I need.
SHOW MASTER STATUS;
I am not sure what table holds the Show Master Status data.
In Linux bash script you can try below command through mysql client to store the File and Position in variables
For File:
mysql -u username -p password -h IP -P Port -e "show master status" | grep "File"| cut -d ":" -f2
For Position:
mysql -u username -p password -h IP -P Port -e "show master status" | grep "Position"| cut -d ":" -f2
For MySQL 8.0 the log file and log position are in the log_status table of the performance_schema schema:
mysql> SELECT * FROM log_status ;
+--------------------------------------+------------------------------------------------------------------------------------------+------------------+-----------------------------------------------------------+
| SERVER_UUID | LOCAL | REPLICATION | STORAGE_ENGINES |
+--------------------------------------+------------------------------------------------------------------------------------------+------------------+-----------------------------------------------------------+
| 506c04ec-815c-11ed-a962-0800272d3b77 | {"gtid_executed": "", "binary_log_file": "mysql-bin.000022", "binary_log_position": 157} | {"channels": []} | {"InnoDB": {"LSN": 36558461, "LSN_checkpoint": 36558461}} |
+--------------------------------------+------------------------------------------------------------------------------------------+------------------+-----------------------------------------------------------+
The values can be extracted directly like this:
mysql> SELECT JSON_EXTRACT(`LOCAL`, '$.binary_log_file') AS file, JSON_EXTRACT(`LOCAL`, '$.binary_log_position') AS position FROM log_status ;
+--------------------+----------+
| file | position |
+--------------------+----------+
| "mysql-bin.000022" | 157 |
+--------------------+----------+
Related
I use a query command from bash which returns a number. However, it is printed as a table.
$ mysql -u muser -p$PASS mm -e "SELECT.....;"
mysql: [Warning] Using a password on the command line interface can be insecure.
+----------------------------+
| COUNT(DISTINCT ula.userid) |
+----------------------------+
| 29 |
+----------------------------+
I just want to get 29 and append that to a file with >> file.txt. How can I do that in mysql?
Use skip-column-names and batch-mode with -N and -B respectively:
mysql -u muser -p$PASS mm -NBe "SELECT.....;" >> file.txt
I have a problem launching MySQL script from shell. I assign a value to my variable ${x}, using filename. So I have to launch a MySQL script using this variable. I would like to launch script without insert all MySQL code in shell (is too long) but using:
mysql -h localhost -uuser -ppsw DB < script.sql
My tentatives are:
mysql -h localhost -uuser -ppsw DB -e "set #x=${x}; source script.sql"
mysql -h localhost -uuser -ppsw DB -e "set #x=${x};"
mysql -h localhost -uuser -ppsw DB< script.sql
But not work for me. Could you help me?
I was surprised that your first solution didn’t work:
mysql -h localhost -uuser -ppsw DB -e "set #x=${x}; source script.sql"
Analysis
source is a MySQL command
set #x=${x}; is an SQL statement.
I thought that there may be an issue combining the two types as one statement as the MySQL --execute=statement, -e statement is supposed to execute the statement and quit.
The and quit part is why the redirected stdin is ignored when I tried my first idea:
mysql -h localhost -uuser -ppsw DB -e "set #x=${x};" < script.sql
Solution
After further experiments, I figured out that simply appending a semi-colon to the source command will prevent the syntax error.
I can’t say why this works as a semi-colon isn’t usually required to terminate the last SQL statement of a list but there you have it:
mysql -h localhost -uuser -ppsw DB -e "set #x=${x}; source script.sql;"
As Glenn Jackman pointed out, if the shell variable is a non-numeric string, the shell variable will have to be wrapped in single quotes so that when the MySQL variable is being assigned, MySQL will treat the right hand side (the shell variable) as a string literal instead of as an identifier for a column name:
mysql -h localhost -uuser -ppsw DB -e "set #x='$x'; source script.sql;"
This version will also work safely with numeric strings as can be seen in the examples below. I’ve also removed the curly braces around the shell variable since they’re not necessary.
Examples
Contents of t.sql:
select now();
select #variable as 'Contents of variable';
Use a numeric string as the shell variable:
$ number=3
$ mysql -e "set #variable=$number; source t.sql;"
+---------------------+
| now() |
+---------------------+
| 2015-10-02 13:06:45 |
+---------------------+
+----------------------+
| Contents of variable |
+----------------------+
| 3 |
+----------------------+
Use a non-numeric string as the shell variable generates errors:
$ text=text
$ mysql -e "set #variable=$text; source t.sql;"
ERROR 1054 (42S22) at line 1: Unknown column 'text' in 'field list'
$ text="This is a string"
$ mysql -e "set #variable=$text; source t.sql;"
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 'a string' at line 1
Now wrap the shell variable in single quotes:
$ mysql -e "set #variable='$text'; source t.sql;"
+---------------------+
| now() |
+---------------------+
| 2015-10-02 13:08:04 |
+---------------------+
+----------------------+
| Contents of variable |
+----------------------+
| This is a string |
+----------------------+
$ text=text
$ mysql -e "set #variable='$text'; source t.sql;"
+---------------------+
| now() |
+---------------------+
| 2015-10-02 13:10:53 |
+---------------------+
+----------------------+
| Contents of variable |
+----------------------+
| text |
+----------------------+
$ mysql -e "set #variable='$number'; source t.sql;"
+---------------------+
| now() |
+---------------------+
| 2015-10-02 13:11:42 |
+---------------------+
+----------------------+
| Contents of variable |
+----------------------+
| 3 |
+----------------------+
Using a non-existing shell variable will set the MySQL variable to an empty string:
$ mysql -e "set #variable='$nonexistent'; source t.sql;"
+---------------------+
| now() |
+---------------------+
| 2015-10-02 13:06:14 |
+---------------------+
+----------------------+
| Contents of variable |
+----------------------+
| |
+----------------------+
How can i store mysql databases in linux using shell scripting
script:
mysql -uusername -hhostname -ppassword -e "show databases"
I think you want this: http://lists.mysql.com/mysql/96132
mysql> use mysql
Database changed
mysql> tee /tmp/mysqltee
Logging to file '/tmp/mysqltee'
mysql> show tables;
+-----------------+
| Tables_in_mysql |
+-----------------+
| columns_priv |
| db |
| host |
| tables_priv |
| user |
+-----------------+
5 rows in set (0.02 sec)
mysql> notee
Outfile disabled.
mysql>
If the file exist, the output will be appended to the existing file (/tmp/mysqltee).
As you can see, the output is also displayed on the screen. This may not be
what you want, especially if the output is big... You could use
mysql -e "select table_name from user_tables" database > output.txt
or
mysql database < script.sql > output.txt
from the os command line. (You may also need to use -u, -p and/or -h, use
the same as when you do a 'normal' start of the mysql client.)
it may help you
#!/bin/bash
results=($(mysql --user root -pwelcome -Bse "show databases;"))
The following code will retrieve all database names into a variable called dbnames. After that, it iterates will just echo a string with each name individually
#!/bin/bash
dbnames=`mysql --user=user --password=password -se "show databases;"`
for x in $dbnames;
do
echo "There is a database called $x"
done;
I am trying to create a file and store in it the results from my query. I have a batch file that contains the single query,
USE database1;
SELECT * FROM table WHERE name = "abc" INTO OUTFILE output.txt;
QUIT
Executing this batch file using,
mysql -u root -p -t -vvv < select.sql
However, the result is not table formatted and fields' names are missing from the top.
100 abc Brown 32
101 abc Flair 25
102 abc McDonald 45
.
.
.
If I remove the INTO OUTFILE statement and print the results on terminal, then is working OK.
+----+------+---------+-----+
| id | name | surname | age |
+----+------+---------+-----+
| 100| abc | Brown | 32|
| 101| abc | Flair | 25|
| 102| abc | McDonald| 45|
+----+------+---------+-----+
How can I achieve the above in a txt file?
UPDATE
Special thanks to GreyBeardedGeek. Here is the solution for this question with help of GreyBeardedGeek.
Batch file:
USE database1;
SELECT * FROM table WHERE name = "abc";
QUIT
and mysql client:
mysql -u root -p -t -vvv < select.sql > output.txt
This should do the trick:
mysql -u root -p -t -vvv < select.sql | sed '1 d' > output.txt
You can also do following:
mysql -uroot -p DatabaseName -t -e "select * from table" > file.txt
This doesn't need to make an SQL file and then filter out the first line.
Besides using mysql client program options (mysql --help) one can configure defaults within .my.cnf file. Example (MacOs, Linux) to enable --table option:
edit/create a file:
vim ~/.my.cnf
add/update:
[client]
table
next time you call mysql command line program it will use options from .my.cnf file producing output in table format, e.g. the same as one has called:
mysql ... --table ...
Please note that command line options override options from the .my.cnf files.
References:
call mysql --help for list of options
https://dev.mysql.com/doc/refman/8.0/en/option-files.html
I have several hosts from which i want to do the same query. So imagine, i have on each server the database db and a table test like :
mysql> desc test;
+-------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+-------+
| id | int(10) unsigned | NO | PRI | | |
| data | varchar(255) | YES | | NULL | |
+-------+------------------+------+-----+---------+-------+
Obviously, each table test has different data but they all have the same type.
Let's say i have 2 host : h1 and h2 which host these tables.
Now i need to write a script which do the same query on each host and get the results on standard output. first idea was :
shell> (mysql -h h1 -u myusername -p mypwd -d db -e "select * from test";
mysql -h h2 -u myusername -p mypwd -d db -e "select * from test";)
> out.txt
I want to do it faster, so what i did was :
shell> (mysql -h h1 -u myusername -p mypwd -d db -e "select * from test" &
mysql -h h2 -u myusername -p mypwd -d db -e "select * from test" &)
> out.txt
The problem is that i have some collision in my output file like
458 Karma police
459 876 Paint it black Everything in its right place
460 street spirit
You have two rows on line 2.
My idea was that mysql buffer the result, so the buffer could end in the middle of a row. In this example, the buffer would stop at 459. But i can't figure out how to solve the problem.
Any ideas ?
Use a loop
for host in h1 h2 ; do
mysql -h $host -u myusername -p mypwd -d db -e "select * from test" >> out.txt
done
Using >> appends to the file. Hosts will be accessed in order, not simultaneously, and so all results from h1 will be entered first, then all results from h2. If this is insufficient then there's another option but it's more complex.