#日志

0 关注者 · 7 帖子

Caché 的每个实例都会保存一个日志,也就是一组文件,这些文件按时间顺序记录了自上次备份以来对数据库所做的更新。此过程是冗余的、有逻辑的,并且不使用 Caché 写守护进程

文档

InterSystems 官方 Michael Lei · 一月 21, 2025

InterSystems 已更正导致在使用特定 $LIST 语法时引入无效数据库和日志记录的缺陷。 遇到此缺陷的可能性非常低,但它对操作的影响可能会很大。

受影响的产品

  • InterSystems IRIS® 数据平台:2023.3、2024.1.0、2024.1.1、2024.1.2、2024.2、2024.3 版
  • InterSystems IRIS® for Health:2023.3、2024.1.0、2024.1.1、2024.1.2、2024.2、2024.3 版
  • HealthShare® Health Connect:2023.3.0、2024.1、2024.1.1、2024.1.2、2024.2、2024.3 版
  • HealthShare® Unified Care Record and Suite:2024.2 版
  • 基于上述产品的所有产品组合

该问题仅影响 Unicode 安装。

使用以下语法在 global 中向列表附加新元素时,会出现此问题:

SET $LIST(<global reference>, *+1) = value.

当此调用的结果列表超出最大字符串长度时,正确的行为是返回 <MAXSTRING> 错误。此错误会出现在 InterSystems IRIS、InterSystems IRIS for Health 和 Health Connect 2023.3 之前的版本中。 在 2023.3 及后续版本中,无效值会保存到数据库而不是生成 <MAXSTRING> 错误.

任何后续引用 global 节点的尝试都会导致出现 <MAXSTRING> 错误。

global 更新也会产生日志记录(假设对此 global 的更新通常都会记录)。任何尝试应用生成的日志记录(包括启动时恢复、日志恢复和镜像操作)都会失败并出现 <MAXSTRING> 错误,同时停止对日志文件的进一步处理。

如果此缺陷给您带来了影响,请联系全球响应中心 (WRC) 寻求帮助。

此缺陷的更正标识为 DP-437169 。在从 InterSystems IRIS、InterSystems IRIS for Health 和 Health Connect 2024.1.3 与 2025.1.0 开始的未来所有版本中,都将包含此更正。 您也可以通过临时分发获取。 HealthShare Unified Care Record 2025.1 版与产品套件会在发布时包含该更正,但在先前版本的维护版中将不包含该更正。 如果您对此提醒有任何疑问,请联系全球响应中心

0
0 59
文章 Michael Lei · 一月 26, 2024 2m read

InterSystems 常见问题解答

如果系统24小时没有停止,旧的日志文件将根据“日志文件删除设置”在0:30删除。

导致日志文件保留的时间早于“日志文件删除设置”的一个可能原因是存在仍处于开放状态的事务。

在这种情况下,您将能够通过搜索执行事务的进程并完成事务来删除日志文件。

下面的示例检查是否存在未完成的事务,如果存在,则输出目标文件名和日志记录信息。

(示例可以从这里下载

*注意*如果要检查的日志文件较大或日志文件较多,则执行需要时间,因此请联系我们的支持中心。

0
0 86
文章 Guangliang Zhang · 十月 21, 2022 6m read

cache数据库自身带有系统监控Portal界面,但需要运维人员定期主动查看才能获取监控信息。当系统故障发生时,容易出现由于没有及时获取故障信息而不能及时处理,从而导致造成的影响扩大。本文研究通过解析cache数据库控制台日志(cconsole.log)进行监控信息获取并主动推送微信或短信实现cache数据库主动实时监控。

cache数据库在运行时会将所有控制台消息包括一般消息、系统错误、某些操作系统错误和网络错误都会发送到控制台日志文件,通过操作员控制台工具从其他系统远程启动的作业的成功或失败等信息也会写入控制台日志,因此通过对控制台日志的解析即可获取所需要监控信息。具体步骤方法如下:

解析控制台日志

控制台日志默认存储在install-dir\mgr路径下。

根据cache版本不同,使用的读取方法也不同。对于cache2016版本以上,系统提供了EnsLib.SQL.Snapshot类,可以直接获取日志的行和列信息,非常方便。对于cache2010及以下版本则无此方法,需要使用%File文件读取方法。

3
2 640
文章 TZ Zhuang · 八月 6, 2021 2m read

可以使用%SYS.Journal.File类中的ByTimeReverseOrder查询,以及%SYS.Journal.Record类中的List查询来实现。

下面是这两个查询的具体作用:

A) %SYS.Journal.File类中的ByTimeReverseOrder查询
这个查询会获取journal日志文件名并按降序排列

USER>set rs=##class(%ResultSet).%New("%SYS.Journal.File:ByTimeReverseOrder")
 
USER>do rs.Execute()
 
USER>while rs.Next() { write rs.Name,! }
c:\intersystems\cache\mgr\journal\20190620.003
c:\intersystems\cache\mgr\journal\20190620.002
c:\intersystems\cache\mgr\journal\20190620.001
c:\intersystems\cache\mgr\journal\20190610.001

B) %SYS.Journal.Record类中的List查询
这个查询可以从指定journal日志文件中获取日志记录

0
1 250
文章 Hao Ma · 一月 10, 2021 6m read

在我发了前一个帖子后,有人催促我说重点 - 好吧,于是我找到了我的“明星”日志 global,也就是那些最占空间的 global - 但如何避免这种情况呢? 如何最大程度地减小日志?

[免责声明:有些人在看到本帖后可能仍然会失望 frown,那就等下个帖子吧... blush]

不过很遗憾,你还得再多失望一会儿,我需要推迟讨论(不会很久...),因为我要先提出两个我认为很重要的问题,之后再讨论如何避免记录那些我们不需要的日志,这两个问题是:

  1. 到底有哪些内容会被写入日志?
  2. 为什么?

