目录

升级前准备

目前 JIRA 版本:7.3.8

升级前做一下JIRA更新检查,检查升级目标版本与当前版本中插件的兼容性,不兼容的建议禁用后再升级。

1. 备份JIRA数据库

mysqldump -u root --default-character-set=utf8mb4 -p jira > /sql/jira-20250606.sql

2. 备份JIRA数据

【系统】-【导入与导出】-【备份系统】

升级Jira7->9记录一下

记录当前版本的ServerID,【系统】-【系统信息】

升级Jira7->9记录一下

ServerID:BKA9-QK04-R963-TZ91

3. 备份文件

需要关注的文件路径

JIRA本地主页位置 /var/atlassian/application-data/jira
JIRA共享主页位置 /var/atlassian/application-data/jira
位置 entityengine xml file:/opt/atlassian/jira/atlassian-jira/WEB-INF/classes/entityengine.xml
atlassian-jira.log的位置 /var/atlassian/application-data/jira/log/atlassian-jira.log
索引位置 /var/atlassian/application-data/jira/caches/indexes
附近位置 /var/atlassian/application-data/jira/data/attachments
备份位置 /var/atlassian/application-data/jira/export

/var/atlassian/application-data/jira 就是正常需要迁移的所有文件。

我看了一下我需要的主要是 data/ 和 dbconfig.xml ,就只迁移这2个,按自己的需求。

cd /var/atlassian/application-data/jira

tar -czvf data.tar.gz data/

安装新版本JIRA

新版本我使用docker安装,使用的是:https://github.com/haxqer/jira

docker-compose.yaml

version: '3.4'
services:
  jira:
    image: haxqer/jira:9.17.5
    privileged: true
    container_name: jira
    environment:
      - TZ=Asia/Shanghai
      - JVM_MINIMUM_MEMORY=1g
      - JVM_MAXIMUM_MEMORY=8g
      - JVM_CODE_CACHE_ARGS='-XX:InitialCodeCacheSize=1g -XX:ReservedCodeCacheSize=8g'
    depends_on:
      - mysql
    ports:
      - "8080:8080"
    volumes:
      - ./jira-data:/var/jira
    restart: always
    networks:
      - network-bridge

  mysql:
    image: mysql:8.0
    container_name: mysql8
    environment:
      - TZ=Asia/Shanghai
      - MYSQL_DATABASE=jira
      - MYSQL_ROOT_PASSWORD=123456
      - MYSQL_USER=jira
      - MYSQL_PASSWORD=123456
    command: ['mysqld', '--character-set-server=utf8mb4', '--collation-server=utf8mb4_bin']
    ports:
      - "13306:3306"
    volumes:
      - ./mysql/data:/var/lib/mysql
      - ./mysql/my.cnf:/etc/my.cnf
    restart: always
    networks:
      - network-bridge

networks:
  network-bridge:
    driver: bridge

配置修改

需要给jira data挂载目录设置用户组:chown -R 999:999 ./jira-data

否则可能会报错:Ensure JIRA has permission to create and write to the jira.home directory /var/jira.

mysql需要设置lower_case_table_names=1,如果不设置为1 忽略大小写的话,后续升级会报错表找不到:

An unexpected error has occured during startup.: We couldn't start JIRA
An error occurred while trying to start JIRA. We can't give you any more detail right now, we suggest checking the logs for more detail and contacting our support team.
See our documentation for more information on contacting our support team and creating a support zip.

SQL Exception
java.sql.SQLSyntaxErrorException: Table 'jira.SEQUENCE_VALUE_ITEM' doesn't exist
        at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120)

主要添加了:

lower_case_table_names=1
character-set-server=utf8mb4
collation-server=utf8mb4_bin

./mysql/my.cnf

# For advice on how to change settings please see
# http://dev.mysql.com/doc/refman/8.0/en/server-configuration-defaults.html

