我们是2010年底开始使用Drupal的,当时Drupal 7还没正式版,所以就用了Drupal 6,在2012年2月的时候就以本博客为例做过Drupal 6到Drupal 7的升级,虽然有些麻烦但好歹算是可以升级成功,而涉及到大数据量Drupal的站点升级却让我吃到苦头,后来新站都用Drupal 7搭建,而Drupal 6的一些网站也就继续停留在Drupal 6,只进行小版本升级,不敢轻易进行大版本的升级。
最近由于在转云服务器,就想一并做Drupal大版本升级,把现在支持越来越少的Drupal 6升级到目前主流的Drupal 7,Drupal 8因为还没有推出正式版还不宜在正式网站采用,与以前手工菜单操作升级不一样,现在可以用Drush批量处理的方式,如果没有这种方式那简直不敢想如何进行,目前尝试了一部分,先把步骤记录下来:
- 做好准备:查阅升级相关资料、准备服务器环境;
- 备份数据库、备份Web文件,传到新服务器上恢复;
- 升级Drupal 6到最新的Drupal 6版本,包括核心模块和第三方模块(drush up -y);
- Drupal 6站点下卸载各种第三方模块,只剩下核心模块(drush pm-disable views -y等);
- 下载最新稳定版本Drupal 7安装,将Drupal 6下的sites目录复制过来,去掉老的模块、模板、翻译等文件,进行settings.php修改等;
- Drupal 7站点下升级核心模块数据库(drush updatedb -y,注意如果数据量大这个过程可能比较长);
- Drupal 6的CCK到Drupal 7的Content Type的转换(drush content-migrate-fields -y,这其实分为结构迁移和数据迁移两部分,也可以用web界面进行,注意如果数据量大的话,这个过程可能比较长,而且要设置php内存限制到比较大,否则可能报错);
- Drupal 7站点下安装各种需要的第三方模块(drush pm-enable views -y等,不一定要安装与Drupal 6中对应一样的第三方模块,根据新站的需要取舍、补充,如果要改响应式设计可以这里一起启用responsive_bartik),再次升级数据库(drush updatedb -y);
- block的检查修改(例如drush sql-query "UPDATE block SET region='-1', weight=0, status=0 WHERE module='locale' AND delta='language' AND theme='seven';");
- views的检查修改(例如views打开编辑、直接保存type从broken到正确的,翻页链接、菜单等的重新设置等);
- 设置新的模板(html.tpl.php, page.tpl.php, node--content_type.tpl.php等);
- 设置新的自定义模块(例如areacode.info, areacode.module, areacode.views_default.inc等);
- 首页或者其它单独页面处理(例如drupal 6中的drupal_set_html_head改为drupal 7中支持的drupal_add_html_head(
$keywords_meta = $keywords;
),views block调用$block = module_invoke('views', 'block_view', 'sic_list-block');$sic_link=render($block['content']);)
$description_meta = $description;
$meta= "
<meta name=\"keywords\" content=\"$keywords_meta\" />
<meta name=\"description\" content=\"$description_meta\" />
";
$element = array(
'#type' => 'markup',
'#markup' => $meta,
);
drupal_add_html_head($element, 'meta'); - 多语言的处理(增加fil语言、修改pt-pt为pt,翻译更新等);
- 其它杂项处理(.htaccess, robots.txt的修改,apc, memcache, cron, action, trigger, 变量cron_safe_threshold=0 / cache_lifetime="86400" / page_cache_maximum_age="86400" / block_cache=1 / page_compression=1 等检查、设置,新老站点的功能对比)。
遇到的一些特殊情况:
- drush updatedb遇到报错:WD php: DatabaseSchemaObjectExistsException: Cannot add field sessions.ssid: field already exists、WD php: DatabaseSchemaObjectExistsException: Cannot add index system_list to table system: index already exists之类,原因是settings.php中加入了一些多余的设置,在升级的时候应该保持settings.php尽量简单纯净,解决办法是drop table掉库里所有表,重新导入表,修改settings.php后重新来过;
- drush content-migrate-fields遇到报错:PHP Fatal error: Allowed memory size of 134217728 bytes,这是遇到大数量的时候PHP内存不足,解决办法是修改php.ini,增加内存限制128M可以改为1024M等,重启apache使之生效,然后重新运行;
- 打开页面遇到报错:Warning: Invalid argument supplied for foreach() in以及Warning: Illegal string offset '#children' in drupal_render()等,解决办法是把调用views_block的办法进行修改,改为例如:$block = module_invoke('views', 'block_view', 'sic_list-block');$sic_link=render($block['content']);,
- 升级后编辑页面的时候遇到Notice: Undefined index: required in field_default_form() (line 109 of /drupal_path/modules/field/field.form.inc).的报错,就去对应的内容类型,管理编辑自动添加的分类字段 http://example.com/admin/structure/types/manage/postcode/fields/taxonomyextra,不做任何改变只要保存一遍,就可以了,再编辑页面的时候那个报错就没有了
- 对于数据量特别巨大的网站(例如百万条以上记录),在drush content-migrate-field-data field_name的最后可能出现General error: 2006 MySQL server has gone away: DELETE FROM {semaphore} ...... in lock_release_all() 这样类似的报错,这是因为最后阶段清理缓存等需要运行的时间比较长,超过了wait_timeout,或者被我们自己添加的脚本杀死,可以考虑的解决办法:增加max_allowed_packet、wait_timeout,或者修改我们自己的脚本(对于正在运行数据迁移的数据库不杀死进程,例如添加判断条件$2!="youbianku_gbr" && $2!="youbianku_bra" && $2!="youbianku_can" && )、2015-10-14 modify aliyun-duoku-ecs-2 php.ini mysqlnd Read buffer size from 32k to 128k然后migrate data field_admin3成功了,这是是修改的mysql client端的内存限制,以前都是改的server端的内存限制,某些特殊情况下需要client端也修改
- ckeditor升级遇到报错PDOException: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'xxx.ckeditor_input_format' doesn't exist,办法是关闭、卸载、重新安装ckeditor这个模块:drush pm-disable ckeditor; drush pm-uninstall ckeditor; drush pm-enable ckeditor;
- 列模块的时候在日志中有报错:Notice: Undefined index: distribution_name 在 drupal_install_profile_distribution_name(),尝试这样:drush vset install_profile standard; drush -l pm-enable standard; drush vset "profiles/standard/standard.profile" 1; 在settings.php中添加$conf['install_profile'] = 'standard';(本条还待验证)
- 某些页面出现array_flip():Can only flip STRING and INTEGER values! in DrupalDefaultEntityController->load()或者Notice: Undefined index: tid in taxonomy_field_formatter_prepare_view等报错,可能是d6到d7某些字段迁移造成的一些问题,可以尝试关闭部分不需要字段的显示、修改字段设置(例如根据提示需要增加reference views等)
- 数据量大的站点进行content-migrate的时候,可能碰到这样的报错The external command could not be executed due to an application error,查询资料说是一台机器上两个php版本造成的, http://drupal.org/node/1402120 or http://drupal.org/node/436968 这两篇中别人说了一些办法
- 遇到这样的报错:Cause: exception "PDOException" with message "SQLSTATE[22001]: String data, right truncated: 1406 Data too long for column "field_address_pinyin_value" at row xxx,是因为字段内容过长,超过255个字符,在Drupal 6中是运行的,但在Drupal 7中普通的text字段最多255个字符,迁移失败的两种解决办法:1、对于少量超长的字段 ,删除或者截短内容,然后重新迁移;2、对于大量超长的字段,人工新建long text字段,然后迁移数据
- 发现模板管理或者其它页面出现报错Notice: Undefined index: distribution_name in drupal_install_profile_distribution_name,可以执行一条sql语句解决:UPDATE system SET status = 1 WHERE filename= 'profiles/standard/standard.profile';(drush命令:drush sql-query "UPDATE system SET status = 1 WHERE filename= 'profiles/standard/standard.profile';")
- 遇到这样的报错:SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'comment_node_some-content-type_form' for key 'PRIMARY'以及captcha module Update #7000 Failed: PDOException: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'comment_node_some-content-type_form' for key 'PRIMARY': INSERT INTO {captcha_points},可以去运行sql语句删除这条记录:DELETE FROM captcha_points WHERE captcha_points.form_id = 'comment_node_some-content-type_form',然后就可以重新运行drush updatedb了;
- 遇到Fatal error: Call to undefined function taxonomy_get_term() in...是因为drupal 7中写法变了:taxonomy_term_load($tid);
- 页面编辑、预览的时候遇到报错:Notice: Undefined index: taxonomy_term in taxonomy_field_formatter_view() (line ... 以及Notice: Trying to get property of non-object in entity_extract_ids() (line ... , 网上搜到一个老外也遇到这样的问题 https://groups.drupal.org/node/151519 ,按照那个办法修改字段显示就解决了;
- 在包含ubercart的数据销售站中添加关联文件时报错:PDOException: in _uc_file_gather_files() (line 1176... ,原因是上传的文件中名包含了特殊字符(如中文或者全角标点符号);
迁移、升级还在进行中,以后补充完善上面的信息,希望对其他人有用。
评论