Oracle 数据库备份与恢复的重要性与最佳实践

news2024/9/30 9:28:13

文章目录

      • 一、备份的重要性
      • 二、备份工具-RMAN
      • 四、比较备份策略
      • 五、实例恢复
      • 六、完全恢复与不完全恢复
      • 七、备份与恢复脚本

引言:
在现代信息时代,数据已成为组织和企业最重要的资产之一。保护和恢复数据的能力对于确保业务连续性和减少潜在风险至关重要。作为一款全球领先的关系型数据库管理系统,Oracle 提供了强大的备份与恢复功能,以确保数据库的持久性和可靠性。本文将探讨Oracle数据库备份与恢复的重要性,并分享一些实践和策略,大家一起学习。

一、备份的重要性

1.数据丢失风险: 数据库可能面临硬件故障、人为错误、恶意攻击、自然灾害等多种潜在风险。如果没有恰当的备份策略,这些事件可能导致数据丢失,从而对业务造成严重影响。
2.业务连续性: 数据库备份是确保业务连续性的关键组成部分。当发生数据丢失或故障时,通过备份可以快速恢复数据,减少停机时间和业务损失。
3.合规与法规要求: 许多行业都有关于数据备份和恢复的合规要求。通过合规备份策略,可以确保遵守各项规定和法规,并降低法律风险。

二、备份工具-RMAN

RMAN(Recovery Manager)属于数据库备份的一种方法和工具。它是由Oracle提供的备份和恢复工具,用于执行数据库的物理备份和恢复操作。RMAN提供了一套强大的命令和功能,可以备份数据库的数据文件和归档日志文件,并在发生故障时进行恢复。

RMAN通过备份数据库的物理文件(如数据文件、控制文件和归档日志文件)来保护数据库的完整性和可用性。它可以执行完整备份(全量备份)、增量备份(增量变更备份)、归档日志备份等多种备份类型。RMAN还支持压缩备份、备份集的跨平台传输和恢复、增量恢复等高级功能。

1.RMAN的备份形式:

  1. 数据库备份集(Database Backup Set):
    数据库备份集是RMAN中备份的基本单位,它是一个或多个数据文件和/或归档日志文件的集合。备份集可以包含完整备份、增量备份、归档日志备份等多种备份类型。备份集可以方便地管理和恢复数据库的备份。
  2. 镜像复制
    对数据文件、控制文件和归档重做日志文件进行复制,镜像复制文件与原文件大小相同,原文件中未使用的数据块也被复制到备份文件中。

2.RMAN备份策略:

RMAN(Recovery Manager)支持多种备份形式,以满足不同的备份需求和策略。以下是常见的RMAN备份形式:

全量备份(Full Backup):
完整备份数据库的所有数据文件、控制文件和归档日志文件。全量备份创建一个完整的备份集,包括数据库的所有数据。该类型的备份提供了最直接的恢复方式,但备份的大小通常较大。

完整备份包含所有使用的数据文件的块,

优点:全量备份基于一个快照点,备份整个数据库,提供了最直接的恢复方式。恢复速度快,适用于小型数据库和频繁变更的数据库。
注意事项:全量备份的大小较大,占用存储空间较多。

增量备份(Incremental Backup):
增量备份只备份自上次备份以来发生更改的数据块或文件。它只备份数据库中已更改的部分,可以显著减小备份大小和备份时间。RMAN提供了多个增量备份级别来支持不同的备份策略。

优点:增量备份只备份自上次备份以来发生变化的数据块或文件,减小了备份的大小和备份时间。适用于大型数据库,可节约存储空间和备份时间。

注意事项:恢复过程相对复杂,需要重新应用增量备份和归档日志。

如:0级增量备份等效于已标记为0级的完整备份,累积增量备份(1级)仅包含自上次0级增量备份以来已修改的块。

案例:
  星期天:0级备份将备份此数据库中曾使用过的所有块
  周一至周六:1级累积增量备份会备份自最近的0级备份以来更改的所有块。
       由于最新的0级备份是在星期日创建的,因此星期一到星期六每天的1级备份会备份自星期日备份以来更改的所有块。
