Mysql性能不佳

我有这个简单的表

CREATE TABLE `user_did_something` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `something_id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `active` int(1) NOT NULL DEFAULT '1'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- Indexes for table `user_did something`
ALTER TABLE `user_did_something`
  ADD PRIMARY KEY (`id`);

当我尝试插入时

INSERT INTO user_did_something (something_id, user_id) VALUES (1,11)

执行时间约为70毫秒.

在不同的机器上测试相同的结构,执行时间约为3ms.

附加信息:

>版本10.0.28-MariaDB-0ubuntu0.16.04
>表没有行
>只有index用于主要的列id.

我不知道如何调试这个.在线阅读一些内容,重新启动一切,结果仍然相同.

我正在寻找如何调试这样的东西的指导,而无需在我的机器上重新安装mysql服务器.

最佳答案

I am looking for a guidance on how to debug stuff like this without the need of reinstalling the mysql server on my machine.

我会尝试回答你问题的这一部分.所以你想要了解一些流程的内幕,看看它在做什么.您不想重新编译它,重新安装它或重新启动它,并且您不希望受到它开箱即用的跟踪的限制.

这是使用DTrace的好机会!它可以让你观察你的流程正在做什么(和much more).

DTrace至少可在Solaris,Mac OS X *和FreeBSD以及I hear a port exists for Linux上使用.否则,您可以使用其他实用程序(BPF tracing got merged into Linux 4.9-rc1 recently)跟踪类似信息.

* Mac OS X用户需要explicitly permit DTrace to run,将其从系统完整性保护中排除

您可以在进入和返回函数时实时观察mysqld:

dtrace -p $(pgrep -x mysqld) -F -n 'pid$target:mysqld::entry{} pid$target:mysqld::return{}'

作为一些输出的例子…… InnoDB即使在空闲时也非常健谈:

2  -> sync_arr_wake_threads_if_sema_free    
6  -> os_event_reset                        
2    -> os_mutex_enter                      
6  <- os_event_reset                        
2    <- os_mutex_enter                      
6  -> pfs_mutex_exit_func                   
6  <- pfs_mutex_exit_func                   
2    -> os_mutex_exit                       
6  -> os_event_reset                        
2    <- os_mutex_exit                       
6  <- os_event_reset                        

您可以观看进入MySQL调度程序的查询!

dtrace -p $(pgrep -x mysqld) -F -n 'pid$target:mysqld:*dispatch_command*:entry{printf("Query: %s\n", copyinstr(arg2));}'

样本输出:

CPU FUNCTION                                 
0  -> dispatch_command(enum_server_command, THD*, char*, unsigned int) Query: SHOW VARIABLES LIKE 'pid_file'

我相信在侦听特定查询运行时发生的函数调用时,DTrace的功能也在其中.例如:你可以使mysqld:* dispatch_command *:entry init一个线程局部变量iff查询匹配某些条件,并使pid $target:mysqld :: entry |仅在定义该变量时返回print.相应的mysqld:* dispatch_command *:exit或类似可以取消定义该变量.当然,如果您希望工作在单独的线程中进行,您也可以使用全局变量.

很抱歉没有写上述具体的例子;我自己的MySQL被软管,我的DTrace书在办公室.

DTraceToolkit的作者Brendan Gregg提供了许多示例脚本,可用于监视错误的进程,包括some one-liners用于监视进程是否遇到页面错误,读取和写入有多大,系统调用正在进行,等等.但是你如果你更全面地学习DTrace,可以做得比单行更好.

我在这里介绍的脚本基于Ben Rockwood的文章Examining MySQL in real time using DTrace中提供的脚本.需要免费注册才能阅读.

我从Brendan Gregg的文章中了解了这个工具,并从Brendan的DTrace book中学到了更多关于DTrace的知识.如果你想看看兔子洞有多深,我强烈推荐这本书.

点赞