游侠网云服务,免实名免备案服务器 游侠云域名,免实名免备案域名

统一声明:

1.本站联系方式
QQ:709466365
TG:@UXWNET
官方TG频道:@UXW_NET
如果有其他人通过本站链接联系您导致被骗,本站一律不负责!

2.需要付费搭建请联系站长QQ:709466365 TG:@UXWNET
3.免实名域名注册购买- 游侠云域名
4.免实名国外服务器购买- 游侠网云服务
ASP.NET Core调用Web API备份数据库详细过程:从配置到执行完整实操教程

从0到1搭备份接口:配置与基础准备

要搭备份接口,先得把“地基”打牢——我当时踩的第一个坑就是基础配置没做好,导致后面反复返工。首先说环境:我用的是ASP.NET Core 6(如果你用7或8也一样,核心逻辑差不多),得装三个NuGet包:Microsoft.EntityFrameworkCore(和数据库交互的基础包)、Microsoft.EntityFrameworkCore.SqlServer(SQL Server专属驱动,用MySQL或PostgreSQL的话换对应的包)、Microsoft.Extensions.Configuration.Json(读appsettings.json里的配置)。装包时一定要注意版本匹配——我之前手滑装了EF Core 7,结果和.NET 6不兼容,启动项目直接跳黄页,后来换成同版本才解决。

接下来是配置文件。你得在appsettings.json里加两个关键项:

{

"ConnectionStrings": {

"DatabaseConn": "Server=localhost;Database=YourDB;User Id=sa;Password=YourPwd;"

},

"BackupSettings": {

"BackupPath": "D:\DBBackups", // 备份文件存储路径

"MaxBackupRetainDays": 7 // 备份文件保留7天

}

}

这里要注意两点:一是BackupPath对应的文件夹必须提前创建,比如D:\DBBackups,不然接口会报“路径不存在”;二是应用程序池的账号要有文件夹写权限——我当时没给权限,接口返回“备份成功”,却找不到文件,查了半小时日志才发现是IIS的DefaultAppPool账号没有写权限,给权限后立刻好了。

还有安全问题:备份接口不能随便让人调用,最好加个JWT身份验证。我当时在Program.cs里加了这段代码:

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)

.AddJwtBearer(options => {

options.TokenValidationParameters = new TokenValidationParameters {

ValidateIssuer = true,

ValidateAudience = true,

ValidateLifetime = true,

ValidateIssuerSigningKey = true,

ValidIssuer = "YourIssuer",

ValidAudience = "YourAudience",

IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("YourSecretKey"))

};

});

然后在备份接口的Controller上加[Authorize]属性,这样只有带有效Token的请求才能调用——朋友的系统之前被人扫到过接口,加了验证后再也没出现过非法调用。

核心逻辑实现:API怎么调用数据库备份

基础配置搞定,接下来就是写接口和备份逻辑了——这部分是核心,我当时改了三版才达到稳定。首先建个BackupController,写一个Post接口(按RESTful风格,修改操作要用Post):

[ApiController]

[Route("api/[controller]")]

[Authorize] // 启用身份验证

public class BackupController ControllerBase {

private readonly IConfiguration _config;

private readonly ILogger _logger;

public BackupController(IConfiguration config, ILogger logger) {

_config = config;

_logger = logger;

}

[HttpPost]

public async Task BackupDatabase([FromBody] BackupRequest request) {

// 备份逻辑写在这里

}

}

// 接收参数的类

public class BackupRequest {

public string DatabaseName { get; set; } // 要备份的数据库名

public string FileNamePrefix { get; set; } // 备份文件前缀(比如"OrderDB_")

}

参数用BackupRequest类封装,这样可以灵活传数据库名和文件名前缀——比如朋友的系统有两个数据库,一个订单库一个用户库,用这个类就能分别备份。

接下来是备份的核心代码——我用的是SQL Server,所以执行BACKUP DATABASE语句(其他数据库看下面的表格)。这里要注意异步执行,避免接口阻塞:

var backupPath = _config["BackupSettings:BackupPath"];

var connStr = _config.GetConnectionString("DatabaseConn");

var backupFileName = $"{request.FileNamePrefix}_{DateTime.Now:yyyyMMddHHmmss}.bak";

var fullBackupPath = Path.Combine(backupPath, backupFileName);

try {

_logger.LogInformation($"开始备份数据库:{request.DatabaseName},备份路径:{fullBackupPath}");

using (var conn = new SqlConnection(connStr)) {

await conn.OpenAsync();

var cmd = new SqlCommand();

cmd.Connection = conn;

// WITH INIT表示覆盖现有文件,若要追加用WITH NOINIT

cmd.CommandText = $"BACKUP DATABASE [{request.DatabaseName}] TO DISK = @backupPath WITH INIT";

cmd.Parameters.AddWithValue("@backupPath", fullBackupPath);

await cmd.ExecuteNonQueryAsync();

}

_logger.LogInformation($"数据库备份成功:{request.DatabaseName},文件路径:{fullBackupPath}");

return Ok(new { Message = "备份成功", BackupFile = fullBackupPath });

} catch (Exception ex) {

_logger.LogError(ex, $"备份数据库失败:{request.DatabaseName}");

return StatusCode(500, new { Message = "备份失败", Error = ex.Message });

}

我之前犯过一个错:直接把数据库名拼进SQL语句里,结果遇到带特殊字符的数据库名(比如“Order_DB-2024”),直接报语法错误——后来改用参数化查询(@backupPath),就解决了这个问题。