使用方法:
RMAN>backup incremental level 1 cumulative database format '/full/orcl_1c-%d.%s.%p.%T';

差异备份(Differential Backup):
差异备份是相对于上次完整备份的增量备份。它备份自上次完整备份以来发生更改的数据块或文件,而不是自上次备份以来的所有更改。差异备份相对于增量备份来说通常较大,但恢复时只需要完整备份和最近一次差异备份。

优点:差异备份是相对于上次全量备份的增量备份,备份自上次全量备份以来发生变化的数据块或文件。恢复速度较快,只需应用最近的差异备份和上次全量备份。

注意事项:随着时间的推移,差异备份的大小可能会越来越大。

如:差异增量备份(1级)仅包含自上次(差异)增量备份以来已修改的块。

案例:
  星期天:0级备份将备份此数据库中曾使用过的所有块
  周一至周六:在星期一到星期六的每一天,1级差异增量备份将备份自级别10的最新增量备份以来已更改的所有块。星期一备份自星期日0级备份以来更改的块,星期二备份复制块自星期一1级备份以来发生了变化,以此类推
使用方法:
RMAN>backup incremental level 1 database format '/full/orcl_1-%d.%s.%p.%T';

归档日志备份(Archive Log Backup):
归档日志备份是备份数据库的归档日志文件,这些文件记录了数据库的所有事务和更改。归档日志备份用于在数据库发生故障时进行恢复,并保证数据的一致性和完整性。

优点:归档日志备份用于备份数据库的归档日志文件,可以提供完整的数据库恢复能力,保证数据的一致性和完整性。

注意事项:归档日志备份的频率和大小可能会随数据库工作负载和事务量的变化而变化。

3.RMAN的基本命令

RMAN命令的类型
RMAN命令具有以下类型:

独立命令:
在RMAN提示符下单独执行
无法在RUN中显示为子命令

作业命令:
必须在RUN命令的大括号内
分组执行
某些命令可以同时作为两种类型执行。

作业命令:示例

RUN
{
   ALLOCATE CHANNEL c1 DEVICE TYPE DISK
   FORMAT "/disk2/%U";
   BACKUP AS BACKUPSET DATABASE;
   SQL 'alter system archive log current';
}

配置RMAN的永久参数
RMAN已预设为默认配置设置.
使用CONFIGURE命令:
自动分配备份通道
指定备份保留策略
指定要创建的备份副本数
将默认备份类型设置为BACKUPSET或镜像拷贝
限制备分片的大小
从备份中指定备份类型(表空间)
启用和禁用备份优化
配置控制文件的自动备份
定义归档日志删除策略
指定设备的并行度
设置要用于备份的加密和压缩参数

使用SHOW ALL命令查看所有配置设置
查询V $ RMAN_CONFIGURATION视图以显示已明确设置的配置设置

设置备份并发度和设备类型:

RMAN> CONFIGURE DEVICE TYPE sbt PARALLELISM 3;

使用SHOW命令列出当前设置:
如:

RMAN> SHOW CONTROLFILE AUTOBACKUP FORMAT;
RMAN> SHOW EXCLUDE;
RMAN> SHOW ALL;

使用CONFIGURE命令的CLEAR选项将任何持久设置重置为其默认值:
如:

RMAN> CONFIGURE BACKUP OPTIMIZATION CLEAR;
RMAN> CONFIGURE MAXSETSIZE CLEAR;
RMAN> CONFIGURE DEFAULT DEVICE TYPE CLEAR;

指定保留策略
保留策略:描述将备份保留多长时间
两种保留策略:

Recovery window:确定一定时间范围内有效

Redundancy: 确定保留分数。

保留策略是互斥的.

4.备份报告
RMAN命令:
LIST:显示有关记录在存储库中的备份集,代理备份和镜像副本的信息
REPORT:对存储库进行详细分析
REPORT NEED BACKUP:列出所有需要备份的数据文件
REPORT OBSOLETE:标识不再满足备份保留策略的文件

