【问题标题】:How to know if a Firebird 2.0 database is being accessed?如何知道是否正在访问 Firebird 2.0 数据库?
【发布时间】:2019-07-31 18:41:52
【问题描述】:

我知道使用 Firebird 2.5+ 我可以检查是否有用户使用 SQL 访问我的数据库,但不幸的是,Firebird 2.0 没有此功能。是的,我知道它是一个旧版本,但它是一个遗留软件,我不能在短时间内升级它...... :(

我需要知道是否有人连接到我的 2.0 Firebird 数据库,因为我将运行一个进程:

  1. 阻止与数据库的连接(但如果没有人连接)
  2. 运行我的进程
  3. 允许用户重新连接

只有在没有用户连接时,我才能启动我的进程。

我的数据库是客户端/服务器系统(非 Web)的一部分。

有什么提示吗?

【问题讨论】:

  • 升级到 FB 2.1,它们在很大程度上兼容并且监控表是从 2.1 开始的
  • 升级是件好事,但正如我在我的问题上所说的那样,我目前不允许这样做。我们的软件分发给许多用户并由他们在本地安装。不管怎样,谢谢你的建议。
  • Firebird 2.0 自 2012 年起停产,2.1 自 2014 年起停产,2.5 自 2019 年起停产。您真的需要开始升级了。尤其是在 2.5 以下的版本中没有修复几个与安全相关的错误。从 2.0 到 2.5 的步骤并没有那么大。不过,从 2.5 到 3.0 可能会涉及更多。
  • @MarkRotteveel 我希望我可以升级 FB。如果事实上,我们将重新设计我们的软件,但这将需要大约 2 年的时间才能交付。我现在需要的只是保持我们的软件运行,只进行强制修改。
  • 为什么你需要这种独占访问,你不能通过使用具有快照表稳定性的事务来代替表保留来实现这一点吗?

标签: firebird


【解决方案1】:

-at[tach] :此参数可防止与数据库建立任何新连接,但 SYSDBA 和数据库所有者除外。如果在超时期过后有任何会话连接,则关闭将失败。如果这些连接的会话属于 SYSDBA、数据库所有者或任何其他用户,则没有区别。任何剩余的连接都将终止关闭,并提供以下详细信息:

https://firebirdsql.org/manual/gfix-dbstartstop.html

还有服务 API 可以执行此操作,因此您的数据库访问库应该公开关闭功能。指定一个短暂的关闭,如果它失败了 - 那么有一些用户。如果成功 - 现在您可以继续进行维护,拥有保修的客户端应用程序将无法连接。


或者,您可以升级 Firebird 2.0 -> 2.1,它比 2.5 更接近 2.0,但已经实施了监控表。 但是,您的方法有一个弱点-竞争条件。使用 M.T.你设想你的工作如下:

  1. 继续查询 M.T. (这会显着降低服务器的工作速度),直到没有其他连接为止。
  2. 开始维护工作,如果其他连接处于活动状态,则会失败
  3. 完成维护工作

问题是,即使在第 1 步获得“无其他连接”状态之后,这并不意味着在第 1 步和第 2 步之间,尤其是在第 2 步和第 3 步之间,现在会建立新的连接。

即使您进行了检查并确保了#1 条件,当您继续进行维护时,也会有一些新用户重新连接并开始工作。当然不是每次,但随着时间的推移,它最终会发生。


但 FB 2.1 中还有一件好事 - 数据库级触发器。

c:\Program Files\Firebird\Firebird_2_1\doc\sql.extensions\README.db_triggers.txt

您可以创建一个常规的“all_current_connections”表,使用on connecton disconnect 触发器使其保持最新状态。 您可能还必须为您的应用程序添加一些逻辑,以便他们使用您的内部应用程序 ID 更新该表,以告知主要工作流应用程序/连接来自服务实用程序。但是,如果您可以从单纯的用户名推断出应用程序的种类,那么触发器知道并可以存储到表中的仅仅是 CURRENT_USERCURRENT_CONNECTION 对也可能足以用于该表。

然后on disconnect 触发器可能会检查是否所有“主工作流”应用程序都已断开连接,POST_EVENT 会通知服务实用程序。但是,无论如何,这些实用程序仍然必须首先shutdown 数据库

【讨论】:

  • 如果我没记错的话,从 2.0 升级到 2.5 也不应该是一个重大飞跃。
  • @MarkRotteveel 据报道,OD 有一些细微的变化,例如标识符名称长度等,尽管 2.5 可以与 h2.0 和 2.1 ODS 一起工作而无需更改它,但该数据库并不总是如此FB 2.0/2.1 可以使用。没有亲身体验过,所以无法提供更多细节
  • @NiloPaim 然后让软件在连接时注册并在断开连接时取消注册。要将您的新应用分发给用户,您仍然需要进行新版本升级。
  • 2.0 到 2.1 已经是 ODS 升级了。并且标识符长度实际上并没有改变(它始终是 31 个字节)。我认为唯一改变的是 API 中的一个错误,它表明标识符在 UNICODE_FSS 中是 31 个字符,而不是在 UNICODE_FSS 中是 31 个字节。
  • @MarkRotteveel 升级到 2.5 ODS 可能与 PSQL 中的非拉丁字符串文字存在问题,但是我所说的是使用 FB2.5 与 2.0 ODS 和 2.1 ODS 一起工作。在纸上,它保持了这些数据库文件与其“本机”以前的 Firebird 版本的兼容性。但似乎魔鬼在细节上,有时只是在 FB 2.5 中使用 2.5 之前的 ODS 文件以某种方式“污染”它们,使它们成为 2.5 之前的服务器的问题。注意,不是转换 w。 B/R 循环,但仅由 2.5 服务器操作旧数据库文件
【解决方案2】:

您可以使用 gfix 关闭数据库。 gfix 工具会尝试关闭数据库,如果超时后连接仍然存在,则关闭失败。

例如,使用:

gfix -shut -attach 5 <your-database>

这将:

  1. 阻止创建新连接,
  2. 等待 5 秒,让现有连接结束,
  3. 如果 5 秒后仍有活动连接,则关闭将中止,
  4. 否则,数据库将在 5 秒后关闭。

关闭后,只有 SYSDBA 或数据库所有者可以创建与数据库的连接。如果您的应用程序本身不使用 SYSDBA 或数据库所有者帐户,这只是一个可行的选择。

您使用以下方法使数据库重新联机:

gfix -online <your-database>

有关详细信息,另请参阅Gfix - Database Housekeeping: Database Startup and Shutdown

【讨论】:

  • 他如何以编程方式检查它是否失败?使用 API 调用会更简单,但我们不知道他的库...
  • @Arioch'如果 Gfix 无法关闭,它会返回错误消息。我假设它也返回一个错误级别,但我没有检查过。您也可以使用服务 API 执行此操作,这也会返回错误响应。
  • 拦截输出和解析是它自己的任务,并且错误代码在 FB 实用程序中似乎并不可靠(失败的 GBAK 返回成功错误代码,将其解释为“成功完成服务 API 会话” )。我还想知道“单连接模式”是否已经在 FB 2.0 中或以后引入,以完全避免在维护结束之前进行竞争条件二次连接的风险。
  • @Arioch'The 单连接模式是在 Firebird 2 中引入的,请参阅我链接的 gfix 文档中的“Firebird 2.0 中的新启动和关闭状态”。无论如何,问题中没有任何内容表明这需要以编程方式完成。
  • @NiloPaim Gfix returns an error message, that must be parsed to know what happened. The error level returned by Gfix is always 0 - GFIX 在这里调用您的程序可以自己调用的 FB 服务 API。您必须查阅您的 Firebird 连接库,以了解验证、备份/恢复和查询信息等服务是如何实现的。您可以在firebirdsql.org/en/reference-manuals 使用 IB6 API 指南交叉检查 lib 源代码,然后您可以查看侧通道如何使用 FB2 引入的扩展数据库(而非服务器)关闭模式来增强该调用。
【解决方案3】:

嗯,这不是一种优雅的方式,但很有效......

  1. 我尝试重命名数据库文件。
  2. 如果有人访问数据库,重命名操作会给我 一个例外,表示该文件正在被某个进程使用。
  3. 如果重命名成功,新用户将无法访问数据库 不再(我的系统使用的连接字符串没有改变)。
  4. 我运行我必须运行的专有进程。
  5. 将数据库文件重命名为其原始名称,允许新用户使用 重新连接。

我发布我的解决方案,希望对面临类似问题的人有所帮助。

我们的新版本产品可能是一个 Web 应用程序,数据库尚未选择,但肯定不会是 Firebird。

感谢所有试图给我答案的人。

【讨论】:

  • 请注意,这只适用于 Windows。在 Linux 和其他系统上,可以重命名正在使用的文件。旧文件句柄将继续工作。使用 gfix 关闭数据库可能会更好。
  • 1-3 和 5 可以在 Firebird 本地方式中完成 - 使数据库进入关闭单用户模式,然后返回在线模式。这样,您就不必让您的应用程序了解文件位置(解耦)和文件访问权限。文件重命名方法不太灵活且更脆弱。
  • @MarkRotteveel 这只是 Windows。感谢上帝,如果我们的产品专门用于 Windows,这个版本。
猜你喜欢
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多