重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
以下五种方法可以快速定位全局锁的位置,仅供参考。
成都创新互联专注于成都网站建设、网站设计、网页设计、网站制作、网站开发。公司秉持“客户至上,用心服务”的宗旨,从客户的利益和观点出发,让客户在网络营销中找到自己的驻足之地。尊重和关怀每一位客户,用严谨的态度对待客户,用专业的服务创造价值,成为客户值得信赖的朋友,为客户解除后顾之忧。
方法1:利用 metadata_locks 视图
此方法仅适用于 MySQL 5.7 以上版本,该版本 performance_schema 新增了 metadata_locks,如果上锁前启用了元数据锁的探针(默认是未启用的),可以比较容易的定位全局锁会话。
方法2:利用 events_statements_history 视图此方法适用于 MySQL 5.6 以上版本,启用 performance_schema.eventsstatements_history(5.6 默认未启用,5.7 默认启用),该表会 SQL 历史记录执行,如果请求太多,会自动清理早期的信息,有可能将上锁会话的信息清理掉。
方法3:利用 gdb 工具如果上述两种都用不了或者没来得及启用,可以尝试第三种方法。利用 gdb 找到所有线程信息,查看每个线程中持有全局锁对象,输出对应的会话 ID,为了便于快速定位,我写成了脚本形式。也可以使用 gdb 交互模式,但 attach mysql 进程后 mysql 会完全 hang 住,读请求也会受到影响,不建议使用交互模式。
方法4:show processlist
如果备份程序使用的特定用户执行备份,如果是 root 用户备份,那 time 值越大的是持锁会话的概率越大,如果业务也用 root 访问,重点是 state 和 info 为空的,这里有个小技巧可以快速筛选,筛选后尝试 kill 对应 ID,再观察是否还有 wait global read lock 状态的会话。
方法5:重启试试!
?php
$host_name="localhost"; //服务器名
$host_user="root"; //连接服务器的用户名
$host_pass="123456"; //连接服务器的密码
$db_name=""; //服务器上的可用数据库
$my_conn=mysql_connect($host_name,$host_user,$host_pass); //连接服务器
mysql_select_db($db_name,$my_conn); //选择操作的数据库
mysql_query("SET NAMES utf-s"); //设置编码
$sql="select content from sheet where id=0 "//mysql语句
//从sheet表中查询id=0的content的值
$row = mysql_fetch_array(mysql_query($sql,$my_conn));//从mysql返回的结果中提取一 //行
?
select `库名`, `COLUMN_NAME` from `information_schema`.`COLUMNS` where `TABLE_SCHEMA`=db_name
and DATA_TYPE in ('字段类型'); 获取所有字段 然后找出有groupId的表,组成sql查询
在数据库中查找某一字段的值的操作方法和步骤如下:
1、首先,在桌面上,单击“
Management Studio”图标,如下图所示。
2、其次,完成上述步骤后,在该界面中,单击左上角的“新建查询”按钮,如下图所示。
3、接着,完成上述步骤后,输入如下红框标注的SQL语句,如下图所示。
4、然后,完成上述步骤后,在该界面中,单击左上方的“执行”选项,如下图所示。
5、最后,完成上述步骤后,在此界面中,显示查询数据库有某个字段,如下图所示。这样,问题就解决了。
like运算符:对字符串进行模糊查找
语法:
xx like '要查找的内容'
含义:
实现对字符串的某种特征信息的模糊查找。它其实依赖于以下2个特殊的"符号"
%:它代表任何个数的任何字符
_ 它代表一个任何字符
例1 select*from tab_load_data where f5 like"%汨罗%";
例2 select*from tab_load_data where name like "%韩%";
常见例子和含义
name like '%罗%':表示name中“罗这一字的所有数据行
name like '罗%':表示name中罗开头的所有数据行比如罗曼罗兰
name like ''%罗" 表示以罗结尾所有数据行比如c罗 魂斗罗
name like '罗_'以罗开头并只有2个字符所有数据行比如 罗兰
name like '_罗'以罗结尾并只有2个字符所有数据行比如c罗
要找含有%或_怎么办?
xx like '%\%%'; 表示xx中含有百分号(%)
例3 select *from tab_load_data where name like '%军';
例2 select *from tab_load_data where name like '韩%';
问题
我们有一个 SQL,用于找到没有主键 / 唯一键的表,但是在 MySQL 5.7 上运行特别慢,怎么办?
实验
我们搭建一个 MySQL 5.7 的环境,此处省略搭建步骤。
写个简单的脚本,制造一批带主键和不带主键的表:
执行一下脚本:
现在执行以下 SQL 看看效果:
...
执行了 16.80s,感觉是非常慢了。
现在用一下 DBA 三板斧,看看执行计划:
感觉有点惨,由于 information_schema.columns 是元数据表,没有必要的统计信息。
那我们来 show warnings 看看 MySQL 改写后的 SQL:
我们格式化一下 SQL:
可以看到 MySQL 将
select from A where A.x not in (select x from B) //非关联子查询
转换成了
select from A where not exists (select 1 from B where B.x = a.x) //关联子查询
如果我们自己是 MySQL,在执行非关联子查询时,可以使用很简单的策略:
select from A where A.x not in (select x from B where ...) //非关联子查询:1. 扫描 B 表中的所有记录,找到满足条件的记录,存放在临时表 C 中,建好索引2. 扫描 A 表中的记录,与临时表 C 中的记录进行比对,直接在索引里比对,
而关联子查询就需要循环迭代:
select from A where not exists (select 1 from B where B.x = a.x and ...) //关联子查询扫描 A 表的每一条记录 rA: 扫描 B 表,找到其中的第一条满足 rA 条件的记录。
显然,关联子查询的扫描成本会高于非关联子查询。
我们希望 MySQL 能先"缓存"子查询的结果(缓存这一步叫物化,MATERIALIZATION),但MySQL 认为不缓存更快,我们就需要给予 MySQL 一定指导。
...
可以看到执行时间变成了 0.67s。
整理
我们诊断的关键点如下:
\1. 对于 information_schema 中的元数据表,执行计划不能提供有效信息。
\2. 通过查看 MySQL 改写后的 SQL,我们猜测了优化器发生了误判。
\3. 我们增加了 hint,指导 MySQL 正确进行优化判断。
但目前我们的实验仅限于猜测,猜中了万事大吉,猜不中就无法做出好的诊断。