5.动态性能视图
动态性能视图在目标数据库中查询以下动态视图,以获取有关备份的信息:

V$BACKUP_SET:已经创建备份集
V$BACKUP_PIECE:存在的备份片
V$DATAFILE_COPY:磁盘上数据文件的副本
V$BACKUP_FILES:有关创建备份时创建的所有文件的信息

6.管理备份
使用以下RMAN命令来管理备份:
CROSSCHECK:针对磁盘或磁带之类的介质,验证记录在RMAN存储库中的备份和副本的状态

DELETE EXPIRED:仅删除存储库中状态为EXPIRED的文件(已经被物理删除的数据库备份或归档日志备份等)

DELETE OBSOLETE:删除不再需要的备份(已经不再满足备份策略的备份 包括数据库备份或归档备份)

EXPIRED后面可以加BACKUP.OBSOLETE不可以加BACKUP;

四、比较备份策略

1.完整备份和增量备份

恢复:
先还原完整备份,然后还原增量备份和归档日志
磁带备份按顺序读取

2.增量更新的磁盘备份
恢复:
通过随机访问读取备份
使用交换副本命令进行无还原的恢复

3.使用物理备库(DG ADG)分担相关备份与恢复
恢复:
发生任何故障时,快速故障转移到备用数据库
如果出现双节点故障,则备份是最后的选择

五、实例恢复

实例恢复是Oracle数据库在异常关闭或故障发生后的恢复过程。检查点(CKPT)进程在实例恢复中扮演着重要的角色。

  1. 检查点是什么?
    检查点是数据库中的一个关键时间点,它标志着在该时间点之前的所有已提交事务的数据已写入数据文件。
    在正常运行期间,Oracle通过将数据库中的脏数据块(已被修改但尚未写入磁盘)写入数据文件并更新相关的数据文件头信息来维护检查点。
    如果数据库发生异常关闭或崩溃,实例恢复将使用检查点信息来确定恢复点,并确保数据库的一致性。

  2. 检查点进程(CKPT):
    检查点进程(CKPT)是Oracle后台进程之一,它负责触发并管理检查点操作。
    CKPT进程周期性地更新数据库的检查点信息,并将其记录到控制文件中。这样,在实例恢复过程中,Oracle可以快速确定合适的恢复点。
    默认情况下,CKPT进程每3分钟执行一次检查点操作,但也会受到其他因素(如数据库活动水平和系统负载)的影响。

  3. 检查点进程的功能:
    写入检查点信息:CKPT进程将检查点信息写入控制文件和数据文件头。这些信息包括最后一个成功检查点的系统改变号(SCN)和检查点的备份类型。
    协助实例恢复:当数据库异常关闭或崩溃后,CKPT进程的信息在实例恢复时起到关键的作用。数据库将基于检查点信息确定恢复点,并恢复到该点。

  4. 相关参数:
    CHECKPOINT_INTERVAL:指定CKPT进程触发检查点的时间间隔。单位为秒,默认值为1800秒(30分钟)。
    FAST_START_MTTR_TARGET:设置在后台进程(包括CKPT)运行期间进行实时CRASH恢复的目标时间(以秒为单位)。

检查点的存在有助于实例恢复过程中快速确定合适的恢复点,并确保数据库的一致性。检查点进程(CKPT)负责触发和管理检查点操作,并将相关信息记录到控制文件和数据文件中。CKPT进程在数据库的正常运行中起到了关键的作用。

CKPT负责:
使用检查点信息更新数据文件头
使用检查点信息更新控制文件
检查点进程向DBWn发出信号

完全检查点(normal checkpoint)

完全检查点(normal checkpoint)是数据库管理系统(DBMS)中的一个重要概念,用于确保数据的持久性和一致性。在数据库中,检查点是指将内存中的数据写入磁盘以确保数据的一致性和持久性的操作。

完全检查点是指在检查点期间,将数据库缓冲区中的所有被修改的数据写入到磁盘,包括数据文件和日志文件。这样可以确保在系统故障或崩溃时,数据库能够从磁盘上的数据进行恢复,并且不会丢失已提交但未写入磁盘的数据。

