Liquibase 在 JBoss 中不工作?

Liquibase not working from within JBoss?

我正在使用 Liquibase 3.3.2 并尝试实现一个接受大量变更日志的 Web 服务,根据上下文查找特定的数据源,并将该数据源与 liquibase ChangeLogs 一起使用以执行数据库更新。

我正在使用 PostgreSQL 作为数据库。

Web 服务端的 liquibase 日志以某种方式显示完全没有问题,一切似乎都在正确执行。然而,没有表出现在数据库中,甚至没有 Liquibase 自己的 lock/state 表..

这是启用了 Liquibase 调试日志记录的 web 服务的日志记录:

14:09:11,918 INFO  [nl.minienm.standaardplatform.databasemanager.DatabaseManager] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2) Parsing with class liquibase.parser.core.xml.XMLChangeLogSAXParser
14:09:12,385 INFO  [nl.minienm.standaardplatform.databasemanager.DatabaseManager] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2) Obtaining Connection...
14:09:12,385 INFO  [nl.minienm.standaardplatform.databasemanager.configuration.ConfigurationLoaderConfigurationProviderImpl] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2) Looking up JNDI datasource for application 'StandaardPlatformReferentieImpl'
14:09:12,410 INFO  [nl.minienm.standaardplatform.databasemanager.configuration.ConfigurationLoaderConfigurationProviderImpl] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2) Application datasource java:jboss/datasources/referentieimplDS
14:09:12,413 INFO  [nl.minienm.standaardplatform.databasemanager.DatabaseManager] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2) Connection Obtained. AC=false SCHEMADEFAULT=public 
14:09:12,440 INFO  [nl.minienm.standaardplatform.databasemanager.DatabaseManager] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2) Running Liquibase on ChangeLog /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml
14:09:12,458 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2) DEBUG 2/27/15 2:09 PM: liquibase: Created database lock table with name: public.databasechangeloglock
14:09:12,459 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2) DEBUG 2/27/15 2:09 PM: liquibase: Executing QUERY database command: select count(*) from public.databasechangeloglock
14:09:12,464 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2) INFO 2/27/15 2:09 PM: liquibase: Successfully acquired change log lock
14:09:12,467 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2) INFO 2/27/15 2:09 PM: liquibase: Creating database history table with name: public.databasechangelog
14:09:12,469 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2) DEBUG 2/27/15 2:09 PM: liquibase: Executing QUERY database command: select count(*) from public.databasechangeloglock
14:09:12,483 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2) DEBUG 2/27/15 2:09 PM: liquibase: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml::1.0.0::sander: Running Changeset:/tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml::1.0.0::sander
14:09:12,485 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2) DEBUG 2/27/15 2:09 PM: liquibase: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml::1.0.0::sander: Reading ChangeSet: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml::1.0.0::sander
14:09:12,486 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2) DEBUG 2/27/15 2:09 PM: liquibase: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml::1.0.0::sander: Executing Statement: liquibase.statement.core.CreateTableStatement@e35392a
14:09:12,486 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2) INFO 2/27/15 2:09 PM: liquibase: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml::1.0.0::sander: Table Persoon created
14:09:12,486 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2) INFO 2/27/15 2:09 PM: liquibase: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml::1.0.0::sander: ChangeSet /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml::1.0.0::sander ran successfully in 2ms
14:09:12,488 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2) DEBUG 2/27/15 2:09 PM: liquibase: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml::1.0.0::sander: Executing QUERY database command: SELECT MAX(ORDEREXECUTED) FROM public.databasechangelog
14:09:12,491 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2) DEBUG 2/27/15 2:09 PM: liquibase: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml::1.0.0::sander: Computed checksum for createTable:[
14:09:12,492 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)     columns=[
14:09:12,492 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)         [
14:09:12,492 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)             [
14:09:12,492 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)                 nullable="true"
14:09:12,492 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)                 primaryKey="false"
14:09:12,492 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)                 unique="false"
14:09:12,493 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)             ]
14:09:12,493 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)             name="Voornaam"
14:09:12,493 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)             type="varchar(64)"
14:09:12,493 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)         ]
14:09:12,493 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)     ]
14:09:12,493 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)     tableName="Persoon"
14:09:12,494 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2) ] as 69c496bed203364c2bcf0d96b3cd03ae
14:09:12,494 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2) DEBUG 2/27/15 2:09 PM: liquibase: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml::1.0.0::sander: Computed checksum for 7:69c496bed203364c2bcf0d96b3cd03ae: as 7723e55b38281ea28fc0d01a060bc8ad
14:09:12,497 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2) DEBUG 2/27/15 2:09 PM: liquibase: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml::1.0.0::sander: Computed checksum for createTable:[
14:09:12,497 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)     columns=[
14:09:12,498 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)         [
14:09:12,498 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)             [
14:09:12,498 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)                 nullable="true"
14:09:12,498 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)                 primaryKey="false"
14:09:12,498 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)                 unique="false"
14:09:12,498 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)             ]
14:09:12,499 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)             name="Voornaam"
14:09:12,499 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)             type="varchar(64)"
14:09:12,499 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)         ]
14:09:12,499 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)     ]
14:09:12,499 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)     tableName="Persoon"
14:09:12,499 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2) ] as 69c496bed203364c2bcf0d96b3cd03ae
14:09:12,500 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2) DEBUG 2/27/15 2:09 PM: liquibase: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml::1.0.0::sander: Computed checksum for 7:69c496bed203364c2bcf0d96b3cd03ae: as 7723e55b38281ea28fc0d01a060bc8ad
14:09:12,508 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2) DEBUG 2/27/15 2:09 PM: liquibase: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml::1.0.1::sander: Running Changeset:/tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml::1.0.1::sander
14:09:12,510 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2) DEBUG 2/27/15 2:09 PM: liquibase: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml::1.0.1::sander: Reading ChangeSet: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml::1.0.1::sander
14:09:12,510 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2) DEBUG 2/27/15 2:09 PM: liquibase: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml::1.0.1::sander: Executing Statement: liquibase.statement.core.CreateTableStatement@6a1b9b89
14:09:12,511 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2) INFO 2/27/15 2:09 PM: liquibase: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml::1.0.1::sander: Table mytable created
14:09:12,511 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2) INFO 2/27/15 2:09 PM: liquibase: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml::1.0.1::sander: ChangeSet /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml::1.0.1::sander ran successfully in 3ms
14:09:12,512 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2) DEBUG 2/27/15 2:09 PM: liquibase: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml::1.0.1::sander: Computed checksum for createTable:[
14:09:12,512 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)     columns=[
14:09:12,512 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)         [
14:09:12,512 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)             [
14:09:12,512 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)                 nullable="true"
14:09:12,513 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)                 primaryKey="false"
14:09:12,513 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)                 unique="false"
14:09:12,513 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)             ]
14:09:12,513 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)             name="teller"
14:09:12,513 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)             type="int"
14:09:12,513 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)         ]
14:09:12,514 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)     ]
14:09:12,514 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)     tableName="mytable"
14:09:12,514 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2) ] as 2297ed7210f5e9b39e7b007c4067500f
14:09:12,514 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2) DEBUG 2/27/15 2:09 PM: liquibase: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml::1.0.1::sander: Computed checksum for 7:2297ed7210f5e9b39e7b007c4067500f: as e7ad573879c5874b948897438bee1f5a
14:09:12,516 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2) DEBUG 2/27/15 2:09 PM: liquibase: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml::1.0.1::sander: Computed checksum for createTable:[
14:09:12,516 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)     columns=[
14:09:12,516 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)         [
14:09:12,516 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)             [
14:09:12,517 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)                 nullable="true"
14:09:12,517 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)                 primaryKey="false"
14:09:12,517 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)                 unique="false"
14:09:12,517 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)             ]
14:09:12,517 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)             name="teller"
14:09:12,517 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)             type="int"
14:09:12,518 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)         ]
14:09:12,518 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)     ]
14:09:12,518 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2)     tableName="mytable"
14:09:12,518 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2) ] as 2297ed7210f5e9b39e7b007c4067500f
14:09:12,518 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2) DEBUG 2/27/15 2:09 PM: liquibase: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml: /tmp/tmp1005363315409204/blah/tmp/test/changelog-001.xml::1.0.1::sander: Computed checksum for 7:2297ed7210f5e9b39e7b007c4067500f: as e7ad573879c5874b948897438bee1f5a
14:09:12,519 ERROR [stderr] (ajp-SP-TST-Orange-PRD-Server2/172.31.115.228:8009-2) INFO 2/27/15 2:09 PM: liquibase: Successfully released change log lock

