问题
最近遇到一个问题,再监控事务启动和堵塞时长的时候,发现和正常时间差距很大,一般我们会用now() - innodb_trx.trx_started 来计算事务启动了多久,是否是长事务。问题如下,
这里我们发现now的时间是正常的,但是innodb_trx的trx_started字段和trx_wait_started字段时间都差一个整小时,这明显是受到了时区影响。
查看信息和分析
我们查看一下时区信息
我们发现系统时区是UTC(进程启动时候系统的时区),而数据库的时区自定义为+8时区了,再来看看innodb_trx字段的trx_started大概代码,如下,
这里我们发现这两个字段实际上都是使用localtime的可重入函数localtime_r来通过进程的时区获取这个时间,而并没有受到time_zone参数的影响。而当我们查看OS时区是正常的,大概如下,
那我们可以知道,在数据库启动的时候系统时区可能是UTC,启动后才修改了OS的时区,那么数据库进程的时区就固定为UTC了,那么只有重启一下数据库进程才能让正确的时区生效。重启后时区正常,同时innodb_trx的trx_started字段和trx_wait_started字段的时间显示正常,如下,