ES8生产实践——ES跨集群数据迁移方案测评

引言

场景需求

经常有小伙伴咨询如何将整个es集群数据如何迁移到另一个集群,其中往往会涉及到以下的问题:
跨es版本:老版本es集群数据迁移到新版本es集群。
跨集群:源数据和目的数据分布在两个不同的集群。
跨网络:两套集群分布数据不同的局域网、一套在公有云、一套在自建机房。

迁移思路

目前主流的解决方案分为以下两类:
批量读取旧集群的数据然后再批量写入新集群:elasticsearch-dump、esm、reindex、logstash都是采用这种方式。
底层文件备份恢复:snapshot直接把旧集群的底层的文件进行备份,在新的集群中恢复出来,相比较scroll query + bulk的方式,snapshot的方式迁移速度最快。

环境准备

测试环境

源数据集群:单节点rpm方式部署的es7.17.18集群,ip地址为192.168.10.70。
目的数据集群:3节点rpm方式部署的es8.12.2集群,ip地址为192.168.10.61/62/63。
数据中转操作节点:可同时连接两套es集群,用于中转数据。

测试数据

使用esrally工具生成测试数据,模拟生产环境大小为2.6G的业务数据。具体可参考文档:https://www.cuiliangblog.cn/detail/article/81
image.png
运行日志生成程序,模拟生产环境中持续写入的日志数据。具体可参考文档:https://www.cuiliangblog.cn/detail/article/63
image.png

全量迁移方案对比测试

数据迁移流程思路

我们先在目的集群设置索引模板,保证写入速率最大化。

PUT _template/geonames
{"index_patterns": ["geonames*"],"order": 100,"settings": {"refresh_interval": "-1","number_of_shards": "3","translog": {"sync_interval": "60s","durability": "async"},"number_of_replicas": "0"}
}

然后使用迁移工具,将源数据导出至目的集群。
最后在索引管理中将number_of_replicas和refresh_interval参数设置为合适的值即可。
image.png

snapshot方案

ES支持快照功能,用于实现数据的备份与恢复。我们可以生成单个索引或整个集群的快照,并将其存储在共享文件系统上的存储库中,并且有一些插件支持 S3、HDFS、Azure、Google Cloud Storage 等上的远程存储库。
本实验以NFS为例演示es的快照备份与恢复。

源集群配置

源数据集群配置NFS共享存储库具体可参考文档:https://www.cuiliangblog.cn/detail/section/162073776,配置完后效果如下所示:
image.png
接下来配置索引快照存储策略,配置完后后点击立即运行。
image.png
等待备份完成,查看备份结果,2.6G数据备份耗时78秒
image.png

目的集群配置

操作与源集群类似,先配置nfs共享存储仓库,配置完后效果如下所示:
image.png
因为源集群和目的集群使用同一个备份存储库,所以目的集群配置完存储库后就可以加载出源集群的备份数据。
image.png
在还原过程中通常会设置number_of_replicas: 0和refresh_interval: -1两个参数,以加速数据恢复。
image.png
等待还原完成,查看还原结果,2.6G数据还原耗时71秒
image.png
恢复后的索引数据如下所示,由于设置了1个副本,因此存储大小变为5.3G
image.png

elasticsearch-dump方案

elasticsearch-dump是一个开源的使用JavaScript语言开发的Elasticsearch数据迁移工具,详细信息请参见文档:https://github.com/elasticsearch-dump/elasticsearch-dump

中转操作节点安装部署

安装elasticdump

[root@tiaoban ~]# dnf install nodejs npm -y
[root@tiaoban ~]# npm install elasticdump -g

Elasticdump标准指令是

elasticdump --input SOURCE --output DESTINATION [OPTIONS]
  • input SOURCE表示读取数据源SOURCE
  • output DESTINATION表示将数据源传输到目的地DESTINATION。
  • SOURCE/DESTINATION两者都可以是Elasticsearch URL或文件,如果是Elasticsearch URL,例如http://127.0.0.1/index,就意味着是直接往地址为http://127.0.0.1ES库里导入或者从其导出索引相关数据。
  • [OPTIONS]是操作选项,比较常用有type和limit,其他操作这里就不展开介绍。

