近期服务器由10升级到11,遂将数据库由5.3一并升级到5.6。升级后,使用还原备份的功能,发现还原过程中发生错误。于是使用导入.sql文件的方式进行数据的恢复,但仍然发生了错误。最终,发现是由于版本升级后,多了一个对日期检定的安全模式造成的。

本文首重于介绍解决过程,如果你只关心解决方法,请跳过前面几个章节。

解决过程记录如下:

备份原数据

以防万一,使用两种备份方式。

  1. navicat的备份功能,优点是快。缺点是由于备份的文件为特定格式,一但有错误,无法手工的修正。当然,也看不到具体的报错信息。
  2. 数据导出的备份功能,上面的优点就是它的缺点。它的优点,就是上面的缺点。

导入原数据

  1. 尝试使用原备份,进行直接恢复。发生错误。
  2. 尝试导入前面导出的SQL文件,发生以下错误。
Error at query 9: Invalid default value for 'backupstart'

解决错误的第一步:翻译。
第9个query语句发生错误: 对字段'backupstart'设置了无效的默认值。
大多数的错误,我们翻译后,就大概的知道它的原因所在了。此时,我们打开要导入的sql文件。并以backupstart为关键字进行查询。
找到如下:

`backupstart` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',

猜想错误

是由于默认值 '0000-00-00 00:00:00' 不被支持造成的错误。

验证猜想

在进行验证时,往往我们只需要一个差不多的环境。比如此时,我建立一个表,这里建立一个字段,并将类型设置为timestamp,再将其默认值设置为,'0000-00-00 00:00:00',看其是否报错。如果报错,说明猜想正确,如果没有报错,说明猜想错误,那么就需要调整解决问题的方向。

clipboard.png

clipboard.png

clipboard.png

果真,报错了。

解决错误

先在navicat中的测试环境中,添加一条合法的默认值,并保存成功。由于时间戳的最小值应该是1970-01-01 00:00:00,所以我们尝试将其设置为1970-01-01 00:00:00,保存仍然得到了错误的信息。如果设置为当前时间2018-xx-xx 00:00:00就可以正常的保存。那么说明我们心里想的最小值,并不是真正的最小值。
原因出现以下两点基础知识上,这个在以前的基础教程中,也涉及过。

  1. 时区的问题:我们是时区是 +8:00,所以时间戳的0,应该是1970-01-01 08:00:00
  2. mysql较验的问题:mysql认为起点虽然是1970-01-01 08:00:00,但最小的起始时间应该是1970-01-01 08:00:01

于是,将默认值由0000-00-00 00:00:00修改为1970-01-01 08:00:01,该错误消失。然后,我们将要导入的.sql中的数据,凡是默认值为0000-00-00 00:00:00改成1970-01-01 08:00:01。尝试进行再次导入。

注意:一定不要能原来的备份文件上直接改,而是复制一个新文件,然后改动复制的文件。这样做的好处是:即使我们改错了,还可以随意的找到以前备份的原数据。而不至于出现数据丢失这种大的低级的错误。

再次导入

发生错误:

Error at query 77: Incorrect datetime value: '0000-00-00 00:00:00' for column 'publish_down' at row 1

翻译

第77个query发生了错误:在第一行的'publish_down'字段上,出现了不正解的日期值'0000-00-00 00:00:00'

猜问题

前面猜对了,这个就更容易猜到了。前面的错误,发生的创建数据表时的验难。此时,发生了插入数据时。原因,当然也是由于这个值最小为:1970-01-01 08:00:01了。

解决问题

将所有的0000-00-00 00:00:00替换为1970-01-01 08:00:01
再次导入的,成功的导入进了数据表。

内容获取错误

虽然数据成功导入了,前台也成功的连接了数据库。但是:joomla前台的数据却是空的,一条数据都没有。此时又该怎么解决呢?

方法

如果有报错信息,查看报错信息;如果没有报错信息,查看日志信息;如果没有日志信息,那么,我们应该查看‘控制台’。
通过对服务器的error及info进行查看,并没有错误的发生。那么只能求救于控制台了。joomla的控制台开启和其它的大多数框架一样,也位于配置文件中,我们以debug为关键字进行查找,并将值由0改为1,然后再刷新页面。发现已经可以查看到控制台信息了。

猜想错误原因

服务器没有报错,页面也出来了,说明基本的框架运行没有问题。没有内容,最大的问题可能是出在数据查询上。我们在控制台上,找到sql语句。发现如下两行:

AND (a.publish_up = '0000-00-00 00:00:00' OR a.publish_up <= '2018-09-13 01:03:40') 
AND (a.publish_down = '0000-00-00 00:00:00' OR a.publish_down >= '2018-09-13 01:03:40') 

顿时好像明白了,由于我们把基本的导入数据改了,所以当进行上述查询时,就找不到数据了。。。

解决方法

查询数据出问题,解决方法无所就是两种。

  1. 以数据为准,改查询语句
  2. 以查询语句为准,改数据。

由于对joomal框架不是很熟悉,另外也不想影响到以后的版本升级,所以选择第一种方法来找joomla源码,然后修改查询语句,并不值得推荐。
所以,我们又回到了原始数据上:能否保留0000-00-00 00:00:00呢?

我们以mysql5.6 0000-00-00 00:00:00为关键进行,进行查询,很快便发现了我们想要的答案。

https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html

原来在高版本的mysql中有,有个sql-model属性,这个属性开启,会对输入的时间进行格式的较验,发现有错误,便抛出异常。

最终解决方法

按官方文件的指引,在服务器上找到mysql的配置文件(my.cnf或my.ini),查看是否有sql-model,如果有,去除日期验验选项:NO_ZERO_DATE, NO_ZERO_IN_DATE。如果没有,添加sql-model,并添加除NO_ZERO_DATE, NO_ZERO_IN_DATE以外的几个验证属性。最后,重启mysql服务。并将最初的sql文件导入数据库。

比如:

...
innodb_autoinc_lock_mode        = 2
skip-symbolic-links         
sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

[mysqldump]
max_allowed_packet              = 256M
...

潘杰
3.1k 声望238 粉丝