
在本文中,我们将讨论从备份还原Jira时如何摆脱Active Objects表的错误,并编写一个插件从备份存档文件中删除不必要的Active Objects表。
什么是活动对象表?
Jira数据库包含两种类型的表:系统表(例如jiraissue,cwd_user,changegroup)和由Jira中安装的插件添加的表。 这些表是活动对象表。 可以通过前缀AO_XXXXXX轻松将它们与系统表区分开。
AO代表Active Objects,XXXXXX是Jira为每个插件生成的哈希码。 为了能够在不同的插件中创建具有相同名称的表,需要使用哈希码。 由于将AO_XXXXXX前缀添加到具有相同名称的表之后,表名称开始有所不同,因此可以在数据库中创建它们。
活动对象是Atlassian产品中的ORM层。
在此处了解更多信息。
在Jira中,如果转到Gear-> System-> Plugin Data Storage,则可以查看有关每个插件创建的所有表的信息。 例如,在我的Jira实例上,插件信息如下所示:

屏幕快照显示Atlassian Notifications插件创建了三个表,其哈希码为21F425
AO错误
现在让我们看看这些错误的实时情况。 这是“遇到不支持的字段:二进制”错误的示例:

我们修复了错误“遇到不支持的字段:二进制”
让我们尝试解决此错误。 为此,请解压缩备份文件。 在内部,我们将看到两个文件:entity.xml和activeobjects.xml。
Entitys.xml文件包含系统表数据。 activeobjects.xml文件包含Active Objects表数据。 我们只需要activeobjects.xml文件。
打开文件activeobjects.xml文件,然后在文件中查找单词“ binary”。 就我而言,找到了10个匹配项。 这些匹配如下所示:
<row> <string>Alexey Matveev</string> <string>alexey.matveev@aaa.com</string> <integer>1</integer> <timestamp xsi:nil="true"/> <string xsi:nil="true"/> <integer xsi:nil="true"/> <binary xsi:nil="true"/> <string xsi:nil="true"/> <string xsi:nil="true"/> <integer xsi:nil="true"/> <string>Europe/Moscow</string> <string>alexey</string> <string>alexey</string> </row>
删除activeobjects.xml文件中的所有行<binary xsi:nil =“ true” />,然后尝试再次还原Jira。
这次错误“遇到不支持的字段:二进制”已修复,但我们看到了一个新错误:

让我们看一下atlassian-jira.log文件的内容:
[INFO] [talledLocalContainer] com.atlassian.activeobjects.spi.ActiveObjectsImportExportException: There was an error during import/export with <unknown plugin> (table AO_6B9F04_AIO_USER):Could not import data in table 'AO_6B9F04_AIO_USER' column
如果您在Internet上查找有关此错误的信息,我们将找到这样的
KB 。
在该KB中,建议将第10号字段的尺寸更改为-1。 让我们尝试一下。
<table name="AO_6B9F04_AIO_USER"> <column name="DISPLAY_NAME" primaryKey="false" autoIncrement="false" sqlType="-9" precision="255"/> <column name="EMAIL_ADDRESS" primaryKey="false" autoIncrement="false" sqlType="-9" precision="255"/> <column name="ID" primaryKey="true" autoIncrement="true" sqlType="4" precision="10"/> <column name="LAST_LOGIN_DATE" primaryKey="false" autoIncrement="false" sqlType="93" precision="23" scale="3"/> <column name="LOCALE" primaryKey="false" autoIncrement="false" sqlType="-9" precision="255"/> <column name="LOGIN_DAYS_COUNT" primaryKey="false" autoIncrement="false" sqlType="4" precision="10"/> <column name="O_AUTH_TOKEN" primaryKey="false" autoIncrement="false" sqlType="-4" precision="2147483647"/> <column name="O_AUTH_TOKEN_SECRET" primaryKey="false" autoIncrement="false" sqlType="-9" precision="255"/> <column name="TABLEAU_KEY" primaryKey="false" autoIncrement="false" sqlType="-9" precision="255"/> <column name="TENANT_ID" primaryKey="false" autoIncrement="false" sqlType="4" precision="10"/> <column name="TIME_ZONE" primaryKey="false" autoIncrement="false" sqlType="-9" precision="255"/> <column name="USERKEY" primaryKey="false" autoIncrement="false" sqlType="-9" precision="255"/> <column name="USERNAME" primaryKey="false" autoIncrement="false" sqlType="-9" precision="255"/> <foreignKey fromTable="AO_6B9F04_AIO_USER" fromColumn="TENANT_ID" toTable="AO_6B9F04_AIO_TENANT" toColumn="ID"/> </table>
变更:
<column name="TENANT_ID" primaryKey="false" autoIncrement="false" sqlType="4" precision="10"/>
在
<column name="TENANT_ID" primaryKey="false" autoIncrement="false" sqlType="4" precision="-1"/>
并尝试从我们的备份中还原Jira。
在日志中,我们再次看到相同的错误。 KB没有帮助。
知名插件
让我们再次仔细阅读该错误。 我们将看到无法导入UKNOWN PLUGIN插件中的数据。 为什么使用未知插件(UKNOWN PLUIGN)?
如果查看下面的屏幕截图,您会发现某些活动对象没有与它们相关的插件的名称:

您可以看到插件在红色矩形中,但是插件不在蓝色矩形中。 如果我们安装插件,然后将其卸载,然后通过删除.osgi_plugins文件夹重新启动Jira,则会发生这种情况。 如果插件有任何问题,建议使用这种类型的重启Jira。
我们的表AIO_USER没有插件名称,因此我们只需删除该表即可。
让我们在activeobjects.xml文件中找到该表的定义,删除找到的定义,然后尝试从备份中还原Jira。
我们将看到另一个错误:
[INFO] [talledLocalContainer] com.atlassian.activeobjects.spi.ActiveObjectsImportExportException: There was an error during import/export with <unknown plugin> (table AO_6B9F04_AIO_USER):Could not create prepared statement for SQL query, [INSERT INTO PUBLIC."AO_6B9F04_AIO_USER" ("DISPLAY_NAME", "EMAIL_ADDRESS", "ID", "LAST_LOGIN_DATE", "LOCALE", "LOGIN_DAYS_COUNT", "O_AUTH_TOKEN", "O_AUTH_TOKEN_SECRET", "TABLEAU_KEY", "TENANT_ID", "TIME_ZONE", "USERKEY", "USERNAME") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)]
问题是我们删除了表定义,但没有从该表中删除数据。 让我们在activeobjects.xml文件中找到此表中的数据并将其删除。
表格上的数据以以下标记开头:
<data tableName="AO_6B9F04_AIO_USER">
并以该标签结尾:
</data>
让我们删除这些标签以及这些标签之间的所有内容,然后再次尝试从备份中还原Jira。
我们将收到另一个错误:
There was a problem restoring ActiveObjects data for the <unknown plugin> plugin. Caught exception with following message: Table "AO_6B9F04_AIO_USER" not found; SQL statement: ALTER TABLE PUBLIC.AO_6B9F04_AIO_REPORT ADD CONSTRAINT fk_ao_6b9f04_aio_report_owner_id FOREIGN KEY (OWNER_ID) REFERENCES PUBLIC.AO_6B9F04_AIO_USER(ID) [42102-185]. Please check the log for details.
这意味着插件中仍然有引用该表的表,因此我们仍然需要删除所有引用远程表的表。 然后一切都会顺着链条进行:您可能需要删除此插件的引用已删除表的表。
因此,以编程方式从备份文件中删除所有带有AO_6B9F04前缀的表将更快。
让我们编写一个插件,该插件将通过给定的前缀从备份文件中删除表。 该插件将由Webwork组成,该Webwork将接收备份文件的名称(备份文件必须位于JIRA_HOME / import中)和前缀。
插件的源代码可以在
这里获取 。
创建一个插件
打开终端并执行以下命令:
atlas-create-jira-plugin
您需要回答以下问题:
Define value for groupId: : ru.matveev.alexey.plugins.jira.cleanbackup Define value for artifactId: : clean-backup Define value for version: 1.0.0-SNAPSHOT: : Define value for package: ru.matveev.alexey.plugins.jira.cleanbackup: : Confirm properties configuration: groupId: ru.matveev.alexey.plugins.jira.cleanbackup artifactId: clean-backup version: 1.0.0-SNAPSHOT package: ru.matveev.alexey.plugins.jira.cleanbackup Y: : Y
编辑POM.XML
pom.xml文件应如下所示:
bitbucket.org/alex1mmm/clean-backup/src/master/pom.xml我们创建WEBWORK,WEB SECTION和WEB ITEM
打开终端并执行:
atlas-create-jira-plugin-module
您需要回答以下问题:
Choose a number (1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17/18/19/20/21/22/23/24/25/26/27/28/29/30/31/32/33/34): 31 Enter Plugin Module Name My Webwork Module: : cleanbackup Show Advanced Setup? (Y/y/N/n) N: : y Module Key cleanbackup: : Module Description The cleanbackup Plugin: : i18n Name Key cleanbackup.name: : i18n Description Key cleanbackup.description: : Enter Action Classname MyActionClass: : CleanBackup Enter Package Name ru.matveev.alexey.plugins.jira.cleanbackup.jira.webwork: : Enter Alias CleanBackup: : CleanBackup Enter View Name success: : success Enter Template Path /templates/cleanbackup/cleanbackup/success.vm: : Add Another View? (Y/y/N/n) N: : N Add Another Action? (Y/y/N/n) N: : N Add Another Plugin Module? (Y/y/N/n) N: : Y Choose a number (1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17/18/19/20/21/22/23/24/25/26/27/28/29/30/31/32/33/34): 30 Enter Plugin Module Name My Web Section: : CleanBackup Enter Location (eg system.admin/mynewsection): admin_plugins_menu Show Advanced Setup? (Y/y/N/n) N: : n Add Another Plugin Module? (Y/y/N/n) N: : Y Choose a number (1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17/18/19/20/21/22/23/24/25/26/27/28/29/30/31/32/33/34): 25 Enter Plugin Module Name My Web Item: : CleanAO Enter Section (eg system.admin/globalsettings): admin_plugins_menu/clean-backup Enter Link URL (eg /secure/CreateIssue!default.jspa): /secure/CleanBackup.jspa? Show Advanced Setup? (Y/y/N/n) N: : Y Module Key clean-ao: : Module Description The CleanAO Plugin: : i18n Name Key clean-ao.name: : i18n Description Key clean-ao.description: : Weight 1000: : Link Id clean-ao-link: : Enter Label Key clean-ao.label: : CleanBackup Enter Label Value CleanAO: : CleanAO Add Label Param? (Y/y/N/n) N: : n Add Icon? (Y/y/N/n) N: : n Add Tooltip? (Y/y/N/n) N: : n Add Resource (Y/y/N/n) N: : n Add Velocity Context Provider (Y/y/N/n) N: : n Add Plugin Module Param? (Y/y/N/n) N: : n Add Conditions? (Y/y/N/n) N: : n Add Another Plugin Module? (Y/y/N/n) N: : n
编辑WEBWORK和SUCCESS.VM
更改我们的success.vm,以便我们的网络可以使用两个参数:备份名称和前缀:
clean-backup / src / main /资源/模板/cleanbackup/cleanbackup/success.vm 。
我们将使用SAX处理xml文件,因此我们将编写一个过滤器来删除表:
clean-backup / src / main / java / ru / matveev / alexey / plugins / jira / cleanbackup / jira / webwork / TableFilter.java 。
现在更改网络。
clean-backup / src / main / java / ru / matveev / alexey / plugins / jira / cleanbackup / jira / webwork / CleanBackup.java生成并运行我们的插件
我们转到plugin文件夹并执行:
atlas-run
Jira启动后,将我们的备份文件放在JIRA_HOME / import中,然后在浏览器中转到以下地址:
本地主机 :2990 / jira /安全/ CleanBackup.jspa
输入备份的名称,前缀,然后单击“清理”按钮:

我们输入的带有前缀的表将从备份中删除,然后您可以还原Jira。