PostgreSQL 的日志只显示:

< 2015-02-27 13:50:16.622 CET >ERROR:  relation "public.databasechangeloglock" does not exist at character 22
< 2015-02-27 13:50:16.622 CET >STATEMENT:  select count(*) from public.databasechangeloglock
< 2015-02-27 13:50:16.632 CET >ERROR:  relation "public.databasechangeloglock" does not exist at character 22
< 2015-02-27 13:50:16.632 CET >STATEMENT:  select count(*) from public.databasechangeloglock
< 2015-02-27 13:50:16.653 CET >ERROR:  relation "public.databasechangelog" does not exist at character 32
< 2015-02-27 13:50:16.653 CET >STATEMENT:  SELECT MAX(ORDEREXECUTED) FROM public.databasechangelog

如果我将 Writer 对象传递给 Liquibase.update(),它会填充正确的 SQL,我可以从 pgAdmin 手动执行并获得所需的结果,所以我知道它不会生成无效 SQL:

-- *********************************************************************
-- Update Database Script
-- *********************************************************************
-- Change Log: /tmp/tmp8746853329558673/blah/tmp/test/changelog-001.xml
-- Ran at: 2/27/15 2:17 PM
-- Against: referentieimplDBUser@jdbc:postgresql://sp-tst-green-prd-server1.kernteamcloud.nl/referentieimplDB
-- Liquibase version: 3.3.2
-- *********************************************************************

