小哥哥,您是怎么解决的尼?
是的。从现象来看,有大约3个地方
- 您修改的时区是time_zone =‘UTC’’
- 和本机的操作系统时区不一致-----需要注意此处的影响
- 和system_time_zone的时区不一致-----需要注意此处的影响
经过将system_time_zone地方更改成 UTC 。让系统保持一致,我这测试成功
不知道为什么很多人复现不了这个问题?我自己重新搭建了6.5.0这个问题没有复现,旧版本升级上来的问题没有解决
测试环境一:导致落错分区
测试环境二:分区完美落地到p43
但是官方文档上没有提到可以修改system_time_zone,不确定修改会有什么危害
我这复现了。而且和您的现象一致。
看了这篇文档,您可以看看。经过文档测试,数据正确的落到了p43分区
此处还有个坑
如果存在已经落地到p42错误分区的数据,数据不会发生移动。必须将错误数据清空,最好重新启动下整个集群
这个是一个bug,并不是一个用法的问题,但是官方貌似在后面的版本是解决了还是咋的,更新文档上没有说。
Proposal: Infer the System Timezone of a TiDB cluster via TZ environment variable
- Author(s): [Zhexuan Yang](file:/Users/ji.wu/Downloads/tidb-5.4.0/docs/design/www.github.com/zhexuany)
- Last updated: 2018/09/09
- Discussion at: Not applicable
Abstract
When it comes to time-related calculation, it is hard for the distributed system. This proposal tries to resolve two problems: 1. timezone may be inconsistent across multiple TiDB
instances, 2. performance degradation caused by pushing System
down to TiKV
. The impact of this proposal is changing the way of TiDB
inferring system’s timezone name. Before this proposal, the default timezone name pushed down to TiKV is System
when session’s timezone is not set. After this, TiDB evaluates system’s timezone name via TZ
environment variable and the path of the soft link of /etc/localtime
. If both of them are failed, TiDB
then push UTC
to TiKV
.
Background
After we solved the daylight saving time issue, we found the performance degradation of TiKV side. Thanks for the investigation done by engineers from TiKV. The root cause of such performance degradation is that TiKV infers System
timezone name via a third party lib, which calls a syscall and costs a lot. In our internal benchmark system, after this PR, our codebase is 1000 times slower than before. We have to address this.
Another problem needs also to be addressed is the potentially incosistent timezone name across multiple TiDB
instances. TiDB
instances may reside at different timezone which could cause incorrect calculation when it comes to time-related calculation. Just getting TiDB
’s system timezone could be broken. We need find a way to ensure the uniqueness of global timezone name across multiple TiDB
’s timezone name and also to leverage to resolve the performance degradation.
Proposal
Firstly, we need to introduce the TZ
environment. In POSIX system, the value of TZ
variable can be one of the following three formats. A detailed description can be found in this link
* std offset
* std offset dst [offset], start[/time], end[/time]
* :characters
The std means the IANA timezone name; the offset means timezone offset; the dst indicates the leading timezone having daylight saving time.
In our case, which means both TiDB
and TiKV
, we need care the first and third formats. For answering why we do not need the second format, we need to review how Golang evaluates timezone. In time
package, the method LoadLocation reads tzData from pre-specified sources(directories may contain tzData) and then builds time.Location
from such tzData which already contains daylight saving time information.
In this proposal, we suggest setting TZ
to a valid IANA timezone name which can be read from TiDB
later. If TiDB
can’t get TZ
or the supply of TZ
is invalid, TiDB
just falls back to evaluate the path of the soft link of /etc/localtime
. In addition, a warning message telling the user you should set TZ
properly will be printed. Setting TZ
can be done in our tidb-ansible
project, it is also can be done at user side by export TZ="Asia/Shanghai"
. If both of them are failed, TiDB
will use UTC
as timezone name.
The positive side of this change is resolving performance degradation issue and ensuring the uniqueness of global timezone name in multiple TiDB
instances.
The negative side is just adding a config item which is a very small matter and the user probably does not care it if we can take care of it and more importantly guarantee the correctness.
Rationale
We tried to read system timezone name by checking the path of the soft link of /etc/localtime
but, sadly, failed at a corner case. The failed case is docker. In docker image, it copies the real timezone file and links to /usr/share/zoneinfo/utc
. The timezone data is correct but the path is not. Regarding of UTC
, Golang just returns UTC
instance and will not further read tzdata from sources. This leads to a fallback solution. When we cannot evaluate from the path, we fall back to UTC
.
Compatibility
It does not have compatibility issue as long as the user deploys by tidb-ansible
. We may mention this in our release-node and the message printed before tidb quits, which must be easy to understand.
The upgrading process need to be handled in particular. TZ
environment variable has to be set before we start new TiDB
binary. In this way, the following bootstrap process can benefit from this and avoid any hazard happening.
Implementation
The implementation is relatively easy. We just get TZ
environment from system and check whether it is valid or not. If it is invalid, TiDB evaluates the path of soft link of /etc/localtime
. In addition, a warning message needs to be printed indicating user has to set TZ
variable properly. For example, if /etc/localtime
links to /usr/share/zoneinfo/Asia/Shanghai
, then timezone name TiDB
gets should be Asia/Shanghai
.
In order to ensure the uniqueness of global timezone across multiple TiDB
instances, we need to write timezone name into variable_value
with variable name system_tz
in mysql.tidb
. This cached value can be read once TiDB
finishes its bootstrap stage. A method loadLocalStr
can do this job.
Open issues (if applicable)
PR of this proposal: https://github.com/pingcap/tidb/pull/7638/files PR of change TZ loading logic of golang: https://github.com/golang/go/pull/27570
@考试没答案 看这个文档,官方已经考虑到这一点了,并且在源码里面写了文档
为了确保跨多个TiDB实例的全局时区的唯一性,我们需要将时区名称写入mysql.TiDB中变量名为system_tz的variable_value中。一旦TiDB完成其引导阶段,就可以读取该缓存值。loadLocalStr方法可以完成此任务。
厉害,竟然能看懂源码。
此话题已在最后回复的 60 天后被自动关闭。不再允许新回复。