[mysqld]
#
# Remove leading # and set to the amount of RAM for the most important data
# cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.
# innodb_buffer_pool_size = 128M
#
# Remove leading # to turn on a very important data integrity option: logging
# changes to the binary log between backups.
# log_bin
#
# Remove leading # to set options mainly useful for reporting servers.
# The server defaults are faster for transactions and fast SELECTs.
# Adjust sizes as needed, experiment to find the optimal values.
# join_buffer_size = 128M
# sort_buffer_size = 2M
# read_rnd_buffer_size = 2M

# Remove leading # to revert to previous value for default_authentication_plugin,
# this will increase compatibility with older clients. For background, see:
# https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_default_authentication_plugin
# default-authentication-plugin=mysql_native_password
skip-host-cache
skip-name-resolve
datadir=/var/lib/mysql
socket=/var/run/mysqld/mysqld.sock
secure-file-priv=/var/lib/mysql-files
user=mysql

lower_case_table_names=1
character-set-server=utf8mb4
collation-server=utf8mb4_bin

pid-file=/var/run/mysqld/mysqld.pid
[client]
socket=/var/run/mysqld/mysqld.sock

!includedir /etc/mysql/conf.d/

启动Jira和mysql

docker compose up -d

导入mysql数据

导入前面备份的老数据SQL

设置字符集和排序规则

sed -i 's/CHARSET=utf8/CHARSET=utf8mb4/g' jira-20250606.sql
sed -i 's/CHARACTER SET utf8/CHARACTER SET utf8mb4/g' jira-20250606.sql
sed -i 's/CHARSET="utf8"/CHARSET="utf8mb4"/g' jira-20250606.sql 
sed -i 's/utf8_bin/utf8mb4_bin/g' jira-20250606.sql
sed -i 's/utf8_unicode_ci/utf8mb4_unicode_ci/g' jira-20250606.sql

导入

mysql -uroot --default-character-set=utf8mb4 -p -D jira < /sql/jira-20250606.sql

升级JIRA

这时候不要直接访问jira,通过页面的方式不能升级,会报错:

您指定的数据库, 不为空, 请指定空数据库。如果您要升级现有的安装, 请按照https://docs.atlassian.com/jira/jadm-docs-0917/Connecting+Jira+applications+to+a+Database#ConnectingJiraapplicationstoadatabase-UpgradingJiraormigratingJiratoanotherserver?"的这些说明。

将dbconfig.xml 放入 jira-data 目录下,修改为新的mysql8数据库参数

chown 999:999 dbconfig.xml

dbconfig.xml

<?xml version="1.0" encoding="UTF8"?>

<jira-database-config>
  <name>defaultDS</name>
  <delegator-name>default</delegator-name>
  <database-type>mysql8</database-type>
  <jdbc-datasource>
    <url>jdbc:mysql://address=(protocol=tcp)(host=192.168.5.1)(port=13306)/jira?sessionVariables=default_storage_engine=InnoDB</url>
    <driver-class>com.mysql.cj.jdbc.Driver</driver-class>
    <username>jira</username>
    <password>123456</password>
    <pool-min-size>40</pool-min-size>
    <pool-max-size>40</pool-max-size>
    <pool-max-wait>30000</pool-max-wait>
    <validation-query>select 1</validation-query>
    <min-evictable-idle-time-millis>60000</min-evictable-idle-time-millis>
    <time-between-eviction-runs-millis>300000</time-between-eviction-runs-millis>
    <pool-max-idle>40</pool-max-idle>
    <pool-remove-abandoned>true</pool-remove-abandoned>
    <pool-remove-abandoned-timeout>300</pool-remove-abandoned-timeout>
    <pool-test-on-borrow>false</pool-test-on-borrow>
    <pool-test-while-idle>true</pool-test-while-idle>
    <validation-query-timeout>3</validation-query-timeout>
    <connection-properties>nullDatabaseMeansCurrent=true</connection-properties>
  </jdbc-datasource>
</jira-database-config>

将备份的 data/ 移动到 jira-data/ 下,记得用户组调整下

tar xzvf data.tar.gz

chown 999:999 data/

获取Jira License

docker exec jira java -jar /var/agent/atlassian-agent.jar \
    -d \
    -p jira \
    -m Hello@world.com \
    -n Hello@world.com \
    -o your-org \
    -s BKA9-QK04-R963-TZ91

