6.5.1.6 mysqladmin — MySQL 服务器管理程序
本节提供了关于如何更有效地使用mysql的技巧,以及关于mysql操作行为的信息。
mysql支持输入行编辑,这使您可以在当前输入行中进行修改或回忆之前的输入行。例如,左箭头和右箭头键水平移动光标位置,而上箭头和下箭头键向上或向下移动之前输入的行。退格键删除光标前面的字符,而输入新字符时,光标位置前的字符会被替换为这些新字符。要提交当前行,请按Enter。
在 Windows 上,编辑键序列与支持的命令编辑键序列相同,可以在控制台窗口中使用。在 Unix 上,键序列取决于用于构建mysql的输入库(例如,libedit
或readline
库)。
对于 libedit
和 readline
库的文档可在线获取。要更改由给定输入库允许的键序列,可以在启动文件中定义键绑定。这是一个位于您的主目录中的文件:.editrc
对于 libedit
,以及 .inputrc
对于 readline
。
例如,在 libedit
中,Ctrl+W 删除光标前面的所有字符,而 Ctrl+U 则删除整行。在 readline
中,Ctrl+W 删除光标前的单词,而 Ctrl+U 删除光标前面的所有字符。如果使用 mysql 构建了使用 libedit
的版本,那么偏好 readline
行为的用户可以将以下两行放入 .editrc
文件中(如果文件不存在则创建):
bind "^W" ed-delete-prev-word
bind "^U" vi-kill-line-prev
要查看当前的键绑定,可以临时在 .editrc
的末尾添加一行只包含 bind
。mysql 在启动时显示绑定。
上箭头 键允许您回忆当前和之前会话的输入行。在共享控制台的情况下,这种行为可能不适宜。mysql 支持部分或完全禁用交互式历史,取决于宿主平台。
在Windows上,历史记录被存储在内存中。 Alt+F7 删除当前历史缓冲区中所有输入行,并且删除使用 F7 显示的序列号前面的列表,以及使用 F9 通过数字回忆的输入行。新输入的行在按下 Alt+F7 后会重新填充当前历史缓冲区。清除缓冲区不会阻止日志记录到Windows事件查看器,如果使用了 --syslog
选项启动 mysql。关闭控制台窗口也会清除当前历史缓冲区。
要在Unix上禁用交互式历史记录,首先删除 .mysql_history
文件,如果它存在(否则之前的输入将被回忆)。然后使用 --histignore="*"
选项启动 mysql 来忽略所有新输入的行。要重新启用回忆(和日志记录)功能,请不带选项重启 mysql。
如果您防止了 .mysql_history
文件的创建(请参阅控制历史文件)并使用 --histignore="*"
选项启动 mysql,则交互式历史记录回忆功能将被完全禁用。或者,如果省略了 --histignore
选项,您可以回忆当前会话期间输入的行。
Unicode 支持 on Windows
Windows 提供基于UTF-16LE 的APIs 来读取和写入控制台; mysql 客户端在Windows上可以使用这些APIs。Windows 安装程序创建了一个名为 MySQL command line client - Unicode
的菜单项。这一项启动了 mysql,并设置了属性,以便通过Unicode字符集与MySQL服务器通信。
要利用这一支持手动,您可以在一个使用兼容Unicode字体的控制台中运行 mysql,并将默认字符集设置为与服务器通信支持的Unicode字符集:
-
打开一个控制台窗口。
-
转到控制台窗口属性,选择字体标签,并选择Lucida Console或其他兼容的Unicode字体。这是必要的,因为控制台窗口默认使用DOS栅格字体,这种字体对于Unicode来说是不够的。
-
执行 mysql.exe,并使用
--default-character-set=utf8mb4
(或utf8mb3
)选项。这一选项是必要的,因为utf16le
是不能用作客户端字符集的字符集。请参阅不允许的客户端字符集。
在进行了这些更改后, mysql 使用Windows API通过UTF-16LE与控制台通信,并通过UTF-8与服务器通信。(前面提到的菜单项设置了字体和字符集。)
要避免每次运行 mysql 时执行这些步骤,您可以创建一个快捷方式,该快捷方式启动 mysql.exe。该快捷方式应该设置控制台字体为Lucida Console或其他兼容的Unicode字体,并将 --default-character-set=utf8mb4
(或 utf8mb3
)选项传递给 mysql.exe。
或者,您可以创建一个只设置控制台字体的快捷方式,并在您的 my.ini
文件中的 [mysql]
组中设置字符集:
[mysql]
default-character-set=utf8mb4 # or utf8mb3
有些查询结果在以垂直方式显示时更易于阅读,而不是使用通常的水平表格格式。可以通过将查询以 \G 结尾而不是分号来垂直显示查询。例如,包含换行符的长文本值经常在垂直输出中更容易阅读:
mysql> SELECT * FROM mails WHERE LENGTH(txt) < 300 LIMIT 300,1\G
*************************** 1. row ***************************
msg_nro: 3068
date: 2000-03-01 23:29:50
time_zone: +0200
mail_from: Jones
reply: jones@example.com
mail_to: "John Smith" <smith@example.com>
sbj: UTF-8
txt: >>>>> "John" == John Smith writes:
John> Hi. I think this is a good idea. Is anyone familiar
John> with UTF-8 or Unicode? Otherwise, I'll put this on my
John> TODO list and see what happens.
Yes, please do that.
Regards,
Jones
file: inbox-jani-1
hash: 190402944
1 row in set (0.09 sec)
对于初学者来说,有一个有用的启动选项是 --safe-updates
(或--i-am-a-dummy
,效果相同)。安全更新模式对于在忘记指定要修改的行时使用 UPDATE 或 DELETE 语句非常有用。通常,这样的语句会更新或删除表中的所有行。在 --safe-updates
模式下,您只能通过指定键值来修改行,或者使用 LIMIT 子句,或者两者都可以。这有助于防止意外的操作。安全更新模式还限制了 SELECT 语句,这些语句产生(或估计将产生)非常大的结果集。
--safe-updates
选项会导致 mysql 在连接到 MySQL 服务器时执行以下语句,以设置会话值的 sql_ safe_updates
、sql_select_limit
和 max_join_size
系统变量:
SET sql_safe_updates=1, sql_select_limit=1000, max_join_size=1000000;
SET
语句对语句处理的方式如下:
-
启用
sql_ safe_updates
会导致 UPDATE 和 DELETE 语句在没有指定 WHERE 子句中的键约束,或者提供 LIMIT 子句,或者两者都有时产生错误。例如:UPDATE tbl_name SET not_key_column=val WHERE key_column=val; UPDATE tbl_name SET not_key_column=val LIMIT 1;
-
将
sql_select_limit
设为 1,000 会导致服务器限制所有 SELECT 结果集的大小,除非语句包含 LIMIT 子句。 -
将
max_join_size
设为 1,000,000 会导致多表 SELECT 语句产生错误,如果服务器估计必须检查超过 1,000,000 行组合。
要使用不同的结果集限制,可以通过在调用 mysql 时指定 --select-limit
和 --max-join-size
选项来覆盖默认值:
mysql --safe-updates --select-limit=500 --max-join-size=10000
即使在安全更新模式下,UPDATE 和 DELETE 语句也可能因为指定了 WHERE 子句中的键而产生错误,如果优化器决定不使用该索引上的键列:
-
如果内存使用超过由
range_ optimizer_max_mem_size
系统变量指定的限制,无法进行基于范围的索引访问。优化器然后退回到表扫描。请参阅 为范围优化限制内存使用。 -
如果键比较需要类型转换,索引可能不会被使用(请参阅第10.3.1节,“MySQL如何使用索引”)。假设有一个带有索引的字符串列
c1
,它被比较为一个数字值使用WHERE c1 = 2222
。对于这样的比较,字符串值会转换为数字,然后操作数将按数字进行比较(请参阅第14.3节,“表达式求值时的类型转换”),这会阻止索引的使用。如果启用了安全更新模式,会发生错误。
这些行为在安全更新模式下是包含的:
-
EXPLAIN
与UPDATE
和DELETE
语句的使用不会产生安全更新错误。这使得可以使用EXPLAIN
加上SHOW WARNINGS
来查看为什么索引不会被使用,这在发生像范围优化器最大内存大小限制或类型转换这样的情况时特别有用,尽管一个键列在WHERE
子句中被指定,但优化器仍然没有使用索引。 -
当安全更新错误发生时,错误消息会包含第一个诊断信息,以提供失败原因的信息。例如,消息可能指出范围优化器最大内存大小限制或类型转换已经发生,这些都可以阻止索引的使用。
-
对于多表删除和更新操作,在安全更新模式下只有当任何目标表使用了表扫描时才会产生错误。
如果mysql客户端与服务器之间的连接丢失,发送语句时,它会立即尝试重新连接一次以发送语句。然而,即使mysql成功重连,第一次连接已经结束,你的所有先前会话对象和设置都将丢失:临时表、自动提交模式以及用户定义和会话变量。同样,任何当前的事务都会回滚。这一行为可能对你有危险,因为在以下示例中,服务器在第一个和第二个语句之间被关闭并重启,而你不知道这一点:
mysql> SET @a=1;
Query OK, 0 rows affected (0.05 sec)
mysql> INSERT INTO t VALUES(@a);
ERROR 2006: MySQL server has gone away
No connection. Trying to reconnect...
Connection id: 1
Current database: test
Query OK, 1 row affected (1.30 sec)
mysql> SELECT * FROM t;
+------+
| a |
+------+
| NULL |
+------+
1 row in set (0.05 sec)
@a用户变量已经在连接丢失时丢失了,与重新连接后是未定义的。如果需要mysql在连接丢失时终止,请使用--skip-reconnect
选项启动mysql客户端。
有关自动重连及其在发生重新连接时对状态信息的影响的更多信息,请参阅自动重连控制。
mysql客户端使用一个在客户端运行的解析器,该解析器不是服务器端完整解析器的副本。这可能导致某些构造的不同对待。例如:
-
服务器解析器将以
"
字符作为标识符而非普通字符串处理,如果启用了ANSI_QUOTES SQL模式。mysql客户端解析器不考虑ANSI_QUOTES SQL模式。它将以
"
、'
和`
字符相同处理字符串,无论是否启用了ANSI_QUOTES
。 -
在
/*! ... */
和/*+ ... */
注释中,mysql 客户端解析器会解释短语格式的 mysql 命令。服务器解析器不会解释它们,因为这些命令在服务器端没有意义。如果希望 mysql 不解释短语格式的命令,特别是在注释中,可以使用
--binary-mode
选项,这样所有 mysql 命令都将被禁用,除了在非交互模式下(即输入通过 mysql 或使用source
命令加载)中的 \C 和 \d 命令。