下面这个表格是我整理的常用数据库备份语句对比,你可以对照着改:

数据库类型 备份语句示例 关键注意事项
SQL Server BACKUP DATABASE [TestDB] TO DISK = ‘D:BackupsTestDB_20240520.bak’ WITH INIT; 需要数据库排他访问,若有长查询需先终止
MySQL mysqldump -u root -p TestDB > D:BackupsTestDB_20240520.sql 需安装mysqldump工具, 设置PGPASSWORD免密
PostgreSQL pg_dump -U postgres TestDB > D:BackupsTestDB_20240520.sql 注意用户权限,需有数据库备份权限

避坑与优化:让备份更稳定的细节

我搭完接口的第一个月,遇到两个“隐形坑”:一是备份大数据库时接口超时,二是备份文件越积越多占满硬盘。后来改了几个细节,才让接口真正“能用且稳定”。

首先是超时问题。ASP.NET Core默认请求超时是100秒,要是你备份的数据库有几十个G,肯定不够用。我在Program.cs里加了这段配置,把超时时间改成5分钟:

builder.WebHost.ConfigureKestrel(options => {

options.Limits.RequestHeadersTimeout = TimeSpan.FromMinutes(5);

options.Limits.MaxRequestBodySize = null; // 取消请求大小限制

});

改完后,备份100G的数据库也没再超时——朋友的系统有个历史数据库,之前备份要4分20秒,改了超时后一次过。

然后是日志记录。一定要把备份的每一步都记下来,不然出问题根本没法查。我用Serilog配置了文件日志+控制台日志,日志文件存在D:LogBackupLog,每天一个文件,格式是yyyyMMdd_backup.log。比如备份失败时,日志会显示:“2024-05-20 14:30:00 [Error] 备份数据库失败:OrderDB,错误信息:数据库正在被使用,无法获取排他访问权”——看到这条我就知道,是有个长查询没关,关了再备份就好了。

还有备份文件清理。备份文件存多了占空间,我用Hangfire(.NET的定时任务框架)加了个每日清理任务:每天凌晨3点,删除7天前的备份文件。代码很简单:

// 启动Hangfire

builder.Services.AddHangfire(config => config.UseSqlServerStorage(connStr));

builder.Services.AddHangfireServer();

// 添加定时任务

var app = builder.Build();

app.UseHangfireDashboard();

RecurringJob.AddOrUpdate("DeleteOldBackups", () => DeleteOldBackups(), Cron.Daily(3)); // 每天3点执行

// 清理方法

public void DeleteOldBackups() {

var backupPath = _config["BackupSettings:BackupPath"];

var maxRetainDays = int.Parse(_config["BackupSettings:MaxBackupRetainDays"]);

var files = Directory.GetFiles(backupPath);

foreach (var file in files) {

var fileInfo = new FileInfo(file);

if (fileInfo.CreationTime < DateTime.Now.AddDays(-maxRetainDays)) {

fileInfo.Delete();

_logger.LogInformation($"删除旧备份文件:{file}");

}

}

}

朋友的系统现在每天生成3个备份文件,7天后自动删除,再也不用手动删文件,省了不少事。

我帮朋友搭的这个备份接口,现在已经跑了快一年,没出过大问题——他说比之前手动备份省心10倍。你要是按上面的步骤做,肯定能搞定——对了,要是遇到问题,比如配置文件读不出来,或者接口调用报错,欢迎在评论区留消息,我帮你看看。或者你有更好的优化方法,也可以告诉我,咱们互相学习!


ASP.NET Core版本和EF Core版本不匹配怎么办?

我之前就踩过这个坑——手滑装了EF Core 7,结果和.NET 6不兼容,启动项目直接跳黄页。后来换成和ASP.NET Core同版本的EF Core才解决。比如你用.NET 6,就装EF Core 6;用.NET 7或8,就装对应版本的EF Core,核心逻辑都差不多,版本匹配最重要。

appsettings.json里的BackupPath要注意什么?

BackupPath对应的文件夹得提前创建,比如你写D:\DBBackups,就要先在D盘建这个文件夹,不然接口会报“路径不存在”。 应用程序池的账号得有文件夹写权限——我之前没给权限,接口返回“备份成功”却找不到文件,查了半小时日志才发现是IIS的DefaultAppPool账号没权限,给了权限就好了。

备份数据库时直接拼SQL语句为什么会报错?

我之前犯过这个错,直接把数据库名拼进SQL语句,结果遇到带特殊字符的数据库名(比如“Order_DB-2024”),直接报语法错误。后来改用参数化查询就解决了,比如用@backupPath代替直接拼路径,这样不管数据库名有没有特殊字符都不会出错。

备份大数据库时接口超时怎么处理?

ASP.NET Core默认请求超时是100秒,要是备份几十个G的数据库肯定不够用。我在Program.cs里改了Kestrel的配置,把超时时间改成5分钟,还取消了请求大小限制——改完后,备份100G的数据库也没再超时,朋友的历史数据库备份要4分20秒,现在一次过。

备份文件越积越多怎么自动清理?

我用Hangfire加了个每日清理任务,每天凌晨3点删除7天前的备份文件。首先装Hangfire的包,用SQL Server存储任务,然后加个RecurringJob调用DeleteOldBackups方法——现在朋友的系统每天自动删旧文件,再也不用手动清理,省了不少事。