type是ES数据导出导入类型,Elasticdum工具支持以下数据类型的导入导出。

type类型说明
mappingES的索引映射结构数据
dataES的数据
settingsES的索引库默认配置
analyzerES的分词器
templateES的模板结构数据
aliasES的索引别名

整个迁移过程分为先设置索引参数参数,再迁移mapping结构,待数据迁移完成后再修改number_of_replicas和refresh_interval为合适的值。

迁移mapping

使用elasticdump工具,将es7单节点的geonames索引mapping迁移到三节点es8集群中。

[root@tiaoban ~]# NODE_TLS_REJECT_UNAUTHORIZED=0 elasticdump \
--input=http://elastic:123.com@192.168.10.70:9200/geonames \
--output=https://elastic:yoVU+Pit0YnVvr+xO_B1@192.168.10.61:9200/geonames \
--type=mappingSun, 17 Mar 2024 11:11:12 GMT | starting dumpSun, 17 Mar 2024 11:11:12 GMT | got 1 objects from source elasticsearch (offset: 0)
Sun, 17 Mar 2024 11:11:12 GMT | sent 1 objects to destination elasticsearch, wrote 2
Sun, 17 Mar 2024 11:11:12 GMT | got 0 objects from source elasticsearch (offset: 1)
Sun, 17 Mar 2024 11:11:12 GMT | Total Writes: 2
Sun, 17 Mar 2024 11:11:12 GMT | dump complete

mapping迁移完成后,查看索引信息,已经创建名为geonames的索引。

迁移data

与迁移mapping类似,我们只需要将type从mapping改为data即可,观察控制台输出,每迁移1万条数据耗时约95秒。

[root@tiaoban ~]# date
2024年 03月 17日 星期日 19:12:50 CST
[root@tiaoban ~]# NODE_TLS_REJECT_UNAUTHORIZED=0 elasticdump \
--input=http://elastic:123.com@192.168.10.70:9200/geonames \
--output=https://elastic:yoVU+Pit0YnVvr+xO_B1@192.168.10.61:9200/geonames \
--type=data
Sun, 17 Mar 2024 12:43:07 GMT | starting dump
Sun, 17 Mar 2024 12:43:08 GMT | got 100 objects from source elasticsearch (offset: 0)
Sun, 17 Mar 2024 12:43:08 GMT | sent 100 objects to destination elasticsearch, wrote 100
Sun, 17 Mar 2024 12:43:08 GMT | got 100 objects from source elasticsearch (offset: 100)
Sun, 17 Mar 2024 12:43:08 GMT | sent 100 objects to destination elasticsearch, wrote 100
Sun, 17 Mar 2024 12:43:08 GMT | got 100 objects from source elasticsearch (offset: 200)

elasticdump执行完成后查看目的集群索引,已成功完成迁移,整个过程耗时约3个小时。

esm方案

esm迁移过程原理与elasticsearch-dump类似,区别在于esm使用go语言开发,号称每分钟可以迁移一千万条数据,仓库地址:https://github.com/medcl/esm

中转操作节点安装部署

安装esm

[root@tiaoban ~]# cd /opt/
[root@tiaoban opt]# wget https://github.com/medcl/esm/releases/download/v0.7.0/esm-linux-amd64

esm标准指令是

esm -s SOURCE -d DESTINATION -x INDEX_NAME [OPTIONS]
  • -s表示读取数据源SOURCE
  • -d表示将数据源传输到目的地DESTINATION。
  • -x表示需要复制的index名称
  • -q表示指定条件的查询语句
  • -n表示base认证的用户名和密码
  • -w表示并发数,默认为1
  • -b表示buck大小,默认5MB
  • -f表示复制前删除已有重名索引
  • –refresh表示完成后再刷新索引

迁移数据

使用esm工具,将es7单节点的geonames索引模板与数据迁移到三节点es8集群中。

