首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答
筛选
回答情况:
全部无回答回答未采纳
提问时间:
不限一周内一月内三月内一年内
回答标签:
sql

CPU 100%,MySQL 到底在干什么?

lllspeed
回答来自于问答智囊团成员:王文安@DBA 专栏:https://cloud.tencent.com/developer/user/7566357 怎么看懂 CPU 使用率 以 Linux 的 top 命令为例,效果如下: 📷 Top 命令 在 %CPU 这一列就展示了 CPU 的使用情况,百分比指代的是总体上占用的时间百分比: %us:表示用户进程的 CPU 使用时间(没有通过 nice 调度) %sy:表示系统进程的 CPU 使用时间,主要是内核使用。 %ni:表示用户进程中,通过 CPU 调度(nice)过的使用时间。 %id:空闲的 CPU 时间 %wa:CPU 运行时在等待 IO 的时间 %hi:CPU 处理硬中断花费的时间 %si:CPU 处理软中断花费的时间 %st:被虚拟机偷走的 CPU 时间 通常情况下,我们讨论的 CPU 使用率过高,指的是 %us 这个指标,监控里面的 CPU 使用率通常也是这个值(也有用其他的方法计算出来的,不过简单起见,不考虑其他的情况 )。其他几个指标过高也代表出 MySQL 的状态异常,简单起见,这里主要还是指 %us 过高的场景。 MySQL 和线程 MySQL 是单进程多线程的结构,意味着独占的 MySQL 服务器里面,只能用 top 命令看到一行数据。 📷 TOP 命令效果 这里能看到的是 MySQL 的进程 ID,如果要看到线程的情况,需要用top -H 📷 TOP 命令效果 在这里能看到的是 MySQL 各个线程的 ID,可以看到 MySQL 在启动之后,会创建非常多的内部线程来工作。 这些内部线程包括 MySQL 自己用来刷脏,读写数据等操作的系统线程,也包括处理用户 SQL 的线程,姑且叫做用户线程吧。用户线程有一个特殊的地方:程序端发送到 MySQL 端的 SQL,只会由一个用户线程来执行(one-thread-per-connection),所以 MySQL 在处理复杂查询的时候,会出现“一核有难,多核围观”的尴尬现象。 参考 %us 的定义,对于 Linux 系统来说,MySQL 进程和它启动的所有线程都不算内核进程,因此 MySQL 的系统线程和用户线程在繁忙的时候,都会体现在 CPU 使用率的 %us 指标上。 MySQL 干什么的时候,CPU 会 100% 从前文的分析来看,MySQL 主要是两类线程占用 CPU:系统线程和用户线程。因此 MySQL 独占的服务器上,只需要留意一下这两类线程的情况,就能 Cover 住绝大部分的问题场景。 系统线程 在实际的环境中,系统线程遇到问题的情况会比较少,一般来说,多个系统线程很少会同时跑满,只要服务器的可用核心数大于等于 4 的话,一般也不会遇到 CPU 100%,当然有一些 bug 可能会有影响,比如这个: 📷 MySQL BUG 虽然情况比较少,但是在面对问题的常规排查过程中,系统线程的问题也是需要关注的。 用户线程 提到用户线程繁忙,很多时候肯定会第一时间凭经验想到慢查询。确实 90% 以上的时候都是“慢查询”引起的,不过作为方法论,还是要根据分析再去得出结论的~ 参考 us% 的定义,是指用户线程占用 CPU 的时间多少,这代表着用户线程占用了大量的时间。 一方面是在进行长时间的计算,例如:order by,group by,临时表,join 等。这一类问题可能是查询效率不高,导致单个 SQL 语句长时间占用 CPU 时间,也有可能是单纯的数据量比较多,导致计算量巨大。另一方面是单纯的 QPS 压力高,所以 CPU 的时间被用满了,比如 4 核的服务器用来支撑 20k 到 30k 的点查询,每个 SQL 占用的 CPU 时间并不多,但是因为整体的 QPS 很高,所以 CPU 的时间被占满了。 怎么定位问题? 分析完之后,就要开始实战了,这里根据前文的分析给出一些经典的 CPU 100% 场景,并给出简要的定位方法作为参考。 PS:系统线程的 bug 的场景 skip,以后有机会再作为详细的案例来分析。 慢查询 在 CPU 100% 这个问题已经发生之后,真实的慢查询和因为 CPU 100% 导致被影响的普通查询会混在一起,难以直观的看 processlist 或者 slowlog 来发现元凶,这时候就需要一些比较明确的特征来进行甄别。 从前文的简单分析可以看出来,查询效率不高的慢查询通常有以下几种情况: 全表扫描:Handler_read_rnd_next 这个值会大幅度突增,且这一类查询在 slowlog 中 row_examined 的值也会非常高。 索引效率不高,索引选错了:Handler_read_next 这个值会大幅度的突增,不过要注意这种情况也有可能是业务量突增引起的,需要结合 QPS/TPS 一起看。这一类查询在 slowlog 中找起来会比较麻烦,row_examined 的值一般在故障前后会有比较明显的不同,或者是不合理的偏高。 比如数据倾斜的场景,一个小范围的 range 查询在某个特定的范围内 row_examined 非常高,而其他的范围时 row_examined 比较低,那么就可能是这个索引效率不高。 排序比较多:order by,group by 这一类查询通常不太好从 Handler 的指标直接判断,如果没有索引或者索引不好,导致排序操作没有消除的话,那么在 processlist 和 slowlog 通常能看到这一类查询语句出现的比较多。 当然,不想详细的分析 MySQL 指标或者是情况比较紧急的话,可以直接在 slowlog 里面用 rows_sent 和 row_examined 做个简单的除法,比如 row_examined/rows_sent > 1000 的都可以拿出来作为“嫌疑人”处理。这类问题一般在索引方面做好优化就能解决。 PS:1000 只是个经验值,具体要根据实际业务情况来定。 计算量大 这一类问题通常是因为数据量比较大,即使索引没什么问题,执行计划也 OK,也会导致 CPU 100%,而且结合 MySQL one-thread-per-connection 的特性,并不需要太多的并发就能把 CPU 使用率跑满。这一类查询其实是是比较好查的,因为执行时间一般会比较久,在 processlist 里面就会非常显眼,反而是 slowlog 里面可能找不到,因为没有执行完的语句是不会记录的。 这一类问题一般来说有三种比较常规的解决方案: 读写分离,把这一类查询放到平时业务不怎么用的只读从库去。 在程序段拆分 SQL,把单个大查询拆分成多个小查询。 使用 HBASE,Spark 等 OLAP 的方案来支持。 高 QPS 这一类问题单纯的就是硬件资源的瓶颈,不论是 row_examined/rows_sent 的比值,还是 SQL 的索引、执行计划,或者是 SQL 的计算量都不会有什么明显问题,只是 QPS 指标会比较高,而且 processlist 里面可能什么内容都看不到,例如: 📷 processlist 总结一下 实际上 CPU 100% 的问题其实不仅仅是单纯的 %us,还会有 %io,%sys 等,这些会涉及到 MySQL 与 Linux 相关联的一部分内容,展开来就会比较多了。本文仅从 %us 出发尝试梳理一下排查&定位的思路和方法,在分析 %io,%sys 等方面的问题时,也可以用类似的思路,从这些指标的意义开始,结合 MySQL 的一些特性或者特点,逐步理清楚表象背后的原因。
1人回答了此问题