完全检查点通常在以下情况下发生:

  1. 执行显式检查点命令:管理员可以手动触发检查点操作,以确保缓冲区中的所有被修改的数据都写入到磁盘。

  2. 定期自动检查点:数据库管理系统会根据一定的策略和配置参数来自动触发检查点操作。这些策略包括时间间隔、写入日志文件的大小、日志序列号等。

  3. 在事务提交时:当一个事务提交时,数据库管理系统通常会将该事务涉及的数据写入到磁盘,以确保已提交的数据持久化。

通过执行完全检查点,数据库可以确保将缓冲区中的数据写入到磁盘,从而保持数据的一致性和持久性。这对于故障恢复和系统可用性非常重要,因为在发生故障或崩溃时,数据库可以从磁盘上的数据进行恢复,并且不会丢失已提交的数据。

下面这些操作将会触发完全检查点(normal checkpoint )事件:

  1. 日志切换:通过ALTER SYSTEM SWITCH LOGFILE;
  2. 执行ALTER SYSTEM checkpoint;
  3. 对数据文件进行热备时,针对该数据文件的checkpoint也会进行,ALTER TABLESPACE TS_NAME BEGIN BACKUP/END BACKUP。
  4. 当运行ALTER TABLESPACE/DATAFILE READ ONLY的时候。
  5. 数据库正常shutdown (immediate,transcational,normal)。

增量检查点:

Oracle 数据库使用检查点(Checkpoint)来确保脏数据块被写入磁盘并刷新日志文件。检查点操作会频繁地发生,可能对数据库性能产生一定的影响,特别是在系统负载较高时。

而增量检查点的思想是,在传统的完整检查点基础上引入了增量部分。它会记录自上次完整检查点以来所发生的变化(即脏数据块),并定期将这些变化的数据块写入磁盘,以减少在数据库恢复时需要应用的 redo 日志量。

通过增量检查点,可以将数据库恢复的时间缩短到只需要恢复自上一次增量检查点以来的变化,而无需完整地应用所有 redo 日志。这样可以节省大量的时间和资源,提高数据库的恢复性能。

需要注意的是,增量检查点需要一定的配置和参数设置来生效。你可以通过设置合适的参数和策略,如FAST_START_MTTR_TARGET(目标恢复时间)、LOG_CHECKPOINT_INTERVAL(检查点间隔时间)和LOG_CHECKPOINT_TIMEOUT(检查点超时时间)来调整和优化增量检查点的行为。

实例恢复过程

1.实例启动(数据文件不同步)

  1. 前滚(Redo Apply):
    当数据库实例启动并执行实例恢复时,已提交但尚未写入数据文件的数据将进行前滚操作。
    前滚是通过应用在线重做日志中的重做记录来实现的,这些记录包含已提交但尚未写入数据文件的更改。
    通过前滚操作,数据库将重新应用这些未写入的更改,以确保数据文件与事务提交的数据保持同步。

  2. 数据库已打开:
    一旦实例恢复完成并进行前滚操作后,数据库将处于已打开状态,可以接受用户的连接和执行数据库操作。
    此时,数据库已经恢复到一个一致且可用的状态,数据文件中存储的数据应该与事务的提交状态保持一致。

  3. 回滚(Rollback):
    如果数据库实例启动过程中发现有未提交的已写入数据或未提交的事务日志(Undo Log),数据库将执行回滚操作来恢复到一致的状态。
    回滚操作的目的是取消未提交的事务或将已提交的事务日志进行撤销。
    回滚操作会使用事务的回滚段或Undo表空间中的回滚段来撤销已写入而未提交的数据或事务记录。

需要注意的是,前滚和回滚是数据库启动和恢复过程中的关键步骤,它们确保数据文件中的数据与事务提交状态保持一致。在数据库已打开后,用户可以安全地进行查询和修改操作,而未提交的数据将会被撤销或者提交到数据文件中。

实例启动的三个阶段:

第一个阶段(STARTUP NOMOUNT),实例通过读取SPFILE文件创建内存结构,但没有连接到数据库文件。这个阶段主要是为了确定实例的一些基本配置参数,并找到控制文件的位置。

第二个阶段(ALTER DATABASE MOUNT),实例会通过读取控制文件将数据文件和日志文件挂载到实例中。这个阶段不会发生实例恢复,但是确保相关文件的状态正确。

第三个阶段(ALTER DATABASE OPEN),实例将打开数据库,并进行实例恢复以达到一致状态。在这个阶段,数据库的完整性将被检查,如果发现数据库的完整性有问题,则需要进行恢复操作。

实例恢复过程中,前滚(Redo Apply)确实是一个数据块修正的过程,通过应用在线重做日志(Redo Log)中的重做记录,实例将未提交的更改应用到数据库数据块中,以确保数据的一致性。

回滚(Rollback)操作是在数据库打开之后进行的,用于撤销未提交的已写入数据或未提交的事务记录。回滚是通过使用回滚段(Rollback Segment)或Undo表空间中的回滚段来实现的。回滚将把未提交的数据回滚到之前的状态,以确保数据库的一致性和完整性。

六、完全恢复与不完全恢复

完全恢复和不完全恢复是数据库恢复过程中的两种不同方式。

  1. 完全恢复(Full Recovery):
    完全恢复是指将数据库恢复到最近的完全备份和应用所有的在线重做日志(Redo Log)以保证数据的一致性和完整性。
    完全恢复是最常见和最安全的恢复方式,它可以确保数据库在故障或崩溃后恢复到最近的可用状态。
    完全恢复的过程包括应用完全备份、应用增量备份(如果有的话)和应用所有的在线重做日志。

  2. 不完全恢复(Incomplete Recovery):
    不完全恢复是指将数据库恢复到一个中间状态,只恢复到某个特定的时间点或者某个恢复序列号之前的状态。
    不完全恢复通常在以下情况下使用:
    当数据库发生了一些误操作或数据被错误地删除时,可以使用不完全恢复将数据库恢复到一个更早的时间点,以减少数据丢失。
    当数据库的完全备份不可用或过时时,可以使用不完全恢复进行部分恢复。

需要注意的是,不完全恢复可能会导致一些数据的丢失,因为它只能恢复到某个特定的时间点或恢复序列号之前的状态。这意味着在此时间点之后或此序列号之后提交的事务和更新的数据将无法恢复。

七、备份与恢复脚本

rman备份脚本

创建备份目录
mkdir -p /u01/app/oracle/backup
mkdir -p /u01/app/oracle/backup/db
mkdir -p /u01/app/oracle/backup/arch
mkdir -p /u01/app/oracle/backup/script/

chown -R oracle:oinstall /u01/app/oracle/backup
chown -R oracle:oinstall /u01/app/oracle/backup/script
chown -R oracle:oinstall /u01/app/oracle/backup/arch
chown -R oracle:oinstall /u01/app/oracle/backup/db

编辑脚本

vi /u01/app/oracle/backup/script/rman_full.sh
export ORACLE_HOME=/u01/app/oracle/product/version/db_1
export ORACLE_SID=orclcdb
export NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS'
rman target / cmdfile=/u01/app/oracle/backup/script/backup.sh  log=/u01/app/oracle/backup/script/backupall_$(date +%F).log 
vi /u01/app/oracle/backup/script/backup.sh
run{
allocate channel c1 type disk;
allocate channel c2 type disk;
# 开始备份数据文件和归档日志,备份完成后删除备份所使用的输入文件
backup as compressed backupset database format '/u01/app/oracle/backup/db/DB%U.bkp' plus archivelog format '/u01/app/oracle/backup/arch/ARCH%U.bkp' delete all input;
release channel c1;
release channel c2;
#列出所有被标记为过期的备份集
report obsolete;
#检查备份副本的状态和完整性
crosscheck copy;
#检查所有归档日志文件的状态
crosscheck archivelog all;
#删除所有被标记为过期的备份集
delete noprompt obsolete;
#检查备份集的状态并更新其在 RMAN 目录中的信息
crosscheck backup;
#删除所有被标记为过期的备份集
delete noprompt expired backup;
}
quit;
EOF

