Firebird 2.5.9备份时MON$REMOTE字段为NULL的问题咨询
Firebird 2.5.9备份服务连接的MON$ATTACHMENTS字段为空问题
问题描述
使用Firebird 2.5.9 x64 Windows版本搭配Delphi XE4,通过TIBBackupService执行备份时,MON$ATTACHMENTS中存在该备份服务的连接记录,但MON$REMOTE_PID和MON$REMOTE_PROCESS字段均为NULL,请问原因是什么?有没有修复方法?
Delphi IBService.pas中的SPB常量定义
当前使用的Delphi组件中,IBService.pas仅定义了以下SPB(服务参数块)常量:
SPBConstantNames: array[1..isc_spb_last_spb_constant] of String = ( 'user_name', {do not localize} 'sys_user_name', {do not localize} 'sys_user_name_enc', {do not localize} 'password', {do not localize} 'password_enc', {do not localize} 'command_line', {do not localize} 'db_name', {do not localize} 'verbose', {do not localize} 'options', {do not localize} 'connect_timeout', {do not localize} 'dummy_packet_interval', {do not localize} 'sql_role_name', {do not localize} 'instance_name', {do not localize} 'user_dbname', {do not localize} 'auth_dbname'); {do not localize}
.NET Provider中的SPB常量对比
查看Firebird .NET Provider的FbBackup.cs,发现其包含更多SPB常量,其中与进程信息相关的关键常量为:
#region Services Parameter Block public const int isc_spb_version1 = 1; public const int isc_spb_current_version = 2; public const int isc_spb_version = isc_spb_current_version; public const int isc_spb_version3 = 3; public const int isc_spb_user_name = isc_dpb_user_name; public const int isc_spb_sys_user_name = isc_dpb_sys_user_name; public const int isc_spb_sys_user_name_enc = isc_dpb_sys_user_name_enc; public const int isc_spb_password = isc_dpb_password; public const int isc_spb_password_enc = isc_dpb_password_enc; public const int isc_spb_command_line = 105; public const int isc_spb_dbname = 106; public const int isc_spb_verbose = 107; public const int isc_spb_options = 108; public const int isc_spb_address_path = 109; public const int isc_spb_process_id = 110; public const int isc_spb_trusted_auth = 111; public const int isc_spb_process_name = 112; // 关键常量 public const int isc_spb_trusted_role = 113; public const int isc_spb_verbint = 114; public const int isc_spb_auth_block = 115; public const int isc_spb_auth_plugin_name = 116; public const int isc_spb_auth_plugin_list = 117; public const int isc_spb_utf8_filename = 118; public const int isc_spb_client_version = 119; public const int isc_spb_remote_protocol = 120; public const int isc_spb_host_name = 121; public const int isc_spb_os_user = 122; public const int isc_spb_config = 123; public const int isc_spb_expected_db = 124;
疑问与.NET环境测试
- 能否在Delphi代码中直接使用
isc_spb_process_name = 112这个常量,来注入进程名称?或者有没有其他方法在Delphi执行备份时填充MON$REMOTE_PROCESS字段? - 在.NET环境中测试时也遇到相同问题:设置
FbConnectionStringBuilder.ApplicationName并未生效,MON$REMOTE_PID和MON$REMOTE_PROCESS依然为NULL,测试代码如下:
FbConnectionStringBuilder csb = new FbConnectionStringBuilder(); csb.Database = "alias"; csb.DataSource = "12.0.0.1"; csb.UserID = "sysdba"; csb.Password = "*******"; csb.ApplicationName = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName; FbBackup backupSvc = new FbBackup(); backupSvc.ConnectionString = csb.ConnectionString; backupSvc.BackupFiles.Add(new FbBackupFile(@"d:\metadata.fbk")); backupSvc.Verbose = true; backupSvc.Options = FbBackupFlags.MetaDataOnly; backupSvc.Execute();
原因分析与修复方案
原因
Firebird服务连接(如备份服务)的MON$REMOTE_PID和MON$REMOTE_PROCESS字段,需要客户端在建立服务连接时主动通过SPB参数传递进程ID和进程名称。而Delphi的TIBBackupService组件以及.NET的FbBackup默认并未在SPB中添加isc_spb_process_id(110)和isc_spb_process_name(112)这两个参数,导致服务端无法获取这些信息,字段值为NULL。
修复方法
Delphi环境
可以手动扩展SPB参数,在调用备份服务前添加进程ID和进程名称:
- 定义缺失的SPB常量:
const isc_spb_process_id = 110; isc_spb_process_name = 112;
- 在
TIBBackupService连接前,手动向SPB中添加参数:
var SPB: TStringList; ProcessID: Integer; ProcessName: string; begin SPB := TStringList.Create; try // 获取当前进程ID和名称 ProcessID := GetCurrentProcessId; ProcessName := ExtractFileName(ParamStr(0)); // 添加基础连接参数 SPB.Add('user_name=sysdba'); SPB.Add('password=masterkey'); SPB.Add('db_name=your_database'); // 添加进程ID和名称参数 SPB.Add(Format('%d=%d', [isc_spb_process_id, ProcessID])); SPB.Add(Format('%d=%s', [isc_spb_process_name, ProcessName])); // 应用SPB到备份服务 IBBackupService1.SetServiceParams(SPB); IBBackupService1.Connected := True; // 执行备份操作... finally SPB.Free; end; end;
注意:需确保使用的SPB版本至少为isc_spb_version2,否则服务端可能无法识别新增参数。
.NET环境
FbBackup默认不会传递ApplicationName到服务连接的SPB中,需要手动构建SPB来添加进程信息参数:
using FirebirdSql.Data.FirebirdClient; using System.Diagnostics; // 手动构建服务连接的SPB var spb = new ServiceParameterBuffer(); spb.Append(IscCodes.isc_spb_version, IscCodes.isc_spb_current_version); spb.Append(IscCodes.isc_spb_user_name, "sysdba"); spb.Append(IscCodes.isc_spb_password, "masterkey"); spb.Append(IscCodes.isc_spb_dbname, "alias"); // 添加进程ID和名称 spb.Append(IscCodes.isc_spb_process_id, Process.GetCurrentProcess().Id); spb.Append(IscCodes.isc_spb_process_name, Process.GetCurrentProcess().MainModule.FileName); using (var backupSvc = new FbBackup()) { backupSvc.ConnectionString = "DataSource=12.0.0.1"; // 仅指定数据源 backupSvc.ServiceParameterBuffer = spb; backupSvc.BackupFiles.Add(new FbBackupFile(@"d:\metadata.fbk")); backupSvc.Verbose = true; backupSvc.Options = FbBackupFlags.MetaDataOnly; backupSvc.Execute(); }
内容的提问来源于stack exchange,提问作者b0bik
相关产品推荐
相关产品推荐

