• GreatSQL社区原创内容未经授权不得随意运用,转载请联系小编并注明来历。
  • GreatSQL是MySQL的国产分支版本,运用上与MySQL一致。
  • 作者:马铃薯娃娃
  • 文章来历:社区投稿

引言

作为一个MySQL数据库从业者,咱们最常用的东西便是mysql了,然而如何让它变的更好用,你了解吗?

mysql Client Commands

作为衔接MySQL数据库的东西,mysql其实有很多十分有用的指令设置,有一些是咱们日常运用的,比方\g、\G、\q,也有咱们不太常用的\P、\T。今天共享一下我对这些设置的了解,期望能对大家在日常的工作中,有所协助。

支撑哪些设置

mysql供给了help指令,用以阐明支撑哪些指令的设置,咱们先看一下

Great[(none)]> help ;
For information about Percona products and services, visit:
   http://www.percona.com/
Percona Server manual: http://www.percona.com/doc/percona-server/8.0/
For the MySQL Reference Manual: http://dev.mysql.com/
To buy Percona support, training, or other products, visit:
   https://www.percona.com/
List of all MySQL commands:
Note that all text commands must be first on line and end with ';'
?         (\?) Synonym for 'help'.
clear     (\c) Clear the current input statement.
connect   (\r) Reconnect to the server. Optional arguments are db and host.
delimiter (\d) Set statement delimiter.
edit      (\e) Edit command with $EDITOR.
ego       (\G) Send command to mysql server, display result vertically.
exit      (\q) Exit mysql. Same as quit.
go        (\g) Send command to mysql server.
help      (\h) Display this help.
nopager   (\n) Disable pager, print to stdout.
notee     (\t) Don't write into outfile.
pager     (\P) Set PAGER [to_pager]. Print the query results via PAGER.
print     (\p) Print current command.
prompt    (\R) Change your mysql prompt.
quit      (\q) Quit mysql.
rehash    (\#) Rebuild completion hash.
source    (\.) Execute an SQL script file. Takes a file name as an argument.
source_decrypt Execute an encrypted script file. Takes file name, decrypt key as arguments.
status    (\s) Get status information from the server.
system    (\!) Execute a system shell command.
tee       (\T) Set outfile [to_outfile]. Append everything into given outfile.
use       (\u) Use another database. Takes database name as argument.
charset   (\C) Switch to another charset. Might be needed for processing binlog with multi-byte charsets.
warnings  (\W) Show warnings after every statement.
nowarning (\w) Don't show warnings after every statement.
resetconnection(\x) Clean session context.
query_attributes Sets string parameters (name1 value1 name2 value2 ...) for the next query to pick up.
For server side help, type 'help contents'

?

显现协助信息,列出一切支撑的操作指令,这个最简略,就不做进一步阐明晰。

clear(\c)

MySQL手册介绍为铲除当时输入的SQL句子,我个人更乐意了解为撤销已输入SQL的履行。看下面的例子:

Great[test]> select * from tt1;
+------+------+------+------+
| id   | dd   | c1   | c2   |
+------+------+------+------+
|    1 | aaa  | NULL | NULL |
|    2 | bbb  | NULL | NULL |
|    3 | NULL | NULL | NULL |
|    4 | 8    | NULL | NULL |
|    5 | NULL | NULL | NULL |
+------+------+------+------+
5 rows in set (0.01 sec)
Great[test]> delete from tt1 
    -> where id = 5 
    -> and c1 is not null
    -> 

当我输入完上面的SQL时,发现逻辑未考虑全,不想履行这个SQL了,怎么办呢?这儿有好几种解决办法:你能够ctrl+c 停止指令的履行,也能够封闭当时的mysql客户端,乃至封闭操作指令的电脑。然后有一种规范且简略的方法,便是在指令的最后加上\c,就能够实现:

Great[test]> delete from tt1
    -> where id = 5 
    -> and c1 is not null
    -> \c
Great[test]>

能够看到,在指令窗口最后输入\c后,SQL不会被履行,而且从头启动新的指令行接收客户端输入。需求留意的是:\c和需求撤销的SQL间,不能有分隔符(默许为分号;),否则会先履行分隔符前面的SQL,然后再履行\c,这时就达不到撤销已输入SQL履行的作用了。

connect(\r)

从头衔接数据库服务端,支撑重连进程中,指定database姓名和衔接主机。

这个功能看起来好像没什么新奇的,客户端履行了SQL,就算衔接超时了,默许状况下,主动就会从头衔接服务端。

可是在MGR、主从复制场景下,假如一切实例的保护账号都具有相同的用户名、暗码、端口,那么经过\r就很便利的切换多个实例进行保护,而不需求从头输入其他衔接信息

Great[test]> select @@report_host;
+---------------+
| @@report_host |
+---------------+
| 172.16.50.82  |
+---------------+
1 row in set (0.00 sec)
Great[test]> \r test 172.16.50.81
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Connection id:    911698
Current database: test
Great[test]> select @@report_host;
+---------------+
| @@report_host |
+---------------+
| 172.16.50.81  |
+---------------+
1 row in set (0.00 sec)
Great[test]> 

重连信息中的ip地址,也能够是在/etc/hosts中配置的主机名

Great[test]> select @@report_host;
+---------------+
| @@report_host |
+---------------+
| 172.16.50.81  |
+---------------+
1 row in set (0.00 sec)
Great[test]> \r test Great82
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Connection id:    2460607
Current database: test
Great[test]> select @@report_host;
+---------------+
| @@report_host |
+---------------+
| 172.16.50.82  |
+---------------+
1 row in set (0.00 sec)
Great[test]>

delimiter(\d)

自定义分隔符,在创立、修正存储进程、函数、触发器、事情、视图都会用到,替换用于替换默许的分号分隔符。

edit(\e)

官网解说说指令用于修正当时输入SQL指令,默许的修正器是vi,也能够经过设置环境变量EDITOR来改变成其他的修正器,比方调整为vim修正器export EDITOR=$(which vim)

有这个指令后,输出错误的SQL,就不需求再用\c停止了,而是直接在其后加上\e进行修正,修正成正确的后,再履行。

比方我实际上想要履行的指令中tt2表不存在,那么只需求经过\e更新SQL句子中的表姓名就能够持续履行,不需求再从头修正整条SQL。

Great[test]> select * from test.tt2 \e

vi中替换表姓名的操作就不再演示了,修正后的履行状况如下:

Great[test]> select * from test.tt2 \e
    -> ;
+------+------+------+------+
| id   | dd   | c1   | c2   |
+------+------+------+------+
|    1 | aaa  | NULL | NULL |
|    2 | bbb  | NULL | NULL |
|    3 | NULL | NULL | NULL |
|    4 | 8    | NULL | NULL |
|    5 | NULL | NULL | NULL |
+------+------+------+------+
5 rows in set (0.01 sec)
Great[test]>

另外在测验进程中,还发现\e能够对上一次履行的SQL进行修正,即独自履行\e时,其实是对前次履行的SQL指令做修正。

Great[test]> \e
select * from test.tt1

这儿有人就会想到,我按向上的方向键,也能修正上一条SQL呀,何必这么费事,这儿有下面的SQL状况,有屡次换行,或许结构更杂乱的SQL

Great[test]> select * from test.z1
    -> join test.z2 
    -> using(id)
    -> limit 3;
+------+------+------+
| id   | name | name |
+------+------+------+
|    1 | 11   | 11   |
|    2 | 22   | 22   |
|   11 | 11   | 11   |
+------+------+------+
3 rows in set (0.00 sec)

假如按上的方向键,整个SQL句子结构就发生了变化,本来规整的SQL句子,变成了很长的一行,很难调整,可是运用\e就不会有这种状况,会坚持之前的输入结构,更便利句子的调整

Great[test]> select * from test.z1
    -> join test.z2 
    -> using(id)
    -> limit 3;
+------+------+------+
| id   | name | name |
+------+------+------+
|    1 | 11   | 11   |
|    2 | 22   | 22   |
|   11 | 11   | 11   |
+------+------+------+
3 rows in set (0.00 sec)
Great[test]> \e
select * from test.z1
join test.z2
using(id)
limit 3

另外,有同学常常苦恼,我昨天才输入的SQL指令,假如需求从头履行,又得输入一遍,其实这儿也有一个小技巧,经过快捷键CTRL+R,输入SQL中的要害信息(比方表姓名),就能快速翻出对应的SQL,假如匹配出来的行不是想要的SQL,能够持续按CTRL+R持续上翻,直到查找到需求的SQL,当然,也有可能需求的SQL现已被清理出历史记载中,这种状况是无法被找到的。

ego(\G)

提交SQL句子到服务器,而且将返回的数据列式显现。

exit(\q)

退出mysql客户端衔接。

go(\g)

提交SQL句子到服务器。

pager(\P)

设置pager规矩,对查询成果履行pager规矩后,再输出成果。这也是一个十分有用的设置,咱们常常由于processlist成果太多而不便利检查,需求经过单行grep或许查询information_schema.processlist来实现,有这个东西后,咱们看看作用

Great[test]> show processlist;
+---------+-----------------+--------------------+------+---------+---------+--------------------------------------------------------+----------------------------------+------------+-----------+---------------+
| Id      | User            | Host               | db   | Command | Time    | State                                                  | Info                             | Time_ms    | Rows_sent | Rows_examined |
+---------+-----------------+--------------------+------+---------+---------+--------------------------------------------------------+----------------------------------+------------+-----------+---------------+
|       6 | event_scheduler | localhost          | NULL | Daemon  | 5019248 | Waiting on empty queue                                 | NULL                             | 5019247326 |         0 |             0 |
|      26 | system user     |                    | NULL | Connect | 5018577 | waiting for handler commit                             | Group replication applier module | 5018576436 |         0 |             0 |
|      29 | system user     |                    | NULL | Query   |    1010 | Slave has read all relay log; waiting for more updates | NULL                             |    1010045 |         0 |             0 |
|      30 | system user     |                    | NULL | Query   |    1010 | Waiting for an event from Coordinator                  | NULL                             |    1010045 |         0 |             0 |
|      31 | system user     |                    | NULL | Query   |  100958 | Waiting for an event from Coordinator                  | NULL                             |  100956966 |         0 |             0 |
|      32 | system user     |                    | NULL | Query   |  100958 | Waiting for an event from Coordinator                  | NULL                             |  100956966 |         0 |             0 |
|      33 | system user     |                    | NULL | Connect | 5018577 | Waiting for an event from Coordinator                  | NULL                             | 5018576419 |         0 |             0 |
|      34 | system user     |                    | NULL | Connect | 5018577 | Waiting for an event from Coordinator                  | NULL                             | 5018576418 |         0 |             0 |
|      35 | system user     |                    | NULL | Connect | 5018577 | Waiting for an event from Coordinator                  | NULL                             | 5018576417 |         0 |             0 |
|      36 | system user     |                    | NULL | Connect | 5018577 | Waiting for an event from Coordinator                  | NULL                             | 5018576415 |         0 |             0 |
|      37 | system user     |                    | NULL | Connect | 5018577 | Waiting for an event from Coordinator                  | NULL                             | 5018576413 |         0 |             0 |
+---------+-----------------+--------------------+------+---------+---------+--------------------------------------------------------+----------------------------------+------------+-----------+---------------+
14 rows in set (0.00 sec)
Great[test]> \P grep -vE 'system user|Sleep'
PAGER set to 'grep -vE 'system user|Sleep''
Great[test]> show processlist;
+---------+-----------------+--------------------+------+---------+---------+--------------------------------------------------------+----------------------------------+------------+-----------+---------------+
| Id      | User            | Host               | db   | Command | Time    | State                                                  | Info                             | Time_ms    | Rows_sent | Rows_examined |
+---------+-----------------+--------------------+------+---------+---------+--------------------------------------------------------+----------------------------------+------------+-----------+---------------+
|       6 | event_scheduler | localhost          | NULL | Daemon  | 5019255 | Waiting on empty queue                                 | NULL                             | 5019255045 |         0 |             0 |
| 2460607 | Great         | 172.16.50.81:59062 | test | Query   |       0 | init                                                   | show processlist                 |          0 |         0 |             0 |
+---------+-----------------+--------------------+------+---------+---------+--------------------------------------------------------+----------------------------------+------------+-----------+---------------+
14 rows in set (0.01 sec)
Great[test]>

pager后边能够跟很多的shell指令,比方awk、grep、wc ,对成果集的处理,当SQL不便利处理而shell便利处理时,不用再运用-e参数每次都进行衔接,然后处理,比方主从结构对Slave_IO_Running、Slave_SQL_Running的监控,可设置pager grep -E 'Slave_IO_Running|Slave_SQL_Running'

pager的另外一个用处:常常有同学问,一些字段中是否有包括某些特定字符串,正常的SQL处理是需求写成col1 like ‘%abc%’ or col2 like ‘%abc%’…,写出来后SQL结构相对杂乱,经过pager设置pager grep -i abc; select * from tab即可便利检查。

nopager(\n)

pager的设置是整个session生命周期内都收效,经过履行nopager进行封闭设置

prompt(\R)

修正mysql客户端的指令行提示信息,支撑显现的提示信息十分多,具体能够拜见MySQL官网介绍。修正mysql客户端的指令行提示信息,也有好几种方法:

1、设置操作体系环境变量MYSQL_PS1 export MYSQL_PS1= " \D_\h_\p_\u > ",格式为”时刻_主机_端口_用户名”

2、经过客户端的指令prompt修正 \R \D_\h_\p_\u >

3、经过my.cnf的[mysql]域进行配置

[mysql]
prompt="\R \D_\h_\p_\u > "

4、假如session中经过\R xxx 暂时修正了指令行提示信息,能够经过独自履行\R来恢复默许设置。

quit(\q)

退出当时session衔接。

auto-rehash(#)

在运用mysql客户端衔接服务器时,默许状况下会主动收集一些元数据信息,在后续输入SQL指令时能够经过tab键补齐指令,比方补齐表姓名、列姓名。

Great[test]> select * from tt(此刻按tab键)
tt1     tt1.c1  tt1.c2  tt1.dd  tt1.id  ttt     ttt.id

可是假如在session中新建了表,或许给表上新增了字段,是无法经过tab键补齐的,这时经过\#指令刷新元数据信息,之后就能对新的DDL结构进行补齐

Great[test]> create table tt2 as select * from tt1;
Query OK, 5 rows affected (0.09 sec)
Records: 5  Duplicates: 0  Warnings: 0
Great[test]> select * from tt(此刻按tab键)
tt1     tt1.c1  tt1.c2  tt1.dd  tt1.id  ttt     ttt.id  
Great[test]> \#
Great[test]> select * from tt(此刻按tab键)
tt1     tt1.c1  tt1.c2  tt1.dd  tt1.id  tt2     tt2.c1  tt2.c2  tt2.dd  tt2.id  ttt     ttt.id  
Great[test]> select * from tt

source(.)

指令后需求跟一个文件名,\. filename会对filename文件中的内容按规范SQL进行解析履行。

status(\s)

输出本次衔接的相关信息及服务器的一些信息,假如衔接时指定了--safe-updates,还会输出查询约束相关的信息,\s输出了很多有用的信息,可仔细阅读。

[#8#root@Great81 ~ 20:26:13]8 m5 3306 --safe-updates
greatsql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 916197
********
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
Great[(none)]> \s
--------------
********
Connection id:  916197
Current database: 
Current user:  Great@127.0.0.1
SSL:   Cipher in use is ECDHE-RSA-AES128-GCM-SHA256
Current pager:  stdout
Using outfile:  ''
Using delimiter: ;
**********
Protocol version: 10
Connection:  127.0.0.1 via TCP/IP
Server characterset: utf8mb4
Db     characterset: utf8mb4
Client characterset: utf8mb4
Conn.  characterset: utf8mb4
TCP port:  3306
Binary data as:  Hexadecimal
Uptime:   51 days 9 hours 5 min 13 sec
Threads: 16  Questions: 4354604  Slow queries: 339  Opens: 19188  Flush tables: 3  Open tables: 6095  Queries per second avg: 0.980
Note that you are running in safe_update_mode:
UPDATEs and DELETEs that don't use a key in the WHERE clause are not allowed.
(One can force an UPDATE/DELETE by adding LIMIT # at the end of the command.)
SELECT has an automatic 'LIMIT 1000' if LIMIT is not used.
Max number of examined row combination in a join is set to: 1000000
--------------
Great[(none)]>Great

system(!)

运用默许指令解说器履行给定指令,简略的说便是返回到操作体系履行\!之后的指令,比方下面

Great[(none)]> \! date
2022年 11月 16日 星期三 20:32:34 CST
Great[(none)]> \! pwd
/root
Great[(none)]> \! cd /Great
Great[(none)]> \! vmstat -w
procs -----------------------memory---------------------- ---swap-- -----io---- -system-- --------cpu--------
 r  b         swpd         free         buff        cache   si   so    bi    bo   in   cs  us  sy  id  wa  st
 1  0            0       358508            0      3117236    0    0   486    20    0    0   5   3  92   0   0
Great[(none)]>

在8.0.19之前,只支撑在unix体系中运用该指令,到8.0.19后,在windows中也支撑了该指令。

tee(\T)

将一切履行的SQL指令及输出成果保存到指定文件中。这在调测、出产保护进程中,都是十分有用的一个功能,特别是一些安全要求高的环境中,控制台只能显现几十行指令时,想要查找之前履行的指令及履行的成果比较难,此刻就能用上\T了。

Great[(none)]> \T /root/a.log
Logging to file '/root/a.log'
Great[(none)]> select * from test.tt1;
+------+------+------+------+
| id   | dd   | c1   | c2   |
+------+------+------+------+
|    1 | aaa  | NULL | NULL |
|    2 | bbb  | NULL | NULL |
|    3 | NULL | NULL | NULL |
|    4 | 8    | NULL | NULL |
|    5 | NULL | NULL | NULL |
+------+------+------+------+
5 rows in set (0.01 sec)
Great[(none)]> \! cat /root/a.log
Great[(none)]> select * from test.tt1;
+------+------+------+------+
| id   | dd   | c1   | c2   |
+------+------+------+------+
|    1 | aaa  | NULL | NULL |
|    2 | bbb  | NULL | NULL |
|    3 | NULL | NULL | NULL |
|    4 | 8    | NULL | NULL |
|    5 | NULL | NULL | NULL |
+------+------+------+------+
5 rows in set (0.01 sec)
Great[(none)]> 

假如想要记载每个人登录数据库,做了哪些操作,由于tee不支撑依据当时时刻动态产生日志文件名,咱们能够这样设置

## 首先创立一个log目录
mkdir -p /Great/logs/client/
## 然后设置环境变量,为了衔接安全,主张运用--login-path的方法进行登录,我这儿运用的是gdb1登录。
echo "alias mlogin='mysql --login-path=gdb1 --tee /Great/logs/client/\$(date +%Y-%m-%d_%H-%M-%S).log'" >> ~/.bashrc; source ~/.bashrc
[#15#root@Great81 /Great/logs/client 20:48:53]15 echo "alias mlogin='mysql --login-path=gdb1 --tee /Great/logs/client/$(date +\"%Y-%m-%d_%H-%M\").log'" >> ~/.bashrc; source ~/.bashrc
## 经过设置的alias登录数据库
[#16#root@Great81 /Great/logs/client 20:49:43]16 mlogin 
Logging to file '/Great/logs/client/2022-11-16_20-49.log'
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 916482
Great
Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show tables from tpcc;
+------------------+
| Tables_in_tpcc   |
+------------------+
| bmsql_config     |
| bmsql_customer   |
| bmsql_district   |
| bmsql_history    |
| bmsql_item       |
| bmsql_new_order  |
| bmsql_oorder     |
| bmsql_order_line |
| bmsql_stock      |
| bmsql_warehouse  |
| datatypes1       |
| datatypes10      |
| datatypes11      |
| datatypes2       |
| datatypes3       |
| datatypes4       |
| datatypes5       |
| datatypes6       |
| datatypes7       |
| datatypes8       |
| datatypes9       |
+------------------+
21 rows in set (0.00 sec)
mysql>

咱们发现指定的日志目录中,现已有了日志文件,而且记载了一切履行的SQL及输出成果

[#9#root@Great81 ~ 20:51:43]9 cd /Great/logs/client/
[#10#root@Great81 /Great/logs/client 20:51:48]10 ll
总用量 8
-rw-r--r-- 1 root root  627 1116 20:48 2022-11-16_20-48.log
-rw-r--r-- 1 root root 3214 1116 20:50 2022-11-16_20-49.log
[#11#root@Great81 /Great/logs/client 20:51:48]11

notee(\t)

撤销\T设置,不再记载操作信息到日志文件中。

use(\u)

切换当时衔接的database。

warnings(\W)

在履行完SQL句子后,当即显现warning信息,不需求再手动履行show warnings;了。

nowarnings(\w)

在履行完SQL句子后,不当即显现warning信息,需求手动履行show warnings;才会显现warning信息。

resetconnection(\x)

以新衔接的状态从头衔接到服务器,而且进行一些信息的清理及复位,不需求再次进行权限验证。主要影响如下信息:

  1. 回滚一切活动的业务,并重置主动提交形式。
  2. 一切DML锁均已开释。
  3. 一切TEMPORARY table 均已封闭(并删去)。
  4. 会话体系变量将从头初始化。
  5. 用户变量设置丢掉。
  6. 准备好的句子被开释。
  7. HANDLER封闭。
  8. LAST_INSERT_ID 置为 0。
  9. 用 GET_LOCK 开释。

能够参阅8.0.26的代码libmysql.cc中4429~4444行

int STDCALL mysql_reset_connection(MYSQL *mysql) {
  DBUG_TRACE;
  if (simple_command(mysql, COM_RESET_CONNECTION, nullptr, 0, 0))
    return 1;
  else {
    mysql_detach_stmt_list(&mysql->stmts, "mysql_reset_connection");
    /* reset some of the members in mysql */
    mysql->insert_id = 0;
    mysql->affected_rows = ~(uint64_t)0;
    free_old_query(mysql);
    mysql->status = MYSQL_STATUS_READY;
    mysql_extension_bind_free(MYSQL_EXTENSION_PTR(mysql));
    return 0;
  }
}

query_attributes

经过query_attributes var1 value1 var2 value2来设置变量,然后经过mysql_query_attribute_string('var1')返回变量值value1,目前来看,并没有发现特别的运用方法,究竟咱们也能够经过set @var1='value1'来设置。

运用体会

mysql Client Commands在某些场景下,能够极大的提高咱们的操作效率,相对于完好的指令ego、pager、edit等,我更喜爱运用他们的简写指令\G、\P、\e,由于有时候完好指令不确定如何正确运用,会导致不收效,可是简写指令,是一定会收效的。

参阅文章

MySQL 8.0 Reference Manual 4.5.1.2 mysql Client Commands

MySQL 8.0 Reference Manual 9.6 Query Attributes


Enjoy GreatSQL :)

关于 GreatSQL

GreatSQL是由万里数据库保护的MySQL分支,专注于提高MGR可靠性及功能,支撑InnoDB并行查询特性,是适用于金融级应用的MySQL分支版本。

相关链接: GreatSQL社区 Gitee GitHub Bilibili

GreatSQL社区:

捉虫活动详情:greatsql.cn/thread-97-1…

社区博客有奖征稿详情:greatsql.cn/thread-100-…

MySQL客户端的进阶操作