TDSQL 账户加固会影响到视图无法访问?

提问2021-01-27708
用户7180642
赞~!
2人回答了此问题

关于登录时到底是被 MySQL 识别为哪个账号的问题?

晓小峰哦
简要分析 MySQL 在创建用户的时候,一般是需要指定用户名和来源 IP 的,比如: mysql> show grants for test@'%'; +----------------------------------+ | Grants for test@% | +----------------------------------+ | GRANT USAGE ON *.* TO 'test'@'%' | +----------------------------------+ 1 row in set (0.00 sec) 由于 Host 这个字段支持正则匹配,因此这个字段设置为 % 的时候,则代表所有的来源 IP 都能匹配到。 因为这个特性,所以有时候创建的账号会有如下的情况出现: +------+---------------+ | user | host | +------+---------------+ | test | % | | test | 10.104.% | | test | 10.104.56.136 | +------+---------------+ 参考官方文档的描述: When multiple matches are possible, the server must determine which of them to use. It resolves this issue as follows: 1.Whenever the server reads the user table into memory, it sorts the rows. 2.When a client attempts to connect, the server looks through the rows in sorted order. 3.The server uses the first row that matches the client host name and user name. The server uses sorting rules that order rows with the most-specific Host values first. 简而言之:MySQL 会按照 Host 的匹配精度,按降序排列同一个 Username 的所有账号,当 Client 端尝试登录 MySQL 的时候,会按照顺序依次这个 Username 下面所有的 Host 规则,直到匹配成功。 Host 这个字段不仅能填 IP,也能写域名,同样也能利用到正则表达式匹配: 📷 匹配示例 由于域名指向的 IP 受 DNS 的影响,因此多数时候会用 IP,一般来说需要 DNS 来屏蔽一些后端细节的时候才会用域名来作为 Host 字段的值。 测试一下 使用如下操作创建三个用户,密码不做区分: mysql> create user test@'%' identified by 'test'; Query OK, 0 rows affected (0.00 sec) mysql> create user test@'10.104.56.136' identified by 'test'; Query OK, 0 rows affected (0.00 sec) mysql> create user test@'10.104.%' identified by 'test'; Query OK, 0 rows affected (0.01 sec) mysql> mysql> mysql> mysql> select user,host from mysql.user where user='test' order by host desc; +------+---------------+ | user | host | +------+---------------+ | test | 10.104.56.136 | | test | 10.104.% | | test | % | +------+---------------+ 3 rows in set (0.00 sec) mysql> PS:order by desc 仅为展示上的考虑。 那么从两个不同的机器上(10.104.56.136 和 10.104.43.107)尝试登录 MySQL,按照文档的描述,匹配的优先级应该是:10.104.56.136->10.104.%->%。那么有一台服务器能完整匹配到 IP,另外一台服务器匹配到的应该是10.104.%。 实际操作一下看看效果: root@debian:~# ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.104.56.136 ......(省略) root@debian:~# mysql -h192.168.1.100 -utest -ptest ......(省略) Server version: 5.7.18-txsql-log 20200331 ......(省略) mysql> show grants; +----------------------------------------------+ | Grants for test@10.104.56.136 | +----------------------------------------------+ | GRANT USAGE ON *.* TO 'test'@'10.104.56.136' | +----------------------------------------------+ 1 row in set (0.00 sec) mysql> 在另外一台机器上: root@VM-43-107-debian:~# ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.104.43.107 ......(省略) root@debian:~# mysql -h192.168.1.100 -utest -ptest ......(省略) Server version: 5.7.18-txsql-log 20200331 ......(省略) mysql> show grants; +-----------------------------------------+ | Grants for test@10.104.% | +-----------------------------------------+ | GRANT USAGE ON *.* TO 'test'@'10.104.%' | +-----------------------------------------+ 1 row in set (0.00 sec) mysql> 换成本地的设备再试一下登录: Tomo@MacBook-Pro ~ % mysql -hgz-cdb.sql.tencentcdb.com -utest -ptest -P59888 ......(省略) Server version: 5.7.18-txsql-log 20200331 ......(省略) mysql> show grants; +----------------------------------+ | Grants for test@% | +----------------------------------+ | GRANT USAGE ON *.* TO 'test'@'%' | +----------------------------------+ 1 row in set (0.02 sec) mysql> 可以看到本地设备的 IP 由于和前两个匹配规则不一致,所以最后匹配到了 % 的这个账号。 总结一下 作为比较保险的办法,尽量少用 Host 来区分不同的账号,直接用不同的 Username 会比较好管理和维护,如果一定需要用 Host 来区分,那么至少也要用不同的密码,防止匹配到了错误的用户,导致权限不足引起业务上的问题。 课外题 localhost 和 127.0.0.1 算是常用的两个 Host,可以作为实践内容动手试一下,体验一下匹配的规律。在 MySQL 看来,精确的域名和精确的 IP 是同等地位的。
1人回答了此问题