-s 后的参数替换成老版本的ServerID(也可从数据库的propertystring表中找到)

升级Jira7->9记录一下

复制License,打开数据库,找到 productlicense 表,将 LICENSE 替换

升级Jira7->9记录一下

重启Jira

docker restart jira

访问jira,可能会报错:

很抱歉, 我们已有技术上的问题的上一次操作期间。
复制下面内容并发送给Jira管理员,日志查询编号: f1a07250-383a-414e-8c53-9e0752dcf358

grep "f1a07250-383a-414e-8c53-9e0752dcf358" jira-data/log/atlassian-jira.log -C 20

也可能会看到下面的页面

升级Jira7->9记录一下

升级Jira7->9记录一下

这时候也需要看一下日志,看一下是否会导致升级失败。

tail -f jira-data/log/atlassian-jira.log -n 200

升级Jira7->9记录一下

升级Jira7->9记录一下

不过我看到的这些错误不会影响程序运行,稍等一会儿再访问应该能登录了。

升级Jira7->9记录一下

升级后重建一下检索

设置二级目录访问

修改文件:/opt/jira/conf/server.xml

比如我想通过http://xxx.com:10086/jira 来访问,主要修改:

<!-- 启用HTTP代理连接器 -->
        <Connector port="8080" relaxedPathChars="[]|" relaxedQueryChars="[]|{}^&#x5c;&#x60;&quot;&lt;&gt;"
                   maxThreads="150" minSpareThreads="25" connectionTimeout="20000" enableLookups="false"
                   maxHttpHeaderSize="8192" protocol="HTTP/1.1" useBodyEncodingForURI="true" redirectPort="8443"
                   acceptCount="100" disableUploadTimeout="true" bindOnInit="false" scheme="http"
                   proxyName="xxx.com" proxyPort="10086"/>
<Context path="/jira" docBase="${catalina.home}/atlassian-jira" reloadable="false" useHttpOnly="true">

然后就会使用二级目录/jira才能访问到项目了。

server.xml 整个文件:

<?xml version="1.0" encoding="utf-8"?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<Server port="8005" shutdown="SHUTDOWN">
    <Listener className="org.apache.catalina.startup.VersionLoggerListener"/>
        <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on"/>
        <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener"/>
    <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/>
    <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener"/>

    <Service name="Catalina">
        <!--
         ==============================================================================================================
         DEFAULT - Direct connector with no proxy for unproxied access to Jira.

         If using a http/https proxy, comment out this connector.
         ==============================================================================================================
        -->

        <!-- Relaxing chars because of JRASERVER-67974 -->
        <!-- 注释 
        <Connector port="8080" relaxedPathChars="[]|" relaxedQueryChars="[]|{}^&#x5c;&#x60;&quot;&lt;&gt;"
                   maxThreads="150" minSpareThreads="25" connectionTimeout="20000" enableLookups="false"
                   maxHttpHeaderSize="8192" protocol="HTTP/1.1" useBodyEncodingForURI="true" redirectPort="8443"
                   acceptCount="100" disableUploadTimeout="true" bindOnInit="false"/>
        -->
        <!-- 启用HTTP代理连接器 -->
        <Connector port="8080" relaxedPathChars="[]|" relaxedQueryChars="[]|{}^&#x5c;&#x60;&quot;&lt;&gt;"
                   maxThreads="150" minSpareThreads="25" connectionTimeout="20000" enableLookups="false"
                   maxHttpHeaderSize="8192" protocol="HTTP/1.1" useBodyEncodingForURI="true" redirectPort="8443"
                   acceptCount="100" disableUploadTimeout="true" bindOnInit="false" scheme="http"
                   proxyName="xxx.com" proxyPort="10086"/>
        <!--
         ==============================================================================================================
         HTTP - Proxying Jira via Apache or Nginx over HTTP

         If you're proxying traffic to Jira over HTTP, uncomment the below connector and comment out the others.
         Ensure the proxyName and proxyPort are updated with the appropriate information if necessary as per the docs.

         See the following for more information:

            Apache - https://confluence.atlassian.com/x/4xQLM
            nginx  - https://confluence.atlassian.com/x/DAFmGQ
         ==============================================================================================================
        -->

        <!--
        <Connector port="8080" relaxedPathChars="[]|" relaxedQueryChars="[]|{}^&#x5c;&#x60;&quot;&lt;&gt;"
                   maxThreads="150" minSpareThreads="25" connectionTimeout="20000" enableLookups="false"
                   maxHttpHeaderSize="8192" protocol="HTTP/1.1" useBodyEncodingForURI="true" redirectPort="8443"
                   acceptCount="100" disableUploadTimeout="true" bindOnInit="false" scheme="http"
                   proxyName="<subdomain>.<domain>.com" proxyPort="80"/>

        -->
        <!--
         ==============================================================================================================
         HTTPS - Proxying Jira via Apache or Nginx over HTTPS

         If you're proxying traffic to Jira over HTTPS, uncomment the below connector and comment out the others.
         Ensure the proxyName and proxyPort are updated with the appropriate information if necessary as per the docs.

         See the following for more information:

            Apache - https://confluence.atlassian.com/x/PTT3MQ
            nginx  - https://confluence.atlassian.com/x/DAFmGQ
         ==============================================================================================================
        -->

        <!--
        <Connector port="8080" relaxedPathChars="[]|" relaxedQueryChars="[]|{}^&#x5c;&#x60;&quot;&lt;&gt;"
                   maxThreads="150" minSpareThreads="25" connectionTimeout="20000" enableLookups="false"
                   maxHttpHeaderSize="8192" protocol="HTTP/1.1" useBodyEncodingForURI="true" redirectPort="8443"
                   acceptCount="100" disableUploadTimeout="true" bindOnInit="false" secure="true" scheme="https"
                   proxyName="<subdomain>.<domain>.com" proxyPort="443"/>
        -->

        <!--
         ==============================================================================================================
         AJP - Proxying Jira via Apache over HTTP or HTTPS

         If you're proxying traffic to Jira using the AJP protocol, uncomment the following connector line
         See the following for more information:

            Apache - https://confluence.atlassian.com/x/QiJ9MQ
         ==============================================================================================================
        -->

        <!--
        <Connector port="8009" URIEncoding="UTF-8" enableLookups="false" protocol="AJP/1.3"/>
        -->

        <Engine name="Catalina" defaultHost="localhost">
            <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">

                <Context path="/jira" docBase="${catalina.home}/atlassian-jira" reloadable="false" useHttpOnly="true">
                    <Resource name="UserTransaction" auth="Container" type="javax.transaction.UserTransaction"
                              factory="org.objectweb.jotm.UserTransactionFactory" jotm.timeout="60"/>
                    <Manager pathname=""/>
                    <JarScanner scanManifest="false"/>
                    <Valve className="org.apache.catalina.valves.StuckThreadDetectionValve" threshold="120" />
                </Context>

            </Host>
            <Valve className="org.apache.catalina.valves.AccessLogValve"
                   pattern="%a %{jira.request.id}r %{jira.request.username}r %t &quot;%m %U%{sanitized.query}r %H&quot; %s %b %D &quot;%{sanitized.referer}r&quot; &quot;%{User-Agent}i&quot; &quot;%{jira.request.assession.id}r&quot;"/>
        </Engine>
    </Service>
</Server>

插件激活

点击【立即购买】,会自动下载插件

升级Jira7->9记录一下

下载完成后点击【管理】

升级Jira7->9记录一下

复制应用密钥,执行命令

docker exec jira java -jar /var/agent/atlassian-agent.jar \
    -d \
    -p {应用密钥} \
    -m Hello@world.com \
    -n Hello@world.com \
    -o your-org \
    -s {ServerID}

示例:

docker exec jira java -jar /var/agent/atlassian-agent.jar \
    -d \
    -p com.appliger.jira.templates \
    -m Hello@world.com \
    -n Hello@world.com \
    -o your-org \
    -s BKA9-QK04-R963-TZ91

将License填入【许可证关键词】中,点击【更新】

升级Jira7->9记录一下