-- Create Database Lock Table
CREATE TABLE public.databasechangeloglock (ID INT NOT NULL, LOCKED BOOLEAN NOT NULL, LOCKGRANTED TIMESTAMP WITHOUT TIME ZONE, LOCKEDBY VARCHAR(255), CONSTRAINT PK_DATABASECHANGELOGLOCK PRIMARY KEY (ID));

-- Initialize Database Lock Table
DELETE FROM public.databasechangeloglock;

INSERT INTO public.databasechangeloglock (ID, LOCKED) VALUES (1, FALSE);

-- Lock Database
UPDATE public.databasechangeloglock SET LOCKED = TRUE, LOCKEDBY = 'SP-TST-Orange-PRD-Server2 (172.31.115.228)', LOCKGRANTED = '2015-02-27 14:17:01.121' WHERE ID = 1 AND LOCKED = FALSE;

-- Create Database Change Log Table
CREATE TABLE public.databasechangelog (ID VARCHAR(255) NOT NULL, AUTHOR VARCHAR(255) NOT NULL, FILENAME VARCHAR(255) NOT NULL, DATEEXECUTED TIMESTAMP WITHOUT TIME ZONE NOT NULL, ORDEREXECUTED INT NOT NULL, EXECTYPE VARCHAR(10) NOT NULL, MD5SUM VARCHAR(35), DESCRIPTION VARCHAR(255), COMMENTS VARCHAR(255), TAG VARCHAR(255), LIQUIBASE VARCHAR(20));

-- Changeset /tmp/tmp8746853329558673/blah/tmp/test/changelog-001.xml::1.0.0::sander
CREATE TABLE public."Persoon" ("Voornaam" VARCHAR(64));

INSERT INTO public.databasechangelog (ID, AUTHOR, FILENAME, DATEEXECUTED, ORDEREXECUTED, MD5SUM, DESCRIPTION, COMMENTS, EXECTYPE, LIQUIBASE) VALUES ('1.0.0', 'sander', '/tmp/tmp8746853329558673/blah/tmp/test/changelog-001.xml', NOW(), 1, '7:7723e55b38281ea28fc0d01a060bc8ad', 'createTable', '', 'EXECUTED', '3.3.2');

-- Changeset /tmp/tmp8746853329558673/blah/tmp/test/changelog-001.xml::1.0.1::sander
CREATE TABLE public.mytable (teller INT);

INSERT INTO public.databasechangelog (ID, AUTHOR, FILENAME, DATEEXECUTED, ORDEREXECUTED, MD5SUM, DESCRIPTION, COMMENTS, EXECTYPE, LIQUIBASE) VALUES ('1.0.1', 'sander', '/tmp/tmp8746853329558673/blah/tmp/test/changelog-001.xml', NOW(), 2, '7:e7ad573879c5874b948897438bee1f5a', 'createTable', '', 'EXECUTED', '3.3.2');

-- Release Database Lock
UPDATE public.databasechangeloglock SET LOCKED = FALSE, LOCKEDBY = NULL, LOCKGRANTED = NULL WHERE ID = 1;

我在这里错过了什么?是否有遗漏的提交?我的数据源有问题吗? Liquibase 中的某些(未)设置状态?

我在这里发布问题后很快就找到了原因,所以回答我自己的问题:

将 Writer 对象传递给 Liquibase 确实会捕获生成的 SQL 给那个 Writer,但也会 防止 它被发送到数据库。

因此,不传递 Writer 对象实际上会使 SQL 转到数据库,在这种情况下,一切都会正常工作。

此行为没有记录,也没有从源代码中立即清楚。