脚本授权
chmod 775 /u01/app/oracle/backup/script/rman_full.sh
chmod 775 /u01/app/oracle/backup/script/backup.sh

执行脚本
/u01/app/oracle/backup/script/rman_full.sh

编写定时任务,30分钟执行一次
crontab -e

*/30 * * * * /u01/app/oracle/backup/script/rman_full.sh

查看是否添加定时任务成功
crontab -l
在这里插入图片描述

rman恢复脚本
恢复控制文件
vim /oracle/home/restore_controlfile.rcv

run { 
allocate channel ch00 type 'SBT_TAPE';
send 'NB_ORA_SERV=jtbackupvpra01,NB_ORA_CLIENT=sjerppprd01';restore controlfile from '/c-2379360884-20231212-20';
Release channel  ch00;
}

rman target / cmdfile=restore_controlfile.rcv

恢复数据文件
vim /oracle/home/recover_database.rcv

run{
allocate channel ch00 type 'sbt_tape';
allocate channel ch01 type 'sbt_tape';
allocate channel ch02 type 'sbt_tape';
allocate channel ch03 type 'sbt_tape';
send 'NB_ORA_SERV=jtbackupvpra01,NB_ORA_CLIENT=sjerppprd01';
set newname for database to '/oracle/data/orcl/datafile/%b';
set until time "to_date('12-01-2023 18:00:00','dd-mm-yyyy hh24:mi:ss')";
restore database;
switch datafile all;
switch tempfile all;
recover database;
release channel  ch00;
release channel  ch01;
release channel  ch02;
release channel  ch03;
}

执行恢复

nohup rman target / cmdfile=/home/oracle/recover_database.rcv & log=/home/oracle/recover_database_$(date +%F).log &

全备和增备脚本

#!/bin/bash


# 定义RMAN脚本所需的环境变量
export ORACLE_HOME=/path/to/oracle/home
export ORACLE_SID=your_oracle_sid


# 定义备份目录和日志目录
BACKUP_DIR=/path/to/backup
LOG_DIR=/path/to/log


# 定义日期时间格式
DATE=$(date +"%Y%m%d%H%M%S")


# 定义全备份目标文件名
FULL_BACKUP_FILE=$BACKUP_DIR/full_${DATE}.bkp


# 定义增量备份目标文件名
INCREMENTAL_BACKUP_FILE=$BACKUP_DIR/incremental_${DATE}.bkp


# 定义日志归档目的地
ARCHIVE_DEST=/path/to/archive


# 初始化RMAN备份
$ORACLE_HOME/bin/rman target / nocatalog << EOF
CONFIGURE CONTROLFILE AUTOBACKUP ON;
CONFIGURE CONTROLFILE AUTOBACKUP FORMAT FOR DEVICE TYPE DISK TO '$BACKUP_DIR/%F';


# 开始全备份
RUN {
    ALLOCATE CHANNEL c1 DEVICE TYPE DISK FORMAT '$FULL_BACKUP_FILE';
    BACKUP AS COMPRESSED BACKUPSET DATABASE PLUS ARCHIVELOG;
    RELEASE CHANNEL c1;
}


# 开始增量备份
RUN {
    ALLOCATE CHANNEL c1 DEVICE TYPE DISK FORMAT '$INCREMENTAL_BACKUP_FILE';
    BACKUP INCREMENTAL LEVEL 1 DATABASE PLUS ARCHIVELOG;
    RELEASE CHANNEL c1;
}


# 同步归档日志
RUN {
    ALLOCATE CHANNEL c1 DEVICE TYPE DISK;
    BACKUP ARCHIVELOG ALL DELETE INPUT;
    RELEASE CHANNEL c1;
}


# 删除过期备份和归档日志
DELETE NOPROMPT EXPIRED BACKUP;
DELETE NOPROMPT EXPIRED ARCHIVELOG ALL;


