这个问题是一个朋友遇到的@风云,并且这位朋友已经得出了近乎正确的判断,下面进行一些描述。
一、问题展示下面是问题当时的系统负载如下:
我们可以看到 40.4%sy 正是系统调用负载较高的表现,随即朋友采集了 perf 如下:
接下来朋友采集了 pstack 给我,我发现大量的线程处于如下状态下:Thread 38 (Thread 0x7fe57a86f700 (LWP 67268)):#0 0x0000003dee4f82ce in __lll_lock_wait_private () from /lib64/libc.so.6#1 0x0000003dee49df8d in _L_lock_2163 () from /lib64/libc.so.6#2 0x0000003dee49dd47 in __tz_convert () from /lib64/libc.so.6#3 0x00000000007c02e7 in Time_zone_system::gmt_sec_to_TIME(st_mysql_time*, long) const ()#4 0x0000000000811df6 in Field_timestampf::get_date_internal(st_mysql_time*) ()#5 0x0000000000809ea9 in Field_temporal_with_date::val_date_temporal() ()#6 0x00000000005f43cc in get_datetime_value(THD*, Item***, Item**, Item*, bool*) ()#7 0x00000000005e7ba7 in Arg_comparator::compare_datetime() ()#8 0x00000000005eef4e in Item_func_gt::val_int() ()#9 0x00000000006fc6ab in evaluate_join_record(JOIN*, st_join_table*) ()#10 0x0000000000700e7e in sub_select(JOIN*, st_join_table*, bool) ()#11 0x00000000006fecc1 in JOIN::exec() ()
我们可以注意一下 __tz_convert 这正是时区转换的证据。二、关于 timestamp 简要说明timestamp:占用 4 字节,内部实现是新纪元时间(1970-01-01 00:00:00)以来的秒,那么这种格式在展示给用户的时候就需要做必要的时区转换才能得到正确数据。下面我们通过访问 ibd 文件来查看一下内部表示方法,使用到了我的两个工具 innodb 和 bcview。详细参考:https://www.jianshu.com/p/719f1bbb21e8。
timestamp 的内部表示建立一个测试表mysql> show variables like '%time_zone%';
+---------------