老版本confluence和bitbucket修改代码连接MySQL5.7

起因

之前给公司装了confluence(v5.8.15)和bitbucket(v4.2.0),因为一直能满足实际需求,也没怎么升级。最近因为要把开发测试环境的项目迁移到同一台服务器上,这就要求必须保持和线上服务器MySQL版本一致,所以要升级这台服务器的MySQL到5.7版本。MySQL5.6升级到MySQL5.7确实很平滑,优化了一下配置,可以直接无缝衔接,但是confluence和bitbucket跑不起来了。

探究

分别查了下confluence和bitbucket对应版本的文档,发现confluence和bitbucket都表示5.7没有经历过测试,最佳MySQL版本还是5.6,其中bitbucket还说5.6的版本不能低于5.6.16(5.7不就是大于这个版本的吗?所以直觉上觉得5.7应该是能兼容的)。从官方的描述来看,之所以不直接支持5.7,完全是因为当时MySQL5.7刚刚出来,没有放出稳定版,无法给产品做足够的测试造成的。我查了下各自的日志,发现都是各自校验数据库的工具类报错,那么一个想法出现了,我修改它们的代码,让它们能够检验通过,运行一段时间看看是否真的不支持MySQL5.7。

解决方案

confluence

先是根据日志

java.sql.SQLException: Unknown system variable 'storage_engine'
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:959)
...

找到官方的文档,根据说明将<confluence-home>/confluence.cfg.xml(如果安装的时候没有指定,默认是/var/atlassian/application-data/confluence)中关于storage_engine的配置去掉(因为5.7里删除了这个参数),当然将storage_engine修改成default_storage_engine也是行的

<property name="hibernate.connection.url">jdbc:mysql://localhost/confluence?sessionVariables=storage_engine%3DInnoDB&amp;useUnicode=true&amp;characterEncoding=utf8</property>

我这里直接改成

<property name="hibernate.connection.url">jdbc:mysql://localhost/confluence?sessionVariables=default_storage_engine%3DInnoDB&amp;useUnicode=true&amp;characterEncoding=utf8</property>

重启,又报错,错误日志:

[confluence.setup.dbcheck.MySQLChecker] checkStorageEngineType Your database Storage Engi
ne could not be determined: Incorrect result size: expected 1, actual 0
org.springframework.dao.EmptyResultDataAccessException: Incorrect result size: expected 1, actual 0
...

说明校验工具类不放过5.7,那么我就只能修改下源码了。因为当初买的startup版本,所以能很方便的找到这个类的源码,在这个类的private void checkStorageEngineType(Properties databaseProperties) throws BootstrapException方法里有这句

 String defaultEngine = getMySQLVariable(template, "storage_engine");
                if (defaultEngine.equalsIgnoreCase("myisam"))
                    throw new BootstrapException("MyISAM is configured as the default storage engine in your database, which may result in data integrity issues. Please see http://confluence.atlassian.com/x/voTcDQ for more information.");

修改代码的时候我没有去下载源代码构建,那样太重了,我直接新建了个工程,然后加入confluence的所有依赖(可以从下载的压缩包形式的confluence发布版的程序目录里confluence/WEB-INF/lib里找,也就是服务器上运行目录里那些lib包),直接新建了个com.atlassian.confluence.setup.dbcheck.MySQLChecker类,内容复制同名原类,修改checkStorageEngineType方法

                String defaultEngine = getMySQLVariable(template, "default_storage_engine");

然后在class文件输出目录找到编译好的类文件,保持包结构扔到服务器上运行目录/confluence/WEB-INF/classes里,根据class loader的加载机制,本地加载的肯定会覆盖从外部jar包加载的同名类,所以不需要替换jar中的这个类就可以达到覆盖效果。

最后,再在classes目录里执行

chown -R confluence:confluence com

再次重启,一切都很正常,尝试着运行了一下,除了中间几个是其他问题引起的异常,没有关于数据库方面的异常,这也多亏了MySQL5.7在使用方面基本兼容了老版本。

bitbucket

原理和步骤和confluence是一样的,先修改<bitbucket-home>/shared/bitbucket.properties里的

jdbc.url=jdbc:mysql://127.0.0.1:3306/bitbucket?sessionVariables=storage_engine&characterEncoding=utf8&useUnicode=true

修改成

jdbc.url=jdbc:mysql://127.0.0.1:3306/bitbucket?characterEncoding=utf8&useUnicode=true

然后修改com.atlassian.stash.internal.db.DefaultDatabaseSupplier里的protected DatabaseSupportLevel supportFor(@Nonnull Database database)方法,将

if (minor == 1 || minor == 5 || (minor == 6 && database.getPatchVersion() >= 16)) {
                    //MySQL 5.1 and 5.5 (all patch versions) are supported
                    //MySQL 5.6.16+ is supported
                    return DatabaseSupportLevel.SUPPORTED;
                }

修改成

if (minor == 1 || minor == 5 || (minor == 6 && database.getPatchVersion() >= 16) || minor == 7) {
                    //MySQL 5.1 and 5.5 (all patch versions) are supported
                    //MySQL 5.6.16+ is supported
                    return DatabaseSupportLevel.SUPPORTED;
                }

同样方法保持包结构扔到运行目录atlassian-bitbucket/WEB-INF/classes里,然后执行

chown -R atlbitbucket:atlbitbucket com

重启观察日志,发现没有问题。

Show Comments