EXIT;
EOF


# 将RMAN输出记录到日志文件
LOG_FILE=$LOG_DIR/rman_backup_${DATE}.log
mv $ORACLE_HOME/rdbms/log/rman.log $LOG_FILE

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1395811.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

探索 2024 年新副业:无人饮品机的新风向

随着科技的迅猛发展&#xff0c;无人饮品机作为一种全新的商业模式&#xff0c;正逐渐成为 2024 年副业的新风向。如果你还没有了解过这种全新的副业&#xff0c;那么现在是时候深入了解一下了。 D咖无人饮品机的优势在于其 24 小时不间断的营业模式&#xff0c;它可以在你睡觉…

【成功案例】首日ROI超70%!ROI目标超150%!看 NetMarvel如何助力棋牌游戏出海?

今天无论是线上线下&#xff0c;中国游戏广告在海外市场上屡见不鲜&#xff0c;甚至还会出现包场式营销&#xff0c;“中国人敢花钱”的印象已经深入人心&#xff0c;特别是休闲游戏的爆发给众多众多厂商带来新的增长机遇&#xff0c;大家花钱的态势更猛了。 棋牌类属于休闲体…

以后要做GIS开发的话是学GIS专业还是学计算机专业好一些?

GIS开发其实严格来说分为前后端以及底层开发。不同的方向&#xff0c;代表了不同的开发语言。 所以大家首先要了解自己具体要做的岗位类型是什么&#xff0c;其次才是选择专业侧重点。 但是严格来说&#xff0c;选择某个专业&#xff0c;到就业方向这个过程&#xff0c;并不是…

大疆笔试题目(2023-08-13)

1. 输出无重复3位数 时间限制&#xff1a; 3000MS 内存限制&#xff1a; 65536KB 题目描述&#xff1a; 从{1,2,3,4,5,6,7,8,9}中随机挑选不重复的5个数字作为输入数组’selectedDigits’&#xff0c;能组成多少个互不相同且无重复数字的3位数&#xff1f;请编写程序&#xff…

大创项目推荐 深度学习的水果识别 opencv python

文章目录 0 前言2 开发简介3 识别原理3.1 传统图像识别原理3.2 深度学习水果识别 4 数据集5 部分关键代码5.1 处理训练集的数据结构5.2 模型网络结构5.3 训练模型 6 识别效果7 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习…

基于小波多普勒变换的回波信号检测matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1小波变换基础 4.2 多普勒效应与多普勒变换 4.3 小波多普勒变换 4.4 回波信号检测 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 %回波…

QT自定义控件0-360°刻度尺

支持0到360&#xff0c;360到0的过度。 直接上代码&#xff0c;可以直接用&#xff0c;使用的paintevent事件实现的&#xff0c;没啥好讲的。 .cpp void Widget::drawCourse(QPainter& p,QPen pen,QFont font) {double currentNumber m_ang;p.setBrush(Qt::black);p.dra…

Docker-02-镜像项目部署

Docker-02-镜像&项目部署 文章目录 Docker-02-镜像&项目部署一、镜像①&#xff1a;镜像结构②&#xff1a;Dockerfile③&#xff1a;构建镜像01&#xff1a;构建02&#xff1a;查看镜像列表03&#xff1a;运行镜像 二、网络①&#xff1a;容器的网络IP地址②&#xff…

【动态规划】【二分查找】【C++算法】730. 统计不同回文子序列

作者推荐 【动态规划】【数学】【C算法】18赛车 涉及知识点 动态规划 二分查找 LeetCode730. 统计不同回文子序列 给你一个字符串 s &#xff0c;返回 s 中不同的非空回文子序列个数 。由于答案可能很大&#xff0c;请返回对 109 7 取余 的结果。 字符串的子序列可以经由…

PGSQL主键序列

PostgreSQL和 MySQL数据库还是有一定的区别。 下面了解一下 PGSQL的主键序列。 一、主键 1、系统自带主键序列 在 PostgreSQL 中&#xff0c;GENERATED BY DEFAULT 和 GENERATED ALWAYS 是用于定义自动生成的列&#xff08;Generated Column&#xff09;的选项。一般可作用…