相对于传统的数据库开发,TXSQL对开发者能更为友好吗?语法一致吗?

提问2018-06-20896
流星留步
TXSQL是腾讯基础架构部数据库团队自研的MySQL分支,对腾讯云以及众多的内部业务提供了强大的数据库内核支撑。相比原生的MySQL,TXSQL在BINLOG复制和InnoDB存储引擎方面做了很多的优化,另外在Server层面也做了大量的工作。因此TXSQL拥有更好的性能,更好的稳定性和可维护性,以及更多的企业级特性。
10人回答了此问题

SQL sever数据库能迁移至TDsql数据库吗?

云峥百宝箱
SQL Server数据库可以迁移至TDSQL数据库,但需要根据TDSQL的具体版本(如TDSQL-MySQL或TDSQL-PG)进行适配和调整。
2人回答了此问题

相同的SQL查询,在腾讯云mysql数据库和普通mysql里返回的结果顺序不一致是什么原因呢?

编辑2025-01-14120
云海泛舟客
我感觉问题不是很大吧……可能跟数据库底层设计有关,也可能跟数据插入时候,底层存储空间位置有关。 anyway,展现的时候,前端自己加个排序应该也是常规操作吧……
2人回答了此问题

flinkcdc连接tdsql报错?

编辑2024-10-23141
用户5184363
老哥 你怎么解决的。我也遇见了
1人回答了此问题