[root@tiaoban opt]# ./esm-linux-amd64 -s http://192.168.10.70:9200 -m elastic:123.com -x "geonames" -d https://192.168.10.61:9200 -n "elastic:yoVU+Pit0YnVvr+xO_B1" -c 10000 -w10 -b=20 -f --refresh
[03-17 22:20:26] [INF] [ migrator.go:115 ,ParseEsApi] source es version: 7.17.18
[03-17 22:20:30] [INF] [ migrator.go:115 ,ParseEsApi] dest es version: 8.12.2
geonames
[03-17 22:20:30] [INF] [ main.go:432 ,main] start data migration..
Scroll 250000 / 11396503 [==>--------------------------------------------------------------------------------------------------------------------]   2.19% 1h07m33s
Bulk 0 / 11396503 [---------------------------------------------------------------------------------------------------------------------------------------]   0.00%

通过控制台可知,整个迁移过程需要时间约1个小时10分钟。

reindex方案

设置索引模板

在迁移数据前,我们先设置索引模板,保证写入速率最大化

PUT _template/geonames
{"index_patterns": ["geonames*"],"order": 100,"settings": {"refresh_interval": "-1","number_of_shards": "3","translog": {"sync_interval": "60s","durability": "async"},"number_of_replicas": "0"}
}

配置集群白名单

需要修改目的集群每个节点配置,新增源数据集群es地址,然后重启elasticsearch服务。

[root@es-1 ~]# vim /etc/elasticsearch/elasticsearch.yml 
reindex.remote.whitelist: "192.168.10.70:9200"
[root@es-1 ~]# systemctl restart elasticsearch.service 

执行reindex迁移

在目的集群使用dev tools工具执行如下指令。

  • 其中size表示每批次的数据量,默认值1000
  • slice表示切片数量,我们有3个数据节点,可将参数设置为3。
  • wait_for_completion=false表示异步执行,ES将会以task 来描述此类执行任务
# 请求
POST _reindex?wait_for_completion=false
{"source": {"remote": {"host": "http://192.168.10.70:9200","username": "elastic","password": "123.com"},"index": "geonames","size": 5000,"slice": {"id": 0,"max": 3}},"dest": {"index": "geonames"}
}
# 响应
{"task": "nkJRutfnRryTwxR3BT3X8g:8989"
}

查询异步任务。

# 请求
GET _tasks/nkJRutfnRryTwxR3BT3X8g:8989
# 响应
{"completed": false,"task": {"node": "nkJRutfnRryTwxR3BT3X8g","id": 8989,"type": "transport","action": "indices:data/write/reindex","status": {"slice_id": 0,"total": 11396503,"updated": 0,"created": 1590000,"deleted": 0,"batches": 319,"version_conflicts": 0,"noops": 0,"retries": {"bulk": 0,"search": 0},"throttled_millis": 0,"requests_per_second": -1,"throttled_until_millis": 0},"description": """reindex from [host=192.168.10.70 port=9200 query={"match_all" : {"boost" : 1.0}
} username=elastic password=<<>>][geonames] to [geonames]""","start_time_in_millis": 1710686333672,"running_time_in_nanos": 54938483353,"cancellable": true,"cancelled": false,"headers": {"trace.id": "8e6e3043b5c916eb3f8f569f9132d9ab"}}
}

实测2.6GB数据迁移用时15分钟。

logstash方案

安装logstash

[root@tiaoban ~]# wget https://artifacts.elastic.co/downloads/logstash/logstash-8.12.2-x86_64.rpm
[root@tiaoban ~]# rpm -ivh logstash-8.12.2-x86_64.rpm
[root@tiaoban ~]# ln -s /usr/share/logstash/bin/logstash /usr/bin/logstash
[root@tiaoban ~]# logstash -V
Using bundled JDK: /usr/share/logstash/jdk
logstash 8.12.2

配置logstash