可达性分析

可达性分析 这个算法的基本思路就是通过 一系列称为“GC Roots”的根对象作为起始节点集&#xff0c;从这些节点开始&#xff0c;根据引用关系向下搜索&#xff0c;搜索过 程所走过的路径称为“引用链”&#xff08;Reference Chain&#xff09;&#xff0c;如果某个对象到GC …

数学建模--比赛

内容来自数学建模BOOM&#xff1a;【快速入门】北海&#xff1a;数模建模基础MATLAB入门论文写作数学模型与算法(推荐数模美赛国赛小白零基础必看教程)_哔哩哔哩_bilibili 目录 1.学习内容 2.参赛须知 1&#xff09;参赛作品的组成 2)参赛作品的提交 3.软件安装 4.注意…

Electron中苹果支付 Apple Pay inAppPurchase 内购支付

正在开发中&#xff0c;开发好了&#xff0c;写一个完整详细的过程&#xff0c;保证无脑集成即可 一、先创建一个App 一般情况下&#xff0c;在你看这篇文章的时候&#xff0c;说明你已经开发的app差不多了。 但是要上架app到Mac App Store&#xff0c;则要在appstoreconnect…

pyspark 笔记:窗口函数window

窗口函数相关的概念和基本规范可以见&#xff1a;pyspark笔记&#xff1a;over-CSDN博客 1 创建Pyspark dataFrame from pyspark.sql.window import Window import pyspark.sql.functions as F employee_salary [("Ali", "Sales", 8000),("Bob&qu…

UI自动化Selenium 无头模式运行

1、导入浏览器参数设置 from selenium.webdriver.chrome.options import Options 2、创建参数&#xff0c;并使用无厘头模式创建driver对象 opt Options() # 新建参数对象 opt.add_argument("--headless") # 无头 self.driver webdriver.Chrome(optionsopt) …

【数据结构】哈希表详解,举例说明 java中的 HashMap、HashTable及其区别

一、哈希表&#xff08;Hash Table&#xff09;简介&#xff1a; 哈希表是一种数据结构&#xff0c;用于实现字典或映射等抽象数据类型。它通过把关键字映射到表中的一个位置来实现快速的数据检索。哈希表的基本思想是利用哈希函数将关键字映射到数组的索引位置上&#xff0c;…

四款免费、易用的Docker漏洞扫描工具

本文向您介绍四种既可以扫描Docker镜像中的漏洞&#xff0c;又能够被轻松地集成到CI/CD中的四种免费实用工具。 基本原理 所有这些工具的工作原理都比较类似。它们使用的是如下两步流程&#xff1a; 生成软件物料清单(Software Bill of Materials&#xff0c;SBOM)。将SBOM与…

USB PHY for FPGA layout

https://blog.csdn.net/qq_41904778/article/details/123967670 ZYNQ7000内部没有USB PYH&#xff0c;我们通过USB 3320 PHY 芯片来连接FPGA 和外部的USB端口&#xff08;DP & DP-&#xff09;。USB 3320 PHY跟FPGA内部是t通过ULPI接口试下的&#xff0c;然后把数据转化为…

windows下编译报‘mutex‘ in namespace ‘std‘ does not name a type的解决方案

问题复述&#xff1a; windows下使用MinGW编译工程时&#xff0c;报如下错误&#xff1a; error: ‘mutex’ in namespace ‘std’ does not name a type error: ‘mutex’ is not a member of ‘std’ error: ‘mutex’ was not declared in this scope 问题分析&#xff…

C#,字符串匹配(模式搜索)Sunday算法的源代码

Sunday算法是Daniel M.Sunday于1990年提出的一种字符串模式匹配算法。 核心思想&#xff1a;在匹配过程中&#xff0c;模式串并不被要求一定要按从左向右进行比较还是从右向左进行比较&#xff0c;它在发现不匹配时&#xff0c;算法能跳过尽可能多的字符以进行下一步的匹配&…