mysql怎么解决子查询返回结果为空导致sql执行很慢?

编辑2024-04-09311
空洞的盒子
对表构造适当的索引,使用Join来替代子查询,然后使用exists语法来简化查询语句,可以适当对空结果集进行判断。
2人回答了此问题

mybatis自定义ResultHandler,得到的结果重复?

编辑2024-02-23295
一凡sir
你在 handleResult 方法中的 list.add 方法调用的前后分别打印一些日志,输出此时 list 中的数据,看看是不是有多次调用和重复数据插入。
1人回答了此问题

在云服务器中创建了数据库,第二天,该数据库没有了?

一凡sir
创建工单问问客服吧,真的出现这种情况,可就是事故了。 自己还是要做好每天的数据库备份才行。
1人回答了此问题

添加外键失败,怎么才能修复这个错误呢?

编辑2023-08-09187
一凡sir
这个错误表示在添加外键约束时,引用表(employee)中缺少被引用的列(emp_id)。在添加外键约束之前,需要确保引用表中存在被引用的列。您需要检查employee表中是否存在emp_id列,并确保该列的名称和数据类型与约束中指定的一致。
1人回答了此问题

使用MySql通过二级索引+回表的方式执行查询时,为什么索引列中重复值过多会导致大量回表操作?

编辑2023-04-19549
程序那些事儿
当使用二级索引+回表的方式进行查询时,如果索引列中的重复值过多,就会导致大量的回表操作。 这是因为MySQL的二级索引结构是B+树,B+树的叶子节点存储了数据行的主键值和其它字段的值,而非主键值的索引列只是作为B+树的一部分,用于定位到叶子节点。因此,当查询条件中包含非主键值的索引列时,MySQL需要先通过B+树定位到叶子节点,再根据叶子节点中的主键值回表查询数据行。 如果索引列中重复值过多,那么同一个叶子节点中可能会包含大量的数据行,这就意味着需要进行大量的回表操作才能获取所有符合查询条件的数据行。这将导致查询性能变得非常低下,甚至会出现性能瓶颈。 因此,为了避免这种情况,我们可以在创建索引时尽量避免选择重复值过多的列作为索引列,或者使用联合索引来减少重复值过多的情况。
1人回答了此问题

TDSQL MySQL版shardkey建议使用自增列吗?

胖五斤回答已采纳
不建议使用自增列作为shardkey。 建议结合业务与实体关联关系,选择适当的查询关联字段选定shardkey,访问数据尽量都带上 shardkey 字段,若不带 shardkey 的 SQL 会路由到所有节点。 另外需要注意shardkey 字段必须是主键以及所有唯一索引的一部分。
1人回答了此问题

TDSQL MySQL版查看集群状态的命令?

胖五斤
可以通过mysql客户端加上-c选项连接proxy后,执行 /*proxy*/ show help; 查看有没你需要的命令; 例如: /*proxy*/ show config; /*proxy*/ show status; 等命令,查看对应的信息。
1人回答了此问题

tdsql使用load_data工具导入数据,使用mode3以替换的方式导入,结果没有被替换?

编辑2022-12-01495
胖五斤回答已采纳
确认一下插入数据的表是否有主键或者是唯一索引。 如果没有,会导致数据重复插入。
1人回答了此问题

腾讯云Mysql数据库怎么做数据比对?

胖五斤
可以参考:https://cloud.tencent.com/document/product/571/45844
1人回答了此问题

网站刚开通后,经常会有很多IP来访问.php结尾的文件,他们想找什么?

编辑2022-09-02188
西门呀在吹雪
扫描器扫描的,盲猜扫描
1人回答了此问题

gradle 工程之flyway插件报错,貌似是url匹配不正,看了下源码没觉得哪里不对啊?

编辑2022-08-28617
用户7135784
谁能给flyway插件论坛提一下,这个是bug,我换了8.0beta版本的插件就好了,其他的一点也没改,应该是bug了!!!
1人回答了此问题

在mysql中写内连接和外连接在实际开发中会写INNER和OUTER吗?

腾讯灯塔小明回答已采纳
不需要,left join,right join,full join的类型是outer join,单写join的类型是inner join,因此不同join的类型是不言自明,无论是否写出inner或outer,对理解、性能都没有区别。 (来源:灯塔小明的实践经验,不代表腾讯灯塔/智能数据分析的建议或官方推荐。)
1人回答了此问题
Hi~
今天想聊点什么呢?
近期活跃用户
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档