[root@tiaoban ~]# vim /etc/logstash/conf.d/es-migrate.conf
input{elasticsearch{hosts =>  ["http://192.168.10.70:9200"] # 源端ES地址。# 安全集群配置登录用户名密码。user => "elastic"password => "123.com"index => "geonames" # 需要迁移的索引列表,多个索引以英文以逗号(,)分隔。# 以下三项保持默认即可,包含线程数和迁移数据大小和Logstash JVM配置相关。docinfo=>trueslices => 5size => 5000}
}
filter {# 去掉一些Logstash自己加的字段。mutate {remove_field => ["@timestamp", "@version"]}
}
output{elasticsearch{hosts => ["https://192.168.10.61:9200"] # 目标端ES地# 安全集群配置登录用户名密码。user => "elastic"password => "yoVU+Pit0YnVvr+xO_B1"index => "geonames" # 目标端索引名称ssl_enabled => true		# 如果是https协议,需要设置为truessl_verification_mode => none # 是否跳过证书验证,如果为false需要指定证书路径}
}

启动logstash

[root@tiaoban ~]# logstash -f /etc/logstash/conf.d/es-migrate.conf 
# 也可以通过systemctl start logstash方式启动

实测2.6GB数据迁移用时8分钟。

增量迁移方案

业务场景

ES除了用于存储业务类数据外,日志和指标数据存储也是其另一大使用场景,在这类业务场景下,数据迁移往往还需要考虑到采集日志客户端逐渐切换过程中日志数据增量迁移的问题。

迁移方案

CCR方案:ES官方推出了CCR跨集群复制方案,可以完美实现数据的实时增量迁移,具体可参考文档https://www.cuiliangblog.cn/detail/section/83558841,需要注意的是开源社区版不支持该功能。
定时任务+时间范围查询方案:然后通过定时任务工具每分钟执行一次迁移工具,查询最近3分钟数据(主要取决于源数据refresh_interval参数,查询时间范围应大于refresh_interval参数),在写入es集群时指定文档id为原始数据id,以保证写入新集群时数据唯一。需要注意的是此方案只能针对数据有增无减的场景使用。可以使用sdk开发程序,或者使用logstash来实现。在增量同步前先执行一次全量迁移任务,保证先前历史数据迁移至新集群,然后再启动增量迁移任务。

logstash迁移方案

修改配置文件,我们只需要将pipeline放置在/etc/logstash/conf.d/目录下并以.conf结尾,logstash启动时会去扫描该目录下所有conf结尾的pipeline并加载。

[root@tiaoban ~]# vim /etc/logstash/conf.d/es-migrate.conf
input{elasticsearch{hosts =>  ["http://192.168.10.70:9200"] # 源端ES地址。# 安全集群配置登录用户名密码。user => "elastic"password => "123.com"index => "logs-myapp-default" # 需要迁移的索引列表,多个索引以英文以逗号(,)分隔。# 包含线程数和迁移数据大小和Logstash JVM配置相关。slices => 5size => 5000# 获取文档元数据信息docinfo=> truedocinfo_target => "[@metadata][doc]"# 按时间范围查询增量数据,以下配置表示查询最近3分钟的数据。query => '{"query":{"range":{"@timestamp":{"gte":"now-3m","lte":"now/m"}}}}'# 定时任务,以下配置表示每分钟执行一次。schedule => "* * * * *"# 滚动查询活动时间scroll => "3m"}
}
filter {# 去掉一些Logstash自己加的字段。mutate {remove_field => ["@timestamp", "@version"]}
}
output{elasticsearch{hosts => ["https://192.168.10.61:9200"] # 目标端ES地# 安全集群配置登录用户名密码。user => "elastic"password => "yoVU+Pit0YnVvr+xO_B1"# 目标数据流配置data_stream => "true"data_stream_type => "logs"data_stream_dataset => "myapp"data_stream_namespace => "default"ssl_enabled => true		# 如果是https协议,需要设置为truessl_verification_mode => none # 是否跳过证书验证,如果为false需要指定证书路径document_id => "%{[@metadata][doc][_id]}" # 目标端数据的id,id存在会覆盖,保证数据唯一。}
}

启动logstash迁移服务

[root@tiaoban ~]# systemctl start logstash
[root@tiaoban ~]# systemctl enable logstash

结果验证
es7集群搜索id为"AYshUY4BV0xJuZCSuWf6"的文档,查看信息。
image.png
es8集群同样可以查询到id为"AYshUY4BV0xJuZCSuWf6"的文档,且内容完全一致。
image.png

方案总结

方案elasticsearch-dumpesmreindexlogstashsnapshot
基本原理逻辑备份,类似mysqldump将数据一条一条导出后再执行导入ESM 是 medcl 开源的派生自:Elasticsearch Dumper 的工具,基于 go 语言开发。reindex 是 Elasticsearch 提供的一个 API 接口,可以把数据从一个集群迁移到另外一个集群从一个集群中读取数据然后写入到另一个集群从源集群通过Snapshot API 创建数据快照,然后在目标集群中进行恢复
网络要求无网络互通要求无网络互通要求网络需要互通网络需要互通无网络互通要求
迁移速度最慢很慢一般很快最快
适合场景适用于数据量小的离线场景适用于数据量小的离线场景适用于数据量中等,在线迁移数据的场景适用于数据量很大,实时数据传输的场景适用于数据量特大,离线数据迁移的场景
配置复杂度简单简单中等中等复杂
缺点速度全宇宙最慢,没有之一跨大版本不能迁移mapping,需要手动迁移需要设置集群白名单,重启elasticsearch服务logstash对资源要求较高,建议单独的一台服务器运行。在快照还原过程中无法修改分片数,分片数取决于源集群索引设置。
迁移时长(1100万条数据)3小时1小时10分钟15分钟8分钟2分钟

查看更多

微信公众号

微信公众号同步更新,欢迎关注微信公众号《崔亮的博客》第一时间获取最近文章。

博客网站

崔亮的博客-专注devops自动化运维,传播优秀it运维技术文章。更多原创运维开发相关文章,欢迎访问https://www.cuiliangblog.cn

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

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

相关文章

ch6文件操作和异常处理

os.listdir(path) 函数详解 功能: os.listdir(path) 函数用于返回指定目录下的所有文件和文件夹的名字列表&#xff0c;但不包括 . 和 ..。 参数: path: 要列出的目录的路径。 返回值: 一个包含目录下所有文件和文件夹名字的列表。 示例: import ospath "/home/u…

备战秋招(coding篇)

其中coding题目来源于师兄面试经验 1、链表的结构体反转链表 本质上就是一个构造函数 struct ListNode{int val_;ListNode* next_;ListNode() : val_(0), next_(NULL) {}ListNode(int x) : val_(x), next_(NULL) {}ListNode(int x, ListNode* next) : val_(x), next_(next) …

Crypto Gladiator League (CGL)

《加密角斗士》是一款完全链上游戏。所有角斗士、装备、代币等的生成过程都可以透明追溯。不可能被篡改或欺骗&#xff0c;使所有游戏物品都是真实资产。 CGL 现已升级为全链游戏平台和 Web3 游戏流量门户&#xff0c;通过多维度收集用户数据&#xff0c;并将数据应用于游戏中&…

【Java11下载、安装、部署指南】

oracle jdk11下载 oracle jdk所有版本归档【archive】下载地址&#xff1a; https://www.oracle.com/java/technologies/downloads/archive/ oracle jdk11下载地址&#xff1a; https://www.oracle.com/java/technologies/javase/jdk11-archive-downloads.html 配置或修改wi…

软件工程-第9章 软件工程项目管理概述

9.1 软件工程管理活动 9.2 软件规模、成本和进度估算 9.3 能力成熟度模型CMM 9.4 ISO 9000系列标准简介 9.5 CMM与ISO 9000系列标准的比较 9.6 本章小结

Matlab|基于多目标粒子群算法的配电网储能选址定容

目录 一、主要内容 二、主要流程 三、部分程序 四、程序结果 五、程序链接 一、主要内容 程序是对文章《基于多目标粒子群算法的配电网储能选址定容》的方法复现&#xff0c;具体内容如下&#xff1a; 以系统节点电压水平&#xff08;电网脆弱性&#xff09;、网络损耗以及…

数据库系统概论-第5章 数据库完整性

5.1 实体完整性 5.2 参照完整性 5.3 用户定义完整性 5.4 完整性约束命名子句 5.5 域中的完整性限制 5.6 断言 5.7 触发器 5.8 小结

Pytest自动化测试框架快速上手(超详细)

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号&#xff1a;互联网杂货铺&#xff0c;回复1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;薪资嘎嘎涨 pytest是一个非常成熟的全功能的Python测试框架&#…

蓝桥杯单片机快速开发笔记——NE555测频

一、原理分析 NE555作为一种多功能集成电路&#xff0c;在信号发生和频率测量方面具有广泛的应用。通过合理配置和连接外部元件&#xff0c;可以实现不同类型的信号发生和频率测量功能。 原理&#xff1a; 信号发生器&#xff1a; NE555可以配置为多种不同的振荡器电路&#x…

【鸿蒙HarmonyOS开发笔记】通知模块之发布基础类型通知,内含如何将图片变成PixelMap对象

通知简介 应用可以通过通知接口发送通知消息&#xff0c;终端用户可以通过通知栏查看通知内容&#xff0c;也可以点击通知来打开应用。 通知常见的使用场景&#xff1a; 显示接收到的短消息、即时消息等。 显示应用的推送消息&#xff0c;如广告、版本更新等。 显示当前正…

基于cnn深度学习的yolov5+pyqt+分类+resnet+骨龄检测系统

往期热门博客项目回顾&#xff1a; 计算机视觉项目大集合 改进的yolo目标检测-测距测速 路径规划算法 图像去雨去雾目标检测测距项目 交通标志识别项目 yolo系列-重磅yolov9界面-最新的yolo 姿态识别-3d姿态识别 深度学习小白学习路线 YOLOv5与骨龄识别 YOLOv5&a…

极简生活|2024年让自己越来越好的18个极简好习惯

哈喽&#xff0c;你好啊&#xff0c;我是雷工&#xff01; 转眼间已经进入了2024年&#xff0c;新的一年&#xff0c;新的开始。 俗话说&#xff1a;百尺高台起于垒土&#xff0c;千里之堤毁于蚁穴。 好习惯积累的越多&#xff0c;坏习惯越来越少&#xff0c;我们的生活才能越…

【NLP笔记】预训练+微调范式之OpenAI Transformer、ELMo、ULM-FiT、Bert..

文章目录 OpenAI TransformerELMoULM-FiTBert基础结构Embedding预训练&微调 【原文链接】&#xff1a; BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding 【本文参考链接】 The Illustrated BERT, ELMo, and co. (How NLP Cracked Tra…

STL第一弹

2 STL初识 2.1 STL的诞生 长久以来&#xff0c;软件界一直希望建立一种可重复利用的东西 C的面向对象和泛型编程思想&#xff0c;目的就是复用性的提升 大多情况下&#xff0c;数据结构和算法都未能有一套标准,导致被迫从事大量重复工作为了建立数据结构和算法的一套标准,诞生…

Gradio官方文档

文章目录 构建您的第一个demo分享您的demo进度条受密码保护的应用程序The Interface class&#xff08;接口类&#xff09;Components Attributes&#xff08;组件属性&#xff09;多个输入和输出组件图像示例嵌套列表描述性内容手风琴中的附加输入The 4 Kinds of Gradio Inter…

蓝桥杯Python B组练习——完美的代价

一、题目 问题描述   回文串&#xff0c;是一种特殊的字符串&#xff0c;它从左往右读和从右往左读是一样的。小龙龙认为回文串才是完美的。现在给你一个串&#xff0c;它不一定是回文的&#xff0c;请你计算最少的交换次数使得该串变成一个完美的回文串。   交换的定义是…

C语言-----冒泡排序

今天&#xff0c;让我们来学习一下C语言中一个简单的排序算法------冒泡排序。 什么是冒泡排序呢&#xff1f; 冒泡排序是C语言中一个可以将一个数组的内容按照升序或者降序进行重新排列的算法。简单来说&#xff0c;是一种排序的思维。 冒泡排序的核心思想&#xff1a;让同…

【手撸IM】通讯协议设计与实现

【手撸IM】专题由来&#xff1a;之前利用业余空闲时间写一个Java版Akka-Rpc&#xff0c;并且基于它写了一个分布式高性能文件服务&#xff0c;从反馈上来看&#xff0c;还是得到了一定的关注&#xff0c;甚至部分同学真的基于此直接抄作业和二开了。因此有了再进一步去手撸一个…

【Vue】el-select下选组件

系列文章 【Vue】vue增加导航标签 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/134965353 【Vue】Element开发笔记 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/133947977 【Vue】vue&#xff0c;在Windows IIS平台…

修改约束

目录 修改约束 创建数据库 添加约束 删除约束 Oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/135209645 修改约束 如果说表结构的修改还在可以容忍的范畴之内&#xff0c;那么约束的修改是绝对 100% 禁止的 所有的约束一定要在…