近期服务器由10升级到11,遂将数据库由5.3一并升级到5.6。升级后,使用还原备份的功能,发现还原过程中发生错误。于是使用导入.sql
文件的方式进行数据的恢复,但仍然发生了错误。最终,发现是由于版本升级后,多了一个对日期检定的安全模式造成的。
本文首重于介绍解决过程,如果你只关心解决方法,请跳过前面几个章节。
解决过程记录如下:
备份原数据
以防万一,使用两种备份方式。
- navicat的备份功能,优点是快。缺点是由于备份的文件为特定格式,一但有错误,无法手工的修正。当然,也看不到具体的报错信息。
- 数据导出的备份功能,上面的优点就是它的缺点。它的优点,就是上面的缺点。
导入原数据
- 尝试使用原备份,进行直接恢复。发生错误。
- 尝试导入前面导出的
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',看其是否报错。如果报错,说明猜想正确,如果没有报错,说明猜想错误,那么就需要调整解决问题的方向。
果真,报错了。
解决错误
先在navicat中的测试环境中,添加一条合法的默认值,并保存成功。由于时间戳的最小值应该是1970-01-01 00:00:00
,所以我们尝试将其设置为1970-01-01 00:00:00
,保存仍然得到了错误的信息。如果设置为当前时间2018-xx-xx 00:00:00
就可以正常的保存。那么说明我们心里想的最小值,并不是真正的最小值。
原因出现以下两点基础知识上,这个在以前的基础教程中,也涉及过。
- 时区的问题:我们是时区是 +8:00,所以时间戳的0,应该是
1970-01-01 08:00:00
- 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')
顿时好像明白了,由于我们把基本的导入数据改了,所以当进行上述查询时,就找不到数据了。。。
解决方法
查询数据出问题,解决方法无所就是两种。
- 以数据为准,改查询语句
- 以查询语句为准,改数据。
由于对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
...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。