mysql 登录socket与TCP
对oracle 登录的很清楚
sqlplus / as sysdba
sqlplus scott/tiger
这种登录方式属于本地登录,不走网络,跟监听没有关系,登录的实例为在环境变量中设置的$ORACLE_SID
sqlplus scott/tiger@orcl
这种登录方式即使在服务器上登录也是通过网络,需要监听配置的。
转向mysql时,好久也没搞明白mysql的登录
今天明白了一点点,先记录一下,后续再补充。
1. socket
socket是用于同一台主机的进程间通讯(IPC),不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序号和应答等,只是将应用层数据从一个进程拷贝到另外一个进程,消息既不会丢失也不会顺序错乱。
一般在配置文件中会配置
[root@MySQL56_L1 ~]# more /etc/my.cnf [client] port = 3306 socket = /tmp/mysql3306.sock
select user,host,plugin from user where user ='root';
+------+-----------+-----------------------+
| user | host | plugin |
+------+-----------+-----------------------+
| root | % | mysql_native_password |
| root | 127.0.0.1 | mysql_native_password |
| root | localhost | caching_sha2_password |
+------+-----------+-----------------------+
原来root 通过-h127.0.0.1登录时使用的是 mysql_native_password, 而默认修改密码使用的插件是caching_sha2_password
所以需要修改密码时加入with mysql_native_password
alter user root@'127.0.0.1' identified with mysql_native_password by 'abc123';
2,使用TCP方式登录
登录时指定 -h -P 。
使用-h127.0.0.1登录时,使用select user()查询到的是 username@'127.0.0.1'
在服务器上使用-h192.0.2.101 指定服务器ip地址登录时, select user()查询到的是 username@'192.0.2.101'
都差点让我误以为 -h指定的是客户端的连接所用的ip地址了。
简单说一下user()与current_user函数的区别
(1)MySQL USER()函数用于为用户正在使用的MySQL连接返回当前用户名和主机名。此函数使用utf8字符集。 USER()函数不需要传递任何参数。
USER()函数返回的用户名是连接到服务器时指定的用户名,而USER()函数返回的主机名是用户用来建立连接的客户端主机名。
(2)MySQL中的CURRENT_USER()函数用于返回MySQL帐户的用户名和主机名,服务器使用该帐户对当前客户端进行身份验证。相当于查询的
select concat(user,'@',host) from mysql.user;
原文链接:https://blog.csdn.net/lianggx3/article/details/116377989
mysql kill会话
在MySQL中有两个kill命令:一个是kill query +线程id,表示终止这个线程中正在执行的语句;一个是kill connection +线程id,这里connection可缺省,表示断开这个线程的连接,当然如果这个线程有语句正在执行,也是要先停止正在执行的语句的。
-
通过MySQL客户端登录时,会话重新连接的选项
--reconnect
默认是开启的,如果要禁止重新连接可在登录时添加 --skip-reconnect -
KILL CONNECTION
与KILL
相同,它在终止连接正在执行的任何语句后,再终止会话连接。 -
KILL QUERY
终止连接当前正在执行的语句,但保持连接本身不变。
kill并不是马上停止的意思,而是告诉执行线程说,这条语句已经不需要继续执行了,可以开始“执行停止的逻辑了”,例如释放锁。
当用户执行kill query thread_id_B时,MySQL里处理kill命令的线程做了两件事:
1. 把session B的运行状态改成THD::KILL_QUERY(将变量killed赋值为THD::KILL_QUERY);
2. 给session B的执行线程发一个信号。
第一步把状态置为THD::KILL_QUERY,但是可能线程当时正在等待锁之类的无法判断的状态的,所以就要发出一条信号。上面的分析中,隐含了这么三层意思:
1. 一个语句执行过程中有多处“埋点”,在这些“埋点”的地方判断线程状态,如果发现线程状态是THD::KILL_QUERY,才开始进入语句终止逻辑;
2. 如果处于等待状态,必须是一个可以被唤醒的等待,否则根本不会执行到“埋点”处;
3. 语句从开始进入终止逻辑,到终止逻辑完全完成,是有一个过程的。
线程的Commnad列显示的是Killed。客户端虽然断开了连接,但实际上服务端上这条语句还在执行过程中。
在实现上,等行锁时,使用的是pthread_cond_timedwait函数,这个等待状态可以被唤醒。但是,在这个例子里,12号线程的等待逻辑是这样的:每10毫秒判断一下是否可以进入InnoDB执行,如果不行,就调用nanosleep函数进入sleep状态。
虽然12号线程的状态已经被设置成了KILL_QUERY,但是在这个等待进入InnoDB的循环过程中,并没有去判断线程的状态,因此根本不会进入终止逻辑阶段。而当session E执行kill connection 命令时,是这么做的,
1. 把12号线程状态设置为KILL_CONNECTION;
2. 关掉12号线程的网络连接。因为有这个操作,所以你会看到,这时候session C收到了断开连接的提示。
终止逻辑耗时较长
1. 超大事务执行期间被kill。这时候,回滚操作需要对事务执行期间生成的所有新数据版本做回收操作,耗时很长。
2. 大查询回滚。如果查询过程中生成了比较大的临时文件,加上此时文件系统压力大,删除临时文件可能需要等待IO资源,导致耗时较长。
3. DDL命令执行到最后阶段,如果被kill,需要删除中间过程的临时文件,也可能受IO资源影响耗时较久。
Ctril+C命令
执行Ctrl+C的时候,是MySQL客户端另外启动一个连接,然后发送一个kill query 命令。
表多连接就慢吗?
当使用默认参数连接的时候,MySQL客户端会提供一个本地库名和表名补全(使用Tab键)的功能。为了实现这个功能,客户端在连接成功后,需要多做一些操作:
1. 执行show databases;
2. 切到db1库,执行show tables;
3. 把这两个命令的结果用于构建一个本地的哈希表。
上面的第三步,是很花时间的,加上命令的-A可以跳过这个功能。加上–quick也可以跳过这个阶段。但是,–quick有一个问题,先看看mySQL客户端发送请求后,接收服务端返回结果的两种方式:
1. 一种是本地缓存,也就是在本地开一片内存,先把结果存起来。如果你用API开发,对应的就是mysql_store_result 方法。
2. 另一种是不缓存,读一个处理一个。如果你用API开发,对应的就是mysql_use_result方法。
加上–quick参数,就会使用第二种不缓存的方式,这时如果本地处理得慢,就会导致服务端发送结果被阻塞,因此会让服务端变慢。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?