我认为在讨论不记录日志之前回答这两个问题非常重要的原因是,从根本上来说,日志记录是有好处的,所以数据首先会放在日志中,如果你决定不记录日志,必须有非常充分的理由。

让我们尝试回答这两个问题 -

通常每个 SET 和 KILL 命令(以及 TSTART 和 TCOMMIT/TROLLBACK)都会记录在日志文件中。

例如,如果我运行以下命令

我会在日志中看到:

日志文件有几个用途:

  1. 为了防止在系统崩溃后的启动恢复中发生数据丢失 - 当系统启动时,如果日志中的操作尚未记入数据库,系统会前滚这些操作(假设它们不是未提交事务的一部分,否则它们会被回滚)。
  2. 作为灾难恢复计划的补充 - 允许恢复自上一个可用备份以来更改的数据。 例如,如果在昨天夜间运行了一次备份,由于某种原因,数据库(即 CACHE.DAT)文件在中午时受损(磁盘损坏或其他原因),那么可以从备份中恢复,让状态回到早上的样子,然后从日志恢复到中午发生系统故障之前的点,以将数据损失降到最低。
  3. 事务回滚支持 - 无论出于何种原因,都能回滚事务。

更多信息,请参见此处

(写一个单独的帖子可以更详细地介绍每个用途,并说明其用法。 还可以介绍日志中的回滚是什么样子等等。 这不是我目前正在计划的帖子,但欢迎其他人阐述这个主题。

所以记录数据日志是有充分理由的,它非常有用,甚至至关重要(重要到甚至有一个开关的说明是,如果日志记录因某种原因失败,我们应该冻结整个系统)。

(希望此时不会让你因为考虑不记录日志而感到内疚...wink

Caché 中的每个数据库都有一个指示数据是否被记录日志的标志。 默认和推荐的设置是记录日志。 即使你决定不记录,你也应该意识到,事务中的任何 SET 或 KILL 仍然会被记入日志,即使数据所在的数据库被标记为不记录日志(为了允许上文所述的回滚)。 [一个重要的例外是位于 CACHETEMP 数据库中的 global,我们稍后会用到它]

例如,SAMPLES 数据库未记录日志,因此简单的 SET 不会被记录,但事务中的 SET 会被记录:

日志不显示第一个 SET(在事务外部),只显示第二个:

对于事务内自动保存的对象同样如此。

再以 SAMPLES 为例:

我们得到这样的结果(尽管我们没有明确发出 TSTART 命令,但对象归档器会在后台执行此操作):

这样,虽然简短,但我们的 2 个问题(日志记录什么和为什么记录)都得到了回答。

这将引导我们进入下一步 – 如何避免某些数据被记入日志。

你会意识到的第一个问题是决定是否可以真正“承担得起”不记录那些你想要避免填满日志的数据。

不过让我先说一个非常简单的案例 -“哇! 我不知道我们在设置这个 global?!”

例如, 查看日志可以发现,也许在代码中的某个地方,我们设置了一个临时开关,可能是设置某个时间,或者是为了调试目的而需要写入一些日志,或者是具有临时调查性质的某种机制,而我们完全不需要这个开关,我们可以删除该代码(或者注释掉,或者不调用,或者关闭开关等等)。

这是一个相对容易的案例,我们不需要继续讨论是否以及如何不记录日志。

现在,关于此案例,你可能会想 - 你需要看日志才能发现这个“失控”的 global 设置吗,你看不到数据库实际在增长吗?

好吧,也许的确如此,数据库也确实在增长,但你忽略了,或者没有给予过多关注并且/或者认为这只是自然增长。 但也可能是另一种情况,这是我要强调的一点,就是日志增长不一定与数据库增长相关联。

举一个极端的例子:

你可以设置一个 global 的值,让其在两个值(比如 0 和 1)之间交替,每秒多次。 数据库完全不会增长,因为数据的大小没有变化,但日志中会有成千上万的 SET 条目。

或者你可以设置一个临时的大型 global 树结构,数秒钟后将其终止,那么树结构占用的数据库大小差不多是恒定的,但是日志会因为记录所有 set 和 kill 操作而填满。

假设情况并非如此,你对设置此数据并不感到惊讶,实际上你很清楚这一点,并且你的应用程序需要设置此数据。 那样的话,我们又回到了前面的问题 - 你是否真正承担得起不记录这些数据的日志?

为了回答这个问题,我们试着把它分成几个小一点的问题:

  1. 你能承受在崩溃前输入(或删除)的数据在崩溃后不存在(或重新出现)吗?
  2. 你能承受所输入(或删除)的数据在系统恢复过程中无法恢复(或重新出现)吗?
  3. 你不需要这些数据作为事务的一部分被回滚吗?

如果你对全部 3 个问题的回答都是“是”,那么你确实可以考虑不记录这些数据的日志了。

但是如果你需要此数据在崩溃后恢复,或者作为备份的一部分恢复,或者需要作为事务的一部分回滚。 你就需要记录日志。

在这种情况下,你只需要计算并确定真正的日志增长率,并确保有足够的磁盘空间 [你可以看我的另一个帖子,一些相关代码在 Git 上,可以帮助估计 Ensemble 接口所需的日志空间。 当然你也可以修改这些代码来用于其他用例]。

以下是我将在下一个帖子介绍的选项,先让你们预览一下:

  • 关闭整个系统的日志记录
  • 将 global 映射到 CACHETEMP
  • 将 global 映射到不记录日志的数据库
  • 关闭对进程的日志记录
  • 关闭用于对象归档的事务

下次再见...(我保证到时候说重点...angel

这是下一个帖子

0
0 178